diff --git a/libraries/base/dp/tb/vhdl/tb_dp_strobe_total_count.vhd b/libraries/base/dp/tb/vhdl/tb_dp_strobe_total_count.vhd index 21b789c1f8c70aa75d77ed2408b00b25c6ef47a9..24f22387fdcd454352a37f80ca0b964ae7e47553 100644 --- a/libraries/base/dp/tb/vhdl/tb_dp_strobe_total_count.vhd +++ b/libraries/base/dp/tb/vhdl/tb_dp_strobe_total_count.vhd @@ -22,6 +22,11 @@ -- Author: E. Kooistra -- Purpose: Test bench for dp_strobe_total_count.vhd -- Description: +-- * maximum g_count_w = 31 to fit in largest NATURAL +-- * Use g_mm_w < c_word_w = 32 to simulate large counts in feasible time. +-- * Use g_nof_sync in combination with g_mm_w and g_count_w to achieve +-- . a count > 2**g_mm_w that uses the high part of an MM word +-- . a count > 2**(g_mm_w*2) that will clip at 2**g_mm_w - 1 -- Usage: -- . as 5 -- . run -all @@ -38,9 +43,12 @@ USE work.dp_stream_pkg.ALL; ENTITY tb_dp_strobe_total_count IS GENERIC ( - g_count_w : NATURAL := 16; - g_gap_size : NATURAL := 0; - g_clip : BOOLEAN := TRUE + g_mm_w : NATURAL := 8; + g_count_w : NATURAL := 7; + g_nof_blocks_per_sync : NATURAL := 10; + g_nof_valid_per_blk : NATURAL := 10; + g_nof_sync : NATURAL := 10; + g_gap_size : NATURAL := 3 ); END tb_dp_strobe_total_count; @@ -53,22 +61,24 @@ ARCHITECTURE tb OF tb_dp_strobe_total_count IS CONSTANT c_dp_clk_period : TIME := 5 ns; CONSTANT c_mm_clk_period : TIME := 10 ns; - CONSTANT c_nof_blocks_per_sync : NATURAL := 5; - CONSTANT c_nof_data_per_blk : NATURAL := 9; - CONSTANT c_nof_sync : NATURAL := 5; - CONSTANT c_nof_blk : NATURAL := c_nof_blocks_per_sync * (c_nof_sync - 1); - + CONSTANT c_skip_nof_sync : NATURAL := 3; + CONSTANT c_tb_nof_sync : NATURAL := c_skip_nof_sync + g_nof_sync; + CONSTANT c_clip : BOOLEAN := TRUE; + -- dut CONSTANT c_nof_counts_max : NATURAL := 15; CONSTANT c_nof_counts : NATURAL := 3; -- count stimuli.sync, sop, valid - + CONSTANT c_count_max : NATURAL := 2**g_count_w - 1; CONSTANT c_mm_addr_clear : NATURAL := c_nof_counts_max*2; - -- c_nof_sync - 1 because stimuli_sosi.sync is used as ref_sync, and ref_sync is used - -- to hold the count. - CONSTANT c_exp_nof_sync : NATURAL := c_nof_sync - 1; - CONSTANT c_exp_nof_sop : NATURAL := c_nof_blk; - CONSTANT c_exp_nof_valid : NATURAL := c_nof_blk * c_nof_data_per_blk; + -- c_tb_nof_sync - c_skip_nof_sync because first sync intervals are skipped + -- by using clear, and -1, because stimuli_sosi.sync is used as ref_sync, + -- and ref_sync is used to hold the counts. + CONSTANT c_exp_nof_sync : NATURAL := c_tb_nof_sync - c_skip_nof_sync - 1; + CONSTANT c_nof_blk : NATURAL := g_nof_blocks_per_sync * c_exp_nof_sync; + CONSTANT c_exp_nof_sop : NATURAL := sel_a_b(c_nof_blk < c_count_max, c_nof_blk, c_count_max); + CONSTANT c_nof_valid : NATURAL := c_nof_blk * g_nof_valid_per_blk; + CONSTANT c_exp_nof_valid : NATURAL := sel_a_b(c_nof_valid < c_count_max, c_nof_valid, c_count_max); SIGNAL dp_clk : STD_LOGIC := '1'; SIGNAL mm_clk : STD_LOGIC := '1'; @@ -104,9 +114,9 @@ BEGIN -- Generate snk_in with data frames u_stimuli : ENTITY work.dp_stream_stimuli GENERIC MAP ( - g_sync_period => c_nof_blocks_per_sync, - g_nof_repeat => c_nof_blocks_per_sync * c_nof_sync, - g_pkt_len => c_nof_data_per_blk, + g_sync_period => g_nof_blocks_per_sync, + g_nof_repeat => g_nof_blocks_per_sync * c_tb_nof_sync, + g_pkt_len => g_nof_valid_per_blk, g_pkt_gap => g_gap_size ) PORT MAP ( @@ -129,10 +139,11 @@ BEGIN ------------------------------------------------------------------------------ u_dut : ENTITY work.dp_strobe_total_count GENERIC MAP ( + g_mm_w => g_mm_w, g_nof_counts_max => c_nof_counts_max, g_nof_counts => c_nof_counts, g_count_w => g_count_w, - g_clip => g_clip + g_clip => c_clip ) PORT MAP ( dp_rst => rst, @@ -153,10 +164,15 @@ BEGIN ------------------------------------------------------------------------------ p_mm : PROCESS - VARIABLE v_rd_data : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); + VARIABLE v_rd_data : STD_LOGIC_VECTOR(g_mm_w-1 DOWNTO 0); VARIABLE v_rd_count : NATURAL; BEGIN - proc_common_wait_until_low(mm_clk, rst); + -- Wait until strobes have started, skip first sync intervals + FOR I IN 0 TO c_skip_nof_sync-1 LOOP + proc_common_wait_until_lo_hi(dp_clk, stimuli_sosi.sync); + END LOOP; + proc_common_wait_some_cycles(dp_clk, 1); + -- Clear to restart counting at next sync interval proc_mem_mm_bus_wr(c_mm_addr_clear, 1, mm_clk, reg_mosi); proc_common_wait_until_lo_hi(dp_clk, stimuli_end); @@ -164,10 +180,16 @@ BEGIN proc_common_wait_some_cycles(mm_clk, 1); FOR I IN 0 TO c_nof_counts-1 LOOP + -- read low part proc_mem_mm_bus_rd(I*2, mm_clk, reg_miso, reg_mosi); proc_mem_mm_bus_rd_latency(1, mm_clk); - v_rd_data := reg_miso.rddata(c_word_w-1 DOWNTO 0); + v_rd_data := reg_miso.rddata(g_mm_w-1 DOWNTO 0); v_rd_count := TO_UINT(v_rd_data); + -- read and add high part + proc_mem_mm_bus_rd(I*2+1, mm_clk, reg_miso, reg_mosi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + v_rd_data := reg_miso.rddata(g_mm_w-1 DOWNTO 0); + v_rd_count := v_rd_count + TO_UINT(v_rd_data) * 2**g_mm_w; rd_count_arr(I) <= v_rd_count; ASSERT exp_count_arr(I) = v_rd_count REPORT "Wrong total block count(" & NATURAL'IMAGE(I) & ")" SEVERITY ERROR; END LOOP; diff --git a/libraries/base/dp/tb/vhdl/tb_tb_dp_strobe_total_count.vhd b/libraries/base/dp/tb/vhdl/tb_tb_dp_strobe_total_count.vhd index 64ed64c4657f5b5caf4cc8092cfec0ab8c1d8f23..f96672f9c71c9bcfb700bf6d62b7ef1598ba2dbb 100644 --- a/libraries/base/dp/tb/vhdl/tb_tb_dp_strobe_total_count.vhd +++ b/libraries/base/dp/tb/vhdl/tb_tb_dp_strobe_total_count.vhd @@ -37,11 +37,25 @@ ARCHITECTURE tb OF tb_tb_dp_strobe_total_count IS SIGNAL tb_end : STD_LOGIC := '0'; -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end' BEGIN - --g_count_w : NATURAL := 16; - --g_gap_size : NATURAL := 0; - --g_clip : BOOLEAN := TRUE + --g_mm_w : NATURAL := c_word_w; + --g_count_w : NATURAL := 16; + --g_nof_blocks_per_sync : NATURAL := 10; + --g_nof_valid_per_blk : NATURAL := 10; + --g_nof_sync : NATURAL := 10; + --g_gap_size : NATURAL := 0; - u_clip_word_gap : ENTITY work.tb_dp_strobe_total_count GENERIC MAP(8, 3, TRUE); - u_clip_word_no_gap : ENTITY work.tb_dp_strobe_total_count GENERIC MAP(8, 0, TRUE); + -- Use g_nof_blocks_per_sync * g_nof_valid_per_blk = 100 valid per sync and + -- use g_nof_sync = 10, so maximum expected valid count is 900. + -- Maximum expected sop count is 90 + -- Maximum expected sync count is 9 + + -- Default usage + u_mm32b_cnt16b_no_gap : ENTITY work.tb_dp_strobe_total_count GENERIC MAP(32, 16, 10,10, 10, 0); + u_mm32b_cnt16b_gap : ENTITY work.tb_dp_strobe_total_count GENERIC MAP(32, 16, 10,10, 10, 3); + -- Check MM high word and counter overflow (clipping) + u_mm8b_cnt16b_high : ENTITY work.tb_dp_strobe_total_count GENERIC MAP(8, 16, 10,10, 10, 3); -- use high part + u_mm8b_cnt9b_overflow : ENTITY work.tb_dp_strobe_total_count GENERIC MAP(8, 9, 10,10, 10, 3); -- cause overflow to clip count high part + u_mm8b_cnt7b_overflow : ENTITY work.tb_dp_strobe_total_count GENERIC MAP(8, 7, 10,10, 10, 3); -- cause overflow to clip count low part + END tb;