本文介绍一套完全运行在国产安陆FPGA上的高速数据采集与网络传输方案。系统使用EG4S20BG256实现RGMII千兆以太网、ARP/IPv4/ICMP/TCP/UDP协议处理,采集AD7606C的8通道16位同步数据,先写入片内64 Mb SDRAM,再通过TCP连续上传到PC。系统还支持UDP设备发现、跨网段网络参数配置、24LC64掉电保存、ADC状态监控、1 kSPS/1 MSPS采样率切换,以及Python数字示波器和MAT录波。
一、项目背景
高速多通道数据采集常见的实现方式,是"ADC + FPGA + 高速接口 + PC软件"。真正有难度的部分并不是把ADC数据读出来,而是同时解决下面几个问题:
- 8通道、16位、1 MSPS数据不能丢失;
- ADC采样时钟域与千兆以太网125 MHz时钟域不同;
- PC的TCP接收会有短时停顿,需要大容量缓存吸收抖动;
- FPGA需要支持开始、暂停、采样率设置和状态回读;
- 板卡出厂或换网段后,必须能够自动发现并修改IP;
- 网络参数要掉电保存,配置损坏时又必须能够恢复默认值;
- 上位机既要实时显示波形,又要在1 MSPS下保持界面流畅并支持录波。
本方案的重点是:不使用外部MCU或嵌入式Linux,在安陆EG4S20 FPGA内部直接实现千兆以太网TCP/IP数据通路。
实际运行时,AD7606C的8通道1 MSPS数据流稳定达到约192.2 Mbit/s;在不受ADC数据率限制的FPGA全速发送测试中,PC端TCP测速可达到约400 Mbit/s。

图1 AD7606C以1 MSPS运行,TCP实时流量192.2 Mbit/s,扫描序号跳变、估算丢失和FPGA丢弃均为0
二、硬件平台介绍
实验平台由安陆EG4S20 FPGA开发板、AD7606C采集板和PC组成。AD7606C采集板通过数据及控制线连接FPGA,FPGA的千兆以太网口通过网线连接PC,组成"模拟量采集---SDRAM缓存---TCP传输---上位机显示"的完整数据链路。

