Skip to content
Snippets Groups Projects
Commit 3197c0ff authored by Pieter Donker's avatar Pieter Donker
Browse files

extra test tb_beamfomer en tb_tb_beamformer

parent eb410eb1
No related branches found
No related tags found
No related merge requests found
......@@ -9,6 +9,7 @@ synth_files =
test_bench_files =
tb/vhdl/tb_beamformer.vhd
tb/vhdl/tb_tb_beamformer.vhd
regression_test_vhdl =
# no self checking tb available yet
......
......@@ -19,8 +19,9 @@
--
--------------------------------------------------------------------------------
-- Author:
-- Authors:
-- . Daniel van der Schuur
-- . Pieter Donker
-- Purpose:
-- .
-- Description:
......@@ -42,7 +43,7 @@ USE mm_lib.mm_file_pkg.ALL;
ENTITY tb_beamformer IS
GENERIC (
g_tb_index : NATURAL := 0; -- use different index to avoid MM file conflict in multi tb
g_technology : NATURAL := c_tech_select_default;
--g_technology : NATURAL := c_tech_select_default;
g_nof_inputs : NATURAL := 2;
g_nof_weights : NATURAL := 32;
g_data_w : NATURAL := 8 --8b complex input data
......@@ -56,39 +57,33 @@ ARCHITECTURE tb OF tb_beamformer IS
-----------------------------------------------------------------------------
CONSTANT c_dp_clk_period : TIME := 5 ns;
CONSTANT c_mm_clk_period : TIME := 25 ns;
CONSTANT c_stimulus_period : TIME := 100 ns;
SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL dp_clk : STD_LOGIC := '1';
SIGNAL dp_rst : STD_LOGIC;
SIGNAL mm_clk : STD_LOGIC := '1';
SIGNAL mm_rst : STD_LOGIC;
SIGNAL OK : STD_LOGIC := '1';
SIGNAL verify_mm_en : STD_LOGIC := '1';
SIGNAL verify_input_en : STD_LOGIC := '0';
SIGNAL verify_sum_en : STD_LOGIC := '0';
-----------------------------------------------------------------------------
-- Block generator
-----------------------------------------------------------------------------
CONSTANT c_bg_block_size : NATURAL := g_nof_weights;
CONSTANT c_bg_gapsize : NATURAL := c_bg_block_size;
CONSTANT c_bg_blocks_per_sync : NATURAL := 10; --not used
CONSTANT c_bg_ctrl : t_diag_block_gen := ('1', -- enable
'0', -- enable_sync
TO_UVEC( c_bg_block_size, c_diag_bg_samples_per_packet_w),
TO_UVEC(c_bg_blocks_per_sync, c_diag_bg_blocks_per_sync_w),
TO_UVEC( c_bg_gapsize, c_diag_bg_gapsize_w),
TO_UVEC( 0, c_diag_bg_mem_low_adrs_w),
TO_UVEC( c_bg_block_size-1, c_diag_bg_mem_high_adrs_w),
TO_UVEC( 0, c_diag_bg_bsn_init_w));
-- Input data cont
CONSTANT c_in_block_size : NATURAL := g_nof_weights;
CONSTANT c_in_block_interval : NATURAL := c_in_block_size;
CONSTANT c_in_nof_blocks_per_sync : NATURAL := g_nof_weights;
CONSTANT c_in_sync_interval : NATURAL := c_in_block_interval*c_in_nof_blocks_per_sync;
SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL dp_clk : STD_LOGIC := '1';
SIGNAL dp_rst : STD_LOGIC;
SIGNAL mm_clk : STD_LOGIC := '1';
SIGNAL mm_rst : STD_LOGIC;
SIGNAL OK : STD_LOGIC := '1';
SIGNAL mm_ok : STD_LOGIC := '1';
SIGNAL addr_ok : STD_LOGIC := '1';
SIGNAL data_ok : STD_LOGIC := '1';
SIGNAL verify_mm_en : STD_LOGIC := '1';
SIGNAL verify_addr_en : STD_LOGIC := '0';
SIGNAL verify_data_en : STD_LOGIC := '0';
-- MM
CONSTANT c_unb_nr : NATURAL := 0;
CONSTANT c_node_nr : NATURAL := 0; -- choose node 0 is FN 0
CONSTANT c_mm_file_ram_beamformer : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_BEAMFORMER_" & int_to_str(g_tb_index);
SIGNAL block_gen_src_out_arr : t_dp_sosi_arr(1-1 DOWNTO 0);
SIGNAL src_in_enable : STD_LOGIC := '0';
SIGNAL src_in : t_dp_sosi := c_dp_sosi_rst;
-----------------------------------------------------------------------------
-- beamformer
......@@ -100,12 +95,18 @@ ARCHITECTURE tb OF tb_beamformer IS
SIGNAL beamformer_snk_in_arr : t_dp_sosi_arr(g_nof_inputs-1 DOWNTO 0);
SIGNAL beamformer_src_out : t_dp_sosi;
SIGNAL beamformer_weight_addr : STD_LOGIC_VECTOR(ceil_log2(g_nof_weights)-1 DOWNTO 0);
SIGNAL beamformer_weight_addr : STD_LOGIC_VECTOR(ceil_log2(g_nof_weights)-1 DOWNTO 0);
SIGNAL addr_stimulus_weight_addr : STD_LOGIC_VECTOR(ceil_log2(g_nof_weights)-1 DOWNTO 0) := (OTHERS=>'0');
SIGNAL data_stimulus_weight_addr : STD_LOGIC_VECTOR(ceil_log2(g_nof_weights)-1 DOWNTO 0) := (OTHERS=>'0');
SIGNAL rd_data : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
BEGIN
-- used to set src_in re data
SIGNAL src_re_data : STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0) := "00000001";
SIGNAL src_im_data : STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0) := "00000001";
BEGIN
-----------------------------------------------------------------------------
-- Clocks and reset
-------------------------------------------------------------------------------
......@@ -115,15 +116,50 @@ BEGIN
mm_clk <= NOT mm_clk OR tb_end AFTER c_mm_clk_period/2;
mm_rst <= '1', '0' AFTER c_mm_clk_period*7;
----------------------------------------------------------------------------
-- Stimuli src_in
----------------------------------------------------------------------------
-- sync, valid, sop, eop
proc_common_gen_duty_pulse(0, 1, c_in_sync_interval, '1', dp_rst, dp_clk, src_in_enable, src_in.sync);
proc_common_gen_duty_pulse(0, c_in_block_size, c_in_block_interval, '1', dp_rst, dp_clk, src_in_enable, src_in.valid);
proc_common_gen_duty_pulse(0, 1, c_in_block_interval, '1', dp_rst, dp_clk, src_in_enable, src_in.sop);
proc_common_gen_duty_pulse(c_in_block_size-1, 1, c_in_block_interval, '1', dp_rst, dp_clk, src_in_enable, src_in.eop); -- DUT uses eop
-- bsn
src_in.bsn <= INCR_UVEC(src_in.bsn, 1) WHEN rising_edge(dp_clk) AND src_in.eop='1';
-- re/im data
src_in.re <= TO_DP_DSP_DATA(TO_UINT(src_re_data));
src_in.im <= TO_DP_DSP_DATA(TO_UINT(src_im_data));
-- set master OK
OK <= mm_ok and addr_ok and data_ok;
-- change beamformer weights address from multiple processes
set_weights : PROCESS(verify_addr_en, addr_stimulus_weight_addr, verify_data_en, data_stimulus_weight_addr)
BEGIN
beamformer_weight_addr <= TO_UVEC(0, ceil_log2(g_nof_weights));
IF verify_addr_en = '1' THEN
beamformer_weight_addr <= addr_stimulus_weight_addr;
END IF;
IF verify_data_en = '1' THEN
beamformer_weight_addr <= data_stimulus_weight_addr;
END IF;
END PROCESS;
-- first check, write/read weight to/from RAM
mm_stimulus: PROCESS
BEGIN
IF verify_mm_en = '1' THEN
-- wait for reset
proc_common_wait_until_low(mm_clk, mm_rst);
proc_common_wait_until_low(dp_clk, dp_rst);
proc_common_wait_some_cycles(dp_clk, 10);
-- enable src_in generator
src_in_enable <= '1';
proc_common_wait_until_hi_lo(dp_clk, src_in.sync);
REPORT "Start mm stumulus";
FOR I IN 0 TO g_nof_inputs-1 LOOP
FOR J IN 0 TO g_nof_weights-1 LOOP
......@@ -136,82 +172,99 @@ BEGIN
FOR J IN 0 TO g_nof_weights-1 LOOP
-- read back MM page
mmf_mm_bus_rd(c_mm_file_ram_beamformer, I*g_nof_weights+J, rd_data, mm_clk);
IF UNSIGNED(rd_data) /= J THEN
OK <= '0';
IF TO_UINT(rd_data) /= J THEN
ASSERT FALSE
REPORT "MM Wrong weight" &
", expected=" & int_to_str(J) &
", readback=" & int_to_str(INTEGER(TO_UINT(rd_data)))
SEVERITY ERROR;
mm_ok <= '0';
END IF;
ASSERT TO_UINT(rd_data)=J
REPORT "MM Wrong weight, expected=" & int_to_str(J) & ", readback=" & int_to_str(INTEGER(TO_UINT(rd_data)))
SEVERITY ERROR;
END LOOP;
END LOOP;
verify_sum_en <= '1';
verify_addr_en <= '1'; -- enable second check
END IF;
WAIT;
END PROCESS;
weights_addr_stimulus: PROCESS
-- second check, activate weights and check effect on output
addr_stimulus: PROCESS
BEGIN
proc_common_wait_until_high(dp_clk, verify_sum_en);
proc_common_wait_until_high(dp_clk, verify_addr_en);
REPORT "Start weights addr stimulus";
-- loop over all weights adresses
FOR i IN 0 TO g_nof_weights-1 LOOP
REPORT "Start weights addr stimulus for weight " & int_to_str(i);
beamformer_weight_addr <= STD_LOGIC_VECTOR(TO_UNSIGNED(i, ceil_log2(g_nof_weights)));
WAIT FOR c_stimulus_period;
proc_common_wait_until_high(dp_clk, beamformer_src_out.valid);
IF UNSIGNED(beamformer_weight_addr)*g_nof_inputs /= UNSIGNED(beamformer_src_out.re) THEN
OK <= '0';
--REPORT "Start weights addr stimulus for weight " & int_to_str(i);
addr_stimulus_weight_addr <= TO_UVEC(i, ceil_log2(g_nof_weights));
proc_common_wait_some_cycles(dp_clk, 5+ceil_log2(g_nof_inputs));
IF TO_UINT(beamformer_weight_addr)*g_nof_inputs /= TO_UINT(beamformer_src_out.re) THEN
ASSERT FALSE
REPORT "Beamformer wrong weights" &
", expected=" & int_to_str(TO_UINT(beamformer_weight_addr)*g_nof_inputs) &
", readback=" & int_to_str(TO_UINT(beamformer_src_out.re))
SEVERITY ERROR;
addr_ok <= '0';
END IF;
ASSERT UNSIGNED(beamformer_weight_addr)*g_nof_inputs = UNSIGNED(beamformer_src_out.re)
REPORT "Beamformer wrong weights" &
", expected=" & int_to_str(TO_SINT(beamformer_weight_addr)*g_nof_inputs) &
", readback=" & int_to_str(TO_SINT(beamformer_src_out.re))
SEVERITY ERROR;
END LOOP;
tb_end <= '1'; -- end test
verify_data_en <= '1'; -- enable third check
WAIT;
END PROCESS;
-- third check, change input data and check effect on output
data_stimulus: PROCESS
BEGIN
proc_common_wait_until_high(dp_clk, verify_data_en);
REPORT "Start data stimulus";
-- loop over weight address 1..2
FOR I IN 1 TO 2 LOOP
data_stimulus_weight_addr <= TO_UVEC(I, ceil_log2(g_nof_weights));
proc_common_wait_some_cycles(dp_clk, 2);
-- loop over input data.re 1..127
FOR J IN 1 TO 127 LOOP
--REPORT "Start data stimulus with input " & int_to_str(i);
src_re_data <= TO_UVEC(J, g_data_w);
proc_common_wait_some_cycles(dp_clk, 4+ceil_log2(g_nof_inputs)+1);
IF TO_UINT(beamformer_weight_addr)*g_nof_inputs*J /= TO_UINT(beamformer_src_out.re) THEN
ASSERT FALSE
REPORT "Beamformer wrong data" &
", expected=" & int_to_str(TO_UINT(beamformer_weight_addr)*g_nof_inputs*J) &
", readback=" & int_to_str(TO_UINT(beamformer_src_out.re))
SEVERITY ERROR;
data_ok <= '0';
END IF;
END LOOP; -- input data
END LOOP; -- weigth address
IF OK = '0' THEN
REPORT "TEST WENT WRONG.";
ELSE
REPORT "Test succesfull ended.";
END IF;
-----------------------------------------------------------------------------
-- Block generator:
-- . X pol = complex( 1, 1)
-- . Y pol = complex(-1,-1)
-----------------------------------------------------------------------------
u_mms_diag_block_gen : ENTITY diag_lib.mms_diag_block_gen
GENERIC MAP (
g_nof_streams => 1,
g_buf_dat_w => g_data_w,
g_buf_addr_w => ceil_log2(TO_UINT(c_bg_ctrl.samples_per_packet)),
g_file_name_prefix => "hex/mms_diag_block_gen",
g_diag_block_gen_rst => c_bg_ctrl
)
PORT MAP (
mm_clk => mm_clk,
mm_rst => mm_rst,
dp_clk => dp_clk,
dp_rst => dp_rst,
tb_end <= '1'; -- end test
WAIT;
END PROCESS;
out_sosi_arr => block_gen_src_out_arr
);
-----------------------------------------------------------------------------
-- beamformer for each TAB
-----------------------------------------------------------------------------
u_mm_file_ram_beamformer : ENTITY mm_lib.mm_file GENERIC MAP(c_mm_file_ram_beamformer) PORT MAP(mm_rst, mm_clk, ram_beamformer_mosi, ram_beamformer_miso);
-- assign input_source to snk_in_arr
gen_beamformer_snk_in_arr : FOR i IN 0 TO g_nof_inputs-1 GENERATE
beamformer_snk_in_arr(i) <= block_gen_src_out_arr(0); -- Copy the block gen stream 'g_nof_inputs' times
beamformer_snk_in_arr(i) <= src_in; -- Copy the block gen stream 'g_nof_inputs' times
END GENERATE;
u_beamformer : ENTITY work.beamformer
GENERIC MAP (
g_technology => g_technology,
g_technology => c_tech_select_default,
g_nof_inputs => g_nof_inputs,
g_nof_weights => g_nof_weights,
g_data_w => g_data_w,
......@@ -232,5 +285,6 @@ BEGIN
src_out => beamformer_src_out
);
END tb;
--------------------------------------------------------------------------------
--
-- Copyright (C) 2017
-- 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/>.
--
--------------------------------------------------------------------------------
-- Author:
-- . Pieter Donker
-- Purpose:
-- .
-- Description:
-- .
LIBRARY IEEE, common_lib, dp_lib, technology_lib, diag_lib, mm_lib;
USE IEEE.std_logic_1164.ALL;
ENTITY tb_tb_beamformer IS
END tb_tb_beamformer;
ARCHITECTURE tb OF tb_tb_beamformer IS
SIGNAL tb_end : STD_LOGIC := '0'; -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end'
BEGIN
-- Usage
-- > as 8
-- > run -all
-- > Testbenches are self-checking
--
-- g_tb_index : NATURAL := 0; -- use different index to avoid MM file conflict in multi tb
-- --g_technology : NATURAL := c_tech_select_default;
-- g_nof_inputs : NATURAL := 2;
-- g_nof_weights : NATURAL := 32;
-- g_data_w : NATURAL := 8 --8b complex input data
--
-- do test for different number of inputs
sim_i1_beamformer : ENTITY work.tb_beamformer GENERIC MAP (1, 1, 32, 8);
sim_i2_beamformer : ENTITY work.tb_beamformer GENERIC MAP (2, 2, 32, 8);
sim_i3_beamformer : ENTITY work.tb_beamformer GENERIC MAP (3, 3, 32, 8);
sim_i8_beamformer : ENTITY work.tb_beamformer GENERIC MAP (4, 8, 32, 8);
sim_i32_beamformer : ENTITY work.tb_beamformer GENERIC MAP (5, 32, 32, 8);
END tb;
\ No newline at end of file
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