diff --git a/libraries/base/dp/src/vhdl/dp_block_validate_bsn_at_sync.vhd b/libraries/base/dp/src/vhdl/dp_block_validate_bsn_at_sync.vhd index c21ef65e507057dd120d32a1d9a0f4629863e52a..7f11d113cf10a2b4504d089f5d924f97098ab9cb 100644 --- a/libraries/base/dp/src/vhdl/dp_block_validate_bsn_at_sync.vhd +++ b/libraries/base/dp/src/vhdl/dp_block_validate_bsn_at_sync.vhd @@ -133,7 +133,6 @@ BEGIN ); -- discarded counter - cnt_discarded_en <= '1' WHEN in_sosi.sync = '1' AND bsn_ok = '0' ELSE '0'; u_discarded_counter : ENTITY common_lib.common_counter GENERIC MAP ( g_width => c_word_w, @@ -187,16 +186,55 @@ BEGIN -- MM registers in st_clk domain reg_wr_arr => OPEN, reg_rd_arr => OPEN, - in_reg => count_reg, -- read only + in_reg => count_reg, -- read only out_reg => OPEN -- no write ); - bsn_at_sync <= bs_sosi.bsn WHEN bs_sosi.sync = '1' ELSE bsn_at_sync_reg; - bsn_ok <= bsn_ok_reg WHEN in_sosi.sync = '0' ELSE '1' WHEN in_sosi.bsn = bsn_at_sync ELSE '0'; - out_valid <= '1' WHEN in_sosi.sop = '1' AND TO_UINT(in_sosi.channel) /= g_check_channel ELSE - bsn_ok WHEN in_sosi.sop = '1' AND TO_UINT(in_sosi.channel) = g_check_channel ELSE - out_valid_reg; + -- Process to check the bsn at sync. It captures the bsn at the sync of bs_sosi. Then compares that bsn to + -- the bsn at sync of in_sosi. If they are unequal all packets during that sync period with in_sosi.channel + -- equal to g_check_channel are discarded. + p_bsn_check : PROCESS(bs_sosi, in_sosi, bsn_at_sync_reg, bsn_ok_reg, out_valid_reg) + -- v_bsn_ok used for the first in_sosi packet of a sync period as sync and sop are both '1'. + VARIABLE v_bsn_ok : STD_LOGIC; + -- Using v_bsn_at_sync to ensure correct behavior when in_sosi has no latency compared to bs_sosi. + VARIABLE v_bsn_at_sync : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0); + BEGIN + v_bsn_at_sync := bsn_at_sync_reg; + v_bsn_ok := bsn_ok_reg; + out_valid <= out_valid_reg; + cnt_discarded_en <= '0'; + + IF bs_sosi.sync = '1' THEN + v_bsn_at_sync := bs_sosi.bsn(g_bsn_w-1 DOWNTO 0); + END IF; + + IF TO_UINT(in_sosi.channel) = g_check_channel THEN + IF in_sosi.sync = '1' THEN + -- Compare bsn at sync of in_sosi to bsn at sync of bs_sosi. + IF UNSIGNED(in_sosi.bsn(g_bsn_w-1 DOWNTO 0)) = UNSIGNED(v_bsn_at_sync) THEN + v_bsn_ok := '1'; + ELSE + v_bsn_ok := '0'; + END IF; + + -- set cnt_discarded_en to control u_discarded_counter. + cnt_discarded_en <= NOT v_bsn_ok; + END IF; + -- Setting out_valid to control the discarding at packet level. + IF in_sosi.sop = '1' THEN + out_valid <= v_bsn_ok; + END IF; + ELSE + IF in_sosi.sop = '1' THEN + out_valid <= '1'; -- Packets with channel unequal to g_check_channel are always valid + END IF; + + END IF; + bsn_ok <= v_bsn_ok; -- bsn_ok is used to indicate if the bsn is correct for the entire sync period of g_check_channel. + bsn_at_sync <= v_bsn_at_sync; -- register to store the bsn at sync of bs_sosi. + END PROCESS; + p_dp_clk : PROCESS(dp_rst, dp_clk) BEGIN IF dp_rst='1' THEN diff --git a/libraries/base/dp/tb/vhdl/tb_dp_block_validate_bsn_at_sync.vhd b/libraries/base/dp/tb/vhdl/tb_dp_block_validate_bsn_at_sync.vhd index 9483cfab0d228c49774aaaadea4e3ee978b62d30..74423a7316df7c613d011459ebd4d0d15c3b882c 100644 --- a/libraries/base/dp/tb/vhdl/tb_dp_block_validate_bsn_at_sync.vhd +++ b/libraries/base/dp/tb/vhdl/tb_dp_block_validate_bsn_at_sync.vhd @@ -46,8 +46,7 @@ ENTITY tb_dp_block_validate_bsn_at_sync IS GENERIC ( g_nof_blocks_per_sync : NATURAL := 5; g_nof_data_per_blk : NATURAL := 6; - g_bsn_init : NATURAL := 7; -- >= g_nof_blocks_per_sync for discarded sync, < g_nof_blocks_per_sync for no discarded sync, - g_check_channel : NATURAL := 8 -- channel to check, the channel field is a counter value. + g_bsn_init : NATURAL := 7 -- >= g_nof_blocks_per_sync for discarded sync, < g_nof_blocks_per_sync for no discarded sync. ); END tb_dp_block_validate_bsn_at_sync; @@ -64,6 +63,12 @@ ARCHITECTURE tb OF tb_dp_block_validate_bsn_at_sync IS CONSTANT c_gap_size : NATURAL := 4; CONSTANT c_nof_sync : NATURAL := 5; CONSTANT c_nof_blk : NATURAL := g_nof_blocks_per_sync * c_nof_sync; + -- The u_stimuli_in creates counter data in stimuli_sosi.channel. Therefore + -- choose some c_check_channel value (> 0, < c_nof_blk) that will occur in + -- the future. Hence this c_check_channel value will occur once in the tb, + -- because stimuli_sosi.channel keeps incrementing. Choosing c_check_channel + -- such that it corresponds with a channel from stimuli on a sync pulse. + CONSTANT c_check_channel : NATURAL := g_nof_blocks_per_sync; -- can be c_check_channel MOD g_nof_blocks_per_sync = 0 but not larger than c_nof_blk. SIGNAL dp_clk : STD_LOGIC := '1'; SIGNAL mm_clk : STD_LOGIC := '1'; @@ -146,7 +151,7 @@ BEGIN ------------------------------------------------------------------------------ u_dut : ENTITY work.dp_block_validate_bsn_at_sync GENERIC MAP ( - g_check_channel => g_check_channel + g_check_channel => c_check_channel ) PORT MAP ( dp_rst => rst, @@ -191,8 +196,9 @@ BEGIN VARIABLE v_valid_blk : BOOLEAN := TRUE; BEGIN IF rising_edge(dp_clk) THEN - IF reference_sosi.sop = '1' THEN - IF g_bsn_init >= g_nof_blocks_per_sync AND TO_UINT(reference_sosi.channel) = g_check_channel THEN + IF reference_sosi.sop = '1' THEN --Decide for each block if it should be valid. + -- A block can only be discarded if its channel field corresponds with the check_channel. + IF g_bsn_init >= g_nof_blocks_per_sync AND TO_UINT(reference_sosi.channel) = c_check_channel THEN v_valid_blk := FALSE; ELSE v_valid_blk := TRUE; @@ -220,10 +226,8 @@ BEGIN proc_mem_mm_bus_rd(0, mm_clk, reg_miso, reg_mosi); proc_mem_mm_bus_rd_latency(1, mm_clk); - IF g_bsn_init = g_nof_blocks_per_sync THEN -- should have c_nof_sync discarded sync - ASSERT c_nof_sync = TO_UINT(reg_miso.rddata(c_word_w-1 DOWNTO 0)) REPORT "Wrong discarded sync count" SEVERITY ERROR; - ELSIF g_bsn_init > g_nof_blocks_per_sync THEN -- should have c_nof_sync -1 discarded sync - ASSERT c_nof_sync-1 = TO_UINT(reg_miso.rddata(c_word_w-1 DOWNTO 0)) REPORT "Wrong discarded sync count" SEVERITY ERROR; + IF g_bsn_init >= g_nof_blocks_per_sync THEN -- should have 1 discarded sync + ASSERT 1 = TO_UINT(reg_miso.rddata(c_word_w-1 DOWNTO 0)) REPORT "Wrong discarded sync count" SEVERITY ERROR; ELSE -- 0 discarded sync ASSERT 0 = TO_UINT(reg_miso.rddata(c_word_w-1 DOWNTO 0)) REPORT "Wrong discarded sync count" SEVERITY ERROR; END IF; diff --git a/libraries/base/dp/tb/vhdl/tb_tb_dp_block_validate_bsn_at_sync.vhd b/libraries/base/dp/tb/vhdl/tb_tb_dp_block_validate_bsn_at_sync.vhd index 6828a0964eebc0d01f5d017ed4866020a4ce2b1d..8832d49c0fd983f40f24ff114ce48be1d0fb7821 100644 --- a/libraries/base/dp/tb/vhdl/tb_tb_dp_block_validate_bsn_at_sync.vhd +++ b/libraries/base/dp/tb/vhdl/tb_tb_dp_block_validate_bsn_at_sync.vhd @@ -43,13 +43,10 @@ ARCHITECTURE tb OF tb_tb_dp_block_validate_bsn_at_sync IS BEGIN -- g_nof_blocks_per_sync : NATURAL := 5; -- g_nof_data_per_blk : NATURAL := 6; --- g_bsn_init : NATURAL := 7; -- >= g_nof_blocks_per_sync for discarded sync, < g_nof_blocks_per_sync for no discarded sync, --- g_check_channel : NATURAL := 8 -- channel to check, the channel field is a counter value. - - u_smaller : ENTITY work.tb_dp_block_validate_bsn_at_sync GENERIC MAP(c_blk_per_sync, c_data_per_blk, 0, 8); -- g_bsn_init < g_nof_blocks_per_sync - u_equal : ENTITY work.tb_dp_block_validate_bsn_at_sync GENERIC MAP(c_blk_per_sync, c_data_per_blk, 5, 8); -- g_bsn_init = g_nof_blocks_per_sync - u_larger : ENTITY work.tb_dp_block_validate_bsn_at_sync GENERIC MAP(c_blk_per_sync, c_data_per_blk, 8, 8); -- g_bsn_init > g_nof_blocks_per_sync - u_ch_on_sync : ENTITY work.tb_dp_block_validate_bsn_at_sync GENERIC MAP(c_blk_per_sync, c_data_per_blk, 5, 10); -- g_check_channel MOD c_blk_per_sync = 0, - u_no_ch : ENTITY work.tb_dp_block_validate_bsn_at_sync GENERIC MAP(c_blk_per_sync, c_data_per_blk, 8, 500); -- channel will never reach 500 +-- g_bsn_init : NATURAL := 7 -- >= g_nof_blocks_per_sync for discarded sync, < g_nof_blocks_per_sync for no discarded sync. + + u_smaller : ENTITY work.tb_dp_block_validate_bsn_at_sync GENERIC MAP(c_blk_per_sync, c_data_per_blk, c_blk_per_sync - 4); -- g_bsn_init < g_nof_blocks_per_sync + u_equal : ENTITY work.tb_dp_block_validate_bsn_at_sync GENERIC MAP(c_blk_per_sync, c_data_per_blk, c_blk_per_sync); -- g_bsn_init = g_nof_blocks_per_sync + u_larger : ENTITY work.tb_dp_block_validate_bsn_at_sync GENERIC MAP(c_blk_per_sync, c_data_per_blk, c_blk_per_sync + 4); -- g_bsn_init > g_nof_blocks_per_sync END tb;