alexforencich / verilog-ethernet

Verilog Ethernet components for FPGA implementation
MIT License
2.25k stars 694 forks source link

export to ku060 #229

Open andylgh opened 1 week ago

andylgh commented 1 week ago

I referenced the ExaNIC_X10 project and ported it to my own Ku060 board. Now, I have a problem where I downloaded the program to the board but the network card is not connected. The top-level is as follows:

module udp_stack_10g # ( parameter C_S_AXI_ADDR_WIDTH = 8, parameter C_S_AXI_DATA_WIDTH = 32,

parameter                                   TARGET                  = "XILINX",
parameter                                   DW                      = 64,
parameter                                   KW                      = DW/8,
//  fpga
parameter       [31:0]                      C_SRC_IP_ADDR           = {8'd192,8'd168,8'd2,8'd101},    
parameter       [15:0]                      C_SRC_UDP_PORT          = 1234,   
parameter       [31:0]                      C_SRC_GATEWAY_IP        = {8'd192,8'd168,8'd2,8'd1},   
parameter       [31:0]                      C_SRC_SUBNET_MASK       = {8'd255,8'd255,8'd255,8'd0},  
parameter       [47:0]                      C_SRC_MAC_ADDR          = 48'h00_0a_35_00_1e_53,        
//  pc                                                
parameter       [31:0]                      C_DST_IP_ADDR           = {8'd192,8'd168,8'd2,8'd100},
parameter       [15:0]                      C_DST_UDP_PORT          = 4001  

)( // AXI4_LITE
// System Signals input wire clk, // 156.25Mhz input wire reset_n, // Slave Interface Write Address Ports input wire [C_S_AXI_ADDR_WIDTH-1:0] s_axi_awaddr, input wire s_axi_awvalid,
output wire s_axi_awready,

//  Slave Interface Write Data Ports                                                                                                                                                                                
input   wire    [C_S_AXI_DATA_WIDTH-1:0]    s_axi_wdata,
input   wire    [C_S_AXI_DATA_WIDTH/8-1:0]  s_axi_wstrb,
input   wire                                s_axi_wvalid,
output  wire                                s_axi_wready,

//  Slave Interface Write Response Ports
output  wire    [1:0]                       s_axi_bresp,
output  wire                                s_axi_bvalid,
input   wire                                s_axi_bready,

//  Slave Interface Read Address Ports                                                                                                                                                                              
input   wire    [C_S_AXI_ADDR_WIDTH-1:0]    s_axi_araddr,
input   wire                                s_axi_arvalid,
output  wire                                s_axi_arready,

//  Slave Interface Read Data Ports
output  wire    [C_S_AXI_DATA_WIDTH-1:0]    s_axi_rdata,
output  wire    [1:0]                       s_axi_rresp,
output  wire                                s_axi_rvalid,
input   wire                                s_axi_rready,

//  user interface                          
//  tx(fpga -> pc)                          
input   wire    [DW-1:0]                    usr_s_axis_tdata,
input   wire    [KW-1:0]                    usr_s_axis_tkeep,
input   wire                                usr_s_axis_tvalid,
output  wire                                usr_s_axis_tready,
input   wire                                usr_s_axis_tlast,
input   wire                                usr_s_axis_tuser,

//  rx(pc -> fpga)                          
output  wire    [DW-1:0]                    usr_m_axis_tdata,
output  wire    [KW-1:0]                    usr_m_axis_tkeep,
output  wire                                usr_m_axis_tvalid,
input   wire                                usr_m_axis_tready,
output  wire                                usr_m_axis_tlast,
output  wire                                usr_m_axis_tuser,    

//input   wire                                clk_100m_p,
//input   wire                                clk_100m_n,   
input   wire                                i_clk_125m,
input   wire                                i_mmcm_lock,    

//  10G Ethernet: SFP BASE_R
input   wire                                sfp_refclk_p,
input   wire                                sfp_refclk_n,

input   wire                                sfp_rx_p,
input   wire                                sfp_rx_n,
output  wire                                sfp_tx_p,
output  wire                                sfp_tx_n

); //** // 内部信号定义 //**
wire [4:0] cmd_phy_addr; wire [4:0] cmd_reg_addr; wire [15:0] cmd_data; wire [1:0] cmd_opcode; wire cmd_start; // pulse wire [15:0] phy_rdata; wire [7:0] prescale; wire mdio_busy;

