From 58732ebeb30ff26120b8c6ce2043e6a084dcf2ad Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 10 Nov 2023 15:25:38 -0800 Subject: [PATCH] Rework Alveo parametrization Signed-off-by: Alex Forencich --- example/Alveo/fpga_25g/rtl/fpga_au200.v | 333 ++++++------------ example/Alveo/fpga_25g/rtl/fpga_core.v | 138 +++----- example/Alveo/fpga_25g/tb/fpga_core/Makefile | 13 +- .../fpga_25g/tb/fpga_core/test_fpga_core.py | 63 ++-- .../fpga_25g/tb/fpga_core/test_fpga_core.v | 145 ++++++++ 5 files changed, 337 insertions(+), 355 deletions(-) create mode 100644 example/Alveo/fpga_25g/tb/fpga_core/test_fpga_core.v diff --git a/example/Alveo/fpga_25g/rtl/fpga_au200.v b/example/Alveo/fpga_25g/rtl/fpga_au200.v index 929d9324c..5c2ae9484 100644 --- a/example/Alveo/fpga_25g/rtl/fpga_au200.v +++ b/example/Alveo/fpga_25g/rtl/fpga_au200.v @@ -49,6 +49,12 @@ module fpga ( inout wire i2c_scl, inout wire i2c_sda, + /* + * UART + */ + output wire uart_txd, + input wire uart_rxd, + /* * Ethernet: QSFP28 */ @@ -82,13 +88,7 @@ module fpga ( input wire qsfp1_intl, output wire qsfp1_lpmode, output wire qsfp1_refclk_reset, - output wire [1:0] qsfp1_fs, - - /* - * UART: 500000 bps, 8N1 - */ - output wire uart_rxd, - input wire uart_txd + output wire [1:0] qsfp1_fs ); // Clock and reset @@ -198,18 +198,6 @@ debounce_switch_inst ( .out({sw_int}) ); -wire uart_txd_int; - -sync_signal #( - .WIDTH(1), - .N(2) -) -sync_signal_inst ( - .clk(clk_156mhz_int), - .in({uart_txd}), - .out({uart_txd_int}) -); - // SI570 I2C wire i2c_scl_i; wire i2c_scl_o = 1'b1; @@ -282,6 +270,20 @@ always @(posedge cfgmclk_int) begin end // XGMII 10G PHY +localparam QSFP_CNT = 2; +localparam CH_CNT = QSFP_CNT*4; + +wire [CH_CNT-1:0] eth_tx_clk; +wire [CH_CNT-1:0] eth_tx_rst; +wire [CH_CNT*64-1:0] eth_txd; +wire [CH_CNT*8-1:0] eth_txc; +wire [CH_CNT-1:0] eth_rx_clk; +wire [CH_CNT-1:0] eth_rx_rst; +wire [CH_CNT*64-1:0] eth_rxd; +wire [CH_CNT*8-1:0] eth_rxc; + +assign clk_156mhz_int = eth_tx_clk[0]; +assign rst_156mhz_int = eth_tx_rst[0]; // QSFP0 assign qsfp0_modsell = 1'b0; @@ -290,42 +292,6 @@ assign qsfp0_lpmode = 1'b0; assign qsfp0_refclk_reset = qsfp_refclk_reset_reg; assign qsfp0_fs = 2'b10; -wire qsfp0_tx_clk_1_int; -wire qsfp0_tx_rst_1_int; -wire [63:0] qsfp0_txd_1_int; -wire [7:0] qsfp0_txc_1_int; -wire qsfp0_rx_clk_1_int; -wire qsfp0_rx_rst_1_int; -wire [63:0] qsfp0_rxd_1_int; -wire [7:0] qsfp0_rxc_1_int; -wire qsfp0_tx_clk_2_int; -wire qsfp0_tx_rst_2_int; -wire [63:0] qsfp0_txd_2_int; -wire [7:0] qsfp0_txc_2_int; -wire qsfp0_rx_clk_2_int; -wire qsfp0_rx_rst_2_int; -wire [63:0] qsfp0_rxd_2_int; -wire [7:0] qsfp0_rxc_2_int; -wire qsfp0_tx_clk_3_int; -wire qsfp0_tx_rst_3_int; -wire [63:0] qsfp0_txd_3_int; -wire [7:0] qsfp0_txc_3_int; -wire qsfp0_rx_clk_3_int; -wire qsfp0_rx_rst_3_int; -wire [63:0] qsfp0_rxd_3_int; -wire [7:0] qsfp0_rxc_3_int; -wire qsfp0_tx_clk_4_int; -wire qsfp0_tx_rst_4_int; -wire [63:0] qsfp0_txd_4_int; -wire [7:0] qsfp0_txc_4_int; -wire qsfp0_rx_clk_4_int; -wire qsfp0_rx_rst_4_int; -wire [63:0] qsfp0_rxd_4_int; -wire [7:0] qsfp0_rxc_4_int; - -assign clk_156mhz_int = qsfp0_tx_clk_1_int; -assign rst_156mhz_int = qsfp0_tx_rst_1_int; - wire qsfp0_rx_block_lock_1; wire qsfp0_rx_block_lock_2; wire qsfp0_rx_block_lock_3; @@ -387,14 +353,14 @@ qsfp0_phy_inst ( /* * PHY connections */ - .phy_1_tx_clk(qsfp0_tx_clk_1_int), - .phy_1_tx_rst(qsfp0_tx_rst_1_int), - .phy_1_xgmii_txd(qsfp0_txd_1_int), - .phy_1_xgmii_txc(qsfp0_txc_1_int), - .phy_1_rx_clk(qsfp0_rx_clk_1_int), - .phy_1_rx_rst(qsfp0_rx_rst_1_int), - .phy_1_xgmii_rxd(qsfp0_rxd_1_int), - .phy_1_xgmii_rxc(qsfp0_rxc_1_int), + .phy_1_tx_clk(eth_tx_clk[0*4+0 +: 1]), + .phy_1_tx_rst(eth_tx_rst[0*4+0 +: 1]), + .phy_1_xgmii_txd(eth_txd[(0*4+0)*64 +: 64]), + .phy_1_xgmii_txc(eth_txc[(0*4+0)*8 +: 8]), + .phy_1_rx_clk(eth_rx_clk[0*4+0 +: 1]), + .phy_1_rx_rst(eth_rx_rst[0*4+0 +: 1]), + .phy_1_xgmii_rxd(eth_rxd[(0*4+0)*64 +: 64]), + .phy_1_xgmii_rxc(eth_rxc[(0*4+0)*8 +: 8]), .phy_1_tx_bad_block(), .phy_1_rx_error_count(), .phy_1_rx_bad_block(), @@ -404,14 +370,14 @@ qsfp0_phy_inst ( .phy_1_cfg_tx_prbs31_enable(1'b0), .phy_1_cfg_rx_prbs31_enable(1'b0), - .phy_2_tx_clk(qsfp0_tx_clk_2_int), - .phy_2_tx_rst(qsfp0_tx_rst_2_int), - .phy_2_xgmii_txd(qsfp0_txd_2_int), - .phy_2_xgmii_txc(qsfp0_txc_2_int), - .phy_2_rx_clk(qsfp0_rx_clk_2_int), - .phy_2_rx_rst(qsfp0_rx_rst_2_int), - .phy_2_xgmii_rxd(qsfp0_rxd_2_int), - .phy_2_xgmii_rxc(qsfp0_rxc_2_int), + .phy_2_tx_clk(eth_tx_clk[0*4+1 +: 1]), + .phy_2_tx_rst(eth_tx_rst[0*4+1 +: 1]), + .phy_2_xgmii_txd(eth_txd[(0*4+1)*64 +: 64]), + .phy_2_xgmii_txc(eth_txc[(0*4+1)*8 +: 8]), + .phy_2_rx_clk(eth_rx_clk[0*4+1 +: 1]), + .phy_2_rx_rst(eth_rx_rst[0*4+1 +: 1]), + .phy_2_xgmii_rxd(eth_rxd[(0*4+1)*64 +: 64]), + .phy_2_xgmii_rxc(eth_rxc[(0*4+1)*8 +: 8]), .phy_2_tx_bad_block(), .phy_2_rx_error_count(), .phy_2_rx_bad_block(), @@ -421,14 +387,14 @@ qsfp0_phy_inst ( .phy_2_cfg_tx_prbs31_enable(1'b0), .phy_2_cfg_rx_prbs31_enable(1'b0), - .phy_3_tx_clk(qsfp0_tx_clk_3_int), - .phy_3_tx_rst(qsfp0_tx_rst_3_int), - .phy_3_xgmii_txd(qsfp0_txd_3_int), - .phy_3_xgmii_txc(qsfp0_txc_3_int), - .phy_3_rx_clk(qsfp0_rx_clk_3_int), - .phy_3_rx_rst(qsfp0_rx_rst_3_int), - .phy_3_xgmii_rxd(qsfp0_rxd_3_int), - .phy_3_xgmii_rxc(qsfp0_rxc_3_int), + .phy_3_tx_clk(eth_tx_clk[0*4+2 +: 1]), + .phy_3_tx_rst(eth_tx_rst[0*4+2 +: 1]), + .phy_3_xgmii_txd(eth_txd[(0*4+2)*64 +: 64]), + .phy_3_xgmii_txc(eth_txc[(0*4+2)*8 +: 8]), + .phy_3_rx_clk(eth_rx_clk[0*4+2 +: 1]), + .phy_3_rx_rst(eth_rx_rst[0*4+2 +: 1]), + .phy_3_xgmii_rxd(eth_rxd[(0*4+2)*64 +: 64]), + .phy_3_xgmii_rxc(eth_rxc[(0*4+2)*8 +: 8]), .phy_3_tx_bad_block(), .phy_3_rx_error_count(), .phy_3_rx_bad_block(), @@ -438,14 +404,14 @@ qsfp0_phy_inst ( .phy_3_cfg_tx_prbs31_enable(1'b0), .phy_3_cfg_rx_prbs31_enable(1'b0), - .phy_4_tx_clk(qsfp0_tx_clk_4_int), - .phy_4_tx_rst(qsfp0_tx_rst_4_int), - .phy_4_xgmii_txd(qsfp0_txd_4_int), - .phy_4_xgmii_txc(qsfp0_txc_4_int), - .phy_4_rx_clk(qsfp0_rx_clk_4_int), - .phy_4_rx_rst(qsfp0_rx_rst_4_int), - .phy_4_xgmii_rxd(qsfp0_rxd_4_int), - .phy_4_xgmii_rxc(qsfp0_rxc_4_int), + .phy_4_tx_clk(eth_tx_clk[0*4+3 +: 1]), + .phy_4_tx_rst(eth_tx_rst[0*4+3 +: 1]), + .phy_4_xgmii_txd(eth_txd[(0*4+3)*64 +: 64]), + .phy_4_xgmii_txc(eth_txc[(0*4+3)*8 +: 8]), + .phy_4_rx_clk(eth_rx_clk[0*4+3 +: 1]), + .phy_4_rx_rst(eth_rx_rst[0*4+3 +: 1]), + .phy_4_xgmii_rxd(eth_rxd[(0*4+3)*64 +: 64]), + .phy_4_xgmii_rxc(eth_rxc[(0*4+3)*8 +: 8]), .phy_4_tx_bad_block(), .phy_4_rx_error_count(), .phy_4_rx_bad_block(), @@ -463,39 +429,6 @@ assign qsfp1_lpmode = 1'b0; assign qsfp1_refclk_reset = qsfp_refclk_reset_reg; assign qsfp1_fs = 2'b10; -wire qsfp1_tx_clk_1_int; -wire qsfp1_tx_rst_1_int; -wire [63:0] qsfp1_txd_1_int; -wire [7:0] qsfp1_txc_1_int; -wire qsfp1_rx_clk_1_int; -wire qsfp1_rx_rst_1_int; -wire [63:0] qsfp1_rxd_1_int; -wire [7:0] qsfp1_rxc_1_int; -wire qsfp1_tx_clk_2_int; -wire qsfp1_tx_rst_2_int; -wire [63:0] qsfp1_txd_2_int; -wire [7:0] qsfp1_txc_2_int; -wire qsfp1_rx_clk_2_int; -wire qsfp1_rx_rst_2_int; -wire [63:0] qsfp1_rxd_2_int; -wire [7:0] qsfp1_rxc_2_int; -wire qsfp1_tx_clk_3_int; -wire qsfp1_tx_rst_3_int; -wire [63:0] qsfp1_txd_3_int; -wire [7:0] qsfp1_txc_3_int; -wire qsfp1_rx_clk_3_int; -wire qsfp1_rx_rst_3_int; -wire [63:0] qsfp1_rxd_3_int; -wire [7:0] qsfp1_rxc_3_int; -wire qsfp1_tx_clk_4_int; -wire qsfp1_tx_rst_4_int; -wire [63:0] qsfp1_txd_4_int; -wire [7:0] qsfp1_txc_4_int; -wire qsfp1_rx_clk_4_int; -wire qsfp1_rx_rst_4_int; -wire [63:0] qsfp1_rxd_4_int; -wire [7:0] qsfp1_rxc_4_int; - wire qsfp1_rx_block_lock_1; wire qsfp1_rx_block_lock_2; wire qsfp1_rx_block_lock_3; @@ -541,14 +474,14 @@ qsfp1_phy_inst ( /* * PHY connections */ - .phy_1_tx_clk(qsfp1_tx_clk_1_int), - .phy_1_tx_rst(qsfp1_tx_rst_1_int), - .phy_1_xgmii_txd(qsfp1_txd_1_int), - .phy_1_xgmii_txc(qsfp1_txc_1_int), - .phy_1_rx_clk(qsfp1_rx_clk_1_int), - .phy_1_rx_rst(qsfp1_rx_rst_1_int), - .phy_1_xgmii_rxd(qsfp1_rxd_1_int), - .phy_1_xgmii_rxc(qsfp1_rxc_1_int), + .phy_1_tx_clk(eth_tx_clk[1*4+0 +: 1]), + .phy_1_tx_rst(eth_tx_rst[1*4+0 +: 1]), + .phy_1_xgmii_txd(eth_txd[(1*4+0)*64 +: 64]), + .phy_1_xgmii_txc(eth_txc[(1*4+0)*8 +: 8]), + .phy_1_rx_clk(eth_rx_clk[1*4+0 +: 1]), + .phy_1_rx_rst(eth_rx_rst[1*4+0 +: 1]), + .phy_1_xgmii_rxd(eth_rxd[(1*4+0)*64 +: 64]), + .phy_1_xgmii_rxc(eth_rxc[(1*4+0)*8 +: 8]), .phy_1_tx_bad_block(), .phy_1_rx_error_count(), .phy_1_rx_bad_block(), @@ -558,14 +491,14 @@ qsfp1_phy_inst ( .phy_1_cfg_tx_prbs31_enable(1'b0), .phy_1_cfg_rx_prbs31_enable(1'b0), - .phy_2_tx_clk(qsfp1_tx_clk_2_int), - .phy_2_tx_rst(qsfp1_tx_rst_2_int), - .phy_2_xgmii_txd(qsfp1_txd_2_int), - .phy_2_xgmii_txc(qsfp1_txc_2_int), - .phy_2_rx_clk(qsfp1_rx_clk_2_int), - .phy_2_rx_rst(qsfp1_rx_rst_2_int), - .phy_2_xgmii_rxd(qsfp1_rxd_2_int), - .phy_2_xgmii_rxc(qsfp1_rxc_2_int), + .phy_2_tx_clk(eth_tx_clk[1*4+1 +: 1]), + .phy_2_tx_rst(eth_tx_rst[1*4+1 +: 1]), + .phy_2_xgmii_txd(eth_txd[(1*4+1)*64 +: 64]), + .phy_2_xgmii_txc(eth_txc[(1*4+1)*8 +: 8]), + .phy_2_rx_clk(eth_rx_clk[1*4+1 +: 1]), + .phy_2_rx_rst(eth_rx_rst[1*4+1 +: 1]), + .phy_2_xgmii_rxd(eth_rxd[(1*4+1)*64 +: 64]), + .phy_2_xgmii_rxc(eth_rxc[(1*4+1)*8 +: 8]), .phy_2_tx_bad_block(), .phy_2_rx_error_count(), .phy_2_rx_bad_block(), @@ -575,14 +508,14 @@ qsfp1_phy_inst ( .phy_2_cfg_tx_prbs31_enable(1'b0), .phy_2_cfg_rx_prbs31_enable(1'b0), - .phy_3_tx_clk(qsfp1_tx_clk_3_int), - .phy_3_tx_rst(qsfp1_tx_rst_3_int), - .phy_3_xgmii_txd(qsfp1_txd_3_int), - .phy_3_xgmii_txc(qsfp1_txc_3_int), - .phy_3_rx_clk(qsfp1_rx_clk_3_int), - .phy_3_rx_rst(qsfp1_rx_rst_3_int), - .phy_3_xgmii_rxd(qsfp1_rxd_3_int), - .phy_3_xgmii_rxc(qsfp1_rxc_3_int), + .phy_3_tx_clk(eth_tx_clk[1*4+2 +: 1]), + .phy_3_tx_rst(eth_tx_rst[1*4+2 +: 1]), + .phy_3_xgmii_txd(eth_txd[(1*4+2)*64 +: 64]), + .phy_3_xgmii_txc(eth_txc[(1*4+2)*8 +: 8]), + .phy_3_rx_clk(eth_rx_clk[1*4+2 +: 1]), + .phy_3_rx_rst(eth_rx_rst[1*4+2 +: 1]), + .phy_3_xgmii_rxd(eth_rxd[(1*4+2)*64 +: 64]), + .phy_3_xgmii_rxc(eth_rxc[(1*4+2)*8 +: 8]), .phy_3_tx_bad_block(), .phy_3_rx_error_count(), .phy_3_rx_bad_block(), @@ -592,14 +525,14 @@ qsfp1_phy_inst ( .phy_3_cfg_tx_prbs31_enable(1'b0), .phy_3_cfg_rx_prbs31_enable(1'b0), - .phy_4_tx_clk(qsfp1_tx_clk_4_int), - .phy_4_tx_rst(qsfp1_tx_rst_4_int), - .phy_4_xgmii_txd(qsfp1_txd_4_int), - .phy_4_xgmii_txc(qsfp1_txc_4_int), - .phy_4_rx_clk(qsfp1_rx_clk_4_int), - .phy_4_rx_rst(qsfp1_rx_rst_4_int), - .phy_4_xgmii_rxd(qsfp1_rxd_4_int), - .phy_4_xgmii_rxc(qsfp1_rxc_4_int), + .phy_4_tx_clk(eth_tx_clk[1*4+3 +: 1]), + .phy_4_tx_rst(eth_tx_rst[1*4+3 +: 1]), + .phy_4_xgmii_txd(eth_txd[(1*4+3)*64 +: 64]), + .phy_4_xgmii_txc(eth_txc[(1*4+3)*8 +: 8]), + .phy_4_rx_clk(eth_rx_clk[1*4+3 +: 1]), + .phy_4_rx_rst(eth_rx_rst[1*4+3 +: 1]), + .phy_4_xgmii_rxd(eth_rxd[(1*4+3)*64 +: 64]), + .phy_4_xgmii_rxc(eth_rxc[(1*4+3)*8 +: 8]), .phy_4_tx_bad_block(), .phy_4_rx_error_count(), .phy_4_rx_bad_block(), @@ -610,7 +543,13 @@ qsfp1_phy_inst ( .phy_4_cfg_rx_prbs31_enable(1'b0) ); -fpga_core +fpga_core #( + .SW_CNT(4), + .LED_CNT(3), + .UART_CNT(1), + .QSFP_CNT(QSFP_CNT), + .CH_CNT(CH_CNT) +) core_inst ( /* * Clock: 156.25 MHz @@ -618,83 +557,33 @@ core_inst ( */ .clk(clk_156mhz_int), .rst(rst_156mhz_int), + /* * GPIO */ .sw(sw_int), .led(led), + .qsfp_led_act(), + .qsfp_led_stat_g(), + .qsfp_led_stat_y(), + + /* + * UART + */ + .uart_txd(uart_txd), + .uart_rxd(uart_rxd), + /* * Ethernet: QSFP28 */ - .qsfp0_tx_clk_1(qsfp0_tx_clk_1_int), - .qsfp0_tx_rst_1(qsfp0_tx_rst_1_int), - .qsfp0_txd_1(qsfp0_txd_1_int), - .qsfp0_txc_1(qsfp0_txc_1_int), - .qsfp0_rx_clk_1(qsfp0_rx_clk_1_int), - .qsfp0_rx_rst_1(qsfp0_rx_rst_1_int), - .qsfp0_rxd_1(qsfp0_rxd_1_int), - .qsfp0_rxc_1(qsfp0_rxc_1_int), - .qsfp0_tx_clk_2(qsfp0_tx_clk_2_int), - .qsfp0_tx_rst_2(qsfp0_tx_rst_2_int), - .qsfp0_txd_2(qsfp0_txd_2_int), - .qsfp0_txc_2(qsfp0_txc_2_int), - .qsfp0_rx_clk_2(qsfp0_rx_clk_2_int), - .qsfp0_rx_rst_2(qsfp0_rx_rst_2_int), - .qsfp0_rxd_2(qsfp0_rxd_2_int), - .qsfp0_rxc_2(qsfp0_rxc_2_int), - .qsfp0_tx_clk_3(qsfp0_tx_clk_3_int), - .qsfp0_tx_rst_3(qsfp0_tx_rst_3_int), - .qsfp0_txd_3(qsfp0_txd_3_int), - .qsfp0_txc_3(qsfp0_txc_3_int), - .qsfp0_rx_clk_3(qsfp0_rx_clk_3_int), - .qsfp0_rx_rst_3(qsfp0_rx_rst_3_int), - .qsfp0_rxd_3(qsfp0_rxd_3_int), - .qsfp0_rxc_3(qsfp0_rxc_3_int), - .qsfp0_tx_clk_4(qsfp0_tx_clk_4_int), - .qsfp0_tx_rst_4(qsfp0_tx_rst_4_int), - .qsfp0_txd_4(qsfp0_txd_4_int), - .qsfp0_txc_4(qsfp0_txc_4_int), - .qsfp0_rx_clk_4(qsfp0_rx_clk_4_int), - .qsfp0_rx_rst_4(qsfp0_rx_rst_4_int), - .qsfp0_rxd_4(qsfp0_rxd_4_int), - .qsfp0_rxc_4(qsfp0_rxc_4_int), - .qsfp1_tx_clk_1(qsfp1_tx_clk_1_int), - .qsfp1_tx_rst_1(qsfp1_tx_rst_1_int), - .qsfp1_txd_1(qsfp1_txd_1_int), - .qsfp1_txc_1(qsfp1_txc_1_int), - .qsfp1_rx_clk_1(qsfp1_rx_clk_1_int), - .qsfp1_rx_rst_1(qsfp1_rx_rst_1_int), - .qsfp1_rxd_1(qsfp1_rxd_1_int), - .qsfp1_rxc_1(qsfp1_rxc_1_int), - .qsfp1_tx_clk_2(qsfp1_tx_clk_2_int), - .qsfp1_tx_rst_2(qsfp1_tx_rst_2_int), - .qsfp1_txd_2(qsfp1_txd_2_int), - .qsfp1_txc_2(qsfp1_txc_2_int), - .qsfp1_rx_clk_2(qsfp1_rx_clk_2_int), - .qsfp1_rx_rst_2(qsfp1_rx_rst_2_int), - .qsfp1_rxd_2(qsfp1_rxd_2_int), - .qsfp1_rxc_2(qsfp1_rxc_2_int), - .qsfp1_tx_clk_3(qsfp1_tx_clk_3_int), - .qsfp1_tx_rst_3(qsfp1_tx_rst_3_int), - .qsfp1_txd_3(qsfp1_txd_3_int), - .qsfp1_txc_3(qsfp1_txc_3_int), - .qsfp1_rx_clk_3(qsfp1_rx_clk_3_int), - .qsfp1_rx_rst_3(qsfp1_rx_rst_3_int), - .qsfp1_rxd_3(qsfp1_rxd_3_int), - .qsfp1_rxc_3(qsfp1_rxc_3_int), - .qsfp1_tx_clk_4(qsfp1_tx_clk_4_int), - .qsfp1_tx_rst_4(qsfp1_tx_rst_4_int), - .qsfp1_txd_4(qsfp1_txd_4_int), - .qsfp1_txc_4(qsfp1_txc_4_int), - .qsfp1_rx_clk_4(qsfp1_rx_clk_4_int), - .qsfp1_rx_rst_4(qsfp1_rx_rst_4_int), - .qsfp1_rxd_4(qsfp1_rxd_4_int), - .qsfp1_rxc_4(qsfp1_rxc_4_int), - /* - * UART: 115200 bps, 8N1 - */ - .uart_rxd(uart_rxd), - .uart_txd(uart_txd_int) + .eth_tx_clk(eth_tx_clk), + .eth_tx_rst(eth_tx_rst), + .eth_txd(eth_txd), + .eth_txc(eth_txc), + .eth_rx_clk(eth_rx_clk), + .eth_rx_rst(eth_rx_rst), + .eth_rxd(eth_rxd), + .eth_rxc(eth_rxc) ); endmodule diff --git a/example/Alveo/fpga_25g/rtl/fpga_core.v b/example/Alveo/fpga_25g/rtl/fpga_core.v index 27d8e5cd5..841ac00e2 100644 --- a/example/Alveo/fpga_25g/rtl/fpga_core.v +++ b/example/Alveo/fpga_25g/rtl/fpga_core.v @@ -33,95 +33,46 @@ THE SOFTWARE. */ module fpga_core # ( - parameter TARGET = "XILINX" + parameter SW_CNT = 4, + parameter LED_CNT = 3, + parameter UART_CNT = 1, + parameter QSFP_CNT = 2, + parameter CH_CNT = QSFP_CNT*4 ) ( /* * Clock: 156.25MHz * Synchronous reset */ - input wire clk, - input wire rst, + input wire clk, + input wire rst, /* * GPIO */ - input wire [3:0] sw, - output wire [2:0] led, + input wire [SW_CNT-1:0] sw, + output wire [LED_CNT-1:0] led, + output wire [QSFP_CNT-1:0] qsfp_led_act, + output wire [QSFP_CNT-1:0] qsfp_led_stat_g, + output wire [QSFP_CNT-1:0] qsfp_led_stat_y, /* - * Ethernet: QSFP28 + * UART */ - input wire qsfp0_tx_clk_1, - input wire qsfp0_tx_rst_1, - output wire [63:0] qsfp0_txd_1, - output wire [7:0] qsfp0_txc_1, - input wire qsfp0_rx_clk_1, - input wire qsfp0_rx_rst_1, - input wire [63:0] qsfp0_rxd_1, - input wire [7:0] qsfp0_rxc_1, - input wire qsfp0_tx_clk_2, - input wire qsfp0_tx_rst_2, - output wire [63:0] qsfp0_txd_2, - output wire [7:0] qsfp0_txc_2, - input wire qsfp0_rx_clk_2, - input wire qsfp0_rx_rst_2, - input wire [63:0] qsfp0_rxd_2, - input wire [7:0] qsfp0_rxc_2, - input wire qsfp0_tx_clk_3, - input wire qsfp0_tx_rst_3, - output wire [63:0] qsfp0_txd_3, - output wire [7:0] qsfp0_txc_3, - input wire qsfp0_rx_clk_3, - input wire qsfp0_rx_rst_3, - input wire [63:0] qsfp0_rxd_3, - input wire [7:0] qsfp0_rxc_3, - input wire qsfp0_tx_clk_4, - input wire qsfp0_tx_rst_4, - output wire [63:0] qsfp0_txd_4, - output wire [7:0] qsfp0_txc_4, - input wire qsfp0_rx_clk_4, - input wire qsfp0_rx_rst_4, - input wire [63:0] qsfp0_rxd_4, - input wire [7:0] qsfp0_rxc_4, - input wire qsfp1_tx_clk_1, - input wire qsfp1_tx_rst_1, - output wire [63:0] qsfp1_txd_1, - output wire [7:0] qsfp1_txc_1, - input wire qsfp1_rx_clk_1, - input wire qsfp1_rx_rst_1, - input wire [63:0] qsfp1_rxd_1, - input wire [7:0] qsfp1_rxc_1, - input wire qsfp1_tx_clk_2, - input wire qsfp1_tx_rst_2, - output wire [63:0] qsfp1_txd_2, - output wire [7:0] qsfp1_txc_2, - input wire qsfp1_rx_clk_2, - input wire qsfp1_rx_rst_2, - input wire [63:0] qsfp1_rxd_2, - input wire [7:0] qsfp1_rxc_2, - input wire qsfp1_tx_clk_3, - input wire qsfp1_tx_rst_3, - output wire [63:0] qsfp1_txd_3, - output wire [7:0] qsfp1_txc_3, - input wire qsfp1_rx_clk_3, - input wire qsfp1_rx_rst_3, - input wire [63:0] qsfp1_rxd_3, - input wire [7:0] qsfp1_rxc_3, - input wire qsfp1_tx_clk_4, - input wire qsfp1_tx_rst_4, - output wire [63:0] qsfp1_txd_4, - output wire [7:0] qsfp1_txc_4, - input wire qsfp1_rx_clk_4, - input wire qsfp1_rx_rst_4, - input wire [63:0] qsfp1_rxd_4, - input wire [7:0] qsfp1_rxc_4, + output wire [UART_CNT-1:0] uart_txd, + input wire [UART_CNT-1:0] uart_rxd, /* - * UART: 115200 bps, 8N1 + * Ethernet */ - output wire uart_rxd, - input wire uart_txd + input wire [CH_CNT-1:0] eth_tx_clk, + input wire [CH_CNT-1:0] eth_tx_rst, + output wire [CH_CNT*64-1:0] eth_txd, + output wire [CH_CNT*8-1:0] eth_txc, + input wire [CH_CNT-1:0] eth_rx_clk, + input wire [CH_CNT-1:0] eth_rx_rst, + input wire [CH_CNT*64-1:0] eth_rxd, + input wire [CH_CNT*8-1:0] eth_rxc ); // AXI between MAC and Ethernet modules @@ -361,21 +312,18 @@ end //assign led = sw; assign led = led_reg; -assign qsfp0_txd_2 = 64'h0707070707070707; -assign qsfp0_txc_2 = 8'hff; -assign qsfp0_txd_3 = 64'h0707070707070707; -assign qsfp0_txc_3 = 8'hff; -assign qsfp0_txd_4 = 64'h0707070707070707; -assign qsfp0_txc_4 = 8'hff; +assign uart_txd = uart_rxd; -assign qsfp1_txd_1 = 64'h0707070707070707; -assign qsfp1_txc_1 = 8'hff; -assign qsfp1_txd_2 = 64'h0707070707070707; -assign qsfp1_txc_2 = 8'hff; -assign qsfp1_txd_3 = 64'h0707070707070707; -assign qsfp1_txc_3 = 8'hff; -assign qsfp1_txd_4 = 64'h0707070707070707; -assign qsfp1_txc_4 = 8'hff; +generate + +genvar n; + +for (n = 1; n < CH_CNT; n = n + 1) begin + assign eth_txd[n*64 +: 64] = 64'h0707070707070707; + assign eth_txc[n*8 +: 8] = 8'hff; +end + +endgenerate eth_mac_10g_fifo #( .ENABLE_PADDING(1), @@ -387,10 +335,10 @@ eth_mac_10g_fifo #( .RX_FRAME_FIFO(1) ) eth_mac_10g_fifo_inst ( - .rx_clk(qsfp0_rx_clk_1), - .rx_rst(qsfp0_rx_rst_1), - .tx_clk(qsfp0_tx_clk_1), - .tx_rst(qsfp0_tx_rst_1), + .rx_clk(eth_rx_clk[0 +: 1]), + .rx_rst(eth_rx_rst[0 +: 1]), + .tx_clk(eth_tx_clk[0 +: 1]), + .tx_rst(eth_tx_rst[0 +: 1]), .logic_clk(clk), .logic_rst(rst), @@ -408,10 +356,10 @@ eth_mac_10g_fifo_inst ( .rx_axis_tlast(rx_axis_tlast), .rx_axis_tuser(rx_axis_tuser), - .xgmii_rxd(qsfp0_rxd_1), - .xgmii_rxc(qsfp0_rxc_1), - .xgmii_txd(qsfp0_txd_1), - .xgmii_txc(qsfp0_txc_1), + .xgmii_rxd(eth_rxd[0*64 +: 64]), + .xgmii_rxc(eth_rxc[0*8 +: 8]), + .xgmii_txd(eth_txd[0*64 +: 64]), + .xgmii_txc(eth_txc[0*8 +: 8]), .tx_fifo_overflow(), .tx_fifo_bad_frame(), diff --git a/example/Alveo/fpga_25g/tb/fpga_core/Makefile b/example/Alveo/fpga_25g/tb/fpga_core/Makefile index d840fbe00..ee6478707 100644 --- a/example/Alveo/fpga_25g/tb/fpga_core/Makefile +++ b/example/Alveo/fpga_25g/tb/fpga_core/Makefile @@ -27,8 +27,9 @@ COCOTB_HDL_TIMEUNIT = 1ns COCOTB_HDL_TIMEPRECISION = 1ps DUT = fpga_core -TOPLEVEL = $(DUT) +TOPLEVEL = test_$(DUT) MODULE = test_$(DUT) +VERILOG_SOURCES += $(TOPLEVEL).v VERILOG_SOURCES += ../../rtl/$(DUT).v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g_fifo.v VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v @@ -59,12 +60,16 @@ VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo.v VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v # module parameters -#export PARAM_A := value +export PARAM_SW_CNT := 4 +export PARAM_LED_CNT := 3 +export PARAM_UART_CNT := 1 +export PARAM_QSFP_CNT := 2 +export PARAM_CH_CNT := $(shell expr $(PARAM_QSFP_CNT) \* 4) ifeq ($(SIM), icarus) PLUSARGS += -fst -# COMPILE_ARGS += -P $(TOPLEVEL).A=$(PARAM_A) + COMPILE_ARGS += $(foreach v,$(filter PARAM_%,$(.VARIABLES)),-P $(TOPLEVEL).$(subst PARAM_,,$(v))=$($(v))) ifeq ($(WAVES), 1) VERILOG_SOURCES += iverilog_dump.v @@ -73,7 +78,7 @@ ifeq ($(SIM), icarus) else ifeq ($(SIM), verilator) COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH -# COMPILE_ARGS += -GA=$(PARAM_A) + COMPILE_ARGS += $(foreach v,$(filter PARAM_%,$(.VARIABLES)),-G$(subst PARAM_,,$(v))=$($(v))) ifeq ($(WAVES), 1) COMPILE_ARGS += --trace-fst diff --git a/example/Alveo/fpga_25g/tb/fpga_core/test_fpga_core.py b/example/Alveo/fpga_25g/tb/fpga_core/test_fpga_core.py index d90e185ee..dae9b488c 100644 --- a/example/Alveo/fpga_25g/tb/fpga_core/test_fpga_core.py +++ b/example/Alveo/fpga_25g/tb/fpga_core/test_fpga_core.py @@ -48,49 +48,39 @@ class TB: cocotb.start_soon(Clock(dut.clk, 2.56, units="ns").start()) # Ethernet - self.qsfp_source = [] - self.qsfp_sink = [] + self.ch_source = [] + self.ch_sink = [] - for x in range(2): - sources = [] - sinks = [] - for y in range(1, 5): - cocotb.start_soon(Clock(getattr(dut, f"qsfp{x}_rx_clk_{y}"), 2.56, units="ns").start()) - source = XgmiiSource(getattr(dut, f"qsfp{x}_rxd_{y}"), getattr(dut, f"qsfp{x}_rxc_{y}"), getattr(dut, f"qsfp{x}_rx_clk_{y}"), getattr(dut, f"qsfp{x}_rx_rst_{y}")) - sources.append(source) - cocotb.start_soon(Clock(getattr(dut, f"qsfp{x}_tx_clk_{y}"), 2.56, units="ns").start()) - sink = XgmiiSink(getattr(dut, f"qsfp{x}_txd_{y}"), getattr(dut, f"qsfp{x}_txc_{y}"), getattr(dut, f"qsfp{x}_tx_clk_{y}"), getattr(dut, f"qsfp{x}_tx_rst_{y}")) - sinks.append(sink) - self.qsfp_source.append(sources) - self.qsfp_sink.append(sinks) - - dut.sw.setimmediatevalue(0) + for ch in self.dut.ch: + cocotb.start_soon(Clock(ch.ch_rx_clk, 2.56, units="ns").start()) + source = XgmiiSource(ch.ch_rxd, ch.ch_rxc, ch.ch_rx_clk, ch.ch_rx_rst) + self.ch_source.append(source) + cocotb.start_soon(Clock(ch.ch_tx_clk, 2.56, units="ns").start()) + sink = XgmiiSink(ch.ch_txd, ch.ch_txc, ch.ch_tx_clk, ch.ch_tx_rst) + self.ch_sink.append(sink) async def init(self): self.dut.rst.setimmediatevalue(0) - for x in range(2): - for y in range(1, 5): - getattr(self.dut, f"qsfp{x}_rx_rst_{y}").setimmediatevalue(0) - getattr(self.dut, f"qsfp{x}_tx_rst_{y}").setimmediatevalue(0) + for ch in self.dut.ch: + ch.ch_rx_rst.setimmediatevalue(0) + ch.ch_tx_rst.setimmediatevalue(0) for k in range(10): await RisingEdge(self.dut.clk) self.dut.rst.value = 1 - for x in range(2): - for y in range(1, 5): - getattr(self.dut, f"qsfp{x}_rx_rst_{y}").value = 1 - getattr(self.dut, f"qsfp{x}_tx_rst_{y}").value = 1 + for ch in self.dut.ch: + ch.ch_rx_rst.value = 1 + ch.ch_tx_rst.value = 1 for k in range(10): await RisingEdge(self.dut.clk) self.dut.rst.value = 0 - for x in range(2): - for y in range(1, 5): - getattr(self.dut, f"qsfp{x}_rx_rst_{y}").value = 0 - getattr(self.dut, f"qsfp{x}_tx_rst_{y}").value = 0 + for ch in self.dut.ch: + ch.ch_rx_rst.value = 0 + ch.ch_tx_rst.value = 0 @cocotb.test() @@ -110,11 +100,11 @@ async def run_test(dut): test_frame = XgmiiFrame.from_payload(test_pkt.build()) - await tb.qsfp_source[0][0].send(test_frame) + await tb.ch_source[0].send(test_frame) tb.log.info("receive ARP request") - rx_frame = await tb.qsfp_sink[0][0].recv() + rx_frame = await tb.ch_sink[0].recv() rx_pkt = Ether(bytes(rx_frame.get_payload())) @@ -142,11 +132,11 @@ async def run_test(dut): resp_frame = XgmiiFrame.from_payload(resp_pkt.build()) - await tb.qsfp_source[0][0].send(resp_frame) + await tb.ch_source[0].send(resp_frame) tb.log.info("receive UDP packet") - rx_frame = await tb.qsfp_sink[0][0].recv() + rx_frame = await tb.ch_sink[0].recv() rx_pkt = Ether(bytes(rx_frame.get_payload())) @@ -176,9 +166,10 @@ eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) def test_fpga_core(request): dut = "fpga_core" module = os.path.splitext(os.path.basename(__file__))[0] - toplevel = dut + toplevel = "test_fpga_core" verilog_sources = [ + os.path.join(tests_dir, f"{toplevel}.v"), os.path.join(rtl_dir, f"{dut}.v"), os.path.join(eth_rtl_dir, "eth_mac_10g_fifo.v"), os.path.join(eth_rtl_dir, "eth_mac_10g.v"), @@ -211,7 +202,11 @@ def test_fpga_core(request): parameters = {} - # parameters['A'] = val + parameters['SW_CNT'] = 4 + parameters['LED_CNT'] = 3 + parameters['UART_CNT'] = 1 + parameters['QSFP_CNT'] = 2 + parameters['CH_CNT'] = parameters['QSFP_CNT']*4 extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} diff --git a/example/Alveo/fpga_25g/tb/fpga_core/test_fpga_core.v b/example/Alveo/fpga_25g/tb/fpga_core/test_fpga_core.v new file mode 100644 index 000000000..bd017b3d1 --- /dev/null +++ b/example/Alveo/fpga_25g/tb/fpga_core/test_fpga_core.v @@ -0,0 +1,145 @@ +/* + +Copyright (c) 2023 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * Testbench top-level module + */ +module test_fpga_core # +( + parameter SW_CNT = 4, + parameter LED_CNT = 3, + parameter UART_CNT = 1, + parameter QSFP_CNT = 2, + parameter CH_CNT = QSFP_CNT*4 +) +( + input wire clk, + input wire rst, + + /* + * GPIO + */ + input wire [SW_CNT-1:0] sw, + output wire [LED_CNT-1:0] led, + output wire [QSFP_CNT-1:0] qsfp_led_act, + output wire [QSFP_CNT-1:0] qsfp_led_stat_g, + output wire [QSFP_CNT-1:0] qsfp_led_stat_y, + + /* + * UART + */ + output wire [UART_CNT-1:0] uart_txd, + input wire [UART_CNT-1:0] uart_rxd +); + +genvar n; + +// XGMII 10G PHY +wire [CH_CNT-1:0] eth_tx_clk; +wire [CH_CNT-1:0] eth_tx_rst; +wire [CH_CNT*64-1:0] eth_txd; +wire [CH_CNT*8-1:0] eth_txc; +wire [CH_CNT-1:0] eth_rx_clk; +wire [CH_CNT-1:0] eth_rx_rst; +wire [CH_CNT*64-1:0] eth_rxd; +wire [CH_CNT*8-1:0] eth_rxc; + +generate + +for (n = 0; n < CH_CNT; n = n + 1) begin : ch + + wire ch_tx_clk; + wire ch_tx_rst; + wire [63:0] ch_txd; + wire [7:0] ch_txc; + wire ch_rx_clk; + wire ch_rx_rst; + wire [63:0] ch_rxd; + wire [7:0] ch_rxc; + + assign eth_tx_clk[n +: 1] = ch_tx_clk; + assign eth_tx_rst[n +: 1] = ch_tx_rst; + assign ch_txd = eth_txd[n*64 +: 64]; + assign ch_txc = eth_txc[n*8 +: 8]; + assign eth_rx_clk[n +: 1] = ch_rx_clk; + assign eth_rx_rst[n +: 1] = ch_rx_rst; + assign eth_rxd[n*64 +: 64] = ch_rxd; + assign eth_rxc[n*8 +: 8] = ch_rxc; + +end + +endgenerate + +fpga_core #( + .SW_CNT(SW_CNT), + .LED_CNT(LED_CNT), + .UART_CNT(UART_CNT), + .QSFP_CNT(QSFP_CNT), + .CH_CNT(CH_CNT) +) +core_inst ( + /* + * Clock: 156.25 MHz + * Synchronous reset + */ + .clk(clk), + .rst(rst), + + /* + * GPIO + */ + .sw(sw), + .led(led), + .qsfp_led_act(qsfp_led_act), + .qsfp_led_stat_g(qsfp_led_stat_g), + .qsfp_led_stat_y(qsfp_led_stat_y), + + /* + * UART + */ + .uart_txd(uart_txd), + .uart_rxd(uart_rxd), + + /* + * Ethernet: QSFP28 + */ + .eth_tx_clk(eth_tx_clk), + .eth_tx_rst(eth_tx_rst), + .eth_txd(eth_txd), + .eth_txc(eth_txc), + .eth_rx_clk(eth_rx_clk), + .eth_rx_rst(eth_rx_rst), + .eth_rxd(eth_rxd), + .eth_rxc(eth_rxc) +); + +endmodule + +`resetall