diff --git a/libraries/dsp/st/src/vhdl/st_histogram.vhd b/libraries/dsp/st/src/vhdl/st_histogram.vhd index effd491ef56cf3b37346761b95a8080886c282c4..b7be065ed61957286605e4288049d0add19a7407 100644 --- a/libraries/dsp/st/src/vhdl/st_histogram.vhd +++ b/libraries/dsp/st/src/vhdl/st_histogram.vhd @@ -293,7 +293,7 @@ BEGIN -- Let bin_arbiter read RAM 0 while user reads RAM 1 and vice versa -- . We always want the MISO bus to switch 1 cycle later than the MOSI (such that the MM operation can finish); hence using prv_bin_arbiter_rd_ram_pointer. bin_arbiter_rd_miso <= common_ram_r_w_rd_miso_arr(0) WHEN prv_bin_arbiter_rd_ram_pointer='0' ELSE common_ram_r_w_rd_miso_arr(1); --- histogram_rd_miso <= common_ram_r_w_rd_miso_arr(1) WHEN bin_arbiter_rd_ram_pointer='0' ELSE common_ram_r_w_rd_miso_arr(0); + histogram_rd_miso <= common_ram_r_w_rd_miso_arr(1) WHEN prv_bin_arbiter_rd_ram_pointer='0' ELSE common_ram_r_w_rd_miso_arr(0); gen_common_ram_r_w : FOR i IN 0 TO c_nof_common_ram_r_w-1 GENERATE u_common_ram_r_w : ENTITY common_lib.common_ram_r_w @@ -350,12 +350,9 @@ BEGIN END PROCESS; ------------------------------------------------------------------------------- - -- Cross clock domains - -- . Input: histogram_rd_miso (from RAM block) - -- mm_histogram_rd_mosi (from user) - -- . Output: mm_histogram_rd_miso (towards user) - -- histogram_rd_mosi (towards RAM block) + -- Expose the MM buses to the user ------------------------------------------------------------------------------- - -- FIXME We should do this in the MMS wrapper. + ram_miso <= histogram_rd_miso; + histogram_rd_mosi <= ram_mosi; END rtl; diff --git a/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd b/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd index e0ada8987a816a22f6f61ddf1a8b16334675291b..72681e58e32586fcda371f13d6b5bd5233d4247e 100644 --- a/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd +++ b/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd @@ -24,7 +24,12 @@ -- . Daniel van der Schuur -- . Jan Oudman -- Purpose: --- . Generate st_histogram input data and clear its RAM +-- . Generate st_histogram input data, verify RAM contents. TB is self checking. +-- ModelSim usage: +-- . (open project, compile) +-- . (load simulation config) +-- . as 8 +-- . run -a -- Description: -- . Verification be eye (wave window) - observe that: -- . There are 4 sync periods in which 3 packets of 1024 words are generated; @@ -35,7 +40,9 @@ -- . 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. ------------------------------------------------------------------------------- LIBRARY IEEE, common_lib, mm_lib, dp_lib; @@ -43,6 +50,7 @@ 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_mem_pkg.ALL; USE common_lib.tb_common_pkg.ALL; USE dp_lib.dp_stream_pkg.ALL; USE dp_lib.tb_dp_pkg.ALL; @@ -73,6 +81,8 @@ ARCHITECTURE tb OF tb_st_histogram IS CONSTANT c_nof_data_per_packet : NATURAL := 4*g_nof_bins; CONSTANT c_nof_data_per_sync : NATURAL := c_nof_packets_per_sync*c_nof_data_per_packet; CONSTANT c_nof_data_before_ram_clear : NATURAL := c_nof_data_per_sync-g_nof_bins; -- Clear RAM just before next Sync interval + + CONSTANT c_expected_ram_content : NATURAL := c_nof_packets_per_sync * (c_nof_data_per_packet/g_nof_bins); -- 3*(1024/256)=12 --------------------------------------------------------------------------- -- Clocks and resets @@ -96,10 +106,17 @@ ARCHITECTURE tb OF tb_st_histogram IS -- st_histogram ---------------------------------------------------------------------------- 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 + ---------------------------------------------------------------------------- + SIGNAL ram_rd_word : STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0); + SIGNAL ram_rd_word_valid : STD_LOGIC; + SIGNAL nxt_ram_rd_word_valid : STD_LOGIC; + BEGIN ---------------------------------------------------------------------------- @@ -173,8 +190,61 @@ BEGIN ram_clear => st_histogram_ram_clear, - ram_mosi => c_mem_mosi_rst, + ram_mosi => st_histogram_ram_mosi, ram_miso => st_histogram_ram_miso ); + + ---------------------------------------------------------------------------- + -- Readout and verification of RAM contents + -- . 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 | + -- +-------------+-------------+----------+--------------+ + -- + ---------------------------------------------------------------------------- + -- Perform MM read and put result in ram_rd_word + p_verify_mm_read : PROCESS + BEGIN + FOR i IN 0 TO c_nof_sync_periods-1 LOOP + proc_common_wait_until_high(dp_clk, stimuli_src_out.sync); + + 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(g_data_w-1 DOWNTO 0); + END LOOP; + END LOOP; + END PROCESS; + + -- Register st_histogram_ram_miso.rdval so we read only valid ram_rd_word + p_nxt_ram_rd_word_valid : PROCESS(dp_rst, dp_clk) + BEGIN + IF dp_rst = '1' THEN + ram_rd_word_valid <= '0'; + ELSIF RISING_EDGE(dp_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 c_nof_sync_periods-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 TO_UINT(ram_rd_word)=0 REPORT "RAM contains wrong bin count (expected 0)" SEVERITY ERROR; + ELSE -- Sync period 1 onwards + ASSERT TO_UINT(ram_rd_word)=c_expected_ram_content REPORT "RAM contains wrong bin count (expected 12)" SEVERITY ERROR; + END IF; + END LOOP; + END PROCESS; END tb;