diff --git a/libraries/io/tr_10GbE/tb/vhdl/tb_tb_tr_10GbE.vhd b/libraries/io/tr_10GbE/tb/vhdl/tb_tb_tr_10GbE.vhd index 9c38a3ae1d05db6b495675080c25c1e4b5676d5d..3222c5b93fa16bea4de7261b0f0ae1d5c554a11f 100644 --- a/libraries/io/tr_10GbE/tb/vhdl/tb_tb_tr_10GbE.vhd +++ b/libraries/io/tr_10GbE/tb/vhdl/tb_tb_tr_10GbE.vhd @@ -26,11 +26,12 @@ -- > as 5 -- > run -all -LIBRARY IEEE, technology_lib, tech_mac_10g_lib; +LIBRARY IEEE, technology_lib, tech_pll_lib, tech_mac_10g_lib; USE IEEE.std_logic_1164.ALL; USE technology_lib.technology_pkg.ALL; USE technology_lib.technology_select_pkg.ALL; USE tech_mac_10g_lib.tb_tech_mac_10g_pkg.ALL; +USE tech_pll_lib.tech_pll_component_pkg.ALL; ENTITY tb_tb_tr_10GbE IS @@ -38,22 +39,29 @@ END tb_tb_tr_10GbE; ARCHITECTURE tb OF tb_tb_tr_10GbE IS - CONSTANT c_tb_end_vec : STD_LOGIC_VECTOR(31 DOWNTO 0) := (OTHERS=>'1'); - SIGNAL tb_end_vec : STD_LOGIC_VECTOR(31 DOWNTO 0) := c_tb_end_vec; -- sufficiently long to fit all tb instances + CONSTANT c_644 : TIME := tech_pll_clk_644_period; + CONSTANT c_156 : TIME := 6.4 ns; + CONSTANT c_data_type : NATURAL := c_tb_tech_mac_10g_data_type_symbols; + + CONSTANT c_tb_end_vec : STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS=>'1'); + SIGNAL tb_end_vec : STD_LOGIC_VECTOR(7 DOWNTO 0) := c_tb_end_vec; -- sufficiently long to fit all tb instances BEGIN --- g_technology : NATURAL := c_tech_stratixiv; --- g_tb_end : BOOLEAN := TRUE; -- when TRUE then tb_end ends this simulation, else a higher multi-testbench will end the simulation --- g_sim_level : NATURAL := 0; -- 0 = use IP; 1 = use fast serdes model --- g_no_dut : BOOLEAN := FALSE; -- default FALSE to verify the DUT, else use TRUE to verify the tb itself without the DUT --- -- g_data_type = c_tb_tech_mac_10g_data_type_symbols = 0 --- -- g_data_type = c_tb_tech_mac_10g_data_type_counter = 1 --- g_data_type : NATURAL := c_tb_tech_mac_10g_data_type_symbols +-- g_technology : NATURAL := c_tech_select_default; +-- g_tb_end : BOOLEAN := TRUE; -- when TRUE then tb_end ends this simulation, else a higher multi-testbench will end the simulation +-- g_no_dut : BOOLEAN := FALSE; -- default FALSE to verify the DUT, else use TRUE to verify the tb itself without the DUT +-- g_sim_level : NATURAL := 1; -- 0 = use IP; 1 = use fast serdes model +-- g_nof_channels : NATURAL := 1; +-- g_ref_clk_644_period : TIME := tech_pll_clk_644_period; -- for 10GBASE-R +-- g_ref_clk_156_period : TIME := 6.4 ns; -- for XAUI +-- g_data_type : NATURAL := c_tb_tech_mac_10g_data_type_symbols; +-- g_verify_link_recovery : BOOLEAN := TRUE; +-- g_link_status_check : STD_LOGIC_VECTOR(c_tech_mac_10g_link_status_w-1 DOWNTO 0) := "11" - u_no_dut_counter : ENTITY work.tb_tr_10GbE GENERIC MAP (c_tech_select_default, FALSE, 0, TRUE, c_tb_tech_mac_10g_data_type_counter) PORT MAP (tb_end_vec(0)); - u_no_dut_symbols : ENTITY work.tb_tr_10GbE GENERIC MAP (c_tech_select_default, FALSE, 0, TRUE, c_tb_tech_mac_10g_data_type_symbols) PORT MAP (tb_end_vec(1)); - u_tr_10GbE_symbols : ENTITY work.tb_tr_10GbE GENERIC MAP (c_tech_select_default, FALSE, 0, FALSE, c_tb_tech_mac_10g_data_type_symbols) PORT MAP (tb_end_vec(5)); - u_tr_10GbE_symbols_sim_level_is_1 : ENTITY work.tb_tr_10GbE GENERIC MAP (c_tech_select_default, FALSE, 1, FALSE, c_tb_tech_mac_10g_data_type_symbols) PORT MAP (tb_end_vec(6)); + u_no_dut : ENTITY work.tb_tr_10GbE GENERIC MAP (c_tech_select_default, FALSE, TRUE, 0, 1, c_644, c_156, c_data_type, TRUE, "11") PORT MAP (tb_end_vec(0)); + u_tr_10GbE : ENTITY work.tb_tr_10GbE GENERIC MAP (c_tech_select_default, FALSE, FALSE, 0, 1, c_644, c_156, c_data_type, TRUE, "11") PORT MAP (tb_end_vec(1)); + u_tr_10GbE_nof_channels_is_2 : ENTITY work.tb_tr_10GbE GENERIC MAP (c_tech_select_default, FALSE, FALSE, 0, 2, c_644, c_156, c_data_type, TRUE, "11") PORT MAP (tb_end_vec(2)); + u_tr_10GbE_sim_level_is_1 : ENTITY work.tb_tr_10GbE GENERIC MAP (c_tech_select_default, FALSE, FALSE, 1, 1, c_644, c_156, c_data_type, TRUE, "11") PORT MAP (tb_end_vec(3)); p_tb_end : PROCESS BEGIN 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 87578e00b2b3d4d0867ef2ce80cc299300c98f23..c783900be7f683fbbad037a998ad68f9805a8af3 100644 --- a/libraries/io/tr_10GbE/tb/vhdl/tb_tr_10GbE.vhd +++ b/libraries/io/tr_10GbE/tb/vhdl/tb_tr_10GbE.vhd @@ -32,9 +32,8 @@ -- > as 10 -- > run -all -LIBRARY IEEE, technology_lib, common_lib, dp_lib, tech_mac_10g_lib; +LIBRARY IEEE, technology_lib, tech_pll_lib, tech_mac_10g_lib, common_lib, dp_lib; USE IEEE.std_logic_1164.ALL; -USE IEEE.numeric_std.ALL; USE common_lib.common_pkg.ALL; USE common_lib.common_mem_pkg.ALL; USE common_lib.common_interface_layers_pkg.ALL; @@ -43,20 +42,24 @@ USE common_lib.common_network_total_header_pkg.ALL; USE common_lib.tb_common_pkg.ALL; USE dp_lib.dp_stream_pkg.ALL; USE technology_lib.technology_pkg.ALL; +USE technology_lib.technology_select_pkg.ALL; USE tech_mac_10g_lib.tech_mac_10g_component_pkg.ALL; USE tech_mac_10g_lib.tb_tech_mac_10g_pkg.ALL; - +USE tech_pll_lib.tech_pll_component_pkg.ALL; ENTITY tb_tr_10GbE IS -- Test bench control parameters GENERIC ( - g_technology : NATURAL := c_tech_stratixiv; - g_tb_end : BOOLEAN := TRUE; -- when TRUE then tb_end ends this simulation, else a higher multi-testbench will end the simulation - g_sim_level : NATURAL := 1; -- 0 = use IP; 1 = use fast serdes model - g_no_dut : BOOLEAN := FALSE; -- default FALSE to verify the DUT, else use TRUE to verify the tb itself without the DUT - -- g_data_type = c_tb_tech_mac_10g_data_type_symbols = 0 - -- g_data_type = c_tb_tech_mac_10g_data_type_counter = 1 - g_data_type : NATURAL := c_tb_tech_mac_10g_data_type_symbols + g_technology : NATURAL := c_tech_select_default; + g_tb_end : BOOLEAN := TRUE; -- when TRUE then tb_end ends this simulation, else a higher multi-testbench will end the simulation + g_no_dut : BOOLEAN := FALSE; -- default FALSE to verify the DUT, else use TRUE to verify the tb itself without the DUT + g_sim_level : NATURAL := 1; -- 0 = use IP; 1 = use fast serdes model + g_nof_channels : NATURAL := 2; + g_ref_clk_644_period : TIME := tech_pll_clk_644_period; -- for 10GBASE-R + g_ref_clk_156_period : TIME := 6.4 ns; -- for XAUI + g_data_type : NATURAL := c_tb_tech_mac_10g_data_type_symbols; + g_verify_link_recovery : BOOLEAN := TRUE; + g_link_status_check : STD_LOGIC_VECTOR(c_tech_mac_10g_link_status_w-1 DOWNTO 0) := "11" ); PORT ( tb_end : OUT STD_LOGIC @@ -68,18 +71,18 @@ ARCHITECTURE tb OF tb_tr_10GbE IS CONSTANT c_sim : BOOLEAN := TRUE; -- tr_xaui_align_dly has time delay ~ 1 sec, so not suitable for simulation - CONSTANT mm_clk_period : TIME := 20 ns; -- 50 MHz - CONSTANT dp_clk_period : TIME := 5 ns; -- 200 MHz CONSTANT cal_clk_period : TIME := 25 ns; -- 40 MHz - CONSTANT clk_156_period : TIME := 6.4 ns; -- 156.25 MHz - CONSTANT phy_delay : TIME := sel_a_b(g_sim_level>0, 0 ns, 1 ns); -- the sim_xaui and sim_10gbase_r only work with zero or tr_clk delays + CONSTANT dp_clk_period : TIME := 5 ns; -- 200 MHz - CONSTANT c_nof_channels : NATURAL := 1; - 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 := array_init(0, 50, 1) & (1472, 1473) & 9000; -- frame longer than 1518-46 = 1472 is received with rx_sosi.err = 8 + CONSTANT phy_delay : TIME := sel_a_b(g_sim_level=0, 1 ns, 0 ns); + + 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 := sel_a_b(g_verify_link_recovery, c_nof_pkt1 + c_nof_pkt2, c_nof_pkt1); 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 @@ -95,202 +98,145 @@ ARCHITECTURE tb OF tb_tr_10GbE IS SIGNAL total_header : t_network_total_header := c_network_total_header_ones; -- default fill all fields with value 1 -- Clocks and reset - SIGNAL rx_end : STD_LOGIC := '0'; - - SIGNAL clk_644 : STD_LOGIC := '1'; -- 644.53125 MHz - SIGNAL clk_312 : STD_LOGIC := '1'; -- 312.5 MHz - SIGNAL clk_156 : STD_LOGIC := '1'; -- 156.25 MHz - SIGNAL rst_156 : STD_LOGIC; -- reset synchronous with clk_156 + SIGNAL tx_end_arr : STD_LOGIC_VECTOR(g_nof_channels-1 DOWNTO 0); + SIGNAL rx_end : STD_LOGIC; SIGNAL cal_clk : STD_LOGIC := '1'; -- calibration clock - SIGNAL mm_clk : STD_LOGIC := '1'; -- memory-mapped bus clock + SIGNAL mm_clk : STD_LOGIC; -- memory-mapped bus clock SIGNAL mm_rst : STD_LOGIC; -- reset synchronous with mm_clk SIGNAL dp_clk : STD_LOGIC := '1'; -- data path clock SIGNAL dp_rst : STD_LOGIC; -- reset synchronous with dp_clk + + -- External reference clocks + SIGNAL tr_ref_clk_644 : STD_LOGIC := '1'; -- 10GBASE-R + SIGNAL tr_ref_clk_312 : STD_LOGIC; -- 10GBASE-R + SIGNAL tr_ref_clk_156 : STD_LOGIC := '1'; -- 10GBASE-R or XAUI + SIGNAL tr_ref_rst_156 : STD_LOGIC; -- 10GBASE-R or XAUI -- MAC 10G control interface - SIGNAL mm_init : STD_LOGIC := '1'; - SIGNAL mac_mosi_wrdata : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- 32 bit; + SIGNAL mm_init : STD_LOGIC; + SIGNAL mac_mosi_wrdata : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- for channel 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 mac_miso_rdval : STD_LOGIC; -- for channel 0 + SIGNAL mac_miso_rddata : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- for channel 0, 32 bit -- MAC 10G transmit interface SIGNAL tx_en : STD_LOGIC := '1'; - SIGNAL tx_siso : t_dp_siso; - SIGNAL tx_siso_arr : t_dp_siso_arr(c_nof_channels-1 DOWNTO 0); - SIGNAL tx_sosi : t_dp_sosi; - SIGNAL tx_sosi_arr : t_dp_sosi_arr(c_nof_channels-1 DOWNTO 0); - SIGNAL tx_sosi_data : STD_LOGIC_VECTOR(c_tech_mac_10g_data_w-1 DOWNTO 0); -- 64 bit + SIGNAL tx_siso_arr : t_dp_siso_arr(g_nof_channels-1 DOWNTO 0); + SIGNAL tx_sosi_arr : t_dp_sosi_arr(g_nof_channels-1 DOWNTO 0); + SIGNAL tx_sosi_data : STD_LOGIC_VECTOR(c_tech_mac_10g_data_w-1 DOWNTO 0); -- for channel 0, 64 bit -- MAC 10G receive interface - SIGNAL rx_siso : t_dp_siso; - SIGNAL rx_siso_arr : t_dp_siso_arr(c_nof_channels-1 DOWNTO 0); - SIGNAL rx_sosi : t_dp_sosi; - SIGNAL rx_sosi_reg : t_dp_sosi; - SIGNAL rx_sosi_arr : t_dp_sosi_arr(c_nof_channels-1 DOWNTO 0); - SIGNAL rx_sosi_data : STD_LOGIC_VECTOR(c_tech_mac_10g_data_w-1 DOWNTO 0); -- 64 bit + SIGNAL rx_siso_arr : t_dp_siso_arr(g_nof_channels-1 DOWNTO 0); + SIGNAL rx_sosi_arr : t_dp_sosi_arr(g_nof_channels-1 DOWNTO 0); + SIGNAL rx_sosi_data : STD_LOGIC_VECTOR(c_tech_mac_10g_data_w-1 DOWNTO 0); -- for channel 0, 64 bit -- PHY XAUI serial I/O - SIGNAL xaui_tx_arr : t_xaui_arr(c_nof_channels-1 DOWNTO 0); - SIGNAL xaui_rx_arr : t_xaui_arr(c_nof_channels-1 DOWNTO 0) := (OTHERS=>(OTHERS=>'0')); + SIGNAL xaui_tx_arr : t_xaui_arr(g_nof_channels-1 DOWNTO 0); + SIGNAL xaui_rx_arr : t_xaui_arr(g_nof_channels-1 DOWNTO 0) := (OTHERS=>(OTHERS=>'0')); -- PHY 10GBASE-R serial IO - SIGNAL serial_tx_arr : STD_LOGIC_VECTOR(c_nof_channels-1 downto 0); - SIGNAL serial_rx_arr : STD_LOGIC_VECTOR(c_nof_channels-1 downto 0) := (OTHERS=>'0'); + SIGNAL serial_tx_arr : STD_LOGIC_VECTOR(g_nof_channels-1 downto 0); + SIGNAL serial_rx_arr : STD_LOGIC_VECTOR(g_nof_channels-1 downto 0) := (OTHERS=>'0'); + -- Model a serial link fault + SIGNAL link_fault_arr : STD_LOGIC_VECTOR(g_nof_channels-1 downto 0); + -- 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 rx_toggle : STD_LOGIC := '0'; -- toggle after every received packet + SIGNAL tx_pkt_cnt_arr : t_natural_arr(g_nof_channels-1 downto 0) := (OTHERS=>0); + SIGNAL rx_pkt_cnt_arr : t_natural_arr(g_nof_channels-1 downto 0) := (OTHERS=>0); + SIGNAL rx_toggle_arr : STD_LOGIC_VECTOR(g_nof_channels-1 downto 0) := (OTHERS=>'0'); -- toggle after every received packet BEGIN cal_clk <= NOT cal_clk AFTER cal_clk_period/2; -- Calibration clock - mm_clk <= NOT mm_clk AFTER mm_clk_period/2; -- MM clock dp_clk <= NOT dp_clk AFTER dp_clk_period/2; -- DP clock - clk_156 <= NOT clk_156 AFTER clk_156_period/2; - - mm_rst <= '1', '0' AFTER mm_clk_period*10; dp_rst <= '1', '0' AFTER dp_clk_period*10; - rst_156 <= '1', '0' AFTER clk_156_period*4; - -- debug signals to ease monitoring in wave window - 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); - + -- debug signals to ease monitoring in wave window 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 - + + tx_sosi_data <= tx_sosi_arr(0).data(c_tech_mac_10g_data_w-1 DOWNTO 0); + rx_sosi_data <= rx_sosi_arr(0).data(c_tech_mac_10g_data_w-1 DOWNTO 0); + -- Use signal to leave unused fields 'X' total_header.eth <= c_eth_header_ethertype; - p_mm_setup : PROCESS - BEGIN - mm_init <= '1'; - mac_mosi.wr <= '0'; - mac_mosi.rd <= '0'; - - -- wait until after reset release - proc_common_wait_until_low(mm_clk, mm_rst); - proc_common_wait_some_cycles(mm_clk, 10); - - proc_tech_mac_10g_setup(g_technology, - c_src_mac, - mm_clk, mac_miso, mac_mosi); - mm_init <= '0'; - WAIT; - END PROCESS; - - - p_ff_transmitter : PROCESS - BEGIN - -- . Avalon ST - tx_sosi <= c_dp_sosi_rst; - - WHILE mm_init/='0' LOOP - WAIT UNTIL rising_edge(dp_clk); - END LOOP; - proc_common_wait_some_cycles(dp_clk, 10); - - -- Loopback txp->rxp so use promiscuous mode or use DST_MAC = c_src_mac to send to itself - - -- TX frame: - -- . I=0 is empty payload, so only 4 words of the ETH header with 46 padding zeros, so empty = 2 - -- . 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) + -- Generate reference clocks + gen_ref_clocks_xaui : IF g_technology=c_tech_stratixiv GENERATE + tr_ref_clk_644 <= 'X'; + tr_ref_clk_312 <= 'X'; + tr_ref_clk_156 <= NOT tr_ref_clk_156 AFTER g_ref_clk_156_period/2; + tr_ref_rst_156 <= '0' AFTER g_ref_clk_156_period*5; + END GENERATE; - 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_siso, tx_sosi); - proc_common_wait_some_cycles(dp_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); - rx_end <= '1'; - WAIT; - END PROCESS; - + gen_ref_clocks_10gbase_r : IF g_technology=c_tech_arria10 GENERATE + tr_ref_clk_644 <= NOT tr_ref_clk_644 AFTER g_ref_clk_644_period/2; - p_ff_receiver : PROCESS - BEGIN - -- . Avalon ST - rx_siso <= c_dp_siso_hold; - - WHILE mm_init/='0' LOOP - WAIT UNTIL rising_edge(dp_clk); - END LOOP; - - -- Receive forever - WHILE TRUE LOOP - proc_tech_mac_10g_rx_packet(total_header, g_data_type, dp_clk, rx_sosi, rx_siso); - rx_toggle <= NOT rx_toggle; - END LOOP; - - WAIT; - END PROCESS; + pll : ENTITY tech_pll_lib.tech_pll_xgmii_mac_clocks + GENERIC MAP ( + g_technology => g_technology + ) + PORT MAP ( + refclk_644 => tr_ref_clk_644, + clk_156 => tr_ref_clk_156, + clk_312 => tr_ref_clk_312, + rst_156 => tr_ref_rst_156, + rst_312 => OPEN + ); + END GENERATE; + -- Setup all MACs in series + u_mm_setup : ENTITY tech_mac_10g_lib.tb_tech_mac_10g_setup + GENERIC MAP ( + g_technology => g_technology, + g_nof_macs => g_nof_channels, + g_src_mac => c_src_mac + ) + PORT MAP ( + tb_end => rx_end, + mm_clk => mm_clk, + mm_rst => mm_rst, + mm_init => mm_init, + mac_mosi => mac_mosi, + mac_miso => mac_miso + ); - p_ff_store_tx_sosi_at_eop : PROCESS(dp_clk) - VARIABLE vI : NATURAL := 0; - BEGIN - IF rising_edge(dp_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_sosi_at_eop : PROCESS(dp_clk) - VARIABLE vI : NATURAL := 0; - VARIABLE vLow : NATURAL := 0; - BEGIN - IF rising_edge(dp_clk) THEN - rx_sosi_reg <= rx_sosi; -- use rx_sosi_reg for verification at eop to account for once cycle latency in expected_sosi_arr() - IF rx_sosi_reg.eop='1' THEN - IF g_no_dut=FALSE THEN - 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_sosi_reg.empty) /= 6 THEN - REPORT "RX: Wrong padded empty" SEVERITY ERROR; - END IF; - END IF; - ELSE - IF rx_sosi_reg.empty /= expected_sosi_arr(vI).empty THEN - REPORT "RX: Wrong empty" SEVERITY ERROR; - ELSE - vLow := TO_UINT(rx_sosi_reg.empty)*8; - ASSERT rx_sosi_reg.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; - END IF; - END IF; - END PROCESS; + gen_transmitter : FOR I IN 0 TO g_nof_channels-1 GENERATE + -- Packet transmitter + u_transmitter : ENTITY tech_mac_10g_lib.tb_tech_mac_10g_transmitter + GENERIC MAP ( + g_data_type => g_data_type, + g_pkt_length_arr1 => c_pkt_length_arr1, + g_pkt_length_arr2 => c_pkt_length_arr2, + g_verify_link_recovery => g_verify_link_recovery + ) + PORT MAP ( + mm_init => mm_init, + total_header => total_header, + tx_clk => dp_clk, + tx_siso => tx_siso_arr(I), + tx_sosi => tx_sosi_arr(I), + link_fault => link_fault_arr(I), + tx_end => tx_end_arr(I) + ); + END GENERATE; no_dut : IF g_no_dut=TRUE GENERATE - rx_sosi <= tx_sosi; - tx_siso <= rx_siso; + rx_sosi_arr <= tx_sosi_arr; + tx_siso_arr <= rx_siso_arr; END GENERATE; gen_dut : IF g_no_dut=FALSE GENERATE - tx_siso <= tx_siso_arr(0); - tx_sosi_arr(0) <= tx_sosi; - - rx_siso_arr(0) <= rx_siso; - rx_sosi <= rx_sosi_arr(0); - u_tr_10GbE : ENTITY work.tr_10GbE GENERIC MAP ( g_technology => g_technology, g_sim => c_sim, g_sim_level => g_sim_level, -- 0 = use IP; 1 = use fast serdes model - g_nof_macs => c_nof_channels, + g_nof_macs => g_nof_channels, g_use_mdio => TRUE, g_mdio_epcs_dis => TRUE, -- TRUE disables Enhanced PCS on init; e.g. to target a 10GbE card in PC that does not support it g_pkt_len => 100, @@ -298,10 +244,10 @@ BEGIN ) PORT MAP ( -- Transceiver PLL reference clock - tr_ref_clk_644 => clk_644, -- 644.531250 MHz for 10GBASE-R - tr_ref_clk_312 => clk_312, -- 312.5 MHz for 10GBASE-R - tr_ref_clk_156 => clk_156, -- 156.25 MHz for 10GBASE-R or for XAUI - tr_ref_rst_156 => rst_156, -- for 10GBASE-R or for XAUI + tr_ref_clk_644 => tr_ref_clk_644, -- 644.531250 MHz for 10GBASE-R + tr_ref_clk_312 => tr_ref_clk_312, -- 312.5 MHz for 10GBASE-R + tr_ref_clk_156 => tr_ref_clk_156, -- 156.25 MHz for 10GBASE-R or for XAUI + tr_ref_rst_156 => tr_ref_rst_156, -- for 10GBASE-R or for XAUI -- Calibration & reconfig clock cal_rec_clk => cal_clk, @@ -344,29 +290,80 @@ BEGIN mdio_mdat_oen_arr => OPEN ); END GENERATE; - - -- Loopback PHY - xaui_rx_arr <= TRANSPORT xaui_tx_arr AFTER phy_delay; -- XAUI - serial_rx_arr <= TRANSPORT serial_tx_arr AFTER phy_delay; -- 10GBASE-R - - -- Verification - tx_pkt_cnt <= tx_pkt_cnt + 1 WHEN tx_sosi.sop='1' AND rising_edge(dp_clk); - rx_pkt_cnt <= rx_pkt_cnt + 1 WHEN rx_sosi.eop='1' AND rising_edge(dp_clk); + + gen_link_connect : FOR I IN 0 TO g_nof_channels-1 GENERATE + u_link_connect : ENTITY tech_mac_10g_lib.tb_tech_mac_10g_link_connect + GENERIC MAP ( + g_loopback => TRUE, + g_link_delay => phy_delay + ) + PORT MAP ( + link_fault => link_fault_arr(I), -- when '1' then forces rx_serial_arr(0)='0' + + -- 10GBASE-R serial layer connect + serial_tx => serial_tx_arr(I), + serial_rx => serial_rx_arr(I), -- connects to delayed tx_serial when g_loopback=TRUE + + -- XAUI serial layer connect + xaui_tx => xaui_tx_arr(I), + xaui_rx => xaui_rx_arr(I) -- connects to delayed xaui_tx when g_loopback=TRUE + ); + END GENERATE; + + gen_receiver : FOR I IN 0 TO g_nof_channels-1 GENERATE + u_receiver : ENTITY tech_mac_10g_lib.tb_tech_mac_10_receiver + GENERIC MAP ( + g_data_type => g_data_type + ) + PORT MAP ( + mm_init => mm_init, + total_header => total_header, + rx_clk => dp_clk, + rx_sosi => rx_sosi_arr(I), + rx_siso => rx_siso_arr(I), + rx_toggle => rx_toggle_arr(I) + ); + END GENERATE; + + gen_verify_rx_at_eop : FOR I IN 0 TO g_nof_channels-1 GENERATE + u_verify_rx_at_eop : ENTITY tech_mac_10g_lib.tb_tech_mac_10_verify_rx_at_eop + GENERIC MAP ( + g_no_padding => g_no_dut, + g_pkt_length_arr => c_pkt_length_arr + ) + PORT MAP ( + tx_clk => dp_clk, + tx_sosi => tx_sosi_arr(I), + rx_clk => dp_clk, + rx_sosi => rx_sosi_arr(I) + ); + END GENERATE; + + gen_verify_rx_pkt_cnt : FOR I IN 0 TO g_nof_channels-1 GENERATE + u_verify_rx_pkt_cnt : ENTITY tech_mac_10g_lib.tb_tech_mac_10g_verify_rx_pkt_cnt + GENERIC MAP ( + g_nof_pkt => c_nof_pkt + ) + PORT MAP ( + tx_clk => dp_clk, + tx_sosi => tx_sosi_arr(I), + rx_clk => dp_clk, + rx_sosi => rx_sosi_arr(I), + tx_pkt_cnt => tx_pkt_cnt_arr(I), + rx_pkt_cnt => rx_pkt_cnt_arr(I), + rx_end => rx_end + ); + END GENERATE; p_tb_end : PROCESS BEGIN tb_end <= '0'; - WAIT UNTIL rx_end='1'; - - -- Verify that all transmitted packets have been received - IF tx_pkt_cnt=0 THEN - REPORT "No packets were transmitted." SEVERITY ERROR; - ELSIF rx_pkt_cnt=0 THEN - REPORT "No packets were received." SEVERITY ERROR; - ELSIF tx_pkt_cnt/=rx_pkt_cnt THEN - REPORT "Not all transmitted packets were received." SEVERITY ERROR; - END IF; - proc_common_wait_some_cycles(clk_156, 100); + rx_end <= '0'; + WAIT UNTIL andv(tx_end_arr)='1'; + proc_common_wait_some_cycles(dp_clk, 1000); + rx_end <= '1'; + proc_common_wait_some_cycles(dp_clk, 100); + --proc_common_wait_some_cycles(dp_clk, 10000); -- uncomment to simulate somewhat longer without tx packet data -- Stop the simulation tb_end <= '1'; @@ -377,5 +374,5 @@ BEGIN END IF; WAIT; END PROCESS; - + END tb;