Skip to content
Snippets Groups Projects
Commit 8624eec1 authored by Daniel van der Schuur's avatar Daniel van der Schuur
Browse files

Update: added DC stimuli and verification to TB and TB_TB.

Also added:

    signed/unsigned histogram readout to st_histogram;
    Extra check in TB to check if verification was done at all;
    Added behavioural sine wave generation in TB;
    Added TB signals to display as Analog; allows viewing of input sine and resulting histogram.
parent 28fd96f0
Branches
No related tags found
1 merge request!137st_histogram updates. Ready for integration in LOFAR2.
......@@ -88,7 +88,8 @@ ENTITY st_histogram IS
GENERIC (
g_data_w : NATURAL := 8;
g_nof_bins : NATURAL := 256;
g_nof_data_per_sync : NATURAL := 1024
g_nof_data_per_sync : NATURAL := 1024;
g_data_type : STRING := "unsigned" -- unsigned or signed
);
PORT (
dp_clk : IN STD_LOGIC;
......@@ -407,8 +408,21 @@ BEGIN
-------------------------------------------------------------------------------
-- Expose the MM buses to the user
-- . apply address correction if snk_in carries signed data
-------------------------------------------------------------------------------
ram_miso <= histogram_rd_miso;
histogram_rd_mosi <= ram_mosi;
gen_unsiged: IF g_data_type="unsigned" GENERATE
histogram_rd_mosi <= ram_mosi;
END GENERATE;
gen_signed: IF g_data_type="signed" GENERATE
p_addr_swap: PROCESS(ram_mosi) IS
BEGIN
histogram_rd_mosi <= ram_mosi;
histogram_rd_mosi.address <= ram_mosi.address;
histogram_rd_mosi.address(g_data_w-1) <= NOT ram_mosi.address(g_data_w-1); -- Invert MS address bit
END PROCESS;
END GENERATE;
END rtl;
......@@ -29,16 +29,20 @@
-- . (load simulation config)
-- . as 8
-- . run -a
-- . For signals 'stimuli_data' and 'histogram' select Format->Analog(automatic)
-- . set Radix to 'decimal' for signed input data.
-- Description:
-- . Verification be eye (wave window) - observe that:
-- . There are 4 sync periods in which 3 packets of 1024 words are generated;
-- . histogram_snk_in.data = 0..1023, 3 times per sync
-- . st_histogram has 256 bins so uses the 8 MS bits of snk_in.data
-- . st_histogram will count 4*0..255 instead of 0..1023 per packet
-- . st_histogram will count 12 occurences (3 packets * 4 * 0..255) per sync.
-- . bin_writer_mosi writes bin counts 1..12 per sync interval;
-- . Both RAMs are used twice: RAM 0, RAM 1, RAM 0, RAM 1;
-- . RAM clearing completes just before the end of each sync interval.
-- . Verification be eye (wave window):
-- . For the sine input, observe input 'stimuli_data' and output 'histogram' signals.
-- . For counter data, observe that:
-- . There are 4 sync periods in which 3 packets of 1024 words are generated;
-- . histogram_snk_in.data = 0..1023, 3 times per sync
-- . st_histogram has 256 bins so uses the 8 MS bits of snk_in.data
-- . st_histogram will count 4*0..255 instead of 0..1023 per packet
-- . st_histogram will count 12 occurences (3 packets * 4 * 0..255) per sync.
-- . bin_writer_mosi writes bin counts 1..12 per sync interval;
-- . Both RAMs are used twice: RAM 0, RAM 1, RAM 0, RAM 1;
-- . RAM clearing completes just before the end of each sync interval.
-- . Automatic verification:
-- . In each sync period the RAM contents are read out via ram_mosi/miso and
-- compared to the expected bin counts.
......@@ -47,7 +51,10 @@
LIBRARY IEEE, common_lib, mm_lib, dp_lib;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE IEEE.math_real.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_lfsr_sequences_pkg.ALL;
USE common_lib.common_str_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE common_lib.tb_common_mem_pkg.ALL;
USE common_lib.tb_common_pkg.ALL;
......@@ -56,10 +63,12 @@ USE dp_lib.tb_dp_pkg.ALL;
ENTITY tb_st_histogram IS
GENERIC(
g_nof_sync : NATURAL := 4; -- We're simulating at least 4 g_nof_sync so both RAMs are written and cleared twice.
g_data_w : NATURAL := 8; -- Determines maximum number of bins (2^g_data_w)
g_nof_bins : NATURAL := 256; -- Lower than or equal to 2^g_data_w. Higher is allowed but makes no sense.
g_nof_data_per_sync : NATURAL := 1024 -- Determines max required RAM data width. e.g. 11b to store max bin count '1024'.
g_nof_sync : NATURAL := 4; -- We're simulating at least 4 g_nof_sync so both RAMs are written and cleared twice.
g_data_w : NATURAL := 8; -- Determines maximum number of bins (2^g_data_w)
g_nof_bins : NATURAL := 256; -- Lower than or equal to 2^g_data_w. Higher is allowed but makes no sense.
g_nof_data_per_sync : NATURAL := 1024; -- Determines max required RAM data width. e.g. 11b to store max bin count '1024'.
g_stimuli_mode : STRING := "sine"; -- "counter", "dc", "sine"
g_data_type : STRING := "signed" -- use "signed" if g_stimuli_mode="sine"
);
END tb_st_histogram;
......@@ -69,7 +78,8 @@ ARCHITECTURE tb OF tb_st_histogram IS
---------------------------------------------------------------------------
-- Constants derived from generics
---------------------------------------------------------------------------
CONSTANT c_expected_ram_content : NATURAL := g_nof_data_per_sync/g_nof_bins;
CONSTANT c_expected_ram_content_counter : NATURAL := g_nof_data_per_sync/g_nof_bins;
CONSTANT c_nof_levels_per_bin : NATURAL := (2**g_data_w)/g_nof_bins; --e.g. 2 values per bin if g_data_w=9 (512 levels) and g_nof_bins=256
CONSTANT c_ram_dat_w : NATURAL := ceil_log2(g_nof_data_per_sync)+1;
......@@ -90,6 +100,10 @@ ARCHITECTURE tb OF tb_st_histogram IS
SIGNAL stimuli_src_out : t_dp_sosi;
SIGNAL stimuli_src_in : t_dp_siso;
SIGNAL stimuli_count : REAL;
SIGNAL stimuli_data : STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0);
SIGNAL stimuli_done : STD_LOGIC;
----------------------------------------------------------------------------
-- st_histogram
......@@ -105,6 +119,12 @@ ARCHITECTURE tb OF tb_st_histogram IS
SIGNAL ram_rd_word_int : NATURAL;
SIGNAL ram_rd_word_valid : STD_LOGIC;
SIGNAL nxt_ram_rd_word_valid : STD_LOGIC;
SIGNAL verification_done : STD_LOGIC;
----------------------------------------------------------------------------
-- Signal to display histogram as 'analog signal' in wave window
----------------------------------------------------------------------------
SIGNAL histogram : NATURAL;
BEGIN
......@@ -116,7 +136,7 @@ BEGIN
----------------------------------------------------------------------------
-- Stimuli: generate st_histogram input data and clear the RAM
-- Stimuli: generate st_histogram input data
----------------------------------------------------------------------------
stimuli_src_in <= c_dp_siso_rdy;
......@@ -124,16 +144,68 @@ BEGIN
p_generate_packets : PROCESS
VARIABLE v_sosi : t_dp_sosi := c_dp_sosi_rst;
BEGIN
stimuli_done <= '0';
stimuli_src_out <= c_dp_sosi_rst;
proc_common_wait_until_low(dp_clk, dp_rst);
proc_common_wait_some_cycles(dp_clk, 5);
FOR I IN 0 TO g_nof_sync-1 LOOP
v_sosi.sync := '1';
v_sosi.data := RESIZE_DP_DATA(v_sosi.data(g_data_w-1 DOWNTO 0)); -- wrap when >= 2**g_data_w
proc_dp_gen_block_data(g_data_w, TO_UINT(v_sosi.data), g_nof_data_per_sync, TO_UINT(v_sosi.channel), TO_UINT(v_sosi.err), v_sosi.sync, v_sosi.bsn, dp_clk, stimuli_en, stimuli_src_in, stimuli_src_out);
END LOOP;
IF g_stimuli_mode="counter" THEN
FOR I IN 0 TO g_nof_sync-1 LOOP
v_sosi.sync := '1';
v_sosi.data := RESIZE_DP_DATA(v_sosi.data(g_data_w-1 DOWNTO 0)); -- wrap when >= 2**g_data_w
-- Generate a block of counter data
proc_dp_gen_block_data(g_data_w, TO_UINT(v_sosi.data), g_nof_data_per_sync, TO_UINT(v_sosi.channel), TO_UINT(v_sosi.err), v_sosi.sync, v_sosi.bsn, dp_clk, stimuli_en, stimuli_src_in, stimuli_src_out);
END LOOP;
END IF;
IF g_stimuli_mode="dc" THEN
stimuli_src_out.valid <= '1';
FOR I IN 0 TO g_nof_sync-1 LOOP
-- Generate a DC level that increments every sync
stimuli_src_out.data <= INCR_UVEC(stimuli_src_out.data, 1); --all g_nof_data_per_sync cycles
stimuli_src_out.sync <= '1'; -- cycle 0
WAIT FOR 5 ns;
FOR j IN 1 TO g_nof_data_per_sync-1 LOOP --cycles 1..g_nof_data_per_sync-1
stimuli_src_out.sync <= '0';
WAIT FOR 5 ns;
END LOOP;
END LOOP;
END IF;
IF g_stimuli_mode="sine" THEN
stimuli_src_out.valid <= '1';
stimuli_count <= 0.0;
FOR I IN 0 TO g_nof_sync-1 LOOP
-- Generate a DC level that increments every sync
stimuli_src_out.data <= (OTHERS=>'0');
stimuli_src_out.sync <= '1'; -- cycle 0
WAIT FOR 5 ns;
FOR j IN 1 TO g_nof_data_per_sync-1 LOOP --cycles 1..g_nof_data_per_sync-1
stimuli_src_out.sync <= '0';
stimuli_data <= TO_SVEC( integer(round( 100.0* sin(stimuli_count) )), g_data_w);
stimuli_src_out.data(g_data_w-1 DOWNTO 0) <= stimuli_data;
stimuli_count<=stimuli_count+0.1;
WAIT FOR 5 ns;
END LOOP;
END LOOP;
END IF;
IF g_stimuli_mode="random" THEN
stimuli_src_out.valid <= '1';
FOR I IN 0 TO g_nof_sync-1 LOOP
stimuli_data <= (OTHERS=>'0');
stimuli_src_out.sync <= '1'; -- cycle 0
WAIT FOR 5 ns;
FOR j IN 1 TO g_nof_data_per_sync-1 LOOP --cycles 1..g_nof_data_per_sync-1
stimuli_src_out.sync <= '0';
stimuli_data <= func_common_random(stimuli_data);
stimuli_src_out.data(g_data_w-1 DOWNTO 0) <= stimuli_data; --all g_nof_data_per_sync cycles
WAIT FOR 5 ns;
END LOOP;
END LOOP;
END IF;
stimuli_done <= '1';
proc_common_wait_some_cycles(dp_clk, 50);
tb_end <= '1';
WAIT;
......@@ -149,7 +221,8 @@ BEGIN
GENERIC MAP(
g_data_w => g_data_w,
g_nof_bins => g_nof_bins,
g_nof_data_per_sync => g_nof_data_per_sync
g_nof_data_per_sync => g_nof_data_per_sync,
g_data_type => g_data_type
)
PORT MAP (
dp_clk => dp_clk,
......@@ -166,23 +239,34 @@ BEGIN
-- . The table below shows what RAM we are reading here ('RAM read') via the
-- ram_mosi/miso interface, and what the expected RAM contents are.
--
---+-------------+-------------+----------+--------------+
-- | Sync period | RAM written | RAM read | RAM contents |
-- +-------------+-------------+----------+--------------+
-- | 0 | 0 | 1 | 256 * 0 |
-- | 1 | 1 | 0 | 256 * 12 |
-- | 2 | 0 | 1 | 256 * 12 |
-- | 3 | 1 | 0 | 256 * 12 |
-- +-------------+-------------+----------+--------------+
-- Counter data (the same every sync excl. sync 0):
---+-------------+-------------+----------+-----------------------+
-- | Sync period | RAM written | RAM read | RAM contents |
-- +-------------+-------------+----------+-----------------------+
-- | 0 | 0 | 1 | 256 addresses * 0 |
-- | 1 | 1 | 0 | 256 addresses * 12 |
-- | 2 | 0 | 1 | 256 addresses * 12 |
-- | 3 | 1 | 0 | 256 addresses * 12 |
-- +-------------+-------------+----------+-----------------------+
--
-- DC data (increments level every sync: 0, 1, 2, 3, ..):
---+-------------+-------------+----------+-----------------------+
-- | Sync period | RAM written | RAM read | RAM contents |
-- +-------------+-------------+----------+-----------------------+
-- | 0 | 0 | 1 | 256 addresses * 0 |
-- | 1 | 1 | 0 | Addr 1: 1024, others 0|
-- | 2 | 0 | 1 | Addr 2: 1024, others 0|
-- | 3 | 1 | 0 | Addr 3: 1024, others 0|
-- +-------------+-------------+----------+-----------------------+
----------------------------------------------------------------------------
-- Perform MM read and put result in ram_rd_word
p_verify_mm_read : PROCESS
BEGIN
st_histogram_ram_mosi.wr <= '0';
FOR i IN 0 TO g_nof_sync-1 LOOP
proc_common_wait_until_high(dp_clk, stimuli_src_out.sync); -- Wait for sync
proc_common_wait_some_cycles(dp_clk, 10); -- give it a couple of more cycles
proc_common_wait_until_high(dp_clk, stimuli_src_out.sync);
proc_common_wait_some_cycles(dp_clk, 10);
FOR j IN 0 TO g_nof_bins-1 LOOP
proc_mem_mm_bus_rd(j, dp_clk, st_histogram_ram_mosi);
ram_rd_word <= st_histogram_ram_miso.rddata(c_ram_dat_w-1 DOWNTO 0);
......@@ -205,16 +289,48 @@ BEGIN
-- Perform verification of ram_rd_word when ram_rd_word_valid
p_verify_assert : PROCESS
BEGIN
verification_done <= '0';
FOR i IN 0 TO g_nof_sync-1 LOOP
proc_common_wait_until_high(dp_clk, stimuli_src_out.sync);
proc_common_wait_until_high(dp_clk, ram_rd_word_valid);
IF i=0 THEN -- Sync period 0: we expect RAM to contain zeros
ASSERT ram_rd_word_int=0 REPORT "RAM contains wrong bin count (expected 0, actual " & INTEGER'IMAGE(ram_rd_word_int) & ")" SEVERITY ERROR;
ELSE -- Sync period 1 onwards
ASSERT ram_rd_word_int=c_expected_ram_content REPORT "RAM contains wrong bin count (expected " & INTEGER'IMAGE(c_expected_ram_content) & ", actual " & INTEGER'IMAGE(ram_rd_word_int) & ")" SEVERITY ERROR;
END IF;
FOR j IN 0 TO g_nof_bins-1 LOOP
proc_common_wait_until_high(dp_clk, ram_rd_word_valid);
IF i=0 THEN -- Sync period 0: we expect RAM to contain zeros
ASSERT ram_rd_word_int=0 REPORT "RAM contains wrong bin count (expected 0, actual " & INTEGER'IMAGE(ram_rd_word_int) & ")" SEVERITY ERROR;
ELSE -- Sync period 1 onwards
IF g_stimuli_mode="counter" THEN
-- Counter data: ban values remain the same every sync
ASSERT ram_rd_word_int=c_expected_ram_content_counter REPORT "RAM contains wrong bin count (expected " & INTEGER'IMAGE(c_expected_ram_content_counter) & ", actual " & INTEGER'IMAGE(ram_rd_word_int) & ")" SEVERITY ERROR;
ELSIF g_stimuli_mode="dc" THEN
-- DC data: DC level increments every sync
IF j=(i/c_nof_levels_per_bin)+1 THEN -- Check bin address and account for multiple levels per bin
-- this address (j) should contain the DC level total count of this sync period (i)
ASSERT ram_rd_word_int=g_nof_data_per_sync REPORT "RAM contains wrong bin count (expected " & INTEGER'IMAGE(g_nof_data_per_sync) & ", actual " & INTEGER'IMAGE(ram_rd_word_int) & ")" SEVERITY ERROR;
ELSE
-- this address should contain zero
ASSERT ram_rd_word_int=0 REPORT "RAM contains wrong bin count (expected 0, actual " & INTEGER'IMAGE(ram_rd_word_int) & ")" SEVERITY ERROR;
END IF;
END IF;
END IF;
WAIT FOR 5 ns;
END LOOP;
END LOOP;
WAIT FOR 5 ns;
verification_done <= '1'; --We have blocking proc_common_wait_until_high procedures above so we need to know if we make it here.
WAIT;
END PROCESS;
-- Check if verification was done at all
p_check_verification_done : PROCESS
BEGIN
proc_common_wait_until_high(dp_clk, stimuli_done);
ASSERT verification_done='1' REPORT "Verification failed" SEVERITY ERROR;
WAIT;
END PROCESS;
----------------------------------------------------------------------------
-- Create a signal that displays histogram (view as analog in Questa Sim)
-- in wave window
----------------------------------------------------------------------------
histogram <= ram_rd_word_int WHEN ram_rd_word_valid='1' ELSE 0;
END tb;
......@@ -25,7 +25,7 @@
-- Usage
-- . as 8
-- . run -all
-- . Testbenches are self-checking
-- . Testbenches are self-checking for g_stimuli_mode="counter" and "dc".
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
......@@ -41,12 +41,19 @@ BEGIN
-- g_data_w : NATURAL := 8;
-- g_nof_bins : NATURAL := 256;
-- g_nof_data : NATURAL := 1024;
-- g_stimuli_mode : STRING := "dc";
-- g_data_type : STRING := "unsigned"
u_tb_st_histogram_0 : ENTITY work.tb_st_histogram GENERIC MAP ( 7, 8, 256, 1024); -- Incoming data wraps (repeats) 1024/ 256= 4 times: Bin count = 4
u_tb_st_histogram_1 : ENTITY work.tb_st_histogram GENERIC MAP ( 6, 10, 256, 4096); -- Incoming data wraps (repeats) 4096/ 256=16 times: Bin count = 16
u_tb_st_histogram_2 : ENTITY work.tb_st_histogram GENERIC MAP ( 5, 12, 512, 4096); -- Incoming data wraps (repeats) 4096/ 512= 8 times: Bin count = 8
u_tb_st_histogram_3 : ENTITY work.tb_st_histogram GENERIC MAP ( 4, 13, 1024, 8192); -- Incoming data wraps (repeats) 8192/1024= 8 times: Bin count = 8
u_tb_st_histogram_4 : ENTITY work.tb_st_histogram GENERIC MAP (40, 6, 64, 128); -- Incoming data wraps (repeats) 128/ 64= 2 times: Bin count = 2
u_tb_st_histogram_0 : ENTITY work.tb_st_histogram GENERIC MAP ( 7, 8, 256, 1024, "counter", "unsigned"); -- Incoming data wraps (repeats) 1024/ 256= 4 times: Bin count = 4
u_tb_st_histogram_1 : ENTITY work.tb_st_histogram GENERIC MAP ( 6, 10, 256, 4096, "counter", "unsigned"); -- Incoming data wraps (repeats) 4096/ 256=16 times: Bin count = 16
u_tb_st_histogram_2 : ENTITY work.tb_st_histogram GENERIC MAP ( 5, 12, 512, 4096, "counter", "unsigned"); -- Incoming data wraps (repeats) 4096/ 512= 8 times: Bin count = 8
u_tb_st_histogram_3 : ENTITY work.tb_st_histogram GENERIC MAP ( 4, 13, 1024, 8192, "counter", "unsigned"); -- Incoming data wraps (repeats) 8192/1024= 8 times: Bin count = 8
u_tb_st_histogram_4 : ENTITY work.tb_st_histogram GENERIC MAP (40, 6, 64, 128, "counter", "unsigned"); -- Incoming data wraps (repeats) 128/ 64= 2 times: Bin count = 2
u_tb_st_histogram_5 : ENTITY work.tb_st_histogram GENERIC MAP ( 2, 8, 256, 1024, "dc", "unsigned");
u_tb_st_histogram_6 : ENTITY work.tb_st_histogram GENERIC MAP ( 6, 10, 256, 4096, "dc", "unsigned");
u_tb_st_histogram_7 : ENTITY work.tb_st_histogram GENERIC MAP ( 5, 12, 512, 4096, "dc", "unsigned");
u_tb_st_histogram_8 : ENTITY work.tb_st_histogram GENERIC MAP ( 4, 13, 1024, 8192, "dc", "unsigned");
u_tb_st_histogram_9 : ENTITY work.tb_st_histogram GENERIC MAP (40, 6, 64, 128, "dc", "unsigned");
END tb;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment