diff --git a/libraries/io/eth/tb/vhdl/tb_tb_eth_tester.vhd b/libraries/io/eth/tb/vhdl/tb_tb_eth_tester.vhd index 8afc5cbad60a69be34dbcd8b7d0f1874fa3602cb..a0b834bb4ad93f8e0e99a1fb7a55022612161162 100644 --- a/libraries/io/eth/tb/vhdl/tb_tb_eth_tester.vhd +++ b/libraries/io/eth/tb/vhdl/tb_tb_eth_tester.vhd @@ -23,36 +23,77 @@ -- -- References: -- [1] https://support.astron.nl/confluence/display/L2M/L6+FWLIB+Design+Document%3A+ETH+tester+unit+for+1GbE +-- [2] https://support.astron.nl/confluence/display/L2M/L4+SDPFW+Decision%3A+Application+header+size+in+Ethernet+packets -- -- Usage: --- > as 3 +-- > as 8 -- > run -all LIBRARY IEEE, diag_lib; USE IEEE.std_logic_1164.ALL; USE diag_lib.diag_pkg.ALL; +USE work.tb_eth_tester_pkg.ALL; ENTITY tb_tb_eth_tester IS END tb_tb_eth_tester; ARCHITECTURE tb OF tb_tb_eth_tester IS - CONSTANT c_bg_ctrl_rst : t_diag_block_gen_integer := func_diag_bg_ctrl_slv_to_integer(c_diag_block_gen_rst); - CONSTANT c_bg_ctrl_first : t_diag_block_gen_integer := ('1', '1', 50, 8, 100, 0, 30, 0); -- for first stream - CONSTANT c_bg_ctrl_others : t_diag_block_gen_integer := ('1', '1', 30, 8, 10, 0, 30, 0); -- for other streams - CONSTANT c_bg_ctrl_len_0 : t_diag_block_gen_integer := ('1', '1', 80, 8, 100, 0, 30, 0); -- nof octets - CONSTANT c_bg_ctrl_len_1 : t_diag_block_gen_integer := ('1', '1', 81, 8, 100, 0, 30, 0); -- nof octets - CONSTANT c_bg_ctrl_len_2 : t_diag_block_gen_integer := ('1', '1', 82, 8, 100, 0, 30, 0); -- nof octets - CONSTANT c_bg_ctrl_len_3 : t_diag_block_gen_integer := ('1', '1', 83, 8, 100, 0, 30, 0); -- nof octets + -- Multi tb + CONSTANT c_tb_w : NATURAL := 50; -- sufficiently long to fit all tb instances + CONSTANT c_tb_end_vec : STD_LOGIC_VECTOR(c_tb_w-1 DOWNTO 0) := (OTHERS=>'1'); + + SIGNAL tb_end_vec : STD_LOGIC_VECTOR(c_tb_w-1 DOWNTO 0) := c_tb_end_vec; + SIGNAL tb_end : STD_LOGIC := '0'; + + -- Tb + CONSTANT c_eth_clk_MHz : NATURAL := 125; + CONSTANT c_st_clk_MHz : NATURAL := 200; + CONSTANT c_nof_sync : NATURAL := 3; + CONSTANT c_nof_sync_many : NATURAL := 100; + CONSTANT c_nof_streams : NATURAL := 3; + + -- Tx packet size and gap size in octets + CONSTANT c_block_len : NATURAL := 50; -- BG block length of first stream [0] + CONSTANT c_link_len : NATURAL := func_eth_tester_eth_packet_on_link_length(c_block_len); + + -- For near maximum 1Gbps link rate the c_block_len + c_gap_len_min time + -- in the st_clk domain equals c_link_len time in eth_clk domain. + CONSTANT c_gap_len_min : NATURAL := c_link_len * c_st_clk_MHz / c_eth_clk_MHz - c_block_len; + CONSTANT c_slot_len_min : NATURAL := c_block_len + c_gap_len_min; + + -- Choose c_gap_len somewhat larger to have packet link rate < 1 Gbps + CONSTANT c_gap_len : NATURAL := c_gap_len_min * 2; -- for g_nof_streams = 1 + CONSTANT c_short_gap : NATURAL := 10; -- to cause BG xon/xoff flow control + CONSTANT c_zero_gap : NATURAL := 0; -- to verify BG ready flow control + + -- Choose c_others_len > c_block_len, so same c_gap_len is suitable to + -- keep Ethernet link rate < 1 Gbps + CONSTANT c_other_len : NATURAL := 65; -- BG block length of other streams [c_nof_streams-1 : 1] + + -- BG ctrl + CONSTANT c_high : NATURAL := c_diag_bg_mem_max_adr; -- = 2**24 + + CONSTANT c_bg_ctrl_rst : t_diag_block_gen_integer := ('0', '0', 1, 8, c_gap_len, 0, c_high, 0); -- place holder for unused stream + + CONSTANT c_bg_ctrl_one : t_diag_block_gen_integer := ('1', '1', c_block_len, 8, c_gap_len, 0, c_high, 0); -- for first stream + CONSTANT c_bg_ctrl_others : t_diag_block_gen_integer := ('1', '1', c_other_len, 8, c_gap_len, 0, c_high, 0); -- for other streams + + CONSTANT c_bg_ctrl_len_0 : t_diag_block_gen_integer := ('1', '1', c_block_len+0, 8, c_gap_len, 0, c_high, 0); -- nof octets + CONSTANT c_bg_ctrl_len_1 : t_diag_block_gen_integer := ('1', '1', c_block_len+1, 8, c_gap_len, 0, c_high, 0); -- nof octets + CONSTANT c_bg_ctrl_len_2 : t_diag_block_gen_integer := ('1', '1', c_block_len+2, 8, c_gap_len, 0, c_high, 0); -- nof octets + CONSTANT c_bg_ctrl_len_3 : t_diag_block_gen_integer := ('1', '1', c_block_len+3, 8, c_gap_len, 0, c_high, 0); -- nof octets + + CONSTANT c_bg_ctrl_multiple_first : t_diag_block_gen_integer := ('1', '1', c_block_len, 8, c_nof_streams * c_gap_len, 0, c_high, 0); -- for first stream + CONSTANT c_bg_ctrl_multiple_others : t_diag_block_gen_integer := ('1', '1', c_other_len, 8, c_nof_streams * c_gap_len, 0, c_high, 0); -- for other streams - SIGNAL tb_end : STD_LOGIC := '0'; -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end' - BEGIN -- g_tb_index : NATURAL := 0; -- use to incremental delay logging from tb instances in tb_tb --- g_tb_str : STRING := ""; -- use to distinguish logging from tb instances in tb_tb +-- g_nof_sync : NATURAL := 3; -- number of BG sync intervals to set c_run_time -- g_nof_streams : NATURAL := 2; -- g_loopback_eth : BOOLEAN := FALSE; -- FALSE = sosi loopback, TRUE = eth loopback +-- g_eth_sim_level : NATURAL := 0; -- when g_loopback_eth = TRUE, then 0 = use IP; 1 = use fast serdes model -- -- -- t_diag_block_gen_integer = -- -- sl: enable @@ -66,13 +107,55 @@ BEGIN -- g_bg_ctrl_first : t_diag_block_gen_integer := ('1', '1', 50, 8, 100, 0, 30, 0); -- for first stream -- g_bg_ctrl_others : t_diag_block_gen_integer := ('1', '1', 30, 8, 10, 0, 30, 0) -- for other streams - u_one_stream : ENTITY work.tb_eth_tester GENERIC MAP (0, "tb_one_stream: ", 1, FALSE, c_bg_ctrl_first, c_bg_ctrl_rst); - u_multiple_streams : ENTITY work.tb_eth_tester GENERIC MAP (1, "tb_multiple_streams: ", 3, FALSE, c_bg_ctrl_first, c_bg_ctrl_others); + -- Tb instance prefix: + -- . st = streaming Tx-Rx interface + -- . sim = sim_tse Tx-Rx interface + -- . tech = tech_tse Tx-Rx interface + + ----------------------------------------------------------------------------- + -- Single stream + ----------------------------------------------------------------------------- + -- Try different loopback interfaces + u_st : ENTITY work.tb_eth_tester GENERIC MAP (0, c_nof_sync, 1, FALSE, 1, c_bg_ctrl_one, c_bg_ctrl_rst) PORT MAP (tb_end_vec(0)); + u_sim_tse : ENTITY work.tb_eth_tester GENERIC MAP (1, c_nof_sync, 1, TRUE, 1, c_bg_ctrl_one, c_bg_ctrl_rst) PORT MAP (tb_end_vec(1)); + u_tech_tse : ENTITY work.tb_eth_tester GENERIC MAP (2, c_nof_sync, 1, TRUE, 0, c_bg_ctrl_one, c_bg_ctrl_rst) PORT MAP (tb_end_vec(2)); + + -- Try different BG block lengths to verify sosi.empty nof octets in last word + u_st_bg_len_0 : ENTITY work.tb_eth_tester GENERIC MAP (10, c_nof_sync, 1, FALSE, 1, c_bg_ctrl_len_0, c_bg_ctrl_rst) PORT MAP (tb_end_vec(10)); + u_st_bg_len_1 : ENTITY work.tb_eth_tester GENERIC MAP (11, c_nof_sync, 1, FALSE, 1, c_bg_ctrl_len_1, c_bg_ctrl_rst) PORT MAP (tb_end_vec(11)); + u_st_bg_len_2 : ENTITY work.tb_eth_tester GENERIC MAP (12, c_nof_sync, 1, FALSE, 1, c_bg_ctrl_len_2, c_bg_ctrl_rst) PORT MAP (tb_end_vec(12)); + u_st_bg_len_3 : ENTITY work.tb_eth_tester GENERIC MAP (13, c_nof_sync, 1, FALSE, 1, c_bg_ctrl_len_3, c_bg_ctrl_rst) PORT MAP (tb_end_vec(13)); + + -- Try BG xon/xoff block flow control by using smaller gapsize that would exceed 1 Gbps + u_st_bg_flow_control : ENTITY work.tb_eth_tester + GENERIC MAP (20, c_nof_sync, 1, FALSE, 1, + ('1', '1', c_block_len, 8, c_zero_gap, 0, c_high, 0), + c_bg_ctrl_rst) + PORT MAP (tb_end_vec(20)); + + ----------------------------------------------------------------------------- + -- Multiple streams + ----------------------------------------------------------------------------- + u_st_multiple_streams : ENTITY work.tb_eth_tester + GENERIC MAP (30, c_nof_sync, c_nof_streams, FALSE, 1, + c_bg_ctrl_multiple_first, + c_bg_ctrl_multiple_others) + PORT MAP (tb_end_vec(30)); + + u_st_multiple_bg_flow_control : ENTITY work.tb_eth_tester + GENERIC MAP (31, c_nof_sync_many, c_nof_streams, FALSE, 1, + ('1', '1', c_block_len, 8, c_short_gap, 0, c_high, 0), + ('1', '1', c_other_len, 8, c_short_gap, 0, c_high, 0)) + PORT MAP (tb_end_vec(31)); + + tb_end <= '1' WHEN tb_end_vec = c_tb_end_vec ELSE '0'; - -- Try different BG block lengths to verify nof octets in last word - u_bg_len_0 : ENTITY work.tb_eth_tester GENERIC MAP (10, "tb_bg_len_0: ", 1, FALSE, c_bg_ctrl_len_0, c_bg_ctrl_rst); - u_bg_len_1 : ENTITY work.tb_eth_tester GENERIC MAP (11, "tb_bg_len_1: ", 1, FALSE, c_bg_ctrl_len_1, c_bg_ctrl_rst); - u_bg_len_2 : ENTITY work.tb_eth_tester GENERIC MAP (12, "tb_bg_len_2: ", 1, FALSE, c_bg_ctrl_len_2, c_bg_ctrl_rst); - u_bg_len_3 : ENTITY work.tb_eth_tester GENERIC MAP (13, "tb_bg_len_3: ", 1, FALSE, c_bg_ctrl_len_3, c_bg_ctrl_rst); + p_tb_end : PROCESS + BEGIN + WAIT UNTIL tb_end='1'; + WAIT FOR 1 ns; + REPORT "Multi tb simulation finished." SEVERITY FAILURE; + WAIT; + END PROCESS; END tb;