diff --git a/libraries/dsp/st/src/vhdl/st_histogram.vhd b/libraries/dsp/st/src/vhdl/st_histogram.vhd
index fdcf030d2f2fd020b0579384c0cd721be6e276bf..1633fa442dd2248a6ba561de9da56f34422300ad 100644
--- a/libraries/dsp/st/src/vhdl/st_histogram.vhd
+++ b/libraries/dsp/st/src/vhdl/st_histogram.vhd
@@ -112,6 +112,11 @@ ARCHITECTURE rtl OF st_histogram IS
   CONSTANT c_adr_low   : NATURAL := g_data_w-c_ram_adr_w; 
   CONSTANT c_ram_dat_w : NATURAL := ceil_log2(g_nof_data_per_sync)+1;
 
+  -------------------------------------------------------------------------------
+  -- snk_in.data help signal
+  -------------------------------------------------------------------------------
+  SIGNAL snk_in_data : STD_LOGIC_VECTOR(g_data_w-1 DOWNTO c_adr_low);
+
   -------------------------------------------------------------------------------
   -- ram_pointer
   -------------------------------------------------------------------------------
@@ -188,6 +193,17 @@ ARCHITECTURE rtl OF st_histogram IS
 
 BEGIN 
 
+  -------------------------------------------------------------------------------
+  -- Select range from snk_in.data and interpret as (un)signed
+  -------------------------------------------------------------------------------
+  gen_signed: IF g_data_type="signed" GENERATE
+    snk_in_data <= offset_binary(snk_in.data(g_data_w-1 DOWNTO c_adr_low));
+  END GENERATE;
+
+  gen_unsigned: IF g_data_type/="signed" GENERATE
+    snk_in_data <= snk_in.data(g_data_w-1 DOWNTO c_adr_low);
+  END GENERATE;
+
   -------------------------------------------------------------------------------
   -- ram_pointer: Keep track of what RAM to target
   -- . Target either RAM 0 or 1 per sync period
@@ -225,7 +241,7 @@ BEGIN
   bin_reader_mosi.wrdata  <= (OTHERS=>'0');
   bin_reader_mosi.wr      <= '0';
   bin_reader_mosi.rd      <= snk_in.valid;
-  bin_reader_mosi.address <= RESIZE_UVEC(ram_pointer & snk_in.data(g_data_w-1 DOWNTO c_adr_low), c_word_w); 
+  bin_reader_mosi.address <= RESIZE_UVEC(ram_pointer & snk_in_data, c_word_w); 
 
   -- Store the rd address as bin_writer needs to know where to write the bin count
   p_prv_bin_reader_mosi : PROCESS(dp_clk, dp_rst) IS
@@ -412,17 +428,17 @@ BEGIN
   -------------------------------------------------------------------------------
   ram_miso <= histogram_rd_miso;
   
-  gen_unsiged: IF g_data_type="unsigned" GENERATE
+--  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 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;
diff --git a/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd b/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd
index e964947870ee0264b067f298398d9a85974e9d80..356ba139b7b0821fbd67f523ec2820b11b7fb7b6 100644
--- a/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd
+++ b/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd
@@ -63,13 +63,14 @@ 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_stimuli_mode      : STRING  := "sine"; -- "counter", "dc", "sine"
-    g_data_type         : STRING  := "signed" -- use "signed" if g_stimuli_mode="sine"
-    );
+    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 := 1000;     -- Determines max required RAM data width. e.g. 11b to store max bin count '1024'.
+    g_stimuli_mode      : STRING  := "sine";   -- "counter", "dc", "sine" or "random"
+    g_data_type         : STRING  := "signed"; -- use "signed" if g_stimuli_mode="sine"
+    g_lock_sine         : BOOLEAN := TRUE      -- TRUE to lock the sine wave to Sync - produces sparse histogram with low number of non-zero samples (occuring 2*c_sine_nof_periods)
+    );                                         -- FALSE produces a dense histogram as the drifting sine wave hits more levels.
 END tb_st_histogram;
 
 
@@ -86,16 +87,22 @@ ARCHITECTURE tb OF tb_st_histogram IS
   ---------------------------------------------------------------------------
   -- Clocks and resets
   ---------------------------------------------------------------------------
-  CONSTANT c_dp_clk_period      : TIME := 5 ns;
+  CONSTANT c_dp_clk_period : TIME := 5 ns;
 
