文章目录
前言
本文档主要介绍 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
(
//RGMII
input [3:0] rgmii_rxd,
input rgmii_rx_ctl,
input rgmii_rxc,
output [3:0] rgmii_txd,
output rgmii_tx_ctl,
//GMII
output 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 功能的差分引脚。必须将 RX 接口放在同一 I/O bank 中,而每个 bank 只有 12 个 PCLK 资源,所以只有 12 个 Soft-CDR 通道可用。 要了解每个 bank 中哪些引脚对可以支持 Soft-CDR 通道,请参阅设备引脚输出文件。在设备引脚输出文件中,“Dedicated Tx/Rx Channel” 列出了可用 LVDS 引脚。
LVDS<bank number>_<pin pair><p or n>
如果 pin pair 为偶数,表示该引脚对支持 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 晶振。