基于Smart ZYNQ (SP/SP2/SL 版) 的PS实验十 千兆网络初测(基于EMIO)

本文介绍在RTL8211千兆网络模块基础上实现PS端的EMIO扩展以太网网口功能。

  • 此章节内容适用于Smart ZYNQ SP SP2和 SL 版的板子 ( 不包含Smart ZYNQ 标准版 ),如是标准版或本站其他板子请看对应板子目录
  • 本文在 vivado2018.3版本上演示

LWIP(Lightweight IP)是一款轻量级的网络协议栈,旨在为资源有限的嵌入式系统提供高效的网络通信功能。它支持多种网络协议(如 TCP、UDP 和 DHCP),具有灵活的配置选项以适应不同硬件资源,提供低延迟和高吞吐量的网络性能。

Xilinx 的SDK平台上就提供了多个Lwip示例项目,本次实验我们就借助其中的LWIP回环实验来演示我们ZYNQ主板的网络功能,也为后续更高阶的网络功能开发奠定基础。

写在前面:

ZYNQ 网络功能可以有4种方式实现

  • 一 PS端 MIO功能直接扩展以太网口
  • 二 PS端通过EMIO的方式将以太网口映射到PL端口上
  • 三 PL端口的硬件以太网功能 通过AXI的方式供PS端调用
  • 四 PL端用逻辑跑以太网功能(不需要PS端参与)

我们这里因为网口接到了 PL端上,所以理论上可以实现二 三 四, 第二种和第三种方式 其实效果差不多,只是方式三更占用逻辑资源,而方式四是 FPGA直接控制网络,所以为了方便测试我们先用方式二 EMIO的方式来进行测试

一、工程创建

一、Vivado工程创建

工程创建的过程可以参考实验一中的内容,这里不详细描述了。基于Smart ZYNQ (SP/SP2/SL 版) 的FPGA实验一 用ZYNQ的PL资源点亮一个LED(完整图文) (芯片型号选XC7Z020CLG484-1)

二、Vivado 中的设置

)IP INTEGRATOR→Create Block Design,在弹出的对话框中输入设计名,最后点击“OK”,如下图所示

2)在右侧的窗口里 ,点击加号,在选择框里搜索ZYNQ,并找到ZYNQ7 PROCESSING SYSTEM ,双击并打开

3)软件自动生成了一个 zynq的block 如下图所示,接下来要做一些相应的设置,双击下图中的ZYNQ核

4)依次在弹窗里找到DDR Configuration→DDR Controller Configuration→DDR3,在Memory Part下拉菜单中根据自己板子上的DDR来选择相应的DDR3,本实验所用到型号:MT41K256M16RE-125,数据位宽选择16bit 最后点击“OK”,如下图所示。

5) 因为工程暂时用不到 AXI功能,所以可以先禁用AXI功能

6) 这里把ENET0通过EMIO引出来 ,并且选中MDIO功能(也用EMIO方式)

之后点选OK 来保存ZYNQ的配置

7)由于 ZYNQ的PS 调用EMIO方式 默认输出是GMII,而我们的网络部分的芯片 RTL8211是 输出RGMII的,所以这里我们需要增加一个 GMII和RGMII转换的IP模块 (Gmii to Rgmii)

打开 GMII TO RGMII模块 设置更改成下面

8) 又因为GMII TO RGMII 是高电平复位 ,但是ZYNQ 是输出低电平复位的,所以这里需要增加一个反相器(搜索utility, 在检索出来的选项里 选择 utility vector logic)

在设置页里改成 not(反相器)将位宽改成1

9) 按下图方式连接好各个模块(复位 时钟 网络)

10)并通过右键 然后选择Make external 的方式引出RGMII 和MDIO_PHY功能引脚

11)这里还要对Z7的模块进行一个修改,因为gmii to rgmii 模块的clkin 在手册上写要求是200mhz,所以我们这里需要对ZYNQ核的输出时钟频率进行修改

重新双击ZYNQ的核,将FCLK_CLK0的频率改成200

12)另外 因为 SDK中 网络功能的例程都需要UART功能来调试,所以这里额外在ZYNQ核心中增加串口功能(选择EMIO方式)

13) 所有的都完成后点选 Run Block Automation,完成后续自动布线