-  SIGNAL dp_rst                 : STD_LOGIC;
-  SIGNAL dp_clk                 : STD_LOGIC := '1';
+  SIGNAL dp_rst            : STD_LOGIC;
+  SIGNAL dp_clk            : STD_LOGIC := '1';
 
-  SIGNAL tb_end                 : STD_LOGIC := '0';
+  SIGNAL tb_end            : STD_LOGIC := '0';
    
   ----------------------------------------------------------------------------
   -- stimuli
   ----------------------------------------------------------------------------
+  CONSTANT c_sine_amplitude               : REAL := real((2**g_data_w)/2-1);
+  CONSTANT c_sine_nof_periods            : REAL := 1.0;
+  CONSTANT c_sine_nof_samples_per_period : REAL := real(g_nof_data_per_sync)/c_sine_nof_periods;
+  CONSTANT c_sine_time_step_denom        : REAL := sel_a_b(g_lock_sine, MATH_2_PI, 5.0); -- Use 5 instead of 2 pi to create unlocked, drifting sine wave
+  CONSTANT c_sine_time_step              : REAL := c_sine_time_step_denom / c_sine_nof_samples_per_period;
+
   SIGNAL stimuli_en : STD_LOGIC := '1';
 
   SIGNAL stimuli_src_out : t_dp_sosi;
@@ -115,10 +122,13 @@ ARCHITECTURE tb OF tb_st_histogram IS
    ----------------------------------------------------------------------------
    -- Automatic verification of RAM readout
    ----------------------------------------------------------------------------
+  SIGNAL ram_rd_addr           : NATURAL;
+  SIGNAL prv_ram_rd_addr       : NATURAL;
   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 sum_of_bins           : NATURAL;
   SIGNAL verification_done     : STD_LOGIC;
 
    ----------------------------------------------------------------------------
@@ -149,19 +159,19 @@ BEGIN
     proc_common_wait_until_low(dp_clk, dp_rst);
     proc_common_wait_some_cycles(dp_clk, 5);
 
+    -- Generate a block of counter data every sync
     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;
-  
+
+    -- Generate a DC level that increments every sync  
     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;
@@ -172,31 +182,33 @@ BEGIN
       END LOOP;     
     END IF;
 
+    -- Generate a sine wave
     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
+      FOR I IN 0 TO g_nof_sync-1 LOOP       
         stimuli_src_out.data <= (OTHERS=>'0');
+        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 <= TO_SVEC( integer(round( 100.0* sin(stimuli_count) )), g_data_w);
+          stimuli_data <= TO_SVEC( integer(round( c_sine_amplitude * sin(stimuli_count) )), g_data_w);
           stimuli_src_out.data(g_data_w-1 DOWNTO 0) <= stimuli_data;
-          stimuli_count<=stimuli_count+0.1;
+          stimuli_count<=stimuli_count+c_sine_time_step;
           WAIT FOR 5 ns;
         END LOOP;
       END LOOP;     
     END IF;
 
+    -- Generate pseudo random noise 
     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
+        FOR j IN 1 TO g_nof_data_per_sync-1 LOOP
           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
@@ -264,24 +276,29 @@ BEGIN
   p_verify_mm_read : PROCESS
   BEGIN
     st_histogram_ram_mosi.wr <= '0';
+    ram_rd_addr <= 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_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_addr <= j;
         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;
+    WAIT;
   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';     
+      ram_rd_word_valid <= '0';
+      prv_ram_rd_addr   <= 0;
     ELSIF RISING_EDGE(dp_clk) THEN
       ram_rd_word_valid <= nxt_ram_rd_word_valid;
+      prv_ram_rd_addr <= ram_rd_addr; -- align the rd address with rd data for wave window debugging
     END IF;
   END PROCESS;
   nxt_ram_rd_word_valid <= st_histogram_ram_miso.rdval;
@@ -291,6 +308,7 @@ BEGIN
   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);  
       FOR j IN 0 TO g_nof_bins-1 LOOP
         proc_common_wait_until_high(dp_clk, ram_rd_word_valid);    
@@ -311,8 +329,15 @@ BEGIN
             END IF;
           END IF;
         END IF;
+        sum_of_bins<=sum_of_bins+ram_rd_word_int; -- Keep the sum of all bins  
         WAIT FOR 5 ns;
-      END LOOP;
+      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" SEVERITY ERROR;
+      END IF;
+
     END LOOP;
     verification_done <= '1'; --We have blocking proc_common_wait_until_high procedures above so we need to know if we make it here.
     WAIT;