Bootstrap

以太网详解(三)FPGA以太网IP配置(Quartus平台)

前言

本文档主要介绍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功能的差分引脚,即偶数编号的差分引脚,这个是必须的,不然会有以下报错。
在这里插入图片描述
解决方案链接: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晶振。

;