图2 实验硬件实物:安陆EG4S20 FPGA开发板、AD7606C采集板及千兆以太网连接
2.1 国产安陆EG4S20 FPGA
本项目使用的目标器件为 EG4S20BG256,开发工具为安陆Tang Dynasty(TD)Release 2026.1 SP2。
EG4S20适合本项目的关键原因是片内资源比较均衡:
- 国产FPGA,55 nm低功耗工艺;
- BGA256封装,能够满足RGMII、ADC串行接口、I2C和调试IO需求;
- 数据手册标称等效23520个4输入查找表;
- TD工具资源模型提供19600个LUT和19600个寄存器;
- 内嵌 2M × 32 bit SDR SDRAM,容量64 Mb,也就是8 MiB;
- 片内SDRAM最高工作频率200 MHz,理论最大读写带宽6.4 Gbit/s;
- 具有BRAM、FIFO硬核、PLL、全局时钟和DSP资源。
最关键的是这片2M × 32 bit片内SDRAM。它不占用普通BRAM资源,也不需要外接DDR芯片,非常适合做高速ADC和TCP之间的弹性缓存。
2.2 AD7606C-16同步采样ADC
AD7606C-16是一款8通道、16位、全通道同步采样ADC,所有通道最高均可达到1 MSPS。它内部集成输入箝位保护、可编程增益放大器、低通滤波器、SAR ADC、参考源和数字滤波器,比较适合电力监测、保护装置、多相电机控制和通用数据采集。
与本项目直接相关的特性包括:
- 8通道同时采样,不需要在通道间轮询;
- 16位分辨率,全通道1 MSPS;
- 每通道模拟输入范围可配置;
- 支持单端和真差分输入;
- 支持25 kHz和220 kHz两档带宽;
- 支持最高256倍过采样;
- 支持并行和串行数字接口;
- 软件模式下可以读写寄存器并进行错误诊断。
当前工程把8个通道全部配置为 ±10 V双极性差分输入 ,量程配置为RANGE_CHx=0x9。寄存器0x03~0x06的期望回读值均为0x99。采样率支持1 kSPS和1 MSPS两档,默认选择1 MSPS,但上电后保持暂停,等待PC发送开始命令。
三、系统总体架构
系统包含4条主线:ADC采集、SDRAM缓存、TCP高速上传和UDP网络管理。
#mermaid-svg-cwtLRdLos6qfD5vo{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-cwtLRdLos6qfD5vo .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-cwtLRdLos6qfD5vo .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-cwtLRdLos6qfD5vo .error-icon{fill:#552222;}#mermaid-svg-cwtLRdLos6qfD5vo .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-cwtLRdLos6qfD5vo .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-cwtLRdLos6qfD5vo .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-cwtLRdLos6qfD5vo .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-cwtLRdLos6qfD5vo .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-cwtLRdLos6qfD5vo .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-cwtLRdLos6qfD5vo .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-cwtLRdLos6qfD5vo .marker{fill:#333333;stroke:#333333;}#mermaid-svg-cwtLRdLos6qfD5vo .marker.cross{stroke:#333333;}#mermaid-svg-cwtLRdLos6qfD5vo svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-cwtLRdLos6qfD5vo p{margin:0;}#mermaid-svg-cwtLRdLos6qfD5vo .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-cwtLRdLos6qfD5vo .cluster-label text{fill:#333;}#mermaid-svg-cwtLRdLos6qfD5vo .cluster-label span{color:#333;}#mermaid-svg-cwtLRdLos6qfD5vo .cluster-label span p{background-color:transparent;}#mermaid-svg-cwtLRdLos6qfD5vo .label text,#mermaid-svg-cwtLRdLos6qfD5vo span{fill:#333;color:#333;}#mermaid-svg-cwtLRdLos6qfD5vo .node rect,#mermaid-svg-cwtLRdLos6qfD5vo .node circle,#mermaid-svg-cwtLRdLos6qfD5vo .node ellipse,#mermaid-svg-cwtLRdLos6qfD5vo .node polygon,#mermaid-svg-cwtLRdLos6qfD5vo .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-cwtLRdLos6qfD5vo .rough-node .label text,#mermaid-svg-cwtLRdLos6qfD5vo .node .label text,#mermaid-svg-cwtLRdLos6qfD5vo .image-shape .label,#mermaid-svg-cwtLRdLos6qfD5vo .icon-shape .label{text-anchor:middle;}#mermaid-svg-cwtLRdLos6qfD5vo .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-cwtLRdLos6qfD5vo .rough-node .label,#mermaid-svg-cwtLRdLos6qfD5vo .node .label,#mermaid-svg-cwtLRdLos6qfD5vo .image-shape .label,#mermaid-svg-cwtLRdLos6qfD5vo .icon-shape .label{text-align:center;}#mermaid-svg-cwtLRdLos6qfD5vo .node.clickable{cursor:pointer;}#mermaid-svg-cwtLRdLos6qfD5vo .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-cwtLRdLos6qfD5vo .arrowheadPath{fill:#333333;}#mermaid-svg-cwtLRdLos6qfD5vo .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-cwtLRdLos6qfD5vo .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-cwtLRdLos6qfD5vo .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-cwtLRdLos6qfD5vo .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-cwtLRdLos6qfD5vo .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-cwtLRdLos6qfD5vo .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-cwtLRdLos6qfD5vo .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-cwtLRdLos6qfD5vo .cluster text{fill:#333;}#mermaid-svg-cwtLRdLos6qfD5vo .cluster span{color:#333;}#mermaid-svg-cwtLRdLos6qfD5vo div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-cwtLRdLos6qfD5vo .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-cwtLRdLos6qfD5vo rect.text{fill:none;stroke-width:0;}#mermaid-svg-cwtLRdLos6qfD5vo .icon-shape,#mermaid-svg-cwtLRdLos6qfD5vo .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-cwtLRdLos6qfD5vo .icon-shape p,#mermaid-svg-cwtLRdLos6qfD5vo .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-cwtLRdLos6qfD5vo .icon-shape .label rect,#mermaid-svg-cwtLRdLos6qfD5vo .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-cwtLRdLos6qfD5vo .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-cwtLRdLos6qfD5vo .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-cwtLRdLos6qfD5vo :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 8×16 bit/scan
UDP/8000
AD7606C-16
8通道同步采样
ADC控制器
50 MHz时钟域
扫描打包
序号+8通道
写侧异步FIFO
EG4S20片内SDRAM
2M×32 bit环形队列
读侧异步FIFO
TCP ADC端点
125 MHz时钟域
COM5402硬件TCP/IP协议栈
GMII MAC
RGMII DDR接口
千兆以太网PHY
Python上位机
发现与网络配置
24LC64 EEPROM
CRC16保护
系统主要使用三个时钟域:
| 时钟域 | 频率 | 主要功能 |
|---|---|---|
| 板载系统时钟 | 50 MHz | AD7606C控制、I2C、SDRAM控制和初始化 |
| 以太网协议时钟 | 125 MHz | TCP/IP协议栈、TCP应用接口和发送调度 |
| RGMII接收时钟 | 125 MHz | PHY接收数据的DDR采样 |
ADC数据不会直接跨到125 MHz网络域,而是通过写侧异步FIFO、片内SDRAM和读侧异步FIFO完成跨时钟域传输。
四、在安陆FPGA上实现千兆以太网TCP/IP
4.1 RGMII、GMII和硬件协议栈
开发板通过RGMII连接千兆以太网PHY。RGMII在125 MHz时钟的上升沿和下降沿分别传输4 bit数据,因此每个时钟周期传输1字节,对应1 Gbit/s物理链路。
FPGA内部的数据路径为:
text
RGMII DDR IO
⇅
GMII 8-bit接口
⇅
以太网MAC
⇅
ARP / IPv4 / ICMP / UDP / TCP
⇅
ADC TCP应用层 + UDP网络配置应用层
COM5402协议栈原本以可综合VHDL实现,本项目完成了安陆器件的BRAM兼容、时钟、RGMII DDR IO和顶层接口移植。协议处理全部在FPGA逻辑中完成,因此没有操作系统调度,也没有软核CPU参与高速数据搬运。
调试RGMII时有一个很关键的经验:能看到RX_CLK和RX_DV跳变,不代表接收数据一定正确。 初期ChipWatcher能够看到PHY在输出数据,但MAC收到的都是错误帧。恢复参考工程的125 MHz、0°外部反馈接收PLL后,RGMII DDR采样相位才稳定,随后ARP和Ping均恢复正常。
4.2 TCP发送缓存和BRAM流水线
为了提高TCP持续吞吐率,工程对发送路径做了两项重点优化:
- TCP接收弹性缓存采用2个2 KiB块,共4 KiB;
- TCP发送弹性缓存扩展为8个2 KiB块,共16 KiB。
发送缓存使用分Bank BRAM组织,并对BRAM读地址、Bank选择和数据有效信号做流水线。这样可以增加未确认TCP数据的在途容量,同时避免把大规模地址译码直接放到125 MHz发送关键路径上。
发送模块遵循CTS/VALID式流控:协议栈允许发送时,ADC端点连续提供数据;协议栈暂时不能接收时,数据保留在SDRAM/FIFO中,不会因为PC短时调度而立刻丢失。
在专用全速数据发生器测试中,FPGA持续填充TCP发送缓存,PC端实测吞吐可达到约 400 Mbit/s(约50 MB/s)。这个结果说明国产EG4S20上的硬件TCP/IP协议栈具有足够的数据通路余量。
需要特别说明:400 Mbit/s是协议栈的全速发送能力;当前真实AD7606C应用由采样记录格式决定,实际TCP负载为192 Mbit/s,两者不是同一个测试条件。
五、AD7606C采集、SDRAM缓存和TCP上传
5.1 ADC上电配置与回读校验
AD7606C控制器运行在独立的50 MHz时钟域,上电后执行:
- 电源稳定和硬件复位时序;
- 通过SPI写寄存器0x02~0x08;
- 逐个读回并与期望值比较;
- 校验全部通过后才允许启动转换;
- 校验失败则保持停止,并把错误寄存器、期望值和读回值上传到PC。
这样可以避免"ADC引脚有数据,但量程、差分模式或带宽配置并未真正生效"的隐蔽问题。
5.2 开始、暂停和采样率设置
PC通过固定12字节的ADCC命令控制ADC:
| 命令 | 功能 | 参数 |
|---|---|---|
| 1 | START | 开始采样 |
| 2 | PAUSE | 暂停产生新扫描 |
| 3 | SET_RATE | 1000或1000000 |
| 4 | STATUS | 查询运行状态和统计计数 |
| 5 | ADC_INFO | 查询SPI配置和回读校验信息 |
暂停命令只停止新的ADC转换;已经进入SDRAM和FIFO的数据仍会继续发送,保证TCP字节流和记录边界完整。
5.3 SDRAM环形FIFO
每次8通道扫描先在FPGA内部整理成5个32位字:
text
Word 0:32位扫描序号
Word 1:CH1 + CH2
Word 2:CH3 + CH4
Word 3:CH5 + CH6
Word 4:CH7 + CH8
因此每次扫描在SDRAM中占20字节。SDRAM使用独立读写指针构成环形队列:
- 写地址和读地址分别递增;
- 到达末尾后自动回到地址0;
buffered_words记录已写入但尚未读出的32位字数;- 只有累积完整32-word突发后才发起SDRAM操作;
- 满时不覆盖旧数据,而是丢弃新的完整扫描并增加
dropped_scans。
SDRAM有效流区域为2097120个32位字,约8 MiB,可保存约419424次扫描。在1 MSPS下相当于约0.419秒缓存,足以吸收PC和TCP协议栈的毫秒级抖动。
SDRAM突发长度选择32 word。这一长度能够整除256-word行长度,避免突发访问跨行后产生地址别名,同时也能摊薄ACTIVATE、READ/WRITE和PRECHARGE等命令开销。
5.4 TCP数据记录
FPGA输出的ADC记录固定为24字节:
| 字节 | 内容 |
|---|---|
| 0~3 | Magic:ADCD |
| 4~7 | 32位扫描序号,大端序 |
| 8~23 | CH1~CH8,每通道16位有符号数,大端序 |
1 MSPS时的网络负载为:
text
24 byte/scan × 1,000,000 scan/s
= 24 MB/s
= 192 Mbit/s
其中真正的ADC数据为16 MB/s,ADCD标识和扫描序号增加8 MB/s。扫描序号非常有价值:TCP能够保证字节可靠有序,但如果FPGA因SDRAM满而主动丢弃扫描,PC仍能通过序号跳变准确判断丢失数量。
5.5 状态监控
除了ADCD数据,TCP连接中还会插入两类固定24字节状态记录:
ADCS:命令应答、运行/暂停、采样率、已产生扫描数、已发送扫描数、丢弃数和缓存满标志;ADCI:ADC初始化状态、SPI校验结果、采样周期、量程、带宽、过采样配置、错误寄存器、期望值和读回值。
三种记录长度都固定为24字节,PC可以先按固定长度分帧,再根据前4字节Magic分派处理,接收效率较高。
六、UDP设备发现和网络参数配置
对于没有显示屏和键盘的采集板,固定IP很容易带来部署问题。因此工程在UDP端口8000实现了板卡发现和网络配置协议。
6.1 广播搜索板卡
PC向255.255.255.255:8000或子网广播地址发送ACFG发现请求。FPGA回复:
- MAC地址;
- IPv4地址;
- 网关;
- 子网掩码;
- TCP监听端口;
- 参数来自EEPROM还是Verilog默认值;
- 当前状态码。
上位机可以遍历PC的全部IPv4网卡分别发送广播,解决Windows多网卡环境下有限广播只走默认路由的问题。

