Skip to content
Snippets Groups Projects
Commit a1b494df authored by Daniel van der Schuur's avatar Daniel van der Schuur
Browse files

-Using RESIZE_DP_DSP_DATA in corr_accumulator;

-Fixed corr_adder sign extension;
-Added g_inter_channel_delay to corr_visibility_buffer and fixed the 
 calculation of dp_src_out_timer's generics based on constants;
-Renamed g_nof_input_folds to g_input_unfold_factor in correlator.vhd;
-Added generics to tb_correlator to indicate which ones can be user set;
-Fixed the output location of the .rec file (moved to tb dir);
-Verified in sim using verify_correlator.py.
parent deba32f5
No related branches found
No related tags found
No related merge requests found
......@@ -163,8 +163,10 @@ BEGIN
-- of zeros initially.
-----------------------------------------------------------------------------
gen_src_out_arr : FOR i IN 0 TO g_nof_inputs-1 GENERATE
nxt_src_out_arr(i).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);
nxt_src_out_arr(i).im(c_acc_data_w-1 DOWNTO 0) <= common_shiftram_src_out_arr(i).data( c_acc_data_w-1 DOWNTO 0);
-- nxt_src_out_arr(i).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);
-- nxt_src_out_arr(i).im(c_acc_data_w-1 DOWNTO 0) <= common_shiftram_src_out_arr(i).data( c_acc_data_w-1 DOWNTO 0);
nxt_src_out_arr(i).re <= RESIZE_DP_DSP_DATA(common_shiftram_src_out_arr(i).data(2*c_acc_data_w-1 DOWNTO c_acc_data_w));
nxt_src_out_arr(i).im <= RESIZE_DP_DSP_DATA(common_shiftram_src_out_arr(i).data( c_acc_data_w-1 DOWNTO 0));
nxt_src_out_arr(i).valid <= '1' WHEN TO_UINT(acc_cnt)<g_nof_accumulators AND common_shiftram_src_out_arr(0).valid='1' ELSE '0';
nxt_src_out_arr(i).sop <= '1' WHEN TO_UINT(acc_cnt)=0 AND common_shiftram_src_out_arr(0).valid='1' ELSE '0';
......
......@@ -108,24 +108,24 @@ BEGIN
-- range (we don't need an extra bit for that).
-- . We do need the extra bit itself though, as it is the sign bit.
-----------------------------------------------------------------------------
gen_output_range : FOR i IN 0 TO g_nof_inputs-1 GENERATE
-- Wire the adder output to ranged_common_complex_add_sub_src_out_arr, minus the two MSbits
ranged_common_complex_add_sub_src_out_arr(i).re(g_data_w-1-1 DOWNTO 0) <= common_complex_add_sub_src_out_arr(i).re(g_data_w-1-1 DOWNTO 0);
ranged_common_complex_add_sub_src_out_arr(i).im(g_data_w-1-1 DOWNTO 0) <= common_complex_add_sub_src_out_arr(i).im(g_data_w-1-1 DOWNTO 0);
-- Don't assign the adder's MSbit-1 as it shouldn't toggle (because our adder input width is already wide enough)
-- NC <= common_complex_add_sub_src_out_arr(i).re(g_data_w-1);
-- NC <= common_complex_add_sub_src_out_arr(i).im(g_data_w-1);
-- Wire up the adder's MSbit (sign) bit
ranged_common_complex_add_sub_src_out_arr(i).re(g_data_w-1) <= common_complex_add_sub_src_out_arr(i).re(g_data_w);
ranged_common_complex_add_sub_src_out_arr(i).im(g_data_w-1) <= common_complex_add_sub_src_out_arr(i).im(g_data_w);
END GENERATE;
-- gen_output_range : FOR i IN 0 TO g_nof_inputs-1 GENERATE
-- -- Wire the adder output to ranged_common_complex_add_sub_src_out_arr, minus the two MSbits
-- ranged_common_complex_add_sub_src_out_arr(i).re(g_data_w-1-1 DOWNTO 0) <= common_complex_add_sub_src_out_arr(i).re(g_data_w-1-1 DOWNTO 0);
-- ranged_common_complex_add_sub_src_out_arr(i).im(g_data_w-1-1 DOWNTO 0) <= common_complex_add_sub_src_out_arr(i).im(g_data_w-1-1 DOWNTO 0);
-- -- Don't assign the adder's MSbit-1 as it shouldn't toggle (because our adder input width is already wide enough)
-- -- NC <= common_complex_add_sub_src_out_arr(i).re(g_data_w-1);
-- -- NC <= common_complex_add_sub_src_out_arr(i).im(g_data_w-1);
-- -- Wire up the adder's MSbit (sign) bit
-- ranged_common_complex_add_sub_src_out_arr(i).re(g_data_w-1) <= common_complex_add_sub_src_out_arr(i).re(g_data_w);
-- ranged_common_complex_add_sub_src_out_arr(i).im(g_data_w-1) <= common_complex_add_sub_src_out_arr(i).im(g_data_w);
-- END GENERATE;
-----------------------------------------------------------------------------
-- Finally, extend the sign bit for human readability
-----------------------------------------------------------------------------
gen_sign_extend : FOR i IN 0 TO g_nof_inputs-1 GENERATE
src_out_arr(i).re <= RESIZE_DP_DSP_DATA(ranged_common_complex_add_sub_src_out_arr(i).re(g_data_w-1 DOWNTO 0));
src_out_arr(i).im <= RESIZE_DP_DSP_DATA(ranged_common_complex_add_sub_src_out_arr(i).im(g_data_w-1 DOWNTO 0));
src_out_arr(i).re <= RESIZE_DP_DSP_DATA(common_complex_add_sub_src_out_arr(i).re(g_data_w-1 DOWNTO 0));
src_out_arr(i).im <= RESIZE_DP_DSP_DATA(common_complex_add_sub_src_out_arr(i).im(g_data_w-1 DOWNTO 0));
END GENERATE;
END str;
......@@ -43,7 +43,7 @@ ENTITY corr_visibility_buffer IS
g_buffer_depth : NATURAL; -- Number of words to buffer
g_data_w : NATURAL; -- Complex input data width
g_nof_pre_mult_folds : NATURAL; -- Nof times the data has been folded
g_integration_period : NATURAL
g_inter_channel_delay : NATURAL -- Nof delay cycles between output channels
);
PORT (
rst : IN STD_LOGIC;
......@@ -56,17 +56,37 @@ END corr_visibility_buffer;
ARCHITECTURE str OF corr_visibility_buffer IS
-- The output block size required so the folder outputs all visibilities per channel
CONSTANT c_output_block_len : NATURAL := pow2(g_nof_pre_mult_folds);
------------------------------------------------------------------------------
-- Example input: 6 visibilities, non-folded (g_nof_inputs = 6,
-- g_nof_pre_mult_folds = 0)
-- The improtance of timing the FIFOs is depiced below:
-- ====================
-- Untimed FIFO output:
-- ====================
-- dp_fifo_sc_src_out_arr(0) -> [ch0, ch1, .. chN-1]
-- dp_fifo_sc_src_out_arr(1) -> [ch0, ch1, .. chN-1]
-- dp_fifo_sc_src_out_arr(2) -> [ch0, ch1, .. chN-1]
-- dp_fifo_sc_src_out_arr(3) -> [ch0, ch1, .. chN-1]
-- dp_fifo_sc_src_out_arr(4) -> [ch0, ch1, .. chN-1]
-- dp_fifo_sc_src_out_arr(5) -> [ch0, ch1, .. chN-1]
-- ====================
-- Timed FIFO output:
-- ====================
-- dp_fifo_sc_src_out_arr(0) -> [ch0] [ch1]
-- dp_fifo_sc_src_out_arr(1) -> [ch0] [ch1]
-- dp_fifo_sc_src_out_arr(2) -> [ch0] [ch1]
-- dp_fifo_sc_src_out_arr(3) -> [ch0] [ch1]
-- dp_fifo_sc_src_out_arr(4) -> [ch0] [ch1]
-- dp_fifo_sc_src_out_arr(5) -> [ch0] [ch1]
--
-- The above timed FIFO output allows the 6 streams to be interleaved into
-- one stream, putting the channels back-to-back in the right order.
-- The minimum period to wait so the folder does not miss data
CONSTANT c_minimum_block_period : NATURAL := g_nof_inputs*c_output_block_len;
-- The number of visibilities interleaved onto one input stream
CONSTANT c_vis_block_len : NATURAL := pow2(g_nof_pre_mult_folds);
-- The channel blocks on the folder output will be c_minimum_block_period long.
-- Wait the maximum time before outputting the next one to yield a constant data rate.
-- Note: insertion of a gap block is only possible if
-- g_integration_period/2 >= c_minimum_block_period.
CONSTANT c_block_valid_ratio : NATURAL := largest(1, g_integration_period/c_minimum_block_period);
-- The minimum period to wait so the folder does not miss data
CONSTANT c_channel_block_length : NATURAL := g_nof_inputs*c_vis_block_len;
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);
......@@ -106,32 +126,33 @@ BEGIN
------------------------------------------------------------------------------
-- 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 with c_output_block_len=1):
-- losing data (example for 16 streams with c_vis_block_len=1):
--
-- |<---c_minimum_block_period---->|
-- 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]
-- |<-----------------------g_block_period-------------------->|
-- |<---c_channel_block_length---->|<--g_inter_channel_delay-->|
-- 0) [0] . [1]
-- 1) | [0] . . [1]
-- 2) | [0] . . [1]
-- 3) | [0] . . [1]
-- 4) | [0] . . [1]
-- 5) | [0] . . ..
-- 6) | [0] . .
-- 7) | [0] . .
-- 8) | [0] . .
-- 9) | [0] . .
-- 10) | [0] . .
-- 11) | [0] . .
-- 12) | [0] . .
-- 13) | [0] . .
-- 14) | [0] . .
-- 15) |<---g_init_valid_delay(15)-->[0] .
------------------------------------------------------------------------------
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*c_output_block_len, --relative to dp_fifo_sc_src_out_arr(i).valid
g_block_period => c_block_valid_ratio*c_minimum_block_period*c_output_block_len,
g_block_len => c_output_block_len
g_init_valid_delay => i*c_vis_block_len, --relative to dp_fifo_sc_src_out_arr(i).valid
g_block_period => c_channel_block_length+g_inter_channel_delay,
g_block_len => c_vis_block_len
)
PORT MAP (
rst => rst,
......
......@@ -33,7 +33,7 @@ USE dp_lib.dp_stream_pkg.ALL;
ENTITY correlator IS
GENERIC (
g_nof_input_streams : NATURAL;
g_nof_input_folds : NATURAL := 0; -- 2**g_nof_input_folds = number of inputs carried on one input stream
g_input_unfold_factor : NATURAL := 0; -- 2**g_input_unfold_factor = number of inputs carried on one input stream
g_nof_pre_mult_folds : NATURAL := 0; -- Number of pre-multiplier stage folds.
g_data_w : NATURAL := 16; -- Complex data width
g_conjugate : BOOLEAN := TRUE;
......@@ -52,7 +52,7 @@ END correlator;
ARCHITECTURE str OF correlator IS
CONSTANT c_nof_inputs : NATURAL := g_nof_input_streams*pow2(g_nof_input_folds);
CONSTANT c_nof_inputs : NATURAL := g_nof_input_streams*pow2(g_input_unfold_factor);
CONSTANT c_nof_visibilities : NATURAL := (c_nof_inputs*(c_nof_inputs+1))/2;
-----------------------------------------------------------------------------
......@@ -97,7 +97,7 @@ BEGIN
u_corr_unfolder : ENTITY work.corr_unfolder
GENERIC MAP (
g_nof_inputs => g_nof_input_streams,
g_nof_unfolds => g_nof_input_folds
g_nof_unfolds => g_input_unfold_factor
)
PORT MAP (
rst => rst,
......@@ -114,7 +114,7 @@ BEGIN
gen_dp_pipeline_corr_unfolder_src_out_arr : FOR i IN 0 TO c_nof_inputs-1 GENERATE
u_dp_pipeline : ENTITY dp_lib.dp_pipeline
GENERIC MAP (
g_pipeline => 0 + (pow2(g_nof_input_folds) - i REM pow2(g_nof_input_folds)-1)
g_pipeline => 0 + (pow2(g_input_unfold_factor) - i REM pow2(g_input_unfold_factor)-1)
)
PORT MAP (
rst => rst,
......@@ -189,6 +189,11 @@ BEGIN
-- rate on the highest stream index. We don't want that (because
-- common_shiftram in corr_accumulator does not support holes in the data),
-- so override the valid with corr_folder_src_out_2arr_2(0).valid in that case.
-- . NOTE!!!!!!!!!!
-- . If you set c_integration_period=0, the code sets JUST the right integration
-- period to yield 100% valid data on the output stream. As mentioned above,
-- if you have an uneven numer of inputs one 50% valid streams will get overriden
-- to 100% causing a FIFO overflow in the visibility buffer.
p_override_valid: PROCESS(corr_folder_src_out_2arr_2)
BEGIN
corr_multiplier_snk_in_2arr_2 <= corr_folder_src_out_2arr_2;
......@@ -279,7 +284,7 @@ BEGIN
g_data_w => c_acc_data_w,
g_buffer_depth => c_nof_accumulators,
g_nof_pre_mult_folds => g_nof_pre_mult_folds,
g_integration_period => c_integration_period
g_inter_channel_delay => 0
)
PORT MAP (
clk => clk,
......
gen_correlator_snk_in_arr_list.py
gen_correlator_snk_in_arr_hex.py
# Produceer dezelfde list als correlator_src_out_arr0.rec.
# correlator_snk_in_arr komt van gen_hex_files_complex_subbands.py -> gelijktrekken.
correlator_snk_in_arr =
def correlator(snk_in_arr):
......@@ -21,6 +21,8 @@
###############################################################################
from common import *
import matplotlib
matplotlib.use('TkAgg')
from common_dsp import *
import test_case
......@@ -31,7 +33,7 @@ import pi_diag_data_buffer
# Description:
# Usage:
NOF_INPUTS = 24
NOF_INPUTS = 10
NOF_VISIBILITIES = (NOF_INPUTS*(NOF_INPUTS+1))/2
BUFFER_WIDTH = 64
......
......@@ -46,7 +46,7 @@ NOF_PRE_MULT_FOLDS = 2
NOF_INPUT_FOLDS = 0 # =< NOF_PRE_MULT_FOLDS
USE_NEW_REC_FILE = False #True = don't use outdated .rec file; wait for new one.
USE_NEW_REC_FILE = True #True = don't use outdated .rec file; wait for new one.
PLOT_CORR_OUT_PHASES = True # Plot the correlator output phases of channel 0 of both the VHDL and the Model
NOF_VISIBILITIES = (NOF_INPUTS*(NOF_INPUTS+1))/2
......
......@@ -30,27 +30,39 @@ USE mm_lib.mm_file_pkg.ALL;
USE mm_lib.mm_file_unb_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
-- Notes on pairing generics:
-- . g_nof_inputs = even, g_nof_input_folds does not leave a remainder
-- . c_nof_visibilities=odd, don't use g_nof_pre_mult_folds>0
-- . c_nof_visibilities=even, make sure g_nof_pre_mult_folds does not leave remainder
ENTITY tb_correlator IS
GENERIC (
g_nof_inputs : NATURAL := 7;
g_nof_channels : NATURAL := 8;
g_nof_pre_mult_folds : NATURAL := 2;-- Make sure c_nof_visibilities can be folded this many times
g_nof_input_folds : NATURAL := 0 -- =< g_nof_pre_mult_folds. Use an even g_nof_inputs.
);
END tb_correlator;
ARCHITECTURE tb OF tb_correlator IS
CONSTANT c_nof_inputs : NATURAL := 10;
CONSTANT c_nof_input_folds : NATURAL := 1;
CONSTANT c_nof_input_streams : NATURAL := c_nof_inputs / pow2(c_nof_input_folds);
CONSTANT c_nof_pre_mult_folds : NATURAL := 1;
CONSTANT c_complex_data_w : NATURAL := 8;
CONSTANT c_nof_input_streams : NATURAL := g_nof_inputs / pow2(g_nof_input_folds);
CONSTANT c_conjugate : BOOLEAN := TRUE;
CONSTANT c_nof_channels : NATURAL := 64;
CONSTANT c_integration_period : NATURAL := 0;
CONSTANT c_nof_visibilities : NATURAL := (g_nof_inputs*(g_nof_inputs+1))/2;
CONSTANT c_nof_visibilities : NATURAL := (c_nof_inputs*(c_nof_inputs+1))/2;
-- Gap size on the correlator input depends on the number of folds
CONSTANT c_block_period : NATURAL := 1; --pow2(c_nof_pre_mult_folds); -- To do: figure out the block period as function of both folding factors.
-- Folding rules:
-- . g_nof_input_folds=g_nof_pre_mult_folds : no gaps are needed/desired in the input data.
-- . g_nof_input_folds<g_nof_pre_mult_folds : gaps are required in the input data
-- . g_nof_input_folds>g_nof_pre_mult_folds : is not allowed
-- . Produces unnecessary/undesired gaps in the multiplier output
CONSTANT c_input_gaps_needed : BOOLEAN := g_nof_input_folds<g_nof_pre_mult_folds;
CONSTANT c_block_period : NATURAL := sel_a_b(c_input_gaps_needed, pow2(g_nof_pre_mult_folds-g_nof_input_folds), 1);
-- Block generator
CONSTANT c_bg_block_size : NATURAL := c_nof_channels*pow2(c_nof_input_folds);
CONSTANT c_bg_block_size : NATURAL := g_nof_channels*pow2(g_nof_input_folds);
CONSTANT c_bg_gapsize : NATURAL := c_bg_block_size*(c_block_period-1);
-- Indicate the integration period with the sync. In the correlator, the
......@@ -132,7 +144,7 @@ BEGIN
g_nof_output_streams => c_nof_input_streams,
g_buf_dat_w => 2*c_complex_data_w,
g_buf_addr_w => ceil_log2(TO_UINT(c_bg_ctrl.samples_per_packet)),
g_file_name_prefix => "../../../libraries/dsp/correlator/src/hex/complex_subbands_" & NATURAL'IMAGE(c_complex_data_w) & "b_" & "fold_" & NATURAL'IMAGE(c_nof_input_folds),
g_file_name_prefix => "../../../libraries/dsp/correlator/src/hex/complex_subbands_" & NATURAL'IMAGE(c_complex_data_w) & "b_" & "fold_" & NATURAL'IMAGE(g_nof_input_folds),
g_diag_block_gen_rst => c_bg_ctrl
)
PORT MAP (
......@@ -197,11 +209,11 @@ BEGIN
u_correlator : ENTITY work.correlator
GENERIC MAP (
g_nof_input_streams => c_nof_input_streams,
g_nof_input_folds => c_nof_input_folds,
g_nof_pre_mult_folds => c_nof_pre_mult_folds,
g_input_unfold_factor => g_nof_input_folds,
g_nof_pre_mult_folds => g_nof_pre_mult_folds,
g_data_w => c_complex_data_w,
g_conjugate => c_conjugate,
g_nof_channels => c_nof_channels,
g_nof_channels => g_nof_channels,
g_integration_period => c_integration_period
)
PORT MAP (
......@@ -247,7 +259,7 @@ BEGIN
g_sim => TRUE,
g_pass_through => FALSE,
g_rec_not_play => TRUE,
g_rec_play_file => "$RADIOHDL/libraries/dsp/correlator/correlator_src_out_arr0.rec",
g_rec_play_file => "$RADIOHDL/libraries/dsp/correlator/tb/rec/correlator_src_out_arr0.rec",
g_record_invalid => FALSE
)
PORT MAP (
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment