From 972f20aeabbaa813ffebf73d37aa22941faf8f26 Mon Sep 17 00:00:00 2001
From: Jan Oudman <oudman@astron.nl>
Date: Mon, 27 Jul 2020 16:09:49 +0200
Subject: [PATCH] added a selfchecking part to tb_st_histogram; small
 corrections to st_histogram_8_april

---
 .../dsp/st/src/vhdl/st_histogram_8_april.vhd  |  19 +-
 libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd  | 177 +++++++++++++++++-
 2 files changed, 186 insertions(+), 10 deletions(-)

diff --git a/libraries/dsp/st/src/vhdl/st_histogram_8_april.vhd b/libraries/dsp/st/src/vhdl/st_histogram_8_april.vhd
index 32188b1b9d..91589c0f53 100644
--- a/libraries/dsp/st/src/vhdl/st_histogram_8_april.vhd
+++ b/libraries/dsp/st/src/vhdl/st_histogram_8_april.vhd
@@ -204,8 +204,8 @@ BEGIN
     out_dat => rd_cnt_allowed_pp
   );
   
-  -- Detect a (valid) repeating address seperated by one other address past the initialisation and outside the first two cycles of a (new) sync
-  toggle_detect  <= snk_in.valid WHEN (bin_reader_mosi_pp.address = bin_reader_mosi.address AND bin_reader_mosi_pp.address /= prev_bin_reader_mosi.address AND toggle_detect_false = '0' AND (snk_in.sync='0' OR dp_pipeline_src_out_p.sync='0') ) 
+  -- Detect a (valid) repeating address seperated by one other address past the initialisation and outside the first two cycles of a (new) sync                                        --also @sync, one wil be true; use  NOT(1 or 1) instead of (0 or 0)
+  toggle_detect  <= snk_in.valid WHEN (bin_reader_mosi_pp.address = bin_reader_mosi.address AND bin_reader_mosi_pp.address /= prev_bin_reader_mosi.address AND toggle_detect_false = '0' AND NOT(snk_in.sync='1' OR dp_pipeline_src_out_p.sync='1') ) 
                                  ELSE '0';
 
   
@@ -246,7 +246,7 @@ BEGIN
   -- . out : bin_writer_mosi  (latency: 3)
   -----------------------------------------------------------------------------
   p_nxt_bin_writer_mosi : PROCESS(common_ram_r_w_0_miso, common_ram_r_w_0_miso.rdval, common_ram_r_w_0_miso.rddata, 
-                                  bin_reader_mosi_pp.address, toggle_detect, rd_cnt_allowed_pp, init_phase, prev_wrdata, prev_prev_wrdata, sync_detect_pp, same_r_w_address_pp, dp_pipeline_src_out_pp.valid) IS -- dp_pipeline_src_out_pp necesary??
+                                  bin_reader_mosi_pp.address, toggle_detect_pp, rd_cnt_allowed_pp, init_phase, prev_wrdata, prev_prev_wrdata, prev_prev_prev_wrdata, sync_detect_pp, same_r_w_address_pp, dp_pipeline_src_out_pp.valid) IS -- dp_pipeline_src_out_pp necesary??
   BEGIN
     nxt_bin_writer_mosi <= c_mem_mosi_rst;
     dbg_state_string <= "unv";
@@ -257,7 +257,7 @@ BEGIN
       nxt_prev_wrdata             <= TO_UINT(common_ram_r_w_0_miso.rddata) + 1;
       dbg_state_string <= "val";
 
-    ELSIF toggle_detect_pp = '1' THEN                                                       -- Mist is sensitivity list !
+    ELSIF toggle_detect_pp = '1' THEN
       nxt_bin_writer_mosi.wr      <= '1';
       nxt_bin_writer_mosi.wrdata  <= TO_UVEC( (prev_prev_wrdata+1), c_mem_data_w);
       nxt_bin_writer_mosi.address <= bin_reader_mosi_pp.address;
@@ -280,7 +280,7 @@ BEGIN
       
     ELSIF same_r_w_address_pp = '1' THEN
       nxt_bin_writer_mosi.wr      <= '1';
