Skip to content
Snippets Groups Projects
Commit 85965a51 authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Merge branch 'L2SDP-285' into 'master'

Resolve L2SDP-285

Closes L2SDP-285

See merge request desp/hdl!86
parents 7e267408 14e81a57
No related branches found
No related tags found
2 merge requests!100Removed text for XSub that is now written in Confluence Subband correlator...,!86Resolve L2SDP-285
...@@ -14,6 +14,7 @@ synth_files = ...@@ -14,6 +14,7 @@ synth_files =
src/vhdl/sdp_info.vhd src/vhdl/sdp_info.vhd
src/vhdl/sdp_beamformer_output.vhd src/vhdl/sdp_beamformer_output.vhd
src/vhdl/sdp_statistics_offload.vhd src/vhdl/sdp_statistics_offload.vhd
src/vhdl/sdp_crosslets_subband_select.vhd
src/vhdl/node_sdp_adc_input_and_timing.vhd src/vhdl/node_sdp_adc_input_and_timing.vhd
src/vhdl/node_sdp_filterbank.vhd src/vhdl/node_sdp_filterbank.vhd
src/vhdl/node_sdp_beamformer.vhd src/vhdl/node_sdp_beamformer.vhd
...@@ -21,10 +22,12 @@ synth_files = ...@@ -21,10 +22,12 @@ synth_files =
test_bench_files = test_bench_files =
tb/vhdl/tb_sdp_info.vhd tb/vhdl/tb_sdp_info.vhd
tb/vhdl/tb_sdp_statistics_offload.vhd tb/vhdl/tb_sdp_statistics_offload.vhd
tb/vhdl/tb_sdp_crosslets_subband_select.vhd
regression_test_vhdl = regression_test_vhdl =
tb/vhdl/tb_sdp_info.vhd tb/vhdl/tb_sdp_info.vhd
tb/vhdl/tb_sdp_statistics_offload.vhd tb/vhdl/tb_sdp_statistics_offload.vhd
tb/vhdl/tb_sdp_crosslets_subband_select.vhd
[modelsim_project_file] [modelsim_project_file]
......
-------------------------------------------------------------------------------
--
-- Copyright 2021
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- Author: R. van der Walle
-- Purpose:
-- Select subbands from incoming blocks
-- Description:
-- The Crosslet subband select selects N_crosslets from each incoming block. Per
-- crosslet there are S_pn = 12 subbands, one from each signal input of the PN.
-- Remark:
-- . See L5 SDPFW Design Document: Subband Correlator
-- Link: https://support.astron.nl/confluence/pages/viewpage.action?spaceKey=L2M&title=L5+SDPFW+Design+Document%3A+Subband+Correlator
-------------------------------------------------------------------------------
LIBRARY IEEE, common_lib, dp_lib, reorder_lib, st_lib;
USE IEEE.STD_LOGIC_1164.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE common_lib.common_network_layers_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
USE work.sdp_pkg.ALL;
ENTITY sdp_crosslets_subband_select IS
GENERIC (
g_N_crosslets : NATURAL := c_sdp_N_crosslets
);
PORT (
dp_clk : IN STD_LOGIC;
dp_rst : IN STD_LOGIC;
in_sosi_arr : IN t_dp_sosi_arr(c_sdp_P_pfb-1 DOWNTO 0);
out_sosi : OUT t_dp_sosi;
mm_rst : IN STD_LOGIC;
mm_clk : IN STD_LOGIC;
reg_crosslets_info_mosi : IN t_mem_mosi := c_mem_mosi_rst;
reg_crosslets_info_miso : OUT t_mem_miso := c_mem_miso_rst;
reg_bsn_scheduler_xsub_mosi : IN t_mem_mosi := c_mem_mosi_rst;
reg_bsn_scheduler_xsub_miso : OUT t_mem_miso := c_mem_miso_rst;
out_crosslets_info : OUT STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0)
);
END sdp_crosslets_subband_select;
ARCHITECTURE str OF sdp_crosslets_subband_select IS
CONSTANT c_crosslets_info_dly : NATURAL := 1;
CONSTANT c_row_select_slv_w : NATURAL := ceil_log2(c_sdp_P_pfb);
CONSTANT c_row_select_pipeline : NATURAL := 1;
CONSTANT c_out_sosi_pipeline : NATURAL := 1;
TYPE t_crosslets_control_reg IS RECORD -- local registers
offset_index : NATURAL;
row_index : NATURAL;
col_index : NATURAL;
step : NATURAL RANGE 0 TO c_sdp_N_sub-1;
offsets : t_natural_arr(g_N_crosslets-1 DOWNTO 0);
started : STD_LOGIC;
row_select_slv : STD_LOGIC_VECTOR(c_row_select_slv_w-1 DOWNTO 0);
col_select_mosi : t_mem_mosi;
sync_detected : STD_LOGIC;
END RECORD;
CONSTANT c_reg_rst : t_crosslets_control_reg := ( 0, 0, 0, 0, (OTHERS => 0), '0', (OTHERS => '0'), c_mem_mosi_rst, '0');
-- Define the local registers in t_crosslets_control_reg record
SIGNAL r : t_crosslets_control_reg;
SIGNAL nxt_r : t_crosslets_control_reg;
SIGNAL start_trigger : STD_LOGIC := '0';
SIGNAL col_select_mosi : t_mem_mosi := c_mem_mosi_rst;
SIGNAL col_select_miso : t_mem_miso := c_mem_miso_rst;
SIGNAL row_select_slv : STD_LOGIC_VECTOR(c_row_select_slv_w-1 DOWNTO 0);
SIGNAL col_sosi_arr : t_dp_sosi_arr(c_sdp_P_pfb-1 DOWNTO 0);
SIGNAL row_sosi : t_dp_sosi;
SIGNAL crosslets_info_reg : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS=>'0');
SIGNAL active_crosslets_info : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0');
BEGIN
---------------------------------------------------------------
-- BSN scheduler
---------------------------------------------------------------
u_bsn_scheduler : ENTITY dp_lib.mms_dp_bsn_scheduler
GENERIC MAP (
g_cross_clock_domain => TRUE,
g_bsn_w => c_dp_stream_bsn_w
)
PORT MAP (
-- Memory-mapped clock domain
mm_rst => mm_rst,
mm_clk => mm_clk,
reg_mosi => reg_bsn_scheduler_xsub_mosi,
reg_miso => reg_bsn_scheduler_xsub_miso,
-- Streaming clock domain
dp_rst => dp_rst,
dp_clk => dp_clk,
snk_in => in_sosi_arr(0), -- only uses eop (= block sync), bsn[]
trigger_out => start_trigger
);
---------------------------------------------------------------
-- Crosslets info
---------------------------------------------------------------
u_crosslets_info : ENTITY common_lib.mms_common_reg
GENERIC MAP(
g_mm_reg => c_sdp_mm_reg_crosslets_info
)
PORT MAP(
-- Clocks and reset
mm_rst => mm_rst,
mm_clk => mm_clk,
st_rst => dp_rst,
st_clk => dp_clk,
-- MM bus access in memory-mapped clock domain
reg_mosi => reg_crosslets_info_mosi,
reg_miso => reg_crosslets_info_miso,
in_reg => crosslets_info_reg,
out_reg => crosslets_info_reg
);
---------------------------------------------------------------
-- Crosslets control process
---------------------------------------------------------------
p_regs_crosslets_control : PROCESS(dp_rst, dp_clk)
BEGIN
IF dp_rst='1' THEN
r <= c_reg_rst;
ELSIF rising_edge(dp_clk) THEN
r <= nxt_r;
END IF;
END PROCESS;
p_comb_crosslets_control : PROCESS(r, start_trigger, crosslets_info_reg, in_sosi_arr, col_select_miso)
VARIABLE v : t_crosslets_control_reg;
VARIABLE v_offsets : t_natural_arr(g_N_crosslets-1 DOWNTO 0); -- Use extra variable to simplify col_select_mosi address selection
BEGIN
v := r;
v.col_select_mosi := c_mem_mosi_rst;
-- start/restart
IF start_trigger = '1' THEN
v.started := '1';
v.offset_index := 0;
v.row_index := 0;
v.col_index := 0;
v.sync_detected := '0';
v.step := TO_UINT(crosslets_info_reg(c_sdp_crosslets_info_reg_w-1 DOWNTO c_sdp_crosslets_info_reg_w - c_sdp_crosslets_index_w));
FOR I IN 0 TO g_N_crosslets-1 LOOP
v_offsets(I) := TO_UINT(crosslets_info_reg((I+1)*c_sdp_crosslets_index_w-1 DOWNTO I*c_sdp_crosslets_index_w));
END LOOP;
END IF;
IF in_sosi_arr(0).sync = '1' AND start_trigger = '0' THEN
v.sync_detected := '1';
END IF;
IF r.started = '1' THEN
-- add step to offsets
IF in_sosi_arr(0).eop = '1' AND r.sync_detected = '1' THEN -- change offsets 1 packet after the sync due to the buffered packet in reorder_col_wide_select
v.sync_detected := '0';
FOR I IN 0 TO g_N_crosslets-1 LOOP
v_offsets(I) := r.offsets(I) + TO_UINT(crosslets_info_reg(c_sdp_crosslets_info_reg_w-1 DOWNTO c_sdp_crosslets_info_reg_w - c_sdp_crosslets_index_w));
END LOOP;
END IF;
-- Make col/row selection
IF col_select_miso.waitrequest = '0' THEN
IF r.col_index >= c_sdp_Q_fft-1 THEN
v.col_index := 0;
IF r.row_index >= c_sdp_P_pfb-1 THEN
v.row_index := 0;
IF r.offset_index >= g_N_crosslets-1 THEN
v.offset_index := 0;
ELSE
v.offset_index := r.offset_index+1;
END IF;
ELSE
v.row_index := r.row_index+1;
END IF;
ELSE
v.col_index := r.col_index+1;
END IF;
v.col_select_mosi.rd := '1';
v.col_select_mosi.address(c_sdp_crosslets_index_w-1 DOWNTO 0) := TO_UVEC(c_sdp_Q_fft*v_offsets(r.offset_index) + r.col_index, c_sdp_crosslets_index_w);
v.row_select_slv := TO_UVEC(r.row_index, c_row_select_slv_w);
END IF;
END IF;
v.offsets := v_offsets;
nxt_r <= v;
END PROCESS;
col_select_mosi <= r.col_select_mosi;
-- pipeline to time row select
u_pipe_row_select : ENTITY common_lib.common_pipeline
GENERIC MAP(
g_pipeline => c_row_select_pipeline,
g_in_dat_w => c_row_select_slv_w,
g_out_dat_w => c_row_select_slv_w
)
PORT MAP(
rst => dp_rst,
clk => dp_clk,
in_dat => r.row_select_slv,
out_dat => row_select_slv
);
active_crosslets_info(c_sdp_crosslets_info_reg_w-1 DOWNTO c_sdp_crosslets_info_reg_w - c_sdp_crosslets_index_w) <= TO_UVEC(r.step, c_sdp_crosslets_index_w);
gen_crosslets_info : FOR I IN 0 TO g_N_crosslets-1 GENERATE
active_crosslets_info((I+1)*c_sdp_crosslets_index_w-1 DOWNTO I*c_sdp_crosslets_index_w) <= TO_UVEC(r.offsets(I), c_sdp_crosslets_index_w);
END GENERATE;
---------------------------------------------------------------
-- Crosslet Select
---------------------------------------------------------------
u_reorder_col_wide_select : ENTITY reorder_lib.reorder_col_wide_select
GENERIC MAP (
g_nof_inputs => c_sdp_P_pfb,
g_dsp_data_w => c_sdp_W_subband,
g_nof_ch_in => c_sdp_N_sub * c_sdp_Q_fft,
g_nof_ch_sel => g_N_crosslets * c_sdp_S_pn
)
PORT MAP (
dp_rst => dp_rst,
dp_clk => dp_clk,
-- Memory Mapped
col_select_mosi => col_select_mosi,
col_select_miso => col_select_miso,
-- Streaming
input_sosi_arr => in_sosi_arr,
output_sosi_arr => col_sosi_arr
);
u_reorder_row_select : ENTITY reorder_lib.reorder_row_select
GENERIC MAP (
g_dsp_data_w => c_sdp_W_subband,
g_nof_inputs => c_sdp_P_pfb,
g_nof_outputs => 1,
g_pipeline_in => 0,
g_pipeline_in_m => 1,
g_pipeline_out => 1
)
PORT MAP (
dp_rst => dp_rst,
dp_clk => dp_clk,
in_select => row_select_slv,
-- Streaming
input_sosi_arr => col_sosi_arr,
output_sosi_arr(0) => row_sosi
);
---------------------------------------------------------------
-- Out Crosslet info pipeline
---------------------------------------------------------------
-- pipeline for alignment with sync
u_common_pipeline : ENTITY common_lib.common_pipeline
GENERIC MAP(
g_pipeline => c_crosslets_info_dly,
g_in_dat_w => c_sdp_crosslets_info_reg_w,
g_out_dat_w => c_sdp_crosslets_info_reg_w
)
PORT MAP(
rst => dp_rst,
clk => dp_clk,
in_en => row_sosi.sync,
in_dat => active_crosslets_info,
out_dat => out_crosslets_info
);
---------------------------------------------------------------
-- Out sosi pipeline
---------------------------------------------------------------
u_dp_pipeline : ENTITY dp_lib.dp_pipeline
GENERIC MAP (
g_pipeline => c_out_sosi_pipeline
)
PORT MAP (
rst => dp_rst,
clk => dp_clk,
-- ST sink
snk_in => row_sosi,
-- ST source
src_out => out_sosi
);
END str;
...@@ -71,6 +71,7 @@ PACKAGE sdp_pkg is ...@@ -71,6 +71,7 @@ PACKAGE sdp_pkg is
-- L3 SDP Decision: SDP Parameter definitions -- L3 SDP Decision: SDP Parameter definitions
CONSTANT c_sdp_f_adc_MHz : NATURAL := 200; CONSTANT c_sdp_f_adc_MHz : NATURAL := 200;
CONSTANT c_sdp_N_beamsets : NATURAL := 2; CONSTANT c_sdp_N_beamsets : NATURAL := 2;
CONSTANT c_sdp_N_crosslets : NATURAL := 1;
CONSTANT c_sdp_N_fft : NATURAL := 1024; CONSTANT c_sdp_N_fft : NATURAL := 1024;
CONSTANT c_sdp_N_pn_lb : NATURAL := 16; CONSTANT c_sdp_N_pn_lb : NATURAL := 16;
CONSTANT c_sdp_N_pol : NATURAL := 2; CONSTANT c_sdp_N_pol : NATURAL := 2;
...@@ -170,6 +171,16 @@ PACKAGE sdp_pkg is ...@@ -170,6 +171,16 @@ PACKAGE sdp_pkg is
-- SST UDP offload MM address widths -- SST UDP offload MM address widths
CONSTANT c_sdp_reg_stat_enable_addr_w :NATURAL := 1; CONSTANT c_sdp_reg_stat_enable_addr_w :NATURAL := 1;
-- XSUB
CONSTANT c_sdp_crosslets_index_w : NATURAL := ceil_log2(c_sdp_N_sub);
CONSTANT c_sdp_mm_reg_crosslets_info : t_c_mem := (latency => 1,
adr_w => 4,
dat_w => c_sdp_crosslets_index_w,
nof_dat => 16, -- 15 offsets + 1 step
init_sl => '0');
CONSTANT c_sdp_crosslets_info_reg_w : NATURAL := c_sdp_mm_reg_crosslets_info.nof_dat*c_sdp_mm_reg_crosslets_info.dat_w;
-- 10GbE offload (cep = central processor) -- 10GbE offload (cep = central processor)
CONSTANT c_sdp_cep_eth_src_mac_47_16 : STD_LOGIC_VECTOR(31 DOWNTO 0) := x"00228608"; -- 47:16, 15:8 = backplane, 7:0 = node CONSTANT c_sdp_cep_eth_src_mac_47_16 : STD_LOGIC_VECTOR(31 DOWNTO 0) := x"00228608"; -- 47:16, 15:8 = backplane, 7:0 = node
CONSTANT c_sdp_cep_ip_src_addr_31_16 : STD_LOGIC_VECTOR(15 DOWNTO 0) := x"C0A8"; -- 31:16, 15:8 = backplane, 7:0 = node + 1 = 192.168.xx.yy CONSTANT c_sdp_cep_ip_src_addr_31_16 : STD_LOGIC_VECTOR(15 DOWNTO 0) := x"C0A8"; -- 31:16, 15:8 = backplane, 7:0 = node + 1 = 192.168.xx.yy
......
-------------------------------------------------------------------------------
--
-- Copyright 2021
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Author : R vd Walle
-- Purpose: Verify sdp_crosslets_subband_select.
-- Usage:
-- > as 10
-- > run -all
-- * The tb is self stopping and self checking,tb_end will stop the simulation by
-- stopping the clk and thus all toggling.
--
-- Description: The tb starts the dut by writing a scheduled bsn to the bsn_scheduler
-- via MM. The offsets and step are configured using MM. The dut makes the subband
-- selection based on the MM configuration and N_crosslets. The TB then verifies out_sosi
-- and out_crosslets_info of the dut by comparing it to the expected output.
LIBRARY IEEE, common_lib, dp_lib;
USE IEEE.std_logic_1164.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE common_lib.tb_common_pkg.ALL;
USE common_lib.tb_common_mem_pkg.ALL;
USE common_lib.common_lfsr_sequences_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
USE dp_lib.tb_dp_pkg.ALL;
USE work.sdp_pkg.ALL;
ENTITY tb_sdp_crosslets_subband_select IS
END tb_sdp_crosslets_subband_select;
ARCHITECTURE tb OF tb_sdp_crosslets_subband_select IS
CONSTANT c_clk_period : TIME := 10 ns;
CONSTANT c_mm_clk_period : TIME := 20 ns;
CONSTANT c_rl : NATURAL := 1;
CONSTANT c_nof_sync : NATURAL := 5;
CONSTANT c_nof_block_per_sync : NATURAL := 4;
CONSTANT c_nof_ch_in : NATURAL := 1024; -- nof input words per block, identical for all input streams.
CONSTANT c_dsp_data_w : NATURAL := c_sdp_W_subband;
CONSTANT c_nof_ch_sel_row : NATURAL := c_sdp_P_pfb;
CONSTANT c_N_crosslets : NATURAL := 2;
CONSTANT c_ch_sel_offsets : t_natural_arr(0 TO c_N_crosslets-1) := (0, 15);
CONSTANT c_nof_ch_sel_col : NATURAL := c_sdp_Q_fft; -- nof of sequential collums to select per row.
CONSTANT c_ch_sel_step : NATURAL := 3; -- offset step size to increase per sync interval
CONSTANT c_nof_ch_sel : NATURAL := c_N_crosslets*c_nof_ch_sel_col*c_nof_ch_sel_row;
CONSTANT scheduled_bsn : NATURAL := 11;
SIGNAL rst : STD_LOGIC;
SIGNAL clk : STD_LOGIC := '1';
SIGNAL mm_clk : STD_LOGIC := '1';
SIGNAL tb_end : STD_LOGIC;
SIGNAL mm_mosi : t_mem_mosi;
SIGNAL mm_miso : t_mem_miso;
SIGNAL mm_trigger_mosi : t_mem_mosi := c_mem_mosi_rst;
SIGNAL mm_trigger_miso : t_mem_miso;
SIGNAL st_en : STD_LOGIC := '1';
SIGNAL st_siso_arr : t_dp_siso_arr(c_sdp_P_pfb-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy);
SIGNAL st_sosi_arr : t_dp_sosi_arr(c_sdp_P_pfb-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
SIGNAL exp_sosi : t_dp_sosi := c_dp_sosi_rst;
SIGNAL bsn : NATURAL := scheduled_bsn-1;
SIGNAL in_sosi_arr : t_dp_sosi_arr(c_sdp_P_pfb-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
SIGNAL out_siso_arr : t_dp_siso_arr(c_sdp_P_pfb-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy);
SIGNAL out_sosi : t_dp_sosi;
SIGNAL exp_crosslets_info : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0');
SIGNAL out_crosslets_info : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := (OTHERS => '0');
BEGIN
clk <= (NOT clk) OR tb_end AFTER c_clk_period/2;
mm_clk <= (NOT mm_clk) OR tb_end AFTER c_mm_clk_period/2;
rst <= '1', '0' AFTER c_clk_period*7;
p_select_stimuli : PROCESS
VARIABLE k : NATURAL;
BEGIN
proc_common_wait_until_low(mm_clk, rst);
proc_common_wait_some_cycles(mm_clk, 50); -- Give dut some time to start
-- BSN Scheduler
proc_mem_mm_bus_wr(0, scheduled_bsn, mm_clk, mm_trigger_miso, mm_trigger_mosi);
proc_mem_mm_bus_wr(1, 0, mm_clk, mm_trigger_miso, mm_trigger_mosi);
-- crosslet info
FOR I IN 0 TO c_N_crosslets-1 LOOP
proc_mem_mm_bus_wr(I, c_ch_sel_offsets(I), mm_clk, mm_miso, mm_mosi); --offsets
END LOOP;
proc_mem_mm_bus_wr(15, c_ch_sel_step, mm_clk, mm_miso, mm_mosi); --step
WAIT;
END PROCESS;
------------------------------------------------------------------------------
-- Data blocks
------------------------------------------------------------------------------
gen_stimuli : FOR K IN 0 TO c_sdp_P_pfb-1 GENERATE
p_st_stimuli : PROCESS
VARIABLE v_re : NATURAL := 0+k*2**5;
VARIABLE v_im : NATURAL := 1+k*2**5;
BEGIN
tb_end <= '0';
st_sosi_arr(K) <= c_dp_sosi_rst;
proc_common_wait_until_low(clk, rst);
-- Run some sync intervals with DSP counter data for the real and imag fields
WAIT UNTIL rising_edge(clk);
FOR I IN 0 TO c_nof_sync-1 LOOP
proc_dp_gen_block_data(c_rl, FALSE, c_dsp_data_w, c_dsp_data_w, 0, v_re, v_im, c_nof_ch_in, 0, 0, '1', "0", clk, st_en, st_siso_arr(K), st_sosi_arr(K)); -- next sync
v_re := v_re + c_nof_ch_in;
v_im := v_im + c_nof_ch_in;
FOR J IN 0 TO c_nof_block_per_sync-2 LOOP -- provide sop and eop for block reference
proc_dp_gen_block_data(c_rl, FALSE, c_dsp_data_w, c_dsp_data_w, 0, v_re, v_im, c_nof_ch_in, 0, 0, '0', "0", clk, st_en, st_siso_arr(K), st_sosi_arr(K)); -- no sync
v_re := v_re + c_nof_ch_in;
v_im := v_im + c_nof_ch_in;
END LOOP;
END LOOP;
st_sosi_arr(K) <= c_dp_sosi_rst;
proc_common_wait_some_cycles(clk, c_nof_ch_in);
proc_common_wait_some_cycles(clk, 10);
tb_end <= '1';
WAIT;
END PROCESS;
END GENERATE;
-- Time stimuli
bsn <= bsn + 1 WHEN rising_edge(clk) AND (st_sosi_arr(0).eop='1');
-- Add BSN to the ST data
p_in_sosi : PROCESS(st_sosi_arr, bsn)
BEGIN
FOR I IN 0 TO c_sdp_P_pfb-1 LOOP
in_sosi_arr(I) <= st_sosi_arr(I);
in_sosi_arr(I).bsn <= TO_DP_BSN(bsn);
END LOOP;
END PROCESS;
------------------------------------------------------------------------------
-- Verification
------------------------------------------------------------------------------
p_generate_exp_data : PROCESS
VARIABLE v_col : NATURAL := 0;
VARIABLE v_row : NATURAL := 0;
VARIABLE v_offset : NATURAL := 0;
VARIABLE v_sync_ix : NATURAL := 0;
VARIABLE v_k : NATURAL := 0;
BEGIN
FOR I IN 0 TO c_nof_sync*c_nof_block_per_sync-1 LOOP
v_sync_ix := I / c_nof_block_per_sync;
exp_sosi <= c_dp_sosi_rst;
WAIT UNTIL rising_edge(out_sosi.sop);
exp_crosslets_info(c_sdp_crosslets_info_reg_w-1 DOWNTO c_sdp_crosslets_info_reg_w - c_sdp_crosslets_index_w) <= TO_UVEC(c_ch_sel_step, c_sdp_crosslets_index_w);
FOR C IN 0 TO c_nof_ch_sel_col-1 LOOP
exp_crosslets_info((C+1)*c_sdp_crosslets_index_w-1 DOWNTO C*c_sdp_crosslets_index_w) <= TO_UVEC(c_ch_sel_offsets(C) + v_sync_ix * c_ch_sel_step, c_sdp_crosslets_index_w);
END LOOP;
FOR J IN 0 TO c_nof_ch_sel-1 LOOP
v_offset := J / (c_nof_ch_sel_col*c_nof_ch_sel_row);
v_col := J MOD c_nof_ch_sel_col;
v_row := (J/c_nof_ch_sel_col) MOD c_nof_ch_sel_row;
v_k := c_nof_ch_sel_col * v_sync_ix * c_ch_sel_step;
exp_sosi <= c_dp_sosi_rst;
exp_sosi.valid <= '1';
IF J = 0 THEN
exp_sosi.sop <= '1';
IF I MOD c_nof_block_per_sync = 0 THEN
exp_sosi.sync <= '1';
END IF;
ELSIF j = c_nof_ch_sel-1 THEN
exp_sosi.eop <= '1';
END IF;
exp_sosi.re <= TO_DP_DSP_DATA( I * c_nof_ch_in + v_k + c_nof_ch_sel_col*c_ch_sel_offsets(v_offset) + v_col + v_row*2**5);
exp_sosi.im <= TO_DP_DSP_DATA(1+ I * c_nof_ch_in + v_k + c_nof_ch_sel_col*c_ch_sel_offsets(v_offset) + v_col + v_row*2**5);
proc_common_wait_some_cycles(clk, 1);
END LOOP;
exp_sosi <= c_dp_sosi_rst;
END LOOP;
WAIT;
END PROCESS;
p_verify_out_data : PROCESS(clk)
BEGIN
IF rising_edge(clk) THEN
ASSERT out_sosi.valid = exp_sosi.valid REPORT "Wrong out_sosi.valid" SEVERITY ERROR;
ASSERT out_sosi.sop = exp_sosi.sop REPORT "Wrong out_sosi.sop" SEVERITY ERROR;
ASSERT out_sosi.eop = exp_sosi.eop REPORT "Wrong out_sosi.eop" SEVERITY ERROR;
ASSERT out_sosi.sync = exp_sosi.sync REPORT "Wrong out_sosi.sync" SEVERITY ERROR;
ASSERT out_crosslets_info = exp_crosslets_info REPORT "Wrong out_crosslets_info" SEVERITY ERROR;
IF exp_sosi.valid = '1' THEN
ASSERT out_sosi.re = exp_sosi.re REPORT "Wrong out_sosi.re" SEVERITY ERROR;
ASSERT out_sosi.im = exp_sosi.im REPORT "Wrong out_sosi.im" SEVERITY ERROR;
END IF;
END IF;
END PROCESS;
u_dut : ENTITY work.sdp_crosslets_subband_select
GENERIC MAP (
g_N_crosslets => c_N_crosslets
)
PORT MAP (
dp_rst => rst,
dp_clk => clk,
mm_rst => rst,
mm_clk => mm_clk,
reg_crosslets_info_mosi => mm_mosi,
reg_crosslets_info_miso => mm_miso,
reg_bsn_scheduler_xsub_mosi => mm_trigger_mosi,
reg_bsn_scheduler_xsub_miso => mm_trigger_miso,
-- Streaming
in_sosi_arr => in_sosi_arr,
out_sosi => out_sosi,
out_crosslets_info => out_crosslets_info
);
END tb;
...@@ -200,8 +200,8 @@ BEGIN ...@@ -200,8 +200,8 @@ BEGIN
retrieve_sosi.im <= RESIZE_DP_DSP_DATA(i_col_select_miso.rddata(c_nof_complex*g_dsp_data_w-1 DOWNTO g_dsp_data_w)); retrieve_sosi.im <= RESIZE_DP_DSP_DATA(i_col_select_miso.rddata(c_nof_complex*g_dsp_data_w-1 DOWNTO g_dsp_data_w));
retrieve_sosi.data <= RESIZE_DP_DATA(i_col_select_miso.rddata( c_nof_complex*g_dsp_data_w-1 DOWNTO 0)); retrieve_sosi.data <= RESIZE_DP_DATA(i_col_select_miso.rddata( c_nof_complex*g_dsp_data_w-1 DOWNTO 0));
retrieve_sosi.valid <= i_col_select_miso.rdval; retrieve_sosi.valid <= i_col_select_miso.rdval;
retrieve_sosi.sop <= retrieve_sop_dly(c_retrieve_lat); retrieve_sosi.sop <= retrieve_sop_dly(c_retrieve_lat) AND i_col_select_miso.rdval; -- Only set sop/eop when valid.
retrieve_sosi.eop <= retrieve_eop_dly(c_retrieve_lat); retrieve_sosi.eop <= retrieve_eop_dly(c_retrieve_lat) AND i_col_select_miso.rdval;
-- Page delay the input_sosi info (sync, BSN, channel at sop and err, empty at eop) and combine it with the retrieved SS data to get the output_sosi -- Page delay the input_sosi info (sync, BSN, channel at sop and err, empty at eop) and combine it with the retrieved SS data to get the output_sosi
info_sop_wr_en <= input_sosi.sop & store_done; info_sop_wr_en <= input_sosi.sop & store_done;
info_eop_wr_en <= input_sosi.eop & store_done; info_eop_wr_en <= input_sosi.eop & store_done;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment