diff --git a/libraries/base/dp/tb/vhdl/tb_dp_bsn_align_v2.vhd b/libraries/base/dp/tb/vhdl/tb_dp_bsn_align_v2.vhd index e3ea3b5d0d7f0858958c8c6d5044ec608c6d406f..ef8cea35ca444bf8f59e2314019a99e1d44eeeab 100644 --- a/libraries/base/dp/tb/vhdl/tb_dp_bsn_align_v2.vhd +++ b/libraries/base/dp/tb/vhdl/tb_dp_bsn_align_v2.vhd @@ -37,20 +37,20 @@ USE dp_lib.tb_dp_pkg.ALL; ENTITY tb_dp_bsn_align_v2 IS GENERIC ( -- DUT - g_nof_streams : NATURAL := 2; -- number of input and output streams - g_bsn_latency_max : NATURAL := 2; -- Maximum travel latency of a remote block in number of block periods T_blk - g_nof_aligners_max : POSITIVE := 1; -- 1 when only align at last node, > 1 when align at every intermediate node - g_block_size : NATURAL := 11; -- > 1, g_block_size=1 is not supported - g_bsn_w : NATURAL := c_dp_stream_bsn_w; -- number of bits in sosi BSN - g_data_w : NATURAL := 16; -- number of bits in sosi data - g_replacement_value : INTEGER := 17; -- output sosi data replacement value for missing input blocks - g_use_mm_output : BOOLEAN := FALSE; -- output via MM or via streaming DP - g_pipeline_input : NATURAL := 1; -- >= 0, choose 0 for wires, choose 1 to ease timing closure - g_rd_latency : NATURAL := 2; -- 1 or 2, choose 2 to ease timing closure + g_nof_streams : NATURAL := 5; -- number of input and output streams + g_bsn_latency_max : NATURAL := 2; -- Maximum travel latency of a remote block in number of block periods T_blk + g_nof_aligners_max : POSITIVE := 1; -- 1 when only align at last node, > 1 when align at every intermediate node + g_block_size : NATURAL := 11; -- > 1, g_block_size=1 is not supported + g_gap_size : NATURAL := 9; -- block period = g_block_size + g_gap_size + g_bsn_w : NATURAL := c_dp_stream_bsn_w; -- number of bits in sosi BSN + g_data_w : NATURAL := 16; -- number of bits in sosi data + g_replacement_value : INTEGER := 17; -- output sosi data replacement value for missing input blocks + g_use_mm_output : BOOLEAN := FALSE; -- output via MM or via streaming DP + g_pipeline_input : NATURAL := 1; -- >= 0, choose 0 for wires, choose 1 to ease timing closure + g_rd_latency : NATURAL := 2; -- 1 or 2, choose 2 to ease timing closure -- TB - g_diff_delay : NATURAL := 0; -- nof clk delay between inputs - g_diff_bsn : NATURAL := 0; -- g_diff_bsn = g_bsn_latency_max can just be aligned + g_diff_delay_max : NATURAL := 45; -- maximum nof clk delay between any inputs, <= c_align_latency g_nof_repeat : NATURAL := 8 ); END tb_dp_bsn_align_v2; @@ -69,9 +69,11 @@ ARCHITECTURE tb OF tb_dp_bsn_align_v2 IS CONSTANT c_sync_period : NATURAL := 7; CONSTANT c_sync_offset : NATURAL := 2; - CONSTANT c_gap_size : NATURAL := 10; - CONSTANT c_block_period : NATURAL := g_block_size + c_gap_size; - + CONSTANT c_block_period : NATURAL := g_block_size + g_gap_size; + CONSTANT c_dut_latency : NATURAL := g_pipeline_input + g_rd_latency + 2; + CONSTANT c_align_latency : NATURAL := g_bsn_latency_max * c_block_period; + CONSTANT c_total_latency : NATURAL := c_dut_latency + c_align_latency; + TYPE t_data_arr IS ARRAY (g_nof_streams-1 DOWNTO 0) OF STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0); TYPE t_bsn_arr IS ARRAY (g_nof_streams-1 DOWNTO 0) OF STD_LOGIC_VECTOR(c_bsn_w-1 DOWNTO 0); TYPE t_err_arr IS ARRAY (g_nof_streams-1 DOWNTO 0) OF STD_LOGIC_VECTOR(c_dp_stream_error_w-1 DOWNTO 0); @@ -84,62 +86,73 @@ ARCHITECTURE tb OF tb_dp_bsn_align_v2 IS out_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); END RECORD; - SIGNAL tb_end_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS=>'0'); - SIGNAL tb_end : STD_LOGIC; - SIGNAL clk : STD_LOGIC := '1'; - SIGNAL rst : STD_LOGIC := '1'; - SIGNAL sl1 : STD_LOGIC := '1'; - - SIGNAL node_index : NATURAL := 0; - - SIGNAL in_siso_arr : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy); - SIGNAL in_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); - SIGNAL in_bsn : t_bsn_arr; - SIGNAL in_data : t_data_arr; - SIGNAL in_val : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - SIGNAL in_sync : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - SIGNAL in_sop : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - SIGNAL in_eop : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - SIGNAL in_err : t_err_arr; - SIGNAL in_channel : t_channel_arr; - - SIGNAL mm_copi_arr : t_mem_copi_arr(g_nof_streams-1 DOWNTO 0); - SIGNAL mm_copi : t_mem_copi; -- read access to output block, all output streams share same mm_copi - SIGNAL mm_cipo_arr : t_mem_cipo_arr(g_nof_streams-1 DOWNTO 0); - SIGNAL mm_sosi : t_dp_sosi; -- streaming information that signals that an output block can be read - SIGNAL mm_done_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - SIGNAL mm_done : STD_LOGIC; - SIGNAL dut_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); - SIGNAL tb_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); - SIGNAL r : t_reg; - SIGNAL nxt_r : t_reg; - - SIGNAL out_siso_arr : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy); - SIGNAL out_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); - SIGNAL out_bsn : t_bsn_arr; - SIGNAL out_data : t_data_arr; - SIGNAL out_val : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - SIGNAL out_sync : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - SIGNAL out_sop : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - SIGNAL out_eop : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - SIGNAL out_gap : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS=>'1'); - SIGNAL out_err : t_err_arr; - SIGNAL out_channel : t_channel_arr; - - SIGNAL in_sosi_arr_dly : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); - SIGNAL out_sosi_arr_exp : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); - SIGNAL tb_bsn : INTEGER; - SIGNAL verify_done_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS=>'0'); - SIGNAL verify_en_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS=>'0'); - - SIGNAL hold_out_sop : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - SIGNAL prev_out_bsn : t_bsn_arr; - SIGNAL expected_out_bsn : t_bsn_arr; - SIGNAL prev_out_data : t_data_arr; - SIGNAL expected_out_data : t_data_arr; - - SIGNAL stream_en_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS=>'1'); -- default all streams are enabled - + SIGNAL tb_end_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS=>'0'); + SIGNAL tb_end : STD_LOGIC; + SIGNAL clk : STD_LOGIC := '1'; + SIGNAL rst : STD_LOGIC := '1'; + + SIGNAL node_index : NATURAL := 0; + + SIGNAL stream_en_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS=>'1'); -- default all streams are enabled + + SIGNAL ref_siso_arr : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy); + SIGNAL ref_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); + SIGNAL in_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>c_dp_sosi_rst); + + SIGNAL in_sync_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); + SIGNAL in_sop_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); + SIGNAL in_eop_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); + SIGNAL in_val_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); + SIGNAL in_data_arr : t_data_arr; + SIGNAL in_bsn_arr : t_bsn_arr; + SIGNAL in_channel_arr : t_channel_arr; + SIGNAL in_err_arr : t_err_arr; + + SIGNAL mm_copi_arr : t_mem_copi_arr(g_nof_streams-1 DOWNTO 0); + SIGNAL mm_copi : t_mem_copi; -- read access to output block, all output streams share same mm_copi + SIGNAL mm_cipo_arr : t_mem_cipo_arr(g_nof_streams-1 DOWNTO 0); + SIGNAL mm_sosi : t_dp_sosi; -- streaming information that signals that an output block can be read + SIGNAL mm_done_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); + SIGNAL mm_done : STD_LOGIC; + SIGNAL dut_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); + SIGNAL tb_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); + SIGNAL r : t_reg; + SIGNAL nxt_r : t_reg; + + SIGNAL out_siso_arr : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy); + SIGNAL out_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); + + SIGNAL out_sync_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); + SIGNAL out_sop_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); + SIGNAL out_eop_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); + SIGNAL out_val_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); + SIGNAL out_data_arr : t_data_arr; + SIGNAL out_bsn_arr : t_bsn_arr; + SIGNAL out_channel_arr : t_channel_arr; + SIGNAL out_err_arr : t_err_arr; + + SIGNAL tb_bsn : INTEGER; + SIGNAL ref_sosi_arr_dly : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); + SIGNAL out_sosi_arr_exp : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); + SIGNAL verify_done_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS=>'0'); + SIGNAL verify_en_prev_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); + SIGNAL verify_en_delayed_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); + + SIGNAL hold_out_sop_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); + SIGNAL prev_out_bsn_arr : t_bsn_arr; + SIGNAL expected_out_bsn_arr : t_bsn_arr; + SIGNAL prev_out_data_arr : t_data_arr; + SIGNAL expected_out_data_arr : t_data_arr; + + -- Return input delay as function of inputs stream index I + FUNCTION func_input_delay(I : NATURAL) RETURN NATURAL IS + BEGIN + RETURN g_diff_delay_max * I / (g_nof_streams - 1); + END; + + SIGNAL dbg_diff_delay_max : NATURAL := g_diff_delay_max; + SIGNAL dbg_func_delay_max : NATURAL := func_input_delay(g_nof_streams - 1); + BEGIN clk <= (NOT clk) OR tb_end AFTER clk_period/2; @@ -159,30 +172,29 @@ BEGIN VARIABLE v_err : NATURAL := c_err_init; VARIABLE v_diff_bsn : NATURAL := 0; BEGIN - -- Create BSN misalignment between the input streams - v_diff_bsn := I MOD (g_diff_bsn+1); - v_data := v_data + I; - v_bsn := INCR_UVEC(v_bsn, v_diff_bsn); - in_sosi_arr(I) <= c_dp_sosi_rst; + ref_sosi_arr(I) <= c_dp_sosi_rst; proc_common_wait_until_low(clk, rst); proc_common_wait_some_cycles(clk, 10); - -- Create latency misalignment between the input streams - proc_common_wait_some_cycles(clk, I*g_diff_delay); - -- Begin of stimuli FOR R IN 0 TO g_nof_repeat-v_diff_bsn-1 LOOP v_sync := sel_a_b(TO_UINT(v_bsn) MOD c_sync_period = c_sync_offset, '1', '0'); - proc_dp_gen_block_data(c_rl, TRUE, c_data_w, c_data_w, v_data, 0, 0, g_block_size, v_channel, v_err, v_sync, v_bsn, clk, stream_en_arr(I), in_siso_arr(I), in_sosi_arr(I)); + proc_dp_gen_block_data(c_rl, TRUE, c_data_w, c_data_w, v_data, 0, 0, g_block_size, v_channel, v_err, v_sync, v_bsn, clk, stream_en_arr(I), ref_siso_arr(I), ref_sosi_arr(I)); v_bsn := INCR_UVEC(v_bsn, 1); v_data := v_data + g_block_size; - proc_common_wait_some_cycles(clk, c_gap_size); -- create gap between frames + proc_common_wait_some_cycles(clk, g_gap_size); -- create gap between frames END LOOP; - -- End of stimuli, g_bsn_latency_max blocks remain in buffer - expected_out_bsn(I) <= INCR_UVEC(v_bsn, -1 -g_bsn_latency_max); - expected_out_data(I) <= TO_UVEC(v_data-1 -g_bsn_latency_max*g_block_size, c_data_w); + -- End of stimuli, g_bsn_latency_max blocks remain in DUT buffer + expected_out_bsn_arr(I) <= INCR_UVEC(v_bsn, -1 - g_bsn_latency_max); + IF func_input_delay(I) <= c_align_latency THEN + -- Verify expected input data + expected_out_data_arr(I) <= TO_UVEC(v_data-1 -g_bsn_latency_max*g_block_size, c_data_w); + ELSE + -- Verify expected replacement data for lost input block + expected_out_data_arr(I) <= TO_UVEC(g_replacement_value, c_data_w); + END IF; proc_common_wait_some_cycles(clk, 100); verify_done_arr(I) <= '1'; @@ -193,71 +205,110 @@ BEGIN WAIT; END PROCESS; END GENERATE; - + + -- Create latency misalignment between the input streams + gen_in_sosi_arr : FOR I IN g_nof_streams-1 DOWNTO 0 GENERATE + in_sosi_arr(I) <= TRANSPORT ref_sosi_arr(I) AFTER func_input_delay(I) * clk_period; + END GENERATE; + + tb_end <= vector_and(tb_end_arr); + mon_sosi : FOR I IN g_nof_streams-1 DOWNTO 0 GENERATE + -- Ease in_sosi_arr monitoring + in_sync_arr(I) <= in_sosi_arr(I).sync; + in_sop_arr(I) <= in_sosi_arr(I).sop; + in_eop_arr(I) <= in_sosi_arr(I).eop; + in_val_arr(I) <= in_sosi_arr(I).valid; + in_data_arr(I) <= in_sosi_arr(I).data(c_data_w-1 DOWNTO 0); + in_bsn_arr(I) <= in_sosi_arr(I).bsn(c_bsn_w-1 DOWNTO 0); + in_channel_arr(I) <= in_sosi_arr(I).channel; + in_err_arr(I) <= in_sosi_arr(I).err; + + -- Ease out_sosi_arr monitoring and verification + out_sync_arr(I) <= out_sosi_arr(I).sync; + out_sop_arr(I) <= out_sosi_arr(I).sop; + out_eop_arr(I) <= out_sosi_arr(I).eop; + out_val_arr(I) <= out_sosi_arr(I).valid; + out_data_arr(I) <= out_sosi_arr(I).data(c_data_w-1 DOWNTO 0); + out_bsn_arr(I) <= out_sosi_arr(I).bsn(c_bsn_w-1 DOWNTO 0); + out_channel_arr(I) <= out_sosi_arr(I).channel; + out_err_arr(I) <= out_sosi_arr(I).err; + END GENERATE; + ------------------------------------------------------------------------------ - -- DATA VERIFICATION + -- DATA VERIFICATION, use multiple ways to increase coverage + -- a) Use proc_dp_verify_*() to verify output compared to prev output + -- b) Use delayed in_sosi_arr as expected out_sosi_arr ------------------------------------------------------------------------------ - tb_bsn <= TO_UINT(out_sosi_arr(0).bsn); - - p_verify_en_arr : PROCESS + ------------------------------------------------------------------------------ + -- a) Use proc_dp_verify_() + ------------------------------------------------------------------------------ + p_verify_en_prev_arr : PROCESS BEGIN - -- Skip initial blocks from verification - proc_common_wait_until_value(TO_UINT(c_bsn_init) + g_bsn_latency_max, clk, tb_bsn); - verify_en_arr <= (OTHERS => '1'); - proc_common_wait_until_value(TO_UINT(c_bsn_init) + g_nof_repeat - g_bsn_latency_max - 1, clk, tb_bsn); - verify_en_arr <= (OTHERS => '0'); + verify_en_prev_arr <= (OTHERS => '0'); + IF g_diff_delay_max <= c_align_latency THEN + -- Can only verify incrementing sosi data when no blocks get lost + -- Skip sample of first block from verification, because then there is no prev_out_bsn_arr, prev_out_data_arr yet + proc_common_wait_until_high(clk, out_sosi_arr(0).sop); + verify_en_prev_arr <= (OTHERS => '1'); + END IF; WAIT; END PROCESS; - gen_verify_sosi : FOR I IN g_nof_streams-1 DOWNTO 0 GENERATE - -- Ease in_sosi_arr monitoring - in_data(I) <= in_sosi_arr(I).data(c_data_w-1 DOWNTO 0); - in_val(I) <= in_sosi_arr(I).valid; - in_sop(I) <= in_sosi_arr(I).sop; - in_eop(I) <= in_sosi_arr(I).eop; - in_err(I) <= in_sosi_arr(I).err; - in_channel(I) <= in_sosi_arr(I).channel; - in_sync(I) <= in_sosi_arr(I).sync; - in_bsn(I) <= in_sosi_arr(I).bsn(c_bsn_w-1 DOWNTO 0); - - -- Ease out_sosi_arr monitoring and verification - out_data(I) <= out_sosi_arr(I).data(c_data_w-1 DOWNTO 0); - out_val(I) <= out_sosi_arr(I).valid; - out_sop(I) <= out_sosi_arr(I).sop; - out_eop(I) <= out_sosi_arr(I).eop; - out_err(I) <= out_sosi_arr(I).err; - out_channel(I) <= out_sosi_arr(I).channel; - out_sync(I) <= out_sosi_arr(I).sync; - out_bsn(I) <= out_sosi_arr(I).bsn(c_bsn_w-1 DOWNTO 0); - + gen_verify_prev_sosi : FOR I IN g_nof_streams-1 DOWNTO 0 GENERATE -- Actual verification of the output streams -- . Verify that sop and eop come in pairs - proc_dp_verify_sop_and_eop(clk, out_val(I), out_sop(I), out_eop(I), hold_out_sop(I)); + proc_dp_verify_sop_and_eop(clk, out_val_arr(I), out_sop_arr(I), out_eop_arr(I), hold_out_sop_arr(I)); -- . Verify that the output is incrementing, like the input stimuli - proc_dp_verify_data("out_sosi.data", c_rl, clk, verify_en_arr(I), out_siso_arr(I).ready, out_val(I), out_data(I), prev_out_data(I)); - proc_dp_verify_data("out_sosi.bsn", c_rl, clk, verify_en_arr(I), out_siso_arr(I).ready, out_sop(I), out_bsn(I), prev_out_bsn(I)); + proc_dp_verify_data("out_sosi.data", c_rl, clk, verify_en_prev_arr(I), out_siso_arr(I).ready, out_val_arr(I), out_data_arr(I), prev_out_data_arr(I)); + proc_dp_verify_data("out_sosi.bsn", c_rl, clk, verify_en_prev_arr(I), out_siso_arr(I).ready, out_sop_arr(I), out_bsn_arr(I), prev_out_bsn_arr(I)); -- . Verify that the stimuli have been applied at all - proc_dp_verify_value("out_data", e_equal, clk, verify_done_arr(I), expected_out_data(I), prev_out_data(I)); - proc_dp_verify_value("out_bsn", e_equal, clk, verify_done_arr(I), expected_out_bsn(I), prev_out_bsn(I)); + proc_dp_verify_value("out_data_arr", e_equal, clk, verify_done_arr(I), expected_out_data_arr(I), prev_out_data_arr(I)); + proc_dp_verify_value("out_bsn_arr", e_equal, clk, verify_done_arr(I), expected_out_bsn_arr(I), prev_out_bsn_arr(I)); END GENERATE; - in_sosi_arr_dly <= TRANSPORT in_sosi_arr AFTER (g_bsn_latency_max * (g_block_size + c_gap_size) + 5) * clk_period; - out_sosi_arr_exp <= in_sosi_arr_dly WHEN rising_edge(clk); + ------------------------------------------------------------------------------ + -- b) Use delayed in_sosi_arr as expected out_sosi_arr + ------------------------------------------------------------------------------ + tb_bsn <= TO_UINT(out_sosi_arr(0).bsn); + + ref_sosi_arr_dly <= TRANSPORT ref_sosi_arr AFTER c_total_latency * clk_period; + out_sosi_arr_exp <= ref_sosi_arr_dly WHEN rising_edge(clk); + + p_verify_en_delayed_arr : PROCESS + BEGIN + verify_en_delayed_arr <= (OTHERS => '1'); + -- Skip last blocks that are still in DUT buffer + proc_common_wait_until_value(TO_UINT(c_bsn_init) + g_nof_repeat - g_bsn_latency_max - 1, clk, tb_bsn); + proc_common_wait_until_high(clk, out_sosi_arr(0).eop); + verify_en_delayed_arr <= (OTHERS => '0'); + WAIT; + END PROCESS; - gen_verify_data : FOR I IN g_nof_streams-1 DOWNTO 0 GENERATE + gen_verify_delayed_sosi : FOR I IN g_nof_streams-1 DOWNTO 0 GENERATE p_verify_data : PROCESS(clk) BEGIN IF rising_edge(clk) THEN - IF verify_en_arr(I) = '1' AND out_sosi_arr_exp(I).valid = '1' THEN + IF verify_en_delayed_arr(I) = '1' AND out_sosi_arr_exp(I).valid = '1' THEN + ASSERT out_sosi_arr(I).sync = out_sosi_arr_exp(I).sync REPORT "Wrong sync for output " & int_to_str(I) SEVERITY ERROR; + ASSERT out_sosi_arr(I).sop = out_sosi_arr_exp(I).sop REPORT "Wrong sop for output " & int_to_str(I) SEVERITY ERROR; + ASSERT out_sosi_arr(I).eop = out_sosi_arr_exp(I).eop REPORT "Wrong eop for output " & int_to_str(I) SEVERITY ERROR; ASSERT out_sosi_arr(I).valid = out_sosi_arr_exp(I).valid REPORT "Wrong valid for output " & int_to_str(I) SEVERITY ERROR; - ASSERT out_sosi_arr(I).data = out_sosi_arr_exp(I).data REPORT "Wrong data for output " & int_to_str(I) & " : " - & int_to_str(TO_UINT(out_sosi_arr(I).data)) - & " /= " & int_to_str(TO_UINT(out_sosi_arr_exp(I).data)) SEVERITY ERROR; + IF func_input_delay(I) <= c_align_latency THEN + -- Verify expected input data + ASSERT out_sosi_arr(I).data = out_sosi_arr_exp(I).data REPORT "Wrong data for output " & int_to_str(I) & " : " + & int_to_str(TO_UINT(out_sosi_arr(I).data)) & " /= " + & int_to_str(TO_UINT(out_sosi_arr_exp(I).data)) SEVERITY ERROR; + ELSE + -- Verify expected replacement data for lost input block + ASSERT TO_UINT(out_sosi_arr(I).data) = g_replacement_value REPORT "Wrong replacement data for output " & int_to_str(I) & " : " + & int_to_str(TO_UINT(out_sosi_arr(I).data)) & " /= " + & int_to_str(g_replacement_value) SEVERITY ERROR; + END IF; END IF; END IF; END PROCESS; diff --git a/libraries/base/dp/tb/vhdl/tb_tb_dp_bsn_align_v2.vhd b/libraries/base/dp/tb/vhdl/tb_tb_dp_bsn_align_v2.vhd index f1ec0cc403fe03e98ff0de9aed0f4eceae302121..01d32c556ca6007b2fa7cc56623161a7609388e7 100644 --- a/libraries/base/dp/tb/vhdl/tb_tb_dp_bsn_align_v2.vhd +++ b/libraries/base/dp/tb/vhdl/tb_tb_dp_bsn_align_v2.vhd @@ -34,13 +34,15 @@ END tb_tb_dp_bsn_align_v2; ARCHITECTURE tb OF tb_tb_dp_bsn_align_v2 IS - CONSTANT c_block_size : NATURAL := 11; - CONSTANT c_diff_delay : NATURAL := 20; - CONSTANT c_diff_bsn : NATURAL := 3; -- g_diff_bsn = g_bsn_latency can just be aligned CONSTANT c_bsn_latency_max : POSITIVE := 1; - CONSTANT c_nof_repeat : NATURAL := 100; -- for constant active stream control using 1 is sufficient, use > 1 to verify longer with random stimuli + CONSTANT c_block : NATURAL := 11; + CONSTANT c_gap : NATURAL := 9; + CONSTANT c_period : NATURAL := c_block + c_gap; + CONSTANT c_delay_max : NATURAL := c_bsn_latency_max * c_period; + CONSTANT c_nof_repeat : NATURAL := 50; SIGNAL tb_end : STD_LOGIC := '0'; -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end' + BEGIN -- -- DUT @@ -48,6 +50,7 @@ BEGIN -- g_bsn_latency_max : NATURAL := 1; -- Maximum travel latency of a remote block in number of block periods T_blk -- g_nof_aligners_max : NATURAL := 1; -- 1 when only align at last node, > 1 when align at every intermediate node -- g_block_size : NATURAL := 11; -- > 1, g_block_size=1 is not supported + -- g_gap_size : NATURAL := 9; -- block period = g_block_size + g_gap_size -- g_bsn_w : NATURAL := c_dp_stream_bsn_w; -- number of bits in sosi BSN -- g_data_w : NATURAL := 16; -- number of bits in sosi data -- c_replacement_value : INTEGER := 0; -- output sosi data replacement value for missing input blocks @@ -56,11 +59,13 @@ BEGIN -- g_rd_latency : NATURAL := 2; -- 1 or 2, choose 2 to ease timing closure -- -- -- TB - -- g_diff_delay : NATURAL := 0; - -- g_diff_bsn : NATURAL := 0; -- g_diff_bsn = g_bsn_latency_max can just be aligned + -- g_diff_delay_max : NATURAL := 0; -- maximum nof clk delay between any inputs -- g_nof_repeat : NATURAL := 100 -- for constant active stream control using 1 is sufficient, use > 1 to verify longer with random stimuli - u_mm_output : ENTITY work.tb_dp_bsn_align_v2 GENERIC MAP (2, c_bsn_latency_max, 1, 11, 32, 16, 0, TRUE, 0, 1, 0, 9, c_nof_repeat); - u_dp_output : ENTITY work.tb_dp_bsn_align_v2 GENERIC MAP (2, c_bsn_latency_max, 1, 11, 32, 16, 0, FALSE, 0, 1, 0, 9, c_nof_repeat); + u_mm_output : ENTITY work.tb_dp_bsn_align_v2 GENERIC MAP (2, c_bsn_latency_max, 1, c_block, c_gap, 32, 16, 17, TRUE, 0, 1, 0, c_nof_repeat); + u_dp_output : ENTITY work.tb_dp_bsn_align_v2 GENERIC MAP (2, c_bsn_latency_max, 1, c_block, c_gap, 32, 16, 17, FALSE, 0, 1, 0, c_nof_repeat); + + u_delay_no_loss : ENTITY work.tb_dp_bsn_align_v2 GENERIC MAP (2, c_bsn_latency_max, 1, c_block, c_gap, 32, 16, 17, FALSE, 0, 1, c_delay_max, c_nof_repeat); + --u_delay_replacement : ENTITY work.tb_dp_bsn_align_v2 GENERIC MAP (2, c_bsn_latency_max, 1, c_block, c_gap, 32, 16, 17, FALSE, 0, 1, 40 + c_delay_max, c_nof_repeat); END tb;