目前,在 ZYNQ 中进行以太网开发的方案,大部分都是基于通过 PS 的 MIO 以 RGMII 接口连接外部 PHY 芯片的方式。但是,由于使用 PS 的 MIO 只能以 RGMII 接口连接外部 PHY 芯片,这就限制了支持其他接口 PHY 芯片的使用,如 GMII、SGMII、MII 等等。因此,若将 PS 内部的以太网控制器 ENET0/ENET1 通过 EMIO 的方式扩展至 PL,便可通过 PL 连接更多种类的接口,从而增加了设计的灵活性。
测试平台:黑金 ZYNQ7035
芯片型号:XC7Z035-2FFG676
本设计基于黑金 ZYNQ7035 开发板,将 PS 的 ETH0 连接网口 1,将 ETH1 通过 EMIO 引出为 GMII 接口,将其与 GMII to RGMII IP 核连接后转换成 RGMII 接口,然后与网口 2 连接,同时修改 Vivado 自带的 LWIP 库文件,使其支持 PHY 芯片 KSZ9031 及自适应,添加 emio_options 选项。
ZYNQ 配置
- 配置 ETH0 和 ETH1,将 ETH1 及其 DMIO 通过 EMIO 引出,如图所示。
- 将 FCLK_CLK0 设置为 200M,作为 GMII to RGMII IP 核内部 IDELAYCTRL 的参考时钟。
-
添加 GMII to RGMII IP 核,在 HR BANK 中,IP 核中 RGMII 接口的接收数据信号和控制信号需要通过 IDELAYE2 来调整信号输入延时,使其时序满足建立和保持时间约束。因此需要在 IP 核包含与 IDELAYE2 相关的 IDELAYCTRL,用来校准 IDELAYE2 每个延时 tap 的延时值。
-
将本 IP 核的 PHY address 设置为 8(该值可任意设置,但不能与现有的 PHY address 相同,否则将产生冲突使 IP 核工作异常)。
- 选择 shared logic 包含在 IP 核内部。
- 添加 Utility Vector Logic,使 FCLK_RESET0_N 通过 Utility Vector Logic 生成的非门后作为 GMII to RGMII IP 核的复位信号:
- 最终的 IP 连线图:
- 添加约束:
set_property PACKAGE_PIN C13 [get_ports MDIO_PHY_mdc]
set_property PACKAGE_PIN D13 [get_ports MDIO_PHY_mdio_io]
set_property PACKAGE_PIN A14 [get_ports phy_rst_n]
set_property PACKAGE_PIN G14 [get_ports EMIO_RGMII_rxc]
set_property PACKAGE_PIN F14 [get_ports EMIO_RGMII_rx_ctl]
set_property PACKAGE_PIN A13 [get_ports {EMIO_RGMII_rd[0]}]
set_property PACKAGE_PIN A12 [get_ports {EMIO_RGMII_rd[1]}]
set_property PACKAGE_PIN B12 [get_ports {EMIO_RGMII_rd[2]}]
set_property PACKAGE_PIN C12 [get_ports {EMIO_RGMII_rd[3]}]
set_property PACKAGE_PIN C11 [get_ports EMIO_RGMII_txc]
set_property PACKAGE_PIN B11 [get_ports EMIO_RGMII_tx_ctl]
set_property PACKAGE_PIN E10 [get_ports {EMIO_RGMII_td[0]}]
set_property PACKAGE_PIN D10 [get_ports {EMIO_RGMII_td[1]}]
set_property PACKAGE_PIN F13 [get_ports {EMIO_RGMII_td[2]}]
set_property PACKAGE_PIN E13 [get_ports {EMIO_RGMII_td[3]}]
set_property IOSTANDARD LVCMOS18 [get_ports MDIO_PHY_mdc]
set_property IOSTANDARD LVCMOS18 [get_ports MDIO_PHY_mdio_io]
set_property IOSTANDARD LVCMOS18 [get_ports phy_rst_n]
set_property IOSTANDARD LVCMOS18 [get_ports EMIO_RGMII_rxc]
set_property IOSTANDARD LVCMOS18 [get_ports EMIO_RGMII_rx_ctl]
set_property IOSTANDARD LVCMOS18 [get_ports {EMIO_RGMII_rd[0]}]
set_property IOSTANDARD LVCMOS18 [get_ports {EMIO_RGMII_rd[1]}]
set_property IOSTANDARD LVCMOS18 [get_ports {EMIO_RGMII_rd[2]}]
set_property IOSTANDARD LVCMOS18 [get_ports {EMIO_RGMII_rd[3]}]
set_property IOSTANDARD LVCMOS18 [get_ports EMIO_RGMII_txc]
set_property IOSTANDARD LVCMOS18 [get_ports EMIO_RGMII_tx_ctl]
set_property IOSTANDARD LVCMOS18 [get_ports {EMIO_RGMII_td[0]}]
set_property IOSTANDARD LVCMOS18 [get_ports {EMIO_RGMII_td[1]}]
set_property IOSTANDARD LVCMOS18 [get_ports {EMIO_RGMII_td[2]}]
set_property IOSTANDARD LVCMOS18 [get_ports {EMIO_RGMII_td[3]}]
set_property SLEW FAST [get_ports EMIO_RGMII_txc]
set_property SLEW FAST [get_ports EMIO_RGMII_tx_ctl]
set_property SLEW FAST [get_ports {EMIO_RGMII_td[*}]
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}]
- 生成比特流
LWIP 库修改
请参考 【ZYNQ】裸机 PS + PL 双网口实现之 lwip 库文件修改
SDK 设计
未完待续…