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

Svn copied tb because of search path to hex file.

parent a8dfcad3
Branches
No related tags found
No related merge requests found
......@@ -42,3 +42,7 @@ test_bench_files =
$UNB/Firmware/modules/Lofar/diag/tb/vhdl/tb_mms_diag_seq.vhd
$UNB/Firmware/modules/Lofar/diag/tb/vhdl/tb_mms_diag_block_gen.vhd
tb/vhdl/tb_diag_regression.vhd
modelsim_copy_files =
$UNB/Firmware/modules/Lofar/diag/src/data/bf_in_data.dat .
$UNB/Firmware/modules/Lofar/diag/src/data/diag_block.hex .
\ No newline at end of file
--------------------------------------------------------------------------------
--
-- Copyright (C) 2011
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.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: test bench for diag_block_gen
-- The tb is self-stopping and self-checking.
-- Usage:
-- > as 5
-- > run -all
LIBRARY IEEE, common_lib, dp_lib;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.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 dp_lib.dp_stream_pkg.ALL;
USE dp_lib.tb_dp_pkg.ALL;
USE work.diag_pkg.ALL;
ENTITY tb_diag_block_gen IS
GENERIC (
g_buf_adr_w : NATURAL := 7; -- Waveform buffer address width (requires corresponding c_buf_file)
g_buf_dat_w : NATURAL := 32 -- Waveform buffer stored data width (requires corresponding c_buf_file)
);
END tb_diag_block_gen;
ARCHITECTURE tb OF tb_diag_block_gen IS
CONSTANT clk_period : TIME := 10 ns;
-- Default settings
CONSTANT c_buf : t_c_mem := (latency => 1,
adr_w => g_buf_adr_w,
dat_w => g_buf_dat_w,
nof_dat => 2**g_buf_adr_w, -- = 2**adr_w
init_sl => '0');
CONSTANT c_buf_file : STRING := sel_a_b(c_buf.adr_w=7 AND c_buf.dat_w=32, "diag_block.hex", "UNUSED");
CONSTANT c_cntr_init : INTEGER := 0;
CONSTANT c_cntr_incr : INTEGER := 1;
CONSTANT c_cntr_arr : t_slv_32_arr(c_buf.nof_dat-1 DOWNTO 0) := flip(array_init(c_cntr_init, c_buf.nof_dat, c_cntr_incr));
CONSTANT c_bg_ctrl : t_diag_block_gen := ( '0',
'0',
TO_UVEC(96, c_diag_bg_samples_per_packet_w),
TO_UVEC(10, c_diag_bg_blocks_per_sync_w),
TO_UVEC(32, c_diag_bg_gapsize_w),
TO_UVEC( 0, c_diag_bg_mem_low_adrs_w),
TO_UVEC(95, c_diag_bg_mem_high_adrs_w),
TO_UVEC(42, c_diag_bg_bsn_init_w));
CONSTANT c_alternative_samples_per_packet : NATURAL := c_buf.nof_dat;
CONSTANT c_alternative_mem_high_adrs : NATURAL := 64;
CONSTANT c_alternative_data_gap : NATURAL := TO_UINT(c_bg_ctrl.mem_high_adrs)-c_alternative_mem_high_adrs;
SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL rst : STD_LOGIC;
SIGNAL clk : STD_LOGIC := '1';
SIGNAL verify_en : STD_LOGIC := '0';
SIGNAL mm_buf_arr : t_slv_32_arr(c_buf.nof_dat-1 DOWNTO 0);
SIGNAL mm_buf_mosi : t_mem_mosi := c_mem_mosi_rst;
SIGNAL mm_buf_miso : t_mem_miso;
SIGNAL bg_buf_mosi : t_mem_mosi := c_mem_mosi_rst;
SIGNAL bg_buf_miso : t_mem_miso;
SIGNAL bg_ctrl : t_diag_block_gen;
SIGNAL out_sosi : t_dp_sosi;
SIGNAL prev_out_sosi : t_dp_sosi;
SIGNAL hold_sop : STD_LOGIC;
SIGNAL exp_size : NATURAL;
SIGNAL cnt_size : NATURAL;
BEGIN
rst <= '1', '0' AFTER clk_period/10;
clk <= NOT clk OR tb_end AFTER clk_period/2;
p_stimuli : PROCESS
BEGIN
bg_ctrl <= c_bg_ctrl;
proc_common_wait_until_low(clk, rst); -- Wait until reset has finished
proc_common_wait_some_cycles(clk, 10);
-- Write waveform buffer
proc_mem_write_ram(c_cntr_arr, clk, mm_buf_mosi);
-- Readback waveform buffer
proc_mem_read_ram(clk, mm_buf_mosi, mm_buf_miso, mm_buf_arr);
ASSERT c_cntr_arr=mm_buf_arr REPORT "Error: Wrong BG buffer readback" SEVERITY FAILURE;
-- Run with a gap
bg_ctrl.enable <= '1';
proc_dp_verify_run_some_cycles(5, 1500, 0, clk, verify_en);
-- Run without gap
bg_ctrl.enable <= '0';
proc_common_wait_some_cycles(clk, 100);
bg_ctrl.gapsize <= TO_UVEC(0, c_diag_bg_gapsize_w);
bg_ctrl.enable <= '1';
proc_dp_verify_run_some_cycles(5, 1500, 0, clk, verify_en);
-- Run with non-aligned memory settings
bg_ctrl.enable <= '0';
proc_common_wait_some_cycles(clk, 100);
bg_ctrl.gapsize <= c_bg_ctrl.gapsize;
bg_ctrl.mem_high_adrs <= TO_UVEC(c_alternative_mem_high_adrs, c_diag_bg_mem_high_adrs_w);
bg_ctrl.enable <= '1';
proc_dp_verify_run_some_cycles(5, 1500, 0, clk, verify_en);
-- Run and change bg_ctrl dynamically
bg_ctrl.enable <= '0';
proc_common_wait_some_cycles(clk, 100);
bg_ctrl <= c_bg_ctrl;
bg_ctrl.mem_high_adrs <= TO_UVEC(c_alternative_mem_high_adrs, c_diag_bg_mem_high_adrs_w);
bg_ctrl.enable <= '1';
proc_dp_verify_run_some_cycles(5, 1500, 0, clk, verify_en);
-- . change gapsize dynamically
bg_ctrl.gapsize <= c_bg_ctrl.gapsize;
proc_dp_verify_run_some_cycles(0, 1500, 0, clk, verify_en);
-- . change mem_high_adrs dynamically
bg_ctrl.mem_high_adrs <= c_bg_ctrl.mem_high_adrs; -- increase, because decreasing could yield an verify data error
proc_dp_verify_run_some_cycles(0, 1500, 0, clk, verify_en);
-- . change samples_per_packet dynamically
bg_ctrl.samples_per_packet <= TO_UVEC(c_alternative_samples_per_packet, c_diag_bg_samples_per_packet_w); -- increase, because decreasing could yield an verify data error
proc_dp_verify_run_some_cycles(0, 1500, 0, clk, verify_en);
-- End simulation
tb_end <= '1';
WAIT;
END PROCESS;
-- Verification
exp_size <= TO_UINT(bg_ctrl.samples_per_packet);
proc_dp_verify_data("BSN", clk, verify_en, out_sosi.sop, out_sosi.bsn, prev_out_sosi.bsn);
proc_dp_verify_data("DATA", TO_UINT(c_bg_ctrl.mem_high_adrs), c_alternative_data_gap, clk, verify_en, out_sosi.valid, out_sosi.data, prev_out_sosi.data);
proc_dp_verify_sop_and_eop(clk, out_sosi.valid, out_sosi.sop, out_sosi.eop, hold_sop);
proc_dp_verify_block_size(exp_size, clk, out_sosi.valid, out_sosi.sop, out_sosi.eop, cnt_size);
-- Waveform buffer
u_buf : ENTITY common_lib.common_ram_crw_crw
GENERIC MAP (
g_ram => c_buf,
g_init_file => c_buf_file
)
PORT MAP (
rst_a => '0',
rst_b => '0',
clk_a => clk,
clk_b => clk,
wr_en_a => mm_buf_mosi.wr,
wr_en_b => '0',
wr_dat_a => mm_buf_mosi.wrdata(c_buf.dat_w-1 DOWNTO 0),
wr_dat_b => (OTHERS=>'0'),
adr_a => mm_buf_mosi.address(c_buf.adr_w-1 DOWNTO 0),
adr_b => bg_buf_mosi.address(c_buf.adr_w-1 DOWNTO 0),
rd_en_a => mm_buf_mosi.rd,
rd_en_b => bg_buf_mosi.rd,
rd_dat_a => mm_buf_miso.rddata(c_buf.dat_w-1 DOWNTO 0),
rd_dat_b => bg_buf_miso.rddata(c_buf.dat_w-1 DOWNTO 0),
rd_val_a => mm_buf_miso.rdval,
rd_val_b => bg_buf_miso.rdval
);
u_dut : ENTITY work.diag_block_gen
GENERIC MAP(
g_buf_dat_w => c_buf.dat_w,
g_buf_addr_w => c_buf.adr_w
)
PORT MAP (
rst => rst,
clk => clk,
buf_addr => bg_buf_mosi.address(c_buf.adr_w-1 DOWNTO 0),
buf_rden => bg_buf_mosi.rd,
buf_rddat => bg_buf_miso.rddata(c_buf.dat_w-1 DOWNTO 0),
buf_rdval => bg_buf_miso.rdval,
ctrl => bg_ctrl,
out_sosi => out_sosi
);
END tb;
-----------------------------------------------------------------------------
--
-- Copyright (C) 2010
-- 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: Test bench for mms_diag_block_gen
-- The tb is self-stopping and self-checking.
-- Usage:
-- > do wave_mms_diag_block_gen.do
-- > run -all
-- Observe tb_state and check the out_sosi fields if data is OK.
-- Try both c_gap_size = 0 and 160
LIBRARY IEEE, common_lib, dp_lib;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE std.textio.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 dp_lib.dp_stream_pkg.ALL;
USE dp_lib.tb_dp_pkg.ALL;
USE work.diag_pkg.ALL;
ENTITY tb_mms_diag_block_gen IS
GENERIC (
g_nof_inputs : POSITIVE := 64;
g_nof_subbands : POSITIVE := 24;
g_nof_streams : NATURAL := 16;
g_buf_dat_w : NATURAL := 32;
g_buf_addr_w : NATURAL := 7;
g_file_name_prefix : STRING := "bf_in_data";
g_sim : BOOLEAN := TRUE
);
END tb_mms_diag_block_gen;
ARCHITECTURE tb OF tb_mms_diag_block_gen IS
CONSTANT clk_period : TIME := 10 ns;
CONSTANT c_block_size : NATURAL := 96;
--CONSTANT c_gap_size : NATURAL := 0;
CONSTANT c_gap_size : NATURAL := 160;
CONSTANT c_period_size : NATURAL := c_block_size + c_gap_size;
--CONSTANT c_blk_sync : BOOLEAN := FALSE;
CONSTANT c_blk_sync : BOOLEAN := TRUE;
CONSTANT c_pend_period : NATURAL := 200;
CONSTANT c_on_period : NATURAL := 1500;
CONSTANT c_off_period : NATURAL := 550;
CONSTANT c_end_period : NATURAL := 5000;
CONSTANT c_bsn_max : UNSIGNED(c_dp_stream_bsn_w-1 DOWNTO 0) := (OTHERS=>'1');
CONSTANT c_bsn_gap : UNSIGNED(c_dp_stream_bsn_w-1 DOWNTO 0) := TO_UNSIGNED(ceil_div(c_off_period, c_period_size), c_dp_stream_bsn_w); -- depends on c_off_period
TYPE t_tb_state IS (s_init, s_enable_sync, s_enable, s_disable, s_xoff, s_xon);
SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL rst : STD_LOGIC;
SIGNAL clk : STD_LOGIC := '1';
SIGNAL en_sync : STD_LOGIC;
SIGNAL tb_state : t_tb_state;
SIGNAL ram_bg_data_mosi : t_mem_mosi := c_mem_mosi_rst;
SIGNAL ram_bg_data_miso : t_mem_miso := c_mem_miso_rst;
SIGNAL reg_bg_ctrl_mosi : t_mem_mosi := c_mem_mosi_rst;
SIGNAL reg_bg_ctrl_miso : t_mem_miso := c_mem_miso_rst;
SIGNAL out_siso_arr : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy);
SIGNAL out_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL verify_en : STD_LOGIC := '1';
SIGNAL out_sosi : t_dp_sosi;
SIGNAL prev_out_sosi : t_dp_sosi;
BEGIN
clk <= NOT clk OR tb_end AFTER clk_period/2;
rst <= '1', '0' AFTER clk_period*5;
p_write_bg_ctrl : PROCESS
BEGIN
en_sync <= '0';
out_siso_arr <= (OTHERS=>c_dp_siso_rdy); -- Flow control XON
-- BG init
tb_state <= s_init;
proc_common_wait_until_low(clk, rst); -- Wait until reset has finished
proc_common_wait_some_cycles(clk, 10); -- Wait an additional amount of cycles
proc_mem_mm_bus_wr(1, c_block_size, clk, reg_bg_ctrl_mosi); -- Set the nof samples per block
proc_mem_mm_bus_wr(2, 10, clk, reg_bg_ctrl_mosi); -- Set the nof blocks per sync
proc_mem_mm_bus_wr(3, c_gap_size, clk, reg_bg_ctrl_mosi); -- Set the gapsize
proc_mem_mm_bus_wr(4, 0, clk, reg_bg_ctrl_mosi); -- Set the mem low address
proc_mem_mm_bus_wr(5, 95, clk, reg_bg_ctrl_mosi); -- Set the mem high address
proc_mem_mm_bus_wr(6, 42, clk, reg_bg_ctrl_mosi); -- Set the lower part of the initial bsn
proc_mem_mm_bus_wr(7, 0, clk, reg_bg_ctrl_mosi); -- Set the higher part of the initial bsn
-- BG enable at en_sync pulse
proc_mem_mm_bus_wr(0, 3, clk, reg_bg_ctrl_mosi); -- Enable the block generator at en_sync pulse.
tb_state <= s_enable_sync;
proc_common_wait_some_cycles(clk, c_pend_period); -- Wait an additional amount of cycles
proc_common_gen_pulse(clk, en_sync); -- Issue the en_sync pulse to start the enabled block generator
proc_common_wait_some_cycles(clk, c_on_period); -- On time
proc_common_wait_until_high(clk, out_sosi_arr(0).valid); -- Wait until block generator is active
proc_common_wait_some_cycles(clk, 20); -- Wait an additional amount of cycles
-- BG disable
proc_mem_mm_bus_wr(0, 0, clk, reg_bg_ctrl_mosi); -- Disable the block generator.
tb_state <= s_disable;
proc_common_wait_some_cycles(clk, c_off_period); -- Off time
-- BG enable
proc_mem_mm_bus_wr(0, 1, clk, reg_bg_ctrl_mosi); -- Enable the block generator.
tb_state <= s_enable;
proc_common_wait_some_cycles(clk, c_on_period); -- On time
proc_common_wait_until_high(clk, out_sosi_arr(0).valid); -- Wait until block generator is active
proc_common_wait_some_cycles(clk, 20); -- Wait an additional amount of cycles
-- BG flow off
out_siso_arr <= (OTHERS=>c_dp_siso_rst); -- Flow control XOFF
tb_state <= s_xoff;
proc_common_wait_some_cycles(clk, c_off_period); -- Off time
-- BG flow on
out_siso_arr <= (OTHERS=>c_dp_siso_rdy); -- Flow control XON
tb_state <= s_xon;
proc_common_wait_some_cycles(clk, c_end_period); -- On time
tb_end <= '1';
WAIT;
END PROCESS;
-------------------------------------------------
-- Instantiation of the device under test
-------------------------------------------------
u_dut : ENTITY work.mms_diag_block_gen
GENERIC MAP (
g_blk_sync => c_blk_sync,
g_nof_output_streams => g_nof_streams,
g_buf_dat_w => g_buf_dat_w,
g_buf_addr_w => g_buf_addr_w,
g_file_name_prefix => g_file_name_prefix
)
PORT MAP (
-- System
mm_rst => rst,
mm_clk => clk,
dp_rst => rst,
dp_clk => clk,
en_sync => en_sync,
-- MM interface
ram_bg_data_mosi => ram_bg_data_mosi,
ram_bg_data_miso => ram_bg_data_miso,
reg_bg_ctrl_mosi => reg_bg_ctrl_mosi,
reg_bg_ctrl_miso => reg_bg_ctrl_miso,
-- ST interface
out_siso_arr => out_siso_arr,
out_sosi_arr => out_sosi_arr
);
-------------------------------------------------
-- Verification
-------------------------------------------------
p_compare_out_sosi_arr : PROCESS(clk)
BEGIN
IF rising_edge(clk) THEN
IF rst='0' THEN
FOR I IN 0 TO g_nof_streams-1 LOOP
-- All outputs have the same framing
ASSERT out_sosi_arr(0).sync =out_sosi_arr(I).sync REPORT "tb_mms_diag_block_gen: Wrong out_sosi_arr(*).sync";
ASSERT out_sosi_arr(0).bsn =out_sosi_arr(I).bsn REPORT "tb_mms_diag_block_gen: Wrong out_sosi_arr(*).bsn";
ASSERT out_sosi_arr(0).im =out_sosi_arr(I).im REPORT "tb_mms_diag_block_gen: Wrong out_sosi_arr(*).im";
ASSERT out_sosi_arr(0).valid=out_sosi_arr(I).valid REPORT "tb_mms_diag_block_gen: Wrong out_sosi_arr(*).valid";
ASSERT out_sosi_arr(0).sop =out_sosi_arr(I).sop REPORT "tb_mms_diag_block_gen: Wrong out_sosi_arr(*).sop";
ASSERT out_sosi_arr(0).eop =out_sosi_arr(I).eop REPORT "tb_mms_diag_block_gen: Wrong out_sosi_arr(*).eop";
-- Only the re part differs per output given the BG buffer data from g_file_name_prefix
ASSERT TO_UINT(out_sosi_arr(0).re)=TO_UINT(out_sosi_arr(I).re)-I*4 REPORT "tb_mms_diag_block_gen: Wrong out_sosi_arr(*).re";
END LOOP;
END IF;
END IF;
END PROCESS;
out_sosi <= out_sosi_arr(0);
p_verify_en : PROCESS
BEGIN
-- t_tb_state = s_init, s_enable_sync, s_enable
verify_en <= '0';
proc_common_wait_some_cycles(clk, 400);
verify_en <= '1';
proc_common_wait_some_cycles(clk, c_on_period);
-- t_tb_state = s_disable
verify_en <= '0';
proc_common_wait_some_cycles(clk, c_off_period);
-- t_tb_state = s_xoff, s_xon
verify_en <= '1'; -- use c_bsn_gap to cover gap in BSN during s_xoff
WAIT;
END PROCESS;
proc_dp_verify_data("BSN", c_bsn_max, c_bsn_gap, clk, verify_en, out_sosi.sop, out_sosi.bsn, prev_out_sosi.bsn);
END tb;
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment