本帖最后由 FPGA课程 于 2024-9-11 14:17 编辑
软件版本:VIVADO2021.1
操作系统:WIN10 64bit
硬件平台:适用 XILINX A7/K7/Z7/ZU/KU 系列 FPGA
实验平台:米联客-MLK-H3-CZ08-7100开发板
板卡获取平台:https://milianke.tmall.com/
登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!
1概述本文介绍基于“米联客”UDP协议栈实现的UDP通信,硬件接口使用了RGMII接口,在后学的文章中,我们还会继续介绍硬件接口使用GTP(artix FPGA)、GTX(kintex FPGA) 、GTH(ultrascale/ ultrascale+ FPGA)实现的UDP通信。 2RGMII接口PHY 的 MII 接口有很多种, 例如 MII、 GMII、 RGMII、 SGMII、 XGMII、 TBI、 RTBI 等。其中 RGMII 的主要优势在于,它可同时适用于 1000M、 100M、 10M 三种速率,而且接口占用引脚数较少。但也存在缺点,其一, PCB 布线时需要尽可能对数据、控制和时钟线迚行等长布线。其二,对其时序约束较为严格。 2.1RGMII信号定义RGMII使用4bit数据接口采用上下沿DDR(Double Data Rate)的方式在一个时钟周期内传输8bit数据信号,即上升沿发送或者接收数据的低4位[3:0],下降沿发送或者接收数据的高4位[7:4]。 同理,使用1bit控制接口采用DDR的方式在一个时钟周期内传输2bit控制信号,即在上升沿发送或者接收数据使能信号(TX_EN、RX_DV),下降沿发送数据错误信号与使能信号的逻辑异戒值(TX_ERR xor TX_EN、RX_ERR xor RX_DV),根据该信号可以计算出相应的数据错误信号。 发送端: TXC:发送数据信号和控制信号对应的同步时钟信号(125M、25M、2.5M) TXD[3:0]:发送数据信号, 4bit 位宽 TX_CTL:发送控制信号 发送端信号时序如下图所示。
接收端: RXC:接收数据信号和控制信号对应的同步时钟信号(125M、25M、2.5M) RXD[3:0]:接收数据信号,4bit位宽 RX_CTL:接收控制信号 接收端信号的时序如下图所示。
2.2RGMII接口信号组合定义发送端: 关于发送端TX_EN(GMII_TX_EN)、TX_ERR(GMII_TX_ER)、TXD[7:0]信号不同组合对应的含义如下图表所示。
在大部分应用中,我们只需要关注最后两种即可。当TX_CTL上升沿和下降沿均为1时,表示数据有效,无何何错误。当TX_CTL上升沿为1,下降沿为0时,表示当前时钟周期的8位数据错误。
接收端: 同理,接收端关于RX_DV(GMII_RX_DV)、RX_ERR(GMII_RX_ER)、RXD[7:0]信号不同组合对应的含义如下图表所示。
与发送端类似,我们首先需要关注最后两种,即当RX_CTL上升沿和下降沿均为1时,表示数据有效,无何何错误。当RX_CTL上升沿为1,下降沿为0时,表示当前时钟周期的数据错误。 除此之外,表中前三项是很有意义的组合类型,这也是为什么RGMII接口可以同时支持1000/100/10M三种速率的一个重要因素。它利用数据帧(frame)之间的发送间隔传递当前连接的状态信息。通过这些信息可以判断当前链路的状态、速率、双工情况。 3RGMII接口的三种速率模式RGMII接口适用亍1000M、100M、10M三种传输速率。 当工作于1000M时,时钟信号TXC和RXC均为125MHz,4bit数据信号上下沿值均有效,控制信号上下沿值也均有效。 当工作于100M时,时钟信号TXC和RXC均为25MHz,4bit数据信号只有上升沿值[3:0]有效,相当于此时数据信号切换为单沿SDR(Single Data Rata)4 位传输模式。控制信号仍为上下沿有效。 当工作于10M时,时钟信号TXC和RXC均为2.5MHz,数据信号和控制信号的使用不100M速率时完全相同。 4RGMII接口时序对于FPGA 来说,这是一种典型的DDR 源同步接口。当RGMII 接口工作于1000M 速率时,TXC 和RXC 时钟信号都为125MHz,那么单个接口的数据率便等同于250Mbps,单个信号的有效数据窗最大为4ns。在FPGA 中设计高速源同步接口的重点在于时序控制和时序约束。在最后的程序设计部分对于基于Tri Mode Ethernet MAC IP-CORE的源码和时序修改需要用到这部内容。 4.1发送端一般的PHY 芯片都支持两种RGMII 发送端口的时序关系。一种称为非延时模式,如下图所示。
即要满足时钟信号TXC 的边沿对准数据信号TXD[3:0]和控制信号TX_CTL 有效窗口中心附近的位置,也就是说TXC 比其他信号存在2ns(90°相位)左右的延时。
另一种为延时模式,如下图所示。
这种时序要求TXC的边沿与其发送的数据TXD和控制信号TX_CTL 边沿对齐,所有信号具有相同的相位。一般来说,大部分PHY芯片默认都是采用正常时序模式,可通过MDIO 接口设置寄存器,或者芯片特殊功能引脚将其配置为延时模式。 4.2接收端RGMII 接收端口同样也存在两种时序关系,同为非延时和延时模式。非延时如下图所示。此时,时钟信号RXC RXD 和RX_CTL 边沿对齐,具有相同的相位。
延时模式时序关系如下图所示。
此时,要满足时钟信号RXC 的边沿对准数据信号RXD[3:0]和控制信号RX_CTL 有效窗口中心附近的位置,即RXC 比其他信号存在2ns(90°相位)左右的延时。 一般来说,PHY 芯片默认即可能是延时模式也有可能是非延时模式,可通过MDIO 接口设置相应的寄存器,或者芯片特殊功能引脚改变PHY 芯片的RGMII 接口时序模式。 4.3 B50610 RGMII接口PHRGMII发送接口时序,该芯片RGMII发送接口默认使用的是延时模式,由如下寄存器的值决定。
延时模式RGMII发送接口时序关系如下图所示。
RGMII接收接口时序,此芯片接收接口默认也是采用了延迟模式,默认寄存器设置如下:
B50610芯片延时模式RGMII接收接口时序关系如下图所示:
4.4 88E1518 RGMII接口PHY88E1518 RGMII发送接口时序,该芯片RGMII发送接口默认使用的是延时模式,由如下寄存器的值决定。
延时模式RGMII发送接口时序关系如下图所示:
88E1518 RGMII接收接口时序,该芯片RGMII接收接口默认使用的也是延时模式,由如下寄存器的值决定。
延时模式RGMII接收接口时序关系如下图所示:
4.5 RTL8211 RGMII接口PHY具体型号以RTL8211FD通过设置引脚为上拉或者下拉来设置延迟,这里需要用户注意的是虽然开发板硬件上没有明确上拉和下拉,但是开发板上RTL8211依然工作在delay模式下,以下是发送或者接收接口的延迟设置:
从下图中我们发现RTL8211描述的发送delay和前面的B50610以及88E1518描述的delay不一样,RTL8211在delay模式下数据setup是正值,说明建立时间在时钟上沿之前。而B50610以及88E1518在delay模式下建立时间是负值说明是在时钟沿之后。
5原语使用在7系列FPGA中实现RGMII接口需要借助5种原语,分别是:IDDR、ODDR、IDELAYE2、ODELAYE2(A7中没有)、IDELAYCTRL。 其中,IDDR和ODDR分别是输入和输出的双边沿寄存器,位于IOB中。IDELAYE2和ODELAYE2,分别用于控制IO口输入和输出延时。同时,IDELAYE2和ODELAYE2的延时值需要使用原语IDELAYCTRL来进行校准。另外,需要注意的是,在7系列器件的HR Bank中没有ODELAYE2,只有在HP BANK中才有ODELAYE2。1).IDDR IDDR将输入的双边沿DDR信号,在输出端恢复为两个并行单边沿SDR信号。IDDR的原语如下。详细参数可参考UG471。 IDDR #( .DDR_CLK_EDGE("OPPOSITE_EDGE"), // "OPPOSITE_EDGE", "SAME_EDGE" // or "SAME_EDGE_PIPELINED" .INIT_Q1(1'b0), // Initial value of Q1: 1'b0 or 1'b1 .INIT_Q2(1'b0), // Initial value of Q2: 1'b0 or 1'b1 .SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC" ) IDDR_inst ( .Q1(Q1), // 1-bit output for positive edge of clock .Q2(Q2), // 1-bit output for negative edge of clock .C(C), // 1-bit clock input .CE(CE), // 1-bit clock enable input .D(D), // 1-bit DDR data input .R(R), // 1-bit reset .S(S) // 1-bit set ); C为同步时钟,Q1和Q2则是分别从C上升沿和下降沿同步的输出的SDR数据,D为DDR输入。参数DDR_CLK_EDGE用来决定了C、Q1、Q2和D之间的时序关系。DDR_CLK_EDGE有3种模式:OPPOSITE_EDGE、SAME_EDGE以及SAME_EDGE_PIPELINED,3种时序关系如下图所示。
一般来说,OPPOSITE_EDGE模式使用较少。SAME_EDGE和SAME_EDGE_PIPELINED的区别在亍,SAME_EDGE模式时的Q1比SAME_EDGE_PIPELINED模式时的Q1提前了一个时钟周期。显然,对RGMII接口来说使用SAME_EDGE模式会造成两个相邻时钟周期之间的数据错位,因此,只能采用SAME_EDGE_PIPELINED模式。 1)ODDR使用ODDR将TXC同一个时钟周期内的两个SDR信号分别通过上升沿和下降沿输出为DDR信号。ODDR的原语如下,详细参数可参考UG471。 ODDR #( .DDR_CLK_EDGE("OPPOSITE_EDGE"), // "OPPOSITE_EDGE" or "SAME_EDGE" .INIT(1'b0), // Initial value of Q: 1'b0 or 1'b1 .SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC" ) ODDR_inst ( .Q(Q), // 1-bit DDR output .C(C), // 1-bit clock input .CE(CE), // 1-bit clock enable input .D1(D1), // 1-bit data input (positive edge) .D2(D2), // 1-bit data input (negative edge) .R(R), // 1-bit reset .S(S) // 1-bit set ); ODDR只需要1个时钟信号输入C,D1和D2则是分别在C的上升沿和下降沿同步的数据输入,Q为DDR输出。参数DDR_CLK_EDGE用来决定了C、D1、D2和Q乊间的时序关系。DDR_CLK_EDGE有两种模式:OPPOSITE_EDGE和SAME_EDGE,两种时序关系如下图所示。
对于OPPOSITE_EDGE模式,在FPGA内部也同样需要两个反相时钟来同步D1和D2,较少使用。在设计RGMII接口时使用了SAME_EDGE模式。
2)IDELAYE2 IDELAYE2用于在信号通过引脚进入芯片内部之前,进行延时调节。这里给出本方案中的用法,原语描述如下。详细参数可参考UG471。 IDELAYE2 #( .IDELAY_TYPE("FIXED"), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE .REFCLK_FREQUENCY(200.0),// IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0) .IDELAY_VALUE(0), // Input delay tap setting (0-31). ) IDELAYE2_inst ( .CNTVALUEOUT(), // 5-bit output: Counter value output .DATAOUT(DATAOUT), // 1-bit output: Delayed data output .C(1'b0), // 1-bit input: Clock input .CE(1'b0), // 1-bit input: Active high enable increment/decrement input .CINVCTRL(1'b0), // 1-bit input: Dynamic clock inversion input .CNTVALUEIN(5'h0), // 5-bit input: Counter value input .DATAIN(1'b0), // 1-bit input: Internal delay data input .IDATAIN(IDATAIN), // 1-bit input: Data input from the I/O .INC(1'b0), // 1-bit input: Increment / Decrement tap delay input .LD(1'b0), // 1-bit input: Load IDELAY_VALUE input .LDPIPEEN(1'b0), // 1-bit input: Enable PIPELINE register to load data input .REGRST(REGRST) // 1-bit input: Active-high reset tap-delay input ); IDATAIN为延时前的输入,DATAOUT为对应延时之后的输出。REFCLK_FREQUENCY参数用来设置输入IDELAYCTRL的参考时钟频率,IDELAY_VALUE参数用来设置延时的tap数。其余参数保持默认值即可。
3)ODELAYE2 由亍A7中不存在ODELAYE2,因此不作介绍。详细参数可参考UG471。
4)IDELAYCTRL IDELAY2和ODELAY2都需要IDELAYCTRL来迚行校准。IDELAYCTRL原语如下。更多详细信息可参考UG471。 IDELAYCTRL IDELAYCTRL_inst ( .RDY(RDY), // 1-bit output: Ready output .REFCLK(REFCLK), // 1-bit input: Reference clock input .RST(RST) // 1-bit input: Active high reset input ); IDELAYCTRL需要一个参考时钟信号REFCLK来校准IDELAY2和ODELAY2每个tap的延时值,可用的REFCLK频率为200M、300M、400M。时钟越高对应的tap延时平均值越小,也就是说延时调节精度越高。DS182中对此有如下描述。
大部分情况下使用200M的参考时钟就可以满足实际需求。 6 UDP通信构架为了实现UDP FPGA通信“米联客”提供了uiudp_stack.dcp协议栈网表文件给用户免费使用,具备和源码一样的功能,并且多年来已经有大量客户用于实际项目开发中稳定可靠,但是需要源码的客户需要付费购买。uiudp_stack这里对于用户就是一个“黑盒子”,上层协议就是用户实际收发的有效数据部分,而Tri Mode Ethernet MAC负责处理以太网的MAC,以及通过RGMII接口和RGMII接口的PHY芯片通信。关于协议栈的使用参考“附录2:米联客uiudp_stack udp ip协议栈使用说明”一文。
7Tri Mode Ethernet MAC使用
7.1IP核设置由于使用千兆通讯,因此将速率设为1Gbps。如下图所示。
首先,由于该IP需要连接到PHY的RGMII接口,所以PHY Interface选择RGMII。 其次,由于1G/2.5G Ethernet PCS/PMA or SGMII使用1G光通讯时采用了1000BASEX标准,速率固定为1G。所以,需要将Tri Mode Ethernet MAC的MAC speed设为1000Mbps,与之相匹配。 将Tri Mode Ethernet MAC的配置方式设置为通过AXI-Lite接口配置。 将AXI-Lite接口的时钟设为与user_clk2频率相同,即125MHz,这样可以使用同一个时钟源。 在设计中不使用MDIO,因此不使能MDIO接口。 上述设置如下图所示。
如果有多个以太网通道需要设置,那么第一个需要设置为include Shared Logic in core 否则选择include Shared Logic in example design
音视频桥、流量控制、参数统计等功能都不使用,设置如下:
7.2Tri Mode Ethernet MAC IP核结构
7.2.1时钟网络
IP核内部时钟网络结构如下图所示。其中,tx_mac_aclk为AXI-Stream发送接口的同步时钟,rx_mac_aclk为AXI-Stream接收接口的同步时钟。由于在设计中没有使用MDIO接口,所以不存在时钟信号mdc。
gtx_clk为IP核工作的全局时钟源,频率125MHz。s_axi_aclk为AXI-Lite接口的同步时钟。其余时钟refclk、gtx_clk90等均与GMII、RGMII接口与外部PHY芯片连接有关。
7.2.2用户接口
这里对一些重要的用户接口进行说明,其他接口可参考IP核手册。
7.2.2.1AXI-Stream接收接口
AXI-Stream接收接口信号如下图所示。用户通过该接口接收从IP核输出的以太网数据包。需要注意的是,接收接口没有使用AXI-Stream标准中的tready信号。这代表接收端需要具备持续接收数据的能力,防止出现数据来不及接收而产生溢出。
AXI-Stream接收接口时序如下图所示。
7.2.2.2AXI-Stream发送接口AXI-Stream发送接口信号如下图所示。用户通过该接口,向IP核传输所需要发送的以太网数据包。其中,tx_ifg_delay用于设置发送间隔,一般都默认采用最小间隔,将tx_ifg_delay置为0即可。
AXI-Stream发送接口时序如下图所示。
7.2.2.3接收发送数据统计信号下图中的信号,用于统计并输出当前发送完毕或者接收完毕的帧对应的各种类型的信息。除了调试用之外,一般无需使用。
信号时序如下图所示:
7.2.2.4流量控制信号非高带宽、大负荷传输情况下,一般不需要使用流量控制功能。因此,不需要发送暂停帧,将以下两个信号均置为0即可。
7.2.2.5AXI-Lite接口AXI-Lite接口主要用于配置和读取IP核内部的寄存器。除此之外,还可以直接通过MDIO接口配置外部PHY芯片或者1G/2.5G Ethernet PCS/PMA or SGMII IP核的寄存器。由于MDIO没有使用。因此,AXI-Lite接口主要用于IP核设置。 7.2.2.6复位信号IP核复位信号网络如下图所示:
其中glbl_rstn为全局复位信号,用于复位整个IP核。rx_axi_rstn和tx_axi_rstn分别用于单独复位接收和发送部分的逻辑,一般无需使用。在例程中,将rx_axi_rstn和tx_axi_rstn都被恒置为1。
tx_reset和rx_reset分别用于表示IP核的发送和接收部分逻辑的复位状态,根据这两个信号可以判断IP核是否处于复位状态。这两个信号需要配合AXI-Stream接收和发送接口的同步时钟信号tx_mac_aclk和rx_mac_aclk进行使用,这是因为可能当tx_reset和rx_reset由1变为0时,IP核才会输出tx_mac_aclk和rx_mac_aclk。对于使用tx_mac_aclk和rx_mac_aclk作为同步时钟的逻辑,复位信号必须以tx_reset和rx_reset作为基准,避免出现复位无效的情况。对此,在例程中给出了参考设计。 7.3IP核使用注意点
7.3.1Tri Mode Ethernet MAC 数据发送长度
Tri Mode Ethernet MAC IP核在默认情况下,发送帧长度小于64字节时,IP核会在帧末尾自动补0,补足至64字节,并且再帧末尾自动插入4字节CRC。接收时,IP核自动去除末尾4字节CRC,但对于长度小于64字节的帧末尾补的0不会被去掉,仍会通过接收接口输出。因此,可以发送的数据长度在14~1514(含14字节MAC帧头)字节之间。
IP使用文档中对此有如下描述。
7.3.2AXI-Lite接口配置策略
通过vivado仿真IP核自带的example,可以观察到example中通过AXI-Lite配置IP核的过程,如下图所示。具体寄存器定义参考PG051。在例程中,直接采用了这部分的代码。
需要说明的是,最后3个步骤均与帧过滤功能有关。
其中,unicast address就是设置IP核的本地MAC地址,用于过滤时进行地址匹配。如果开启帧过滤功能,除了广播地址、暂停地址和本地MAC地址,含有其他目的MAC地址的帧将会被全部进行过滤,不被用户接收。
最后一个步骤启用IP核的promiscuous mode,关闭了接收帧过滤功能,使IP核接收包含任何目的MAC地址的以太网帧。如果用户需要考虑进行MAC地址过滤可关闭该功能。相关寄存器如下图所示。
7.4RGMII时序约束本文这里不对时序约束做详细的说明,米联客基于XILINX FPGA的时序约束课程预计很快会提供给大家学习。 tri_mode_ethernet_mac IP默认的RGMII发送接口结构如下图所示:
7.4.1PHY芯片B50610开发板使用的PHY芯片为B50610,该芯片RGMII发送接口默认使用的是延时模式,由如下寄存器的值决定。
B50610芯片延时模式RGMII发送接口时序关系如下图所示。
这可以通过修改IP核生成的RGMII发送接口部分的代码来实现。RGMII接口的发送时序可以通过修改IP核内部的tri_mode_ethernet_mac_0_rgmii_v2_0_if.v来实现。如下图所示:
修改发送时钟ODDR的参考时钟和复位信号,如下图:
改为:
另外默认的IP不能直接修改,需要设置下属性:
时序约束首先是Tri Mode Ethernet MAC IP-CORE自带的时序约束文件在路径,当然我们可以直接修改这个文件
修改时序Iodelay相关的时序约束 接收io delay时序约束 - set_input_delay -clock [get_clocks $rgmii_rx_clk] -max -1.2 [get_ports {rgmii_rxd[*] rgmii_rx_ctl}]
- set_input_delay -clock [get_clocks $rgmii_rx_clk] -min -2.8 [get_ports {rgmii_rxd[*] rgmii_rx_ctl}]
- set_input_delay -clock [get_clocks $rgmii_rx_clk] -clock_fall -max -1.2 -add_delay [get_ports {rgmii_rxd[*] rgmii_rx_ctl}]
- set_input_delay -clock [get_clocks $rgmii_rx_clk] -clock_fall -min -2.8 -add_delay [get_ports {rgmii_rxd[*] rgmii_rx_ctl}]
复制代码发送io delay 时序约束 - set_output_delay 1.0 -max -clock [get_clocks $rgmii_tx_clk] [get_ports {rgmii_txd[*] rgmii_tx_ctl}]
- set_output_delay -1.0 -min -clock [get_clocks $rgmii_tx_clk] [get_ports {rgmii_txd[*] rgmii_tx_ctl}]
- set_output_delay -1.0 -max -clock [get_clocks $rgmii_tx_clk] [get_ports {rgmii_txd[*] rgmii_tx_ctl}] -clock_fall -add_delay
- set_output_delay -1.0 -min -clock [get_clocks $rgmii_tx_clk] [get_ports {rgmii_txd[*] rgmii_tx_ctl}] -clock_fall -add_delay
复制代码
7.4.2PHY芯片88E151888E1518 RGMII发送接口时序,该芯片RGMII发送接口默认使用的是延时模式,由如下寄存器的值决定。
延时模式RGMII发送接口时序关系如下图所示:
88E1518 RGMII接收接口时序,该芯片RGMII接收接口默认使用的也是延时模式,由如下寄存器的值决定。
因此也是需要修改,修改发送时钟ODDR的参考时钟和复位信号,如下图:
改为:
时序约束首先是Tri Mode Ethernet MAC IP-CORE自带的时序约束文件在路径,当然我们可以直接修改这个文件
修改时序Iodelay相关的时序约束 接收io delay时序约束 - set_input_delay -clock [get_clocks $rgmii_rx_clk] -max -1.2 [get_ports {rgmii_rxd[*] rgmii_rx_ctl}]
- set_input_delay -clock [get_clocks $rgmii_rx_clk] -min -2.8 [get_ports {rgmii_rxd[*] rgmii_rx_ctl}]
- set_input_delay -clock [get_clocks $rgmii_rx_clk] -clock_fall -max -1.2 -add_delay [get_ports {rgmii_rxd[*] rgmii_rx_ctl}]
- set_input_delay -clock [get_clocks $rgmii_rx_clk] -clock_fall -min -2.8 -add_delay [get_ports {rgmii_rxd[*] rgmii_rx_ctl}]
复制代码发送io delay 时序约束 - set_output_delay -0.9 -max -clock [get_clocks $rgmii_tx_clk] [get_ports {rgmii_txd[*] rgmii_tx_ctl}]
- set_output_delay -2.7 -min -clock [get_clocks $rgmii_tx_clk] [get_ports {rgmii_txd[*] rgmii_tx_ctl}]
- set_output_delay -0.9 -max -clock [get_clocks $rgmii_tx_clk] [get_ports {rgmii_txd[*] rgmii_tx_ctl}] -clock_fall -add_delay
- set_output_delay -2.7 -min -clock [get_clocks $rgmii_tx_clk] [get_ports {rgmii_txd[*] rgmii_tx_ctl}] -clock_fall -add_delay
复制代码
7.4.3PHY芯片RTL8211以RTL8211FD通过设置引脚为上拉或者下拉来设置延迟,这里需要用户注意的是虽然开发板硬件上没有明确上拉和下拉,但是开发板上RTL8211依然工作在delay模式下,以下是发送或者接收接口的延迟设置:
从下图中我们发现RTL8211描述的发送delay和前面的B50610以及88E1518描述的delay不一样,RTL8211在delay模式下数据setup是正值,说明建立时间在时钟上沿之前。而B50610以及88E1518在delay模式下建立时间是负值说明是在时钟沿之后。
所以对于RTL8211无需修改代码。
另外默认的IP不能直接修改,需要设置下属性:
时序约束首先是Tri Mode Ethernet MAC IP-CORE自带的时序约束文件在路径,当然我们可以直接修改这个文件
接收io delay时序约束 - set_input_delay -clock [get_clocks $rgmii_rx_clk] -max -1.2 [get_ports {rgmii_rxd[*] rgmii_rx_ctl}]
- set_input_delay -clock [get_clocks $rgmii_rx_clk] -min -2.8 [get_ports {rgmii_rxd[*] rgmii_rx_ctl}]
- set_input_delay -clock [get_clocks $rgmii_rx_clk] -clock_fall -max -1.2 -add_delay [get_ports {rgmii_rxd[*] rgmii_rx_ctl}]
- set_input_delay -clock [get_clocks $rgmii_rx_clk] -clock_fall -min -2.8 -add_delay [get_ports {rgmii_rxd[*] rgmii_rx_ctl}]
复制代码
发送io delay 时序约束 - set_input_delay -clock [get_clocks $rgmii_rx_clk] -max -1.2 [get_ports {rgmii_rxd[*] rgmii_rx_ctl}]
- set_input_delay -clock [get_clocks $rgmii_rx_clk] -min -2.8 [get_ports {rgmii_rxd[*] rgmii_rx_ctl}]
- set_input_delay -clock [get_clocks $rgmii_rx_clk] -clock_fall -max -1.2 -add_delay [get_ports {rgmii_rxd[*] rgmii_rx_ctl}]
- set_input_delay -clock [get_clocks $rgmii_rx_clk] -clock_fall -min -2.8 -add_delay [get_ports {rgmii_rxd[*] rgmii_rx_ctl}]
复制代码
8例程设计第一个demo是环路收发测试,即在电脑上通过网络调试助手向开发板发送任意长度小于1472字节的UDP包。 第二个demo是只让FPGA发送数据测试发送的最高速度,但是不代表接收端不丢包的速度。
由于UDP IP 协议栈的AXI-Stream 数据接口位宽为64bit,而Tri Mode Ethernet MAC 的AXI-Stream 数据接口位宽为8bit。因此,要将UDP IP 协议栈与Tri Mode Ethernet MAC 之间通过AXI-Stream 接口互联,需要进行时钟域和数据位宽的转换。实现方案如下图所示。
8.1AXI-Stream DATA FIFO
收发路径都使用了2个AXI-Stream DATA FIFO,通过其中1个FIFO实现异步时钟域的转换,1个FIFO实现数据缓冲和同步Packet mode功能。
由于1G速率下Tri Mode Ethernet MAC的AXI-Stream数据接口同步时钟信号为125MHz。此时,UDP IP协议栈64bit的AXI-Stream数据接口同步时钟信号应该为125MHz/(64/8)=15.625MHz。因此,异步AXI-Stream DATA FIFO两端的时钟分别为125MHz(8bit),15.625MHz(64bit)。
Packet mode是指FIFO在输出数据前持续缓存AXI-Stream接口输入的数据直至输入端tlast信号拉高,即存满一个完整的数据包时,才开始在AXI-Stream输出端口向外输出数据。Packet mode功能设置如下图所示。需要注意的是,启用Packet mode时,FIFO必须工作于同步模式。 对于发送路径,启用Packet mode是为了防止FIFO被IP核读空。对于接收路径,是由于米联的UDP IP协议栈要求1个数据包的tvalid信号在数据包持续期间必须恒为1。
8.2AXI4-Stream Data Width ConverterUDP IP协议栈的AXI-Stream接口经过FIFO时钟域转换后,还需要进行数据数据位宽转换,数据位宽的转换通过AXI4-Stream Data Width Converter完成。
在接收路径中,进行8bit到64bit的转换,AXI4-Stream DataWidth Converter设置如下图所示:
在发送路径中,进行64bit到8bit的转换,AXI4-Stream Data Width Converter设置如下图所示:
9程序测速
9.1硬件接线
以MK7325FA 开发板为测试样板,其他开发板使用也一样,其他开发板的接线见“ 附录 1 ”。
9.2环路测速连接任意一个网口连接,在例程中,电脑的IP地址为192.168.137.1,UDP端口号为6001,开发板中的所有网口的IP地址均为192.168.137.2,UDP端口号均为6002。 测试前,需要将所使用电脑网卡的IP地址设置为192.168.137.1,子网掩码设为255.255.255.0,如下图所示。
打开网络调试助手,分别设置好电脑和开发板的IP地址位和UDP端口号,通过网络调试助手以udp包的形式向开发板发送文字数据,并以1ms的间隔不断循环发送,如下图所示。
测试结果上图所示。从图中可以看出,网络调试助手所发出的udp包和开发板返回的udp包一致,接收和发送的数据包数量一致。 通过wireshark软件可捕获电脑和开发板之间的通信数据包,如下图所示。
在网络调试助手向开发板发UDP包的同时,通过cmd命令窗不断向开发板发起ping命令,观察ping命令的返回,如下图所示。从图中可以看到开发板能够快速响应电脑发起的ping命令,UDP数据包收发与ping应答互不干扰。
9.3发送测速第二个demo是发送测速,在电脑上观察开发板以太网网口的发送速率,这个测速只代表可能的最高的速度,不代表电脑真实的不丢包速度,UDP的点到点不丢包速度和电脑的网卡、CPU速度、内存速度、操作系统都有关系。 VIO虚拟IO设置: 本例中对千兆发送速率进行了测试。程序中添加了VIO IP核,用户可以通过VIO修改发送的UDP包长度以及发送间隔。 VIO共设置了3个输出端口,如下图所示。
VIO的3个输出参数为:
- trans_en,UDP包发送使能信号。1代表使能发送,0代表关闭发送。
- PACKET_LENGTH,发送UDP数据包的长度(不含UDP首部),单位为字节,可设置范围1~1472。
- PACKET_INTERVAL,UDP包发送间隔,单位为时钟周期数,可设置范围0~65535。
需要注意的是,在修改PACKET_LENGTH和PACKET_INTERVAL两个参数之前,必须先将trans_en设为0,停止UDP包发送,否则会产生错误。 不断以最小间隔循环发送1472字节的UDP包,用来测试协议栈的最高发送带宽。在VIO中先将trans_en设为0,再将PACKET_LENGTH设为1472,PACKET_INTERVAL设为0,然后将trans_en设为1,如下图所示。
测试结果 :
|