-      nxt_bin_writer_mosi.wrdata  <= TO_UVEC( (prev_prev_prev_wrdata+1), c_mem_data_w);       -- Misses in sensitivity list !
+      nxt_bin_writer_mosi.wrdata  <= TO_UVEC( (prev_prev_prev_wrdata+1), c_mem_data_w);
       nxt_bin_writer_mosi.address <= bin_reader_mosi_pp.address;
       nxt_prev_wrdata             <= prev_prev_prev_wrdata + 1;
       dbg_state_string  <= "srw";
@@ -312,9 +312,9 @@ BEGIN
   -- .     : bin_arbiter_wr_mosi (latency: 4)
   -----------------------------------------------------------------------------
   nxt_bin_arbiter_wr_mosi <= bin_writer_mosi;
-  -- Read RAM when subsequent addresses are not the same, when there is no toggle detected and only when the same address is not going to be written to
-  nxt_bin_arbiter_rd_mosi.rd <= bin_reader_mosi.rd WHEN (bin_reader_mosi.address /= prev_bin_reader_mosi.address AND bin_reader_mosi.address /= bin_reader_mosi_pp.address AND NOT(bin_reader_mosi.address = bin_reader_mosi_ppp.address) ) 
-                                                         -- AND sync_detect='0')                                                                                  -- activate sync !
+  -- Read RAM when subsequent addresses are not the same, when there is no toggle detected and only when the same address is not going to be written to. When a sync is detected don't read in the old RAM block.
+  nxt_bin_arbiter_rd_mosi.rd <= bin_reader_mosi.rd WHEN (bin_reader_mosi.address /= prev_bin_reader_mosi.address AND bin_reader_mosi.address /= bin_reader_mosi_pp.address 
+                                                         AND NOT(bin_reader_mosi.address = bin_reader_mosi_ppp.address) AND sync_detect='0')
                                                    OR (init_phase = '1') ELSE '0';
   nxt_bin_arbiter_rd_mosi.address <= bin_reader_mosi.address;
 
@@ -328,6 +328,9 @@ BEGIN
       bin_arbiter_rd_mosi <= nxt_bin_arbiter_rd_mosi;
     END IF;
   END PROCESS;
+  
+  -- Temporary debug data
+  ram_miso.rddata <= bin_arbiter_wr_mosi.wrdata;
 
 
   -----------------------------------------------------------------------------
diff --git a/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd b/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd
index ac0bc99663..8fef744bfa 100644
--- a/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd
+++ b/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd
@@ -127,6 +127,37 @@ ARCHITECTURE tb OF tb_st_histogram IS
   SIGNAL st_histogram_snk_in : t_dp_sosi;
   
   
+  ----------------------------------------------------------------------------
+  -- Streaming Output
+  ----------------------------------------------------------------------------
+  
+  SIGNAL st_histogram_ram_miso : t_mem_miso;
+  
+  
+  ----------------------------------------------------------------------------
+  -- Self check array
+  ----------------------------------------------------------------------------
+  TYPE t_data_check_arr IS ARRAY (0 TO g_nof_bins) OF INTEGER;  -- 0 TO g_nof_bins -- NATURAL RANGE <>
+  SIGNAL data_check_arr         : t_data_check_arr := (OTHERS=> 0);-- (OTHERS=> 0)); -- := (1,1,1,1,0,1,1,1,1, 1, 1, 1, 1, 0, 1, 1, 1);
+                                            --  1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17
+                                            
+  SIGNAL check_adr               : NATURAL := 0; --(g_data_w DOWNTO c_adr_low) : STD_LOGIC_VECTOR;
+  SIGNAL prev_check_adr          : NATURAL;
+  SIGNAL nxt_check_arr_cnt       : NATURAL;
+  
+--  SIGNAL data_check_index_cnt    : NATURAL   := 0;
+  
+  SIGNAL dp_pipeline_src_out_pp  : t_dp_sosi;
+  SIGNAL dp_pipeline_src_out_ppp : t_dp_sosi;
+  SIGNAL dp_pipeline_src_out_pppp: t_dp_sosi;
+--  SIGNAL dbg_check_adr           :STD_LOGIC_VECTOR(g_data_w-1 DOWNTO c_adr_low); --  : NATURAL;
+  
+  SIGNAL dbg_error_location      : STD_LOGIC;
+  SIGNAL error_cnt               : NATURAL;  -- or variable
+  SIGNAL dbg_int_data_miso       : NATURAL;
+  SIGNAL dbg_int_data_arr        : NATURAL;
+  
+  
 BEGIN 
   
   ----------------------------------------------------------------------------
@@ -320,7 +351,7 @@ BEGIN
           dbg_valid <= I;
           WAIT UNTIL rising_edge(dp_clk);
         END LOOP;
-        proc_common_wait_some_cycles(dp_clk, (g_sync_length - (c_val_arr'LENGTH -2) ));
+        proc_common_wait_some_cycles(dp_clk, (g_sync_length - (c_val_arr'LENGTH -2) )); --the -2 has to be ditched as the sync happens 2 cycles to soon
       END LOOP;
       -- ending
       FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
@@ -351,7 +382,149 @@ BEGIN
   
     -- Memory Mapped
     ram_mosi     => c_mem_mosi_rst,-- sla_in_
-    ram_miso     => OPEN -- sla_out_
+    ram_miso     => st_histogram_ram_miso --OPEN -- sla_out_
   );
   
+  
+  
+  ----------------------------------------------------------------------------
+  -- Selfcheck:
+  --  The selfcheck is done by counting the adresses created from 3 cycles 
+  --  delayed snk_in data into an address separated array (when in the array, 
+  --  the data is 4 cycles delayed). This data is used as reference for 
+  --  comparing it with the data written into a RAM block in st_histogram. 
+  --  Because the data in st_histogram is written 4 cycles later than it got 
+  --  in, both data are in sync and can be compared directly. 
+  --  When the data is valid but is not the same as the reference data the 
+  --  debug signal dbg_error_location becomes '1' so the location can be 
+  --  easily spotted in the wave window and a report is made.
+  ----------------------------------------------------------------------------
+  
+  u_dp_pipeline_st_histogram_snk_in_2_cycle : ENTITY dp_lib.dp_pipeline            -- not used
+  GENERIC MAP (
+    g_pipeline   => 2  -- 0 for wires, > 0 for registers, 
+  )
+  PORT MAP (
+    rst          => dp_rst,
+    clk          => dp_clk,
+    snk_in       => st_histogram_snk_in,
+    src_out      => dp_pipeline_src_out_pp
+  );
+  
+  u_dp_pipeline_st_histogram_snk_in_3_cycle : ENTITY dp_lib.dp_pipeline
+  GENERIC MAP (
+    g_pipeline   => 3  -- 0 for wires, > 0 for registers, 
+  )
+  PORT MAP (
+    rst          => dp_rst,
+    clk          => dp_clk,
+    snk_in       => st_histogram_snk_in,
+    src_out      => dp_pipeline_src_out_ppp
+  );
+  
+  u_dp_pipeline_st_histogram_snk_in_4_cycle : ENTITY dp_lib.dp_pipeline
+  GENERIC MAP (
+    g_pipeline   => 4  -- 0 for wires, > 0 for registers, 
+  )
+  PORT MAP (
+    rst          => dp_rst,
+    clk          => dp_clk,
+    snk_in       => st_histogram_snk_in,
+    src_out      => dp_pipeline_src_out_pppp
+  );
+  
+  ---------------------------------------
+  -- create address from the source data 
+  check_adr <= TO_UINT( dp_pipeline_src_out_ppp.data(g_data_w-1 DOWNTO c_adr_low) );
+--  dbg_check_adr <= dp_pipeline_src_out_ppp.data(g_data_w -1 DOWNTO c_adr_low);
+  
+  p_prev_check_adr : PROCESS (dp_rst, dp_clk, check_adr)
+  BEGIN
+    IF dp_rst='1' THEN
+      prev_check_adr <= 0;
+    ELSIF rising_edge(dp_clk) THEN
+      prev_check_adr <= check_adr;
+    END IF;
+  END PROCESS;
+  
+  -----------------------------
+  -- when valid increase array based on address 
+  nxt_check_arr_cnt <= data_check_arr(check_adr) + 1 WHEN dp_pipeline_src_out_ppp.valid = '1' ELSE data_check_arr(check_adr);
+  
+  
+  --------------------
+  -- filling the array
+  p_cumulate_testdata : PROCESS (dp_rst, dp_clk, nxt_check_arr_cnt, check_adr, dp_pipeline_src_out_ppp.sync) --misses prev_check_adr
+  BEGIN 
+    --PROCESS
+    --c_data_check_arr(check_adr) <= nxt_check_arr_cnt;
+    IF dp_rst='1' THEN
+    data_check_arr(0 TO g_nof_bins) <= (OTHERS => 0);
+    ELSIF rising_edge(dp_clk) THEN
+      --data_check_arr(prev_check_adr) <= nxt_check_arr_cnt;
+      data_check_arr(check_adr) <= nxt_check_arr_cnt; --old timing
+      IF dp_pipeline_src_out_ppp.sync='1' THEN
+        data_check_arr(0 TO g_nof_bins) <= (check_adr => 1, OTHERS => 0 );  -- null except check_adr
+        --
+      END IF;
+    END IF; 
+  END PROCESS;
+  
+  ---------------------
+  -- extra dbg signals 
+  dbg_int_data_miso <= TO_UINT(st_histogram_ram_miso.rddata);
+  dbg_int_data_arr <= data_check_arr(prev_check_adr);
+  
+  ---------------------
+  -- selftest
+--  p_selfcheck : PROCESS (dp_rst, dp_clk, data_check_arr, prev_check_adr, st_histogram_ram_miso.rddata)
+--  BEGIN 
+--    --PROCESS
+--    -- compare cumulated testdata with ram_mosi
+--    
+--    --dbg_int_data_miso <= TO_UINT(st_histogram_ram_miso.rddata);
+--    --dbg_int_data_arr <= data_check_arr(check_adr);
+--    IF rising_edge(dp_clk) THEN
+--      --dbg_error_location <= '0';
+--      --dbg_int_data_miso <= TO_UINT(st_histogram_ram_miso.rddata);
+--      --dbg_int_data_arr <= data_check_arr(check_adr);
+--      IF data_check_arr(prev_check_adr) /= TO_UINT(st_histogram_ram_miso.rddata) AND dp_pipeline_src_out_pppp.valid='1' THEN
+--        dbg_error_location <= '1';
+--        REPORT "The value written to the RAM is not what it should be. See signal 'dbg_int_data_arr'. The failure concerns the bin (and array) address: " &integer'image(prev_check_adr) SEVERITY ERROR;
+--        error_cnt <= error_cnt + 1;
+--      ELSE
+--        dbg_error_location <= '0';
+--      END IF;
+--    END IF;
+--
+----    IF dp_rst='1' THEN
+----    data_check_arr(0 TO g_nof_bins) <= (OTHERS => 0);
+----    ELSIF rising_edge(dp_clk) THEN
+----      data_check_arr(check_adr) <= nxt_check_arr_cnt;
+----    END IF; 
+--  END PROCESS;
+
+  
+  -- show the location of an error after a small delay (to prevent spikes) when the data written is not the same as the reference and only when the data was initially valid. Do not allow to be triggered at the testbench end.
+  dbg_error_location <= '1' AFTER c_dp_clk_period/5 WHEN ( (data_check_arr(prev_check_adr) /= TO_UINT(st_histogram_ram_miso.rddata) ) AND dp_pipeline_src_out_pppp.valid='1' AND tb_end='0' ) ELSE '0';
+  ASSERT dbg_error_location='0' REPORT "The value written to the RAM is not what it should be. Comparison failed on (bin and array) address: " &integer'image(prev_check_adr) SEVERITY ERROR;
+  
+
+  --error count
+  p_count_total_error_cnt : PROCESS (dp_clk, dbg_error_location)
+  BEGIN
+    IF dp_rst='1' THEN
+      error_cnt <= 0;
+    ELSIF dbg_error_location='1' AND tb_end='0' AND rising_edge(dp_clk) THEN
+      error_cnt <= error_cnt + 1;
+    END IF;
+  END PROCESS;
+
+  p_view_total_error_cnt : PROCESS (tb_end, error_cnt)
+  BEGIN
+    IF tb_end='1' AND error_cnt>0 THEN
+      REPORT "When comparing there were " &integer'image(error_cnt) &" cycles where the value in the RAM address was not the value expected" SEVERITY ERROR;
+    END IF;
+  END PROCESS;
+  
 END tb;
-- 
GitLab