Quick Start
- 准备开发板:使用安路科技 EG4S20(或高云 GW2A-18)FPGA 开发板,确保板载至少 100MHz 晶振、2 个以太网 PHY(如 KSZ9031)及 RJ45 接口。
- 安装 EDA 工具:下载并安装安路 TangDynasty(TD)5.0 以上版本(或高云 Gowin IDE 1.9.9),申请免费 License。
- 获取开源 EtherCAT IP:从 GitHub 克隆“open-ethercat”项目(基于 Verilog,支持国产 FPGA 移植)。
- 创建工程:在 EDA 中新建工程,选择对应器件型号,添加开源 IP 的 RTL 文件及顶层文件。
- 约束配置:编写 .sdc 文件,约束系统时钟 100MHz、EtherCAT 时钟 25MHz(来自 PHY)、复位信号异步低有效。
- 综合与实现:运行综合(Synthesis),检查无关键警告;执行布局布线(Place & Route),确保时序收敛。
- 生成比特流:生成 .bit 或 .fs 文件,通过 JTAG 下载到开发板。
- 验证通信:使用 TwinCAT 3(PC 端)扫描 EtherCAT 从站,若能识别并从站状态机进入 OP(Operational)模式,则 Quick Start 成功。
验收点:TwinCAT 3 显示从站设备名称与配置一致,PDO 数据可读写。
前置条件与环境
| 项目 | 推荐值 | 说明 | 替代方案 |
|---|---|---|---|
| FPGA 器件 | 安路 EG4S20BG256 (20K LUT) 或高云 GW2A-18 (18K LUT) | — | 紫光同创 Logos-2 (25K LUT);需调整 IP 适配 |
| EDA 版本 | TangDynasty 5.0.3 或 Gowin IDE 1.9.9 | — | Vivado 2024.2(仅用于仿真,不支持国产器件综合) |
| 仿真器 | ModelSim SE-64 2020.4 或 Gowin Simulator | — | QuestaSim、VCS |
| 系统时钟 | 100MHz 晶振(板载) | — | 50MHz 晶振 + PLL 倍频至 100MHz |
| 复位信号 | 异步低有效,按键输入 | — | 上电复位(需 RC 延迟) |
| 以太网 PHY | KSZ9031RNX(千兆,支持 100Mbps 模式) | — | RTL8211、DP83822(需调整管理接口时序) |
| 接口依赖 | MII(4 位数据,25MHz 时钟)或 RMII(2 位数据,50MHz 时钟) | — | RGMII(需 DDR 接口,国产 FPGA 支持有限) |
| 约束文件 | .sdc 格式(TangDynasty)或 .cst(Gowin) | — | 需手动编写,不可自动生成 |
目标与验收标准
- 功能点:实现 EtherCAT 从站控制器(ESC),支持状态机(Init → Pre-OP → Safe-OP → OP)、PDO 数据收发、SM(SyncManager)与 FMMU(Fieldbus Memory Management Unit)配置。
- 性能指标:PDO 周期时间 ≤ 100μs(典型 50μs);帧处理延迟 ≤ 1μs(从 PHY 接收至应用层响应)。
- 资源占用:LUT ≤ 6000(示例,安路 EG4S20 约 30%);Block RAM ≤ 8 个(9K 位每个)。
- Fmax:系统时钟 ≥ 100MHz;EtherCAT 时钟(来自 PHY)≥ 25MHz。
- 验收方式:通过 TwinCAT 3 扫描与配置,读取从站设备描述(ESI 文件),运行 1 小时无通信错误(CRC 错误计数为 0)。
实施步骤
阶段一:工程结构搭建
- 创建顶层模块 top_ethercat_slave,例化开源 ESC 核、PHY 接口、应用接口(如 SPI 或 GPIO)。
- 目录结构:rtl/(RTL 源码)、sim/(仿真脚本与 testbench)、constr/(约束文件)、ip/(PLL、DPRAM 等 IP 核)。
- 在 EDA 中设置顶层模块,添加所有 RTL 文件,排除仿真专用文件。
阶段二:关键模块实现
以下代码为开源 ESC 核的顶层例化示例(安路 EG4S20 适配)。
module top_ethercat_slave (
input wire clk_100m, // 100MHz 系统时钟
input wire rst_n, // 异步复位,低有效
// MII 接口
input wire mii_rx_clk, // PHY 接收时钟 25MHz
input wire [3:0] mii_rxd, // 4 位接收数据
input wire mii_rx_dv, // 接收数据有效
output wire mii_tx_clk, // PHY 发送时钟 25MHz
output wire [3:0] mii_txd, // 4 位发送数据
output wire mii_tx_en, // 发送使能
// 应用层接口(SPI 从机)
input wire spi_cs_n,
input wire spi_sclk,
input wire spi_mosi,
output wire spi_miso
);
// 内部信号
wire esc_rst_n;
wire [15:0] esc_din, esc_dout;
wire esc_wren;
// 例化 ESC 核
esc_core u_esc (
.clk_i (clk_100m),
.rst_n_i (esc_rst_n),
.mii_rx_clk_i (mii_rx_clk),
.mii_rxd_i (mii_rxd),
.mii_rx_dv_i (mii_rx_dv),
.mii_tx_clk_o (mii_tx_clk),
.mii_txd_o (mii_txd),
.mii_tx_en_o (mii_tx_en),
.app_dout_o (esc_dout),
.app_din_i (esc_din),
.app_wren_i (esc_wren)
);
// 复位同步器
rst_sync u_rst_sync (
.clk_i (clk_100m),
.rst_n_i (rst_n),
.rst_n_o (esc_rst_n)
);
// 应用层接口(SPI 从机)
spi_slave u_spi (
.clk_i (clk_100m),
.rst_n_i (esc_rst_n),
.spi_cs_n_i (spi_cs_n),
.spi_sclk_i (spi_sclk),
.spi_mosi_i (spi_mosi),
.spi_miso_o (spi_miso),
.app_dout_i (esc_dout),
.app_din_o (esc_din),
.app_wren_o (esc_wren)
);
endmodule逐行说明
- 第 1–2 行:模块声明,定义输入输出端口。clk_100m 为系统时钟,rst_n 为异步复位,低有效。
- 第 3–8 行:MII 接口信号。mii_rx_clk 来自 PHY,频率 25MHz(100Mbps 模式);mii_rxd 为 4 位数据总线;mii_rx_dv 指示数据有效。发送端类似。
- 第 9–12 行:SPI 从机接口,用于主站(如 MCU)访问 ESC 寄存器。
- 第 14–17 行:内部信号声明。esc_din/esc_dout 为应用层与 ESC 核的数据总线,esc_wren 为写使能。
- 第 18–27 行:例化开源 ESC 核。注意其时钟域:clk_i 为系统时钟(100MHz),用于内部状态机;MII 时钟来自 PHY,用于帧接收/发送。
- 第 28–32 行:复位同步器,将异步复位同步到系统时钟域,避免亚稳态。
- 第 33–42 行:SPI 从机接口,将主站读写请求转换为 ESC 核的应用接口时序。
阶段三:时序与约束
# 系统时钟约束
create_clock -name clk_100m -period 10.000 [get_ports clk_100m]
# MII 接收时钟(来自 PHY)
create_clock -name mii_rx_clk -period 40.000 [get_ports mii_rx_clk]
# 异步复位(false path)
set_false_path -from [get_ports rst_n] -to [all_registers]
# 跨时钟域路径(MII 时钟域到系统时钟域)
set_clock_groups -asynchronous -group {clk_100m} -group {mii_rx_clk}逐行说明
- 第 1 行:约束系统时钟 100MHz,周期 10ns。
- 第 2 行:约束 MII 接收时钟 25MHz,周期 40ns。注意该时钟由 PHY 提供,非 FPGA 内部生成。
- 第 3 行:将复位端口设为 false path,因为复位信号不参与时序分析。
- 第 4 行:声明两个时钟域为异步关系,避免工具分析跨时钟域路径(这些路径已通过同步器处理)。
阶段四:验证
- 编写 testbench:例化顶层模块,模拟 PHY 行为(发送 EtherCAT 帧:前导码、帧头、数据、FCS)。
- 仿真检查:使用 ModelSim 运行 1ms 仿真,观察 ESC 状态机是否从 Init 进入 Pre-OP(写入 AL 控制寄存器 0x0120)。
- 常见坑:仿真中未初始化 PHY 管理接口(MDIO),导致链路状态错误。需在 testbench 中模拟 MDIO 通信。
阶段五:上板调试
- 使用 ILA(集成逻辑分析仪)或示波器观察 MII 接口信号:mii_rx_dv 应在帧期间为高,mii_rxd 数据稳定。
- 在 TwinCAT 3 中创建从站设备描述(ESI 文件),配置 PDO 映射。
- 若扫描不到设备,检查 PHY 地址(通常为 0x01)与 MDIO 时序。
- 常见坑:国产 FPGA 的 PLL 输出抖动较大,可能导致 MII 时钟质量下降。建议在 PHY 侧使用内部时钟输出(如 KSZ9031 的 25MHz 输出)作为参考。
原理与设计说明
为什么选择开源 ESC 核而非商业 IP? 商业 EtherCAT IP(如 Beckhoff、IXXAT)通常需要授权费,且对国产 FPGA 适配不足。开源核(如 open-ethercat)基于 Verilog,可自由修改,但需要自行处理 PHY 适配与时序收敛。
关键 trade-off:资源 vs Fmax 开源 ESC 核通常采用单周期状态机实现帧处理,逻辑深度大,Fmax 受限(示例中 100MHz 系统时钟下约 60MHz)。若需更高 Fmax(如 200MHz),可引入流水线,但 LUT 增加 20%。对于工业以太网应用,100MHz 足够满足 100μs 周期要求,因此优先资源优化。
吞吐 vs 延迟 EtherCAT 采用“集总帧”技术,每个从站处理延迟需 < 1μs 以保证整体确定性。开源核通过直通(cut-through)方式处理帧:接收前 2 字节后即开始转发,延迟约 0.5μs。代价是需额外逻辑缓存帧头。
易用性 vs 可移植性 国产 FPGA 的 EDA 工具对 SystemVerilog 支持有限(如 Gowin IDE 不支持 interface)。因此推荐使用 Verilog-2001 编写代码,避免高级语法,确保跨平台兼容。
验证与结果
| 指标 | 测量值(示例) | 测量条件 |
|---|---|---|
| Fmax(系统时钟) | 105 MHz | 安路 EG4S20,TD 5.0.3,时序约束 10ns |
| LUT 资源 | 5,820 (29%) | 开源 ESC 核 + SPI 从机,无 PLL |
| Block RAM | 6 个 (9K 位) | 用于帧缓存与寄存器 |
| PDO 周期时间 | 48 μs | TwinCAT 3 主站,100Mbps 链路 |
| 帧处理延迟 | 0.6 μs | 示波器测量 MII 输入到输出 |
说明:以上数据基于典型配置,以实际工程与数据手册为准。资源占用随 PDO 大小变化(每增加 8 字节约多 100 LUT)。
故障排查
- 现象:TwinCAT 扫描不到从站。原因:PHY 地址或 MDIO 时序错误。检查点:用示波器测量 MDIO 信号,确认地址匹配。修复:修改顶层参数 PHY_ADDR 为 0x01。
- 现象:从站状态机卡在 Init。原因:AL 控制寄存器未正确写入。检查点:仿真中检查 SPI 写入时序。修复:确保 SPI 时钟极性(CPOL=0, CPHA=0)与主站匹配。
- 现象:PDO 数据错误。原因:FMMU 配置错误或数据对齐问题。检查点:读取从站寄存器 0x0600-0x06FF(FMMU 配置)。修复:重新生成 ESI 文件,确保 PDO 映射与硬件一致。
- 现象:链路指示灯不亮。原因:PHY 未初始化或复位未释放。检查点:测量 PHY 复位引脚电平。修复:增加上电延迟(至少 10ms)。
- 现象:综合后时序不收敛。原因:跨时钟域路径未约束。检查点:查看时序报告,检查 setup/hold 违例。修复:添加 set_clock_groups 约束。
- 现象:仿真中帧 FCS 错误。原因:CRC 计算模块时序错误。检查点:对比开源核 CRC 输出与标准算法。修复:检查 CRC 多项式(0x04C11DB7)是否匹配。
- 现象:上板后偶尔通信中断。原因:电源噪声导致 PLL 失锁。检查点:用示波器测量 FPGA 核心电压(1.2V)。修复:增加去耦电容(10μF + 0.1μF)。
- 现象:TwinCAT 显示“EtherCAT 错误:帧丢失”。原因:PHY 协商模式不匹配。检查点:检查 PHY 寄存器 0x00(BMCR)。修复:强制设置 100Mbps 全双工。
扩展与下一步
- 参数化:将 ESC 核的 PDO 大小、SM 数量改为参数,通过 Verilog 的 parameter 实现,适应不同应用。
- 带宽提升:升级至千兆 EtherCAT(需 RGMII 接口),国产 FPGA(如安路 PH1A)支持 DDR 接口,可尝试。
- 跨平台:将代码移植至紫光同创 Logos-2 或高云 GW5A,注意 EDA 工具差异(如约束语法)。
- 加入断言:在仿真中插入 SystemVerilog 断言(SVA),自动检查状态机转换与数据完整性。
- 形式验证:使用开源工具(如 SymbiYosys)对 ESC 核进行形式验证,确保无死锁或状态机错误。
参考与信息来源
- EtherCAT 协议规范(ETG.1000.1.0.2)
- open-ethercat 开源项目:https://github.com/ethercat/open-ethercat
- 安路科技 EG4S20 数据手册(Rev 1.2)
- 高云 GW2A-18 用户指南(UG286-1.9.9)
- KSZ9031RNX 数据手册(Microchip)
技术附录
术语表
- ESC:EtherCAT Slave Controller,从站控制器。
- PDO:Process Data Object,过程数据对象。
- FMMU:Fieldbus Memory Management Unit,现场总线内存管理单元。
- SM:SyncManager,同步管理器。
- MII:Media Independent Interface,媒体独立接口。
检查清单
- [ ] PHY 地址配置正确(通常 0x01)
- [ ] MDIO 时序符合标准(时钟频率 ≤ 2.5MHz)
- [ ] 约束文件包含所有时钟与异步组
- [ ] 仿真通过状态机转换(Init → Pre-OP)
- [ ] 上板后 TwinCAT 扫描成功
关键约束速查
# 安路 TangDynasty .sdc 示例
create_clock -name clk_100m -period 10.000 [get_ports clk_100m]
create_clock -name mii_rx_clk -period 40.000 [get_ports mii_rx_clk]
set_false_path -from [get_ports rst_n] -to [all_registers]
set_clock_groups -asynchronous -group {clk_100m} -group {mii_rx_clk}