图3 上位机通过UDP广播发现FPGA,并显示EEPROM中的MAC、IP、网关、掩码和TCP端口
6.2 按当前MAC跨网段修改参数
如果PC已经切换到10网段,而FPGA仍保存192.168.4.x,普通单播配置很可能无法到达。为此增加了"按当前MAC广播设置"命令:
- 请求中携带板卡当前MAC;
- 同一广播域内只有MAC匹配的FPGA处理请求;
- 请求同时携带新MAC、新IP、网关、子网掩码和TCP端口;
- FPGA保存并回读成功后才返回状态0;
- 成功回复发出后再切换到新的网络参数。

图4 通过当前MAC精确选择板卡,防止广播域内其他设备被误配置
6.3 24LC64掉电保存和CRC16
网络参数保存在24LC64 EEPROM中,其A0、A1、A2全部接地,I2C 7位地址为0x50。
EEPROM记录保存:
- Magic、版本和长度;
- MAC地址;
- IP地址;
- 网关;
- 子网掩码;
- TCP监听端口;
- CRC16-CCITT;
- 固定结束标志。
UDP应用报文本身不重复增加CRC16,依赖以太网FCS、IPv4校验和和UDP校验机制;只有EEPROM内部记录使用CRC16。上电读取时,如果Magic、字段合法性、结束标志或CRC16任一检查失败,FPGA自动使用Verilog中的默认网络参数,避免配置损坏后板卡彻底失联。
写入流程采用"页写入 -> 等待写周期 -> 全记录回读 -> CRC和字段比较 -> 返回结果",不是发出I2C写命令后立即报告成功。

