diff --git a/libraries/dsp/correlator/src/vhdl/corr_accumulator.vhd b/libraries/dsp/correlator/src/vhdl/corr_accumulator.vhd index 7954ecb0ee58808540e0fde2ad8ac1f4f745d113..a1b71ddbc14d7fa7eed1571e404ce8112514aecb 100644 --- a/libraries/dsp/correlator/src/vhdl/corr_accumulator.vhd +++ b/libraries/dsp/correlator/src/vhdl/corr_accumulator.vhd @@ -35,7 +35,7 @@ USE dp_lib.dp_stream_pkg.ALL; ENTITY corr_accumulator IS GENERIC ( g_nof_inputs : NATURAL; -- Number of input streams - g_nof_acc_per_input : NATURAL; -- Number of accumulators to keep per input stream + g_nof_acc_per_input : NATURAL; -- Number of accumulators to keep per input stream (a.k.a. channels) g_nof_words_to_acc : NATURAL; -- Number of words to accumulate g_data_w : NATURAL -- Complex input data width ); @@ -56,11 +56,16 @@ ARCHITECTURE str OF corr_accumulator IS -- 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_io_delay : NATURAL := 4; -- common_shiftram data_in takes 4 cycles to emerge as data_out - CONSTANT c_shiftram_delay : NATURAL := g_nof_acc_per_input-c_shiftram_io_delay-1; + CONSTANT c_shiftram_delay : NATURAL := g_nof_acc_per_input-c_shiftram_io_delay-2; CONSTANT c_shift_w : NATURAL := ceil_log2(g_nof_acc_per_input); CONSTANT c_common_shiftram_shift_in : STD_LOGIC_VECTOR(c_shift_w-1 DOWNTO 0) := TO_UVEC(c_shiftram_delay, c_shift_w); + -- Counter to keep track of the total numer of accumulations so we know when to reset accumulator to zero + SIGNAL acc_cnt : STD_LOGIC_VECTOR(ceil_log2(g_nof_acc_per_input*g_nof_words_to_acc)-1 DOWNTO 0); + SIGNAL nxt_acc_cnt : STD_LOGIC_VECTOR(ceil_log2(g_nof_acc_per_input*g_nof_words_to_acc)-1 DOWNTO 0); + SIGNAL corr_adder_snk_in_2arr_2 : t_dp_sosi_2arr_2(g_nof_inputs-1 DOWNTO 0); -- Array of pairs + SIGNAL nxt_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); @@ -69,21 +74,40 @@ ARCHITECTURE str OF corr_accumulator IS TYPE t_common_shiftram_data_out_shift_arr IS ARRAY(g_nof_inputs-1 DOWNTO 0) OF STD_LOGIC_VECTOR(c_shift_w-1 DOWNTO 0); SIGNAL common_shiftram_data_out_shift_arr : t_common_shiftram_data_out_shift_arr; + + BEGIN ----------------------------------------------------------------------------- -- Adder inputs: current snk_in_arr + corresponding previous running sum - -- from shiftram + -- from shiftram. + -- When we've completed one integration period for each all the channels, + -- we'll feed zeros into the second adder input to reset the accumulator value + -- for each channel. ----------------------------------------------------------------------------- + nxt_acc_cnt <= (OTHERS=>'0') WHEN TO_UINT(acc_cnt)=g_nof_acc_per_input*g_nof_words_to_acc-1 ELSE + INCR_UVEC(acc_cnt, 1) WHEN snk_in_arr(0).valid = '1' ELSE acc_cnt; + gen_adder_inputs : FOR i IN 0 TO g_nof_inputs-1 GENERATE - -- Incoming data width: g_data_w interpreted as c_acc_data_w - corr_adder_snk_in_2arr_2(i)(0) <= snk_in_arr(i); - -- Accumulator data width: c_acc_data_w - corr_adder_snk_in_2arr_2(i)(1).valid <= common_shiftram_src_out_arr(i).valid; - corr_adder_snk_in_2arr_2(i)(1).re(c_acc_data_w-1 DOWNTO 0) <= common_shiftram_src_out_arr(i).data(2*c_acc_data_w-1 DOWNTO c_acc_data_w); - corr_adder_snk_in_2arr_2(i)(1).im(c_acc_data_w-1 DOWNTO 0) <= common_shiftram_src_out_arr(i).data( c_acc_data_w-1 DOWNTO 0); + nxt_corr_adder_snk_in_2arr_2(i)(0) <= snk_in_arr(i); + nxt_corr_adder_snk_in_2arr_2(i)(1).valid <= common_shiftram_src_out_arr(i).valid; + nxt_corr_adder_snk_in_2arr_2(i)(1).re(c_acc_data_w-1 DOWNTO 0) <= (OTHERS=>'0') WHEN TO_UINT(acc_cnt)<=g_nof_acc_per_input-1 ELSE + common_shiftram_src_out_arr(i).data(2*c_acc_data_w-1 DOWNTO c_acc_data_w); + nxt_corr_adder_snk_in_2arr_2(i)(1).im(c_acc_data_w-1 DOWNTO 0) <= (OTHERS=>'0') WHEN TO_UINT(acc_cnt)<=g_nof_acc_per_input-1 ELSE + common_shiftram_src_out_arr(i).data( c_acc_data_w-1 DOWNTO 0); END GENERATE; + p_clk : PROCESS (clk, rst) + BEGIN + IF rst='1' THEN + acc_cnt <= (OTHERS=>'0'); + corr_adder_snk_in_2arr_2 <= (OTHERS=>(OTHERS=>c_dp_sosi_rst)); + ELSIF rising_edge(clk) THEN + acc_cnt <= nxt_acc_cnt; + corr_adder_snk_in_2arr_2 <= nxt_corr_adder_snk_in_2arr_2; + END IF; + END PROCESS; + ----------------------------------------------------------------------------- -- Complex adder stage -----------------------------------------------------------------------------