diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_local.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_local.vhd index dd3b98a7ba0b9fdbaef242e17801916fe41b7459..02ba7c39bd8d756c58521bbcdcceb60cfbd3962c 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_local.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_local.vhd @@ -39,7 +39,9 @@ USE work.sdp_pkg.ALL; ENTITY sdp_beamformer_local IS GENERIC ( - g_bf_weights_file_name : STRING := "UNUSED" + g_bf_weights_file_name : STRING := "UNUSED"; + g_raw_dat_w : NATURAL := c_sdp_W_subband; + g_raw_fraction_w : NATURAL := 0 ); PORT ( dp_clk : IN STD_LOGIC; @@ -62,15 +64,20 @@ ARCHITECTURE str OF sdp_beamformer_local IS CONSTANT c_bf_weights_latency : NATURAL := 5; -- 3 for complex multiplier + 2 RAM latency CONSTANT c_total_latency : NATURAL := 3 + c_bf_weights_latency + c_complex_adder_latency; - CONSTANT c_complex_adder_sum_w : NATURAL := c_sdp_W_bf_product + ceil_log2(c_sdp_S_pn); + -- Product width, do -1 to skip double sign bit in product + CONSTANT c_product_w : NATURAL := c_sdp_W_bf_weight + g_raw_dat_w - 1; + CONSTANT c_complex_adder_sum_w : NATURAL := c_product_w + ceil_log2(c_sdp_S_pn); SIGNAL sub_sosi_arr : t_dp_sosi_arr(c_sdp_N_pol_bf*c_sdp_P_pfb-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst); + SIGNAL bf_weights_out_sosi_arr : t_dp_sosi_arr(c_sdp_N_pol_bf*c_sdp_P_pfb-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst); + SIGNAL bf_weights_x_sosi_arr : t_dp_sosi_arr(c_sdp_P_pfb-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst); SIGNAL bf_weights_y_sosi_arr : t_dp_sosi_arr(c_sdp_P_pfb-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst); SIGNAL deinterleaved_x_sosi_arr : t_dp_sosi_arr(c_sdp_S_pn-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst); SIGNAL deinterleaved_y_sosi_arr : t_dp_sosi_arr(c_sdp_S_pn-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst); SIGNAL interleave_out_sosi_arr : t_dp_sosi_arr(c_sdp_S_pn-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst); + SIGNAL complex_add_out_sosi : t_dp_sosi := c_dp_sosi_rst; SIGNAL pipelined_in_sosi : t_dp_sosi := c_dp_sosi_rst; SIGNAL dp_requantize_in_sosi : t_dp_sosi := c_dp_sosi_rst; @@ -94,7 +101,8 @@ BEGIN --------------------------------------------------------------- u_sdp_bf_weights : ENTITY work.sdp_bf_weights GENERIC MAP ( - g_gains_file_name => g_bf_weights_file_name + g_gains_file_name => g_bf_weights_file_name, + g_raw_dat_w => g_raw_dat_w ) PORT MAP( dp_clk => dp_clk, @@ -176,7 +184,7 @@ BEGIN u_dp_complex_add : ENTITY dp_lib.dp_complex_add GENERIC MAP( g_nof_inputs => c_sdp_S_pn, - g_data_w => c_sdp_W_bf_product + g_data_w => c_product_w ) PORT MAP( rst => dp_rst, @@ -217,7 +225,7 @@ BEGIN GENERIC MAP ( g_complex => TRUE, g_representation => "SIGNED", - g_lsb_w => c_sdp_W_bf_weight_fraction + c_sdp_W_subband_fraction, + g_lsb_w => c_sdp_W_bf_weight_fraction + g_raw_fraction_w, g_lsb_round => TRUE, g_lsb_round_clip => FALSE, g_msb_clip => FALSE, diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_bf_weights.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_bf_weights.vhd index 9b83b850167505a0bf9c527030253cb9b4fd4f4e..9f52c63883b6c6b7ab579530a7de52f40714cd58 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_bf_weights.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_bf_weights.vhd @@ -25,12 +25,13 @@ -- . Implements the functionality of sdp_bf_weights in the beamformer (BF) of -- the LOFAR2 SDPFW design. -- Description: --- The sdp_bf_weights.vhd consists of mms_dp_gain_serial_arr.vhd and --- some address counter logic to select the address of the subband weight. +-- . The sdp_bf_weights.vhd consists of mms_dp_gain_serial_arr.vhd and +-- some address counter logic to select the address of the subband weight. +-- . The sdp_bf_weights.vhd does no rounding, so output data width = input +-- data width = g_raw_dat_w. Rounding can be done after the BF adder stage. -- Remark: -- . sdp_bf_weights.vhd is similar to sdp_subband_equalizer.vhd. The --- difference is that they have a different purpose and that the --- sdp_subband_equalizer requantizes the output. +-- difference is that they have a different purpose. ------------------------------------------------------------------------------- LIBRARY IEEE, common_lib, dp_lib; @@ -42,7 +43,8 @@ USE work.sdp_pkg.ALL; ENTITY sdp_bf_weights IS GENERIC ( - g_gains_file_name : STRING := "UNUSED" + g_gains_file_name : STRING := "UNUSED"; + g_raw_dat_w : NATURAL ); PORT ( dp_clk : IN STD_LOGIC; @@ -61,16 +63,18 @@ END sdp_bf_weights; ARCHITECTURE str OF sdp_bf_weights IS - CONSTANT c_in_dat_w : NATURAL := c_sdp_W_subband + c_sdp_W_subband_fraction; CONSTANT c_gain_addr_w : NATURAL := ceil_log2(c_sdp_Q_fft * c_sdp_S_sub_bf); - CONSTANT c_gain_out_dat_w : NATURAL := c_sdp_W_bf_weight + c_in_dat_w - 1; -- -1 to skip double sign bit in product + + -- Product width, do -1 to skip double sign bit in product + CONSTANT c_gain_out_dat_w : NATURAL := c_sdp_W_bf_weight + g_raw_dat_w - 1; + SIGNAL in_sosi : t_dp_sosi; SIGNAL cnt : NATURAL RANGE 0 TO c_sdp_Q_fft * c_sdp_S_sub_bf-1; SIGNAL gains_rd_address : STD_LOGIC_VECTOR(c_gain_addr_w-1 DOWNTO 0); BEGIN - ASSERT c_gain_out_dat_w = c_sdp_W_bf_product REPORT "Wrong beamformer product width." SEVERITY FAILURE; + in_sosi <= in_sosi_arr(0); -- use ctrl from input [0] --------------------------------------------------------------- -- Counter @@ -90,8 +94,8 @@ BEGIN v_Q := 0; v_BLET := 0; ELSIF rising_edge(dp_clk) THEN - IF in_sosi_arr(0).valid = '1' THEN - IF in_sosi_arr(0).eop = '1' THEN + IF in_sosi.valid = '1' THEN + IF in_sosi.eop = '1' THEN v_Q := 0; v_BLET := 0; ELSE @@ -122,7 +126,7 @@ BEGIN g_complex_data => TRUE, g_complex_gain => TRUE, g_gain_w => c_sdp_W_bf_weight, - g_in_dat_w => c_in_dat_w, + g_in_dat_w => g_raw_dat_w, g_out_dat_w => c_gain_out_dat_w, g_gains_file_name => g_gains_file_name ) diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_subband_equalizer.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_subband_equalizer.vhd index 7b4db7cbb3efe480f2cd1d65604a1d78824f699f..392062697981e0e01c2a798f754754b30b6c112d 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_subband_equalizer.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_subband_equalizer.vhd @@ -25,11 +25,14 @@ -- . Implements the functionality of the subband equalizer in the subband -- filterbank (Fsub) of the LOFAR2 SDPFW design. -- Description: --- The sdp_subband_equalizer.vhd consists of mms_dp_gain_serial_arr.vhd and --- some address counter logic to select the address of the subband weight --- and a dp_requantize.vhd component. +-- . The sdp_subband_equalizer.vhd consists of mms_dp_gain_serial_arr.vhd and +-- some address counter logic to select the address of the subband weight +-- and a dp_requantize.vhd component. +-- . Subband widths: +-- - raw_sosi : g_raw_dat_w bits +-- - quant_sosi : c_quant_dat_w = g_raw_dat_w - g_raw_fraction_w bits -- Remark: --- . +-- ------------------------------------------------------------------------------- LIBRARY IEEE, common_lib, dp_lib; @@ -41,15 +44,18 @@ USE work.sdp_pkg.ALL; ENTITY sdp_subband_equalizer IS GENERIC ( - g_gains_file_name : STRING := "UNUSED"; - g_nof_streams : NATURAL := c_sdp_P_pfb + g_gains_file_name : STRING := "UNUSED"; + g_nof_streams : NATURAL := c_sdp_P_pfb; + g_raw_dat_w : NATURAL := c_sdp_W_subband; + g_raw_fraction_w : NATURAL := 0 ); PORT ( dp_clk : IN STD_LOGIC; dp_rst : IN STD_LOGIC; - in_sosi_arr : IN t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); - out_sosi_arr : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); + in_raw_sosi_arr : IN t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); + out_raw_sosi_arr : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); + out_quant_sosi_arr : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); mm_rst : IN STD_LOGIC; mm_clk : IN STD_LOGIC; @@ -61,22 +67,26 @@ END sdp_subband_equalizer; ARCHITECTURE str OF sdp_subband_equalizer IS - CONSTANT c_in_dat_w : NATURAL := c_sdp_W_subband + c_sdp_W_subband_fraction; CONSTANT c_gain_addr_w : NATURAL := ceil_log2(c_sdp_Q_fft * c_sdp_N_sub); - CONSTANT c_gain_out_dat_w : NATURAL := c_sdp_W_sub_weight + c_in_dat_w - 1; -- = c_sdp_W_se_product + + -- Product width, do -1 to skip double sign bit in product + CONSTANT c_gain_out_dat_w : NATURAL := c_sdp_W_sub_weight + g_raw_dat_w - 1; + + CONSTANT c_quant_dat_w : NATURAL := g_raw_dat_w - g_raw_fraction_w; + SIGNAL in_sosi : t_dp_sosi; SIGNAL cnt : NATURAL RANGE 0 TO c_sdp_Q_fft * c_sdp_N_sub-1; SIGNAL gains_rd_address : STD_LOGIC_VECTOR(c_gain_addr_w-1 DOWNTO 0); - SIGNAL dp_gain_serial_out_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); + SIGNAL weighted_raw_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); BEGIN - ASSERT c_gain_out_dat_w = c_sdp_W_equalizer_product REPORT "Wrong subband equalizer product width." SEVERITY FAILURE; + in_sosi <= in_raw_sosi_arr(0); -- use ctrl from input [0] - --------------------------------------------------------------- - -- Counter - --------------------------------------------------------------- - -- The subband weigths per PN are stored as + ----------------------------------------------------------------------------- + -- Counter + ----------------------------------------------------------------------------- + -- The subband weigths per PN are stored as -- (cint16)subband_weights[S_pn/Q_fft]_[Q_fft][N_sub], but have -- to be applied according the subband data order -- fsub[S_pn/Q_fft]_[N_sub][Q_fft]. Therefore the counter in @@ -91,8 +101,8 @@ BEGIN v_Q := 0; v_SUB := 0; ELSIF rising_edge(dp_clk) THEN - IF in_sosi_arr(0).valid = '1' THEN - IF in_sosi_arr(0).eop = '1' THEN + IF in_sosi.valid = '1' THEN + IF in_sosi.eop = '1' THEN v_Q := 0; v_SUB := 0; ELSE @@ -113,9 +123,9 @@ BEGIN END PROCESS; gains_rd_address <= TO_UVEC(cnt, c_gain_addr_w); - --------------------------------------------------------------- - -- Gain - --------------------------------------------------------------- + ----------------------------------------------------------------------------- + -- Gain + ----------------------------------------------------------------------------- u_mms_dp_gain_serial_arr : ENTITY dp_lib.mms_dp_gain_serial_arr GENERIC MAP ( g_nof_streams => g_nof_streams, @@ -123,7 +133,7 @@ BEGIN g_complex_data => TRUE, g_complex_gain => TRUE, g_gain_w => c_sdp_W_sub_weight, - g_in_dat_w => c_in_dat_w, + g_in_dat_w => g_raw_dat_w, g_out_dat_w => c_gain_out_dat_w, g_gains_file_name => g_gains_file_name ) @@ -141,33 +151,60 @@ BEGIN -- ST interface gains_rd_address => gains_rd_address, - in_sosi_arr => in_sosi_arr, - out_sosi_arr => dp_gain_serial_out_sosi_arr + in_sosi_arr => in_raw_sosi_arr, + out_sosi_arr => weighted_raw_sosi_arr ); - --------------------------------------------------------------- + ----------------------------------------------------------------------------- -- Requantize - --------------------------------------------------------------- + ----------------------------------------------------------------------------- + gen_dp_requantize : FOR I IN 0 TO g_nof_streams-1 GENERATE - u_dp_requantize : ENTITY dp_lib.dp_requantize + -- For raw output only round the c_sdp_W_sub_weight_fraction, and keep the + -- g_raw_fraction_w, so that the output width remains the same as the input + -- width g_raw_dat_w. + u_dp_requantize_out_raw : ENTITY dp_lib.dp_requantize + GENERIC MAP ( + g_complex => TRUE, + g_representation => "SIGNED", + g_lsb_w => c_sdp_W_sub_weight_fraction, + g_lsb_round => TRUE, + g_lsb_round_clip => FALSE, + g_msb_clip => TRUE, + g_msb_clip_symmetric => FALSE, + g_in_dat_w => c_gain_out_dat_w, + g_out_dat_w => g_raw_dat_w + ) + PORT MAP ( + rst => dp_rst, + clk => dp_clk, + -- ST sink + snk_in => weighted_raw_sosi_arr(I), + -- ST source + src_out => out_raw_sosi_arr(I) + ); + + -- For quant output round the entire fraction, so that the output width + -- becomes c_quant_dat_w. + u_dp_requantize_out_quant : ENTITY dp_lib.dp_requantize GENERIC MAP ( g_complex => TRUE, g_representation => "SIGNED", - g_lsb_w => c_sdp_W_sub_weight_fraction + c_sdp_W_subband_fraction, + g_lsb_w => c_sdp_W_sub_weight_fraction + g_raw_fraction_w, g_lsb_round => TRUE, g_lsb_round_clip => FALSE, g_msb_clip => TRUE, g_msb_clip_symmetric => FALSE, g_in_dat_w => c_gain_out_dat_w, - g_out_dat_w => c_sdp_W_subband + g_out_dat_w => c_quant_dat_w ) PORT MAP ( rst => dp_rst, clk => dp_clk, -- ST sink - snk_in => dp_gain_serial_out_sosi_arr(I), + snk_in => weighted_raw_sosi_arr(I), -- ST source - src_out => out_sosi_arr(I) + src_out => out_quant_sosi_arr(I) ); END GENERATE; END str;