diff --git a/libraries/dsp/correlator/hdllib.cfg b/libraries/dsp/correlator/hdllib.cfg index 6e4e375559dba7dce9dc2b3fee3e74fa89967079..8072cbdb51bec8e4d7273772ef90d2892465f205 100644 --- a/libraries/dsp/correlator/hdllib.cfg +++ b/libraries/dsp/correlator/hdllib.cfg @@ -13,6 +13,7 @@ synth_files = $SVN/RadioHDL/trunk/libraries/dsp/correlator/src/vhdl/corr_multiplier.vhd $SVN/RadioHDL/trunk/libraries/dsp/correlator/src/vhdl/corr_adder.vhd $SVN/RadioHDL/trunk/libraries/dsp/correlator/src/vhdl/corr_accumulator.vhd + $SVN/RadioHDL/trunk/libraries/dsp/correlator/src/vhdl/corr_visibility_buffer.vhd $SVN/RadioHDL/trunk/libraries/dsp/correlator/src/vhdl/correlator.vhd test_bench_files = diff --git a/libraries/dsp/correlator/src/vhdl/corr_visibility_buffer.vhd b/libraries/dsp/correlator/src/vhdl/corr_visibility_buffer.vhd new file mode 100644 index 0000000000000000000000000000000000000000..4d0cc9ec599de47eb0ab4feaddee14db9ac0fb86 --- /dev/null +++ b/libraries/dsp/correlator/src/vhdl/corr_visibility_buffer.vhd @@ -0,0 +1,127 @@ +-------------------------------------------------------------------------------- +-- +-- Copyright (C) 2014 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib, dp_lib; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE common_lib.common_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; + +-- Purpose: +-- . Buffer the visibilities during folding +-- Description: +-- . Consists of an array of FIFOs that are read out periodically + +ENTITY corr_visibility_buffer IS + GENERIC ( + g_nof_inputs : NATURAL; -- Number of input streams + g_nof_channels : NATURAL; -- Number of channels per visibility + g_data_w : NATURAL -- Complex input data width + ); + PORT ( + rst : IN STD_LOGIC; + clk : IN STD_LOGIC; + + snk_in_arr : IN t_dp_sosi_arr(g_nof_inputs-1 DOWNTO 0); + src_out_arr : OUT t_dp_sosi_arr(g_nof_inputs-1 DOWNTO 0) + ); +END corr_visibility_buffer; + +ARCHITECTURE str OF corr_visibility_buffer IS + + SIGNAL dp_fifo_sc_src_out_arr : t_dp_sosi_arr(g_nof_inputs-1 DOWNTO 0); + SIGNAL dp_fifo_sc_src_in_arr : t_dp_siso_arr(g_nof_inputs-1 DOWNTO 0); + +BEGIN + + ------------------------------------------------------------------------------ + -- Buffer the visibilities before the folding stage. + -- . All accumulators output blocks of visibilities at the same time. We need + -- to buffer the visibilities to source them to the folder at the right + -- pace. + ------------------------------------------------------------------------------ + gen_dp_fifo_sc : FOR i IN 0 TO g_nof_inputs-1 GENERATE + u_dp_fifo_sc : ENTITY dp_lib.dp_fifo_sc + GENERIC MAP ( + g_data_w => 2*g_data_w, + g_use_ctrl => FALSE, + g_use_complex => TRUE, + g_fifo_size => g_nof_channels, + g_fifo_af_margin => 0 + ) + PORT MAP ( + rst => rst, + clk => clk, + + wr_ful => OPEN, + usedw => OPEN, + rd_emp => OPEN, + + snk_out => OPEN, + snk_in => snk_in_arr(i), + src_in => dp_fifo_sc_src_in_arr(i), + src_out => dp_fifo_sc_src_out_arr(i) + ); + END GENERATE; + + ------------------------------------------------------------------------------ + -- Read out the FIFOs such that dp_fifo_sc_src_out_arr only carries one valid + -- word per cycle. This allows folding (multiplexing) into one stream without + -- losing data (example for 16 streams): + -- + -- |<--g_nof_invalid_per_valid-->| + -- 0) [0] [1] .. + -- 1) | [0] . [1] + -- 2) | [0] . [1] + -- 3) | [0] . [1] + -- 4) | [0] . [1] + -- 5) | [0] . [1] + -- 6) | [0] . [1] + -- 7) | [0] . [1] + -- 8) | [0] . [1] + -- 9) | [0] . [1] + -- 10) | [0] . [1] + -- 11) | [0] . [1] + -- 12) | [0] . [1] + -- 13) | [0] . [1] + -- 14) | [0] . [1] + -- 15) |<---g_init_valid_delay(15)-->[0] [1] + ------------------------------------------------------------------------------ + gen_dp_src_out_timer : FOR i IN 0 TO g_nof_inputs-1 GENERATE + u_dp_src_out_timer : ENTITY dp_lib.dp_src_out_timer + GENERIC MAP ( + g_init_valid_delay => i, --relative to dp_fifo_sc_src_out_arr(i).valid + g_nof_invalid_per_valid => g_nof_inputs + ) + PORT MAP ( + rst => rst, + clk => clk, + + init_valid_delay_ref => snk_in_arr(i).valid, + + snk_in => dp_fifo_sc_src_out_arr(i), + snk_out => dp_fifo_sc_src_in_arr(i) + ); + END GENERATE; + + src_out_arr <= dp_fifo_sc_src_out_arr; + +END str; diff --git a/libraries/dsp/correlator/src/vhdl/correlator.vhd b/libraries/dsp/correlator/src/vhdl/correlator.vhd index 715e115a74f42afd3ded8c0401c2f43709e2a5f3..ab8b6d69e31075e8760a98c726ac751d351f3d97 100644 --- a/libraries/dsp/correlator/src/vhdl/correlator.vhd +++ b/libraries/dsp/correlator/src/vhdl/correlator.vhd @@ -51,7 +51,7 @@ END correlator; ARCHITECTURE str OF correlator IS - CONSTANT c_nof_visibilities : NATURAL := (g_nof_inputs*(g_nof_inputs+1))/2; + CONSTANT c_nof_visibilities : NATURAL := (g_nof_inputs*(g_nof_inputs+1))/2; ----------------------------------------------------------------------------- -- The array of multiplier input streams can be folded, e.g.: @@ -62,24 +62,23 @@ ARCHITECTURE str OF correlator IS -- . c_nof_visibilities=10, g_nof_pre_mult_folds=4 -> c_nof_mults= 1 -- . c_nof_visibilities=10, g_nof_pre_mult_folds<0 -> c_nof_mults= 1 ----------------------------------------------------------------------------- - CONSTANT c_nof_mults : NATURAL := sel_a_b(g_nof_pre_mult_folds>=0, ceil_div(c_nof_visibilities, ceil_pow2(g_nof_pre_mult_folds)), 1); + CONSTANT c_nof_mults : NATURAL := sel_a_b(g_nof_pre_mult_folds>=0, ceil_div(c_nof_visibilities, ceil_pow2(g_nof_pre_mult_folds)), 1); -- We can multiplex the accumulator outputs onto one stream as long as the integration period is -- equal to or larger than the number of accumulator outputs. - CONSTANT c_integration_period : NATURAL := largest(g_integration_period, c_nof_mults); + CONSTANT c_integration_period : NATURAL := largest(g_integration_period, c_nof_mults); - CONSTANT c_acc_data_w : NATURAL := ceil_log2(c_integration_period*(pow2(g_data_w)-1)); + CONSTANT c_acc_data_w : NATURAL := ceil_log2(c_integration_period*(pow2(g_data_w)-1)); - SIGNAL corr_permutator_src_out_2arr_2 : t_dp_sosi_2arr_2(g_nof_inputs*(g_nof_inputs+1)/2-1 DOWNTO 0); -- Array of pairs - SIGNAL corr_folder_snk_in_2arr_2 : t_dp_sosi_2arr_2(g_nof_inputs*(g_nof_inputs+1)/2-1 DOWNTO 0); -- Array of pairs, not folded yet - SIGNAL corr_folder_src_out_2arr_2 : t_dp_sosi_2arr_2(g_nof_inputs*(g_nof_inputs+1)/2-1 DOWNTO 0); -- Array of pairs, not folded yet - SIGNAL corr_multiplier_src_out_arr : t_dp_sosi_arr(c_nof_mults-1 DOWNTO 0); - SIGNAL corr_accumulator_snk_in_arr : t_dp_sosi_arr(c_nof_mults-1 DOWNTO 0); - SIGNAL corr_accumulator_src_out_arr : t_dp_sosi_arr(c_nof_mults-1 DOWNTO 0); - SIGNAL dp_fifo_sc_snk_in_arr : t_dp_sosi_arr(c_nof_mults-1 DOWNTO 0); - SIGNAL dp_fifo_sc_src_out_arr : t_dp_sosi_arr(c_nof_mults-1 DOWNTO 0); - SIGNAL dp_fifo_sc_src_in_arr : t_dp_siso_arr(c_nof_mults-1 DOWNTO 0); - SIGNAL corr_folder_src_out_arr : t_dp_sosi_arr(1-1 DOWNTO 0); + SIGNAL corr_permutator_src_out_2arr_2 : t_dp_sosi_2arr_2(g_nof_inputs*(g_nof_inputs+1)/2-1 DOWNTO 0); -- Array of pairs + SIGNAL corr_folder_snk_in_2arr_2 : t_dp_sosi_2arr_2(g_nof_inputs*(g_nof_inputs+1)/2-1 DOWNTO 0); -- Array of pairs, not folded yet + SIGNAL corr_folder_src_out_2arr_2 : t_dp_sosi_2arr_2(g_nof_inputs*(g_nof_inputs+1)/2-1 DOWNTO 0); -- Array of pairs, not folded yet + SIGNAL corr_multiplier_src_out_arr : t_dp_sosi_arr(c_nof_mults-1 DOWNTO 0); + SIGNAL corr_accumulator_snk_in_arr : t_dp_sosi_arr(c_nof_mults-1 DOWNTO 0); + SIGNAL corr_accumulator_src_out_arr : t_dp_sosi_arr(c_nof_mults-1 DOWNTO 0); + SIGNAL corr_visibility_buffer_snk_in_arr : t_dp_sosi_arr(c_nof_mults-1 DOWNTO 0); + SIGNAL corr_visibility_buffer_src_out_arr : t_dp_sosi_arr(c_nof_mults-1 DOWNTO 0); + SIGNAL corr_folder_src_out_arr : t_dp_sosi_arr(1-1 DOWNTO 0); BEGIN @@ -188,79 +187,28 @@ BEGIN clk => clk, snk_in => corr_accumulator_src_out_arr(i), - src_out => dp_fifo_sc_snk_in_arr(i) + src_out => corr_visibility_buffer_snk_in_arr(i) ); END GENERATE; ------------------------------------------------------------------------------ -- Buffer the visibilities before the folding stage. -- . All accumulators output blocks of visibilities at the same time. We need - -- to buffer the visibilities so we can take our time to multiplex them - -- onto one stream. + -- to buffer the visibilities to source them to the folder at the right + -- pace. ------------------------------------------------------------------------------ - gen_dp_fifo_sc : FOR i IN 0 TO c_nof_mults-1 GENERATE - u_dp_fifo_sc : ENTITY dp_lib.dp_fifo_sc - GENERIC MAP ( - g_data_w => 2*c_acc_data_w, - g_use_ctrl => FALSE, - g_use_complex => TRUE, - g_fifo_size => 64, - g_fifo_af_margin => 0 - ) - PORT MAP ( - rst => rst, - clk => clk, - - wr_ful => OPEN, - usedw => OPEN, - rd_emp => OPEN, - - snk_out => OPEN, - snk_in => dp_fifo_sc_snk_in_arr(i), - src_in => dp_fifo_sc_src_in_arr(i), - src_out => dp_fifo_sc_src_out_arr(i) - ); - END GENERATE; - - ------------------------------------------------------------------------------ - -- Read out the FIFOs such that dp_fifo_sc_src_out_arr only carries one valid - -- word per cycle. This allows folding (multiplexing) into one stream without - -- losing data (example for 16 streams): - -- - -- |<--g_nof_invalid_per_valid-->| - -- 0) [0] [1] .. - -- 1) | [0] . [1] - -- 2) | [0] . [1] - -- 3) | [0] . [1] - -- 4) | [0] . [1] - -- 5) | [0] . [1] - -- 6) | [0] . [1] - -- 7) | [0] . [1] - -- 8) | [0] . [1] - -- 9) | [0] . [1] - -- 10) | [0] . [1] - -- 11) | [0] . [1] - -- 12) | [0] . [1] - -- 13) | [0] . [1] - -- 14) | [0] . [1] - -- 15) |<---g_init_valid_delay(15)-->[0] [1] - ------------------------------------------------------------------------------ - gen_dp_src_out_timer : FOR i IN 0 TO c_nof_mults-1 GENERATE - u_dp_src_out_timer : ENTITY dp_lib.dp_src_out_timer - GENERIC MAP ( - g_init_valid_delay => i, --relative to dp_fifo_sc_src_out_arr(i).valid - g_nof_invalid_per_valid => c_nof_mults - ) - PORT MAP ( - rst => rst, - clk => clk, - - init_valid_delay_ref => dp_fifo_sc_snk_in_arr(i).valid, + u_corr_visibility_buffer : ENTITY work.corr_visibility_buffer + GENERIC MAP ( + g_nof_inputs => c_nof_mults, + g_data_w => c_acc_data_w + ) + PORT MAP ( + clk => clk, + rst => rst, - snk_in => dp_fifo_sc_src_out_arr(i), - snk_out => dp_fifo_sc_src_in_arr(i) - ); - END GENERATE; + snk_in_arr => corr_visibility_buffer_snk_in_arr, + src_out_arr => corr_visibility_buffer_src_out_arr + ); ------------------------------------------------------------------------------ -- Fold onto one stream @@ -274,7 +222,7 @@ BEGIN rst => rst, clk => clk, - snk_in_arr => dp_fifo_sc_src_out_arr, + snk_in_arr => corr_visibility_buffer_src_out_arr, src_out_arr => corr_folder_src_out_arr );