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/SRAMQSPI(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)
1MB1,048,576B~65,000组130ms
8MB8,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读取单次ADC1B17B4线
0x81读取FIFO2B66B4线
0xEB读取SRAM3BNB4线+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_BK0SPI1时钟
PA6(SPI1_MISO)FPGA_BK2SPI1数据(回读)
PA7(SPI1_MOSI)FPGA_BK0SPI1数据(发送)
PC4(SPI1_CS)FPGA_BK1SPI1片选
PB2(QSPI_CLK)FPGA_BK1QSPI时钟
PD11(QSPI_CS)FPGA_BK1QSPI片选
PD03(QSPI_D03)FPGA_BK2QSPI四线数据

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接口深度解析》

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