diff --git a/libraries/dsp/st/tb/vhdl/tb_mmp_st_histogram.vhd b/libraries/dsp/st/tb/vhdl/tb_mmp_st_histogram.vhd index 98fbed5994737e5efeaa70f15e89bd0f9c467770..57f34d26041b1cc6357e74c9acb708843ef50544 100644 --- a/libraries/dsp/st/tb/vhdl/tb_mmp_st_histogram.vhd +++ b/libraries/dsp/st/tb/vhdl/tb_mmp_st_histogram.vhd @@ -52,13 +52,22 @@ ENTITY tb_mmp_st_histogram IS g_nof_instances : NATURAL := 12; g_data_w : NATURAL := 14; g_nof_bins : NATURAL := 512; - g_nof_data_per_sync : NATURAL := 16384 -- g_nof_data_per_sync/g_nof_bins should be integer so - ); -- counter data yields the same histogram in each bin + g_nof_data_per_sync : NATURAL := 16384; -- g_nof_data_per_sync/g_nof_bins should be integer so counter data yields the same histogram in each bin + g_stimuli_mode : STRING := "counter" -- "counter", "dc", "sine" or "random" + ); END tb_mmp_st_histogram; ARCHITECTURE tb OF tb_mmp_st_histogram IS - + + --------------------------------------------------------------------------- + -- Constants derived from generics + --------------------------------------------------------------------------- + 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); + CONSTANT c_ram_adr_w : NATURAL := ceil_log2(g_nof_bins); + --------------------------------------------------------------------------- -- Clocks and resets --------------------------------------------------------------------------- @@ -82,22 +91,23 @@ ARCHITECTURE tb OF tb_mmp_st_histogram IS ---------------------------------------------------------------------------- -- st_histogram ---------------------------------------------------------------------------- - SIGNAL st_histogram_snk_in_arr : t_dp_sosi_arr(g_nof_instances-1 DOWNTO 0); - SIGNAL st_histogram_ram_copi : t_mem_copi; - SIGNAL st_histogram_ram_cipo : t_mem_cipo; + SIGNAL st_histogram_snk_in_arr : t_dp_sosi_arr(g_nof_instances-1 DOWNTO 0); + SIGNAL st_histogram_ram_copi : t_mem_copi; + SIGNAL prv_st_histogram_ram_copi : t_mem_copi; + SIGNAL st_histogram_ram_cipo : t_mem_cipo; - ---------------------------------------------------------------------------- - -- Readout & verification + -- Automatic verification of RAM readout ---------------------------------------------------------------------------- - 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; + -- Use these 4 signals to verify histogram by eye in the wave window + SIGNAL histogram_data : NATURAL; -- QuestaSim: Format->Analog + SIGNAL histogram_bin_unsigned : NATURAL; + SIGNAL histogram_bin_signed : INTEGER; -- QuestaSim: Radix->Decimal + SIGNAL histogram_valid : STD_LOGIC; + + SIGNAL sum_of_bins : NATURAL; + SIGNAL verification_done : 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; - SIGNAL verification_done : STD_LOGIC; BEGIN @@ -168,57 +178,88 @@ BEGIN ---------------------------------------------------------------------------- - -- MM Readout of st_histogram instances - ---------------------------------------------------------------------------- - p_ram_clear : PROCESS + -- Readout and verification of RAM contents + -- . The table below shows what RAM we are reading here ('RAM read') via the + -- ram_copi/cipo interface, and what the expected RAM contents are. + -- + -- 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_copi <= c_mem_copi_rst; - 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); - FOR i IN 0 TO g_nof_sync-2 LOOP - -- Wait for a full sync period of data + st_histogram_ram_copi.wr <= '0'; + FOR i IN 0 TO g_nof_sync-1 LOOP proc_common_wait_until_high(dp_clk, stimuli_src_out.sync); - -- 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_copi); - ram_rd_word <= st_histogram_ram_cipo.rddata(c_ram_dat_w-1 DOWNTO 0); - ram_rd_word_int <= TO_UINT(ram_rd_word); + 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_copi); END LOOP; - END LOOP; - END PROCESS; - - -- Register st_histogram_ram_cipo.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 LOOP; + WAIT; END PROCESS; - nxt_ram_rd_word_valid <= st_histogram_ram_cipo.rdval; + -- Help signals that contain the histogram bins+data + histogram_bin_unsigned <= TO_UINT( prv_st_histogram_ram_copi.address(c_ram_adr_w-1 DOWNTO 0)); + histogram_bin_signed <= TO_SINT(offset_binary(prv_st_histogram_ram_copi.address(c_ram_adr_w-1 DOWNTO 0))); + histogram_data <= TO_UINT(st_histogram_ram_cipo.rddata(c_ram_dat_w-1 DOWNTO 0)) WHEN st_histogram_ram_cipo.rdval='1'ELSE 0; + histogram_valid <= st_histogram_ram_cipo.rdval; - ---------------------------------------------------------------------------- -- 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 + sum_of_bins <= 0; 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; + FOR j IN 0 TO g_nof_bins-1 LOOP + proc_common_wait_until_high(dp_clk, histogram_valid); + IF i=0 THEN -- Sync period 0: we expect RAM to contain zeros + ASSERT histogram_data=0 REPORT "RAM contains wrong bin count (expected 0, actual " & INTEGER'IMAGE(histogram_data) & ")" SEVERITY ERROR; + ELSE -- Sync period 1 onwards + IF g_stimuli_mode="counter" THEN + -- Counter data: bin values remain the same every sync + ASSERT histogram_data=c_expected_ram_content_counter REPORT "RAM contains wrong bin count (expected " & INTEGER'IMAGE(c_expected_ram_content_counter) & ", actual " & INTEGER'IMAGE(histogram_data) & ")" SEVERITY ERROR; + ELSIF g_stimuli_mode="dc" THEN + -- DC data: DC level increments every sync + IF j=(i/c_nof_levels_per_bin) 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 histogram_data=g_nof_data_per_sync REPORT "RAM contains wrong bin count (expected " & INTEGER'IMAGE(g_nof_data_per_sync) & ", actual " & INTEGER'IMAGE(histogram_data) & ")" SEVERITY ERROR; + ELSE + -- this address should contain zero + ASSERT histogram_data=0 REPORT "RAM contains wrong bin count (expected 0, actual " & INTEGER'IMAGE(histogram_data) & ")" SEVERITY ERROR; + END IF; + END IF; + END IF; + sum_of_bins<=sum_of_bins+histogram_data; -- Keep the sum of all bins + WAIT FOR 5 ns; + END LOOP; + + -- Check the sum of all bins + IF i>0 THEN -- Skip sync 0 (histogram still all zeros) + ASSERT sum_of_bins=g_nof_data_per_sync REPORT "Sum of bins not equal to g_nof_data_per_sync (expected " & INTEGER'IMAGE(g_nof_data_per_sync) & ", actual " & INTEGER'IMAGE(sum_of_bins) & ")" SEVERITY ERROR; END IF; + 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 @@ -230,5 +271,16 @@ BEGIN WAIT; END PROCESS; + -- Register MOSI to store the read address + p_clk: PROCESS(dp_rst, dp_clk) IS + BEGIN + IF dp_rst = '1' THEN + prv_st_histogram_ram_copi <= c_mem_copi_rst; + ELSIF RISING_EDGE(dp_clk) THEN + prv_st_histogram_ram_copi <= st_histogram_ram_copi; + END IF; + END PROCESS; + + END tb;