手把手教你用ZYNQ7035开发板实现双网口:一个PS直连,一个PL转接GMII
ZYNQ7035双网口实战:从硬件配置到裸机网络架构设计
在工业控制、边缘计算等领域,双网口设计已成为嵌入式系统的标配需求。ZYNQ系列芯片凭借其独特的PS+PL架构,为开发者提供了灵活的网络接口扩展方案。本文将基于黑金ZYNQ7035开发板,带你从零构建一个PS直连与PL转接GMII的双网口系统。
1. 硬件平台选型与设计思路
黑金ZYNQ7035开发板搭载XC7Z035-2FFG676芯片,这款芯片的PS部分内置两个千兆以太网控制器(ENET0/ENET1),为双网口设计提供了硬件基础。传统方案通常只利用PS的MIO接口连接RGMII PHY,这种设计存在两个明显局限:
- 接口类型受限(仅支持RGMII)
- 无法充分利用PL侧的灵活性
我们的创新方案采用混合架构:
- 网口1:PS端ENET0通过MIO直连RGMII PHY
- 网口2:PS端ENET1通过EMIO引出至PL,经GMII to RGMII IP核转换后连接第二个PHY
这种设计带来了三个显著优势:
- 接口兼容性:PL侧可支持GMII、SGMII等多种PHY
- 布局灵活性:PHY位置不再受PS引脚限制
- 性能可扩展:PL逻辑可加入数据预处理功能
2. Vivado工程配置详解
2.1 ZYNQ IP核关键配置
创建Vivado工程后,首先需要对ZYNQ7 Processing System IP进行正确配置:
# 基础时钟配置 set_property CONFIG.PCW_FPGA0_PERIPHERAL_FREQMHZ {100} [get_bd_cells processing_system7_0] set_property CONFIG.PCW_USE_M_AXI_GP0 {1} [get_bd_cells processing_system7_0] # 以太网控制器配置 set_property CONFIG.PCW_ENET0_PERIPHERAL_ENABLE {1} [get_bd_cells processing_system7_0] set_property CONFIG.PCW_ENET0_GRP_MDIO_ENABLE {1} [get_bd_cells processing_system7_0] set_property CONFIG.PCW_ENET1_PERIPHERAL_ENABLE {1} [get_bd_cells processing_system7_0] set_property CONFIG.PCW_ENET1_GRP_MDIO_ENABLE {1} [get_bd_cells processing_system7_0]特别注意以下参数设置:
| 参数项 | 推荐值 | 作用说明 |
|---|---|---|
| PCW_ENET0_ENET0_IO | EMIO | 将ENET0引出到PL |
| PCW_ENET1_ENET1_IO | MIO | ENET1使用PS直连 |
| PCW_FCLK_CLK0_FREQ | 200000000 | GMII IP核参考时钟 |
2.2 GMII to RGMII IP核集成
在IP Catalog中添加GMII to RGMII IP核时,需要特别关注几个关键配置:
- PHY地址设置:必须确保与系统中其他PHY地址不冲突,建议使用8(0x08)
- 时钟域配置:
- 选择"Include Shared Logic in Core"
- 参考时钟设置为200MHz(与FCLK_CLK0一致)
- 复位信号处理:
- 通过Utility Vector Logic将FCLK_RESET0_N反相
- 连接到IP核的resetn输入
// 复位信号处理示例 reset_inverter reset_inst ( .Op1(processing_system7_0_FCLK_RESET0_N), .Res(~processing_system7_0_FCLK_RESET0_N) );3. 时序约束与引脚分配
3.1 关键时序约束
RGMII接口对时序要求严格,必须添加正确的输入延迟约束:
# 创建接收时钟约束 create_clock -period 8.000 -name rgmii_rx_clk [get_ports EMIO_RGMII_rxc] # 设置输入延迟约束 set_input_delay -clock [get_clocks rgmii_rx_clk] -max 2.800 [get_ports {{EMIO_RGMII_rd[*]} EMIO_RGMII_rx_ctl}] set_input_delay -clock [get_clocks rgmii_rx_clk] -min 1.200 [get_ports {{EMIO_RGMII_rd[*]} EMIO_RGMII_rx_ctl}] set_input_delay -clock [get_clocks rgmii_rx_clk] -clock_fall -max -add_delay 2.800 [get_ports {{EMIO_RGMII_rd[*]} EMIO_RGMII_rx_ctl}] set_input_delay -clock [get_clocks rgmii_rx_clk] -clock_fall -min -add_delay 1.200 [get_ports {{EMIO_RGMII_rd[*]} EMIO_RGMII_rx_ctl}]3.2 引脚分配策略
根据黑金开发板的原理图,推荐以下引脚分配方案:
| 信号名称 | 引脚号 | I/O标准 | 备注 |
|---|---|---|---|
| MDIO_PHY_mdc | C13 | LVCMOS18 | MDIO时钟 |
| MDIO_PHY_mdio_io | D13 | LVCMOS18 | MDIO数据 |
| EMIO_RGMII_rxc | G14 | LVCMOS18 | 接收时钟 |
| EMIO_RGMII_rd[0] | A13 | LVCMOS18 | 接收数据0 |
| EMIO_RGMII_txc | C11 | LVCMOS18 | 发送时钟 |
注意:所有RGMII发送信号(td[*], tx_ctl, txc)应设置SLEW属性为FAST,以确保信号边沿速率满足要求。
4. 系统集成与验证
4.1 硬件验证流程
完成比特流生成后,按以下步骤验证硬件设计:
硬件导出:
- 在Vivado中选择File → Export → Export Hardware
- 勾选"Include bitstream"选项
- 点击OK生成硬件描述文件
SDK环境准备:
- 通过File → Launch SDK启动开发环境
- 创建新的Application Project
- 选择"Hello World"模板作为起点
基础测试:
- 使用AXI Ethernet Lite驱动测试PHY连接
- 通过MDIO接口读取PHY寄存器确认通信正常
4.2 常见问题排查
在实际调试中,可能会遇到以下典型问题:
PHY无法通信:
- 检查MDIO线路是否正确连接
- 确认PHY地址设置与硬件一致
- 测量PHY复位信号时序
数据包丢失:
- 验证时序约束是否生效
- 检查IDELAYCTRL是否正常工作
- 使用ILA抓取RGMII信号观察数据对齐
性能瓶颈:
- 确认DMA缓冲区大小设置合理
- 检查PS-PL AXI总线带宽利用率
- 优化中断处理流程
5. 裸机网络协议栈优化
在双网口系统中,传统的lwIP协议栈需要进行针对性优化:
// 双网口初始化示例 struct netif netif1, netif2; void setup_network() { // 初始化网口1 (PS直连) ip_addr_t ip1, gw1, nm1; IP4_ADDR(&ip1, 192, 168, 1, 10); IP4_ADDR(&gw1, 192, 168, 1, 1); IP4_ADDR(&nm1, 255, 255, 255, 0); netif_add(&netif1, &ip1, &nm1, &gw1, NULL, ðernetif_init, ðernet_input); // 初始化网口2 (PL转接) ip_addr_t ip2, gw2, nm2; IP4_ADDR(&ip2, 192, 168, 2, 10); IP4_ADDR(&gw2, 192, 168, 2, 1); IP4_ADDR(&nm2, 255, 255, 255, 0); netif_add(&netif2, &ip2, &nm2, &gw2, NULL, ðernetif_init, ðernet_input); // 设置默认网口 netif_set_default(&netif1); netif_set_up(&netif1); netif_set_up(&netif2); }关键优化点包括:
- 为每个网口分配独立的内存池
- 调整TCP窗口大小适应高速传输
- 实现基于优先级的流量调度算法
- 添加网口状态监控机制
在实际项目中,双网口配置最常见的应用场景是网络冗余和流量分离。通过合理的路由表配置,可以实现:
- 主备网络自动切换
- 控制数据与视频数据分流转发
- 多网络负载均衡
调试过程中,建议先确保单个网口工作正常,再逐步启用双网口功能。遇到问题时,可以从以下几个方面入手排查:
- 检查PHY芯片的电源和复位信号
- 确认MDIO总线能够正确读写PHY寄存器
- 使用示波器测量RGMII信号质量
- 验证DMA描述符链是否正确构建
