Skip to content
Snippets Groups Projects
Commit 85a628d2 authored by Reinier van der Walle's avatar Reinier van der Walle
Browse files

implemented st_xsq_mm_to_dp and initial commit of st_xst and its tb +

tb_tb
parent 62f55d86
No related branches found
No related tags found
2 merge requests!100Removed text for XSub that is now written in Confluence Subband correlator...,!89Resolve L2SDP-308
......@@ -10,7 +10,9 @@ synth_files =
src/vhdl/st_calc.vhd
src/vhdl/st_sst.vhd
src/vhdl/st_xsq.vhd
src/vhdl/st_xsq_arr.vhd
src/vhdl/st_xsq_arr.vhd
src/vhdl/st_xsq_mm_to_dp.vhd
src/vhdl/st_xst.vhd
# src/vhdl/st_top.vhd
src/vhdl/st_histogram.vhd
src/vhdl/st_histogram_reg.vhd
......@@ -25,6 +27,8 @@ test_bench_files =
tb/vhdl/tb_mmf_st_sst.vhd
tb/vhdl/tb_st_xsq.vhd
tb/vhdl/tb_tb_st_xsq.vhd
tb/vhdl/tb_st_xst.vhd
tb/vhdl/tb_tb_st_xst.vhd
tb/vhdl/tb_st_histogram.vhd
tb/vhdl/tb_mms_st_histogram.vhd
tb/vhdl/tb_tb_st_histogram.vhd
......@@ -32,6 +36,7 @@ test_bench_files =
regression_test_vhdl =
tb/vhdl/tb_st_acc.vhd
tb/vhdl/tb_tb_st_xsq.vhd
tb/vhdl/tb_tb_st_xst.vhd
#tb/vhdl/tb_st_calc.vhd -- tb is not self checking yet
......
......@@ -19,14 +19,16 @@
-------------------------------------------------------------------------------
-- Author : R. vd Walle
-- Purpose:
-- . Read a block of data from memory mapped (MM) location and stream it as a block of data.
-- . Read a block of xsq data with size (g_nof_crosslets * g_nof_signal_inputs)
-- from memory mapped (MM) location and stream it as a block of data of
-- size g_nof_crosslets * g_nof_signal_inputs **2.
-- Description:
-- After every in_sosi.sop the st_xsq_mm_to_dp.vhd reads g_nof_streams blocks of data
-- via mm and outputs it as g_nof_streams parallel streams via out_sosi_arr. in_sosi.sync is
-- passed on to out_sosi.
-- After every in_sosi.sop the st_xsq_mm_to_dp.vhd reads blocks of data
-- via g_nof_streams mm and outputs it as g_nof_streams parallel streams via
-- out_sosi_arr. In_sosi.sync is passed on to out_sosi.
-- --------------------------------------------------------------------------
LIBRARY IEEE,common_lib;
LIBRARY IEEE,common_lib, dp_lib;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE common_lib.common_pkg.ALL;
......@@ -35,59 +37,49 @@ USE dp_lib.dp_stream_pkg.ALL;
ENTITY st_xsq_mm_to_dp IS
GENERIC (
g_data_size : NATURAL;
g_step_size : NATURAL;
g_nof_data : NATURAL
g_nof_streams : NATURAL;
g_nof_crosslets : NATURAL;
g_nof_signal_inputs : NATURAL;
g_dsp_data_w : NATURAL := 16
);
PORT (
rst : IN STD_LOGIC;
clk : IN STD_LOGIC;
start_pulse : IN STD_LOGIC;
mm_done : OUT STD_LOGIC;
mm_mosi : OUT t_mem_mosi;
mm_miso : IN t_mem_miso;
out_sosi : OUT t_dp_sosi;
out_siso : IN t_dp_siso
in_sosi : IN t_dp_sosi; -- sop used as start signal
mm_mosi_arr : OUT t_mem_mosi_arr(g_nof_streams -1 DOWNTO 0);
mm_miso_arr : IN t_mem_miso_arr(g_nof_streams -1 DOWNTO 0);
out_sosi_arr : OUT t_dp_sosi_arr(g_nof_streams -1 DOWNTO 0)
);
END st_xsq_mm_to_dp;
ARCHITECTURE rtl OF st_xsq_mm_to_dp IS
CONSTANT c_mem_size : NATURAL := g_step_size * g_nof_data;
TYPE t_reg IS RECORD
busy : STD_LOGIC;
sop : STD_LOGIC;
eop : STD_LOGIC;
word_index : NATURAL;
step_index : NATURAL;
in_sosi_strobe : t_dp_sosi;
out_sosi_ctrl : t_dp_sosi;
busy : STD_LOGIC;
crosslets_index : NATURAL;
in_a_index : NATURAL;
in_b_index : NATURAL;
END RECORD;
CONSTANT c_reg_rst : t_reg := ('0', '0', '0', 0, 0);
CONSTANT c_reg_rst : t_reg := (c_dp_sosi_rst, c_dp_sosi_rst, '0', 0, 0, 0);
SIGNAL r : t_reg;
SIGNAL nxt_r : t_reg;
SIGNAL mm_address : NATURAL := 0;
SIGNAL last_mm_address : NATURAL := 0;
BEGIN
last_mm_address <= g_step_size * (g_nof_data - 1) + g_data_size + start_address - 1;
mm_address <= start_address + r.word_index + r.step_index;
mm_mosi.address <= TO_MEM_ADDRESS(mm_address);
u_sosi : PROCESS(r, mm_miso)
u_sosi : PROCESS(r, mm_miso_arr)
BEGIN
out_sosi <= c_dp_sosi_rst; -- To avoid Modelsim warnings on conversion to integer from unused fields.
out_sosi.data <= RESIZE_DP_DATA(mm_miso.rddata(c_word_w-1 DOWNTO 0));
out_sosi.valid <= mm_miso.rdval; -- read latency from mm_mosi.rd to mm_miso.rdval is 1, so same as the ready latency (RL = 1)
out_sosi.sop <= r.sop; -- read latency from mm_mosi.rd to mm_miso.rdval is 1, so r.sop can be used for output sop
out_sosi.eop <= r.eop; -- read latency from mm_mosi.rd to mm_miso.rdval is 1, so r.eop can be used for output eop
FOR I IN 0 TO g_nof_streams-1 LOOP
out_sosi_arr(I) <= r.out_sosi_ctrl;
out_sosi_arr(I).re <= RESIZE_DP_DSP_DATA(mm_miso_arr(I).rddata(g_dsp_data_w-1 DOWNTO 0));
out_sosi_arr(I).im <= RESIZE_DP_DSP_DATA(mm_miso_arr(I).rddata(c_nof_complex * g_dsp_data_w -1 DOWNTO g_dsp_data_w));
out_sosi_arr(I).valid <= mm_miso_arr(I).rdval; -- read latency from mm_mosi.rd to mm_miso.rdval is 1, so same as the ready latency (RL = 1)
END LOOP;
END PROCESS;
mm_done <= r.eop;
p_reg : PROCESS(rst, clk)
BEGIN
IF rst='1' THEN
......@@ -97,40 +89,55 @@ BEGIN
END IF;
END PROCESS;
p_comb : PROCESS(r, start_pulse, out_siso, mm_address, last_mm_address)
p_comb : PROCESS(r, in_sosi)
VARIABLE v : t_reg;
BEGIN
v := r;
v.sop := '0';
v.eop := '0';
mm_mosi.rd <= '0';
IF r.busy = '0' AND start_pulse = '1' THEN
v.out_sosi_ctrl := c_dp_sosi_rst;
FOR I IN 0 TO g_nof_streams-1 LOOP
mm_mosi_arr(I).rd <= '0';
END LOOP;
IF r.busy = '0' AND in_sosi.sop = '1' THEN
-- initiate next block
v.busy := '1';
v.in_sosi_strobe := in_sosi;
ELSIF r.busy = '1' THEN
IF out_siso.ready = '1' THEN
-- continue with block
mm_mosi.rd <= '1';
IF r.word_index < g_data_size - 1 THEN
v.word_index := r.word_index + 1;
-- continue with block
FOR I IN 0 TO g_nof_streams-1 LOOP
mm_mosi_arr(I).rd <= '1';
mm_mosi_arr(I).address <= TO_MEM_ADDRESS(r.crosslets_index * g_nof_signal_inputs + r.in_b_index); -- streams iterate over in_b_index
END LOOP;
-- Counters
IF r.in_b_index < g_nof_signal_inputs - 1 THEN
v.in_b_index := r.in_b_index + 1;
ELSE
v.in_b_index := 0;
IF r.in_a_index < g_nof_signal_inputs - 1 THEN
v.in_a_index := r.in_a_index + 1;
ELSE
v.word_index := 0;
v.step_index := r.step_index + g_step_size;
END IF;
-- check start of block
IF r.word_index = 0 AND r.step_index = 0 THEN
v.sop := '1';
END IF;
-- check end of block
IF mm_address >= last_mm_address THEN
v.eop := '1';
-- prepare for next block
v.busy := '0';
v.word_index := 0;
v.step_index := 0;
END IF;
v.in_a_index := 0;
IF r.crosslets_index < g_nof_crosslets - 1 THEN
v.crosslets_index := r.crosslets_index + 1;
ELSE
v.crosslets_index := 0;
END IF;
END IF;
END IF;
-- check start of block
IF r.crosslets_index = 0 AND r.in_a_index = 0 AND r.in_b_index = 0 THEN
v.out_sosi_ctrl.sop := '1';
v.out_sosi_ctrl.sync := r.in_sosi_strobe.sync;
v.out_sosi_ctrl.bsn := r.in_sosi_strobe.bsn;
END IF;
-- check end of block
IF r.crosslets_index >= (g_nof_crosslets - 1) AND r.in_a_index >= (g_nof_signal_inputs - 1) AND r.in_b_index >= (g_nof_signal_inputs - 1) THEN
v.out_sosi_ctrl.eop := '1';
v.out_sosi_ctrl.err := r.in_sosi_strobe.err;
v.busy := '0';
END IF;
END IF;
nxt_r <= v;
......
-------------------------------------------------------------------------------
--
-- 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:
-- Calculate Crosslets Statistics
-- Description:
-- Consists of st_xsq_mm_to_dp connected to st_xsq_arr. in_b_arr comes directly
-- from st_xsq_mm_to_dp but all streams in in_a_arr are x_sosi_arr(0) with corrected
-- indices done by a process.
-- Remarks:
-- . More detail, see:
-- https://support.astron.nl/confluence/display/L2M/L5+SDPFW+Design+Document%3A+Subband+Correlator
-------------------------------------------------------------------------------
LIBRARY IEEE, common_lib, mm_lib, technology_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.common_field_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
ENTITY st_xst IS
GENERIC (
g_nof_streams : NATURAL := 1;
g_nof_crosslets : NATURAL := 1;
g_nof_signal_inputs : NATURAL := 2;
g_in_data_w : NATURAL := 18; -- width of the data to be accumulated
g_stat_data_w : NATURAL := 54; -- statistics accumulator width
g_stat_data_sz : NATURAL := 2 -- statistics word width >= statistics accumulator width and fit in a power of 2 multiple 32b MM words
);
PORT (
mm_rst : IN STD_LOGIC;
mm_clk : IN STD_LOGIC;
dp_rst : IN STD_LOGIC;
dp_clk : IN STD_LOGIC;
-- Streaming
in_sosi : IN t_dp_sosi;
-- DP Memory Mapped
mm_mosi_arr : OUT t_mem_mosi_arr(g_nof_streams -1 DOWNTO 0);
mm_miso_arr : IN t_mem_miso_arr(g_nof_streams -1 DOWNTO 0);
-- MM Memory Mapped
ram_st_xsq_mosi : IN t_mem_mosi;
ram_st_xsq_miso : OUT t_mem_miso
);
END st_xst;
ARCHITECTURE str OF st_xst IS
CONSTANT c_xsq : NATURAL := g_nof_signal_inputs * g_nof_signal_inputs;
CONSTANT c_nof_statistics : NATURAL := g_nof_crosslets * c_xsq;
CONSTANT c_nof_word : NATURAL := g_stat_data_sz*c_nof_statistics*c_nof_complex;
CONSTANT c_nof_word_w : NATURAL := ceil_log2(c_nof_word);
TYPE t_reg IS RECORD
busy : STD_LOGIC;
in_a_index : NATURAL;
in_b_index : NATURAL;
END RECORD;
CONSTANT c_reg_rst : t_reg := ('0', 0, 0);
SIGNAL r : t_reg;
SIGNAL nxt_r : t_reg;
SIGNAL in_a_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL in_b_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL x_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL reg_x_sosi_0_re : t_slv_64_arr(g_nof_signal_inputs-1 DOWNTO 0);
SIGNAL reg_x_sosi_0_im : t_slv_64_arr(g_nof_signal_inputs-1 DOWNTO 0);
BEGIN
st_xsq_mm_to_dp : ENTITY work.st_xsq_mm_to_dp
GENERIC MAP(
g_nof_streams => g_nof_streams,
g_nof_crosslets => g_nof_crosslets,
g_nof_signal_inputs => g_nof_signal_inputs,
g_dsp_data_w => g_in_data_w
)
PORT MAP(
rst => dp_rst,
clk => dp_clk,
in_sosi => in_sosi,
mm_mosi_arr => mm_mosi_arr,
mm_miso_arr => mm_miso_arr,
out_sosi_arr => x_sosi_arr
);
-- rewire
in_b_sosi_arr <= x_sosi_arr;
reg_x_sosi_0_re(nxt_r.in_b_index) <= x_sosi_arr(0).re;
reg_x_sosi_0_im(nxt_r.in_b_index) <= x_sosi_arr(0).im;
p_in_a : PROCESS(x_sosi_arr, reg_x_sosi_0_re, reg_x_sosi_0_im, nxt_r.in_a_index)
BEGIN
FOR I IN 0 TO g_nof_streams-1 LOOP
in_a_sosi_arr(I) <= x_sosi_arr(0);
in_a_sosi_arr(I).re <= reg_x_sosi_0_re(nxt_r.in_a_index);
in_a_sosi_arr(I).im <= reg_x_sosi_0_im(nxt_r.in_a_index);
END LOOP;
END PROCESS;
p_reg : 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 : PROCESS(r, x_sosi_arr)
VARIABLE v : t_reg;
BEGIN
v := r;
IF r.busy = '0' AND x_sosi_arr(0).sop = '1' THEN
-- initiate next block
v.busy := '1';
ELSIF r.busy = '1' THEN
-- Counters
IF r.in_b_index < g_nof_signal_inputs - 1 THEN
v.in_b_index := r.in_b_index + 1;
ELSE
v.in_b_index := 0;
IF r.in_a_index < g_nof_signal_inputs - 1 THEN
v.in_a_index := r.in_a_index + 1;
ELSE
v.in_a_index := 0;
END IF;
END IF;
END IF;
IF x_sosi_arr(0).eop = '1' THEN
v.busy := '0';
v.in_a_index := 0;
v.in_b_index := 0;
END IF;
nxt_r <= v;
END PROCESS;
-- st_xsq instances
st_xsq_arr : ENTITY work.st_xsq_arr
GENERIC MAP (
g_nof_streams => g_nof_streams,
g_nof_crosslets => g_nof_crosslets,
g_nof_signal_inputs => g_nof_signal_inputs,
g_in_data_w => g_in_data_w,
g_stat_data_w => g_stat_data_w,
g_stat_data_sz => g_stat_data_sz
)
PORT MAP (
mm_rst => mm_rst,
mm_clk => mm_clk,
dp_rst => dp_rst,
dp_clk => dp_clk,
-- Streaming
in_a_arr => in_a_sosi_arr,
in_b_arr => in_b_sosi_arr,
-- Memory Mapped
ram_st_xsq_mosi => ram_st_xsq_mosi,
ram_st_xsq_miso => ram_st_xsq_miso
);
END str;
-------------------------------------------------------------------------------
--
-- 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: Testbench for the st_xst unit.
--
-- Usage in non-auto-mode (c_modelsim_start = 0 in python):
-- > as 5
-- > run -all
-- Description:
-- The tb generates random data to feed into st_xst. The output is compared to
-- a pre-calculated expected array of xsq values.
-- Remark:
-- . More detail can be found in:
-- https://support.astron.nl/confluence/display/L2M/L5+SDPFW+Design+Document%3A+Subband+Correlator
LIBRARY IEEE, common_lib, mm_lib, diag_lib, dp_lib;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_math_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE common_lib.common_str_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 mm_lib.mm_file_unb_pkg.ALL;
USE mm_lib.mm_file_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
USE diag_lib.diag_pkg.ALL;
USE dp_lib.tb_dp_pkg.ALL;
USE work.tb_st_pkg.ALL;
ENTITY tb_st_xst IS
GENERIC(
g_nof_streams : NATURAL := 9;
g_nof_crosslets : NATURAL := 2;
g_nof_signal_inputs : NATURAL := 12;
g_in_data_w : NATURAL := 16;
g_nof_sync : NATURAL := 3;
g_stat_data_w : NATURAL := 64; -- statistics accumulator width
g_stat_data_sz : NATURAL := 2; -- statistics word width >= statistics accumulator width and fit in a power of 2 multiple 32b MM words
g_nof_block_per_sync : NATURAL := 5;
g_nof_clk_per_blk : NATURAL := 1024
);
END tb_st_xst;
ARCHITECTURE tb OF tb_st_xst IS
CONSTANT c_sim : BOOLEAN := TRUE;
CONSTANT c_rl : NATURAL := 1;
CONSTANT c_block_size : NATURAL := g_nof_crosslets * g_nof_signal_inputs;
CONSTANT c_random_data_w : NATURAL := 8;
CONSTANT c_xsq : NATURAL := g_nof_signal_inputs * g_nof_signal_inputs;
CONSTANT c_nof_statistics : NATURAL := g_nof_crosslets * c_xsq;
CONSTANT c_nof_statistics_w : NATURAL := ceil_log2(c_nof_statistics);
CONSTANT c_nof_statistics_mem_size : NATURAL := c_nof_complex * 2**c_nof_statistics_w;
CONSTANT c_single_stream_mem_size : NATURAL := c_nof_complex * c_nof_statistics * g_stat_data_sz;
CONSTANT c_total_mem_size : NATURAL := g_nof_streams * c_nof_statistics_mem_size * g_stat_data_sz;
CONSTANT c_random_seed : NATURAL := 100;
CONSTANT c_mm_ram : t_c_mem := (latency => 1,
adr_w => ceil_log2(c_block_size),
dat_w => c_nof_complex * g_in_data_w,
nof_dat => c_block_size,
init_sl => '0'); -- MM side : sla_in, sla_out
TYPE t_random_in_2arr IS ARRAY (INTEGER RANGE <>) OF t_integer_arr(0 TO c_block_size-1);
TYPE t_xsq_2arr IS ARRAY (INTEGER RANGE <>) OF t_integer_arr(0 TO c_nof_statistics * c_nof_complex-1);
TYPE t_xsq_out_2arr IS ARRAY (INTEGER RANGE <>) OF t_slv_32_arr(0 TO c_single_stream_mem_size-1);
SIGNAL random_in_re_2arr : t_random_in_2arr(0 TO g_nof_streams-1);
SIGNAL random_in_im_2arr : t_random_in_2arr(0 TO g_nof_streams-1);
SIGNAL expected_xsq_2arr : t_xsq_2arr(0 TO g_nof_streams-1);
----------------------------------------------------------------------------
-- Clocks and resets
----------------------------------------------------------------------------
CONSTANT c_mm_clk_period : TIME := 100 ps;
CONSTANT c_dp_clk_period : TIME := 5 ns;
SIGNAL tb_end : STD_LOGIC;
SIGNAL mm_rst : STD_LOGIC := '1';
SIGNAL mm_clk : STD_LOGIC := '1';
SIGNAL dp_rst : STD_LOGIC;
SIGNAL dp_clk : STD_LOGIC := '1';
SIGNAL in_sosi : t_dp_sosi := c_dp_sosi_rst;
----------------------------------------------------------------------------
-- MM buses
----------------------------------------------------------------------------
SIGNAL ram_st_xsq_mosi : t_mem_mosi := c_mem_mosi_rst;
SIGNAL ram_st_xsq_miso : t_mem_miso := c_mem_miso_rst;
SIGNAL st_xst_mm_mosi_arr : t_mem_mosi_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS => c_mem_mosi_rst);
SIGNAL st_xst_mm_miso_arr : t_mem_miso_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS => c_mem_miso_rst);
SIGNAL in_mosi_arr : t_mem_mosi_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS => c_mem_mosi_rst);
----------------------------------------------------------------------------
-- Output array
----------------------------------------------------------------------------
SIGNAL st_xsq_out_2arr : t_xsq_out_2arr(0 TO g_nof_streams-1) := (OTHERS => (OTHERS => (OTHERS => '0')));
BEGIN
-- random input and expected xsq
gen_in_exp : FOR I IN 0 TO g_nof_streams-1 GENERATE
random_in_re_2arr(I) <= common_math_create_random_arr(c_block_size, c_random_data_w, c_random_seed+2*I);
random_in_im_2arr(I) <= common_math_create_random_arr(c_block_size, c_random_data_w, c_random_seed+2*I+1);
expected_xsq_2arr(I) <= func_st_calculate_expected_xsq(random_in_re_2arr(0), random_in_im_2arr(0), random_in_re_2arr(I), random_in_im_2arr(I), g_nof_crosslets, g_nof_block_per_sync);
END GENERATE;
----------------------------------------------------------------------------
-- Clock and reset generation
----------------------------------------------------------------------------
mm_clk <= NOT mm_clk OR tb_end AFTER c_mm_clk_period/2;
mm_rst <= '1', '0' AFTER c_mm_clk_period*5;
dp_clk <= NOT dp_clk OR tb_end AFTER c_dp_clk_period/2;
dp_rst <= '1', '0' AFTER c_dp_clk_period*5;
------------------------------------------------------------------------------
-- in mosi Stimuli
------------------------------------------------------------------------------
gen_p_in_mosi : FOR M IN 0 TO g_nof_streams-1 GENERATE
p_in_mosi : PROCESS
VARIABLE v_ram_arr : t_slv_32_arr(c_block_size-1 DOWNTO 0);
BEGIN
-- write random data to ram
proc_common_wait_until_low(mm_clk, mm_rst);
FOR J IN 0 TO c_block_size-1 LOOP
v_ram_arr(J) := TO_SVEC(random_in_im_2arr(M)(J), g_in_data_w) & TO_SVEC(random_in_re_2arr(M)(J), g_in_data_w);
END LOOP;
proc_mem_write_ram(v_ram_arr, mm_clk, in_mosi_arr(M));
WAIT;
END PROCESS;
END GENERATE;
------------------------------------------------------------------------------
-- MM Stimuli
------------------------------------------------------------------------------
gen_mm_stim : FOR M IN 0 TO g_nof_streams-1 GENERATE
p_mm_stimuli : PROCESS
BEGIN
-- read statistics
FOR I IN 0 TO g_nof_sync -1 LOOP
proc_common_wait_until_lo_hi(dp_clk, in_sosi.sync);
END LOOP;
proc_common_wait_some_cycles(dp_clk, g_nof_clk_per_blk);
proc_common_wait_some_cycles(dp_clk, 20);
proc_common_wait_some_cycles(mm_clk, 2 * M * c_single_stream_mem_size);
proc_mem_read_ram(M*c_nof_statistics_mem_size, c_single_stream_mem_size, mm_clk, ram_st_xsq_mosi, ram_st_xsq_miso, st_xsq_out_2arr(M));
WAIT;
END PROCESS;
END GENERATE;
------------------------------------------------------------------------------
-- Data blocks
------------------------------------------------------------------------------
p_in_sosi : PROCESS
BEGIN
tb_end <= '0';
in_sosi <= c_dp_sosi_rst;
proc_common_wait_until_low(dp_clk, dp_rst);
-- Run some sync intervals with DSP counter data for the real and imag fields
WAIT UNTIL rising_edge(dp_clk);
proc_common_wait_some_cycles(dp_clk, 7);
FOR I IN 0 TO g_nof_sync-1 LOOP
in_sosi.sop <= '1';
in_sosi.eop <= '1';
in_sosi.sync <= '1';
proc_common_wait_some_cycles(dp_clk, 1);
in_sosi <= c_dp_sosi_rst;
proc_common_wait_some_cycles(dp_clk, g_nof_clk_per_blk-1);
FOR J IN 0 TO g_nof_block_per_sync-2 LOOP -- provide sop and eop for block reference
in_sosi.sop <= '1';
in_sosi.eop <= '1';
proc_common_wait_some_cycles(dp_clk, 1);
in_sosi <= c_dp_sosi_rst;
proc_common_wait_some_cycles(dp_clk, g_nof_clk_per_blk-1);
END LOOP;
END LOOP;
in_sosi <= c_dp_sosi_rst;
proc_common_wait_some_cycles(dp_clk, 100);
tb_end <= '1';
WAIT;
END PROCESS;
------------------------------------------------------------------------------
-- Verification
------------------------------------------------------------------------------
p_verify : PROCESS
BEGIN
proc_common_wait_until_high(mm_clk, ram_st_xsq_miso.rdval);
proc_common_wait_some_cycles(mm_clk, 2* c_total_mem_size + 10);
FOR M IN 0 TO g_nof_streams -1 LOOP
FOR I IN 0 TO c_nof_statistics * c_nof_complex -1 LOOP
ASSERT TO_SINT(st_xsq_out_2arr(M)(g_stat_data_sz * I)) = expected_xsq_2arr(M)(I) REPORT "WRONG XSQ DATA" SEVERITY ERROR; -- Only read low part of statistic
END LOOP;
END LOOP;
WAIT;
END PROCESS;
----------------------------------------------------------------------------
-- RAM
----------------------------------------------------------------------------
gen_ram : FOR I IN 0 TO g_nof_streams-1 GENERATE
u_ram : ENTITY common_lib.common_ram_cr_cw
GENERIC MAP(
g_ram => c_mm_ram
)
PORT MAP(
wr_rst => mm_rst,
wr_clk => mm_clk,
wr_en => in_mosi_arr(I).wr,
wr_adr => in_mosi_arr(I).address(c_mm_ram.adr_w-1 DOWNTO 0),
wr_dat => in_mosi_arr(I).wrdata(c_mm_ram.dat_w-1 DOWNTO 0),
rd_rst => dp_rst,
rd_clk => dp_clk,
rd_en => st_xst_mm_mosi_arr(I).rd,
rd_adr => st_xst_mm_mosi_arr(I).address(c_mm_ram.adr_w-1 DOWNTO 0),
rd_dat => st_xst_mm_miso_arr(I).rddata(c_mm_ram.dat_w-1 DOWNTO 0),
rd_val => st_xst_mm_miso_arr(I).rdval
);
END GENERATE;
----------------------------------------------------------------------------
-- DUT: Device Under Test
----------------------------------------------------------------------------
u_dut : ENTITY work.st_xst
GENERIC MAP(
g_nof_streams => g_nof_streams,
g_nof_signal_inputs => g_nof_signal_inputs,
g_nof_crosslets => g_nof_crosslets,
g_in_data_w => g_in_data_w,
g_stat_data_w => g_stat_data_w,
g_stat_data_sz => g_stat_data_sz
)
PORT MAP(
mm_rst => mm_rst,
mm_clk => mm_clk,
dp_rst => dp_rst,
dp_clk => dp_clk,
-- Streaming
in_sosi => in_sosi,
-- DP Memory Mapped
mm_mosi_arr => st_xst_mm_mosi_arr,
mm_miso_arr => st_xst_mm_miso_arr,
-- Memory Mapped
ram_st_xsq_mosi => ram_st_xsq_mosi,
ram_st_xsq_miso => ram_st_xsq_miso
);
END tb;
-------------------------------------------------------------------------------
--
-- 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: Test multiple instances of tb_st_xst
-- Usage:
-- > as 10
-- > run -all
--
-- Description: See tb_st_xst
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
ENTITY tb_tb_st_xst IS
END tb_tb_st_xst;
ARCHITECTURE tb OF tb_tb_st_xst IS
CONSTANT c_nof_sync : NATURAL := 3;
CONSTANT c_dsp_data_w : NATURAL := 16;
SIGNAL tb_end : STD_LOGIC := '0'; -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end'
BEGIN
-- GENERICS:
-- g_nof_streams : NATURAL := 9;
-- g_nof_crosslets : NATURAL := 2;
-- g_nof_signal_inputs : NATURAL := 12;
-- g_in_data_w : NATURAL := 16;
-- g_nof_sync : NATURAL := 3;
-- g_stat_data_w : NATURAL := 64; -- statistics accumulator width
-- g_stat_data_sz : NATURAL := 2; -- statistics word width >= statistics accumulator width and fit in a power of 2 multiple 32b MM words
-- g_nof_block_per_sync : NATURAL := 5;
-- g_nof_clk_per_blk : NATURAL := 1024
u_sdp : ENTITY work.tb_st_xst GENERIC MAP (9, 1, 12, c_dsp_data_w, c_nof_sync, 64, 2, 5, 1024);
u_sdp_one : ENTITY work.tb_st_xst GENERIC MAP (1, 1, 12, c_dsp_data_w, c_nof_sync, 64, 2, 5, 1024);
u_sdp_mult_crosslets : ENTITY work.tb_st_xst GENERIC MAP (9, 7, 12, c_dsp_data_w, c_nof_sync, 64, 2, 5, 1024);
-- Note: u_max shows that the dut will skip sync periods if nof_statistics is not < g_nof_clk_per_blk
u_max : ENTITY work.tb_st_xst GENERIC MAP (2, 16, 8, c_dsp_data_w, c_nof_sync, 64, 2, 5, 1024); -- g_nof_crosslets * g_nof_signal_inputs**2 = 16 * 8 * 8 = 1024 = g_nof_clk_per_blk
END tb;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment