Skip to content
Snippets Groups Projects
Commit 0621ddad authored by Reinier van der Walle's avatar Reinier van der Walle
Browse files

added clipping function to common_counter

parent c1fcbfbc
No related branches found
No related tags found
1 merge request!124Resolve L2SDP-271
......@@ -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
......
......@@ -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,
......
......@@ -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,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment