diff --git a/libraries/dsp/correlator/src/vhdl/corr_accumulator.vhd b/libraries/dsp/correlator/src/vhdl/corr_accumulator.vhd index 25f9bd9e366f451533cfc68bcfba056268d2e629..bbbbaa6f430321eb70724b962918e3a66b43d170 100644 --- a/libraries/dsp/correlator/src/vhdl/corr_accumulator.vhd +++ b/libraries/dsp/correlator/src/vhdl/corr_accumulator.vhd @@ -47,90 +47,93 @@ ENTITY corr_accumulator IS ); END corr_accumulator; -ARCHITECTURE rtl OF corr_accumulator IS +ARCHITECTURE str OF corr_accumulator IS + + -- Help constant so other constants can be calculated if g_accumulator_depth<1 + CONSTANT c_accumulator_depth : NATURAL := sel_a_b(g_accumulator_depth>0, g_accumulator_depth, 3); CONSTANT c_shiftram_io_delay : NATURAL := 3; -- common_shiftram data_in takes 3 cycles to emerge as data_out -- c_shiftram_delay is such that common_shiftram output aligns exactly with snk_in_arr. Functionally this -- means we aligned the current word to the corresponding previous word at the adder inputs. --- CONSTANT c_shiftram_delay : NATURAL := sel_a_b(g_accumulator_depth>0, g_accumulator_depth-c_shiftram_io_delay, 1); --- CONSTANT c_shift_w : NATURAL := sel_a_b(g_accumulator_depth>0, ceil_log2(g_accumulator_depth), 3); --- CONSTANT c_common_shiftram_shift_in : STD_LOGIC_VECTOR(c_shift_w-1 DOWNTO 0) := TO_UVEC(c_shiftram_delay, c_shift_w); --- --- SIGNAL corr_adder_snk_in_2arr_2 : t_dp_sosi_2arr_2(g_nof_inputs-1 DOWNTO 0); -- Array of pairs --- SIGNAL corr_adder_src_out_arr : t_dp_sosi_arr(g_nof_inputs-1 DOWNTO 0); --- --- SIGNAL common_shiftram_snk_in_arr : t_dp_sosi_arr(g_nof_inputs-1 DOWNTO 0); --- SIGNAL common_shiftram_src_out_arr : t_dp_sosi_arr(g_nof_inputs-1 DOWNTO 0); + CONSTANT c_shiftram_delay : NATURAL := c_accumulator_depth-c_shiftram_io_delay; + CONSTANT c_shift_w : NATURAL := ceil_log2(c_accumulator_depth); + CONSTANT c_common_shiftram_shift_in : STD_LOGIC_VECTOR(c_shift_w-1 DOWNTO 0) := TO_UVEC(c_shiftram_delay, c_shift_w); + + SIGNAL corr_adder_snk_in_2arr_2 : t_dp_sosi_2arr_2(g_nof_inputs-1 DOWNTO 0); -- Array of pairs + SIGNAL corr_adder_src_out_arr : t_dp_sosi_arr(g_nof_inputs-1 DOWNTO 0); + + SIGNAL common_shiftram_snk_in_arr : t_dp_sosi_arr(g_nof_inputs-1 DOWNTO 0); + SIGNAL common_shiftram_src_out_arr : t_dp_sosi_arr(g_nof_inputs-1 DOWNTO 0); BEGIN --- gen_accumulator: IF g_accumulator_depth>0 GENERATE --- ----------------------------------------------------------------------------- --- -- Adder inputs: current snk_in_arr + corresponding previous running sum --- -- from shiftram --- ----------------------------------------------------------------------------- --- gen_adder_inputs : FOR i IN 0 TO g_nof_inputs-1 GENERATE --- corr_adder_snk_in_2arr_2(i)(0) <= snk_in_arr(i); --- corr_adder_snk_in_2arr_2(i)(1) <= common_shiftram_src_out_arr(i); --- END GENERATE; --- --- ----------------------------------------------------------------------------- --- -- Complex adder stage --- ----------------------------------------------------------------------------- --- u_corr_adder : ENTITY work.corr_adder --- GENERIC MAP ( --- g_nof_inputs => g_nof_inputs --- ) --- PORT MAP ( --- clk => clk, --- rst => rst, --- --- snk_in_2arr_2 => corr_adder_snk_in_2arr_2, --- src_out_arr => corr_adder_src_out_arr --- ); --- --- ----------------------------------------------------------------------------- --- -- Write the current sum to RAM; RAM outputs delayed running sums that align --- -- at the adder inputs: --- -- . common_shiftram_src_out_arr = delayed corr_adder_src_out_arr --- ----------------------------------------------------------------------------- --- -- Concatenate real&imaginary parts --- gen_concat_complex : FOR i IN 0 TO g_nof_inputs-1 GENERATE --- common_shiftram_snk_in_arr(i).data(g_data_w-1 DOWNTO g_data_w/2) <= corr_adder_src_out_arr(i).re(g_data_w/2-1 DOWNTO 0); --- common_shiftram_snk_in_arr(i).data(g_data_w/2-1 DOWNTO 0) <= corr_adder_src_out_arr(i).im(g_data_w/2-1 DOWNTO 0); --- END GENERATE; --- --- gen_common_shiftram : FOR i IN 0 TO g_nof_inputs-1 GENERATE --- u_common_shiftram : ENTITY common_lib.common_shiftram --- GENERIC MAP ( --- g_data_w => g_data_w, --- g_nof_words => g_accumulator_depth --- ) --- PORT MAP ( --- rst => rst, --- clk => clk, --- --- data_in => common_shiftram_snk_in_arr(i).data(g_data_w-1 DOWNTO 0), --- data_in_val => common_shiftram_snk_in_arr(i).valid, --- data_in_shift => c_common_shiftram_shift_in, --- --- data_out => common_shiftram_src_out_arr(i).data(g_data_w-1 DOWNTO 0), --- data_out_val => common_shiftram_src_out_arr(i).valid, --- data_out_shift => OPEN --- ); --- END GENERATE; --- --- ----------------------------------------------------------------------------- --- -- Output 1/g_accumulator_depth words per stream --- -- . Not implemented yet. --- ----------------------------------------------------------------------------- --- src_out_arr <= common_shiftram_src_out_arr; --- --- END GENERATE; --- + gen_accumulator: IF g_accumulator_depth>0 GENERATE + ----------------------------------------------------------------------------- + -- Adder inputs: current snk_in_arr + corresponding previous running sum + -- from shiftram + ----------------------------------------------------------------------------- + gen_adder_inputs : FOR i IN 0 TO g_nof_inputs-1 GENERATE + corr_adder_snk_in_2arr_2(i)(0) <= snk_in_arr(i); + corr_adder_snk_in_2arr_2(i)(1) <= common_shiftram_src_out_arr(i); + END GENERATE; + + ----------------------------------------------------------------------------- + -- Complex adder stage + ----------------------------------------------------------------------------- + u_corr_adder : ENTITY work.corr_adder + GENERIC MAP ( + g_nof_inputs => g_nof_inputs + ) + PORT MAP ( + clk => clk, + rst => rst, + + snk_in_2arr_2 => corr_adder_snk_in_2arr_2, + src_out_arr => corr_adder_src_out_arr + ); + + ----------------------------------------------------------------------------- + -- Write the current sum to RAM; RAM outputs delayed running sums that align + -- at the adder inputs: + -- . common_shiftram_src_out_arr = delayed corr_adder_src_out_arr + ----------------------------------------------------------------------------- + -- Concatenate real&imaginary parts + gen_concat_complex : FOR i IN 0 TO g_nof_inputs-1 GENERATE + common_shiftram_snk_in_arr(i).data(g_data_w-1 DOWNTO g_data_w/2) <= corr_adder_src_out_arr(i).re(g_data_w/2-1 DOWNTO 0); + common_shiftram_snk_in_arr(i).data(g_data_w/2-1 DOWNTO 0) <= corr_adder_src_out_arr(i).im(g_data_w/2-1 DOWNTO 0); + END GENERATE; + + gen_common_shiftram : FOR i IN 0 TO g_nof_inputs-1 GENERATE + u_common_shiftram : ENTITY common_lib.common_shiftram + GENERIC MAP ( + g_data_w => g_data_w, + g_nof_words => c_accumulator_depth + ) + PORT MAP ( + rst => rst, + clk => clk, + + data_in => common_shiftram_snk_in_arr(i).data(g_data_w-1 DOWNTO 0), + data_in_val => common_shiftram_snk_in_arr(i).valid, + data_in_shift => c_common_shiftram_shift_in, + + data_out => common_shiftram_src_out_arr(i).data(g_data_w-1 DOWNTO 0), + data_out_val => common_shiftram_src_out_arr(i).valid, + data_out_shift => OPEN + ); + END GENERATE; + + ----------------------------------------------------------------------------- + -- Output 1/c_accumulator_depth words per stream + -- . Not implemented yet. + ----------------------------------------------------------------------------- + src_out_arr <= common_shiftram_src_out_arr; + + END GENERATE; + gen_bypass: IF g_accumulator_depth<1 GENERATE src_out_arr <= snk_in_arr; END GENERATE; -END rtl; +END str;