wire            [31:0]                      src_ip_addr;    
wire            [15:0]                      src_udp_port;   
wire            [31:0]                      src_gateway_ip; 
wire            [31:0]                      src_subnet_mask;
wire            [47:0]                      src_mac_addr;   
wire            [31:0]                      dst_ip_addr;    
wire            [15:0]                      dst_udp_port;  
wire            [1:0]                       phy_speed;

wire                                        usr_rst;

//  udp <-> mac
//  mac(m) -> udp(s)
wire            [DW-1:0]                    mac_s_axis_tdata;
wire            [KW-1:0]                    mac_s_axis_tkeep;
wire                                        mac_s_axis_tvalid;
wire                                        mac_s_axis_tready;
wire                                        mac_s_axis_tlast;
wire                                        mac_s_axis_tuser;

//  udp(m) -> mac(s)                                            
wire            [DW-1:0]                    mac_m_axis_tdata;
wire            [KW-1:0]                    mac_m_axis_tkeep;
wire                                        mac_m_axis_tvalid;
wire                                        mac_m_axis_tready;
wire                                        mac_m_axis_tlast;
wire                                        mac_m_axis_tuser;

//  10G phy
wire            [63:0]                      xgmii_sfp_txd;
wire            [7:0]                       xgmii_sfp_txc;
wire            [63:0]                      xgmii_sfp_rxd;
wire            [7:0]                       xgmii_sfp_rxc;
wire                                        xgmii_rx_clk_156mhz;
wire                                        xgmii_rx_rst_156mhz;
wire                                        xgmii_tx_clk_156mhz;
wire                                        xgmii_tx_rst_156mhz;

wire                                        sfp_mgt_refclk;
wire                                        phy_rx_block_lock;
wire                                        sfp_qpll0lock;
wire                                        sfp_qpll0outclk;
wire                                        sfp_qpll0outrefclk;

//******************************************************************************
//                      主控逻辑
//******************************************************************************  
udp_stack_reg #(
    .C_S_AXI_ADDR_WIDTH     (   C_S_AXI_ADDR_WIDTH  ),                                                                                                                                       
    .C_S_AXI_DATA_WIDTH     (   C_S_AXI_DATA_WIDTH  ),
    .C_SRC_IP_ADDR          (   C_SRC_IP_ADDR       ),    
    .C_SRC_UDP_PORT         (   C_SRC_UDP_PORT      ),
    .C_SRC_GATEWAY_IP       (   C_SRC_GATEWAY_IP    ),
    .C_SRC_SUBNET_MASK      (   C_SRC_SUBNET_MASK   ),
    .C_SRC_MAC_ADDR         (   C_SRC_MAC_ADDR      ),
    .C_DST_IP_ADDR          (   C_DST_IP_ADDR       ),
    .C_DST_UDP_PORT         (   C_DST_UDP_PORT      )
) udp_stack_reg (            
    //  axi lite slave                                                                                                                                                                                                              
    .s_axi_aclk             (   clk                 ),                                                                                                                                                             
    .s_axi_aresetn          (   reset_n             ),
    .s_axi_awaddr           (   s_axi_awaddr        ),                                                                                                                                                           
    .s_axi_awvalid          (   s_axi_awvalid       ),                                                                                                                                                          
    .s_axi_awready          (   s_axi_awready       ),
    .s_axi_wdata            (   s_axi_wdata         ),                                                                                                                                                            
    .s_axi_wstrb            (   s_axi_wstrb         ),                                                                                                                                                            
    .s_axi_wvalid           (   s_axi_wvalid        ),                                                                                                                                                           
    .s_axi_wready           (   s_axi_wready        ),
    .s_axi_bresp            (   s_axi_bresp         ),                                                                                                                                                            
    .s_axi_bvalid           (   s_axi_bvalid        ),                                                                                                                                                           
    .s_axi_bready           (   s_axi_bready        ),
    .s_axi_araddr           (   s_axi_araddr        ),                                                                                                                                                           
    .s_axi_arvalid          (   s_axi_arvalid       ),                                                                                                                                                          
    .s_axi_arready          (   s_axi_arready       ),
    .s_axi_rdata            (   s_axi_rdata         ),                                                                                                                                                            
    .s_axi_rresp            (   s_axi_rresp         ),                                                                                                                                                            
    .s_axi_rvalid           (   s_axi_rvalid        ),                                                                                                                                                           
    .s_axi_rready           (   s_axi_rready        ),   

    //  User register       
    .cmd_phy_addr           (   cmd_phy_addr        ),
    .cmd_reg_addr           (   cmd_reg_addr        ),
    .cmd_data               (   cmd_data            ),
    .cmd_opcode             (   cmd_opcode          ),
    .cmd_start              (   cmd_start           ),
    .phy_rdata              (   phy_rdata           ),
    .prescale               (   prescale            ),  
    .mdio_busy              (   mdio_busy           ),

    .src_ip_addr            (   src_ip_addr         ),
    .src_udp_port           (   src_udp_port        ),
    .src_gateway_ip         (   src_gateway_ip      ),
    .src_subnet_mask        (   src_subnet_mask     ),
    .src_mac_addr           (   src_mac_addr        ),
    .dst_ip_addr            (   dst_ip_addr         ),
    .dst_udp_port           (   dst_udp_port        ),
    .usr_rst                (   usr_rst             ),
    .phy_speed              (   phy_speed           )
); 

