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

Use generic g_switch_en, instead of signal, to support zero input to output...

Use generic g_switch_en, instead of signal, to support zero input to output latency when g_switch_en = FALSE.
parent 7054457c
No related branches found
No related tags found
1 merge request!205Added g_sepa_switch_en to support mitigation of quantization noise crosstalk...
Pipeline #25509 passed
......@@ -31,13 +31,13 @@
-- blocks of c_nof_clk_per_block samples to the FFT.
-- Remark: Copy from applications/lofar1/RSP/pft2/src/vhdl/pft_switch.vhd
LIBRARY IEEE, common_lib, dp_lib;
LIBRARY IEEE, common_lib;
USE IEEE.std_logic_1164.ALL;
USE common_lib.common_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
ENTITY fft_switch IS
GENERIC (
g_switch_en : BOOLEAN := FALSE;
g_fft_sz_w : NATURAL;
g_dat_w : NATURAL
);
......@@ -45,7 +45,6 @@ ENTITY fft_switch IS
in_re : IN STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0); -- real input A
in_im : IN STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0); -- real input B
in_val : IN STD_LOGIC;
switch_en : IN STD_LOGIC := '1';
out_re : OUT STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0);
out_im : OUT STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0);
out_val : OUT STD_LOGIC;
......@@ -59,6 +58,9 @@ ARCHITECTURE rtl OF fft_switch IS
CONSTANT c_nof_clk_per_block : NATURAL := 2**g_fft_sz_w;
SIGNAL in_sop : STD_LOGIC;
SIGNAL in_eop : STD_LOGIC;
SIGNAL cnt : STD_LOGIC_VECTOR(g_fft_sz_w DOWNTO 0) := (OTHERS => '0');
SIGNAL nxt_cnt : STD_LOGIC_VECTOR(cnt'RANGE);
......@@ -71,60 +73,84 @@ ARCHITECTURE rtl OF fft_switch IS
BEGIN
p_reg : PROCESS (rst, clk)
BEGIN
IF rst = '1' THEN
cnt <= (OTHERS => '0');
out_val <= '0';
out_re <= (OTHERS => '0');
out_im <= (OTHERS => '0');
ELSIF rising_edge(clk) THEN
cnt <= nxt_cnt;
out_val <= in_val;
out_re <= nxt_out_re;
out_im <= nxt_out_im;
END IF;
END PROCESS;
p_counter: PROCESS(cnt, in_val)
BEGIN
nxt_cnt <= cnt;
IF in_val = '1' THEN
nxt_cnt <= INCR_UVEC(cnt, 1);
END IF;
END PROCESS;
p_lfsr_ctrl: PROCESS(cnt, in_val)
BEGIN
if TO_SINT(cnt) = -1 AND in_val = '1' THEN
lfsr_en <= '1';
ELSE
lfsr_en <= '0';
END IF;
END PROCESS;
p_out: PROCESS(in_re, in_im, switch_en, cnt, lfsr_bit1, lfsr_bit2)
BEGIN
nxt_out_re <= in_re;
nxt_out_im <= in_im;
IF switch_en = '1' THEN
-- Create input strobes to view data blocks for debugging
u_in_strobes : ENTITY common_lib.common_create_strobes_from_valid
GENERIC MAP (
g_pipeline => FALSE,
g_nof_clk_per_sync => c_nof_clk_per_block * 16, -- void value, sync is not used
g_nof_clk_per_block => c_nof_clk_per_block
)
PORT MAP (
rst => rst,
clk => clk,
in_val => in_val,
out_val => OPEN, -- out_val = in_val, because g_pipeline = FALSE
out_sop => in_sop,
out_eop => in_eop,
out_sync => OPEN
);
no_switch : IF g_switch_en = FALSE GENERATE
-- wire inputs to outputs
out_re <= in_re;
out_im <= in_im;
out_val <= in_val;
END GENERATE;
gen_switch : IF g_switch_en = TRUE GENERATE
p_reg : PROCESS (rst, clk)
BEGIN
IF rst = '1' THEN
cnt <= (OTHERS => '0');
out_val <= '0';
out_re <= (OTHERS => '0');
out_im <= (OTHERS => '0');
ELSIF rising_edge(clk) THEN
cnt <= nxt_cnt;
out_val <= in_val;
out_re <= nxt_out_re;
out_im <= nxt_out_im;
END IF;
END PROCESS;
p_counter: PROCESS(cnt, in_val)
BEGIN
nxt_cnt <= cnt;
IF in_val = '1' THEN
nxt_cnt <= INCR_UVEC(cnt, 1);
END IF;
END PROCESS;
p_lfsr_ctrl: PROCESS(cnt, in_val)
BEGIN
if TO_SINT(cnt) = -1 AND in_val = '1' THEN
lfsr_en <= '1';
ELSE
lfsr_en <= '0';
END IF;
END PROCESS;
p_out: PROCESS(in_re, in_im, cnt, lfsr_bit1, lfsr_bit2)
BEGIN
nxt_out_re <= in_re;
nxt_out_im <= in_im;
IF lfsr_bit1 = cnt(cnt'HIGH) THEN
nxt_out_re <= NEGATE_SVEC(in_re, g_dat_w); -- negate block of input A samples
END IF;
IF lfsr_bit2 = cnt(cnt'HIGH) THEN
nxt_out_im <= NEGATE_SVEC(in_im, g_dat_w); -- negate block of input B samples
END IF;
END IF;
END PROCESS;
u_fft_lfsr: ENTITY work.fft_lfsr
PORT MAP (
clk => clk,
rst => rst,
in_en => lfsr_en,
out_bit1 => lfsr_bit1,
out_bit2 => lfsr_bit2
);
END PROCESS;
u_fft_lfsr: ENTITY work.fft_lfsr
PORT MAP (
clk => clk,
rst => rst,
in_en => lfsr_en,
out_bit1 => lfsr_bit1,
out_bit2 => lfsr_bit2
);
END GENERATE;
END rtl;
......@@ -26,13 +26,13 @@
-- c_nof_clk_per_block samples, forever after rst release.
-- Remark: Copy from applications/lofar1/RSP/pft2/src/vhdl/pft_unswitch.vhd
LIBRARY IEEE, common_lib, dp_lib;
LIBRARY IEEE, common_lib;
USE IEEE.std_logic_1164.ALL;
USE common_lib.common_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
ENTITY fft_unswitch IS
GENERIC (
g_switch_en : BOOLEAN := FALSE;
g_fft_sz_w : NATURAL;
g_dat_w : NATURAL
);
......@@ -40,7 +40,6 @@ ENTITY fft_unswitch IS
in_re : IN STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0);
in_im : IN STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0);
in_val : IN STD_LOGIC;
switch_en : IN STD_LOGIC := '1';
out_re : OUT STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0);
out_im : OUT STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0);
out_val : OUT STD_LOGIC;
......@@ -53,7 +52,8 @@ ARCHITECTURE rtl OF fft_unswitch IS
CONSTANT c_nof_clk_per_block : NATURAL := 2**g_fft_sz_w;
SIGNAL in_sosi : t_dp_sosi;
SIGNAL in_sop : STD_LOGIC;
SIGNAL in_eop : STD_LOGIC;
SIGNAL cnt : STD_LOGIC_VECTOR(g_fft_sz_w DOWNTO 0) := (OTHERS => '0');
SIGNAL nxt_cnt : STD_LOGIC_VECTOR(cnt'RANGE);
......@@ -68,44 +68,68 @@ ARCHITECTURE rtl OF fft_unswitch IS
BEGIN
p_reg : PROCESS (rst, clk)
BEGIN
IF rst = '1' THEN
cnt <= (OTHERS => '0');
out_val <= '0';
out_re <= (OTHERS => '0');
out_im <= (OTHERS => '0');
ELSIF rising_edge(clk) THEN
cnt <= nxt_cnt;
out_val <= in_val;
out_re <= nxt_out_re;
out_im <= nxt_out_im;
END IF;
END PROCESS;
p_counter: PROCESS(cnt, in_val)
BEGIN
nxt_cnt <= cnt;
IF in_val = '1' THEN
nxt_cnt <= INCR_UVEC(cnt, 1);
END IF;
END PROCESS;
p_lfsr_ctrl: PROCESS(cnt, in_val)
BEGIN
if TO_SINT(cnt) = -1 AND in_val = '1' THEN
lfsr_en <= '1';
ELSE
lfsr_en <= '0';
END IF;
END PROCESS;
p_out: PROCESS(in_re, in_im, switch_en, cnt, lfsr_bit1, lfsr_bit2)
BEGIN
nxt_out_re <= in_re;
nxt_out_im <= in_im;
IF switch_en = '1' THEN
-- Create input strobes to view data blocks for debugging
u_in_strobes : ENTITY common_lib.common_create_strobes_from_valid
GENERIC MAP (
g_pipeline => FALSE,
g_nof_clk_per_sync => c_nof_clk_per_block * 16, -- void value, sync is not used
g_nof_clk_per_block => c_nof_clk_per_block
)
PORT MAP (
rst => rst,
clk => clk,
in_val => in_val,
out_val => OPEN, -- out_val = in_val, because g_pipeline = FALSE
out_sop => in_sop,
out_eop => in_eop,
out_sync => OPEN
);
no_switch : IF g_switch_en = FALSE GENERATE
-- wire inputs to outputs
out_re <= in_re;
out_im <= in_im;
out_val <= in_val;
END GENERATE;
gen_switch : IF g_switch_en = TRUE GENERATE
p_reg : PROCESS (rst, clk)
BEGIN
IF rst = '1' THEN
cnt <= (OTHERS => '0');
out_val <= '0';
out_re <= (OTHERS => '0');
out_im <= (OTHERS => '0');
ELSIF rising_edge(clk) THEN
cnt <= nxt_cnt;
out_val <= in_val;
out_re <= nxt_out_re;
out_im <= nxt_out_im;
END IF;
END PROCESS;
p_counter: PROCESS(cnt, in_val)
BEGIN
nxt_cnt <= cnt;
IF in_val = '1' THEN
nxt_cnt <= INCR_UVEC(cnt, 1);
END IF;
END PROCESS;
p_lfsr_ctrl: PROCESS(cnt, in_val)
BEGIN
if TO_SINT(cnt) = -1 AND in_val = '1' THEN
lfsr_en <= '1';
ELSE
lfsr_en <= '0';
END IF;
END PROCESS;
p_out: PROCESS(in_re, in_im, cnt, lfsr_bit1, lfsr_bit2)
BEGIN
nxt_out_re <= in_re;
nxt_out_im <= in_im;
-- multiplexed spectrum for input A at index 0, B at index 1
IF cnt(0) = '0' THEN
IF cnt(cnt'HIGH) = lfsr_bit1 THEN -- negate spectrum to undo negate of block of real input A
......@@ -118,16 +142,16 @@ BEGIN
nxt_out_im <= NEGATE_SVEC(in_im, g_dat_w);
END IF;
END IF;
END IF;
END PROCESS;
u_fft_lfsr: ENTITY work.fft_lfsr
PORT MAP (
clk => clk,
rst => rst,
in_en => lfsr_en,
out_bit1 => lfsr_bit1,
out_bit2 => lfsr_bit2
);
END PROCESS;
u_fft_lfsr: ENTITY work.fft_lfsr
PORT MAP (
clk => clk,
rst => rst,
in_en => lfsr_en,
out_bit1 => lfsr_bit1,
out_bit2 => lfsr_bit2
);
END GENERATE;
END rtl;
......@@ -55,6 +55,7 @@ USE common_lib.tb_common_pkg.ALL;
ENTITY tb_fft_switch IS
GENERIC (
g_switch_en : BOOLEAN := TRUE;
g_in_val_gaps : BOOLEAN := TRUE;
g_increment_at_val : BOOLEAN := TRUE;
g_fft_size_w : NATURAL := 3;
......@@ -87,7 +88,6 @@ ARCHITECTURE tb OF tb_fft_switch IS
SIGNAL in_eop : STD_LOGIC := '0';
SIGNAL in_sync : STD_LOGIC := '0';
SIGNAL switch_en : STD_LOGIC := '1';
SIGNAL switch_a : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
SIGNAL switch_b : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
SIGNAL switch_val : STD_LOGIC;
......@@ -101,7 +101,6 @@ ARCHITECTURE tb OF tb_fft_switch IS
SIGNAL mux_im : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0) := (OTHERS => '0');
SIGNAL mux_val : STD_LOGIC := '0';
SIGNAL unswitch_en : STD_LOGIC := '1';
SIGNAL unswitch_re : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
SIGNAL unswitch_im : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
SIGNAL unswitch_val : STD_LOGIC := '0';
......@@ -185,14 +184,14 @@ BEGIN
u_fft_switch : ENTITY work.fft_switch
GENERIC MAP (
g_fft_sz_w => g_fft_size_w,
g_dat_w => c_dat_w
g_switch_en => g_switch_en,
g_fft_sz_w => g_fft_size_w,
g_dat_w => c_dat_w
)
PORT MAP (
in_re => in_a,
in_im => in_b,
in_val => in_val,
switch_en => switch_en,
out_re => switch_a,
out_im => switch_b,
out_val => switch_val,
......@@ -227,14 +226,14 @@ BEGIN
u_fft_unswitch : ENTITY work.fft_unswitch
GENERIC MAP (
g_fft_sz_w => g_fft_size_w,
g_dat_w => c_dat_w
g_switch_en => g_switch_en,
g_fft_sz_w => g_fft_size_w,
g_dat_w => c_dat_w
)
PORT MAP (
in_re => mux_re,
in_im => mux_im,
in_val => mux_val,
switch_en => unswitch_en,
out_re => unswitch_re,
out_im => unswitch_im,
out_val => unswitch_val,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment