以太网详解(三)FPGA以太网IP配置(Quartus平台)
文章目录
- 前言
- GMII
- Core Configurations配置界面
- MAC Options配置界面
- FIFO Options配置界面
- Instantiation Template
- 接口详解
- RGMII
- Instantiation Template
- gmii_rgmii_bridge
- SGMII
- Core Configurations配置界面
- Instantiation Template
- 接口详解
前言
本文档主要介绍GRMII、RGMII、SGMII接口Quartus平台Triple-Speed Ethernet Intel FPGA IP的配置和注意事项。Quartus平台版本为Quartus Prime Pro 22.3。FPGA器件为Arria 10。硬件模式为1000BASE-T。
GMII
Core Configurations配置界面
选择MAC类型为10/100/1000Mb Ethernet MAC。
勾选使用内部FIFO缓存。
MAC Options配置界面
根据具体需求可以勾选不同的MAC功能选项:
Enable MAC 10/100 half duplex support
打开此选项以支持10/100 Mbps连接上的半双工操作。
Enable local loopback on MII/GMII/RGMII
打开此选项可以在MAC的MII、GMII或RGMII接口上启用本地环回。如果打开此选项,则可以在系统运行期间通过MAC配置寄存器动态启用或禁用环回功能。
Enable supplemental MAC unicast addresses
打开此选项以支持MAC单播地址,用于基于硬件的快速接收帧过滤。
【注】
MAC地址是以太网二层使用的一个48bit(6字节十六进制数)的地址,用来标识设备位置。MAC地址分成两部分,前24位是组织唯一标识符(OUI, Organizationally unique identifier),后24位由厂商自行分配。
MAC地址有单播、组播、广播之分。单播地址(unicast address)表示单一设备、节点,多播地址或者组播地址(multicast address、group address)表示一组设备、节点,广播地址(broadcast address)是组播的特例,表示所有地址,用全F表示:FF-FF-FF-FF-FF-FF。当然,三层的IP地址也有单播、组播、广播之分。
48bit的MAC地址一般用6字节的十六进制来表示,如XX-XX-XX-XX-XX。IEEE 802.3规定:以太网的第48bit用于表示这个地址是组播地址还是单播地址。如果这一位是0,表示此MAC地址是单播地址,如果这位是1,表示此MAC地址是多播地址。
Include statistics counters
打开此选项以包括对输入和输出以太网数据包的简单网络监视协议(SNMP)管理信息库(MIB)和远程监视(RMON)统计计数器寄存器的支持。默认情况下,所有统计计数器的宽度为32位。
Enable 64-bit statistics byte counters
打开此选项可将所选统计计数器的宽度扩展到64位。
Include multicast hashtable
打开此选项以实现哈希表,这是一种快速的基于硬件的机制,用于检测和过滤接收到的以太网数据包中的多播目标MAC地址。
Align packet headers to 32-bit boundary
打开此选项以包含将所有数据包头对齐到32位边界的逻辑。这有助于减少重新调整数据缓冲区时的软件开销。此选项可用于具有32位宽的内部FIFO缓冲区的MAC变体和没有内部FIFO缓冲区的MAC变体。如果您打算使Interniche TCP/IP协议栈,则必须打开此选项。
Enable full-duplex flow control
打开此选项以包含全双工流控制的逻辑,其中包括PAUSE帧生成和终止。
Enable VLAN detection
打开此选项以包含VLAN和堆叠VLAN帧检测的逻辑。关闭时,MAC不检测VLAN帧和绑定VLAN帧。MAC将这些帧转发给用户应用程序而不进行处理。
Enable magic packet detection
打开此选项以包含用于魔术包检测的逻辑(用于局域网唤醒)。
Include MDIO module (MDC/MDIO)
如果要访问连接到MAC功能的外部PHY设备,请打开此选项。当关闭时,核心不包括与MDIO接口相关的逻辑或信号。
Host clock divisor
MAC控制接口的时钟频率设置,产生MDIO接口上的MDC时钟输出。默认值为40。例如,MAC控制接口时钟频率为100MHz, MDC时钟频率为100Mhz/40=2.5 MHz,则分频系数设置为40。Intel建MDC频率不超过2.5 MHz。
搭建最小系统以上均可以不勾选,这里勾选Include MDIO module (MDC/MDIO)选项,因为外部接入的MAC控制接口时钟频率为125MHz,所以分频系数设置为50,MDC时钟频率为125Mhz/50=2.5 MHz。
FIFO Options配置界面
根据实际使用需求设置FIFO缓存位宽和深度。
其他IP界面保持默认设置。
Instantiation Template
eth u0 (.clk (_connected_to_clk_), // input, width = 1, control_port_clock_connection.clk.reset (_connected_to_reset_), // input, width = 1, reset_connection.reset.reg_addr (_connected_to_reg_addr_), // input, width = 8, control_port.address.reg_data_out (_connected_to_reg_data_out_), // output, width = 32, .readdata.reg_rd (_connected_to_reg_rd_), // input, width = 1, .read.reg_data_in (_connected_to_reg_data_in_), // input, width = 32, .writedata.reg_wr (_connected_to_reg_wr_), // input, width = 1, .write.reg_busy (_connected_to_reg_busy_), // output, width = 1, .waitrequest.ff_tx_clk (_connected_to_ff_tx_clk_), // input, width = 1, transmit_clock_connection.clk.ff_rx_clk (_connected_to_ff_rx_clk_), // input, width = 1, receive_clock_connection.clk.ff_rx_data (_connected_to_ff_rx_data_), // output, width = 8, receive.data.ff_rx_eop (_connected_to_ff_rx_eop_), // output, width = 1, .endofpacket.rx_err (_connected_to_rx_err_), // output, width = 6, .error.ff_rx_rdy (_connected_to_ff_rx_rdy_), // input, width = 1, .ready.ff_rx_sop (_connected_to_ff_rx_sop_), // output, width = 1, .startofpacket.ff_rx_dval (_connected_to_ff_rx_dval_), // output, width = 1, .valid.ff_tx_data (_connected_to_ff_tx_data_), // input, width = 8, transmit.data.ff_tx_eop (_connected_to_ff_tx_eop_), // input, width = 1, .endofpacket.ff_tx_err (_connected_to_ff_tx_err_), // input, width = 1, .error.ff_tx_rdy (_connected_to_ff_tx_rdy_), // output, width = 1, .ready.ff_tx_sop (_connected_to_ff_tx_sop_), // input, width = 1, .startofpacket.ff_tx_wren (_connected_to_ff_tx_wren_), // input, width = 1, .valid.ff_tx_crc_fwd (_connected_to_ff_tx_crc_fwd_), // input, width = 1, mac_misc_connection.ff_tx_crc_fwd.ff_tx_septy (_connected_to_ff_tx_septy_), // output, width = 1, .ff_tx_septy.tx_ff_uflow (_connected_to_tx_ff_uflow_), // output, width = 1, .tx_ff_uflow.ff_tx_a_full (_connected_to_ff_tx_a_full_), // output, width = 1, .ff_tx_a_full.ff_tx_a_empty (_connected_to_ff_tx_a_empty_), // output, width = 1, .ff_tx_a_empty.rx_err_stat (_connected_to_rx_err_stat_), // output, width = 18, .rx_err_stat.rx_frm_type (_connected_to_rx_frm_type_), // output, width = 4, .rx_frm_type.ff_rx_dsav (_connected_to_ff_rx_dsav_), // output, width = 1, .ff_rx_dsav.ff_rx_a_full (_connected_to_ff_rx_a_full_), // output, width = 1, .ff_rx_a_full.ff_rx_a_empty (_connected_to_ff_rx_a_empty_), // output, width = 1, .ff_rx_a_empty.mdc (_connected_to_mdc_), // output, width = 1, mac_mdio_connection.mdc.mdio_in (_connected_to_mdio_in_), // input, width = 1, .mdio_in.mdio_out (_connected_to_mdio_out_), // output, width = 1, .mdio_out.mdio_oen (_connected_to_mdio_oen_), // output, width = 1, .mdio_oen.gm_rx_d (_connected_to_gm_rx_d_), // input, width = 8, mac_gmii_connection.gmii_rx_d.gm_rx_dv (_connected_to_gm_rx_dv_), // input, width = 1, .gmii_rx_dv.gm_rx_err (_connected_to_gm_rx_err_), // input, width = 1, .gmii_rx_err.gm_tx_d (_connected_to_gm_tx_d_), // output, width = 8, .gmii_tx_d.gm_tx_en (_connected_to_gm_tx_en_), // output, width = 1, .gmii_tx_en.gm_tx_err (_connected_to_gm_tx_err_), // output, width = 1, .gmii_tx_err.m_rx_d (_connected_to_m_rx_d_), // input, width = 4, mac_mii_connection.mii_rx_d.m_rx_en (_connected_to_m_rx_en_), // input, width = 1, .mii_rx_dv.m_rx_err (_connected_to_m_rx_err_), // input, width = 1, .mii_rx_err.m_tx_d (_connected_to_m_tx_d_), // output, width = 4, .mii_tx_d.m_tx_en (_connected_to_m_tx_en_), // output, width = 1, .mii_tx_en.m_tx_err (_connected_to_m_tx_err_), // output, width = 1, .mii_tx_err.set_10 (_connected_to_set_10_), // input, width = 1, mac_status_connection.set_10.set_1000 (_connected_to_set_1000_), // input, width = 1, .set_1000.eth_mode (_connected_to_eth_mode_), // output, width = 1, .eth_mode.ena_10 (_connected_to_ena_10_), // output, width = 1, .ena_10.tx_clk (_connected_to_tx_clk_), // input, width = 1, pcs_mac_tx_clock_connection.clk.rx_clk (_connected_to_rx_clk_) // input, width = 1, pcs_mac_rx_clock_connection.clk);
其中,必须要接的接口为以下接口
eth eth_inst (.clk (clk_125M), // input, width = 1, control_port_clock_connection.clk.reset (~i_rst_n), // input, width = 1, reset_connection.reset.reg_addr (eth_address), // input, width = 8, control_port.address.reg_data_out (eth_readdata), // output, width = 32, .readdata.reg_rd (eth_read), // input, width = 1, .read.reg_data_in (eth_writedata), // input, width = 32, .writedata.reg_wr (eth_write), // input, width = 1, .write.reg_busy (eth_waitrequest), // output, width = 1, .waitrequest.ff_tx_clk (clk_125M), // input, width = 1, transmit_clock_connection.clk.ff_rx_clk (clk_125M), // input, width = 1, receive_clock_connection.clk.ff_rx_data (mac_rx_tdata), // output, width = 8, receive.data.ff_rx_eop (mac_rx_tlast), // output, width = 1, .endofpacket.rx_err (), // output, width = 6, .error.ff_rx_rdy (mac_rx_tready), // input, width = 1, .ready.ff_rx_sop (), // output, width = 1, .startofpacket.ff_rx_dval (mac_rx_tvalid), // output, width = 1, .valid.ff_tx_data (mac_tx_tdata), // input, width = 8, transmit.data.ff_tx_eop (mac_tx_tlast), // input, width = 1, .endofpacket.ff_tx_err (1'b0), // input, width = 1, .error.ff_tx_rdy (mac_tx_tready), // output, width = 1, .ready.ff_tx_sop (mac_tx_tfirst), // input, width = 1, .startofpacket.ff_tx_wren (mac_tx_tvalid), // input, width = 1, .valid.ff_tx_crc_fwd (), // input, width = 1, mac_misc_connection.ff_tx_crc_fwd.ff_tx_septy (), // output, width = 1, .ff_tx_septy.tx_ff_uflow (), // output, width = 1, .tx_ff_uflow.ff_tx_a_full (), // output, width = 1, .ff_tx_a_full.ff_tx_a_empty (), // output, width = 1, .ff_tx_a_empty.rx_err_stat (), // output, width = 18, .rx_err_stat.rx_frm_type (), // output, width = 4, .rx_frm_type.ff_rx_dsav (), // output, width = 1, .ff_rx_dsav.ff_rx_a_full (), // output, width = 1, .ff_rx_a_full.ff_rx_a_empty (), // output, width = 1, .ff_rx_a_empty.mdc (mdc), // output, width = 1, mac_mdio_connection.mdc.mdio_in (mdio_in), // input, width = 1, .mdio_in.mdio_out (mdio_out), // output, width = 1, .mdio_out.mdio_oen (mdio_oen), // output, width = 1, .mdio_oen.gm_rx_d (gm_rx_d), // input, width = 8, mac_gmii_connection.gmii_rx_d.gm_rx_dv (gm_rx_dv), // input, width = 1, .gmii_rx_dv.gm_rx_err (gm_rx_err), // input, width = 1, .gmii_rx_err.gm_tx_d (gm_tx_d), // output, width = 8, .gmii_tx_d.gm_tx_en (gm_tx_en), // output, width = 1, .gmii_tx_en.gm_tx_err (gm_tx_err), // output, width = 1, .gmii_tx_err.m_rx_d (), // input, width = 4, mac_mii_connection.mii_rx_d.m_rx_en (), // input, width = 1, .mii_rx_dv.m_rx_err (), // input, width = 1, .mii_rx_err.m_tx_d (), // output, width = 4, .mii_tx_d.m_tx_en (), // output, width = 1, .mii_tx_en.m_tx_err (), // output, width = 1, .mii_tx_err.set_10 (1'b0), // input, width = 1, mac_status_connection.set_10.set_1000 (1'b1), // input, width = 1, .set_1000.eth_mode (), // output, width = 1, .eth_mode.ena_10 (), // output, width = 1, .ena_10.tx_clk (gm_tx_c), // input, width = 1, pcs_mac_tx_clock_connection.clk.rx_clk (gm_rx_c) // input, width = 1, pcs_mac_rx_clock_connection.clk);
接口详解
以下接口为MAC配置接口,连接MAC配置模块。
.clk (clk_125M), // input, width = 1, control_port_clock_connection.clk.reset (~i_rst_n), // input, width = 1, reset_connection.reset.reg_addr (eth_address), // input, width = 8, control_port.address.reg_data_out (eth_readdata), // output, width = 32, .readdata.reg_rd (eth_read), // input, width = 1, .read.reg_data_in (eth_writedata), // input, width = 32, .writedata.reg_wr (eth_write), // input, width = 1, .write.reg_busy (eth_waitrequest), // output, width = 1, .waitrequest
以下接口为MAC传输接口,连接UDP模块。
传输层采用UDP协议,UDP模块为OpenCores开源模块。
链接:
https://opencores.org/websvn/listing?repname=udp_ip_stack&path=%2Fudp_ip_stack%2Ftrunk%2Frtl%2Fvhdl%2F#path_udp_ip_stack_trunk_rtl_vhdl_
.ff_tx_clk (clk_125M), // input, width = 1, transmit_clock_connection.clk.ff_rx_clk (clk_125M), // input, width = 1, receive_clock_connection.clk.ff_rx_data (mac_rx_tdata), // output, width = 8, receive.data.ff_rx_eop (mac_rx_tlast), // output, width = 1, .endofpacket.rx_err (), // output, width = 6, .error.ff_rx_rdy (mac_rx_tready), // input, width = 1, .ready.ff_rx_sop (), // output, width = 1, .startofpacket.ff_rx_dval (mac_rx_tvalid), // output, width = 1, .valid.ff_tx_data (mac_tx_tdata), // input, width = 8, transmit.data.ff_tx_eop (mac_tx_tlast), // input, width = 1, .endofpacket.ff_tx_err (1'b0), // input, width = 1, .error.ff_tx_rdy (mac_tx_tready), // output, width = 1, .ready.ff_tx_sop (mac_tx_tfirst), // input, width = 1, .startofpacket.ff_tx_wren (mac_tx_tvalid), // input, width = 1, .valid
以下接口为PHY管理接口。
.mdc (mdc), // output, width = 1, mac_mdio_connection.mdc.mdio_in (mdio_in), // input, width = 1, .mdio_in.mdio_out (mdio_out), // output, width = 1, .mdio_out.mdio_oen (mdio_oen), // output, width = 1, .mdio_oen
//MDIO
output mdc, // Marvell PHY management data refclk
inout mdio, // Marvell PHY management data// -------------------------------------------------------------------------
// MDIO ports connection
// -------------------------------------------------------------------------
assign mdio = mdio_oen ? 1'bz : mdio_out;
assign mdio_in = mdio;
以下接口为MAC状态接口。
配置为千兆模式。
.set_10 (1'b0), // input, width = 1, mac_status_connection.set_10.set_1000 (1'b1), // input, width = 1, .set_1000.eth_mode (), // output, width = 1, .eth_mode.ena_10 (), // output, width = 1, .ena_10
以下接口为GMII接口。
.gm_rx_d (gm_rx_d), // input, width = 8, mac_gmii_connection.gmii_rx_d.gm_rx_dv (gm_rx_dv), // input, width = 1, .gmii_rx_dv.gm_rx_err (gm_rx_err), // input, width = 1, .gmii_rx_err.gm_tx_d (gm_tx_d), // output, width = 8, .gmii_tx_d.gm_tx_en (gm_tx_en), // output, width = 1, .gmii_tx_en.gm_tx_err (gm_tx_err), // output, width = 1, .gmii_tx_err.tx_clk (gm_tx_c), // input, width = 1, pcs_mac_tx_clock_connection.clk.rx_clk (gm_rx_c) // input, width = 1, pcs_mac_rx_clock_connection.clk
RGMII
从英特尔Quartus Prime软件版本17.1起,在英特尔Stratix 10、英特尔Arria 10和英特尔Cyclone 10 GX设备中不支持RGMII接口。
所以RGMII的IP配置与GMII相同,在外部使用gmii_rgmii_bridge模块实现RGMII接口与GMII接口的转换。
Instantiation Template
gmii_rgmii_bridge gmii_rgmii_bridge_inst(//RGMII.rgmii_rxc (rgmii_rxc),.rgmii_rxd (rgmii_rxd),.rgmii_rx_ctl (rgmii_rx_ctl),.rgmii_txd (rgmii_txd),.rgmii_tx_ctl (rgmii_tx_ctl),//GMII.gm_rx_c (gm_rx_c),.gm_rx_d (gm_rx_d),.gm_rx_dv (gm_rx_dv),.gm_rx_err (gm_rx_err),.gm_tx_c (gm_tx_c_temp),.gm_tx_d (gm_tx_d),.gm_tx_en (gm_tx_en),.gm_tx_err (gm_tx_err));
gmii_rgmii_bridge
gmii_rgmii_bridge模块源码如下:
`timescale 1ns / 1ps
//==============================================================================
// Company:
// Engineer: G2突破手259
//
// Create Date:
// Design Name:
// Module Name: gmii_rgmii_bridge
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision: 1.0
// Revision
// Additional Comments:
//
//==============================================================================module gmii_rgmii_bridge
(//RGMIIinput [3:0] rgmii_rxd,input rgmii_rx_ctl,input rgmii_rxc,output [3:0] rgmii_txd,output rgmii_tx_ctl,//GMIIoutput gm_rx_c,output [7:0] gm_rx_d,output gm_rx_dv,output gm_rx_err,input gm_tx_c,input [7:0] gm_tx_d,input gm_tx_en,input gm_tx_err
);ddio_in ddio_in_inst
(.ck (rgmii_rxc), // input, width = 1, ck.export.dout (gm_rx_d), // output, width = 8, dout.export.pad_in (rgmii_rxd) // input, width = 4, pad_in.export
);ddio_out ddio_out_inst
(.ck (gm_tx_c), // input, width = 1, ck.export.din (gm_tx_d), // input, width = 8, din.export.pad_out (rgmii_txd) // output, width = 4, pad_out.export
);ctrl_in ctrl_in_inst
(.ck (rgmii_rxc), // input, width = 1, ck.export.dout (gm_rx_dv), // output, width = 1, dout.export.pad_in (rgmii_rx_ctl) // input, width = 1, pad_in.export
);ctrl_out ctrl_out_inst
(.ck (gm_tx_c), // input, width = 1, ck.export.din (gm_tx_en), // input, width = 1, din.export.pad_out (rgmii_tx_ctl) // output, width = 1, pad_out.export
);assign gm_rx_c = rgmii_rxc;
assign gm_rx_err = 1'b0;endmodule
ddio_in配置界面如下所示:
ddio_out配置界面如下所示:
ctrl_in配置界面如下所示:
ctrl_out配置界面如下所示:
SGMII
Core Configurations配置界面
选择MAC类型为10/100/1000Mb Ethernet MAC with 1000BASE-X/SGMII PCS。选择这个类型,IP用户接口与GMII、RGMII一样是MAC传输接口,连接UDP模块更加方便。如果选择1000BASE-X/SGMII PCS only,IP用户接口是GMII接口,实现GMII接口与SGMII接口的转接功能。
PCS Transceiver type选择LVDS I/O,也可以选择GXB,根据硬件设计自由选择,这里因为GXB资源比较紧张,所以选择使用LVDS I/O。硬件分配FPGA IO时,需要注意以下事项:
1.SGMII的TX、RX,LVDS的参考时钟需要放在同一个Bank
2.为了防止潜在的性能问题,请确保LVDS的参考时钟直接使用同一I/O bank内的专用参考时钟输入。不建议手动提升参考时钟。
3.RX要放在支持Soft-CDR功能的差分引脚,即偶数编号的差分引脚,这个是必须的,不然会有以下报错。
解决方案链接:https://www.intel.com/content/www/us/en/programmable/quartushelp/current/index.htm#msgs/msgs/elvds_nf_invalid_cdr_constraint.htm
其他IP界面配置与GMII一致。
Instantiation Template
eth u0 (.ff_tx_clk (_connected_to_ff_tx_clk_), // input, width = 1, transmit_clock_connection.clk.ff_rx_clk (_connected_to_ff_rx_clk_), // input, width = 1, receive_clock_connection.clk.ff_rx_data (_connected_to_ff_rx_data_), // output, width = 8, receive.data.ff_rx_eop (_connected_to_ff_rx_eop_), // output, width = 1, .endofpacket.rx_err (_connected_to_rx_err_), // output, width = 6, .error.ff_rx_rdy (_connected_to_ff_rx_rdy_), // input, width = 1, .ready.ff_rx_sop (_connected_to_ff_rx_sop_), // output, width = 1, .startofpacket.ff_rx_dval (_connected_to_ff_rx_dval_), // output, width = 1, .valid.ff_tx_data (_connected_to_ff_tx_data_), // input, width = 8, transmit.data.ff_tx_eop (_connected_to_ff_tx_eop_), // input, width = 1, .endofpacket.ff_tx_err (_connected_to_ff_tx_err_), // input, width = 1, .error.ff_tx_rdy (_connected_to_ff_tx_rdy_), // output, width = 1, .ready.ff_tx_sop (_connected_to_ff_tx_sop_), // input, width = 1, .startofpacket.ff_tx_wren (_connected_to_ff_tx_wren_), // input, width = 1, .valid.ff_tx_crc_fwd (_connected_to_ff_tx_crc_fwd_), // input, width = 1, mac_misc_connection.ff_tx_crc_fwd.ff_tx_septy (_connected_to_ff_tx_septy_), // output, width = 1, .ff_tx_septy.tx_ff_uflow (_connected_to_tx_ff_uflow_), // output, width = 1, .tx_ff_uflow.ff_tx_a_full (_connected_to_ff_tx_a_full_), // output, width = 1, .ff_tx_a_full.ff_tx_a_empty (_connected_to_ff_tx_a_empty_), // output, width = 1, .ff_tx_a_empty.rx_err_stat (_connected_to_rx_err_stat_), // output, width = 18, .rx_err_stat.rx_frm_type (_connected_to_rx_frm_type_), // output, width = 4, .rx_frm_type.ff_rx_dsav (_connected_to_ff_rx_dsav_), // output, width = 1, .ff_rx_dsav.ff_rx_a_full (_connected_to_ff_rx_a_full_), // output, width = 1, .ff_rx_a_full.ff_rx_a_empty (_connected_to_ff_rx_a_empty_), // output, width = 1, .ff_rx_a_empty.mdc (_connected_to_mdc_), // output, width = 1, mac_mdio_connection.mdc.mdio_in (_connected_to_mdio_in_), // input, width = 1, .mdio_in.mdio_out (_connected_to_mdio_out_), // output, width = 1, .mdio_out.mdio_oen (_connected_to_mdio_oen_), // output, width = 1, .mdio_oen.clk (_connected_to_clk_), // input, width = 1, control_port_clock_connection.clk.reset (_connected_to_reset_), // input, width = 1, reset_connection.reset.reg_data_out (_connected_to_reg_data_out_), // output, width = 32, control_port.readdata.reg_rd (_connected_to_reg_rd_), // input, width = 1, .read.reg_data_in (_connected_to_reg_data_in_), // input, width = 32, .writedata.reg_wr (_connected_to_reg_wr_), // input, width = 1, .write.reg_busy (_connected_to_reg_busy_), // output, width = 1, .waitrequest.reg_addr (_connected_to_reg_addr_), // input, width = 8, .address.ref_clk (_connected_to_ref_clk_), // input, width = 1, pcs_ref_clk_clock_connection.clk.led_crs (_connected_to_led_crs_), // output, width = 1, status_led_connection.crs.led_link (_connected_to_led_link_), // output, width = 1, .link.led_panel_link (_connected_to_led_panel_link_), // output, width = 1, .panel_link.led_col (_connected_to_led_col_), // output, width = 1, .col.led_an (_connected_to_led_an_), // output, width = 1, .an.led_char_err (_connected_to_led_char_err_), // output, width = 1, .char_err.led_disp_err (_connected_to_led_disp_err_), // output, width = 1, .disp_err.rx_recovclkout (_connected_to_rx_recovclkout_), // output, width = 1, serdes_control_connection.export.rxp (_connected_to_rxp_), // input, width = 1, serial_connection.rxp_0.txp (_connected_to_txp_) // output, width = 1, .txp_0);
其中,必须要接的接口为以下接口
eth eth_inst (.ff_tx_clk (clk_125M), // input, width = 1, transmit_clock_connection.clk.ff_rx_clk (clk_125M), // input, width = 1, receive_clock_connection.clk.ff_rx_data (mac_rx_tdata), // output, width = 8, receive.data.ff_rx_eop (mac_rx_tlast), // output, width = 1, .endofpacket.rx_err (), // output, width = 6, .error.ff_rx_rdy (mac_rx_tready), // input, width = 1, .ready.ff_rx_sop (), // output, width = 1, .startofpacket.ff_rx_dval (mac_rx_tvalid), // output, width = 1, .valid.ff_tx_data (mac_tx_tdata), // input, width = 8, transmit.data.ff_tx_eop (mac_tx_tlast), // input, width = 1, .endofpacket.ff_tx_err (1'b0), // input, width = 1, .error.ff_tx_rdy (mac_tx_tready), // output, width = 1, .ready.ff_tx_sop (mac_tx_tfirst), // input, width = 1, .startofpacket.ff_tx_wren (mac_tx_tvalid), // input, width = 1, .valid.ff_tx_crc_fwd (), // input, width = 1, mac_misc_connection.ff_tx_crc_fwd.ff_tx_septy (), // output, width = 1, .ff_tx_septy.tx_ff_uflow (), // output, width = 1, .tx_ff_uflow.ff_tx_a_full (), // output, width = 1, .ff_tx_a_full.ff_tx_a_empty (), // output, width = 1, .ff_tx_a_empty.rx_err_stat (), // output, width = 18, .rx_err_stat.rx_frm_type (), // output, width = 4, .rx_frm_type.ff_rx_dsav (), // output, width = 1, .ff_rx_dsav.ff_rx_a_full (), // output, width = 1, .ff_rx_a_full.ff_rx_a_empty (), // output, width = 1, .ff_rx_a_empty.mdc (mdc), // output, width = 1, mac_mdio_connection.mdc.mdio_in (mdio_in), // input, width = 1, .mdio_in.mdio_out (mdio_out), // output, width = 1, .mdio_out.mdio_oen (mdio_oen), // output, width = 1, .mdio_oen.clk (clk_125M), // input, width = 1, control_port_clock_connection.clk.reset (~i_rst_n), // input, width = 1, reset_connection.reset.reg_data_out (eth_readdata), // output, width = 32, control_port.readdata.reg_rd (eth_read), // input, width = 1, .read.reg_data_in (eth_writedata), // input, width = 32, .writedata.reg_wr (eth_write), // input, width = 1, .write.reg_busy (eth_waitrequest), // output, width = 1, .waitrequest.reg_addr (eth_address), // input, width = 8, .address.ref_clk (sgmii_clk), // input, width = 1, pcs_ref_clk_clock_connection.clk.led_crs (), // output, width = 1, status_led_connection.crs.led_link (), // output, width = 1, .link.led_panel_link (), // output, width = 1, .panel_link.led_col (), // output, width = 1, .col.led_an (), // output, width = 1, .an.led_char_err (), // output, width = 1, .char_err.led_disp_err (), // output, width = 1, .disp_err.rx_recovclkout (), // output, width = 1, serdes_control_connection.export.rxp (sgmii_rxd), // input, width = 1, serial_connection.rxp_0.txp (sgmii_txd) // output, width = 1, .txp_0);
接口详解
以下接口为SGMII接口。
.ref_clk (sgmii_clk), // input, width = 1, pcs_ref_clk_clock_connection.clk.rxp (sgmii_rxd), // input, width = 1, serial_connection.rxp_0.txp (sgmii_txd) // output, width = 1, .txp_0
需要注意,SGMII使用的是without CLK模式,这里的sgmii_clk是pcs的参考时钟,接的是125Mhz晶振。