因为我们增加了EMIO 的UART,所以这里需要将UART的引脚引出 ,右键选择ZYNQ模块的UART_0,然后选择Make External

14)创建硬件描述,source→Design Source ,右键我们创建的BLOCK工程,点击create HDL wrapper如下图所示(这一步的作用相当于将图纸转换成对应的硬件描述语言的功能)

15)编写好代码后 对代码进行编译

16)添加约束文件 对管脚 和 电平进行约束, 尤其要注意 最下面的时序约束部分 一定要添加,不然大概率无法ping通

set_property PACKAGE_PIN G21 [get_ports MDIO_PHY_0_mdc]
set_property PACKAGE_PIN H22 [get_ports MDIO_PHY_0_mdio_io]
set_property PACKAGE_PIN A22 [get_ports {RGMII_0_rd[0]}]
set_property PACKAGE_PIN A18 [get_ports {RGMII_0_rd[1]}]
set_property PACKAGE_PIN A19 [get_ports {RGMII_0_rd[2]}]
set_property PACKAGE_PIN B20 [get_ports {RGMII_0_rd[3]}]
set_property PACKAGE_PIN A21 [get_ports RGMII_0_rx_ctl]
set_property PACKAGE_PIN B19 [get_ports RGMII_0_rxc]
set_property PACKAGE_PIN E21 [get_ports {RGMII_0_td[0]}]
set_property PACKAGE_PIN F21 [get_ports {RGMII_0_td[1]}]
set_property PACKAGE_PIN F22 [get_ports {RGMII_0_td[2]}]
set_property PACKAGE_PIN G20 [get_ports {RGMII_0_td[3]}]
set_property PACKAGE_PIN G22 [get_ports RGMII_0_tx_ctl]
set_property PACKAGE_PIN D21 [get_ports RGMII_0_txc]
set_property PACKAGE_PIN M17 [get_ports UART_0_0_rxd]
set_property PACKAGE_PIN L17 [get_ports UART_0_0_txd]



