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

added tb_st_xsq

parent 516e1540
No related branches found
No related tags found
2 merge requests!100Removed text for XSub that is now written in Confluence Subband correlator...,!88Resolve L2SDP-288
......@@ -8,9 +8,9 @@ synth_files =
$RADIOHDL_WORK/libraries/base/common/src/vhdl/common_pkg.vhd
src/vhdl/common_str_pkg.vhd
src/vhdl/common_mem_pkg.vhd
src/vhdl/common_math_pkg.vhd
src/vhdl/common_field_pkg.vhd
src/vhdl/common_lfsr_sequences_pkg.vhd
src/vhdl/common_math_pkg.vhd
src/vhdl/common_interface_layers_pkg.vhd
src/vhdl/common_network_layers_pkg.vhd
src/vhdl/common_network_total_header_pkg.vhd
......
......@@ -36,7 +36,7 @@ LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.MATH_REAL.ALL;
USE work.common_pkg.ALL;
USE work.common_lfsr_sequences_pkg.ALL;
PACKAGE common_math_pkg IS
......@@ -79,7 +79,10 @@ PACKAGE common_math_pkg IS
-- To create an FFT input phasor with frequency in the middle of a channel use FREQ = ch.
FUNCTION common_math_create_look_up_table_phasor(N, W : POSITIVE; AMPL, FREQ, PHI : REAL) RETURN t_nat_integer_arr;
FUNCTION common_math_create_look_up_table_phasor(N, W : POSITIVE; AMPL, FREQ, PHI : REAL) RETURN t_slv_32_arr; -- range 0 TO N-1
FUNCTION common_math_create_random_arr(N, W : POSITIVE) RETURN t_integer_arr;
END common_math_pkg;
......@@ -178,6 +181,18 @@ PACKAGE BODY common_math_pkg IS
END LOOP;
RETURN v_exp_arr;
END;
FUNCTION common_math_create_random_arr(N, W : POSITIVE) RETURN t_integer_arr IS
VARIABLE v_rand_arr : t_integer_arr(0 TO N-1);
VARIABLE v_random : STD_LOGIC_VECTOR(W-1 DOWNTO 0) := (OTHERS => '0');
BEGIN
FOR I IN 0 TO N-1 LOOP
v_random := func_common_random(v_random);
v_rand_arr(I) := TO_SINT(v_random);
END LOOP;
RETURN v_rand_arr;
END;
END common_math_pkg;
......@@ -5,6 +5,7 @@ hdl_lib_uses_sim =
hdl_lib_technology =
synth_files =
src/vhdl/st_pkg.vhd
src/vhdl/st_acc.vhd
src/vhdl/st_ctrl.vhd
src/vhdl/st_calc.vhd
......@@ -21,6 +22,7 @@ test_bench_files =
tb/vhdl/tb_st_acc.vhd
tb/vhdl/tb_st_calc.vhd
tb/vhdl/tb_mmf_st_sst.vhd
tb/vhdl/tb_st_xsq.vhd
tb/vhdl/tb_st_histogram.vhd
tb/vhdl/tb_mms_st_histogram.vhd
tb/vhdl/tb_tb_st_histogram.vhd
......
-------------------------------------------------------------------------------
--
-- 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:
-- Functions used in st_lib
LIBRARY IEEE, common_lib;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE common_lib.common_pkg.ALL;
PACKAGE st_pkg IS
FUNCTION func_st_calculate_expected_xsq(a_re, a_im, b_re, b_im : t_integer_arr; N_crosslets, N_int : NATURAL) RETURN t_integer_arr;
END st_pkg;
PACKAGE BODY st_pkg IS
FUNCTION func_st_calculate_expected_xsq(a_re, a_im, b_re, b_im : t_integer_arr; N_crosslets, N_int : NATURAL) RETURN t_integer_arr IS
CONSTANT c_N_s : NATURAL := a_re'LENGTH/N_crosslets;
CONSTANT c_xsq : NATURAL := c_N_s * c_N_s;
CONSTANT c_N_stat : NATURAL := N_crosslets * c_xsq;
VARIABLE v_exp_xsq : t_integer_arr(0 TO c_nof_complex * c_N_stat-1);
BEGIN
FOR N IN 0 TO N_crosslets-1 LOOP
FOR I IN 0 TO c_N_s-1 LOOP
FOR J IN 0 TO c_N_s-1 LOOP
v_exp_xsq(c_nof_complex * (N*c_xsq + I*c_N_s+J) ) := N_int * COMPLEX_MULT_REAL(a_re(N*c_N_s +I), a_im(N*c_N_s +I), b_re(N*c_N_s +J), b_im(N*c_N_s +J));
v_exp_xsq(c_nof_complex * (N*c_xsq + I*c_N_s+J)+1) := N_int * COMPLEX_MULT_IMAG(a_re(N*c_N_s +I), a_im(N*c_N_s +I), b_re(N*c_N_s +J), b_im(N*c_N_s +J));
END LOOP;
END LOOP;
END LOOP;
RETURN v_exp_xsq;
END;
END st_pkg;
......@@ -65,8 +65,8 @@ ENTITY st_xsq IS
in_b : IN t_dp_sosi; -- Complex input data
-- Memory Mapped
ram_st_xsq_mosi : IN t_mem_mosi;
ram_st_xsq_miso : OUT t_mem_miso
ram_st_xsq_mosi : IN t_mem_mosi := c_mem_mosi_rst;
ram_st_xsq_miso : OUT t_mem_miso := c_mem_miso_rst
);
END st_xsq;
......@@ -79,6 +79,7 @@ ARCHITECTURE str OF st_xsq IS
CONSTANT c_nof_word : NATURAL := g_stat_data_sz*c_nof_statistics;
CONSTANT c_nof_word_w : NATURAL := ceil_log2(c_nof_word);
CONSTANT c_stat_word_w : NATURAL := g_stat_data_sz*c_word_w;
CONSTANT c_total_ram_addr_w : NATURAL := ceil_log2(c_nof_complex) + c_nof_word_w;
-- Statistics register
CONSTANT c_mm_ram : t_c_mem := (latency => 1,
......@@ -139,13 +140,14 @@ BEGIN
---------------------------------------------------------------
-- COMBINE MEMORY MAPPED INTERFACES
---------------------------------------------------------------
-- Translate incoming MM interface [N_crosslets][S_pn A][S_pn B][N_complex] to
-- [N_complex][N_crosslets][S_pn A][S_pn B]
-- Translate incoming MM interface [N_crosslets][S_pn A][S_pn B][N_complex][word] to
-- [N_complex][N_crosslets][S_pn A][S_pn B][word]
p_remap : PROCESS(ram_st_xsq_mosi)
BEGIN
remapped_ram_st_xsq_mosi <= ram_st_xsq_mosi;
remapped_ram_st_xsq_mosi.address(ceil_log2(c_nof_complex)+c_nof_word_w -1 DOWNTO c_nof_word_w) <= ram_st_xsq_mosi.address(ceil_log2(c_nof_complex)-1 DOWNTO 0);
remapped_ram_st_xsq_mosi.address(c_nof_word_w -1 DOWNTO 0) <= ram_st_xsq_mosi.address(ceil_log2(c_nof_complex)+c_nof_word_w -1 DOWNTO ceil_log2(c_nof_complex));
--
remapped_ram_st_xsq_mosi.address(c_total_ram_addr_w -1 DOWNTO c_nof_word_w) <= ram_st_xsq_mosi.address(ceil_log2(c_nof_complex)+ceil_log2(g_stat_data_sz)-1 DOWNTO ceil_log2(g_stat_data_sz));
remapped_ram_st_xsq_mosi.address(c_nof_word_w -1 DOWNTO 0) <= ram_st_xsq_mosi.address(c_total_ram_addr_w -1 DOWNTO ceil_log2(c_nof_complex)+ceil_log2(g_stat_data_sz)) & ram_st_xsq_mosi.address(ceil_log2(g_stat_data_sz)-1 DOWNTO 0);
END PROCESS;
-- Combine the internal array of mm interfaces for both real
......
-------------------------------------------------------------------------------
--
-- Copyright (C) 2012
-- 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/>.
--
-------------------------------------------------------------------------------
--
-- Purpose: Testbench for the st_xsq unit.
--
--
-- Usage in non-auto-mode (c_modelsim_start = 0 in python):
-- > as 5
-- > run -all
-- > Run python script in separate terminal: "python tc_mmf_st_xst.py --unb 0 --bn 0 --sim"
-- > Check the results of the python script.
-- > Stop the simulation manually in Modelsim by pressing the stop-button.
-- > Evalute the WAVE window.
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.st_pkg.ALL;
ENTITY tb_st_xsq IS
GENERIC(
g_nof_crosslets : NATURAL := 1;
g_nof_signal_inputs : NATURAL := 2;
g_in_data_w : NATURAL := 16;
g_stat_data_w : NATURAL := 32; -- 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_sync : NATURAL := 3;
g_nof_block_per_sync : NATURAL := 20;
g_nof_clk_per_blk : NATURAL := 512
);
END tb_st_xsq;
ARCHITECTURE tb OF tb_st_xsq 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_gap_size : NATURAL := g_nof_clk_per_blk - c_block_size;
CONSTANT c_xsq : NATURAL := g_nof_signal_inputs * g_nof_signal_inputs;
CONSTANT c_nof_statistics : NATURAL := g_nof_crosslets * c_xsq;
CONSTANT c_random_in_a_re : t_integer_arr(0 TO c_block_size-1) := common_math_create_random_arr(c_block_size, g_in_data_w);
CONSTANT c_random_in_a_im : t_integer_arr(0 TO c_block_size-1) := common_math_create_random_arr(c_block_size, g_in_data_w-1);
CONSTANT c_random_in_b_re : t_integer_arr(0 TO c_block_size-1) := common_math_create_random_arr(c_block_size, g_in_data_w-2);
CONSTANT c_random_in_b_im : t_integer_arr(0 TO c_block_size-1) := common_math_create_random_arr(c_block_size, g_in_data_w-3);
CONSTANT c_expected_xsq : t_integer_arr(0 TO c_nof_statistics * c_nof_complex-1) := func_st_calculate_expected_xsq(c_random_in_a_re, c_random_in_a_im, c_random_in_b_re, c_random_in_b_im, g_nof_crosslets, g_nof_block_per_sync);
----------------------------------------------------------------------------
-- Clocks and resets
----------------------------------------------------------------------------
CONSTANT c_mm_clk_period : TIME := 100 ps;
CONSTANT c_dp_clk_period : TIME := 5 ns;
CONSTANT c_dp_pps_period : NATURAL := 64;
SIGNAL tb_end : STD_LOGIC;
SIGNAL dp_pps : 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 st_en : STD_LOGIC := '1';
SIGNAL st_siso : t_dp_siso := c_dp_siso_rdy;
SIGNAL st_sosi : t_dp_sosi := c_dp_sosi_rst;
SIGNAL in_sosi_a : t_dp_sosi := c_dp_sosi_rst;
SIGNAL in_sosi_b : 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_xsq_out_arr : t_slv_32_arr(0 TO c_nof_statistics * c_nof_complex * g_stat_data_sz-1) := (OTHERS => (OTHERS => '0'));
BEGIN
----------------------------------------------------------------------------
-- 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;
------------------------------------------------------------------------------
-- MM Stimuli
------------------------------------------------------------------------------
p_mm_stimuli : PROCESS
BEGIN
FOR I IN 0 TO g_nof_sync -1 LOOP
proc_common_wait_until_lo_hi(dp_clk, st_sosi.sync);
END LOOP;
proc_common_wait_some_cycles(dp_clk, 3);
-- read ram
proc_mem_read_ram(0, c_nof_statistics * c_nof_complex * g_stat_data_sz, mm_clk, ram_st_xsq_mosi, ram_st_xsq_miso, st_xsq_out_arr);
WAIT;
END PROCESS;
------------------------------------------------------------------------------
-- Data blocks
------------------------------------------------------------------------------
p_st_stimuli : PROCESS
VARIABLE v_re : NATURAL := 0;
VARIABLE v_im : NATURAL := 0;
BEGIN
tb_end <= '0';
st_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);
FOR I IN 0 TO g_nof_sync-1 LOOP
proc_dp_gen_block_data(c_rl, FALSE, g_in_data_w, g_in_data_w, 0, v_re, v_im, c_block_size, 0, 0, '1', "0", dp_clk, st_en, st_siso, st_sosi); -- next sync
st_sosi <= c_dp_sosi_rst;
proc_common_wait_some_cycles(dp_clk, c_gap_size);
FOR J IN 0 TO g_nof_block_per_sync-2 LOOP -- provide sop and eop for block reference
proc_dp_gen_block_data(c_rl, FALSE, g_in_data_w, g_in_data_w, 0, v_re, v_im, c_block_size, 0, 0, '0', "0", dp_clk, st_en, st_siso, st_sosi); -- no sync
st_sosi <= c_dp_sosi_rst;
proc_common_wait_some_cycles(dp_clk, c_gap_size);
END LOOP;
END LOOP;
st_sosi <= c_dp_sosi_rst;
proc_common_wait_some_cycles(dp_clk, 100);
tb_end <= '1';
WAIT;
END PROCESS;
in_sosi_a.sync <= st_sosi.sync;
in_sosi_b.sync <= st_sosi.sync;
in_sosi_a.sop <= st_sosi.sop;
in_sosi_b.sop <= st_sosi.sop;
in_sosi_a.eop <= st_sosi.eop;
in_sosi_b.eop <= st_sosi.eop;
in_sosi_a.valid <= st_sosi.valid;
in_sosi_b.valid <= st_sosi.valid;
p_random_stimuli : PROCESS
BEGIN
FOR I IN 0 TO g_nof_sync * g_nof_block_per_sync-1 LOOP
WAIT UNTIL rising_edge(st_sosi.sop);
FOR J IN 0 TO c_block_size-1 LOOP
in_sosi_a.re <= TO_DP_DSP_DATA(c_random_in_a_re(J));
in_sosi_a.im <= TO_DP_DSP_DATA(c_random_in_a_im(J));
in_sosi_b.re <= TO_DP_DSP_DATA(c_random_in_b_re(J));
in_sosi_b.im <= TO_DP_DSP_DATA(c_random_in_b_im(J));
proc_common_wait_some_cycles(dp_clk, 1);
END LOOP;
END LOOP;
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, c_nof_statistics * c_nof_complex * g_stat_data_sz + 10);
FOR I IN 0 TO c_nof_statistics * c_nof_complex -1 LOOP
ASSERT TO_SINT(st_xsq_out_arr(I*2)) = c_expected_xsq(I) REPORT "WRONG XSQ DATA" SEVERITY ERROR; -- Only read low part of statistic
END LOOP;
WAIT;
END PROCESS;
----------------------------------------------------------------------------
-- DUT: Device Under Test
----------------------------------------------------------------------------
u_dut : ENTITY work.st_xsq
GENERIC MAP(
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_a => in_sosi_a,
in_b => in_sosi_b,
-- Memory Mapped
ram_st_xsq_mosi => ram_st_xsq_mosi,
ram_st_xsq_miso => ram_st_xsq_miso
);
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