assign  phy_rdata = 16'd0;
assign  mdio_busy = 1'b0;
assign  phy_speed = {phy_rx_block_lock,sfp_qpll0lock};
//---------------------------------udp--------------------------------------------------
//  udp_stack
udp_stack_logic #
(
    .TARGET                 (   TARGET              ),
    .DW                     (   64                  )
)udp_stack_logic(           

    .clk                    (   clk                 ),
    .rst                    (   ~reset_n            ),

    .src_ip_addr            (   src_ip_addr         ),
    .src_udp_port           (   src_udp_port        ),
    .src_gateway_ip         (   src_gateway_ip      ),
    .src_subnet_mask        (   src_subnet_mask     ),
    .src_mac_addr           (   src_mac_addr        ),
    .dst_ip_addr            (   dst_ip_addr         ),
    .dst_udp_port           (   dst_udp_port        ),
    //  tx(fpga -> pc)                           
    .usr_s_axis_tdata       (   usr_s_axis_tdata    ),
    .usr_s_axis_tkeep       (   usr_s_axis_tkeep    ),
    .usr_s_axis_tvalid      (   usr_s_axis_tvalid   ),
    .usr_s_axis_tready      (   usr_s_axis_tready   ),
    .usr_s_axis_tlast       (   usr_s_axis_tlast    ),
    .usr_s_axis_tuser       (   usr_s_axis_tuser    ),
    //  rx(pc -> fpga)                          
    .usr_m_axis_tdata       (   usr_m_axis_tdata    ),
    .usr_m_axis_tkeep       (   usr_m_axis_tkeep    ),
    .usr_m_axis_tvalid      (   usr_m_axis_tvalid   ),
    .usr_m_axis_tready      (   usr_m_axis_tready   ),
    .usr_m_axis_tlast       (   usr_m_axis_tlast    ),
    .usr_m_axis_tuser       (   usr_m_axis_tuser    ),

    .mac_s_axis_tdata       (   mac_s_axis_tdata    ),
    .mac_s_axis_tkeep       (   mac_s_axis_tkeep    ),
    .mac_s_axis_tvalid      (   mac_s_axis_tvalid   ),
    .mac_s_axis_tready      (   mac_s_axis_tready   ),
    .mac_s_axis_tlast       (   mac_s_axis_tlast    ),
    .mac_s_axis_tuser       (   mac_s_axis_tuser    ),

    .mac_m_axis_tdata       (   mac_m_axis_tdata    ),
    .mac_m_axis_tkeep       (   mac_m_axis_tkeep    ),
    .mac_m_axis_tvalid      (   mac_m_axis_tvalid   ),
    .mac_m_axis_tready      (   mac_m_axis_tready   ),
    .mac_m_axis_tlast       (   mac_m_axis_tlast    ),
    .mac_m_axis_tuser       (   mac_m_axis_tuser    )
);

