diff --git a/libraries/io/eth/tb/vhdl/tb_eth_tester.vhd b/libraries/io/eth/tb/vhdl/tb_eth_tester.vhd index cc0ba0bfd548a94b7b6fa3cab5ded54b40fe7209..be8f3a05e8011bb471241862c661e8967943221a 100644 --- a/libraries/io/eth/tb/vhdl/tb_eth_tester.vhd +++ b/libraries/io/eth/tb/vhdl/tb_eth_tester.vhd @@ -22,13 +22,16 @@ -- Description: See detailed design in [1] -- The g_nof_streams >= 1 are tested independently, using g_bg_ctrl_first for -- BG in stream 0 and g_bg_ctrl_others for all other streams. +-- -- Usage: -- > as 8 -- > run -a +-- -- 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 -LIBRARY IEEE, common_lib, dp_lib, diag_lib; +LIBRARY IEEE, common_lib, dp_lib, diag_lib, technology_lib, tech_tse_lib; USE IEEE.std_logic_1164.ALL; USE IEEE.numeric_std.ALL; USE common_lib.common_pkg.ALL; @@ -43,13 +46,18 @@ USE diag_lib.diag_pkg.ALL; USE work.eth_pkg.ALL; USE work.eth_tester_pkg.ALL; USE work.tb_eth_tester_pkg.ALL; +--USE technology_lib.technology_pkg.ALL; +USE technology_lib.technology_select_pkg.ALL; +USE tech_tse_lib.tech_tse_pkg.ALL; +USE tech_tse_lib.tb_tech_tse_pkg.ALL; ENTITY tb_eth_tester IS GENERIC ( 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_streams : NATURAL := 2; -- <= c_eth_nof_udp_ports = 4 when g_loopback_tx_rx = 1 - g_loopback_eth : BOOLEAN := TRUE; -- FALSE = sosi loopback, TRUE = eth loopback + g_nof_sync : NATURAL := 93; -- number of BG sync intervals to set c_run_time + g_nof_streams : NATURAL := 1; -- <= c_eth_nof_udp_ports = 4 when g_loopback_tx_rx = 1 + g_loopback_eth : BOOLEAN := FALSE; -- FALSE = sosi loopback, TRUE = eth loopback + g_eth_sim_level : NATURAL := 1; -- when g_loopback_eth = TRUE, then 0 = use tech_tse IP; 1 = use fast sim_tse model -- t_diag_block_gen_integer = -- sl: enable @@ -60,47 +68,66 @@ ENTITY tb_eth_tester IS -- nat: mem_low_adrs -- nat: mem_high_adrs -- nat: bsn_init - g_bg_ctrl_first : t_diag_block_gen_integer := ('1', '1', 50, 8, 100, 0, c_diag_bg_mem_max_adr, 0); -- for first stream + --g_bg_ctrl_first : t_diag_block_gen_integer := ('1', '1', 50, 8, 100, 0, c_diag_bg_mem_max_adr, 0); -- for first stream + --g_bg_ctrl_others : t_diag_block_gen_integer := ('1', '1', 30, 8, 10, 0, c_diag_bg_mem_max_adr, 0) -- for other streams + g_bg_ctrl_first : t_diag_block_gen_integer := ('1', '1', 50, 8, 660, 0, c_diag_bg_mem_max_adr, 0); -- for first stream g_bg_ctrl_others : t_diag_block_gen_integer := ('1', '1', 30, 8, 10, 0, c_diag_bg_mem_max_adr, 0) -- for other streams ); + PORT ( + tb_end : OUT STD_LOGIC + ); END tb_eth_tester; ARCHITECTURE tb OF tb_eth_tester IS - + + CONSTANT c_tb_str : STRING := "tb-" & NATURAL'IMAGE(g_tb_index) & " : "; -- use to distinguish logging from tb instances in tb_tb CONSTANT eth_clk_period : TIME := 8 ns; -- 125 MHz CONSTANT mm_clk_period : TIME := 10 ns; -- 100 MHz - CONSTANT st_clk_period : TIME := 5 ns; -- 200 MHz + CONSTANT c_nof_st_clk_per_s : NATURAL := 200 * 10**6; + CONSTANT st_clk_period : TIME := (10**9 / c_nof_st_clk_per_s) * 1 ns; -- 5 ns, 200 MHz + + CONSTANT c_bg_block_len_first : NATURAL := g_bg_ctrl_first.samples_per_packet; + CONSTANT c_bg_block_len_others : NATURAL := g_bg_ctrl_others.samples_per_packet; + + CONSTANT c_bg_slot_len_first : NATURAL := c_bg_block_len_first + g_bg_ctrl_first.gapsize; + CONSTANT c_bg_slot_len_others : NATURAL := c_bg_block_len_others + g_bg_ctrl_others.gapsize; + + CONSTANT c_eth_packet_len_first : NATURAL := func_eth_tester_eth_packet_length(c_bg_block_len_first); + CONSTANT c_eth_packet_len_others : NATURAL := func_eth_tester_eth_packet_length(c_bg_block_len_others); - CONSTANT c_bg_slot_len_first : NATURAL := g_bg_ctrl_first.samples_per_packet + g_bg_ctrl_first.gapsize; - CONSTANT c_bg_slot_len_others : NATURAL := g_bg_ctrl_others.samples_per_packet + g_bg_ctrl_others.gapsize; + -- Use REAL to avoid NATURAL overflow in bps calculation + CONSTANT c_eth_nof_bps_first : REAL := REAL(c_eth_packet_len_first * c_octet_w) * REAL(c_nof_st_clk_per_s) / REAL(c_bg_slot_len_first); + CONSTANT c_eth_nof_bps_others : REAL := REAL(c_eth_packet_len_others * c_octet_w) * REAL(c_nof_st_clk_per_s) / REAL(c_bg_slot_len_others); + CONSTANT c_eth_nof_bps_total : REAL := c_eth_nof_bps_first + REAL(g_nof_streams - 1) * c_eth_nof_bps_others; CONSTANT c_bg_sync_period_first : NATURAL := c_bg_slot_len_first * g_bg_ctrl_first.blocks_per_sync; CONSTANT c_bg_sync_period_others : NATURAL := c_bg_slot_len_others * g_bg_ctrl_others.blocks_per_sync; CONSTANT c_bg_sync_period_max : NATURAL := largest(c_bg_sync_period_first, c_bg_sync_period_others); - CONSTANT c_nof_sync : NATURAL := 3; - CONSTANT c_run_time : NATURAL := c_nof_sync * c_bg_sync_period_max; + CONSTANT c_run_time : NATURAL := g_nof_sync * c_bg_sync_period_max; CONSTANT c_nof_sync_first : NATURAL := c_run_time / c_bg_sync_period_first; CONSTANT c_nof_sync_others : NATURAL := c_run_time / c_bg_sync_period_others; -- Expected Tx --> Rx latency values obtained from a tb run - CONSTANT c_tx_exp_latency : NATURAL := 0; - CONSTANT c_rx_exp_latency : NATURAL := sel_a_b(g_loopback_eth, 450, 27); + CONSTANT c_tx_exp_latency : NATURAL := 0; + CONSTANT c_rx_exp_latency_st : NATURAL := 27; + CONSTANT c_rx_exp_latency_sim_tse : NATURAL := 165; + CONSTANT c_rx_exp_latency_tech_tse : NATURAL := 375; -- CRC is added by ETH IP. Therefore Tx packet has no CRC yet and Rx -- packet length depends on g_loopback_eth = TRUE - CONSTANT c_nof_valid_per_packet_first : NATURAL := g_bg_ctrl_first.samples_per_packet + sel_a_b(g_loopback_eth, 4, 0); - CONSTANT c_nof_valid_per_packet_others : NATURAL := g_bg_ctrl_others.samples_per_packet + sel_a_b(g_loopback_eth, 4, 0); + CONSTANT c_nof_valid_per_packet_first : NATURAL := c_bg_block_len_first + sel_a_b(g_loopback_eth, 4, 0); + CONSTANT c_nof_valid_per_packet_others : NATURAL := c_bg_block_len_others + sel_a_b(g_loopback_eth, 4, 0); CONSTANT c_total_count_nof_valid_per_sync_first : NATURAL := g_bg_ctrl_first.blocks_per_sync * c_nof_valid_per_packet_first; CONSTANT c_total_count_nof_valid_per_sync_others : NATURAL := g_bg_ctrl_others.blocks_per_sync * c_nof_valid_per_packet_others; CONSTANT c_mon_nof_sop_first : NATURAL := g_bg_ctrl_first.blocks_per_sync; CONSTANT c_mon_nof_sop_others : NATURAL := g_bg_ctrl_others.blocks_per_sync; - CONSTANT c_mon_nof_valid_first_tx : NATURAL := c_mon_nof_sop_first * ceil_div(g_bg_ctrl_first.samples_per_packet * c_octet_w, c_word_w); + CONSTANT c_mon_nof_valid_first_tx : NATURAL := c_mon_nof_sop_first * ceil_div(c_bg_block_len_first * c_octet_w, c_word_w); CONSTANT c_mon_nof_valid_first_rx : NATURAL := c_mon_nof_sop_first * c_nof_valid_per_packet_first; - CONSTANT c_mon_nof_valid_others_tx : NATURAL := c_mon_nof_sop_others * ceil_div(g_bg_ctrl_others.samples_per_packet* c_octet_w, c_word_w); + CONSTANT c_mon_nof_valid_others_tx : NATURAL := c_mon_nof_sop_others * ceil_div(c_bg_block_len_others* c_octet_w, c_word_w); CONSTANT c_mon_nof_valid_others_rx : NATURAL := c_mon_nof_sop_others * c_nof_valid_per_packet_others; -- Use sim default src MAC, IP, UDP port from eth_tester_pkg.vhd and based on c_gn_index @@ -116,7 +143,7 @@ ARCHITECTURE tb OF tb_eth_tester IS SIGNAL st_clk : STD_LOGIC := '1'; SIGNAL st_pps : STD_LOGIC := '0'; SIGNAL stimuli_end : STD_LOGIC := '0'; - SIGNAL tb_end : STD_LOGIC := '0'; + SIGNAL i_tb_end : STD_LOGIC := '0'; SIGNAL eth_clk : STD_LOGIC := '1'; SIGNAL eth_txp : STD_LOGIC; @@ -125,6 +152,8 @@ ARCHITECTURE tb OF tb_eth_tester IS -- Use same bg_ctrl for all streams, this provides sufficient test coverage SIGNAL bg_ctrl_arr : t_diag_block_gen_integer_arr(g_nof_streams-1 DOWNTO 0); + SIGNAL tx_fifo_rd_emp_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); + -- ETH UDP data path interface SIGNAL tx_udp_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); SIGNAL tx_udp_siso_arr : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy); @@ -174,6 +203,12 @@ ARCHITECTURE tb OF tb_eth_tester IS SIGNAL reg_eth_copi : t_mem_copi := c_mem_copi_rst; SIGNAL reg_eth_cipo : t_mem_cipo; + -- . set up eth when g_eth_sim_level = 0 + SIGNAL tse_init : STD_LOGIC := '1'; + SIGNAL tse_copi : t_mem_copi := c_mem_copi_rst; + SIGNAL tse_cipo : t_mem_cipo; + SIGNAL tse_psc_access : STD_LOGIC; + -- View in Wave window SIGNAL dbg_c_mon_nof_sop_first : NATURAL := c_mon_nof_sop_first; SIGNAL dbg_c_mon_nof_sop_others : NATURAL := c_mon_nof_sop_others; @@ -184,16 +219,18 @@ ARCHITECTURE tb OF tb_eth_tester IS BEGIN - eth_clk <= (NOT eth_clk) OR tb_end AFTER eth_clk_period/2; - mm_clk <= (NOT mm_clk) OR tb_end AFTER mm_clk_period/2; - st_clk <= (NOT st_clk) OR tb_end AFTER st_clk_period/2; + tb_end <= i_tb_end; + + eth_clk <= (NOT eth_clk) OR i_tb_end AFTER eth_clk_period/2; + mm_clk <= (NOT mm_clk) OR i_tb_end AFTER mm_clk_period/2; + st_clk <= (NOT st_clk) OR i_tb_end AFTER st_clk_period/2; mm_rst <= '1', '0' AFTER mm_clk_period*5; st_rst <= '1', '0' AFTER st_clk_period*5; -- Using --SIGNAL exp_total_count_nof_packet_arr : t_natural_arr(g_nof_streams-1 DOWNTO 0); - -- (g_nof_streams-1 DOWNTO 1 => c_nof_sync * g_bg_ctrl_others.blocks_per_sync, - -- 0 => c_nof_sync * g_bg_ctrl_first.blocks_per_sync); + -- (g_nof_streams-1 DOWNTO 1 => g_nof_sync * g_bg_ctrl_others.blocks_per_sync, + -- 0 => g_nof_sync * g_bg_ctrl_first.blocks_per_sync); -- yields verror 1074, verror 1048, therefor use p_init instead, and -- therefor use bg_ctrl_arr instead of c_bg_ctrl_arr. p_init : PROCESS @@ -215,21 +252,26 @@ BEGIN -- MM control and monitoring ----------------------------------------------------------------------------- p_mm : PROCESS - VARIABLE v_offset : NATURAL; - VARIABLE v_port : NATURAL; - VARIABLE v_value : NATURAL; + VARIABLE v_value : NATURAL; + VARIABLE v_offset : NATURAL; + VARIABLE v_udp_dst_port : NATURAL; BEGIN + i_tb_end <= '0'; + proc_common_wait_until_low(mm_clk, mm_rst); proc_common_wait_some_cycles(mm_clk, 10); + proc_common_wait_until_low(mm_clk, tse_init); + proc_common_wait_some_cycles(mm_clk, 10); + --------------------------------------------------------------------------- -- Rx UDP offload port --------------------------------------------------------------------------- - v_port := TO_UINT(c_eth_tester_udp_dst_port); + v_udp_dst_port := TO_UINT(c_eth_tester_udp_dst_port); IF g_loopback_eth = TRUE THEN -- Set up demux in eth Rx based on destination UDP port - v_value := 2**16 + v_port; -- enable bit 16, udp port number [15:0] + v_value := 2**16 + v_udp_dst_port; -- enable bit 16, udp port number [15:0] FOR I IN g_nof_streams-1 DOWNTO 0 LOOP proc_mem_mm_bus_wr(0 + I, v_value + I, mm_clk, reg_eth_copi); -- increment udp_dst_port per stream END LOOP; @@ -239,7 +281,7 @@ BEGIN v_offset := I * c_eth_tester_reg_hdr_dat_addr_span; -- Set destination MAC/IP/UDP port in tx header, increment udp_dst_port per stream -- The MM addresses follow from byte address_offset // 4 in eth.peripheral.yaml - proc_mem_mm_bus_wr(v_offset + 16#6#, v_port + I, mm_clk, reg_hdr_dat_cipo, reg_hdr_dat_copi); + proc_mem_mm_bus_wr(v_offset + 16#6#, v_udp_dst_port + I, mm_clk, reg_hdr_dat_cipo, reg_hdr_dat_copi); proc_mem_mm_bus_wr(v_offset + 16#9#, TO_SINT(c_eth_tester_ip_dst_addr), mm_clk, reg_hdr_dat_cipo, reg_hdr_dat_copi); -- use signed to fit 32 b in INTEGER proc_mem_mm_bus_wr(v_offset + 16#17#, TO_SINT(c_eth_tester_eth_dst_mac(31 DOWNTO 0)), mm_clk, reg_hdr_dat_cipo, reg_hdr_dat_copi); -- use signed to fit 32 b in INTEGER proc_mem_mm_bus_wr(v_offset + 16#18#, TO_UINT(c_eth_tester_eth_dst_mac(47 DOWNTO 32)), mm_clk, reg_hdr_dat_cipo, reg_hdr_dat_copi); @@ -274,12 +316,36 @@ BEGIN -- Disable the other BG proc_mem_mm_bus_wr(v_offset + 0, 0, mm_clk, reg_bg_ctrl_copi); END LOOP; - proc_common_wait_some_cycles(st_clk, sel_a_b(g_loopback_eth, 20, 1) * c_bg_sync_period_max); + + -- Wait until Tx FIFOs have emptied for all streams + WHILE UNSIGNED(tx_fifo_rd_emp_arr(g_nof_streams-1 DOWNTO 0)) /= 2**g_nof_streams - 1 LOOP + proc_common_wait_some_cycles(st_clk, 1); + END LOOP; + proc_common_wait_some_cycles(st_clk, c_bg_sync_period_max); stimuli_end <= '1'; - -- Dealy logging between different tb instances + -- Delay logging between different tb instances proc_common_wait_some_cycles(st_clk, g_tb_index * 100); + + -- Print logging print_str(""); -- log empty line between tb results + FOR I IN g_nof_streams-1 DOWNTO 0 LOOP + IF I = 0 THEN + print_str(c_tb_str & + "ETH bit rate (" & NATURAL'IMAGE(I) & ") :" & + " c_eth_nof_bps_first = " & REAL'IMAGE(c_eth_nof_bps_first) & " bps"); + ELSE + print_str(c_tb_str & + "ETH bit rate (" & NATURAL'IMAGE(I) & ") :" & + " c_eth_nof_bps_others = " & REAL'IMAGE(c_eth_nof_bps_others) & " bps"); + END IF; + END LOOP; + IF g_nof_streams > 1 THEN + print_str(c_tb_str & + "ETH bit rate total :" & + " c_eth_nof_bps_total = " & REAL'IMAGE(c_eth_nof_bps_total) & " bps"); + END IF; + ASSERT c_eth_nof_bps_total < 10.0**9 REPORT "Total ETH bitrate must be < 1Gbps." SEVERITY WARNING; ------------------------------------------------------------------------- -- Verification: Total counts @@ -306,40 +372,51 @@ BEGIN proc_common_wait_some_cycles(mm_clk, 1); -- Print logging - print_str(g_tb_str & + print_str(c_tb_str & "Tx total counts monitor(" & NATURAL'IMAGE(I) & ") :" & " nof_packet = " & NATURAL'IMAGE(tx_total_count_nof_packet_arr(I))); - print_str(g_tb_str & + print_str(c_tb_str & "Rx total counts monitor(" & NATURAL'IMAGE(I) & ") :" & " nof_packet = " & NATURAL'IMAGE(rx_total_count_nof_packet_arr(I)) & ", nof_valid = " & NATURAL'IMAGE(rx_total_count_nof_valid_arr(I)) & ", nof_corrupted = " & NATURAL'IMAGE(rx_total_count_nof_corrupted_arr(I))); - -- Verify, only log when wrong - ASSERT tx_total_count_nof_packet_arr(I) = exp_total_count_nof_packet_arr(I) REPORT g_tb_str & - "Wrong Tx total nof packets count(" & NATURAL'IMAGE(I) & - "), Tx count = " & NATURAL'IMAGE(tx_total_count_nof_packet_arr(I)) & - " /= " & NATURAL'IMAGE(exp_total_count_nof_packet_arr(I)) & - " = Expected count" SEVERITY ERROR; - - ASSERT rx_total_count_nof_packet_arr(I) = exp_total_count_nof_packet_arr(I) REPORT g_tb_str & - "Wrong Rx total nof packets count(" & NATURAL'IMAGE(I) & - "), Rx count = " & NATURAL'IMAGE(rx_total_count_nof_packet_arr(I)) & - " /= " & NATURAL'IMAGE(exp_total_count_nof_packet_arr(I)) & - " = Expected count" SEVERITY ERROR; - - ASSERT rx_total_count_nof_valid_arr(I) = rx_exp_total_count_nof_valid_arr(I) REPORT g_tb_str & - "Wrong Rx total nof valids count(" & NATURAL'IMAGE(I) & - "), Rx count = " & NATURAL'IMAGE(rx_total_count_nof_valid_arr(I)) & - " /= " & NATURAL'IMAGE(rx_exp_total_count_nof_valid_arr(I)) & - " = Expected count" SEVERITY ERROR; - - ASSERT rx_total_count_nof_corrupted_arr(I) = rx_exp_total_count_nof_corrupted_arr(I) REPORT g_tb_str & - "Wrong Rx total nof corrupted count(" & NATURAL'IMAGE(I) & - "), Rx count = " & NATURAL'IMAGE(rx_total_count_nof_corrupted_arr(I)) & - " /= " & NATURAL'IMAGE(rx_exp_total_count_nof_corrupted_arr(I)) & - " = Expected count" SEVERITY ERROR; + IF c_eth_nof_bps_total < 10.0**9 THEN + -- Verify, only log when wrong + ASSERT tx_total_count_nof_packet_arr(I) = exp_total_count_nof_packet_arr(I) REPORT c_tb_str & + "Wrong Tx total nof packets count(" & NATURAL'IMAGE(I) & + "), Tx count = " & NATURAL'IMAGE(tx_total_count_nof_packet_arr(I)) & + " /= " & NATURAL'IMAGE(exp_total_count_nof_packet_arr(I)) & + " = Expected count" SEVERITY ERROR; + + ASSERT rx_total_count_nof_packet_arr(I) = exp_total_count_nof_packet_arr(I) REPORT c_tb_str & + "Wrong Rx total nof packets count(" & NATURAL'IMAGE(I) & + "), Rx count = " & NATURAL'IMAGE(rx_total_count_nof_packet_arr(I)) & + " /= " & NATURAL'IMAGE(exp_total_count_nof_packet_arr(I)) & + " = Expected count" SEVERITY ERROR; + + ASSERT rx_total_count_nof_valid_arr(I) = rx_exp_total_count_nof_valid_arr(I) REPORT c_tb_str & + "Wrong Rx total nof valids count(" & NATURAL'IMAGE(I) & + "), Rx count = " & NATURAL'IMAGE(rx_total_count_nof_valid_arr(I)) & + " /= " & NATURAL'IMAGE(rx_exp_total_count_nof_valid_arr(I)) & + " = Expected count" SEVERITY ERROR; + + ASSERT rx_total_count_nof_corrupted_arr(I) = rx_exp_total_count_nof_corrupted_arr(I) REPORT c_tb_str & + "Wrong Rx total nof corrupted count(" & NATURAL'IMAGE(I) & + "), Rx count = " & NATURAL'IMAGE(rx_total_count_nof_corrupted_arr(I)) & + " /= " & NATURAL'IMAGE(rx_exp_total_count_nof_corrupted_arr(I)) & + " = Expected count" SEVERITY ERROR; + ELSE + -- Verify that Tx total nof packets = Rx total nof packets, also when + -- BG experiences siso.xon block level flow control, to stay below + -- 1 Gbps of the 1GbE link rate. + ASSERT tx_total_count_nof_packet_arr(I) = rx_total_count_nof_packet_arr(I) REPORT c_tb_str & + "Wrong Tx total nof packets count(" & NATURAL'IMAGE(I) & + "), Tx count = " & NATURAL'IMAGE(tx_total_count_nof_packet_arr(I)) & + " /= " & NATURAL'IMAGE(tx_total_count_nof_packet_arr(I)) & + " = Rx count" SEVERITY ERROR; + END IF; END LOOP; ------------------------------------------------------------------------- @@ -373,39 +450,61 @@ BEGIN proc_common_wait_some_cycles(mm_clk, 1); -- Print logging - print_str(g_tb_str & + print_str(c_tb_str & "Tx BSN monitor(" & NATURAL'IMAGE(I) & ") :" & " nof_sop = " & NATURAL'IMAGE(tx_mon_nof_sop_arr(I)) & ", nof_valid = " & NATURAL'IMAGE(tx_mon_nof_valid_arr(I)) & ", latency = " & NATURAL'IMAGE(tx_mon_latency_arr(I))); - print_str(g_tb_str & + print_str(c_tb_str & "Rx BSN monitor(" & NATURAL'IMAGE(I) & ") :" & " nof_sop = " & NATURAL'IMAGE(rx_mon_nof_sop_arr(I)) & ", nof_valid = " & NATURAL'IMAGE(rx_mon_nof_valid_arr(I)) & ", latency = " & NATURAL'IMAGE(rx_mon_latency_arr(I))); - -- Verify, only log when wrong - IF I = 0 THEN - ASSERT tx_mon_nof_sop_arr(I) = c_mon_nof_sop_first REPORT g_tb_str & "Wrong tx nof_sop for stream (" & NATURAL'IMAGE(I) & ")" SEVERITY ERROR; - ASSERT rx_mon_nof_sop_arr(I) = c_mon_nof_sop_first REPORT g_tb_str & "Wrong rx nof_sop for stream (" & NATURAL'IMAGE(I) & ")" SEVERITY ERROR; - ASSERT tx_mon_nof_valid_arr(I) = c_mon_nof_valid_first_tx REPORT g_tb_str & "Wrong tx nof_valid for stream (" & NATURAL'IMAGE(I) & ")" SEVERITY ERROR; - ASSERT rx_mon_nof_valid_arr(I) = c_mon_nof_valid_first_rx REPORT g_tb_str & "Wrong rx nof_valid for stream (" & NATURAL'IMAGE(I) & ")" SEVERITY ERROR; - ELSE - ASSERT tx_mon_nof_sop_arr(I) = c_mon_nof_sop_others REPORT g_tb_str & "Wrong tx nof_sop for stream (" & NATURAL'IMAGE(I) & ")" SEVERITY ERROR; - ASSERT rx_mon_nof_sop_arr(I) = c_mon_nof_sop_others REPORT g_tb_str & "Wrong rx nof_sop for stream (" & NATURAL'IMAGE(I) & ")" SEVERITY ERROR; - ASSERT tx_mon_nof_valid_arr(I) = c_mon_nof_valid_others_tx REPORT g_tb_str & "Wrong tx nof_valid for stream (" & NATURAL'IMAGE(I) & ")" SEVERITY ERROR; - ASSERT rx_mon_nof_valid_arr(I) = c_mon_nof_valid_others_rx REPORT g_tb_str & "Wrong rx nof_valid for stream (" & NATURAL'IMAGE(I) & ")" SEVERITY ERROR; + IF c_eth_nof_bps_total < 10.0**9 THEN + -- Verify BSN monitors only when the BG sync interval is stable, so + -- the ETH data rate < 1 Gbps and no BG block flow control. + -- Verify, only log when wrong + IF I = 0 THEN + ASSERT tx_mon_nof_sop_arr(I) = c_mon_nof_sop_first REPORT c_tb_str & "Wrong tx nof_sop for stream (" & NATURAL'IMAGE(I) & ")" SEVERITY ERROR; + ASSERT rx_mon_nof_sop_arr(I) = c_mon_nof_sop_first REPORT c_tb_str & "Wrong rx nof_sop for stream (" & NATURAL'IMAGE(I) & ")" SEVERITY ERROR; + ASSERT tx_mon_nof_valid_arr(I) = c_mon_nof_valid_first_tx REPORT c_tb_str & "Wrong tx nof_valid for stream (" & NATURAL'IMAGE(I) & ")" SEVERITY ERROR; + ASSERT rx_mon_nof_valid_arr(I) = c_mon_nof_valid_first_rx REPORT c_tb_str & "Wrong rx nof_valid for stream (" & NATURAL'IMAGE(I) & ")" SEVERITY ERROR; + ELSE + ASSERT tx_mon_nof_sop_arr(I) = c_mon_nof_sop_others REPORT c_tb_str & "Wrong tx nof_sop for stream (" & NATURAL'IMAGE(I) & ")" SEVERITY ERROR; + ASSERT rx_mon_nof_sop_arr(I) = c_mon_nof_sop_others REPORT c_tb_str & "Wrong rx nof_sop for stream (" & NATURAL'IMAGE(I) & ")" SEVERITY ERROR; + ASSERT tx_mon_nof_valid_arr(I) = c_mon_nof_valid_others_tx REPORT c_tb_str & "Wrong tx nof_valid for stream (" & NATURAL'IMAGE(I) & ")" SEVERITY ERROR; + ASSERT rx_mon_nof_valid_arr(I) = c_mon_nof_valid_others_rx REPORT c_tb_str & "Wrong rx nof_valid for stream (" & NATURAL'IMAGE(I) & ")" SEVERITY ERROR; + END IF; + ASSERT tx_mon_latency_arr(I) = c_tx_exp_latency REPORT c_tb_str & "Wrong tx latency for stream (" & NATURAL'IMAGE(I) & ")" SEVERITY ERROR; + -- The rx_exp_latency is fixed when: + -- . g_loopback_eth = FALSE: the streams operate in parallel. + -- . g_loopback_eth = TRUE and g_nof_streams = 1, because for + -- g_nof_streams > 1 the streams are mulitplexed, so then the Rx + -- latency will vary. + IF g_loopback_eth = TRUE THEN + IF g_nof_streams = 1 THEN + IF g_eth_sim_level = 0 THEN + ASSERT almost_equal(rx_mon_latency_arr(I), c_rx_exp_latency_tech_tse, 1) REPORT + c_tb_str & "Wrong rx latency using tech_tse interface" SEVERITY ERROR; + ELSIF g_eth_sim_level = 1 THEN + ASSERT almost_equal(rx_mon_latency_arr(I), c_rx_exp_latency_sim_tse, 1) REPORT + c_tb_str & "Wrong rx latency using sim_tse interface" SEVERITY ERROR; + END IF; + END IF; + ELSE + ASSERT rx_mon_latency_arr(I) = c_rx_exp_latency_st REPORT + c_tb_str & "Wrong rx latency using st interface (" & NATURAL'IMAGE(I) & ")" SEVERITY ERROR; + END IF; END IF; - ASSERT tx_mon_latency_arr(I) = c_tx_exp_latency REPORT g_tb_str & "Wrong tx latency for stream (" & NATURAL'IMAGE(I) & ")" SEVERITY ERROR; - ASSERT rx_mon_latency_arr(I) = c_rx_exp_latency REPORT g_tb_str & "Wrong rx latency for stream (" & NATURAL'IMAGE(I) & ")" SEVERITY ERROR; END LOOP; ------------------------------------------------------------------------- -- End of test ------------------------------------------------------------------------- proc_common_wait_some_cycles(mm_clk, 100); - tb_end <= '1'; + i_tb_end <= '1'; WAIT; END PROCESS; @@ -426,6 +525,8 @@ BEGIN ip_src_addr => c_gn_ip_src_addr, udp_src_port => c_gn_udp_src_port, + tx_fifo_rd_emp_arr => tx_fifo_rd_emp_arr, + tx_udp_sosi_arr => tx_udp_sosi_arr, tx_udp_siso_arr => tx_udp_siso_arr, @@ -450,12 +551,15 @@ BEGIN ); -- Wire Tx to Rx - gen_loopback_sosi : IF g_loopback_eth = FALSE GENERATE + gen_loopback_st : IF g_loopback_eth = FALSE GENERATE + -- Loop back at streaming sosi level + rx_udp_sosi_arr <= tx_udp_sosi_arr; + tse_init <= '0'; END GENERATE; gen_loopback_eth : IF g_loopback_eth = TRUE GENERATE - eth_rxp <= eth_txp; + -- Loop back at ethernet 1Gbps line level eth_tx_udp_sosi_arr(g_nof_streams-1 DOWNTO 0) <= tx_udp_sosi_arr; tx_udp_siso_arr <= eth_tx_udp_siso_arr(g_nof_streams-1 DOWNTO 0); @@ -463,12 +567,46 @@ BEGIN rx_udp_sosi_arr <= eth_rx_udp_sosi_arr(g_nof_streams-1 DOWNTO 0); eth_rx_udp_siso_arr(g_nof_streams-1 DOWNTO 0) <= (OTHERS => c_dp_siso_rdy); + -- Copied from tb_tech_tse.vhd + use_sim_tse : IF g_eth_sim_level > 0 GENERATE + eth_rxp <= eth_txp; + tse_init <= '0'; + END GENERATE; + use_tech_tse : IF g_eth_sim_level = 0 GENERATE + eth_rxp <= TRANSPORT eth_txp AFTER 12 ns; -- apply cable delay + + p_tech_tse_setup : PROCESS + -- When c_promis_en = FALSE then only accept broadcast and packets with + -- dst_mac for this src_mac, else accept packets for any dst MAC + -- Therefore when c_promis_en = FALSE the TSE c_src_mac must be equal + -- to the Tx packet dst_mac to be able to receive the Tx packets via + -- the tx-rx loopback. + CONSTANT c_promis_en : BOOLEAN := FALSE; + CONSTANT c_src_mac : STD_LOGIC_VECTOR(47 DOWNTO 0) := sel_a_b(c_promis_en, c_gn_eth_src_mac, c_eth_tester_eth_dst_mac); + BEGIN + tse_init <= '1'; + tse_copi.wr <= '0'; + tse_copi.rd <= '0'; + + proc_common_wait_until_low(mm_clk, mm_rst); + proc_common_wait_some_cycles(mm_clk, 10); + + proc_tech_tse_setup(c_tech_select_default, + c_promis_en, c_tech_tse_tx_fifo_depth, c_tech_tse_rx_fifo_depth, c_tech_tse_tx_ready_latency, + c_src_mac, tse_psc_access, + mm_clk, tse_cipo, tse_copi); + tse_init <= '0'; + WAIT; + END PROCESS; + END GENERATE; + + -- ETH module, see [1] u_eth : ENTITY work.eth GENERIC MAP ( g_init_ip_address => X"0A630000", g_cross_clock_domain => TRUE, g_sim => TRUE, - g_sim_level => 1 -- when g_sim = TRUE, then 0 = use IP; 1 = use fast serdes model + g_sim_level => g_eth_sim_level ) PORT MAP ( -- Clocks and reset @@ -486,8 +624,8 @@ BEGIN udp_rx_src_out_arr => eth_rx_udp_sosi_arr, -- Memory Mapped Slaves - tse_sla_in => c_mem_copi_rst, -- ETH TSE MAC registers - tse_sla_out => OPEN, + tse_sla_in => tse_copi, -- ETH TSE MAC registers + tse_sla_out => tse_cipo, reg_sla_in => reg_eth_copi, -- ETH control and status registers reg_sla_out => reg_eth_cipo, reg_sla_interrupt => OPEN, -- Interrupt