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

-Added RAM readout and verification to tb_mms_st_histogram.

parent 920bbdab
No related branches found
No related tags found
3 merge requests!101Merged sub-branch L2SDP-151 into L2SDP-143 (st_histogram rework),!99Cleaned/rewrote st_histogram.,!98Major rework on st_histogram.
......@@ -35,9 +35,8 @@
-- 3) User reads ram_filling status until it reads zero via reg_mosi
-- 4) User reads freshly filled RAM contents via ram_mosi
-- . Clearing the RAMs:
-- 1) User writes to bit 0 of ram_clear register to clear RAMs of all
-- g_nof_instances
-- . ram_clearing status will go high
-- . The inactive RAM is cleared automatically just before the next input sync.
-- . ram_clearing status will go high during this time.
LIBRARY IEEE, common_lib, mm_lib, technology_lib, dp_lib;
USE IEEE.std_logic_1164.ALL;
......@@ -90,13 +89,9 @@ ARCHITECTURE str OF mms_st_histogram IS
SIGNAL common_ram_cr_cw_rd_mosi : t_mem_mosi;
SIGNAL common_ram_cr_cw_rd_miso : t_mem_miso;
-- SIGNAL reg_mosi_arr : t_mem_mosi_arr(g_nof_instances-1 DOWNTO 0);
-- SIGNAL reg_miso_arr : t_mem_miso_arr(g_nof_instances-1 DOWNTO 0);
SIGNAL ram_mosi_arr : t_mem_mosi_arr(g_nof_instances-1 DOWNTO 0);
SIGNAL ram_miso_arr : t_mem_miso_arr(g_nof_instances-1 DOWNTO 0);
SIGNAL ram_clear : STD_LOGIC;
SIGNAL ram_clearing_arr : STD_LOGIC_VECTOR(g_nof_instances-1 DOWNTO 0);
SIGNAL ram_fill_inst : STD_LOGIC_VECTOR(ceil_log2(g_nof_instances)-1 DOWNTO 0);
......@@ -126,7 +121,6 @@ BEGIN
snk_in => snk_in_arr(i),
ram_clear => ram_clear,
ram_clearing => ram_clearing_arr(i),
ram_mosi => ram_mosi_arr(i),
......@@ -148,7 +142,6 @@ BEGIN
mm_clk => mm_clk,
mm_rst => mm_rst,
ram_clear => ram_clear,
ram_fill_inst => ram_fill_inst,
ram_fill => ram_fill,
......@@ -157,22 +150,6 @@ BEGIN
);
-- -------------------------------------------------------------------------------
-- -- MM multiplexer from g_nof_instances to 1
-- -------------------------------------------------------------------------------
-- u_common_mem_mux_reg : ENTITY common_lib.common_mem_mux
-- GENERIC MAP (
-- g_nof_mosi => g_nof_instances,
-- g_mult_addr_w => c_reg_adr_w
-- )
-- PORT MAP (
-- mosi => reg_mosi,
-- miso => reg_miso,
-- mosi_arr => reg_mosi_arr,
-- miso_arr => reg_miso_arr
-- );
-------------------------------------------------------------------------------
-- Dual clock RAM: DP write side, MM read side
-------------------------------------------------------------------------------
......
......@@ -50,10 +50,10 @@
-- | |
-- bin_writer_mosi bin_arbiter_wr_mosi
-- Usage:
-- . The ram_mosi and ram_clear inputs apply to the RAM page that is inactive (not
-- . The ram_mosi input applies to the RAM page that is inactive (not
-- being written to from data path) *at that time*. The user should take care to
-- time these controls such that the active RAM page does not swap before these
-- operations (ram_mosi readout, ram_clear) have finished.
-- operation (ram_mosi readout) has finished.
-- Remarks:
-- . common_ram_r_w
-- . Why common_ram_r_w was selected: it uses a single clock
......@@ -85,7 +85,6 @@ ENTITY st_histogram IS
snk_in : IN t_dp_sosi; -- Active RAM page swaps on snk_in.sync
ram_clear : IN STD_LOGIC; -- Control input: Pulse high to clear the inactive RAM page
ram_clearing : OUT STD_LOGIC; -- Status output: high while RAM is being cleared
ram_mosi : IN t_mem_mosi; -- MM access to the inactive RAM page
......@@ -164,6 +163,13 @@ ARCHITECTURE rtl OF st_histogram IS
-------------------------------------------------------------------------------
-- ram_clear
-------------------------------------------------------------------------------
CONSTANT c_data_cnt_w : NATURAL := ceil_log2(g_nof_data_per_sync);
SIGNAL data_cnt : STD_LOGIC_VECTOR(c_data_cnt_w-1 DOWNTO 0);
SIGNAL nxt_data_cnt : STD_LOGIC_VECTOR(c_data_cnt_w-1 DOWNTO 0);
SIGNAL ram_clear : STD_LOGIC;
SIGNAL ram_clear_address : STD_LOGIC_VECTOR(c_ram_adr_w-1 DOWNTO 0);
SIGNAL nxt_ram_clear_address : STD_LOGIC_VECTOR(c_ram_adr_w-1 DOWNTO 0);
......@@ -365,6 +371,12 @@ BEGIN
-- for user being late (the ram pointer is checked only the very moment
-- ram_clear is set)
-------------------------------------------------------------------------------
-- Count input data for automatic RAM clear before next sync interval
nxt_data_cnt <= (OTHERS=>'0') WHEN TO_UINT(data_cnt)=g_nof_data_per_sync-1 ELSE INCR_UVEC(data_cnt, 1) WHEN snk_in.valid='1' ELSE data_cnt;
-- Clear all g_nof_bins RAM addresses just before the next sync
ram_clear <= '1' WHEN TO_UINT(data_cnt)=g_nof_data_per_sync-g_nof_bins-1 ELSE '0';
-- Signal to indicate when RAM is being cleared
nxt_ram_clearing <= '1' WHEN ram_clear='1' ELSE '0' WHEN TO_UINT(ram_clear_address)=g_nof_bins-1 ELSE i_ram_clearing;
......@@ -382,9 +394,11 @@ BEGIN
IF dp_rst = '1' THEN
ram_clear_address <= (OTHERS=>'0');
i_ram_clearing <= '0';
data_cnt <= (OTHERS=>'0');
ELSIF RISING_EDGE(dp_clk) THEN
ram_clear_address <= nxt_ram_clear_address;
i_ram_clearing <= nxt_ram_clearing;
data_cnt <= nxt_data_cnt;
END IF;
END PROCESS;
......
......@@ -45,10 +45,11 @@ USE dp_lib.tb_dp_pkg.ALL;
ENTITY tb_mms_st_histogram IS
GENERIC(
g_nof_instances : NATURAL := 1;
g_data_w : NATURAL := 8;
g_nof_bins : NATURAL := 256;
g_nof_data_per_sync : NATURAL := 1024
g_nof_sync : NATURAL := 4;
g_nof_instances : NATURAL := 12;
g_data_w : NATURAL := 14;
g_nof_bins : NATURAL := 512;
g_nof_data_per_sync : NATURAL := 40000
);
END tb_mms_st_histogram;
......@@ -69,10 +70,18 @@ ARCHITECTURE tb OF tb_mms_st_histogram IS
SIGNAL tb_end : STD_LOGIC := '0';
----------------------------------------------------------------------------
-- stimuli
----------------------------------------------------------------------------
SIGNAL stimuli_en : STD_LOGIC := '1';
SIGNAL stimuli_src_out : t_dp_sosi;
SIGNAL stimuli_src_in : t_dp_siso;
----------------------------------------------------------------------------
-- st_histogram
----------------------------------------------------------------------------
SIGNAL st_histogram_snk_in : t_dp_sosi;
SIGNAL st_histogram_snk_in_arr : t_dp_sosi_arr(g_nof_instances-1 DOWNTO 0);
SIGNAL st_histogram_reg_mosi : t_mem_mosi;
SIGNAL st_histogram_reg_miso : t_mem_miso;
......@@ -81,6 +90,20 @@ ARCHITECTURE tb OF tb_mms_st_histogram IS
SIGNAL st_histogram_ram_miso : t_mem_miso;
----------------------------------------------------------------------------
-- Readout & verification
----------------------------------------------------------------------------
CONSTANT c_ram_dat_w : NATURAL := ceil_log2(g_nof_data_per_sync)+1;
CONSTANT c_expected_ram_content : NATURAL := g_nof_data_per_sync/g_nof_bins;
SIGNAL ram_filling : STD_LOGIC;
SIGNAL ram_rd_word : STD_LOGIC_VECTOR(c_ram_dat_w-1 DOWNTO 0);
SIGNAL ram_rd_word_int : NATURAL;
SIGNAL ram_rd_word_valid : STD_LOGIC;
SIGNAL nxt_ram_rd_word_valid : STD_LOGIC;
BEGIN
----------------------------------------------------------------------------
......@@ -93,9 +116,37 @@ BEGIN
mm_rst <= '1', '0' AFTER c_mm_clk_period*10;
----------------------------------------------------------------------------
-- DP Stimuli: generate st_histogram input data
----------------------------------------------------------------------------
stimuli_src_in <= c_dp_siso_rdy;
-- Generate g_nof_sync packets of g_nof_data_per_sync words
p_generate_packets : PROCESS
VARIABLE v_sosi : t_dp_sosi := c_dp_sosi_rst;
BEGIN
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;
proc_common_wait_some_cycles(dp_clk, 50);
tb_end <= '1';
WAIT;
END PROCESS;
----------------------------------------------------------------------------
-- mms_st_histogram
----------------------------------------------------------------------------
gen_snk_in_arr: FOR i IN 0 TO g_nof_instances-1 GENERATE
st_histogram_snk_in_arr(i) <= stimuli_src_out;
END GENERATE;
u_mms_st_histogram : ENTITY work.mms_st_histogram
GENERIC MAP(
g_nof_instances => g_nof_instances,
......@@ -110,7 +161,7 @@ BEGIN
mm_clk => mm_clk,
mm_rst => mm_rst,
snk_in_arr(0)=> st_histogram_snk_in,
snk_in_arr => st_histogram_snk_in_arr,
reg_mosi => st_histogram_reg_mosi,
reg_miso => st_histogram_reg_miso,
......@@ -119,27 +170,81 @@ BEGIN
ram_miso => st_histogram_ram_miso
);
----------------------------------------------------------------------------
-- Readout of RAM
-- MM Readout of st_histogram instances
----------------------------------------------------------------------------
-- Perform MM read
p_verify_mm_read : PROCESS
p_ram_clear : PROCESS
BEGIN
st_histogram_ram_mosi <= c_mem_mosi_rst;
st_histogram_reg_mosi <= c_mem_mosi_rst;
proc_common_wait_until_low(mm_clk, mm_rst);
ram_filling <= '0';
ram_rd_word <= (OTHERS=>'0');
-- The first sync indicates start of incoming data - let it pass
proc_common_wait_until_high(dp_clk, stimuli_src_out.sync);
proc_common_wait_some_cycles(mm_clk, 10);
-- Start RAM filling
FOR i IN 0 TO g_nof_sync-2 LOOP
-- Wiat for a full sync period of data
proc_common_wait_until_high(dp_clk, stimuli_src_out.sync);
-- The sync has passed, we can start reading the resulting histogram
FOR j IN 0 TO g_nof_instances-1 LOOP
-- Select st_histogram instance to read out
proc_mem_mm_bus_wr(1, j, mm_clk, st_histogram_reg_mosi);
proc_common_wait_some_cycles(mm_clk, 2);
-- Enable RAM filling
proc_mem_mm_bus_wr(2, 1, mm_clk, st_histogram_reg_mosi);
proc_common_wait_some_cycles(mm_clk, 10);
-- Wait until RAM filling is done
proc_mem_mm_bus_rd(2, mm_clk, st_histogram_reg_mosi);
ram_filling <= st_histogram_reg_miso.rddata(0);
proc_common_wait_some_cycles(mm_clk, 2);
WHILE ram_filling='1' LOOP
-- Read filling status
proc_mem_mm_bus_rd(2, mm_clk, st_histogram_reg_mosi);
ram_filling <= st_histogram_reg_miso.rddata(0);
proc_common_wait_some_cycles(mm_clk, 1);
END LOOP;
-- Read out the RAM contents
FOR k IN 0 TO g_nof_bins-1 LOOP
proc_mem_mm_bus_rd(k, mm_clk, st_histogram_ram_mosi);
ram_rd_word <= st_histogram_ram_miso.rddata(c_ram_dat_w-1 DOWNTO 0);
ram_rd_word_int <= TO_UINT(ram_rd_word);
END LOOP;
END LOOP;
END LOOP;
END PROCESS;
proc_common_wait_some_cycles(mm_clk, 1000);
tb_end <= '1';
WAIT;
-- Register st_histogram_ram_miso.rdval so we read only valid data
p_nxt_ram_rd_word_valid : PROCESS(mm_rst, mm_clk)
BEGIN
IF mm_rst = '1' THEN
ram_rd_word_valid <= '0';
ELSIF RISING_EDGE(mm_clk) THEN
ram_rd_word_valid <= nxt_ram_rd_word_valid;
END IF;
END PROCESS;
nxt_ram_rd_word_valid <= st_histogram_ram_miso.rdval;
----------------------------------------------------------------------------
-- Perform verification of ram_rd_word when ram_rd_word_valid
----------------------------------------------------------------------------
p_verify_assert : PROCESS
BEGIN
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;
END LOOP;
WAIT FOR 5 ns;
END PROCESS;
END tb;
......@@ -69,7 +69,6 @@ ARCHITECTURE tb OF tb_st_histogram IS
---------------------------------------------------------------------------
-- Constants derived from generics
---------------------------------------------------------------------------
CONSTANT c_nof_data_before_ram_clear : NATURAL := largest(1, g_nof_data_per_sync-g_nof_bins); -- Clear RAM just before next Sync interval
CONSTANT c_expected_ram_content : NATURAL := g_nof_data_per_sync/g_nof_bins;
CONSTANT c_ram_dat_w : NATURAL := ceil_log2(g_nof_data_per_sync)+1;
......@@ -98,7 +97,6 @@ ARCHITECTURE tb OF tb_st_histogram IS
SIGNAL st_histogram_snk_in : t_dp_sosi;
SIGNAL st_histogram_ram_mosi : t_mem_mosi;
SIGNAL st_histogram_ram_miso : t_mem_miso;
SIGNAL st_histogram_ram_clear : STD_LOGIC;
----------------------------------------------------------------------------
-- Automatic verification of RAM readout
......@@ -141,22 +139,6 @@ BEGIN
WAIT;
END PROCESS;
-- Clear the RAM
p_ram_clear : PROCESS
BEGIN
FOR I IN 0 TO g_nof_sync-1 LOOP
-- Sync up with p_generate_packets above by waiting for stimuli_src_out.sync
proc_common_wait_until_high(dp_clk, stimuli_src_out.sync);
-- Wait until c_nof_data_before_ram_clear cycles have passed
st_histogram_ram_clear <= '0';
proc_common_wait_some_cycles(dp_clk, c_nof_data_before_ram_clear-1);
-- Toggle RAM clear for 1 cycle
st_histogram_ram_clear <= '1';
proc_common_wait_some_cycles(dp_clk, 1);
st_histogram_ram_clear <= '0';
END LOOP;
END PROCESS;
----------------------------------------------------------------------------
-- st_histogram
......@@ -175,8 +157,6 @@ BEGIN
snk_in => st_histogram_snk_in,
ram_clear => st_histogram_ram_clear,
ram_mosi => st_histogram_ram_mosi,
ram_miso => st_histogram_ram_miso
);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment