D223 FPGA内部架构与Verilog设计:从AD7606接口到FIFO控制
·
www.z-linear.com
D223的核心创新是使用FPGA作为AD7606和STM32之间的桥梁。FPGA内部怎么控制AD7606采样?FIFO怎么缓存数据?SRAM怎么记录?QSPI接口怎么响应?本文解析D223 FPGA的内部架构。
一、FPGA在D223中的角色
1.1 为什么需要FPGA?
AD7606的并行总线时序复杂——BUSY、CS、RD、CONVST、DB[15:0]需要精确控制。STM32直接控制并行总线会占用大量CPU时间,且无法同时处理USB通信。FPGA承担了AD7606的硬件控制,释放STM32的CPU。
| 功能 | 无FPGA(7606) | 有FPGA(D223) |
|---|---|---|
| ADC接口 | SPI(串行,慢) | 并行(快) |
| 最大采样率 | 35KSPS(SPI限制) | 500KSPS(并行) |
| CPU占用 | 高(每次采样都要CPU) | 低(DMA读取) |
| FIFO缓存 | 无 | FPGA内置FIFO |
| SRAM记录 | 无 | FPGA外挂SRAM |
1.2 D223 FPGA型号
| 参数 | 值 |
|---|---|
| 芯片 | GOWIN Tang Primer |
| 逻辑单元 | ~10000+ |
| BRAM | 内置FIFO |
| 封装 | QFN88 |
| 供电 | 1.2V核心/3.3V IO |
| 配置 | 外部Flash |
二、FPGA内部功能模块
2.1 模块框图
┌─────────────────────────────────────────┐
│ FPGA内部 │
│ │
│ ┌──────────┐ ┌──────────┐ │
│ │ AD7606 │───→│ FIFO │ │
│ │ 控制器 │ │ (4组缓存) │ │
│ │ │ │ │ │
│ │ CONVST │ │ 写指针 │ │
│ │ BUSY │ │ 读指针 │ │
│ │ CS/RD │ └────┬─────┘ │
│ │ DB[15:0] │ │ │
│ └──────────┘ │ │
│ ↓ │
│ ┌──────────┐ ┌──────────┐ │
│ │ SPI寄存器 │ │ QSPI │ │
│ │ 接口 │ │ 接口 │ │
│ │ │ │ │ │
│ │ A2F寄存器 │ │ 命令解码 │ │
│ │ F2A寄存器 │ │ 数据读出 │ │
│ └──────────┘ └──────────┘ │
│ │ │
│ ┌──────────┐ │ │
│ │ SRAM │←────────┘ │
│ │ 控制器 │ │
│ └──────────┘ │
└─────────────────────────────────────────┘
2.2 模块清单
| 模块 | 功能 | 接口 |
|---|---|---|
| AD7606控制器 | 产生CONVST/读取DB[15:0] | 并行总线 |
| FIFO缓存 | 4组×8通道ADC数据缓存 | 内部BRAM |
| SPI寄存器接口 | STM32读写FPGA寄存器 | SPI1(3线) |
| QSPI接口 | STM32高速读取FIFO/SRAM | QSPI(4线) |
| SRAM控制器 | 外部SRAM读写控制 | 并行地址/数据总线 |
| 命令解码 | 解析QSPI命令码(0x80/0x81/0xEB) | 内部逻辑 |
| 触发控制 | DIN8外部触发SRAM记录 | GPIO输入 |
三、AD7606控制器
3.1 控制时序
CONVST ──┐ ┌──────
│ │
└────┘ (≥40ns高电平)
↓
BUSY ─────────┐ ┌──
│ 4μs转换 │
└─────────┘
↓ 数据就绪
CS ──────────┐ ┌──
│ │
RD ──┐ ┌──┐ ┌──┐ ┌──┐ │
│ │ │ │ │ ... │ │ │
└──┘ └──┘ └──┘ └──┘ │
V1 V2 V3 ... V8 │
DB[15:0] ←─V1─←V2─←V3─...←V8─────┘
3.2 Verilog伪代码
module ad7606_controller (
input clk, // FPGA主时钟
input convst_start, // 来自TIM13的采样触发
output reg convst, // AD7606 CONVST
input busy, // AD7606 BUSY
output reg cs_n, // AD7606 CS
output reg rd_n, // AD7606 RD
input [15:0] db, // AD7606 数据总线
output reg [2:0] os, // 过采样控制
output reg range, // 量程控制
output reg [15:0] ch_data [7:0], // 8通道数据
output reg data_ready // 数据就绪标志
);
// 状态机
localparam IDLE = 0,
CONV = 1,
WAIT = 2,
READ = 3,
DONE = 4;
reg [2:0] state = IDLE;
reg [3:0] ch_cnt = 0;
always @(posedge clk) begin
case(state)
IDLE: begin
cs_n <= 1; rd_n <= 1; convst <= 0;
if(convst_start) begin
convst <= 1;
state <= CONV;
end
end
CONV: begin
convst <= 0; // CONVST脉冲(≥40ns)
state <= WAIT;
end
WAIT: begin
if(!busy) begin // BUSY下降沿
cs_n <= 0;
state <= READ;
ch_cnt <= 0;
end
end
READ: begin
rd_n <= 0; // RD低电平读取
ch_data[ch_cnt] <= db; // 锁存数据
rd_n <= 1;
ch_cnt <= ch_cnt + 1;
if(ch_cnt == 7) state <= DONE;
end
DONE: begin
cs_n <= 1;
data_ready <= 1; // 通知FIFO写入
state <= IDLE;
end
endcase
end
endmodule
四、FIFO缓存设计
4.1 FIFO格式
FPGA内部FIFO存储4组ADC数据,每组66字节。
FIFO结构:
┌──────────────────────────────────────────────┐
│ index(4字节) 低8位=写索引, 高8位=DIN状态 │
├──────────────────────────────────────────────┤
│ Group0: CH1[2B] CH2[2B] ... CH8[2B] = 16B │
├──────────────────────────────────────────────┤
│ Group1: CH1[2B] CH2[2B] ... CH8[2B] = 16B │
├──────────────────────────────────────────────┤
│ Group2: CH1[2B] CH2[2B] ... CH8[2B] = 16B │
├──────────────────────────────────────────────┤
│ Group3: CH1[2B] CH2[2B] ... CH8[2B] = 16B │
└──────────────────────────────────────────────┘
总计: 2 + 4×16 = 66字节
4.2 FIFO读写指针
// FIFO写指针
reg [7:0] fifo_wr_idx = 0; // 低8位
always @(posedge data_ready) begin
fifo_wr_idx <= fifo_wr_idx + 1;
fifo_data[fifo_wr_idx] <= {din_state, fifo_wr_idx[7:0]}; // 索引+DIN
fifo_data[fifo_wr_idx].data[0] <= ch_data[0]; // CH1
fifo_data[fifo_wr_idx].data[1] <= ch_data[1]; // CH2
// ...
fifo_data[fifo_wr_idx].data[7] <= ch_data[7]; // CH8
end
4.3 STM32读取FIFO
STM32通过QSPI命令0x81读取FIFO的66字节数据,DMA自动搬运到内存。
QSPI命令0x81:
[CS↓] [0x81] [地址(2B)] [数据(66B)] [CS↑]
↑
4线传输@50MHz
五、SPI寄存器接口
5.1 寄存器映射
STM32通过SPI1读写FPGA的控制/状态寄存器。
// A2F寄存器(ARM→FPGA方向)
reg [15:0] reg_samplingPeriod; // 采样周期
reg [15:0] reg_sramBaseAddr; // SRAM基地址
reg [15:0] reg_sramDataLen; // SRAM数据长度
reg [7:0] reg_workState; // 工作状态(待机/在线/SRAM)
reg [7:0] reg_workState2; // 触发使能
reg [7:0] reg_convstCtrl; // AD7606转换控制
// ...
// F2A寄存器(FPGA→ARM方向)
reg [15:0] reg_fifoWriteIndex; // FIFO写索引
reg [7:0] reg_sramWorkState; // SRAM记录状态
reg [7:0] reg_sramWorkState2; // 外部触发状态
reg [15:0] reg_fpgaVersion; // FPGA版本号
// ...
5.2 SPI命令解码
// SPI命令处理
// 命令码最高位: 1=写, 0=读
always @(posedge spi_sck) begin
if(!spi_cs_n) begin
cmd_buffer <= spi_mosi;
if(cmd_buffer[7] == 1) begin
// 写操作: 数据写入reg
reg_file[addr] <= spi_data;
end else begin
// 读操作: 数据从reg读出
spi_miso <= reg_file[addr];
end
end
end
六、SRAM控制器
6.1 SRAM记录模式
SRAM记录模式时,FPGA持续将ADC数据写入外部SRAM,记录完成后STM32分批读取。
SRAM记录流程:
1. STM32设置工作状态=SRAM记录
2. STM32设置SRAM基地址+数据长度
3. 可选: 使能DIN8外部触发
4. FPGA开始持续采样→写入SRAM
5. SRAM写满或收到停止命令
6. STM32用QSPI命令0xEB分批读取SRAM
6.2 QSPI命令0xEB
命令0xEB用于读取SRAM数据,使用24位地址和6个dummy周期。
[CS↓] [0xEB] [地址(3B)] [Dummy(6)] [数据(NB)] [CS↑]
1线 1线 4线 4线
6.3 SRAM容量
| SRAM | 容量 | 采样点数 | 记录时长(8CH@500K) |
|---|---|---|---|
| 1MB | 1,048,576B | ~65,000组 | 130ms |
| 8MB | 8,388,608B | ~520,000组 | 1.04s |
七、触发控制
7.1 DIN8外部触发
SRAM记录模式支持DIN8外部触发。当DIN8出现上升沿/下降沿时,FPGA开始记录。
// 触发检测
reg din8_prev;
wire din8_trigger = (din8_prev == 0 && din8 == 1) ? 1 : 0; // 上升沿
always @(posedge clk) begin
din8_prev <= din8;
if(reg_workState == SRAM_RECORD && reg_trigEnable) begin
if(din8_trigger) begin
sram_start <= 1; // 开始SRAM记录
reg_sramWorkState2 <= 1; // 通知STM32触发已发生
end
end
end
八、QSPI命令解码
8.1 命令码定义
| 命令码 | 功能 | 地址长度 | 数据长度 | 传输方式 |
|---|---|---|---|---|
| 0x80 | 读取单次ADC | 1B | 17B | 4线 |
| 0x81 | 读取FIFO | 2B | 66B | 4线 |
| 0xEB | 读取SRAM | 3B | NB | 4线+6Dummy |
8.2 命令解码逻辑
always @(posedge qspi_clk) begin
if(!qspi_cs_n) begin
case(qspi_cmd)
8'h80: begin
// 单次ADC读取
adc_single_read;
end
8'h81: begin
// FIFO读取(66字节)
fifo_read(addr, 66);
end
8'hEB: begin
// SRAM读取(变长)
sram_read(addr, data_len);
end
endcase
end
end
九、FPGA与STM32的连接
9.1 引脚连接
从D223原理图可见FPGA与STM32的连接:
| STM32引脚 | FPGA引脚 | 功能 |
|---|---|---|
| PA5(SPI1_SCK) | FPGA_BK0 | SPI1时钟 |
| PA6(SPI1_MISO) | FPGA_BK2 | SPI1数据(回读) |
| PA7(SPI1_MOSI) | FPGA_BK0 | SPI1数据(发送) |
| PC4(SPI1_CS) | FPGA_BK1 | SPI1片选 |
| PB2(QSPI_CLK) | FPGA_BK1 | QSPI时钟 |
| PD11(QSPI_CS) | FPGA_BK1 | QSPI片选 |
| PD03(QSPI_D03) | FPGA_BK2 | QSPI四线数据 |
9.2 串阻设计
FPGA与STM32之间的QSPI信号线串联49.9Ω电阻,用于阻抗匹配和抑制反射。
十、总结
D223的FPGA设计实现了:
| 模块 | 功能 | 关键参数 |
|---|---|---|
| AD7606控制器 | 并行总线控制 | CONVST/BUSY/RD/DB[15:0] |
| FIFO缓存 | 4组ADC数据 | 66字节/帧 |
| SPI寄存器 | STM32←→FPGA通信 | A2F/F2A双方向 |
| QSPI接口 | 高速数据读取 | 0x80/0x81/0xEB命令 |
| SRAM控制器 | 外部SRAM读写 | 24位地址/变长数据 |
| 触发控制 | DIN8外部触发 | 上升沿检测 |
| 命令解码 | QSPI命令解析 | 3种命令码 |
FPGA是D223的核心创新——它将AD7606的并行总线时序转换为QSPI高速串行接口,使STM32能以500KSPS采集8通道同步数据,同时保持CPU空闲处理USB通信和DAC输出。从Verilog状态机控制AD7606采样到FIFO缓存和SRAM记录,FPGA内部架构是D223性能优势的技术基础。
下篇预告:《D223 ULPI USB PHY接口深度解析》
更多推荐


所有评论(0)