图5 只有EEPROM写入、回读和校验全部通过后,上位机才提示设置成功
七、Python上位机功能
上位机使用Python、Tkinter、NumPy和SciPy开发,并已打包为单文件Windows EXE。软件将TCP采集、UDP配置、实时显示和MAT录波集中在一个界面中。
主要功能包括:
- TCP连接/断开单按钮切换;
- ADC开始/暂停单按钮切换;
- 1 kSPS和1 MSPS采样率选择;
- 读取ADC运行状态和SPI配置校验结果;
- 8通道共用±10 V坐标系叠加显示;
- CH1~CH8独立显示开关;
- 1 ms~1000 ms全屏时基;
- 显示扫描数、序号跳变、估算丢失、FPGA丢弃、吞吐率和刷新率;
- UDP广播搜索和板卡网络参数配置;
- 高速MAT录波,保存通道数据、扫描序号、采样率和ADC配置。
GUI接收线程使用NumPy结构化数组批量解析TCP数据,显示缓冲采用固定容量环形数组。绘图时根据画布像素宽度做min/max降采样,而不是把1 MSPS的每个点都交给Tkinter绘制,因此界面能够保持约25~30 FPS刷新而不阻塞TCP接收。
录波线程先把ADC数据和扫描序号连续写入临时二进制文件,停止后再生成MAT v5文件。这样可以避免长时间录波时把全部数据堆在内存中。截图中的录波包含1838566×8个int16采样值,录波队列丢失为0。

