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

Support using different FFT swicth seed per fft_r2_pipe instance index.

parent c125bc0f
No related branches found
No related tags found
1 merge request!217Resolve L2SDP-663
Pipeline #26114 failed
...@@ -21,12 +21,20 @@ ...@@ -21,12 +21,20 @@
-- Author: ported by E. Kooistra, original 2004 by W. Lubberhuizen / W. Poeisz -- Author: ported by E. Kooistra, original 2004 by W. Lubberhuizen / W. Poeisz
-- Purpose: Scramble quantization noise crosstalk between two real inputs -- Purpose: Scramble quantization noise crosstalk between two real inputs
-- Description: Ported from LOFAR1, see readme_lofar1.txt -- 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; LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL; USE IEEE.std_logic_1164.ALL;
USE work.fft_pkg.ALL;
ENTITY fft_lfsr IS 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 ( PORT (
in_en : IN STD_LOGIC; in_en : IN STD_LOGIC;
out_bit1 : OUT STD_LOGIC; out_bit1 : OUT STD_LOGIC;
...@@ -43,23 +51,23 @@ ARCHITECTURE rtl OF fft_lfsr IS ...@@ -43,23 +51,23 @@ ARCHITECTURE rtl OF fft_lfsr IS
-- x^41 + x^20 + 1 and x^41 + x^3 + 1 -- x^41 + x^20 + 1 and x^41 + x^3 + 1
-- see XAPP217 -- 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 c1 : NATURAL := 20;
CONSTANT c2 : NATURAL := 3; CONSTANT c2 : NATURAL := 3;
SIGNAL s1 : 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_max-1 DOWNTO 0); SIGNAL nxt_s1 : STD_LOGIC_VECTOR(c_len-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 s2 : STD_LOGIC_VECTOR(c_len-1 DOWNTO 0);
SIGNAL nxt_s2 : STD_LOGIC_VECTOR(c_len-1 DOWNTO 0);
BEGIN BEGIN
p_reg : PROCESS(rst,clk) p_reg : PROCESS(rst,clk)
BEGIN BEGIN
IF rst='1' THEN IF rst='1' THEN
s1 <= "01000101011101110101001011111000101100001"; s1 <= g_seed1;
s2 <= "11011001000101001011011001110101100101100"; s2 <= g_seed2;
ELSIF rising_edge(clk) THEN ELSIF rising_edge(clk) THEN
s1 <= nxt_s1; s1 <= nxt_s1;
s2 <= nxt_s2; s2 <= nxt_s2;
...@@ -75,16 +83,16 @@ BEGIN ...@@ -75,16 +83,16 @@ BEGIN
nxt_s2 <= s2; nxt_s2 <= s2;
IF in_en = '1' THEN IF in_en = '1' THEN
-- shift -- shift
nxt_s1(c_max-1 DOWNTO 1) <= s1(c_max-2 DOWNTO 0); nxt_s1(c_len-1 DOWNTO 1) <= s1(c_len-2 DOWNTO 0);
nxt_s2(c_max-1 DOWNTO 1) <= s2(c_max-2 DOWNTO 0); nxt_s2(c_len-1 DOWNTO 1) <= s2(c_len-2 DOWNTO 0);
-- feedback 1 -- feedback 1
nxt_s1(0) <= s1(c_max-1); nxt_s1(0) <= s1(c_len-1);
nxt_s2(0) <= s2(c_max-1); nxt_s2(0) <= s2(c_len-1);
-- feedback 2 -- feedback 2
nxt_s1(c1) <= s1(c_max-1) xor s1(c1-1); nxt_s1(c1) <= s1(c_len-1) xor s1(c1-1);
nxt_s2(c2) <= s2(c_max-1) xor s2(c2-1); nxt_s2(c2) <= s2(c_len-1) xor s2(c2-1);
END IF; END IF;
END PROCESS; END PROCESS;
......
...@@ -25,6 +25,13 @@ use common_lib.common_pkg.all; ...@@ -25,6 +25,13 @@ use common_lib.common_pkg.all;
package fft_pkg is 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) -- FFT parameters for pipelined FFT (fft_pipe), parallel FFT (fft_par) and wideband FFT (fft_wide)
type t_fft is record type t_fft is record
use_reorder : boolean; -- = false for bit-reversed output, true for normal output use_reorder : boolean; -- = false for bit-reversed output, true for normal output
...@@ -68,6 +75,11 @@ end package fft_pkg; ...@@ -68,6 +75,11 @@ end package fft_pkg;
package body fft_pkg is 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 function fft_r2_parameter_asserts(g_fft : t_fft) return boolean is
begin begin
-- nof_points -- nof_points
......
...@@ -66,6 +66,7 @@ use work.fft_pkg.all; ...@@ -66,6 +66,7 @@ use work.fft_pkg.all;
entity fft_r2_pipe is entity fft_r2_pipe is
generic ( generic (
g_instance_index : natural := 0; -- used for FFT switch seed
g_fft : t_fft := c_fft; -- generics for the FFT 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_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_dont_flip_channels : boolean := false; -- generic to prevent re-ordering of the channels
...@@ -92,6 +93,8 @@ architecture str of fft_r2_pipe is ...@@ -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_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_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_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_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_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_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 ...@@ -143,6 +146,8 @@ begin
u_switch : ENTITY work.fft_switch u_switch : ENTITY work.fft_switch
GENERIC MAP ( GENERIC MAP (
g_switch_en => c_switch_en, 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_fft_sz_w => c_switch_sz_w,
g_dat_w => c_switch_dat_w g_dat_w => c_switch_dat_w
) )
...@@ -303,6 +308,8 @@ begin ...@@ -303,6 +308,8 @@ begin
u_unswitch : ENTITY work.fft_unswitch u_unswitch : ENTITY work.fft_unswitch
GENERIC MAP ( GENERIC MAP (
g_switch_en => c_switch_en, 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_fft_sz_w => c_switch_sz_w,
g_dat_w => c_unswitch_dat_w g_dat_w => c_unswitch_dat_w
) )
......
...@@ -46,10 +46,13 @@ ...@@ -46,10 +46,13 @@
LIBRARY IEEE, common_lib; LIBRARY IEEE, common_lib;
USE IEEE.std_logic_1164.ALL; USE IEEE.std_logic_1164.ALL;
USE common_lib.common_pkg.ALL; USE common_lib.common_pkg.ALL;
USE work.fft_pkg.ALL;
ENTITY fft_switch IS ENTITY fft_switch IS
GENERIC ( GENERIC (
g_switch_en : BOOLEAN := FALSE; 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_fft_sz_w : NATURAL;
g_dat_w : NATURAL g_dat_w : NATURAL
); );
...@@ -156,6 +159,10 @@ BEGIN ...@@ -156,6 +159,10 @@ BEGIN
END PROCESS; END PROCESS;
u_fft_lfsr: ENTITY work.fft_lfsr u_fft_lfsr: ENTITY work.fft_lfsr
GENERIC MAP (
g_seed1 => g_seed1,
g_seed2 => g_seed2
)
PORT MAP ( PORT MAP (
clk => clk, clk => clk,
rst => rst, rst => rst,
......
...@@ -31,10 +31,13 @@ ...@@ -31,10 +31,13 @@
LIBRARY IEEE, common_lib; LIBRARY IEEE, common_lib;
USE IEEE.std_logic_1164.ALL; USE IEEE.std_logic_1164.ALL;
USE common_lib.common_pkg.ALL; USE common_lib.common_pkg.ALL;
USE work.fft_pkg.ALL;
ENTITY fft_unswitch IS ENTITY fft_unswitch IS
GENERIC ( GENERIC (
g_switch_en : BOOLEAN := FALSE; 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_fft_sz_w : NATURAL;
g_dat_w : NATURAL g_dat_w : NATURAL
); );
...@@ -147,6 +150,10 @@ BEGIN ...@@ -147,6 +150,10 @@ BEGIN
END PROCESS; END PROCESS;
u_fft_lfsr: ENTITY work.fft_lfsr u_fft_lfsr: ENTITY work.fft_lfsr
GENERIC MAP (
g_seed1 => g_seed1,
g_seed2 => g_seed2
)
PORT MAP ( PORT MAP (
clk => clk, clk => clk,
rst => rst, rst => rst,
......
...@@ -52,9 +52,11 @@ LIBRARY IEEE, common_lib; ...@@ -52,9 +52,11 @@ LIBRARY IEEE, common_lib;
USE IEEE.std_logic_1164.ALL; USE IEEE.std_logic_1164.ALL;
USE common_lib.common_pkg.ALL; USE common_lib.common_pkg.ALL;
USE common_lib.tb_common_pkg.ALL; USE common_lib.tb_common_pkg.ALL;
USE work.fft_pkg.ALL;
ENTITY tb_fft_switch IS ENTITY tb_fft_switch IS
GENERIC ( GENERIC (
g_instance_index : NATURAL := 0;
g_switch_en : BOOLEAN := TRUE; g_switch_en : BOOLEAN := TRUE;
g_in_val_gaps : BOOLEAN := TRUE; g_in_val_gaps : BOOLEAN := TRUE;
g_increment_at_val : BOOLEAN := TRUE; g_increment_at_val : BOOLEAN := TRUE;
...@@ -76,6 +78,9 @@ ARCHITECTURE tb OF tb_fft_switch IS ...@@ -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_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 tb_end : STD_LOGIC := '0';
SIGNAL rst : STD_LOGIC := '1'; SIGNAL rst : STD_LOGIC := '1';
SIGNAL clk : STD_LOGIC := '0'; SIGNAL clk : STD_LOGIC := '0';
...@@ -185,6 +190,8 @@ BEGIN ...@@ -185,6 +190,8 @@ BEGIN
u_fft_switch : ENTITY work.fft_switch u_fft_switch : ENTITY work.fft_switch
GENERIC MAP ( GENERIC MAP (
g_switch_en => g_switch_en, 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_fft_sz_w => g_fft_size_w,
g_dat_w => c_dat_w g_dat_w => c_dat_w
) )
...@@ -227,6 +234,8 @@ BEGIN ...@@ -227,6 +234,8 @@ BEGIN
u_fft_unswitch : ENTITY work.fft_unswitch u_fft_unswitch : ENTITY work.fft_unswitch
GENERIC MAP ( GENERIC MAP (
g_switch_en => g_switch_en, 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_fft_sz_w => g_fft_size_w,
g_dat_w => c_dat_w g_dat_w => c_dat_w
) )
......
...@@ -597,6 +597,7 @@ begin ...@@ -597,6 +597,7 @@ begin
gen_fft_r2_pipe_streams: for S in 0 to g_wpfb.nof_wb_streams-1 generate 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 u_fft_r2_pipe : entity fft_lib.fft_r2_pipe
generic map( generic map(
g_instance_index => S,
g_fft => c_fft, g_fft => c_fft,
g_pipeline => g_wpfb.fft_pipeline, g_pipeline => g_wpfb.fft_pipeline,
g_dont_flip_channels => g_dont_flip_channels, g_dont_flip_channels => g_dont_flip_channels,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment