diff --git a/libraries/technology/eth_10g/tb_tech_eth_10g.vhd b/libraries/technology/eth_10g/tb_tech_eth_10g.vhd index 50d255f9996e3ec6d8024bfeea867378e84d72ba..1364c8be313a2263e8f9b47a74fd02f73a33a129 100644 --- a/libraries/technology/eth_10g/tb_tech_eth_10g.vhd +++ b/libraries/technology/eth_10g/tb_tech_eth_10g.vhd @@ -63,10 +63,13 @@ ARCHITECTURE tb OF tb_tech_eth_10g IS 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_sosi.err = 8 + CONSTANT c_pkt_length_arr1 : 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; + CONSTANT c_pkt_length_arr2 : t_nat_natural_arr := array_init(46, 10, 139) & 1472; + CONSTANT c_pkt_length_arr : t_nat_natural_arr := c_pkt_length_arr1 & c_pkt_length_arr2; + CONSTANT c_nof_pkt1 : NATURAL := c_pkt_length_arr1'LENGTH; + CONSTANT c_nof_pkt2 : NATURAL := c_pkt_length_arr2'LENGTH; + CONSTANT c_nof_pkt : NATURAL := c_nof_pkt1 + c_nof_pkt2; CONSTANT c_dst_mac : STD_LOGIC_VECTOR(c_network_eth_mac_slv'RANGE) := X"10FA01020300"; CONSTANT c_src_mac : STD_LOGIC_VECTOR(c_network_eth_mac_slv'RANGE) := X"123456789ABC"; -- = 12-34-56-78-9A-BC @@ -116,8 +119,13 @@ ARCHITECTURE tb OF tb_tech_eth_10g IS SIGNAL rx_sosi_data : STD_LOGIC_VECTOR(c_tech_mac_10g_data_w-1 DOWNTO 0); -- 64 bit -- 10G PHY serial interface - SIGNAL tx_serial_arr : STD_LOGIC_VECTOR(0 DOWNTO 0); - SIGNAL rx_serial_arr : STD_LOGIC_VECTOR(0 DOWNTO 0); + SIGNAL tx_serial_arr : STD_LOGIC_VECTOR(0 DOWNTO 0); + SIGNAL tx_serial_arr_dly : STD_LOGIC_VECTOR(0 DOWNTO 0); + SIGNAL tx_serial_arr_fault : STD_LOGIC_VECTOR(0 DOWNTO 0); + SIGNAL rx_serial_arr : STD_LOGIC_VECTOR(0 DOWNTO 0); + + -- Model a serial link fault + SIGNAL link_fault : STD_LOGIC; -- Verification SIGNAL expected_sosi_arr : t_dp_sosi_arr(0 TO c_nof_pkt-1); @@ -163,13 +171,15 @@ BEGIN p_ff_transmitter : PROCESS BEGIN + link_fault <= '0'; + -- . Avalon ST tx_sosi <= c_dp_sosi_rst; WHILE mm_init/='0' LOOP WAIT UNTIL rising_edge(clk_156); END LOOP; - proc_common_wait_some_cycles(clk_156, 3125); -- 20 us + proc_common_wait_some_cycles(clk_156, 10); -- Loopback txp->rxp so use promiscuous mode or use DST_MAC = c_src_mac to send to itself @@ -178,12 +188,25 @@ BEGIN -- . For I=1 to 46 the payload length remains 46 with padding zeros, so empty = 2 -- . 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, clk_156, tx_en, tx_siso, tx_sosi); + FOR I IN 0 TO c_nof_pkt1-1 LOOP + proc_tech_mac_10g_tx_packet(total_header, c_pkt_length_arr1(I), g_data_type, c_rl, c_nof_tx_not_valid, clk_156, tx_en, tx_siso, tx_sosi); proc_common_wait_some_cycles(clk_156, 0); END LOOP; - proc_common_wait_some_cycles(clk_156, c_pkt_length_arr(c_nof_pkt-1)/c_tech_mac_10g_symbols_per_beat); + proc_common_wait_some_cycles(clk_156, c_pkt_length_arr1(c_nof_pkt1-1)/c_tech_mac_10g_symbols_per_beat); + proc_common_wait_some_cycles(clk_156, 100); + + -- Model a link fault to verify Rx recovery + link_fault <= '1'; + proc_common_wait_some_cycles(clk_156, 1000); + link_fault <= '0'; + + FOR I IN 0 TO c_nof_pkt2-1 LOOP + proc_tech_mac_10g_tx_packet(total_header, c_pkt_length_arr2(I), g_data_type, c_rl, c_nof_tx_not_valid, clk_156, tx_en, tx_siso, tx_sosi); + proc_common_wait_some_cycles(clk_156, 0); + END LOOP; + + proc_common_wait_some_cycles(clk_156, c_pkt_length_arr2(c_nof_pkt2-1)/c_tech_mac_10g_symbols_per_beat); proc_common_wait_some_cycles(clk_156, 100); tb_end <= '1'; WAIT; @@ -309,7 +332,15 @@ BEGIN END GENERATE; -- Loopback serial - rx_serial_arr <= TRANSPORT tx_serial_arr AFTER phy_delay; + tx_serial_arr_dly <= TRANSPORT tx_serial_arr AFTER phy_delay; + + p_rx_serial : PROCESS(tx_serial_arr_dly, link_fault) + BEGIN + rx_serial_arr <= tx_serial_arr_dly; + IF link_fault='1' THEN + rx_serial_arr(0) <= '0'; + END IF; + END PROCESS; -- Verification tx_pkt_cnt <= tx_pkt_cnt + 1 WHEN tx_sosi.sop='1' AND rising_edge(clk_156);