diff --git a/libraries/dsp/fft/src/vhdl/fft_lfsr.vhd b/libraries/dsp/fft/src/vhdl/fft_lfsr.vhd index 56f5b5e453f9a2e009a05c2418f6890ee6aa22e3..7f53b0a398f8dddef39cc056eb7225767d53362b 100644 --- a/libraries/dsp/fft/src/vhdl/fft_lfsr.vhd +++ b/libraries/dsp/fft/src/vhdl/fft_lfsr.vhd @@ -21,12 +21,20 @@ -- Author: ported by E. Kooistra, original 2004 by W. Lubberhuizen / W. Poeisz -- Purpose: Scramble quantization noise crosstalk between two real inputs -- Description: Ported from LOFAR1, see readme_lofar1.txt --- Remark: Copy from applications/lofar1/RSP/pft2/src/vhdl/pft_lfsr.vhd +-- Remark: +-- . Copy from applications/lofar1/RSP/pft2/src/vhdl/pft_lfsr.vhd +-- . The g_seed must be > 0 for LFSR period is 2**c_fft_lfsr_len - 1. Value +-- g_seed = 0 causes the LFSR to remain stuck at 0. LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; +USE work.fft_pkg.ALL; ENTITY fft_lfsr IS + GENERIC ( + g_seed1 : STD_LOGIC_VECTOR(c_fft_lfsr_len-1 DOWNTO 0) := c_fft_switch_seed1; + g_seed2 : STD_LOGIC_VECTOR(c_fft_lfsr_len-1 DOWNTO 0) := c_fft_switch_seed2 + ); PORT ( in_en : IN STD_LOGIC; out_bit1 : OUT STD_LOGIC; @@ -43,23 +51,23 @@ ARCHITECTURE rtl OF fft_lfsr IS -- x^41 + x^20 + 1 and x^41 + x^3 + 1 -- see XAPP217 - CONSTANT c_max : NATURAL := 41; + CONSTANT c_len : NATURAL := c_fft_lfsr_len; -- = 41, same for both trinomials CONSTANT c1 : NATURAL := 20; CONSTANT c2 : NATURAL := 3; - SIGNAL s1 : STD_LOGIC_VECTOR(c_max-1 DOWNTO 0); - SIGNAL nxt_s1 : STD_LOGIC_VECTOR(c_max-1 DOWNTO 0); - - SIGNAL s2 : STD_LOGIC_VECTOR(c_max-1 DOWNTO 0); - SIGNAL nxt_s2 : STD_LOGIC_VECTOR(c_max-1 DOWNTO 0); - + SIGNAL s1 : STD_LOGIC_VECTOR(c_len-1 DOWNTO 0); + SIGNAL nxt_s1 : STD_LOGIC_VECTOR(c_len-1 DOWNTO 0); + SIGNAL s2 : STD_LOGIC_VECTOR(c_len-1 DOWNTO 0); + SIGNAL nxt_s2 : STD_LOGIC_VECTOR(c_len-1 DOWNTO 0); + BEGIN + p_reg : PROCESS(rst,clk) BEGIN IF rst='1' THEN - s1 <= "01000101011101110101001011111000101100001"; - s2 <= "11011001000101001011011001110101100101100"; + s1 <= g_seed1; + s2 <= g_seed2; ELSIF rising_edge(clk) THEN s1 <= nxt_s1; s2 <= nxt_s2; @@ -69,22 +77,22 @@ BEGIN out_bit1 <= s1(s1'HIGH); out_bit2 <= s2(s2'HIGH); - p_seed : PROCESS(in_en,s1,s2) + p_seed : PROCESS(in_en, s1, s2) BEGIN nxt_s1 <= s1; nxt_s2 <= s2; - IF in_en='1' THEN + IF in_en = '1' THEN -- shift - nxt_s1(c_max-1 DOWNTO 1) <= s1(c_max-2 DOWNTO 0); - nxt_s2(c_max-1 DOWNTO 1) <= s2(c_max-2 DOWNTO 0); + nxt_s1(c_len-1 DOWNTO 1) <= s1(c_len-2 DOWNTO 0); + nxt_s2(c_len-1 DOWNTO 1) <= s2(c_len-2 DOWNTO 0); -- feedback 1 - nxt_s1(0) <= s1(c_max-1); - nxt_s2(0) <= s2(c_max-1); + nxt_s1(0) <= s1(c_len-1); + nxt_s2(0) <= s2(c_len-1); -- feedback 2 - nxt_s1(c1) <= s1(c_max-1) xor s1(c1-1); - nxt_s2(c2) <= s2(c_max-1) xor s2(c2-1); + nxt_s1(c1) <= s1(c_len-1) xor s1(c1-1); + nxt_s2(c2) <= s2(c_len-1) xor s2(c2-1); END IF; END PROCESS; diff --git a/libraries/dsp/fft/src/vhdl/fft_pkg.vhd b/libraries/dsp/fft/src/vhdl/fft_pkg.vhd index 4b4a00f80ba00c619efabaf1b8c5be9995588636..05eaa1ffb226920d9127c5d69ea56bdd2ecacefe 100644 --- a/libraries/dsp/fft/src/vhdl/fft_pkg.vhd +++ b/libraries/dsp/fft/src/vhdl/fft_pkg.vhd @@ -25,6 +25,13 @@ use common_lib.common_pkg.all; package fft_pkg is + -- Default FFT switch and unswitch seeds from LOFAR1 + constant c_fft_lfsr_len : natural := 41; + constant c_fft_switch_seed1 : std_logic_vector(c_fft_lfsr_len-1 DOWNTO 0) := "01000101011101110101001011111000101100001"; + constant c_fft_switch_seed2 : std_logic_vector(c_fft_lfsr_len-1 DOWNTO 0) := "11011001000101001011011001110101100101100"; + + function fft_switch_new_seed(seed : std_logic_vector; offset : natural) return std_logic_vector; + -- FFT parameters for pipelined FFT (fft_pipe), parallel FFT (fft_par) and wideband FFT (fft_wide) type t_fft is record use_reorder : boolean; -- = false for bit-reversed output, true for normal output @@ -68,6 +75,11 @@ end package fft_pkg; package body fft_pkg is + function fft_switch_new_seed(seed : std_logic_vector; offset : natural) return std_logic_vector is + begin + return INCR_UVEC(seed, offset); -- make new unique seed + end; + function fft_r2_parameter_asserts(g_fft : t_fft) return boolean is begin -- nof_points diff --git a/libraries/dsp/fft/src/vhdl/fft_r2_pipe.vhd b/libraries/dsp/fft/src/vhdl/fft_r2_pipe.vhd index c9ed7f72c558ac588935c3670265363a810f4b5f..00c2007bd8a4bb7bafb6ca126bf1a11b5f602755 100644 --- a/libraries/dsp/fft/src/vhdl/fft_r2_pipe.vhd +++ b/libraries/dsp/fft/src/vhdl/fft_r2_pipe.vhd @@ -66,6 +66,7 @@ use work.fft_pkg.all; entity fft_r2_pipe is generic ( + g_instance_index : natural := 0; -- used for FFT switch seed g_fft : t_fft := c_fft; -- generics for the FFT 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 @@ -92,6 +93,8 @@ architecture str of fft_r2_pipe is 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_switch_seed1 : STD_LOGIC_VECTOR(c_fft_lfsr_len-1 DOWNTO 0) := fft_switch_new_seed(c_fft_switch_seed1, g_instance_index); + constant c_switch_seed2 : STD_LOGIC_VECTOR(c_fft_lfsr_len-1 DOWNTO 0) := fft_switch_new_seed(c_fft_switch_seed2, g_instance_index); 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); @@ -143,6 +146,8 @@ begin u_switch : ENTITY work.fft_switch GENERIC MAP ( g_switch_en => c_switch_en, + g_seed1 => c_switch_seed1, + g_seed2 => c_switch_seed2, g_fft_sz_w => c_switch_sz_w, g_dat_w => c_switch_dat_w ) @@ -303,6 +308,8 @@ begin u_unswitch : ENTITY work.fft_unswitch GENERIC MAP ( g_switch_en => c_switch_en, + g_seed1 => c_switch_seed1, + g_seed2 => c_switch_seed2, g_fft_sz_w => c_switch_sz_w, g_dat_w => c_unswitch_dat_w ) diff --git a/libraries/dsp/fft/src/vhdl/fft_switch.vhd b/libraries/dsp/fft/src/vhdl/fft_switch.vhd index cad57405ab3b2c03ed84834171fab082b2ed6b51..9da13b566ede8834d55739437b8515417fac3bf5 100644 --- a/libraries/dsp/fft/src/vhdl/fft_switch.vhd +++ b/libraries/dsp/fft/src/vhdl/fft_switch.vhd @@ -46,10 +46,13 @@ LIBRARY IEEE, common_lib; USE IEEE.std_logic_1164.ALL; USE common_lib.common_pkg.ALL; +USE work.fft_pkg.ALL; ENTITY fft_switch IS GENERIC ( g_switch_en : BOOLEAN := FALSE; + g_seed1 : STD_LOGIC_VECTOR(c_fft_lfsr_len-1 DOWNTO 0) := c_fft_switch_seed1; + g_seed2 : STD_LOGIC_VECTOR(c_fft_lfsr_len-1 DOWNTO 0) := c_fft_switch_seed2; g_fft_sz_w : NATURAL; g_dat_w : NATURAL ); @@ -156,6 +159,10 @@ BEGIN END PROCESS; u_fft_lfsr: ENTITY work.fft_lfsr + GENERIC MAP ( + g_seed1 => g_seed1, + g_seed2 => g_seed2 + ) PORT MAP ( clk => clk, rst => rst, diff --git a/libraries/dsp/fft/src/vhdl/fft_unswitch.vhd b/libraries/dsp/fft/src/vhdl/fft_unswitch.vhd index 6d9f561a15e7ca184f70c418810bd85f9b1ac6d6..f94f12e7f0954a3b6af011504a33052e471bef90 100644 --- a/libraries/dsp/fft/src/vhdl/fft_unswitch.vhd +++ b/libraries/dsp/fft/src/vhdl/fft_unswitch.vhd @@ -31,10 +31,13 @@ LIBRARY IEEE, common_lib; USE IEEE.std_logic_1164.ALL; USE common_lib.common_pkg.ALL; +USE work.fft_pkg.ALL; ENTITY fft_unswitch IS GENERIC ( g_switch_en : BOOLEAN := FALSE; + g_seed1 : STD_LOGIC_VECTOR(c_fft_lfsr_len-1 DOWNTO 0) := c_fft_switch_seed1; + g_seed2 : STD_LOGIC_VECTOR(c_fft_lfsr_len-1 DOWNTO 0) := c_fft_switch_seed2; g_fft_sz_w : NATURAL; g_dat_w : NATURAL ); @@ -147,6 +150,10 @@ BEGIN END PROCESS; u_fft_lfsr: ENTITY work.fft_lfsr + GENERIC MAP ( + g_seed1 => g_seed1, + g_seed2 => g_seed2 + ) PORT MAP ( clk => clk, rst => rst, diff --git a/libraries/dsp/fft/tb/vhdl/tb_fft_switch.vhd b/libraries/dsp/fft/tb/vhdl/tb_fft_switch.vhd index 08d04ee3e9bae1ffaea762e535be0d38d97395f6..981f017da2af2a9125e6155283168f6e17d83542 100644 --- a/libraries/dsp/fft/tb/vhdl/tb_fft_switch.vhd +++ b/libraries/dsp/fft/tb/vhdl/tb_fft_switch.vhd @@ -52,9 +52,11 @@ LIBRARY IEEE, common_lib; USE IEEE.std_logic_1164.ALL; USE common_lib.common_pkg.ALL; USE common_lib.tb_common_pkg.ALL; +USE work.fft_pkg.ALL; ENTITY tb_fft_switch IS GENERIC ( + g_instance_index : NATURAL := 0; g_switch_en : BOOLEAN := TRUE; g_in_val_gaps : BOOLEAN := TRUE; g_increment_at_val : BOOLEAN := TRUE; @@ -66,9 +68,9 @@ END tb_fft_switch; ARCHITECTURE tb OF tb_fft_switch IS - CONSTANT clk_period : TIME := 10 ns; + CONSTANT clk_period : TIME := 10 ns; - CONSTANT c_dat_w : NATURAL := 16; + CONSTANT c_dat_w : NATURAL := 16; CONSTANT c_nof_clk_per_block : NATURAL := 2**g_fft_size_w; CONSTANT c_nof_block_per_sync_max : NATURAL := ceil_div(g_nof_clk_per_sync, c_nof_clk_per_block); @@ -76,6 +78,9 @@ ARCHITECTURE tb OF tb_fft_switch IS CONSTANT c_dly : NATURAL := 4; -- pipeling in fft_switch, mux, fft_unswitch and demux + constant c_switch_seed1 : STD_LOGIC_VECTOR(c_fft_lfsr_len-1 DOWNTO 0) := fft_switch_new_seed(c_fft_switch_seed1, g_instance_index); + constant c_switch_seed2 : STD_LOGIC_VECTOR(c_fft_lfsr_len-1 DOWNTO 0) := fft_switch_new_seed(c_fft_switch_seed2, g_instance_index); + SIGNAL tb_end : STD_LOGIC := '0'; SIGNAL rst : STD_LOGIC := '1'; SIGNAL clk : STD_LOGIC := '0'; @@ -185,6 +190,8 @@ BEGIN u_fft_switch : ENTITY work.fft_switch GENERIC MAP ( g_switch_en => g_switch_en, + g_seed1 => c_switch_seed1, + g_seed2 => c_switch_seed2, g_fft_sz_w => g_fft_size_w, g_dat_w => c_dat_w ) @@ -227,6 +234,8 @@ BEGIN u_fft_unswitch : ENTITY work.fft_unswitch GENERIC MAP ( g_switch_en => g_switch_en, + g_seed1 => c_switch_seed1, + g_seed2 => c_switch_seed2, g_fft_sz_w => g_fft_size_w, g_dat_w => c_dat_w ) diff --git a/libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd b/libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd index 158f3cb747fb60b86fb13e8ba917f330920df0d1..c12d89665762e8451ba9e6e337e367d3bb72f11f 100644 --- a/libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd +++ b/libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd @@ -597,6 +597,7 @@ begin gen_fft_r2_pipe_streams: for S in 0 to g_wpfb.nof_wb_streams-1 generate u_fft_r2_pipe : entity fft_lib.fft_r2_pipe generic map( + g_instance_index => S, g_fft => c_fft, g_pipeline => g_wpfb.fft_pipeline, g_dont_flip_channels => g_dont_flip_channels,