diff --git a/libraries/base/common/hdllib.cfg b/libraries/base/common/hdllib.cfg index 507266e0ecca3abf8a42762d4ac1ba85ce4a7258..6a8deef3b0251bc4dc8d5a8401c9b93e470c8ff9 100644 --- a/libraries/base/common/hdllib.cfg +++ b/libraries/base/common/hdllib.cfg @@ -197,6 +197,7 @@ test_bench_files = tb/vhdl/tb_mms_common_variable_delay.vhd tb/vhdl/tb_tb_resize.vhd + tb/vhdl/tb_tb_round.vhd tb/vhdl/tb_tb_common_add_sub.vhd tb/vhdl/tb_tb_common_adder_tree.vhd tb/vhdl/tb_tb_common_fanout_tree.vhd @@ -220,7 +221,7 @@ regression_test_vhdl = tb/vhdl/tb_common_transpose_symbol.vhd tb/vhdl/tb_common_variable_delay.vhd tb/vhdl/tb_tb_resize.vhd - #tb/vhdl/tb_round.vhd -- has no self verification yet + tb/vhdl/tb_tb_round.vhd tb/vhdl/tb_requantize.vhd tb/vhdl/tb_common_to_sreal.vhd tb/vhdl/tb_common_pulse_delay.vhd diff --git a/libraries/base/common/tb/vhdl/tb_round.vhd b/libraries/base/common/tb/vhdl/tb_round.vhd index 5d63ec8dd1ca72fa3cd65f44065794bb370faad4..ee7235dc9348041c85f75f70c3ccb9647913ff76 100644 --- a/libraries/base/common/tb/vhdl/tb_round.vhd +++ b/libraries/base/common/tb/vhdl/tb_round.vhd @@ -40,7 +40,7 @@ USE work.common_pkg.ALL; ENTITY tb_round IS GENERIC ( - g_in_dat_w : NATURAL := 5; + g_in_dat_w : NATURAL := 4; g_out_dat_w : NATURAL := 3 ); END tb_round; @@ -53,20 +53,27 @@ ARCHITECTURE tb OF tb_round IS CONSTANT c_pipeline_output : NATURAL := 0; CONSTANT c_pipeline : NATURAL := c_pipeline_input + c_pipeline_output; - CONSTANT c_round_w : NATURAL := g_in_dat_w - g_out_dat_w; + CONSTANT c_round_w : INTEGER := g_in_dat_w - g_out_dat_w; - CONSTANT c_in_smax : INTEGER := 2**(g_in_dat_w-1) - 1; - CONSTANT c_in_smin : INTEGER := -2**(g_in_dat_w-1); - CONSTANT c_in_half : INTEGER := 2**(c_round_w-1); - CONSTANT c_in_umax : INTEGER := 2**g_in_dat_w - 1; - CONSTANT c_in_umax_no_clip : INTEGER := c_in_umax - c_in_half; + -- Expected rounded results from [2] for w = g_in_dat_w = 4 and r = c_round_w = 1 + CONSTANT c_exp_w4_r1_signed_truncate : t_integer_arr(0 TO 15) := (-4, -4, -3, -3, -2, -2, -1, -1, 0, 0, 1, 1, 2, 2, 3, 3); + CONSTANT c_exp_w4_r1_signed_round_half_away : t_integer_arr(0 TO 15) := (-4, -4, -3, -3, -2, -2, -1, -1, 0, 1, 1, 2, 2, 3, 3, -4); + CONSTANT c_exp_w4_r1_signed_round_half_away_clip : t_integer_arr(0 TO 15) := (-4, -4, -3, -3, -2, -2, -1, -1, 0, 1, 1, 2, 2, 3, 3, 3); + CONSTANT c_exp_w4_r1_signed_round_half_even : t_integer_arr(0 TO 15) := (-4, -4, -3, -2, -2, -2, -1, 0, 0, 0, 1, 2, 2, 2, 3, -4); + CONSTANT c_exp_w4_r1_signed_round_half_even_clip : t_integer_arr(0 TO 15) := (-4, -4, -3, -2, -2, -2, -1, 0, 0, 0, 1, 2, 2, 2, 3, 3); + + CONSTANT c_exp_w4_r1_unsigned_truncate : t_natural_arr(0 TO 15) := (0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7); + CONSTANT c_exp_w4_r1_unsigned_round_half_up : t_natural_arr(0 TO 15) := (0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 0); + CONSTANT c_exp_w4_r1_unsigned_round_half_up_clip : t_natural_arr(0 TO 15) := (0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 7); + CONSTANT c_exp_w4_r1_unsigned_round_half_even : t_natural_arr(0 TO 15) := (0, 0, 1, 2, 2, 2, 3, 4, 4, 4, 5, 6, 6, 6, 7, 0); + CONSTANT c_exp_w4_r1_unsigned_round_half_even_clip : t_natural_arr(0 TO 15) := (0, 0, 1, 2, 2, 2, 3, 4, 4, 4, 5, 6, 6, 6, 7, 7); -- Expected rounded results from [2] for w = g_in_dat_w = 5 and r = c_round_w = 2 - CONSTANT c_exp_w5_r2_signed_truncate : t_integer_arr(0 TO 31) := (-4, -4, -4, -4, -3, -3, -3, -3, -2, -2, -2, -2, -1, -1, -1, -1, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3); - CONSTANT c_exp_w5_r2_signed_round_half_away : t_integer_arr(0 TO 31) := (-4, -4, -4, -3, -3, -3, -3, -2, -2, -2, -2, -1, -1, -1, -1, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, -4, -4); - CONSTANT c_exp_w5_r2_signed_round_half_away_clip : t_integer_arr(0 TO 31) := (-4, -4, -4, -3, -3, -3, -3, -2, -2, -2, -2, -1, -1, -1, -1, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3); - CONSTANT c_exp_w5_r2_signed_round_half_even : t_integer_arr(0 TO 31) := (-4, -4, -4, -3, -3, -3, -2, -2, -2, -2, -2, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, -4, -4); - CONSTANT c_exp_w5_r2_signed_round_half_even_clip : t_integer_arr(0 TO 31) := (-4, -4, -4, -3, -3, -3, -2, -2, -2, -2, -2, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3); + CONSTANT c_exp_w5_r2_signed_truncate : t_integer_arr(0 TO 31) := (-4, -4, -4, -4, -3, -3, -3, -3, -2, -2, -2, -2, -1, -1, -1, -1, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3); + CONSTANT c_exp_w5_r2_signed_round_half_away : t_integer_arr(0 TO 31) := (-4, -4, -4, -3, -3, -3, -3, -2, -2, -2, -2, -1, -1, -1, -1, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, -4, -4); + CONSTANT c_exp_w5_r2_signed_round_half_away_clip : t_integer_arr(0 TO 31) := (-4, -4, -4, -3, -3, -3, -3, -2, -2, -2, -2, -1, -1, -1, -1, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3); + CONSTANT c_exp_w5_r2_signed_round_half_even : t_integer_arr(0 TO 31) := (-4, -4, -4, -3, -3, -3, -2, -2, -2, -2, -2, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, -4, -4); + CONSTANT c_exp_w5_r2_signed_round_half_even_clip : t_integer_arr(0 TO 31) := (-4, -4, -4, -3, -3, -3, -2, -2, -2, -2, -2, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3); CONSTANT c_exp_w5_r2_unsigned_truncate : t_natural_arr(0 TO 31) := (0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7); CONSTANT c_exp_w5_r2_unsigned_truncate_symmetric : t_natural_arr(0 TO 31) := (0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7); @@ -75,6 +82,7 @@ ARCHITECTURE tb OF tb_round IS CONSTANT c_exp_w5_r2_unsigned_round_half_even : t_natural_arr(0 TO 31) := (0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 0, 0); CONSTANT c_exp_w5_r2_unsigned_round_half_even_clip : t_natural_arr(0 TO 31) := (0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7); + SIGNAL tb_end : STD_LOGIC := '0'; SIGNAL clk : STD_LOGIC := '1'; @@ -93,12 +101,20 @@ ARCHITECTURE tb OF tb_round IS SIGNAL fs_signed_round_half_even : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0); SIGNAL fs_signed_round_half_even_clip : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0); + SIGNAL S_w4_r1 : NATURAL; -- lookup index for signed + SIGNAL exp_w4_r1_signed_truncate : INTEGER; + SIGNAL exp_w4_r1_signed_round_half_away : INTEGER; + SIGNAL exp_w4_r1_signed_round_half_away_clip : INTEGER; + SIGNAL exp_w4_r1_signed_round_half_even : INTEGER; + SIGNAL exp_w4_r1_signed_round_half_even_clip : INTEGER; + SIGNAL S_w5_r2 : NATURAL; -- lookup index for signed SIGNAL exp_w5_r2_signed_truncate : INTEGER; SIGNAL exp_w5_r2_signed_round_half_away : INTEGER; SIGNAL exp_w5_r2_signed_round_half_away_clip : INTEGER; SIGNAL exp_w5_r2_signed_round_half_even : INTEGER; SIGNAL exp_w5_r2_signed_round_half_even_clip : INTEGER; + -- . show as real in Wave window SIGNAL fs_sreal_fixed_point : REAL := 0.0; SIGNAL fs_sreal_truncate : REAL := 0.0; @@ -116,6 +132,13 @@ ARCHITECTURE tb OF tb_round IS SIGNAL fs_unsigned_round_half_even : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0); SIGNAL fs_unsigned_round_half_even_clip : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0); + SIGNAL U_w4_r1 : NATURAL; -- lookup index for unsigned + SIGNAL exp_w4_r1_unsigned_truncate : INTEGER; + SIGNAL exp_w4_r1_unsigned_round_half_up : INTEGER; + SIGNAL exp_w4_r1_unsigned_round_half_up_clip : INTEGER; + SIGNAL exp_w4_r1_unsigned_round_half_even : INTEGER; + SIGNAL exp_w4_r1_unsigned_round_half_even_clip : INTEGER; + SIGNAL U_w5_r2 : NATURAL; -- lookup index for unsigned SIGNAL exp_w5_r2_unsigned_truncate : INTEGER; SIGNAL exp_w5_r2_unsigned_round_half_up : INTEGER; @@ -126,18 +149,11 @@ ARCHITECTURE tb OF tb_round IS -- . show as real in Wave window SIGNAL fs_ureal_fixed_point : REAL := 0.0; SIGNAL fs_ureal_truncate : REAL := 0.0; - SIGNAL fs_ureal_round_half_away : REAL := 0.0; - SIGNAL fs_ureal_round_half_away_clip : REAL := 0.0; + SIGNAL fs_ureal_round_half_up : REAL := 0.0; + SIGNAL fs_ureal_round_half_up_clip : REAL := 0.0; SIGNAL fs_ureal_round_half_even : REAL := 0.0; SIGNAL fs_ureal_round_half_even_clip : REAL := 0.0; - -- Debug signals, for view in Wave window - SIGNAL dbg_c_exp_w5_r2_signed_truncate : t_integer_arr(0 TO 31) := c_exp_w5_r2_signed_truncate; - SIGNAL dbg_c_exp_w5_r2_signed_round_half_away : t_integer_arr(0 TO 31) := c_exp_w5_r2_signed_round_half_away; - SIGNAL dbg_c_exp_w5_r2_signed_round_half_away_clip : t_integer_arr(0 TO 31) := c_exp_w5_r2_signed_round_half_away_clip; - SIGNAL dbg_c_exp_w5_r2_signed_round_half_even : t_integer_arr(0 TO 31) := c_exp_w5_r2_signed_round_half_even; - SIGNAL dbg_c_exp_w5_r2_signed_round_half_even_clip : t_integer_arr(0 TO 31) := c_exp_w5_r2_signed_round_half_even_clip; - BEGIN -- Stimuli @@ -354,19 +370,32 @@ BEGIN -- . unsigned fs_ureal_fixed_point <= TO_UREAL(fs_unsigned_integer, c_round_w); fs_ureal_truncate <= TO_UREAL(fs_unsigned_truncate, 0); - fs_ureal_round_half_away <= TO_UREAL(fs_unsigned_round_half_up, 0); - fs_ureal_round_half_away_clip <= TO_UREAL(fs_unsigned_round_half_up_clip, 0); + fs_ureal_round_half_up <= TO_UREAL(fs_unsigned_round_half_up, 0); + fs_ureal_round_half_up_clip <= TO_UREAL(fs_unsigned_round_half_up_clip, 0); fs_ureal_round_half_even <= TO_UREAL(fs_unsigned_round_half_even, 0); fs_ureal_round_half_even_clip <= TO_UREAL(fs_unsigned_round_half_even_clip, 0); -- Expected rounded values - S_w5_r2 <= (TO_UINT(in_dat) + 16) MOD 32; + S_w4_r1 <= (TO_UINT(in_dat) + 8) MOD 16; -- 2**4 = 16 + exp_w4_r1_signed_truncate <= c_exp_w4_r1_signed_truncate(S_w4_r1); + exp_w4_r1_signed_round_half_away <= c_exp_w4_r1_signed_round_half_away(S_w4_r1); + exp_w4_r1_signed_round_half_away_clip <= c_exp_w4_r1_signed_round_half_away_clip(S_w4_r1); + exp_w4_r1_signed_round_half_even <= c_exp_w4_r1_signed_round_half_even(S_w4_r1); + exp_w4_r1_signed_round_half_even_clip <= c_exp_w4_r1_signed_round_half_even_clip(S_w4_r1); + U_w4_r1 <= TO_UINT(in_dat) MOD 16; + exp_w4_r1_unsigned_truncate <= c_exp_w4_r1_unsigned_truncate(U_w4_r1); + exp_w4_r1_unsigned_round_half_up <= c_exp_w4_r1_unsigned_round_half_up(U_w4_r1); + exp_w4_r1_unsigned_round_half_up_clip <= c_exp_w4_r1_unsigned_round_half_up_clip(U_w4_r1); + exp_w4_r1_unsigned_round_half_even <= c_exp_w4_r1_unsigned_round_half_even(U_w4_r1); + exp_w4_r1_unsigned_round_half_even_clip <= c_exp_w4_r1_unsigned_round_half_even_clip(U_w4_r1); + + S_w5_r2 <= (TO_UINT(in_dat) + 16) MOD 32; -- 2**5 = 32 exp_w5_r2_signed_truncate <= c_exp_w5_r2_signed_truncate(S_w5_r2); exp_w5_r2_signed_round_half_away <= c_exp_w5_r2_signed_round_half_away(S_w5_r2); exp_w5_r2_signed_round_half_away_clip <= c_exp_w5_r2_signed_round_half_away_clip(S_w5_r2); exp_w5_r2_signed_round_half_even <= c_exp_w5_r2_signed_round_half_even(S_w5_r2); exp_w5_r2_signed_round_half_even_clip <= c_exp_w5_r2_signed_round_half_even_clip(S_w5_r2); - U_w5_r2 <= TO_UINT(in_dat); + U_w5_r2 <= TO_UINT(in_dat) MOD 32; exp_w5_r2_unsigned_truncate <= c_exp_w5_r2_unsigned_truncate(U_w5_r2); exp_w5_r2_unsigned_round_half_up <= c_exp_w5_r2_unsigned_round_half_up(U_w5_r2); exp_w5_r2_unsigned_round_half_up_clip <= c_exp_w5_r2_unsigned_round_half_up_clip(U_w5_r2); @@ -378,7 +407,7 @@ BEGIN BEGIN WAIT UNTIL rising_edge(clk); IF reg_val = '1' THEN - IF c_round_w = 0 THEN + IF c_round_w <= 0 THEN -- Without rounding the expected value is same as input value -- . signed ASSERT SIGNED(fs_signed_truncate ) = SIGNED(reg_dat) REPORT "Wrong wired fs_signed_truncate" SEVERITY ERROR; @@ -394,6 +423,20 @@ BEGIN ASSERT UNSIGNED(fs_unsigned_round_half_even_clip) = UNSIGNED(reg_dat) REPORT "Wrong wired fs_unsigned_round_half_even_clip" SEVERITY ERROR; ELSE -- With rounding then compare with expected list of values from common_round_tb.py + IF g_in_dat_w = 4 AND c_round_w = 1 THEN + -- . signed + ASSERT SIGNED(fs_signed_truncate ) = exp_w4_r1_signed_truncate REPORT "Wrong exp_w4_r1_signed_truncate" SEVERITY ERROR; + ASSERT SIGNED(fs_signed_round_half_away ) = exp_w4_r1_signed_round_half_away REPORT "Wrong exp_w4_r1_signed_round_half_away" SEVERITY ERROR; + ASSERT SIGNED(fs_signed_round_half_away_clip) = exp_w4_r1_signed_round_half_away_clip REPORT "Wrong exp_w4_r1_signed_round_half_away_clip" SEVERITY ERROR; + ASSERT SIGNED(fs_signed_round_half_even ) = exp_w4_r1_signed_round_half_even REPORT "Wrong exp_w4_r1_signed_round_half_even" SEVERITY ERROR; + ASSERT SIGNED(fs_signed_round_half_even_clip) = exp_w4_r1_signed_round_half_even_clip REPORT "Wrong exp_w4_r1_signed_round_half_even_clip" SEVERITY ERROR; + -- . unsigned + ASSERT UNSIGNED(fs_unsigned_truncate ) = exp_w4_r1_unsigned_truncate REPORT "Wrong exp_w4_r1_unsigned_truncate" SEVERITY ERROR; + ASSERT UNSIGNED(fs_unsigned_round_half_up ) = exp_w4_r1_unsigned_round_half_up REPORT "Wrong exp_w4_r1_unsigned_round_half_up" SEVERITY ERROR; + ASSERT UNSIGNED(fs_unsigned_round_half_up_clip ) = exp_w4_r1_unsigned_round_half_up_clip REPORT "Wrong exp_w4_r1_unsigned_round_half_up_clip" SEVERITY ERROR; + ASSERT UNSIGNED(fs_unsigned_round_half_even ) = exp_w4_r1_unsigned_round_half_even REPORT "Wrong exp_w4_r1_unsigned_round_half_even" SEVERITY ERROR; + ASSERT UNSIGNED(fs_unsigned_round_half_even_clip) = exp_w4_r1_unsigned_round_half_even_clip REPORT "Wrong exp_w4_r1_unsigned_round_half_even_clip" SEVERITY ERROR; + END IF; IF g_in_dat_w = 5 AND c_round_w = 2 THEN -- . signed ASSERT SIGNED(fs_signed_truncate ) = exp_w5_r2_signed_truncate REPORT "Wrong exp_w5_r2_signed_truncate" SEVERITY ERROR;