diff --git a/libraries/dsp/rTwoSDF/src/vhdl/rTwoSDF.vhd b/libraries/dsp/rTwoSDF/src/vhdl/rTwoSDF.vhd index 06745606030856de10906904dfed7e2d5dd76837..feaaa25f8c9cc5948cfd4f8742fa9600912eda48 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 8f40621d13484cb722656eb52109340eafd64de4..389aca4cd7e11836ed355d843ebb4aab0a4e9ebb 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 ead344fece9b262abc3641dabb2795592cf2041c..a508eda63d047b44df34e3ed4c2896216e114c69 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 4a008c8871d91f44fe6fc1b201fe878f6b244484..48c5eabc7536184dd6654a51b75feb74347e9b22 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,