//  mac(fifo:32KB)
eth_mac_10g_fifo #(
    .ENABLE_PADDING         (   1                   ),
    .ENABLE_DIC             (   1                   ),
    .MIN_FRAME_LENGTH       (   64                  ),
    .TX_FIFO_DEPTH          (   4096                ),
    .TX_FRAME_FIFO          (   1                   ),
    .RX_FIFO_DEPTH          (   4096                ),
    .RX_FRAME_FIFO          (   1                   )
)eth_mac_10g_fifo_inst      (
    .rx_clk                 (   xgmii_rx_clk_156mhz ),  //  同步xgmii_rxd
    .rx_rst                 (   xgmii_rx_rst_156mhz ),
    .tx_clk                 (   xgmii_tx_clk_156mhz ),  //  同步xgmii_txd
    .tx_rst                 (   xgmii_tx_rst_156mhz ),

    .logic_clk              (   clk                 ),
    .logic_rst              (   ~reset_n            ),

    .tx_axis_tdata          (   mac_m_axis_tdata    ),
    .tx_axis_tkeep          (   mac_m_axis_tkeep    ),
    .tx_axis_tvalid         (   mac_m_axis_tvalid   ),
    .tx_axis_tready         (   mac_m_axis_tready   ),
    .tx_axis_tlast          (   mac_m_axis_tlast    ),
    .tx_axis_tuser          (   mac_m_axis_tuser    ),

    .rx_axis_tdata          (   mac_s_axis_tdata    ),
    .rx_axis_tkeep          (   mac_s_axis_tkeep    ),
    .rx_axis_tvalid         (   mac_s_axis_tvalid   ),
    .rx_axis_tready         (   mac_s_axis_tready   ),
    .rx_axis_tlast          (   mac_s_axis_tlast    ),
    .rx_axis_tuser          (   mac_s_axis_tuser    ),

    .xgmii_rxd              (   xgmii_sfp_rxd       ),
    .xgmii_rxc              (   xgmii_sfp_rxc       ),
    .xgmii_txd              (   xgmii_sfp_txd       ),
    .xgmii_txc              (   xgmii_sfp_txc       ),

    .tx_fifo_overflow       (                       ),
    .tx_fifo_bad_frame      (                       ),
    .tx_fifo_good_frame     (                       ),
    .rx_error_bad_frame     (                       ),
    .rx_error_bad_fcs       (                       ),
    .rx_fifo_overflow       (                       ),
    .rx_fifo_bad_frame      (                       ),
    .rx_fifo_good_frame     (                       ),

    .ifg_delay              (   8'd12               )
);

//  xilinx phy(pcs+pma): include share logic in the core

wire                        clk_125m_rst;  

sync_reset #(
    .N                      (   4                   )
)sync_reset (                              
    .clk                    (   i_clk_125m          ),
    .rst                    (   ~i_mmcm_lock        ),
    .out                    (   clk_125m_rst        )
);

IBUFDS_GTE3     ibufds_gte3_sfp_mgt_refclk_inst 
(
    .I                      (   sfp_refclk_p        ),
    .IB                     (   sfp_refclk_n        ),
    .CEB                    (   1'b0                ),
    .O                      (   sfp_mgt_refclk      ),
    .ODIV2                  (                       )
);

eth_xcvr_phy_wrapper #(
    .HAS_COMMON             (   1                   )
)sfp_1_phy_inst(
    .xcvr_ctrl_clk          (   i_clk_125m          ),  //  freerun
    .xcvr_ctrl_rst          (   clk_125m_rst        ),

    // Common
    .xcvr_gtpowergood_out   (                       ),

    // PLL out
    .xcvr_gtrefclk00_in     (   sfp_mgt_refclk      ),
    .xcvr_qpll0lock_out     (   sfp_qpll0lock       ),
    .xcvr_qpll0outclk_out   (   sfp_qpll0outclk     ),
    .xcvr_qpll0outrefclk_out(   sfp_qpll0outrefclk  ),

    // PLL in
    .xcvr_qpll0lock_in      (   1'b0                ),
    .xcvr_qpll0reset_out    (                       ),
    .xcvr_qpll0clk_in       (   1'b0                ),
    .xcvr_qpll0refclk_in    (   1'b0                ),

    // Serial data
    .xcvr_txp               (   sfp_tx_p            ),
    .xcvr_txn               (   sfp_tx_n            ),
    .xcvr_rxp               (   sfp_rx_p            ),
    .xcvr_rxn               (   sfp_rx_n            ),

    // PHY connections
    .phy_tx_clk             (   xgmii_tx_clk_156mhz ),  //  o
    .phy_tx_rst             (   xgmii_tx_rst_156mhz ),  //  o
    .phy_xgmii_txd          (   xgmii_sfp_txd       ),  //  i    
    .phy_xgmii_txc          (   xgmii_sfp_txc       ),  //  i

    .phy_rx_clk             (   xgmii_rx_clk_156mhz ),  //  o
    .phy_rx_rst             (   xgmii_rx_rst_156mhz ),  //  o
    .phy_xgmii_rxd          (   xgmii_sfp_rxd       ),  //  o
    .phy_xgmii_rxc          (   xgmii_sfp_rxc       ),  //  o

    .phy_tx_bad_block       (                       ),
    .phy_rx_error_count     (                       ),
    .phy_rx_bad_block       (                       ),
    .phy_rx_sequence_error  (                       ),
    .phy_rx_block_lock      (   phy_rx_block_lock   ),
    .phy_rx_high_ber        (                       ),
    .phy_tx_prbs31_enable   (                       ),
    .phy_rx_prbs31_enable   (                       )
);

endmodule

`resetall

andylgh commented 1 week ago

i change the eth_xcvr_gt.tcl as follow: set base_name {eth_xcvr_gt}

set preset {GTH-10GBASE-R}

set freerun_freq {125} set line_rate {10.3125} set refclk_freq {156.25} set qpll_fracn [expr {int(fmod($line_rate1000/2 / $refclk_freq, 1)pow(2, 24))}] set user_data_width {64} set int_data_width {32} set extra_ports [list {rxpolarity_in} {txpolarity_in}] set extra_pll_ports [list {qpll0lock_out}]

set config [dict create]

dict set config TX_LINE_RATE $line_rate dict set config TX_REFCLK_FREQUENCY $refclk_freq dict set config TX_QPLL_FRACN_NUMERATOR $qpll_fracn dict set config TX_USER_DATA_WIDTH $user_data_width dict set config TX_INT_DATA_WIDTH $int_data_width dict set config RX_LINE_RATE $line_rate dict set config RX_REFCLK_FREQUENCY $refclk_freq dict set config RX_QPLL_FRACN_NUMERATOR $qpll_fracn dict set config RX_USER_DATA_WIDTH $user_data_width dict set config RX_INT_DATA_WIDTH $int_data_width dict set config ENABLE_OPTIONAL_PORTS $extra_ports dict set config LOCATE_COMMON {CORE} dict set config LOCATE_RESET_CONTROLLER {CORE} dict set config LOCATE_TX_USER_CLOCKING {CORE} dict set config LOCATE_RX_USER_CLOCKING {CORE} dict set config LOCATE_USER_DATA_WIDTH_SIZING {CORE} dict set config FREERUN_FREQUENCY $freerun_freq dict set config DISABLE_LOC_XDC {1}

proc create_gtwizard_ip {name preset config} { create_ip -name gtwizard_ultrascale -vendor xilinx.com -library ip -module_name $name set ip [get_ips $name] set_property CONFIG.preset $preset $ip set config_list {} dict for {name value} $config { lappend config_list "CONFIG.${name}" $value } set_property -dict $config_list $ip }

variant with channel and common

dict set config ENABLE_OPTIONAL_PORTS [concat $extra_pll_ports $extra_ports] dict set config LOCATE_COMMON {CORE}

create_gtwizard_ip "${base_name}_full" $preset $config

variant with channel only

dict set config ENABLE_OPTIONAL_PORTS $extra_ports dict set config LOCATE_COMMON {EXAMPLE_DESIGN}

create_gtwizard_ip "${base_name}_channel" $preset $config

andylgh commented 1 week ago

xdc file as follow:

100M

set_property -dict {PACKAGE_PIN D23 IOSTANDARD LVCMOS12} [get_ports clk_100m]

set_property -dict {PACKAGE_PIN E22 IOSTANDARD DIFF_SSTL12} [get_ports clk_100m_p]

set_property -dict {PACKAGE_PIN E23 IOSTANDARD DIFF_SSTL12} [get_ports clk_100m_n]

set_property -dict {PACKAGE_PIN E22 IOSTANDARD LVDS} [get_ports clk_100m_p] set_property -dict {PACKAGE_PIN E23 IOSTANDARD LVDS} [get_ports clk_100m_n]

set_property -dict {PACKAGE_PIN AP9 IOSTANDARD LVCMOS33} [get_ports {leds[0]}] set_property -dict {PACKAGE_PIN AN9 IOSTANDARD LVCMOS33} [get_ports {leds[1]}] set_property -dict {PACKAGE_PIN AP8 IOSTANDARD LVCMOS33} [get_ports {leds[2]}] set_property -dict {PACKAGE_PIN AN8 IOSTANDARD LVCMOS33} [get_ports {leds[3]}] set_property -dict {PACKAGE_PIN AL10 IOSTANDARD LVCMOS33} [get_ports {leds[4]}] set_property -dict {PACKAGE_PIN AM10 IOSTANDARD LVCMOS33} [get_ports {leds[5]}] set_property -dict {PACKAGE_PIN AE11 IOSTANDARD LVCMOS33} [get_ports {leds[6]}]

REF_CLK

set_property -dict {PACKAGE_PIN J30} [get_ports sfp_a_refclk_n] set_property -dict {PACKAGE_PIN J29} [get_ports sfp_a_refclk_p]

SFP_A

set_property -dict {PACKAGE_PIN G34} [get_ports sfp_a_rx_n] set_property -dict {PACKAGE_PIN G33} [get_ports sfp_a_rx_p] set_property -dict {PACKAGE_PIN H32} [get_ports sfp_a_tx_n] set_property -dict {PACKAGE_PIN H31} [get_ports sfp_a_tx_p]

set_property -dict {PACKAGE_PIN AG11 IOSTANDARD LVCMOS33} [get_ports {sfp_a_tx_dis}]

set_property -dict {PACKAGE_PIN AH13 IOSTANDARD LVCMOS33} [get_ports {sfp_a_rs0}]

set_property -dict {PACKAGE_PIN AJ13 IOSTANDARD LVCMOS33} [get_ports {sfp_a_rs1}]

set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design] set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]

create_clock -period 6.400 -name sfp_a_refclk_p -waveform {0.000 3.200} [get_ports sfp_a_refclk_p]

161.1328125 MHz MGT reference clock

create_clock -period 6.206 -name sfp_a_refclk_p [get_ports sfp_a_refclk_p]

andylgh commented 1 week ago

the status : phy_rx_block_lock = 1 and sfp_qpll0lock =1 this normal but eth is no link, Is it incorrect where the port was transplanted? As far as I understand it, gth ref clk is give correct and gth pin assign ok download the bit to the FPGA, and the Ethernet will link normally?

alexforencich commented 1 week ago

The rx_status signal is more reliable than rx_block_lock, so look at that one. Do you see rx_status high when connected to an external 10G NIC? Do you see rx_status high when you use a loopback SFP?

andylgh commented 1 week ago

Does rx_status refer to the following signal?

output wire [6:0]             phy_rx_error_count,
output wire                   phy_rx_bad_block,
output wire                   phy_rx_sequence_error,
output wire                   phy_rx_block_lock,
output wire                   phy_rx_high_ber,
alexforencich commented 1 week ago

By rx_status I mean rx_status: https://github.com/alexforencich/verilog-ethernet/blob/master/rtl/eth_phy_10g.v#L81

andylgh commented 4 days ago

I made modifications directly from the ExaNIC_X10 project, only modifying the pin constraints and ref_clk constraints. I found that the project also couldn't run ,and phy was not connected. I can directly use the 10G/25G ETH subsystem of Xilinx , see that phy can be connected. Attached is the project I modified. Can you give me some suggestions. vivado version:2019.1 ExaNIC_X10_ku060.zip