diff --git a/libraries/io/tr_10GbE/tb/vhdl/tb_tr_10GbE.vhd b/libraries/io/tr_10GbE/tb/vhdl/tb_tr_10GbE.vhd index 26effd748dd147c356e20baa3b8b8c9c129fd292..5952762232f7e8cb146e57a7131c7e0ab662fb5f 100644 --- a/libraries/io/tr_10GbE/tb/vhdl/tb_tr_10GbE.vhd +++ b/libraries/io/tr_10GbE/tb/vhdl/tb_tr_10GbE.vhd @@ -57,20 +57,14 @@ END tb_tr_10GbE; ARCHITECTURE tb OF tb_tr_10GbE IS CONSTANT mm_clk_period : TIME := 20 ns; -- 50 MHz - CONSTANT dp_clk_period : TIME := 5 ns; -- 200 MHz CONSTANT tx_ref_clk_period : TIME := 6.4 ns; -- 156.25 MHz - CONSTANT cal_rec_clk_period : TIME := 25 ns; -- 40 MHz CONSTANT phy_delay : TIME := 0 ns; - CONSTANT c_nof_macs : NATURAL := 1; -- fixed 1 in this tb - CONSTANT c_sim : BOOLEAN := TRUE; - CONSTANT c_sim_level : NATURAL := 0; -- 0 = use IP; 1 = use fast serdes model - CONSTANT c_st_loopback : BOOLEAN := FALSE; -- default FALSE to verify the DUT, else use TRUE to verify the tb itself without the DUT CONSTANT c_rl : NATURAL := 1; CONSTANT c_nof_tx_not_valid : NATURAL := 0; -- when > 0 then pull tx valid low for c_nof_tx_not_valid beats during tx --CONSTANT c_pkt_length_arr : t_nat_natural_arr := (0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 1472, 1473, 9000); - CONSTANT c_pkt_length_arr : t_nat_natural_arr := array_init(0, 50, 1) & (1472, 1473) & 9000; -- frame longer than 1518-46 = 1472 is received with rx_src_out.err = 8 + CONSTANT c_pkt_length_arr : t_nat_natural_arr := array_init(0, 50, 1) & (1472, 1473) & 9000; -- frame longer than 1518-46 = 1472 is received with rx_sosi.err = 8 -- jumbo frame is 9018-46 = 8972 CONSTANT c_nof_pkt : NATURAL := c_pkt_length_arr'LENGTH; @@ -91,73 +85,60 @@ ARCHITECTURE tb OF tb_tr_10GbE IS SIGNAL tb_end : STD_LOGIC := '0'; SIGNAL mm_clk : STD_LOGIC := '0'; -- memory-mapped bus clock SIGNAL mm_rst : STD_LOGIC; -- reset synchronous with mm_clk - SIGNAL dp_clk : STD_LOGIC := '0'; -- data path bus clock - SIGNAL dp_rst : STD_LOGIC; -- reset synchronous with dp_clk SIGNAL tx_ref_clk : STD_LOGIC := '0'; -- mac_10g reference clock - SIGNAL cal_rec_clk : STD_LOGIC := '0'; -- calibration reconfiguration reference clock + SIGNAL tx_rst : STD_LOGIC; -- reset synchronous with tx_ref_clk + SIGNAL rx_phy_clk : STD_LOGIC := '0'; -- mac_10g rx clock from phy = tx_ref_clk in this tb + SIGNAL rx_rst : STD_LOGIC; -- reset synchronous with rx_phy_clk = tx_ref_clk in this tb -- 10G MAC control interface SIGNAL mm_init : STD_LOGIC := '1'; - SIGNAL mac_mosi_wrdata : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- 32 bit; - SIGNAL mac_mosi : t_mem_mosi; - SIGNAL mac_miso : t_mem_miso; - SIGNAL mac_miso_rdval : STD_LOGIC; - SIGNAL mac_miso_rddata : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- 32 bit; + SIGNAL mm_mosi_wrdata : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- 32 bit; + SIGNAL mm_mosi : t_mem_mosi; + SIGNAL mm_miso : t_mem_miso; + SIGNAL mm_miso_rdval : STD_LOGIC; + SIGNAL mm_miso_rddata : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- 32 bit; -- 10G MAC transmit interface -- . The tb is the ST source SIGNAL tx_en : STD_LOGIC := '1'; - SIGNAL tx_snk_out : t_dp_siso; - SIGNAL tx_snk_out_arr : t_dp_siso_arr(c_nof_macs-1 DOWNTO 0); - SIGNAL tx_snk_in_arr : t_dp_sosi_arr(c_nof_macs-1 DOWNTO 0); - SIGNAL tx_snk_in : t_dp_sosi; - SIGNAL tx_snk_in_data : STD_LOGIC_VECTOR(c_tech_mac_10g_data_w-1 DOWNTO 0); -- 64 bit + SIGNAL tx_siso : t_dp_siso; + SIGNAL tx_sosi : t_dp_sosi; + SIGNAL tx_sosi_data : STD_LOGIC_VECTOR(c_tech_mac_10g_data_w-1 DOWNTO 0); -- 64 bit -- 10G MAC receive interface -- . The tb is the ST sink - SIGNAL rx_src_in : t_dp_siso; - SIGNAL rx_src_in_arr : t_dp_siso_arr(c_nof_macs-1 DOWNTO 0); - SIGNAL rx_src_out_arr : t_dp_sosi_arr(c_nof_macs-1 DOWNTO 0); - SIGNAL rx_src_out : t_dp_sosi; - SIGNAL rx_src_out_data : STD_LOGIC_VECTOR(c_tech_mac_10g_data_w-1 DOWNTO 0); -- 64 bit - - -- PHY serial interface XAUI - SIGNAL xaui_rx_in_arr : t_xaui_arr(c_nof_macs-1 DOWNTO 0); - SIGNAL xaui_tx_out_arr : t_xaui_arr(c_nof_macs-1 DOWNTO 0); + SIGNAL rx_siso : t_dp_siso; + SIGNAL rx_sosi : t_dp_sosi; + SIGNAL rx_sosi_data : STD_LOGIC_VECTOR(c_tech_mac_10g_data_w-1 DOWNTO 0); -- 64 bit - -- PHY serial interface 10gbase_r - SIGNAL serial_tx_out_arr : std_logic_vector(c_nof_macs-1 downto 0); - SIGNAL serial_rx_in_arr : std_logic_vector(c_nof_macs-1 downto 0); + -- 10G MAC XGMII interface + SIGNAL xgmii_tx_data : STD_LOGIC_VECTOR(c_xgmii_w-1 DOWNTO 0); -- 72 bit + SIGNAL xgmii_rx_data : STD_LOGIC_VECTOR(c_xgmii_w-1 DOWNTO 0); -- 72 bit -- Verification SIGNAL expected_sosi_arr : t_dp_sosi_arr(0 TO c_nof_pkt-1); - SIGNAL tx_pkt_cnt : NATURAL := 0; - SIGNAL rx_pkt_cnt : NATURAL := 0; + SIGNAL tx_pkt_cnt : NATURAL := 0; + SIGNAL rx_pkt_cnt : NATURAL := 0; BEGIN -- run 50 us - mm_clk <= NOT mm_clk AFTER mm_clk_period/2; -- MM clock - dp_clk <= NOT dp_clk AFTER dp_clk_period/2; -- DP clock - tx_ref_clk <= NOT tx_ref_clk AFTER tx_ref_clk_period/2; -- mac_10g tx reference clock - cal_rec_clk <= NOT cal_rec_clk AFTER tx_ref_clk_period/2; -- tr phy calibration clock + mm_clk <= NOT mm_clk AFTER mm_clk_period/2; -- MM clock + tx_ref_clk <= NOT tx_ref_clk AFTER tx_ref_clk_period/2; -- mac_10g tx reference clock + rx_phy_clk <= tx_ref_clk; -- use tx_ref_clk to model PHY mm_rst <= '1', '0' AFTER mm_clk_period*10; - dp_rst <= '1', '0' AFTER dp_clk_period*10; + tx_rst <= '1', '0' AFTER tx_ref_clk_period*10; + rx_rst <= '1', '0' AFTER tx_ref_clk_period*10; -- debug signals to ease monitoring in wave window - tx_snk_out <= tx_snk_out_arr(0); - tx_snk_in_arr(0) <= tx_snk_in; - tx_snk_in_data <= tx_snk_in.data(c_tech_mac_10g_data_w-1 DOWNTO 0); - - rx_src_in_arr(0) <= rx_src_in; - rx_src_out <= rx_src_out_arr(0); - rx_src_out_data <= rx_src_out.data(c_tech_mac_10g_data_w-1 DOWNTO 0); + tx_sosi_data <= tx_sosi.data(c_tech_mac_10g_data_w-1 DOWNTO 0); + rx_sosi_data <= rx_sosi.data(c_tech_mac_10g_data_w-1 DOWNTO 0); - mac_mosi_wrdata <= mac_mosi.wrdata(c_word_w-1 DOWNTO 0); - mac_miso_rddata <= mac_miso.rddata(c_word_w-1 DOWNTO 0); - mac_miso_rdval <= '1' WHEN mac_mosi.rd='1' AND mac_miso.waitrequest='0' ELSE '0'; -- c_rd_latency = 1 + mm_mosi_wrdata <= mm_mosi.wrdata(c_word_w-1 DOWNTO 0); + mm_miso_rddata <= mm_miso.rddata(c_word_w-1 DOWNTO 0); + mm_miso_rdval <= '1' WHEN mm_mosi.rd='1' AND mm_miso.waitrequest='0' ELSE '0'; -- c_rd_latency = 1 -- Use signal to leave unused fields 'X' total_header.eth <= c_eth_header_ethertype; @@ -165,8 +146,8 @@ BEGIN p_mm_setup : PROCESS BEGIN mm_init <= '1'; - mac_mosi.wr <= '0'; - mac_mosi.rd <= '0'; + mm_mosi.wr <= '0'; + mm_mosi.rd <= '0'; -- wait until after reset release proc_common_wait_until_low(mm_clk, mm_rst); @@ -174,7 +155,7 @@ BEGIN proc_tech_mac_10g_setup(g_technology, c_src_mac, - mm_clk, mac_miso, mac_mosi); + mm_clk, mm_miso, mm_mosi); mm_init <= '0'; WAIT; END PROCESS; @@ -183,12 +164,12 @@ BEGIN p_ff_transmitter : PROCESS BEGIN -- . Avalon ST - tx_snk_in <= c_dp_sosi_rst; + tx_sosi <= c_dp_sosi_rst; WHILE mm_init/='0' LOOP - WAIT UNTIL rising_edge(dp_clk); + WAIT UNTIL rising_edge(tx_ref_clk); END LOOP; - proc_common_wait_some_cycles(dp_clk, 10); + proc_common_wait_some_cycles(tx_ref_clk, 10); -- Loopback txp->rxp so use promiscuous mode or use DST_MAC = c_src_mac to send to itself @@ -198,12 +179,12 @@ BEGIN -- . For I>46 the payload length is I and empty = 4 - (I mod 4) FOR I IN 0 TO c_nof_pkt-1 LOOP - proc_tech_mac_10g_tx_packet(total_header, c_pkt_length_arr(I), g_data_type, c_rl, c_nof_tx_not_valid, dp_clk, tx_en, tx_snk_out, tx_snk_in); - proc_common_wait_some_cycles(dp_clk, 0); + proc_tech_mac_10g_tx_packet(total_header, c_pkt_length_arr(I), g_data_type, c_rl, c_nof_tx_not_valid, tx_ref_clk, tx_en, tx_siso, tx_sosi); + proc_common_wait_some_cycles(tx_ref_clk, 0); END LOOP; - proc_common_wait_some_cycles(dp_clk, c_pkt_length_arr(c_nof_pkt-1)/c_tech_mac_10g_symbols_per_beat); - proc_common_wait_some_cycles(dp_clk, 100); + proc_common_wait_some_cycles(tx_ref_clk, c_pkt_length_arr(c_nof_pkt-1)/c_tech_mac_10g_symbols_per_beat); + proc_common_wait_some_cycles(tx_ref_clk, 100); tb_end <= '1'; WAIT; END PROCESS; @@ -212,50 +193,50 @@ BEGIN p_ff_receiver : PROCESS BEGIN -- . Avalon ST - rx_src_in <= c_dp_siso_hold; + rx_siso <= c_dp_siso_hold; WHILE mm_init/='0' LOOP - WAIT UNTIL rising_edge(dp_clk); + WAIT UNTIL rising_edge(rx_phy_clk); END LOOP; -- Receive forever WHILE TRUE LOOP - proc_tech_mac_10g_rx_packet(total_header, g_data_type, dp_clk, rx_src_out, rx_src_in); + proc_tech_mac_10g_rx_packet(total_header, g_data_type, rx_phy_clk, rx_sosi, rx_siso); END LOOP; WAIT; END PROCESS; - p_ff_store_tx_snk_in_at_eop : PROCESS(dp_clk) + p_ff_store_tx_sosi_at_eop : PROCESS(tx_ref_clk) VARIABLE vI : NATURAL := 0; BEGIN - IF rising_edge(dp_clk) THEN - IF tx_snk_in.eop='1' THEN - expected_sosi_arr(vI) <= tx_snk_in; + IF rising_edge(tx_ref_clk) THEN + IF tx_sosi.eop='1' THEN + expected_sosi_arr(vI) <= tx_sosi; vI := vI +1; END IF; END IF; END PROCESS; - p_ff_verify_rx_src_out_at_eop : PROCESS(dp_clk) + p_ff_verify_rx_sosi_at_eop : PROCESS(rx_phy_clk) VARIABLE vI : NATURAL := 0; VARIABLE vLow : NATURAL := 0; BEGIN - IF rising_edge(dp_clk) THEN - IF rx_src_out.eop='1' THEN + IF rising_edge(rx_phy_clk) THEN + IF rx_sosi.eop='1' THEN -- frame shorter than 64 get padded so em IF c_pkt_length_arr(vI) < 64 - 14 - 20 - 8 - 4 THEN -- = minimum frame 64 - ETH 14 - IP 20 - UDP 8 - CRC 4 -- frame shorter than 64 get padded so empty after stripping the Rx CRC is fixed 4, which becomes 6 due to pre header padding for UDP word align - IF TO_UINT(rx_src_out.empty) /= 6 THEN + IF TO_UINT(rx_sosi.empty) /= 6 THEN REPORT "RX: Wrong padded empty" SEVERITY ERROR; END IF; ELSE - IF rx_src_out.empty /= expected_sosi_arr(vI).empty THEN + IF rx_sosi.empty /= expected_sosi_arr(vI).empty THEN REPORT "RX: Wrong empty" SEVERITY ERROR; ELSE - vLow := TO_UINT(rx_src_out.empty)*8; - ASSERT rx_src_out.data(63 DOWNTO vLow) = expected_sosi_arr(vI).data(63 DOWNTO vLow) REPORT "RX: Wrong data at eop" SEVERITY ERROR; + vLow := TO_UINT(rx_sosi.empty)*8; + ASSERT rx_sosi.data(63 DOWNTO vLow) = expected_sosi_arr(vI).data(63 DOWNTO vLow) REPORT "RX: Wrong data at eop" SEVERITY ERROR; END IF; END IF; vI := vI +1; @@ -264,76 +245,47 @@ BEGIN END PROCESS; gen_dut : IF c_st_loopback=FALSE GENERATE - dut : ENTITY work.tr_10GbE + dut : ENTITY tech_mac_10g_lib.tech_mac_10g GENERIC MAP ( - g_sim => c_sim, - g_sim_level => c_sim_level, - g_nof_macs => c_nof_macs, - g_use_mdio => TRUE, - g_mdio_epcs_dis => FALSE, -- TRUE disables EPCS on init; e.g. to target a 10GbE card in PC that does not support it - g_pkt_len => 100, - g_lpbk_sosi => FALSE, -- i/o pins <-> ][ <-> tr_xaui <-> ][ <-> tr_10GbE <-> ][ <-> packetizing <-> user - g_lpbk_xgmii => FALSE, -- ^^ ^^ ^^ - g_lpbk_xaui => FALSE, -- g_lpbk_xaui| g_lpbk_xgmii| g_lpbk_sosi| - g_use_hdr_ram => FALSE, - g_hdr_ram_init_file => "UNUSED", - g_hdr_release_at_init => '0', -- '1' = Release header onto datapath at init - g_word_alignment_padding => TRUE + g_technology => g_technology, + --g_pre_header_padding => FALSE + g_pre_header_padding => TRUE ) PORT MAP ( - mm_rst => mm_rst, - mm_clk => mm_clk, - - tr_clk => tx_ref_clk, -- 156.25 MHz local reference - - cal_rec_clk => cal_rec_clk, - - dp_rst => dp_rst, - dp_clk => dp_clk, - - snk_out_arr => tx_snk_out_arr, - snk_in_arr => tx_snk_in_arr, -- 64 bit data + -- MM + mm_clk => mm_clk, + mm_rst => mm_rst, + csr_mosi => mm_mosi, -- CSR = control status register + csr_miso => mm_miso, - src_in_arr => rx_src_in_arr, - src_out_arr => rx_src_out_arr, -- 64 bit data - - -- MM registers - reg_mac_mosi => mac_mosi, -- MAC CSR = control status register - reg_mac_miso => mac_miso, - - --Serial I/O - xaui_tx_out_arr => xaui_tx_out_arr, -- PHY XAUI - xaui_rx_in_arr => xaui_rx_in_arr, + -- ST + tx_clk => tx_ref_clk, -- 156.25 MHz local reference + tx_rst => tx_rst, + tx_snk_in => tx_sosi, -- 64 bit data + tx_snk_out => tx_siso, - tx_serial_data => serial_tx_out_arr, -- PHY 10gbase_r - rx_serial_data => serial_rx_in_arr, + rx_clk => rx_phy_clk, -- 156.25 MHz from rx phy + rx_rst => rx_rst, + rx_src_out => rx_sosi, -- 64 bit data + rx_src_in => rx_siso, - -- MDIO External clock and serial data i/o - mdio_rst => OPEN, - mdio_mdc_arr => OPEN, - mdio_mdat_in_arr => (OTHERS=>'0'), - mdio_mdat_oen_arr => OPEN, - - mdio_mosi_arr => (OTHERS=>c_mem_mosi_rst), - mdio_miso_arr => OPEN, - - -- XAUI PHY IP MM control/status - xaui_mosi => c_mem_mosi_rst, - xaui_miso => OPEN + -- XGMII + xgmii_tx_data => xgmii_tx_data, -- 72 bit + xgmii_rx_data => xgmii_rx_data -- 72 bit ); - END GENERATE; - + END GENERATE; + no_dut : IF c_st_loopback=TRUE GENERATE - rx_src_out <= tx_snk_in; - tx_snk_out <= rx_src_in; + rx_sosi <= tx_sosi; + tx_siso <= rx_siso; END GENERATE; - -- Loopback XAUI - xaui_rx_in_arr <= TRANSPORT xaui_tx_out_arr AFTER phy_delay; + -- Loopback XGMII + xgmii_rx_data <= TRANSPORT xgmii_tx_data AFTER phy_delay; -- Verification - tx_pkt_cnt <= tx_pkt_cnt + 1 WHEN tx_snk_in.sop='1' AND rising_edge(dp_clk); - rx_pkt_cnt <= rx_pkt_cnt + 1 WHEN rx_src_out.eop='1' AND rising_edge(dp_clk); + tx_pkt_cnt <= tx_pkt_cnt + 1 WHEN tx_sosi.sop='1' AND rising_edge(tx_ref_clk); + rx_pkt_cnt <= rx_pkt_cnt + 1 WHEN rx_sosi.eop='1' AND rising_edge(rx_phy_clk); p_tb_end : PROCESS BEGIN