diff --git a/libraries/base/common/src/vhdl/common_counter.vhd b/libraries/base/common/src/vhdl/common_counter.vhd index 4a3dd59d1da1b92a0722d2e6523a57e95ed58881..07a7d116544c7d4bf938260687839b3e83cbfb0d 100644 --- a/libraries/base/common/src/vhdl/common_counter.vhd +++ b/libraries/base/common/src/vhdl/common_counter.vhd @@ -22,6 +22,7 @@ -- Purpose : Counter with extra options -- Description: -- - default wrap at 2**g_width or special wrap at fixed g_max or dynamically via cnt_max +-- - count can be clipped instead of wrapped by setting g_clip to True. -- - default increment +1 or other g_step_size -- - external clr -- - external load with g_init or dynamically via load @@ -42,7 +43,8 @@ ENTITY common_counter IS g_init : INTEGER := 0; g_width : NATURAL := 32; g_max : NATURAL := 0; -- default 0 to disable the g_max setting. - g_step_size : INTEGER := 1 -- counting in steps of g_step_size, can be + or - + g_step_size : INTEGER := 1; -- counting in steps of g_step_size, can be + or - + g_clip : BOOLEAN := FALSE -- when True, counter will clip at g_max, if g_max = 0 and g_step_size > 0, the counter clips at 2**g_width -1. ); PORT ( rst : IN STD_LOGIC := '0'; -- either use asynchronous rst or synchronous cnt_clr @@ -51,7 +53,8 @@ ENTITY common_counter IS cnt_clr : IN STD_LOGIC := '0'; -- synchronous cnt_clr is only interpreted when clken is active cnt_ld : IN STD_LOGIC := '0'; -- cnt_ld loads the output count with the input load value, independent of cnt_en cnt_en : IN STD_LOGIC := '1'; - cnt_max : IN STD_LOGIC_VECTOR(g_width-1 DOWNTO 0) := TO_UVEC(sel_a_b(ceil_log2(g_max+1)>g_width, 0, g_max), g_width); -- see remarks + cnt_max : IN STD_LOGIC_VECTOR(g_width-1 DOWNTO 0) := sel_a_b( g_step_size > 0 AND g_max = 0, array_init('1', g_width), + sel_a_b( ceil_log2(g_max+1) > g_width, array_init('1', g_width), TO_UVEC(g_max, g_width) )); -- see remarks load : IN STD_LOGIC_VECTOR(g_width-1 DOWNTO 0) := TO_SVEC(g_init, g_width); count : OUT STD_LOGIC_VECTOR(g_width-1 DOWNTO 0) ); @@ -60,7 +63,6 @@ END common_counter; ARCHITECTURE rtl OF common_counter IS - CONSTANT zeros : STD_LOGIC_VECTOR(count'RANGE) := (OTHERS => '0'); -- used to check if cnt_max is zero SIGNAL reg_count : STD_LOGIC_VECTOR(count'RANGE) := TO_SVEC(g_init, g_width); -- in case rst is not used SIGNAL nxt_count : STD_LOGIC_VECTOR(count'RANGE) := TO_SVEC(g_init, g_width); -- to avoid Warning: NUMERIC_STD.">=": metavalue detected, returning FALSE, when using unsigned() SIGNAL comb_count : STD_LOGIC_VECTOR(count'RANGE) := TO_SVEC(g_init, g_width); -- to avoid Warning: NUMERIC_STD.">=": metavalue detected, returning FALSE, when using unsigned() @@ -87,8 +89,12 @@ BEGIN p_count : PROCESS(reg_count, cnt_clr, cnt_en, cnt_ld, load, cnt_max) BEGIN nxt_count <= reg_count; - IF cnt_clr='1' OR (reg_count=cnt_max AND cnt_max /= zeros) THEN + IF cnt_clr='1' THEN nxt_count <= (OTHERS => '0'); + ELSIF reg_count=cnt_max THEN + IF NOT g_clip THEN + nxt_count <= (OTHERS => '0'); + END IF; ELSIF cnt_ld='1' THEN nxt_count <= load; ELSIF cnt_en='1' THEN 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 e1e714d42dec00842405d373fc6869aa0da30c8d..b71ce78bc5cdfcf2bbfbee099bbde6ea961265e9 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 @@ -134,7 +134,8 @@ BEGIN 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 + g_width => c_word_w, + g_clip => TRUE ) PORT MAP ( rst => dp_rst, @@ -148,7 +149,8 @@ BEGIN -- sync counter u_blk_counter : ENTITY common_lib.common_counter GENERIC MAP ( - g_width => c_word_w + g_width => c_word_w, + g_clip => TRUE ) PORT MAP ( rst => dp_rst, diff --git a/libraries/base/dp/src/vhdl/dp_block_validate_err.vhd b/libraries/base/dp/src/vhdl/dp_block_validate_err.vhd index d556561e91200eba47fa455630d27d6b3dfaab03..8ec87e33d5e660fcffebb90920322adf73704d99 100644 --- a/libraries/base/dp/src/vhdl/dp_block_validate_err.vhd +++ b/libraries/base/dp/src/vhdl/dp_block_validate_err.vhd @@ -120,7 +120,6 @@ ARCHITECTURE rtl OF dp_block_validate_err IS SIGNAL mm_cnt_clr : STD_LOGIC; SIGNAL cnt_clr : STD_LOGIC; SIGNAL cnt_blk : STD_LOGIC_VECTOR(g_cnt_w-1 DOWNTO 0); - SIGNAL cnt_blk_en : STD_LOGIC; SIGNAL cnt_discarded : STD_LOGIC_VECTOR(g_cnt_w-1 DOWNTO 0); SIGNAL cnt_discarded_en : STD_LOGIC; SIGNAL cnt_err : t_cnt_err_arr(g_nof_err_counts-1 DOWNTO 0); @@ -151,26 +150,26 @@ BEGIN ); -- block counter - cnt_blk_en <= snk_in.eop WHEN UNSIGNED(cnt_blk) < UNSIGNED(c_max_cnt) ELSE '0'; u_blk_counter : ENTITY common_lib.common_counter GENERIC MAP ( - g_width => g_cnt_w + g_width => g_cnt_w, + g_clip => TRUE ) PORT MAP ( rst => dp_rst, clk => dp_clk, cnt_clr => cnt_clr, - cnt_en => cnt_blk_en, + cnt_en => snk_in.eop, count => cnt_blk ); -- discarded block counter - cnt_discarded_en <= '1' WHEN snk_in.eop = '1' AND TO_UINT(snk_in.err(g_nof_err_counts-1 DOWNTO 0)) > 0 - AND UNSIGNED(cnt_discarded) < UNSIGNED(c_max_cnt) ELSE '0'; + cnt_discarded_en <= snk_in.eop WHEN TO_UINT(snk_in.err(g_nof_err_counts-1 DOWNTO 0)) > 0 ELSE '0'; u_discarded_counter : ENTITY common_lib.common_counter GENERIC MAP ( - g_width => g_cnt_w + g_width => g_cnt_w, + g_clip => TRUE ) PORT MAP ( rst => dp_rst, @@ -183,10 +182,11 @@ BEGIN -- error counters gen_err_counters : FOR I IN 0 TO g_nof_err_counts-1 GENERATE - cnt_err_en(I) <= snk_in.eop AND snk_in.err(I) WHEN UNSIGNED(cnt_err(I)) < UNSIGNED(c_max_cnt) ELSE '0'; + cnt_err_en(I) <= snk_in.eop AND snk_in.err(I); u_blk_counter : ENTITY common_lib.common_counter GENERIC MAP ( - g_width => g_cnt_w + g_width => g_cnt_w, + g_clip => TRUE ) PORT MAP ( rst => dp_rst,