From 3cf90717139d901fff1e6127ed1083170c18067e Mon Sep 17 00:00:00 2001 From: Eric Kooistra <kooistra@astron.nl> Date: Sun, 17 Jan 2021 14:52:06 +0100 Subject: [PATCH] Added g_stage_dat_w to pft2 and pfb2, added g_switch_en to pfb2. Verified g_switch_en and g_stage_dat_w tin tb_tb_pft2.vhd (result OK). --- applications/lofar1/pfb2/src/vhdl/pfb2.vhd | 76 +++++++++++-------- applications/lofar1/pft2/src/vhdl/pft.vhd | 14 ++-- applications/lofar1/pft2/tb/vhdl/tb_pft2.vhd | 12 ++- .../lofar1/pft2/tb/vhdl/tb_tb_pft2.vhd | 67 +++++++++++----- 4 files changed, 109 insertions(+), 60 deletions(-) diff --git a/applications/lofar1/pfb2/src/vhdl/pfb2.vhd b/applications/lofar1/pfb2/src/vhdl/pfb2.vhd index 62d2a5e3e9..db851833e0 100644 --- a/applications/lofar1/pfb2/src/vhdl/pfb2.vhd +++ b/applications/lofar1/pfb2/src/vhdl/pfb2.vhd @@ -27,7 +27,7 @@ -- . Convert between LOFAR1 sync timing 1 clk before sop and streaming data path -- (DP) sync timing at sop. -- . g_switch_en = '1' decorrelates rounding crosstalk between the X and Y output --- that can occur due to PFT_MODE_REAL2. +-- that occurs due to shared complex FFT and seperate in PFT_MODE_REAL2. LIBRARY IEEE, common_lib, dp_lib, pfs_lib, pft2_lib; USE IEEE.std_logic_1164.ALL; @@ -37,18 +37,20 @@ USE pft2_lib.pft_pkg.ALL; ENTITY pfb2 IS GENERIC ( - g_nof_points : NATURAL := 1024; + g_nof_points : NATURAL := 1024; -- pfs - g_pfs_nof_taps : NATURAL := 16; - g_pfs_in_dat_w : NATURAL := 12; - g_pfs_out_dat_w : NATURAL := 18; - g_pfs_coef_dat_w : NATURAL := 16; + g_pfs_bypass : BOOLEAN := FALSE; + g_pfs_nof_taps : NATURAL := 16; + g_pfs_in_dat_w : NATURAL := 12; + g_pfs_out_dat_w : NATURAL := 18; + g_pfs_coef_dat_w : NATURAL := 16; - -- pft2 - g_pft_mode : PFT_MODE_TYPE := PFT_MODE_REAL2; - g_pft_switch_en : STD_LOGIC := '1'; - g_pft_out_dat_w : NATURAL := 18 + -- pft2 + g_pft_mode : PFT_MODE_TYPE := PFT_MODE_REAL2; + g_pft_switch_en : STD_LOGIC := '1'; + g_pft_stage_dat_w : NATURAL := c_pft_stage_dat_w; -- c_pft_stage_dat_w = 20 in pft_pkg.vhd + g_pft_out_dat_w : NATURAL := 18 ); PORT ( dp_rst : IN STD_LOGIC; @@ -86,38 +88,48 @@ BEGIN pfs_in_val <= in_sosi.valid WHEN rising_edge(dp_clk); pfs_in_sync <= in_sosi.sync; - pfs : ENTITY pfs_lib.pfs - GENERIC MAP ( - g_nof_bands => g_nof_points, - g_nof_taps => c_nof_coeffs, - g_in_dat_w => g_pfs_in_dat_w, - g_out_dat_w => g_pfs_out_dat_w, - g_coef_dat_w => g_pfs_coef_dat_w - ) - PORT MAP ( - in_dat_x => pfs_in_dat_x, - in_dat_y => pfs_in_dat_y, - in_val => pfs_in_val, - in_sync => pfs_in_sync, - out_dat_x => fil_out_dat_x, - out_dat_y => fil_out_dat_y, - out_val => fil_out_val, - out_sync => fil_out_sync, - clk => dp_clk, - rst => dp_rst, - restart => '0' - ); + gen_pfs : IF g_pfs_bypass=FALSE GENERATE + u_pfs : ENTITY pfs_lib.pfs + GENERIC MAP ( + g_nof_bands => g_nof_points, + g_nof_taps => c_nof_coeffs, + g_in_dat_w => g_pfs_in_dat_w, + g_out_dat_w => g_pfs_out_dat_w, + g_coef_dat_w => g_pfs_coef_dat_w + ) + PORT MAP ( + in_dat_x => pfs_in_dat_x, + in_dat_y => pfs_in_dat_y, + in_val => pfs_in_val, + in_sync => pfs_in_sync, + out_dat_x => fil_out_dat_x, + out_dat_y => fil_out_dat_y, + out_val => fil_out_val, + out_sync => fil_out_sync, + clk => dp_clk, + rst => dp_rst, + restart => '0' + ); + END GENERATE; + + no_pfs : IF g_pfs_bypass=TRUE GENERATE + fil_out_dat_x <= SHIFT_SVEC(pfs_in_dat_x, g_pfs_in_dat_w - g_pfs_out_dat_w); -- < 0 is shift left, > 0 is shift right + fil_out_dat_y <= SHIFT_SVEC(pfs_in_dat_y, g_pfs_in_dat_w - g_pfs_out_dat_w); -- < 0 is shift left, > 0 is shift right + fil_out_val <= pfs_in_val, + fil_out_sync <= pfs_in_sync, + END GENERATE; fil_sosi.re <= RESIZE_DP_DSP_DATA(fil_out_dat_x); fil_sosi.im <= RESIZE_DP_DSP_DATA(fil_out_dat_y); fil_sosi.valid <= fil_out_val; fil_sosi.sync <= fil_out_sync; - pft : ENTITY pft2_lib.pft + u_pft : ENTITY pft2_lib.pft GENERIC MAP ( g_fft_size_w => ceil_log2(g_nof_points), g_in_dat_w => g_pfs_out_dat_w, g_out_dat_w => g_pft_out_dat_w, + g_stage_dat_w => g_pft_stage_dat_w, g_mode => PFT_MODE_REAL2 ) PORT MAP ( diff --git a/applications/lofar1/pft2/src/vhdl/pft.vhd b/applications/lofar1/pft2/src/vhdl/pft.vhd index 624d916f47..5ed7893acc 100644 --- a/applications/lofar1/pft2/src/vhdl/pft.vhd +++ b/applications/lofar1/pft2/src/vhdl/pft.vhd @@ -36,6 +36,7 @@ ENTITY pft IS g_fft_size_w : NATURAL := 10; g_in_dat_w : NATURAL := 18; g_out_dat_w : NATURAL := 18; + g_stage_dat_w : NATURAL := c_pft_stage_dat_w; -- c_pft_stage_dat_w = 20 in pft_pkg.vhd g_mode : PFT_MODE_TYPE := PFT_MODE_BITREV ); PORT ( @@ -68,12 +69,11 @@ ARCHITECTURE str OF pft IS END; CONSTANT c_nof_stages : NATURAL := g_fft_size_w/2; - CONSTANT c_stage_dat_w : NATURAL := c_pft_stage_dat_w; CONSTANT c_pft_dat_w : NATURAL := pft_dat_w(g_out_dat_w, g_mode); TYPE stage_rec IS RECORD - re : STD_LOGIC_VECTOR(c_stage_dat_w-1 DOWNTO 0); - im : STD_LOGIC_VECTOR(c_stage_dat_w-1 DOWNTO 0); + re : STD_LOGIC_VECTOR(g_stage_dat_w-1 DOWNTO 0); + im : STD_LOGIC_VECTOR(g_stage_dat_w-1 DOWNTO 0); val : STD_LOGIC; sync : STD_LOGIC; END RECORD; @@ -154,7 +154,7 @@ BEGIN GENERIC MAP ( g_index => c_nof_stages-1, g_in_dat_w => g_in_dat_w, - g_out_dat_w => c_stage_dat_w + g_out_dat_w => g_stage_dat_w ) PORT MAP ( in_re => switch_re, @@ -175,8 +175,8 @@ BEGIN middle_stage : ENTITY pft2_lib.pft_stage GENERIC MAP ( g_index => i, - g_in_dat_w => c_stage_dat_w, - g_out_dat_w => c_stage_dat_w + g_in_dat_w => g_stage_dat_w, + g_out_dat_w => g_stage_dat_w ) PORT MAP ( in_re => stage(i).re, @@ -196,7 +196,7 @@ BEGIN last_stage : ENTITY pft2_lib.pft_stage GENERIC MAP ( g_index => 0, - g_in_dat_w => c_stage_dat_w, + g_in_dat_w => g_stage_dat_w, g_out_dat_w => c_pft_dat_w ) PORT MAP ( diff --git a/applications/lofar1/pft2/tb/vhdl/tb_pft2.vhd b/applications/lofar1/pft2/tb/vhdl/tb_pft2.vhd index 639aec0382..6d82563e30 100644 --- a/applications/lofar1/pft2/tb/vhdl/tb_pft2.vhd +++ b/applications/lofar1/pft2/tb/vhdl/tb_pft2.vhd @@ -28,6 +28,7 @@ -- - PFT_MODE_BITREV, PFT_MODE_COMPLEX: out_fft_re, out_fft_im -- - PFT_MODE_REAL2: out_x_re, out_x_im, out_y_re, out_y_im -- . Copy these signals in Wave Window to view them in both literal format and analog format +-- View diff_max_* in Wave Window, if diff_max_* < c_diff_max then tb yields OK. -- - The tb works OK for all three PFT modes. LIBRARY IEEE, tst_lib, common_lib; @@ -39,6 +40,10 @@ USE common_lib.tb_common_pkg.ALL; ENTITY tb_pft2 IS GENERIC ( + -- >>> PFT settings + g_switch_en : STD_LOGIC := '0'; + g_stage_dat_w : NATURAL := c_pft_stage_dat_w; -- c_pft_stage_dat_w = 20 in pft_pkg.vhd + -- The PFT has 3 modes: -- . PFT_MODE_BITREV --> DIT output -- . PFT_MODE_COMPLEX --> DIF output @@ -50,6 +55,7 @@ ENTITY tb_pft2 IS -- . For PFT_MODE_REAL2 select any signal pair for X and Y input. -- . For PFT_MODE_BITREV and PFT_MODE_COMPLEX select zeros for Y input. + -- >>> Testbench settings -- Select one input signal for X (used as real input to the PFT) --g_name_x : STRING := "cosin_N2"; --g_name_x : STRING := "cosin_1"; @@ -79,8 +85,9 @@ ENTITY tb_pft2 IS --g_name_y : STRING := "block_1"; --g_name_y : STRING := "block_117"; --g_name_y : STRING := "u_noise"; + g_repeat : NATURAL := 2 -- minimal 2 due to PFT latency - --g_repeat : NATURAL := 10 -- > c_nof_block_per_sync to view multiple in_sync and out_sync intervals + --g_repeat : NATURAL := 10 -- > c_nof_block_per_sync to view multiple in_sync and out_sync intervals ); END tb_pft2; @@ -554,6 +561,7 @@ BEGIN g_fft_size_w => c_fft_size_w, g_in_dat_w => c_in_dat_w, g_out_dat_w => c_out_dat_w, + g_stage_dat_w => g_stage_dat_w, g_mode => g_pft_mode ) PORT MAP ( @@ -561,7 +569,7 @@ BEGIN in_im => in_dat_y, in_val => in_val, in_sync => in_sync, - switch_en => '0', + switch_en => g_switch_en, out_re => out_re, out_im => out_im, out_val => out_val, diff --git a/applications/lofar1/pft2/tb/vhdl/tb_tb_pft2.vhd b/applications/lofar1/pft2/tb/vhdl/tb_tb_pft2.vhd index 398c87d757..53f218d6af 100644 --- a/applications/lofar1/pft2/tb/vhdl/tb_tb_pft2.vhd +++ b/applications/lofar1/pft2/tb/vhdl/tb_tb_pft2.vhd @@ -32,9 +32,16 @@ END tb_tb_pft2; USE work.pft_pkg.ALL; ARCHITECTURE tb OF tb_tb_pft2 IS + CONSTANT c_sw : STD_LOGIC := '1'; -- default for g_switch_en + CONSTANT c_dat_w : NATURAL := c_pft_stage_dat_w; -- default for g_stage_dat_w + SIGNAL tb_end : STD_LOGIC := '0'; -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end' BEGIN + -- >>> PFT settings + --g_switch_en : STD_LOGIC := '0'; + --g_stage_dat_w : NATURAL := c_pft_stage_dat_w; -- c_pft_stage_dat_w = 20 in pft_pkg.vhd + -- -- The PFT has 3 modes: -- . PFT_MODE_BITREV --> DIT output -- . PFT_MODE_COMPLEX --> DIF output @@ -46,6 +53,7 @@ BEGIN -- . For PFT_MODE_REAL2 select any signal pair for X and Y input. -- . For PFT_MODE_BITREV and PFT_MODE_COMPLEX select zeros for Y input. -- + -- >>> Testbench settings -- Select one input signal for X (used as real input to the PFT) --g_name_x : STRING := "cosin_N2"; --g_name_x : STRING := "cosin_1"; @@ -78,26 +86,47 @@ BEGIN -- --g_repeat : NATURAL := 2 -- minimal 2 due to PFT latency --g_repeat : NATURAL := 10 -- > c_nof_block_per_sync to view multiple in_sync and out_sync intervals - - u_cosin_N2 : ENTITY work.tb_pft2 GENERIC MAP(PFT_MODE_REAL2, "cosin_N2" , "zeros", 2); - u_cosin_1 : ENTITY work.tb_pft2 GENERIC MAP(PFT_MODE_REAL2, "cosin_1" , "zeros", 2); - u_cosin_39 : ENTITY work.tb_pft2 GENERIC MAP(PFT_MODE_REAL2, "cosin_39" , "zeros", 2); - u_sinus_1 : ENTITY work.tb_pft2 GENERIC MAP(PFT_MODE_REAL2, "sinus_1" , "zeros", 2); - u_sinus_13 : ENTITY work.tb_pft2 GENERIC MAP(PFT_MODE_REAL2, "sinus_13" , "zeros", 2); - u_sinus_13s : ENTITY work.tb_pft2 GENERIC MAP(PFT_MODE_REAL2, "sinus_13s", "zeros", 2); - u_impulse_0 : ENTITY work.tb_pft2 GENERIC MAP(PFT_MODE_REAL2, "impulse_0", "zeros", 2); - u_impulse_1 : ENTITY work.tb_pft2 GENERIC MAP(PFT_MODE_REAL2, "impulse_1", "zeros", 2); - u_zeros : ENTITY work.tb_pft2 GENERIC MAP(PFT_MODE_REAL2, "zeros" , "zeros", 2); - u_dc : ENTITY work.tb_pft2 GENERIC MAP(PFT_MODE_REAL2, "dc" , "zeros", 2); - u_block_1 : ENTITY work.tb_pft2 GENERIC MAP(PFT_MODE_REAL2, "block_1" , "zeros", 2); - u_block_117 : ENTITY work.tb_pft2 GENERIC MAP(PFT_MODE_REAL2, "block_117", "zeros", 2); - u_u_noise : ENTITY work.tb_pft2 GENERIC MAP(PFT_MODE_REAL2, "u_noise" , "zeros", 2); - u_impulse_0_impulse_1 : ENTITY work.tb_pft2 GENERIC MAP(PFT_MODE_REAL2, "impulse_0", "impulse_1", 2); - u_dc_cosin_N2 : ENTITY work.tb_pft2 GENERIC MAP(PFT_MODE_REAL2, "dc", "cosin_N2", 2); - u_dc_sinus_13 : ENTITY work.tb_pft2 GENERIC MAP(PFT_MODE_REAL2, "dc", "sinus_13", 2); - u_block_117_u_noise : ENTITY work.tb_pft2 GENERIC MAP(PFT_MODE_REAL2, "block_117", "u_noise", 2); - u_u_noise_u_noise : ENTITY work.tb_pft2 GENERIC MAP(PFT_MODE_REAL2, "u_noise", "u_noise", 2); + -- g_switch_en + -- . g_stage_dat_w + -- . . g_pft_mode + -- . . . g_name_x + -- . . . . g_name_y + -- . . . . . g_repeat + -- . . . . . . + -- One active input, other input zeros . . . . . . + u_cosin_N2 : ENTITY work.tb_pft2 GENERIC MAP(c_sw, c_dat_w, PFT_MODE_REAL2, "cosin_N2", "zeros", 2); + u_cosin_1 : ENTITY work.tb_pft2 GENERIC MAP(c_sw, c_dat_w, PFT_MODE_REAL2, "cosin_1", "zeros", 2); + u_cosin_39 : ENTITY work.tb_pft2 GENERIC MAP(c_sw, c_dat_w, PFT_MODE_REAL2, "cosin_39", "zeros", 2); + u_sinus_1 : ENTITY work.tb_pft2 GENERIC MAP(c_sw, c_dat_w, PFT_MODE_REAL2, "sinus_1", "zeros", 2); + u_sinus_13 : ENTITY work.tb_pft2 GENERIC MAP(c_sw, c_dat_w, PFT_MODE_REAL2, "sinus_13", "zeros", 2); + u_sinus_13s : ENTITY work.tb_pft2 GENERIC MAP(c_sw, c_dat_w, PFT_MODE_REAL2, "sinus_13s", "zeros", 2); + u_impulse_0 : ENTITY work.tb_pft2 GENERIC MAP(c_sw, c_dat_w, PFT_MODE_REAL2, "impulse_0", "zeros", 2); + u_impulse_1 : ENTITY work.tb_pft2 GENERIC MAP(c_sw, c_dat_w, PFT_MODE_REAL2, "impulse_1", "zeros", 2); + u_zeros : ENTITY work.tb_pft2 GENERIC MAP(c_sw, c_dat_w, PFT_MODE_REAL2, "zeros", "zeros", 2); + u_dc : ENTITY work.tb_pft2 GENERIC MAP(c_sw, c_dat_w, PFT_MODE_REAL2, "dc", "zeros", 2); + u_block_1 : ENTITY work.tb_pft2 GENERIC MAP(c_sw, c_dat_w, PFT_MODE_REAL2, "block_1", "zeros", 2); + u_block_117 : ENTITY work.tb_pft2 GENERIC MAP(c_sw, c_dat_w, PFT_MODE_REAL2, "block_117", "zeros", 2); + u_u_noise : ENTITY work.tb_pft2 GENERIC MAP(c_sw, c_dat_w, PFT_MODE_REAL2, "u_noise", "zeros", 2); + + -- Two active inputs + u_impulse_0_impulse_1 : ENTITY work.tb_pft2 GENERIC MAP(c_sw, c_dat_w, PFT_MODE_REAL2, "impulse_0", "impulse_1", 2); + u_dc_cosin_N2 : ENTITY work.tb_pft2 GENERIC MAP(c_sw, c_dat_w, PFT_MODE_REAL2, "dc", "cosin_N2", 2); + u_dc_sinus_13 : ENTITY work.tb_pft2 GENERIC MAP(c_sw, c_dat_w, PFT_MODE_REAL2, "dc", "sinus_13", 2); + u_block_117_u_noise : ENTITY work.tb_pft2 GENERIC MAP(c_sw, c_dat_w, PFT_MODE_REAL2, "block_117", "u_noise", 2); + u_u_noise_u_noise : ENTITY work.tb_pft2 GENERIC MAP(c_sw, c_dat_w, PFT_MODE_REAL2, "u_noise", "u_noise", 2); + + -- Vary g_stage_dat_w (pft2 g_in_dat_w = g_out_dat_w = 18) + -- . for g_stage_dat_w = 16 tb result is still OK, but <= 15 it fails + u_16_cosin_39 : ENTITY work.tb_pft2 GENERIC MAP(c_sw, 16, PFT_MODE_REAL2, "cosin_39", "zeros", 2); + u_17_cosin_39 : ENTITY work.tb_pft2 GENERIC MAP(c_sw, 17, PFT_MODE_REAL2, "cosin_39", "zeros", 2); + u_18_cosin_39 : ENTITY work.tb_pft2 GENERIC MAP(c_sw, 18, PFT_MODE_REAL2, "cosin_39", "zeros", 2); + u_19_cosin_39 : ENTITY work.tb_pft2 GENERIC MAP(c_sw, 19, PFT_MODE_REAL2, "cosin_39", "zeros", 2); + u_16_block_117_u_noise : ENTITY work.tb_pft2 GENERIC MAP(c_sw, 16, PFT_MODE_REAL2, "block_117", "u_noise", 2); + u_17_block_117_u_noise : ENTITY work.tb_pft2 GENERIC MAP(c_sw, 17, PFT_MODE_REAL2, "block_117", "u_noise", 2); + u_18_block_117_u_noise : ENTITY work.tb_pft2 GENERIC MAP(c_sw, 18, PFT_MODE_REAL2, "block_117", "u_noise", 2); + u_19_block_117_u_noise : ENTITY work.tb_pft2 GENERIC MAP(c_sw, 19, PFT_MODE_REAL2, "block_117", "u_noise", 2); + -- . for g_stage_dat_w > 20 tb result is still OK, but diff_max_* does not reduce further END tb; -- GitLab