From 1649713a0ad79684da5ca2152a12c1bc47f41995 Mon Sep 17 00:00:00 2001 From: Eric Kooistra <kooistra@astron.nl> Date: Fri, 8 Apr 2022 13:53:09 +0200 Subject: [PATCH] Support g_round_even. Default g_round_even = true. --- libraries/dsp/rTwoSDF/src/vhdl/rTwoSDF.vhd | 8 ++- .../dsp/rTwoSDF/src/vhdl/rTwoSDFStage.vhd | 14 +++-- libraries/dsp/rTwoSDF/src/vhdl/rTwoWMul.vhd | 53 +++++++++++++++---- libraries/dsp/rTwoSDF/tb/vhdl/tb_rTwoSDF.vhd | 3 +- 4 files changed, 59 insertions(+), 19 deletions(-) diff --git a/libraries/dsp/rTwoSDF/src/vhdl/rTwoSDF.vhd b/libraries/dsp/rTwoSDF/src/vhdl/rTwoSDF.vhd index 0674560603..feaaa25f8c 100644 --- a/libraries/dsp/rTwoSDF/src/vhdl/rTwoSDF.vhd +++ b/libraries/dsp/rTwoSDF/src/vhdl/rTwoSDF.vhd @@ -43,6 +43,7 @@ entity rTwoSDF is g_stage_dat_w : natural := 18; -- number of bits used between the stages g_guard_w : natural := 2; -- guard bits are used to avoid overflow in single FFT stage. g_nof_points : natural := 1024; -- N point FFT + g_round_even : boolean := true; -- generics for rTwoSDFStage g_pipeline : t_fft_pipeline := c_fft_pipeline ); @@ -104,6 +105,7 @@ begin g_stage_offset => c_stage_offset, g_twiddle_offset => c_twiddle_offset, g_scale_enable => sel_a_b(stage <= g_guard_w, FALSE, TRUE), -- On average all stages have a gain factor of 2 therefore each stage needs to round 1 bit except for the last g_guard_w nof stages due to the input c_in_scale_w + g_round_even => g_round_even, g_pipeline => g_pipeline ) port map ( @@ -157,7 +159,8 @@ begin g_representation => "SIGNED", g_lsb_w => c_out_scale_w, g_lsb_round => TRUE, - g_lsb_round_clip => FALSE, + g_lsb_round_clip => FALSE, + g_lsb_round_even => g_round_even, g_msb_clip => FALSE, g_msb_clip_symmetric => FALSE, g_pipeline_remove_lsb => 0, @@ -179,7 +182,8 @@ begin g_lsb_w => c_out_scale_w, g_lsb_round => TRUE, g_lsb_round_clip => FALSE, - g_msb_clip => FALSE, + g_lsb_round_even => g_round_even, + g_msb_clip => FALSE, g_msb_clip_symmetric => FALSE, g_pipeline_remove_lsb => 0, g_pipeline_remove_msb => 0, diff --git a/libraries/dsp/rTwoSDF/src/vhdl/rTwoSDFStage.vhd b/libraries/dsp/rTwoSDF/src/vhdl/rTwoSDFStage.vhd index 8f40621d13..389aca4cd7 100644 --- a/libraries/dsp/rTwoSDF/src/vhdl/rTwoSDFStage.vhd +++ b/libraries/dsp/rTwoSDF/src/vhdl/rTwoSDFStage.vhd @@ -31,7 +31,8 @@ entity rTwoSDFStage is g_stage : natural := 8; g_stage_offset : natural := 0; -- The Stage offset: 0 for normal FFT. Other than 0 in wideband FFT g_twiddle_offset : natural := 0; -- The twiddle offset: 0 for normal FFT. Other than 0 in wideband FFT - g_scale_enable : boolean := TRUE; -- + g_scale_enable : boolean := TRUE; + g_round_even : boolean := TRUE; g_pipeline : t_fft_pipeline := c_fft_pipeline -- internal pipeline settings ); port ( @@ -146,8 +147,9 @@ begin ------------------------------------------------------------------------------ u_TwiddleMult: entity work.rTwoWMul generic map ( - g_stage => g_stage, - g_lat => g_pipeline.mul_lat + g_stage => g_stage, + g_round_even => g_round_even, + g_lat => g_pipeline.mul_lat ) port map ( clk => clk, @@ -171,7 +173,8 @@ begin g_representation => "SIGNED", g_lsb_w => c_r2_stage_bit_growth, g_lsb_round => TRUE, - g_lsb_round_clip => FALSE, + g_lsb_round_clip => FALSE, + g_lsb_round_even => g_round_even, g_msb_clip => FALSE, g_msb_clip_symmetric => FALSE, g_pipeline_remove_lsb => 0, @@ -193,7 +196,8 @@ begin g_lsb_w => c_r2_stage_bit_growth, g_lsb_round => TRUE, g_lsb_round_clip => FALSE, - g_msb_clip => FALSE, + g_lsb_round_even => g_round_even, + g_msb_clip => FALSE, g_msb_clip_symmetric => FALSE, g_pipeline_remove_lsb => 0, g_pipeline_remove_msb => 0, diff --git a/libraries/dsp/rTwoSDF/src/vhdl/rTwoWMul.vhd b/libraries/dsp/rTwoSDF/src/vhdl/rTwoWMul.vhd index ead344fece..a508eda63d 100644 --- a/libraries/dsp/rTwoSDF/src/vhdl/rTwoWMul.vhd +++ b/libraries/dsp/rTwoSDF/src/vhdl/rTwoWMul.vhd @@ -29,6 +29,7 @@ entity rTwoWMul is generic ( g_technology : NATURAL := c_tech_select_default; g_stage : natural := 1; + g_round_even : boolean := true; g_lat : natural := 3+1 -- 3 for mult, 1 for round ); port ( @@ -184,17 +185,47 @@ begin gen_sround : if c_use_truncate=false GENERATE - -- Use resize_svec(s_round()) instead of truncate_and_resize_svec() to have symmetrical rounding around 0 - -- Rounding takes logic due to adding 0.5 therefore need to use c_round_lat=1 to achieve timing - gen_comb : if c_round_lat=0 generate - ASSERT false REPORT "rTwoWMul: can probably not achieve timing for sround without pipeline" SEVERITY FAILURE; - round_re <= RESIZE_SVEC(s_round(product_re, c_round_w), c_out_dat_w); - round_im <= RESIZE_SVEC(s_round(product_im, c_round_w), c_out_dat_w); - end generate; - gen_reg : if c_round_lat=1 generate - round_re <= RESIZE_SVEC(s_round(product_re, c_round_w), c_out_dat_w) when rising_edge(clk); - round_im <= RESIZE_SVEC(s_round(product_im, c_round_w), c_out_dat_w) when rising_edge(clk); - end generate; + u_requantize_re : entity common_lib.common_requantize + generic map ( + g_representation => "SIGNED", + g_lsb_w => c_round_w, + g_lsb_round => TRUE, + g_lsb_round_clip => FALSE, + g_lsb_round_even => g_round_even, + g_msb_clip => FALSE, + g_msb_clip_symmetric => FALSE, + g_pipeline_remove_lsb => c_round_lat, + g_pipeline_remove_msb => 0, + g_in_dat_w => c_prod_w, + g_out_dat_w => c_out_dat_w + ) + port map ( + clk => clk, + in_dat => product_re, + out_dat => round_re, + out_ovr => open + ); + + u_requantize_im : entity common_lib.common_requantize + generic map ( + g_representation => "SIGNED", + g_lsb_w => c_round_w, + g_lsb_round => TRUE, + g_lsb_round_clip => FALSE, + g_lsb_round_even => g_round_even, + g_msb_clip => FALSE, + g_msb_clip_symmetric => FALSE, + g_pipeline_remove_lsb => c_round_lat, + g_pipeline_remove_msb => 0, + g_in_dat_w => c_prod_w, + g_out_dat_w => c_out_dat_w + ) + port map ( + clk => clk, + in_dat => product_im, + out_dat => round_im, + out_ovr => open + ); end generate; diff --git a/libraries/dsp/rTwoSDF/tb/vhdl/tb_rTwoSDF.vhd b/libraries/dsp/rTwoSDF/tb/vhdl/tb_rTwoSDF.vhd index 4a008c8871..48c5eabc75 100644 --- a/libraries/dsp/rTwoSDF/tb/vhdl/tb_rTwoSDF.vhd +++ b/libraries/dsp/rTwoSDF/tb/vhdl/tb_rTwoSDF.vhd @@ -268,7 +268,8 @@ begin g_out_dat_w => g_out_dat_w, g_stage_dat_w => c_stage_dat_w, g_guard_w => g_guard_w, - g_nof_points => g_nof_points + g_nof_points => g_nof_points, + g_round_even => false -- golden results use round half ) port map( clk => clk, -- GitLab