图6 MATLAB读取的录波变量,包括8通道ADC数据、扫描序号、采样率、量程和开始时间
除GUI外,还提供命令行校验工具,可执行定时采集并检查:
- 24字节记录是否对齐;
- 扫描序号是否连续;
- 估算丢失扫描数;
- FPGA是否报告缓存满或主动丢弃;
- TCP实际吞吐率。
八、FPGA资源用量
以下数据来自TD 2026.1 SP2对EG4S20BG256完成布局布线后的报告:
| 资源 | 已用 | 总量 | 利用率 |
|---|---|---|---|
| LUT | 10028 | 19600 | 51.16% |
| 寄存器 | 6640 | 19600 | 33.88% |
| 9K BRAM/FIFO | 32 | 64 | 50.00% |
| 其中普通BRAM9K | 28 | - | - |
| 其中FIFO9K | 4 | - | - |
| BRAM32K | 0 | 16 | 0% |
| DSP | 0 | 29 | 0% |
| IO PAD | 41 | 188 | 21.81% |
| PLL | 1 | 4 | 25.00% |
| 全局时钟 | 2 | 16 | 12.50% |
片内2M×32 bit SDRAM属于独立硬核,不计入上表的32个BRAM。当前逻辑资源约使用一半,寄存器和IO仍有较大余量;BRAM主要消耗在TCP收发弹性缓存、协议栈缓存和跨时钟FIFO。
工程没有使用DSP,后续仍可加入数字滤波、抽取、FFT或触发算法。但如果继续增加TCP连接数量或显著扩大收发窗口,BRAM会比LUT更早成为限制资源。
九、时序分析
最终静态时序分析覆盖Slow和Fast工艺角,布局布线后的主要结果如下:
| 项目 | 结果 |
|---|---|
| STA覆盖率 | 99.90% |
| 最差建立时间余量SWNS | +0.102 ns |
| 建立时间总负余量STNS | 0.000 ns |
| 最差保持时间余量HWNS | +0.011 ns |
| 保持时间总负余量HTNS | 0.000 ns |
| 违例端点 | 0 |
主要时钟分析:
| 时钟 | 约束频率 | 报告Fmax | 建立余量 |
|---|---|---|---|
| TCP/IP与RGMII内部时钟 | 125 MHz | 126.614 MHz | +0.102 ns |
| 50 MHz系统时钟 | 50 MHz | 52.296 MHz | +0.439 ns |
| SDRAM控制时钟 | 50 MHz | 115.101 MHz | +5.656 ns |
125 MHz网络域是当前最紧的时序路径,余量不算大,但Slow/Fast角均为正且没有违例。优化TCP发送缓存时,如果把Bank译码、地址计算和数据选择组合在同一个周期,125 MHz路径很容易失败;加入BRAM地址/Bank/VALID流水线后,关键路径才稳定收敛。
这里还需要注意:时序报告中的Fmax是当前网表和约束下的静态分析结果,不等于以太网吞吐率。吞吐率还取决于TCP窗口、确认延迟、PC接收效率、包头开销和应用层是否持续供数。
十、实测结果
10.1 TCP协议栈全速发送
在FPGA内部使用专用数据发生器持续供数,绕过ADC的192 Mbit/s数据率限制后:
- RGMII链路协商为1 Gbit/s;
- FPGA连续填充16 KiB TCP TX缓存;
- PC端TCP测速约400 Mbit/s;
- 对应应用层接收速度约50 MB/s。
这说明协议栈和MAC数据通路能够覆盖当前ADC应用,并保留约2倍吞吐余量。
10.2 真实AD7606C采集
1 MSPS、8通道、24字节/扫描条件下:
- 实测TCP流量约192.0~192.2 Mbit/s;
- 连续数百万次扫描无序号跳变;
- 估算丢失为0;
- FPGA主动丢弃为0;
- SPI配置和回读校验通过;
- 上位机保持约25 FPS显示。
1 kSPS和1 MSPS可以在同一TCP控制协议下切换。1 kSPS适合观察低速或长时间信号,1 MSPS用于满速采集。
10.3 UDP和EEPROM
- 单播发现和广播发现均可返回完整网络参数;
- 多网卡PC可以从所有IPv4接口发起搜索;
- 按当前MAC可以跨IPv4网段广播设置;
- EEPROM写入后执行回读验证;
- FPGA重新配置或重新上电后仍能从24LC64恢复参数;
- EEPROM记录CRC错误时自动回退Verilog默认参数。
十一、总结
本项目验证了在国产安陆EG4S20 FPGA上实现高性能千兆以太网数据采集系统的可行性:
- TCP/IP、UDP、MAC和RGMII全部在FPGA逻辑中运行;
- AD7606C实现8通道16位1 MSPS同步采集;
- 片内2M×32 bit SDRAM构成约8 MiB环形FIFO;
- 真实ADC数据通过TCP稳定传输约192.2 Mbit/s;
- FPGA全速TCP发送时,PC端测速可达到约400 Mbit/s;
- 支持ADC开始、暂停、1 kSPS/1 MSPS切换和SPI状态监控;
- 支持UDP设备发现、跨网段按MAC配置和24LC64掉电保存;
- Python上位机支持8通道示波器、完整性统计和MAT高速录波;
- 当前资源约占一半,125 MHz网络域完成布局布线并实现零时序违例。
对工业采集、在线监测、电力电子和多通道仪器而言,这种"国产FPGA + 高速同步ADC + 硬件TCP/IP + PC软件"的结构具有较好的实时性、可控性和扩展空间。后续可以继续加入硬件触发、预触发缓存、数字滤波、抽取、FFT、多板同步和USB 3.0/万兆网络等功能。