Skip to content
Snippets Groups Projects
Commit 7054457c authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Use c_switch_dat_w = g_fft.in_dat_w + 1 to fit negate of most negative input value.

parent 0dfe6b5b
No related branches found
No related tags found
1 merge request!205Added g_sepa_switch_en to support mitigation of quantization noise crosstalk...
......@@ -63,8 +63,7 @@ entity fft_r2_pipe is
g_pipeline : t_fft_pipeline := c_fft_pipeline; -- generics for pipelining in each stage, defined in rTwoSDF_lib.rTwoSDFPkg
g_dont_flip_channels : boolean := false; -- generic to prevent re-ordering of the channels
g_r2_mul_extra_w : natural := 0; -- extra bits at rTwoWMul output in rTwoSDFStage to improve rTwoSDFStage output requantization
g_sepa_extra_w : natural := 0; -- extra LSbits in output of last rTwoSDFStage to improve two real separate requantization
g_sepa_switch_en : boolean := false -- when true apply switch/unswitch to two real inputs to mitigate quantization crosstalk
g_sepa_extra_w : natural := 0 -- extra LSbits in output of last rTwoSDFStage to improve two real separate requantization
);
port (
clk : in std_logic;
......@@ -82,22 +81,28 @@ architecture str of fft_r2_pipe is
constant c_pipeline_remove_lsb : natural := 0;
constant c_switch_en : boolean := g_fft.use_separate; -- default do apply switch/unswitch per real input to mitigate quantization crosstalk
constant c_switch_sz_w : natural := ceil_log2(g_fft.nof_points) + g_fft.nof_chan;
constant c_switch_dat_w : natural := g_fft.in_dat_w + 1; -- add 1 extra bit to fit negation of most negative value per real input switch function
constant c_unswitch_dat_w : natural := g_fft.out_dat_w; -- no need for extra bit, because most negative value cannot occur in output
constant c_nof_stages : natural := ceil_log2(g_fft.nof_points);
constant c_stage_offset : natural := true_log2(g_fft.wb_factor); -- Stage offset is required for twiddle generation in wideband fft
constant c_in_scale_w : natural := g_fft.stage_dat_w - g_fft.in_dat_w - sel_a_b(g_fft.guard_enable, g_fft.guard_w, 0);
constant c_out_scale_w : integer := g_fft.stage_dat_w - g_fft.out_dat_w - g_fft.out_gain_w; -- Estimate number of LSBs to throw throw away when > 0 or insert when < 0
constant c_raw_dat_extra_w : natural := sel_a_b(g_fft.use_separate, g_sepa_extra_w, 0);
constant c_raw_dat_w : natural := g_fft.stage_dat_w + c_raw_dat_extra_w;
constant c_sepa_mitigate : std_logic := sel_a_b(g_fft.use_separate, '1', '0'); -- apply switch/unswitch to two real inputs to mitigate quantization crosstalk
constant c_switch_en : std_logic := sel_a_b(g_sepa_switch_en, c_sepa_mitigate, '0');
-- number the stage instances from c_nof_stages:1
-- . the data input for the first stage has index c_nof_stages
-- . the data output of the last stage has index 0
type t_data_arr is array(c_nof_stages downto 0) of std_logic_vector(g_fft.stage_dat_w-1 downto 0);
signal switch_re : std_logic_vector(g_fft.in_dat_w-1 downto 0);
signal switch_im : std_logic_vector(g_fft.in_dat_w-1 downto 0);
signal in_dat_re : std_logic_vector(c_switch_dat_w-1 downto 0);
signal in_dat_im : std_logic_vector(c_switch_dat_w-1 downto 0);
signal in_dat_val : std_logic;
signal switch_re : std_logic_vector(c_switch_dat_w-1 downto 0);
signal switch_im : std_logic_vector(c_switch_dat_w-1 downto 0);
signal switch_val : std_logic;
signal data_re : t_data_arr;
......@@ -123,16 +128,21 @@ begin
-- the inputs per lock in a random pattern, when g_fft.use_separate = TRUE.
------------------------------------------------------------------------------
-- Inputs
in_dat_re <= RESIZE_SVEC(in_re, c_switch_dat_w);
in_dat_im <= RESIZE_SVEC(in_im, c_switch_dat_w);
in_dat_val <= in_val;
u_switch : ENTITY work.fft_switch
GENERIC MAP (
g_fft_sz_w => ceil_log2(g_fft.nof_points),
g_dat_w => g_fft.in_dat_w
g_switch_en => c_switch_en,
g_fft_sz_w => c_switch_sz_w,
g_dat_w => c_switch_dat_w
)
PORT MAP (
in_re => in_re,
in_im => in_im,
in_val => in_val,
switch_en => c_switch_en,
in_re => in_dat_re,
in_im => in_dat_im,
in_val => in_dat_val,
out_re => switch_re,
out_im => switch_im,
out_val => switch_val,
......@@ -140,7 +150,6 @@ begin
rst => rst
);
-- Inputs
data_re( c_nof_stages) <= scale_and_resize_svec(switch_re, c_in_scale_w, g_fft.stage_dat_w);
data_im( c_nof_stages) <= scale_and_resize_svec(switch_im, c_in_scale_w, g_fft.stage_dat_w);
data_val(c_nof_stages) <= switch_val;
......@@ -188,12 +197,11 @@ begin
in_re => data_re(1),
in_im => data_im(1),
in_val => data_val(1),
out_re => last_re,
out_im => last_im,
out_re => last_re, -- = data_re(0), but may instead have c_raw_dat_w bits
out_im => last_im, -- = data_im(0), but may instead have c_raw_dat_w bits
out_val => data_val(0)
);
------------------------------------------------------------------------------
-- Optional output reorder and separation
------------------------------------------------------------------------------
......@@ -287,14 +295,14 @@ begin
-- Undo input random negation of u_switch at output when g_fft.use_separate = TRUE
u_unswitch : ENTITY work.fft_unswitch
GENERIC MAP (
g_fft_sz_w => ceil_log2(g_fft.nof_points),
g_dat_w => g_fft.out_dat_w
g_switch_en => c_switch_en,
g_fft_sz_w => c_switch_sz_w,
g_dat_w => c_unswitch_dat_w
)
PORT MAP (
in_re => quant_re,
in_im => quant_im,
in_val => quant_val,
switch_en => c_switch_en,
out_re => out_re,
out_im => out_im,
out_val => out_val,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment