diff --git a/libraries/base/common/src/vhdl/common_pkg.vhd b/libraries/base/common/src/vhdl/common_pkg.vhd index e81085087bca4e5a67920bea7e00f08decda7f2d..91776d3db8afe8ea7906a5b9757c36fa05903d4b 100644 --- a/libraries/base/common/src/vhdl/common_pkg.vhd +++ b/libraries/base/common/src/vhdl/common_pkg.vhd @@ -373,8 +373,8 @@ PACKAGE common_pkg IS FUNCTION RESIZE_UVEC_32(vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR; -- = RESIZE_UVEC() with w=32 for t_slv_32_arr slv elements FUNCTION RESIZE_SVEC_32(vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR; -- = RESIZE_SVEC() with w=32 for t_slv_32_arr slv elements - -- Negate vec, but avoid overflow by forcing -min to +max. Use w <= vec'LENGTH. - FUNCTION NEGATE_SVEC(vec : STD_LOGIC_VECTOR; w : INTEGER) RETURN STD_LOGIC_VECTOR; + FUNCTION NEGATE_SVEC(vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR; -- assume negated ranges fits within -+max + FUNCTION NEGATE_SVEC(vec : STD_LOGIC_VECTOR; w : INTEGER) RETURN STD_LOGIC_VECTOR; -- avoid overflow by forcing -min to +max. Use w <= vec'LENGTH FUNCTION INCR_UVEC(vec : STD_LOGIC_VECTOR; dec : INTEGER) RETURN STD_LOGIC_VECTOR; FUNCTION INCR_UVEC(vec : STD_LOGIC_VECTOR; dec : UNSIGNED) RETURN STD_LOGIC_VECTOR; @@ -1757,6 +1757,13 @@ PACKAGE BODY common_pkg IS RETURN RESIZE_SVEC(vec, 32); END; + -- Negate vec, assume value range fits -+c_max, so no logic needed to check for c_min + FUNCTION NEGATE_SVEC(vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS + BEGIN + -- use NUMERIC_STD to avoid range limitation of 32b INTEGER + RETURN STD_LOGIC_VECTOR(-SIGNED(vec)); -- negate by multiplying by -1 + END; + -- Negate vec, but avoid overflow by forcing -min to +max. Use w <= vec'LENGTH. FUNCTION NEGATE_SVEC(vec : STD_LOGIC_VECTOR; w : INTEGER) RETURN STD_LOGIC_VECTOR IS CONSTANT c_max : INTEGER := 2**(w-1)-1; @@ -1766,6 +1773,7 @@ PACKAGE BODY common_pkg IS VARIABLE v_val : STD_LOGIC_VECTOR(w-1 DOWNTO 0); BEGIN v_val := v_vec(w-1 DOWNTO 0); -- operate on width w and resize to c_vec_w for return + -- use NUMERIC_STD to avoid range limitation of 32b INTEGER IF SIGNED(v_val) = c_min THEN RETURN STD_LOGIC_VECTOR(TO_SIGNED(c_max, c_vec_w)); -- most negative becomes most positive ELSE diff --git a/libraries/dsp/si/src/vhdl/si.vhd b/libraries/dsp/si/src/vhdl/si.vhd index 14d61189ce30513a56070e74e5c0680a2387f789..1cb6271c137296963a0ee0163bd1a08a54f0ca85 100755 --- a/libraries/dsp/si/src/vhdl/si.vhd +++ b/libraries/dsp/si/src/vhdl/si.vhd @@ -29,7 +29,9 @@ -- where n = 0 is the first sample in the FFT block. For more information -- see section 4.19 in LOFAR_ASTRON_SDD_018_RSP_Firmware_DD.pdf. -- Remark: --- . Ported from LOFAR1 rsp. Then rewrote code to use t_dp_sosi. +-- . Ported from LOFAR1 rsp. +-- . Rewrote code to use t_dp_sosi. Used the combinatorial style of writing the +-- code so with <sig_name>_reg instead of nxt_<sig_name). ------------------------------------------------------------------------------- LIBRARY IEEE, common_lib, dp_lib; diff --git a/libraries/dsp/si/tb/vhdl/tb_si.vhd b/libraries/dsp/si/tb/vhdl/tb_si.vhd index 462b6b6a8a1b9a671e1b3ed8852ea70431f384d8..cf715e2cbb39350599c579605bb14b63c11da7c8 100755 --- a/libraries/dsp/si/tb/vhdl/tb_si.vhd +++ b/libraries/dsp/si/tb/vhdl/tb_si.vhd @@ -26,10 +26,15 @@ -- Test bench for si.vhd. -- Remark: -- . Ported from LOFAR1 rsp. Made the tb self-stopping and self-checking. +-- Usage: +-- > as 5 +-- > run -a +-- view out_dat in radix decimal format in Wave window to see + and - data value LIBRARY IEEE, common_lib, dp_lib; USE IEEE.STD_LOGIC_1164.ALL; USE common_lib.common_pkg.ALL; +USE common_lib.common_str_pkg.ALL; USE common_lib.tb_common_pkg.ALL; USE dp_lib.dp_stream_pkg.ALL; @@ -61,9 +66,12 @@ ARCHITECTURE tb OF tb_si IS SIGNAL rst : STD_LOGIC; SIGNAL tb_end : STD_LOGIC := '0'; + SIGNAL verify_en : STD_LOGIC; SIGNAL toggle : STD_LOGIC; SIGNAL clip_even : STD_LOGIC; SIGNAL clip_odd : STD_LOGIC; + SIGNAL cnt_even : NATURAL; + SIGNAL cnt_odd : NATURAL; BEGIN @@ -114,12 +122,18 @@ BEGIN p_stimuli : PROCESS BEGIN + verify_en <= '1'; si_en <= '1'; in_sop <= '0'; in_sync <= '0'; in_val <= '0'; WAIT FOR 10*c_clk_period; + --------------------------------------------------------------------------- + -- First some blocks with +1 * even and -1 * odd index + -- ==> only clip_odd will occur + ----------------------------------------------------- --------------------- + -- pulse in_sync, to check that it is passed on -- pulse sop and continue with valid data in_sync <= '1'; @@ -143,6 +157,52 @@ BEGIN WAIT FOR c_block_size*c_clk_period; END LOOP; + --------------------------------------------------------------------------- + -- Some blocks with -1 * even and +1 * odd index + -- ==> only clip_even will occur + ----------------------------------------------------- --------------------- + -- insert one extra valid do let in_sop occur on odd index + WAIT FOR c_clk_period; + + -- disable verification while using sop and two valids periods to transition to the new sop index phase + verify_en <= '0'; + in_sop <= '1'; + WAIT FOR c_clk_period; + in_sop <= '0'; + WAIT FOR c_clk_period; + verify_en <= '1'; + + -- some more blocks + FOR I IN 0 TO 15 LOOP + in_sop <= '1'; + WAIT FOR c_clk_period; + in_sop <= '0'; + WAIT FOR c_block_size*c_clk_period; + END LOOP; + + --------------------------------------------------------------------------- + -- Some blocks with +1 * even and -1 * odd index + -- ==> only clip_odd will occur + ----------------------------------------------------- --------------------- + -- insert one extra valid do let in_sop occur on even index + WAIT FOR c_clk_period; + + -- disable verification while using sop and two valids periods to transition to the new sop index phase + verify_en <= '0'; + in_sop <= '1'; + WAIT FOR c_clk_period; + in_sop <= '0'; + WAIT FOR c_clk_period; + verify_en <= '1'; + + -- some more blocks + FOR I IN 0 TO 15 LOOP + in_sop <= '1'; + WAIT FOR c_clk_period; + in_sop <= '0'; + WAIT FOR c_block_size*c_clk_period; + END LOOP; + tb_end <= '1'; WAIT; END PROCESS; @@ -167,17 +227,26 @@ BEGIN clip_odd <= v_clip_odd; -- show in wave window (only cycle late) -- compare pair IF tb_end = '0' THEN - IF v_even /= -v_odd THEN - IF NOT (v_clip_even = '1') THEN - IF NOT (v_clip_odd = '1') THEN - REPORT "Wrong negate value" SEVERITY ERROR; - END IF; - END IF; + IF verify_en = '1' THEN + IF v_even /= -1 * v_odd THEN + IF NOT (v_clip_even = '1') THEN + IF NOT (v_clip_odd = '1') THEN + REPORT "Wrong negate value at valid (v_even = " & int_to_str(v_even) & " v_odd = " & int_to_str(v_odd) SEVERITY ERROR; + END IF; + END IF; + END IF; END IF; ELSE + -- Verify expected number of clip_even (when in_sop is at even) and clip_odd (when in_sop is at odd) + ASSERT cnt_even = 4 REPORT "Wrong number of expected clipped c_min to c_max at even index" SEVERITY ERROR; + ASSERT cnt_odd = 12 REPORT "Wrong number of expected clipped c_min to c_max at odd index" SEVERITY ERROR; WAIT; END IF; END PROCESS; - + + -- Count number of clip_even and clip_odd + cnt_even <= cnt_even + 1 WHEN rising_edge(clk) AND clip_even = '1'; + cnt_odd <= cnt_odd + 1 WHEN rising_edge(clk) AND clip_odd = '1'; + END tb;