export to ku060
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
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_rate*1000/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
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]
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?
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?
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,
By rx_status I mean rx_status: https://github.com/alexforencich/verilog-ethernet/blob/master/rtl/eth_phy_10g.v#L81