set_property IOSTANDARD LVCMOS33 [get_ports MDIO_PHY_0_mdc]
set_property IOSTANDARD LVCMOS33 [get_ports MDIO_PHY_0_mdio_io]
set_property IOSTANDARD LVCMOS33 [get_ports {RGMII_0_rd[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {RGMII_0_rd[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {RGMII_0_rd[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {RGMII_0_rd[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports RGMII_0_rx_ctl]
set_property IOSTANDARD LVCMOS33 [get_ports RGMII_0_rxc]
set_property IOSTANDARD LVCMOS33 [get_ports {RGMII_0_td[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {RGMII_0_td[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {RGMII_0_td[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {RGMII_0_td[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports RGMII_0_tx_ctl]
set_property IOSTANDARD LVCMOS33 [get_ports RGMII_0_txc]
set_property IOSTANDARD LVCMOS33 [get_ports UART_0_0_rxd]
set_property IOSTANDARD LVCMOS33 [get_ports UART_0_0_txd]


set_property SLEW FAST [get_ports {RGMII_0_td[0]}]
set_property SLEW FAST [get_ports {RGMII_0_td[1]}]
set_property SLEW FAST [get_ports {RGMII_0_td[2]}]
set_property SLEW FAST [get_ports {RGMII_0_td[3]}]
set_property SLEW FAST [get_ports RGMII_0_tx_ctl]
set_property SLEW FAST [get_ports RGMII_0_txc]


create_clock -period 8.000 -name RGMII_0_rxc -waveform {0.000 4.000} [get_ports RGMII_0_rxc]
set_clock_groups -logically_exclusive -group [get_clocks -include_generated_clocks {gmii_clk_25m_out gmii_clk_2_5m_out}] -group [get_clocks -include_generated_clocks gmii_clk_125m_out]

17. 修改之后 点击 Generate Bitstream 进行综合以及生成Bit 文件

等待布线综合完成

三、SDK部分设计

1)File→Export→Export hardware…,在弹出的对话框中勾选“include bitstream”,点击“OK”确认,如下图所示。

2)File→Lauch SDK,在弹出的对话框中,保存默认,点击“OK”,如下图所示。

系统将自动打开SDK开发环境

3)在SDK环境下创建网络工程

输入一个工程名,然后点选下一步,选择 LwIP Echo Server选项,自动导入网络SDK自带的网络例程。

4)对网络进行调试

硬件部分将网络模块的RJ45接上网线

将主板通过TYPEC 连接电脑(在设备管理器中查看主板的串口在系统中的串口号),并且在SDK 的终端中添加这个串口,如下图所示(波特率115200) 也可以用第三方串口助手来调试

接下来点选program FPGA 对FPGA进行配置

接下来点选DEBUG

最好对RUN AS进行设置 勾选 Reset entire system 和Program FPGA 再下载,否则有可能不能正常访问网络(原因在最下面的备注项)里

勾选 Reset entire system 和Program FPGA

通过串口观察到网络已经启动,并且速度为1000M, 网络IP为192.168.1.113(板子需要连接到路由器才能分配到IP) 如果板子和PC直接通过网线直连 请看本文最后的备注部分

用相同路由器网段的 WINDOWS电脑 ping 一下这个IP 可以ping 通,说明网络连接成功了

通过网络助手(百度可以下载)连接后,发送什么数据,就能通过网络接收到什么数据(设置的端口号是7,IP地址按照之前SDK 串口读到的板子IP地址设置)

备注:有部分客户按上述先下载PL 后debug的方法操作 出现无法自动获取路由器的IP(并且无法ping通的情况),并且路由器列表上没有检测到设备(猜测可能是因为PL单独下载后,PS还没下载的情况下,路由器和板子握手失败后,就停止了板子访问网络的权限,造成板子网络部能正常工作),这种情况下可以按下面方法勾选reset entire system,和program fpga选项(让系统每次debug 都能重新配置整个fpga)

a )右键点我们的PS工程,调试界面里 点击RUN AS 里的 设置项目,如下图所示

b)设置里勾选 复位整个工程和下载FPGA部分代码的选项 如下图所示,并点击应用和RUN

c)勾选上述两个选项后,每次debug的时候,系统都会重新配置FPGA和初始化整个工程,网络功能也恢复正常了。

以上 内容仅供参考

另外,很多网站都是手动把速度设置成1000mbps 但是我这边设置了反而无法连接了,怀疑是phy芯片和demo有点冲突引起的,后续会继续研究,以及大吞吐量测试 以确定网络模块功能正常

后记: 经过IPREF测试 系统大吞吐量测试可以稳定在 940M环境下,模块工作稳定,至于上面的问题应该是PHY握手比较慢,怀疑是官方demo在手动模式下 超时引起的, 设置成自动模式连接千兆没问题(大吞吐量测试图如下, 有时间再整理下大吞吐量的测试方法,也是XILINX的官方demo)

SDK程序全部都是官网的例程,具体功能大家自行研究

板子和PC 通过网线直连的注意事项

备注: 关于板子和PC 直接通过网线直连, 之前一直发现不成功 无法ping通, 或者板子先和路由器直连,获取到IP后,再拔下网线 将板子和PC 直连,此时可以ping通,但是如果一开始直接直连,就永远都无法ping通, 经过最近的调试终于发现问题了。

板子如果和PC 直连, 此工程必须要接交叉式的网线(也就是PC连PC的网线)才可以正常ping通。( 但是很奇怪当板子跑PYNQ的时候就不需要一定用交叉的网线),怀疑是官方SDK的例程没有打开MDI SWAP 功能导致的(也可能通过程序可以打开,暂时还没找到),所以,如果大家遇到直连ping不通的情况下 ,请试着更换特殊的交叉网线再进行尝试。

直连状态会无法获得IP,那系统自动分配IP 192.168.1.10, 那本地主机也记得将对应的网络口设置成192.168.1.* 的网络段, 网关设置成192.168.1.1才可以ping通

  • 本文的完整工程下载:10_PS_EMIO_NET_TEST
  • VIVADO的版本:2018.3
  • 工程创建目录:E:\Smart_ZYNQ_SP_SL\SDK\10_PS_EMIO_NET_TEST
  • 工程适用主板: Smart ZYNQ (SP / SP2 / SL) (不适用于Smart ZYNQ 标准版 
  • 测试工具网络调试助手:网络调试助手 v4.3.29下载

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注