Skip to content
Snippets Groups Projects
Commit 85f9cea5 authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Improve verification of diff input delay.

parent 1ba47729
No related branches found
No related tags found
1 merge request!156Added first version of dp_bsn_align_v2.vhd with mmp and tb. This was...
...@@ -37,20 +37,20 @@ USE dp_lib.tb_dp_pkg.ALL; ...@@ -37,20 +37,20 @@ USE dp_lib.tb_dp_pkg.ALL;
ENTITY tb_dp_bsn_align_v2 IS ENTITY tb_dp_bsn_align_v2 IS
GENERIC ( GENERIC (
-- DUT -- DUT
g_nof_streams : NATURAL := 2; -- number of input and output streams 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_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_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_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_gap_size : NATURAL := 9; -- block period = g_block_size + g_gap_size
g_data_w : NATURAL := 16; -- number of bits in sosi data g_bsn_w : NATURAL := c_dp_stream_bsn_w; -- number of bits in sosi BSN
g_replacement_value : INTEGER := 17; -- output sosi data replacement value for missing input blocks g_data_w : NATURAL := 16; -- number of bits in sosi data
g_use_mm_output : BOOLEAN := FALSE; -- output via MM or via streaming DP g_replacement_value : INTEGER := 17; -- output sosi data replacement value for missing input blocks
g_pipeline_input : NATURAL := 1; -- >= 0, choose 0 for wires, choose 1 to ease timing closure g_use_mm_output : BOOLEAN := FALSE; -- output via MM or via streaming DP
g_rd_latency : NATURAL := 2; -- 1 or 2, choose 2 to ease timing closure 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 -- TB
g_diff_delay : NATURAL := 0; -- nof clk delay between inputs g_diff_delay_max : NATURAL := 45; -- maximum nof clk delay between any inputs, <= c_align_latency
g_diff_bsn : NATURAL := 0; -- g_diff_bsn = g_bsn_latency_max can just be aligned
g_nof_repeat : NATURAL := 8 g_nof_repeat : NATURAL := 8
); );
END tb_dp_bsn_align_v2; END tb_dp_bsn_align_v2;
...@@ -69,9 +69,11 @@ ARCHITECTURE tb OF tb_dp_bsn_align_v2 IS ...@@ -69,9 +69,11 @@ ARCHITECTURE tb OF tb_dp_bsn_align_v2 IS
CONSTANT c_sync_period : NATURAL := 7; CONSTANT c_sync_period : NATURAL := 7;
CONSTANT c_sync_offset : NATURAL := 2; CONSTANT c_sync_offset : NATURAL := 2;
CONSTANT c_gap_size : NATURAL := 10; CONSTANT c_block_period : NATURAL := g_block_size + g_gap_size;
CONSTANT c_block_period : NATURAL := g_block_size + c_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_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_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); 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 ...@@ -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); out_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
END RECORD; END RECORD;
SIGNAL tb_end_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS=>'0'); SIGNAL tb_end_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS=>'0');
SIGNAL tb_end : STD_LOGIC; SIGNAL tb_end : STD_LOGIC;
SIGNAL clk : STD_LOGIC := '1'; SIGNAL clk : STD_LOGIC := '1';
SIGNAL rst : STD_LOGIC := '1'; SIGNAL rst : STD_LOGIC := '1';
SIGNAL sl1 : STD_LOGIC := '1';
SIGNAL node_index : NATURAL := 0;
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 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 ref_siso_arr : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy);
SIGNAL in_bsn : t_bsn_arr; SIGNAL ref_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL in_data : t_data_arr; SIGNAL in_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>c_dp_sosi_rst);
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_sync_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
SIGNAL in_sop : 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 : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); SIGNAL in_eop_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
SIGNAL in_err : t_err_arr; SIGNAL in_val_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
SIGNAL in_channel : t_channel_arr; SIGNAL in_data_arr : t_data_arr;
SIGNAL in_bsn_arr : t_bsn_arr;
SIGNAL mm_copi_arr : t_mem_copi_arr(g_nof_streams-1 DOWNTO 0); SIGNAL in_channel_arr : t_channel_arr;
SIGNAL mm_copi : t_mem_copi; -- read access to output block, all output streams share same mm_copi SIGNAL in_err_arr : t_err_arr;
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_copi_arr : t_mem_copi_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL mm_done_arr : STD_LOGIC_VECTOR(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_done : STD_LOGIC; SIGNAL mm_cipo_arr : t_mem_cipo_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL dut_sosi_arr : t_dp_sosi_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 tb_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); SIGNAL mm_done_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
SIGNAL r : t_reg; SIGNAL mm_done : STD_LOGIC;
SIGNAL nxt_r : t_reg; 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 out_siso_arr : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy); SIGNAL r : t_reg;
SIGNAL out_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); SIGNAL nxt_r : t_reg;
SIGNAL out_bsn : t_bsn_arr;
SIGNAL out_data : t_data_arr; SIGNAL out_siso_arr : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy);
SIGNAL out_val : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); SIGNAL out_sosi_arr : t_dp_sosi_arr(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_sync_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
SIGNAL out_eop : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); SIGNAL out_sop_arr : 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_eop_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
SIGNAL out_err : t_err_arr; SIGNAL out_val_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
SIGNAL out_channel : t_channel_arr; SIGNAL out_data_arr : t_data_arr;
SIGNAL out_bsn_arr : t_bsn_arr;
SIGNAL in_sosi_arr_dly : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); SIGNAL out_channel_arr : t_channel_arr;
SIGNAL out_sosi_arr_exp : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); SIGNAL out_err_arr : t_err_arr;
SIGNAL tb_bsn : INTEGER;
SIGNAL verify_done_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS=>'0'); SIGNAL tb_bsn : INTEGER;
SIGNAL verify_en_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS=>'0'); 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 hold_out_sop : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); SIGNAL verify_done_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS=>'0');
SIGNAL prev_out_bsn : t_bsn_arr; SIGNAL verify_en_prev_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
SIGNAL expected_out_bsn : t_bsn_arr; SIGNAL verify_en_delayed_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
SIGNAL prev_out_data : t_data_arr;
SIGNAL expected_out_data : t_data_arr; SIGNAL hold_out_sop_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
SIGNAL prev_out_bsn_arr : t_bsn_arr;
SIGNAL stream_en_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS=>'1'); -- default all streams are enabled 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 BEGIN
clk <= (NOT clk) OR tb_end AFTER clk_period/2; clk <= (NOT clk) OR tb_end AFTER clk_period/2;
...@@ -159,30 +172,29 @@ BEGIN ...@@ -159,30 +172,29 @@ BEGIN
VARIABLE v_err : NATURAL := c_err_init; VARIABLE v_err : NATURAL := c_err_init;
VARIABLE v_diff_bsn : NATURAL := 0; VARIABLE v_diff_bsn : NATURAL := 0;
BEGIN BEGIN
-- Create BSN misalignment between the input streams
v_diff_bsn := I MOD (g_diff_bsn+1);
v_data := v_data + I; v_data := v_data + I;
v_bsn := INCR_UVEC(v_bsn, v_diff_bsn); ref_sosi_arr(I) <= c_dp_sosi_rst;
in_sosi_arr(I) <= c_dp_sosi_rst;
proc_common_wait_until_low(clk, rst); proc_common_wait_until_low(clk, rst);
proc_common_wait_some_cycles(clk, 10); 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 -- Begin of stimuli
FOR R IN 0 TO g_nof_repeat-v_diff_bsn-1 LOOP 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'); 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_bsn := INCR_UVEC(v_bsn, 1);
v_data := v_data + g_block_size; 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 LOOP;
-- End of stimuli, g_bsn_latency_max blocks remain in buffer -- End of stimuli, g_bsn_latency_max blocks remain in DUT buffer
expected_out_bsn(I) <= INCR_UVEC(v_bsn, -1 -g_bsn_latency_max); expected_out_bsn_arr(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); 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); proc_common_wait_some_cycles(clk, 100);
verify_done_arr(I) <= '1'; verify_done_arr(I) <= '1';
...@@ -193,71 +205,110 @@ BEGIN ...@@ -193,71 +205,110 @@ BEGIN
WAIT; WAIT;
END PROCESS; END PROCESS;
END GENERATE; 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); 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); ------------------------------------------------------------------------------
-- a) Use proc_dp_verify_()
p_verify_en_arr : PROCESS ------------------------------------------------------------------------------
p_verify_en_prev_arr : PROCESS
BEGIN BEGIN
-- Skip initial blocks from verification verify_en_prev_arr <= (OTHERS => '0');
proc_common_wait_until_value(TO_UINT(c_bsn_init) + g_bsn_latency_max, clk, tb_bsn); IF g_diff_delay_max <= c_align_latency THEN
verify_en_arr <= (OTHERS => '1'); -- Can only verify incrementing sosi data when no blocks get lost
proc_common_wait_until_value(TO_UINT(c_bsn_init) + g_nof_repeat - g_bsn_latency_max - 1, clk, tb_bsn); -- Skip sample of first block from verification, because then there is no prev_out_bsn_arr, prev_out_data_arr yet
verify_en_arr <= (OTHERS => '0'); proc_common_wait_until_high(clk, out_sosi_arr(0).sop);
verify_en_prev_arr <= (OTHERS => '1');
END IF;
WAIT; WAIT;
END PROCESS; END PROCESS;
gen_verify_sosi : FOR I IN g_nof_streams-1 DOWNTO 0 GENERATE gen_verify_prev_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);
-- Actual verification of the output streams -- Actual verification of the output streams
-- . Verify that sop and eop come in pairs -- . 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 -- . 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.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_arr(I), out_siso_arr(I).ready, out_sop(I), out_bsn(I), prev_out_bsn(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 -- . 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_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", e_equal, clk, verify_done_arr(I), expected_out_bsn(I), prev_out_bsn(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; 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) p_verify_data : PROCESS(clk)
BEGIN BEGIN
IF rising_edge(clk) THEN 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).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) & " : " IF func_input_delay(I) <= c_align_latency THEN
& int_to_str(TO_UINT(out_sosi_arr(I).data)) -- Verify expected input data
& " /= " & int_to_str(TO_UINT(out_sosi_arr_exp(I).data)) 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;
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 IF; END IF;
END PROCESS; END PROCESS;
......
...@@ -34,13 +34,15 @@ END tb_tb_dp_bsn_align_v2; ...@@ -34,13 +34,15 @@ END tb_tb_dp_bsn_align_v2;
ARCHITECTURE tb OF tb_tb_dp_bsn_align_v2 IS 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_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' SIGNAL tb_end : STD_LOGIC := '0'; -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end'
BEGIN BEGIN
-- -- DUT -- -- DUT
...@@ -48,6 +50,7 @@ BEGIN ...@@ -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_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_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_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_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_data_w : NATURAL := 16; -- number of bits in sosi data
-- c_replacement_value : INTEGER := 0; -- output sosi data replacement value for missing input blocks -- c_replacement_value : INTEGER := 0; -- output sosi data replacement value for missing input blocks
...@@ -56,11 +59,13 @@ BEGIN ...@@ -56,11 +59,13 @@ BEGIN
-- g_rd_latency : NATURAL := 2; -- 1 or 2, choose 2 to ease timing closure -- g_rd_latency : NATURAL := 2; -- 1 or 2, choose 2 to ease timing closure
-- --
-- -- TB -- -- TB
-- g_diff_delay : NATURAL := 0; -- g_diff_delay_max : NATURAL := 0; -- maximum nof clk delay between any inputs
-- g_diff_bsn : NATURAL := 0; -- g_diff_bsn = g_bsn_latency_max can just be aligned
-- g_nof_repeat : NATURAL := 100 -- for constant active stream control using 1 is sufficient, use > 1 to verify longer with random stimuli -- 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_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, 11, 32, 16, 0, FALSE, 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, 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; END tb;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment