diff --git a/libraries/dsp/st/hdllib.cfg b/libraries/dsp/st/hdllib.cfg
index 660c6f533ce2a2b0b6ce93d12acab8a7683d0441..21443d39f3629e98383ef0678cc9191f97d8bb4b 100644
--- a/libraries/dsp/st/hdllib.cfg
+++ b/libraries/dsp/st/hdllib.cfg
@@ -10,11 +10,17 @@ synth_files =
     src/vhdl/st_calc.vhd 
     src/vhdl/st_sst.vhd 
 #    src/vhdl/st_top.vhd 
+    src/vhdl/st_histogram.vhd
+    src/vhdl/st_histogram_reg.vhd
+    src/vhdl/mms_st_histogram.vhd
+    src/vhdl/st_histogram_8_april.vhd
  
 test_bench_files = 
     tb/vhdl/tb_st_acc.vhd 
     tb/vhdl/tb_st_calc.vhd 
-    tb/vhdl/tb_mmf_st_sst.vhd   
+    tb/vhdl/tb_mmf_st_sst.vhd
+    tb/vhdl/tb_st_histogram.vhd
+    tb/vhdl/tb_mms_st_histogram.vhd
 
 regression_test_vhdl = 
     tb/vhdl/tb_st_acc.vhd 
diff --git a/libraries/dsp/st/src/vhdl/mms_st_histogram.vhd b/libraries/dsp/st/src/vhdl/mms_st_histogram.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..372f5187091d077d31a483556dbfb94ac2b4360d
--- /dev/null
+++ b/libraries/dsp/st/src/vhdl/mms_st_histogram.vhd
@@ -0,0 +1,125 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright 2020
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+-- 
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+-- 
+--     http://www.apache.org/licenses/LICENSE-2.0
+-- 
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- 
+-- Author: J.W.E. Oudman
+-- Purpose: Create a histogram from the input data and present it to the MM bus
+-- Description: 
+--   mms_st_histogram couples the st_histogram component which works entirely
+--   in the dp clock domain through st_histogram_reg that handles the cross
+--   domain conversion to the MM bus.
+--
+--
+--             --------------------------------------
+--             | mms_st_histogram                   |
+--             |                                    |
+--             |   ----------------                 |         -------
+--   snk_in -->|-->| st_histogram |                 |             ^
+--             |   ----------------                 |             |
+--             |      |      ^                      |
+--             |      |      |                      |           dp clock domain
+--             |    ram_st_histogram_miso           |
+--             |      |      |                      |          
+--             |      |    ram_st_histogram_mosi    |             |
+--             |      v      |                      |             v
+--             | --------------------               |         -------
+--             | | st_histogram_reg |-- ram_miso -->|-->        mm clock domain
+--             | |                  |<-- ram_mosi --|<--
+--             | --------------------               |         -------
+--             |                                    |
+--             --------------------------------------
+--
+--
+-------------------------------------------------------------------------------
+
+LIBRARY IEEE, common_lib, mm_lib, technology_lib, dp_lib;
+USE IEEE.std_logic_1164.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
+USE dp_lib.dp_stream_pkg.ALL;
+USE technology_lib.technology_select_pkg.ALL;
+
+ENTITY mms_st_histogram IS
+  GENERIC (
+    g_in_data_w     : NATURAL := 14;   -- >= 9 when g_nof_bins is 512; (max. c_dp_stream_data_w =768)
+    g_nof_bins      : NATURAL := 512;  -- is a power of 2 and g_nof_bins <= c_data_span; max. 512
+    g_nof_data      : NATURAL;         -- 
+    g_str           : STRING  := "freq.density"  -- to select output to MM bus ("frequency" or "freq.density")
+  );                
+  PORT (            
+    dp_rst          : IN  STD_LOGIC;
+    dp_clk          : IN  STD_LOGIC;
+    mm_rst          : IN  STD_LOGIC;
+    mm_clk          : IN  STD_LOGIC;
+                    
+    -- Streaming    
+    snk_in      : IN  t_dp_sosi;
+
+    -- Memory Mapped
+    ram_mosi : IN  t_mem_mosi;
+    ram_miso : OUT t_mem_miso
+  );
+END mms_st_histogram;
+
+ARCHITECTURE str OF mms_st_histogram IS
+  
+  SIGNAL ram_st_histogram_mosi : t_mem_mosi;
+  SIGNAL ram_st_histogram_miso : t_mem_miso;
+  
+BEGIN 
+  
+  u_st_histogram : ENTITY work.st_histogram
+  GENERIC MAP(
+    g_in_data_w => g_in_data_w,
+    g_nof_bins  => g_nof_bins,
+    g_nof_data  => g_nof_data,
+    g_str       => g_str
+  )
+  PORT MAP (
+    dp_rst      => dp_rst,
+    dp_clk      => dp_clk,
+    
+    snk_in      => snk_in,
+    sla_in_ram_mosi    => ram_st_histogram_mosi,
+    sla_out_ram_miso    => ram_st_histogram_miso
+  );
+  
+  u_st_histogram_reg : ENTITY work.st_histogram_reg
+--  GENERIC MAP(
+--    g_in_data_w =>
+--    g_nof_bins  =>
+--    g_nof_data  =>
+--    g_str       =>
+--  )
+  PORT MAP (
+    dp_rst                => dp_rst,
+    dp_clk                => dp_clk,
+    mm_rst                => mm_rst,
+    mm_clk                => mm_clk,
+    
+    mas_out_ram_mosi => ram_st_histogram_mosi,
+    mas_in_ram_miso => ram_st_histogram_miso,
+    
+    ram_mosi              => ram_mosi,
+    ram_miso              => ram_miso
+  );
+  
+END str;
diff --git a/libraries/dsp/st/src/vhdl/st_histogram.vhd b/libraries/dsp/st/src/vhdl/st_histogram.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..4177fdd6c43189ed20f8075d5abe46372fae8057
--- /dev/null
+++ b/libraries/dsp/st/src/vhdl/st_histogram.vhd
@@ -0,0 +1,575 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright 2020
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+-- 
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+-- 
+--     http://www.apache.org/licenses/LICENSE-2.0
+-- 
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- 
+-- Author: J.W.E. Oudman
+-- Purpose: Create a histogram from the input data and present it to 
+--   st_histogram_reg
+-- Description: 
+--   The histogram component separates it's input samples in counter bins based
+--   on the value of the MSbits of the input. These bins are adresses on a RAM
+--   block that is swapped with another RAM block at every sync pulse plus 2 
+--   cycles. While one RAM block is used to count the input samples, the other
+--   is read by the MM bus through st_histogram_reg.
+--
+-- 
+--           ram_pointer        ram_pointer
+--               |                  |
+--               | /o--- RAM_0 ---o |
+--               |/                 |
+--               /                  |
+--  snk_in ----o/                   | /o----- ram_miso (st_histogram_reg)
+--                                  |/           _mosi
+--                                  /
+--                  o--- RAM_1 ---o/
+--
+--
+-- The input data is a dp stream which obviously uses a dp_clk. Because the
+-- RAM is swapped after every sync both RAM blocks need to use the dp_clk.
+-- If the MM bus needs to acces the data in a RAM block it has to acces it
+-- through st_histogram_reg as the mm_clk can't be used.
+-- 
+-- Remarks:
+-- . Because the values of the generics g_nof_bins depends on g_in_data_w
+--   (you should not have more bins than data values) an assert is made to
+--   warn in the simulation when the maximum value of g_nof_bins is reached.
+--   If exceeded the simulator will throw fatal error ("...Port length (#) does
+--   not match actual length (#)...")
+--
+-- . when an adress is determined it takes 1 cycle to receive it's value and
+--   another cycle before the calculated value can be written into that RAM
+--   adress. There is also the limitation of not being able to read and write 
+--   on the same adress at the same time. These limitations cause the following
+--   complications in the implementation:
+--   . repeating samples of the same adress have to be counted first till 
+--     another adress appears before written (as you would miss the second and
+--     further consecutive samples and have the read/write limitation)
+--   . If adresses are toggling at every cycle (e.g. adress 0; 1; 0; 1) you
+--     have to remember the data to be written and increment it as you have the
+--     read/write limitation and writing takes priority in this case
+--   . When a sync signal appears the RAM has to be swapped 2 cycles later so 
+--     the first 2 cycles may not be read from the old RAM block 
+-- 
+-------------------------------------------------------------------------------
+
+LIBRARY IEEE, common_lib, mm_lib, technology_lib, dp_lib;
+USE IEEE.std_logic_1164.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
+USE dp_lib.dp_stream_pkg.ALL;
+USE technology_lib.technology_select_pkg.ALL;
+
+ENTITY st_histogram IS
+  GENERIC (
+    g_in_data_w     : NATURAL := 14;   -- >= 9 when g_nof_bins is 512; (max. c_dp_stream_data_w =768)         <-- maybe just g_data_w ??
+    g_nof_bins      : NATURAL := 512;  -- is a power of 2 and g_nof_bins <= c_data_span; max. 512
+    g_nof_data      : NATURAL;         -- 
+    g_str           : STRING  := "freq.density"  -- to select output to MM bus ("frequency" or "freq.density")
+  );                
+  PORT (            
+    dp_rst          : IN  STD_LOGIC;
+    dp_clk          : IN  STD_LOGIC;
+                    
+    -- Streaming    
+    snk_in      : IN  t_dp_sosi;
+    
+    -- DP clocked memory bus
+    sla_in_ram_mosi : IN  t_mem_mosi;  -- Beware, works in dp clock domain !
+    sla_out_ram_miso : OUT t_mem_miso   --  ''                              !
+--    ram_mosi : IN  t_mem_mosi;  -- Beware, works in dp clock domain !
+--    ram_miso : OUT t_mem_miso   --  ''                              !
+  );
+END st_histogram;
+
+
+ARCHITECTURE rtl OF st_histogram IS
+
+  CONSTANT c_data_span    : NATURAL  := pow2(g_in_data_w);      -- any use?
+  CONSTANT c_bin_w        : NATURAL  := ceil_log2(g_nof_data);  -- any use?
+  CONSTANT c_clear        : NATURAL  := g_nof_data - g_nof_bins;
+  CONSTANT c_adr_w        : NATURAL  := ceil_log2(g_nof_bins);
+  CONSTANT c_adr_low_calc : INTEGER  := g_in_data_w-c_adr_w;          -- Calculation might yield a negative number
+  CONSTANT c_adr_low      : NATURAL  := largest(0, c_adr_low_calc);   -- Override any negative value of c_adr_low_calc
+  
+  CONSTANT c_ram          : t_c_mem := (latency  => 1,
+                                        adr_w    => c_adr_w,          -- 9 bits needed to adress/select 512 adresses
+                                        dat_w    => c_word_w,         -- 32bit, def. in common_pkg; >= c_bin_w
+                                        nof_dat  => g_nof_bins,       -- 512 adresses with 32 bit words, so 512
+                                        init_sl  => '0');             -- MM side : sla_in, sla_out
+  
+  SIGNAL dp_pipeline_src_out_p : t_dp_sosi;
+  SIGNAL dp_pipeline_src_out_pp : t_dp_sosi;
+  
+  SIGNAL rd_adr_cnt         : NATURAL  := 1;
+  SIGNAL nxt_rd_adr_cnt     : NATURAL;
+  SIGNAL prev_rd_adr        : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
+  
+  -- Toggle implementation signals
+  SIGNAL prev_same_r_w_adr : STD_LOGIC  := '0';
+  SIGNAL same_r_w_adr      : STD_LOGIC  := '0';
+  SIGNAL nxt_same_r_w_adr  : STD_LOGIC  := '0';
+
+  
+  SIGNAL ram_pointer       : STD_LOGIC  := '0';
+  SIGNAL cycle_cnt         : NATURAL    :=  0 ;
+  SIGNAL nxt_cycle_cnt     : NATURAL    :=  0 ;
+  SIGNAL wr_en           : STD_LOGIC  := '0';
+  SIGNAL nxt_wr_en       : STD_LOGIC;
+  SIGNAL wr_dat          : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0);
+  SIGNAL nxt_wr_dat      : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0);
+  SIGNAL wr_adr             : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
+  SIGNAL rd_adr             : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
+  SIGNAL rd_en           : STD_LOGIC  := '0';
+  SIGNAL rd_dat          : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0);
+  SIGNAL rd_val          : STD_LOGIC;
+  
+  SIGNAL mm_adr_cnt        : NATURAL   :=  0 ;
+  SIGNAL mm_adr_illegal    : STD_LOGIC := '0';
+  SIGNAL mm_adr_illegal_pp : STD_LOGIC := '0';
+  
+  
+  SIGNAL ram_0_wr_en    : STD_LOGIC;
+--  SIGNAL ram_0_wr_en_b    : STD_LOGIC  := '0'; -- pointer=1, temp'0'
+  SIGNAL ram_0_wr_dat   : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0);
+--  SIGNAL ram_0_wr_dat_b   : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0) := (OTHERS =>'0'); -- pointer=1, temp'0'
+  SIGNAL ram_0_wr_adr      : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
+  SIGNAL ram_0_rd_adr      : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
+  SIGNAL ram_0_rd_en    : STD_LOGIC;
+  SIGNAL ram_0_rd_dat   : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0);
+  SIGNAL ram_0_rd_val   : STD_LOGIC;
+  
+  SIGNAL ram_1_wr_en    : STD_LOGIC;
+  SIGNAL ram_1_wr_dat   : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0);
+  SIGNAL ram_1_wr_adr      : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
+  SIGNAL ram_1_rd_adr      : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
+  SIGNAL ram_1_rd_en    : STD_LOGIC;
+  SIGNAL ram_1_rd_dat   : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0);
+  SIGNAL ram_1_rd_val   : STD_LOGIC;
+  
+  SIGNAL ram_out_wr_en    : STD_LOGIC;
+  SIGNAL ram_out_wr_dat   : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0);
+  SIGNAL ram_out_wr_adr   : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
+  SIGNAL ram_out_rd_adr   : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
+  SIGNAL ram_out_rd_en    : STD_LOGIC;
+  SIGNAL ram_out_rd_dat   : STD_LOGIC_VECTOR(c_word_w -1 DOWNTO 0);
+  SIGNAL ram_out_rd_val   : STD_LOGIC;
+  
+  SIGNAL prev_ram_out_wr_adr  : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
+  SIGNAL ram_out_same_w_r_adr : STD_LOGIC;
+  
+BEGIN 
+  
+  -----------------------------------------------------------------------------
+  -- Check Generics
+  -----------------------------------------------------------------------------
+  ASSERT c_adr_low_calc>0 REPORT "ceil_log2(g_nof_bins) is as large as g_in_data_w, don't increase g_nof_bins" SEVERITY WARNING;
+  
+  -----------------------------------------------------------------------------
+  -- Assign inputs of RAM:
+  -- . Determine address based on input data
+  -- . Compare adress with the two previous adresses and if:
+  --   . it is the same as the last adress increase a counter
+  --   . it is the same as 2 cycles back but not the last copy the data to be 
+  --     written directly into the counter instead of trying to read (ask) it 
+  --     back from RAM at the same clock cycle (which is impossible)
+  --   . it is not the same enable the nxt_wr_dat data to be written
+  --     at the next cycle by making nxt_wr_en high
+  -- . Write the wr_dat data to the RAM
+  -- . At the snk_in.sync pulse:
+  --   . let first 2 cycles start counting from 0 again
+  --   . (plus 2 cycles) let counting depend on values in RAM (which should
+  --     be 0)
+  -- . Restart or pause counting when a snk_in.valid = '0' appears:
+  --   . pause when adress is the same as the previous adress
+  --   . restart from 0 when adress is not the same as previous adress
+  --   . restart from 0 when also a sync appears
+  -- 
+  -- input: snk_in; rd_dat; rd_val
+  -- output: wr_adr; rd_adr; wr_en; rd_en; wr_dat; 
+  ----------------------------------------------------------------------------
+
+  -- cycles after sync
+  u_dp_pipeline_snk_in_1_cycle : ENTITY dp_lib.dp_pipeline
+  GENERIC MAP (
+    g_pipeline   => 1  -- 0 for wires, > 0 for registers, 
+  )
+  PORT MAP (
+    rst          => dp_rst,
+    clk          => dp_clk,
+    snk_in       => snk_in,
+    src_out      => dp_pipeline_src_out_p
+  );
+  
+  p_bin_cnt_switch : PROCESS(snk_in) IS -- misses g_nof_bins ??
+  BEGIN
+    rd_adr <= (OTHERS =>'0');
+    IF g_nof_bins>1 THEN
+      rd_adr <= snk_in.data(g_in_data_w-1 DOWNTO c_adr_low);-- WHEN snk_in.valid='1' ELSE (OTHERS =>'0'); -- AND dp_rst='0';
+    END IF;
+  END PROCESS;
+  
+  -- Pipelined to compare previous rd_adr against current 
+  u_common_pipeline_adr_cnt : ENTITY common_lib.common_pipeline --rename to u_common_pipeline_rd_adr
+  GENERIC MAP (
+    g_representation => "UNSIGNED", --orig. signed
+    g_pipeline       => 1,
+    g_in_dat_w       => c_adr_w,
+    g_out_dat_w      => c_adr_w
+  )
+  PORT MAP (
+    clk     => dp_clk,
+    clken   => '1',
+    in_dat  => STD_LOGIC_VECTOR(rd_adr),
+    out_dat => prev_rd_adr
+  );
+  
+  p_nxt_wr_en : PROCESS(prev_rd_adr, rd_adr, snk_in.sync) IS -- misses g_nof_bins ??
+  BEGIN
+    nxt_wr_en <= '0';
+    IF rd_adr /= prev_rd_adr THEN
+      nxt_wr_en <= '1';
+    ELSIF snk_in.sync = '1' AND g_nof_bins = 1 THEN
+      nxt_wr_en <= '1';
+    ELSIF snk_in.sync = '1' THEN
+      nxt_wr_en <= '1';
+    END IF;
+  END PROCESS;
+  
+  -- requested data on adress can be written back 2 cycles later
+  u_common_pipeline_adr : ENTITY common_lib.common_pipeline
+  GENERIC MAP (
+    g_representation => "UNSIGNED", --orig. signed
+    g_pipeline       => 2,
+    g_in_dat_w       => c_adr_w,
+    g_out_dat_w      => c_adr_w
+  )
+  PORT MAP (
+    clk     => dp_clk,
+    clken   => '1',
+    in_dat  => STD_LOGIC_VECTOR(rd_adr),
+    out_dat => wr_adr
+  );
+  
+  p_rd_en : PROCESS(dp_pipeline_src_out_p.sync, snk_in.valid, wr_en, wr_adr, rd_adr, prev_rd_adr) IS
+  BEGIN
+    rd_en <= '1';
+    IF dp_pipeline_src_out_p.sync = '1' AND wr_en = '1' THEN  --
+      rd_en <= '0';
+    ELSIF wr_adr = rd_adr AND wr_adr /= prev_rd_adr THEN  -- toggle implementation
+      rd_en <= '0';                                 -- toggle implementation  
+    ELSIF snk_in.valid = '0' AND wr_en = '1' THEN
+      rd_en <= '1';
+    END IF;
+  END PROCESS;
+  
+  -- cycles after sync
+  u_dp_pipeline_snk_in_2_cycle : ENTITY dp_lib.dp_pipeline
+  GENERIC MAP (
+    g_pipeline   => 2   -- 0 for wires, > 0 for registers, 
+  )
+  PORT MAP (
+    rst          => dp_rst,
+    clk          => dp_clk,
+    snk_in       => snk_in,
+    src_out      => dp_pipeline_src_out_pp
+  );
+
+  p_prev_adr_cnt : PROCESS(wr_adr, rd_adr, prev_rd_adr, rd_adr_cnt, snk_in.sync, snk_in.valid, dp_pipeline_src_out_p.valid, dp_pipeline_src_out_p.sync) IS --change to p_nxt_rd_adr_cnt ;; misses wr_dat; 
+  BEGIN
+    nxt_rd_adr_cnt <= 1;
+    IF rd_adr = prev_rd_adr AND snk_in.valid = '1' AND snk_in.sync = '0' THEN
+      nxt_rd_adr_cnt <= rd_adr_cnt + 1 ;
+    ELSIF snk_in.valid = '0' AND snk_in.sync = '1' THEN  --address doesn't matter at unvalid and sync, removed: rd_adr = prev_rd_adr AND
+      nxt_rd_adr_cnt <= 0;
+    ELSIF rd_adr = prev_rd_adr AND snk_in.valid = '0' THEN
+      nxt_rd_adr_cnt <= rd_adr_cnt;
+    ELSIF rd_adr = prev_rd_adr AND snk_in.valid = '1' AND dp_pipeline_src_out_p.valid = '0' AND snk_in.sync = '1' THEN  -- toggle implementation; do the adresses even matter?
+      nxt_rd_adr_cnt <= 1;                                                                                             -- toggle implementation
+    ELSIF rd_adr = prev_rd_adr AND snk_in.valid = '1' AND dp_pipeline_src_out_p.valid = '0' THEN  -- toggle implementation
+      nxt_rd_adr_cnt <= rd_adr_cnt + 1;                                                           -- toggle implementation
+    ELSIF wr_adr = rd_adr AND snk_in.valid = '1' AND snk_in.sync = '1' THEN    -- toggle implementation; do the adresses even matter?
+      nxt_rd_adr_cnt <= 1;                                                    -- toggle implementation
+    ELSIF wr_adr = rd_adr AND rd_adr /= prev_rd_adr AND snk_in.valid = '0' THEN  -- toggle implementation: disable count; -2 cycles count + 0
+      nxt_rd_adr_cnt <= TO_UINT(wr_dat);                                    -- toggle implementation
+    ELSIF wr_adr = rd_adr AND snk_in.valid = '1' AND dp_pipeline_src_out_p.sync = '0' THEN  -- toggle implentation
+      nxt_rd_adr_cnt <= TO_UINT(wr_dat) + 1;        -- toggle implentation
+    ELSIF wr_adr = rd_adr AND snk_in.valid = '0' THEN  -- toggle implentation
+      nxt_rd_adr_cnt <= rd_adr_cnt;                    -- toggle implentation
+    ELSIF snk_in.valid = '0' AND rd_adr /= prev_rd_adr AND wr_adr /= rd_adr THEN
+      nxt_rd_adr_cnt <= 0;
+    END IF;
+  END PROCESS;
+  
+  p_nxt_same_r_w_adr : PROCESS(wr_adr, rd_adr) IS  -- toggle implentation  ;; misses g_nof_bins ??
+  BEGIN
+    nxt_same_r_w_adr <= '0';
+    IF wr_adr = rd_adr AND g_nof_bins > 1 THEN
+      nxt_same_r_w_adr <= '1';
+    END IF;
+  END PROCESS;
+  
+  -- Pipeline for toggle issue
+  u_common_pipeline_sl_same_r_w_adr : ENTITY common_lib.common_pipeline_sl
+  GENERIC MAP(
+    g_pipeline       => 1 -- 0 for wires, > 0 for registers, 
+  )
+  PORT MAP (
+    clk     => dp_clk,
+    in_dat  => same_r_w_adr,
+    out_dat => prev_same_r_w_adr
+  );
+  
+  p_nxt_wr_dat : PROCESS(rd_dat, rd_adr_cnt, rd_val, dp_pipeline_src_out_p.sync, dp_pipeline_src_out_pp.sync, wr_en) IS --misses: same_r_w_adr; c_word_w?; prev_same_r_w_adr;
+  BEGIN
+    nxt_wr_dat <= (OTHERS => '0');
+    IF dp_pipeline_src_out_p.sync = '1' THEN
+      nxt_wr_dat <= TO_UVEC(rd_adr_cnt, c_word_w);
+    ELSIF dp_pipeline_src_out_pp.sync = '1' THEN
+      nxt_wr_dat <= TO_UVEC(rd_adr_cnt, c_word_w);
+    ELSIF same_r_w_adr = '1' AND rd_val = '0' THEN    -- toggle implementation: same adress forced rd_val to 0, counter instead of ram knows what to write
+      nxt_wr_dat <= TO_UVEC(rd_adr_cnt, c_word_w);     -- toggle implementation
+    ELSIF dp_pipeline_src_out_pp.valid = '0' AND prev_same_r_w_adr = '1' THEN  -- toggle implementation: prevent 2* rd_dat
+      nxt_wr_dat <= TO_UVEC(rd_adr_cnt, c_word_w);     -- toggle implementation
+    ELSIF rd_val = '1' THEN
+      nxt_wr_dat <= INCR_UVEC(rd_dat, rd_adr_cnt);
+    END IF;
+  END PROCESS;
+  
+  p_clk : PROCESS(dp_clk, dp_rst)
+  BEGIN
+  IF dp_rst='1' THEN
+    rd_adr_cnt <= 0;
+    wr_en <= '0';
+  ELSIF rising_edge(dp_clk) THEN
+    rd_adr_cnt <= nxt_rd_adr_cnt;
+    wr_dat <= nxt_wr_dat;
+    wr_en <= nxt_wr_en;
+    same_r_w_adr <= nxt_same_r_w_adr;
+    cycle_cnt <= nxt_cycle_cnt;                     -- ( ander functieblok )
+    prev_ram_out_wr_adr <= ram_out_wr_adr;          --         ''
+  END IF; 
+  END PROCESS;  
+  
+  
+  -----------------------------------------------------------------------------
+  -- RAM selector & Dual swapped RAM instances:
+  --  2 cycles after a sync the RAM block is swapped for an empty one to allow
+  --  the block to be read out till the next sync+2 cycles
+  --
+  -- Depending on ram_pointer:
+  -- ram_pointer = '0': input RAM_0, output RAM_1
+  -- ram_pointer = '1': input RAM_1, output RAM_0
+  --
+  -- input in:  dp_pipeline_src_out_pp.sync;  wr_en; wr_dat; wr_adr; 
+  --            rd_adr; rd_en; 
+  --       out: rd_dat, rd_val
+  --
+  -- output in:  ram_out_wr_en; ram_out_wr_dat; ram_out_wr_adr; ram_out_rd_adr;
+  --             ram_out_rd_en
+  --        out: ram_out_rd_dat; ram_out_rd_val
+  -----------------------------------------------------------------------------
+  p_ram_pointer_at_sync : PROCESS(dp_pipeline_src_out_pp) IS -- needs nxt_ram_pointer ??
+  BEGIN
+    IF dp_pipeline_src_out_pp.sync = '1' THEN
+      ram_pointer <= NOT(ram_pointer);
+    END IF;
+  END PROCESS;
+  
+  p_ram_pointer : PROCESS(ram_pointer, wr_en, wr_dat, wr_adr, rd_adr, rd_en, ram_0_rd_dat, ram_0_rd_val, 
+                          ram_out_wr_en, ram_out_wr_dat, ram_out_wr_adr, ram_out_rd_adr, ram_out_rd_en, ram_1_rd_dat, ram_1_rd_val) IS
+  BEGIN
+    IF ram_pointer='0' THEN
+    
+      -- ST side (RAM 0)
+      ram_0_wr_en <= wr_en;
+      ram_0_wr_dat <= wr_dat;
+      ram_0_wr_adr <= wr_adr;
+      ram_0_rd_adr <= rd_adr;
+      ram_0_rd_en <= rd_en;
+      rd_dat <= ram_0_rd_dat;
+      rd_val <= ram_0_rd_val;
+      
+      
+      -- dp_clk'd  MM side (RAM 1)
+      ram_1_wr_en <= ram_out_wr_en;
+      ram_1_wr_dat <= ram_out_wr_dat;
+      ram_1_wr_adr <= ram_out_wr_adr;
+      ram_1_rd_adr <= ram_out_rd_adr;
+      ram_1_rd_en <= ram_out_rd_en;
+      ram_out_rd_dat <= ram_1_rd_dat;
+      ram_out_rd_val <= ram_1_rd_val;
+      
+      
+    ELSE -- ram_pointer='1'
+    
+      -- ST side (RAM 1)
+      ram_1_wr_en <= wr_en;
+      ram_1_wr_dat <= wr_dat;
+      ram_1_wr_adr <= wr_adr;
+      ram_1_rd_adr <= rd_adr;
+      ram_1_rd_en <= rd_en;
+      rd_dat <= ram_1_rd_dat;
+      rd_val <= ram_1_rd_val;
+      
+      --dp_clk'd  MM side (RAM 0)
+      ram_0_wr_en <= ram_out_wr_en;
+      ram_0_wr_dat <= ram_out_wr_dat;
+      ram_0_wr_adr <= ram_out_wr_adr;
+      ram_0_rd_adr <= ram_out_rd_adr;
+      ram_0_rd_en <= ram_out_rd_en;
+      ram_out_rd_dat <= ram_0_rd_dat;
+      ram_out_rd_val <= ram_0_rd_val;
+
+    END IF;
+  END PROCESS;
+  
+  
+  -- Dual swapped RAM instances
+  ram_0: ENTITY common_lib.common_ram_r_w
+  GENERIC MAP (
+    g_technology     => c_tech_select_default,
+    g_ram            => c_ram,
+    g_init_file      => "UNUSED"
+  )
+  PORT MAP (
+    rst      => dp_rst, 
+    clk      => dp_clk,
+    clken    => '1',            -- only necessary for Stratix iv
+    wr_en    => ram_0_wr_en,
+    wr_adr   => ram_0_wr_adr,
+    wr_dat   => ram_0_wr_dat,
+    rd_en    => ram_0_rd_en,
+    rd_adr   => ram_0_rd_adr,
+    rd_dat   => ram_0_rd_dat,
+    rd_val   => ram_0_rd_val
+  );
+  
+  ram_1: ENTITY common_lib.common_ram_r_w
+  GENERIC MAP (
+    g_technology     => c_tech_select_default,
+    g_ram            => c_ram,
+    g_init_file      => "UNUSED"
+  )
+  PORT MAP (
+    rst      => dp_rst, 
+    clk      => dp_clk,
+    clken    => '1',            -- only necessary for Stratix iv
+    wr_en    => ram_1_wr_en,
+    wr_adr   => ram_1_wr_adr,
+    wr_dat   => ram_1_wr_dat,
+    rd_en    => ram_1_rd_en,
+    rd_adr   => ram_1_rd_adr,
+    rd_dat   => ram_1_rd_dat,
+    rd_val   => ram_1_rd_val
+  );
+  
+  
+  
+  -----------------------------------------------------------------------------
+  -- Connect interface to DUAL swapped RAM, read out histogram statistics:
+  -- . Limit the data read by the MM master to the RAM block where it started
+  --   to read (the values read after a new sync will be OTHERS => '0')
+  -- . In the last g_nof_bins cycles all addresses will sequentially be cleared
+  --
+  -- RAM selector:
+  -- input: ram_out_rd_dat; ram_out_rd_val
+  -- output: ram_out_wr_en; ram_out_wr_dat; ram_out_wr_adr; ram_out_rd_adr;
+  --         ram_out_wr_en 
+  -- (PORT):
+  -- input: snk_in; sla_in_ram_mosi
+  -- output: sla_out_ram_miso
+  -----------------------------------------------------------------------------
+  
+  -- Pipeline for identified illegal read requests after new sync
+  u_common_pipeline_sl_mm_adr_illegal : ENTITY common_lib.common_pipeline_sl
+  GENERIC MAP(
+    g_pipeline       => 2 -- 0 for wires, > 0 for registers, 
+  )
+  PORT MAP (
+    clk     => dp_clk,
+    in_dat  => mm_adr_illegal,
+    out_dat => mm_adr_illegal_pp
+  );
+  
+  p_mm_adr_illegal : PROCESS(snk_in.sync, mm_adr_cnt) IS
+  BEGIN
+    IF snk_in.sync = '1' AND mm_adr_cnt /= 0 THEN
+      mm_adr_illegal <= '1';
+    ELSIF mm_adr_cnt = g_nof_bins-1 THEN
+      mm_adr_illegal <= '0';
+    ELSE
+    END IF;
+  END PROCESS;
+  
+  mm_adr_cnt <= TO_UINT(sla_in_ram_mosi.address(c_ram.adr_w-1 DOWNTO 0)) WHEN sla_in_ram_mosi.rd = '1';
+  ram_out_same_w_r_adr <= '1' WHEN ram_out_wr_adr = sla_in_ram_mosi.address(c_ram.adr_w-1 DOWNTO 0) ELSE '0';
+  
+  p_ram_to_fifo : PROCESS(dp_pipeline_src_out_pp.sync, cycle_cnt, sla_in_ram_mosi.address, sla_in_ram_mosi.rd, ram_out_rd_dat, ram_out_rd_val, prev_ram_out_wr_adr, mm_adr_illegal, ram_out_same_w_r_adr) IS
+  BEGIN
+    IF dp_pipeline_src_out_pp.sync = '1' THEN
+      ram_out_wr_en <= '0';
+      nxt_cycle_cnt <= 0;
+    ELSIF cycle_cnt = c_clear THEN
+      ram_out_wr_adr <= (OTHERS => '0');
+      ram_out_wr_dat <= (OTHERS => '0');
+      ram_out_wr_en <= '1';
+      IF ram_out_same_w_r_adr = '1' THEN
+        ram_out_rd_en                           <= '0';
+        sla_out_ram_miso.rddata(c_ram.dat_w-1 DOWNTO 0) <= (OTHERS => '0');
+        sla_out_ram_miso.rdval                          <= ram_out_rd_val;
+      ELSE
+        ram_out_rd_adr                          <= sla_in_ram_mosi.address(c_ram.adr_w-1 DOWNTO 0);
+        ram_out_rd_en                           <= sla_in_ram_mosi.rd;
+        sla_out_ram_miso.rddata(c_ram.dat_w-1 DOWNTO 0) <= ram_out_rd_dat;
+        sla_out_ram_miso.rdval                          <= ram_out_rd_val;
+      END IF;
+      nxt_cycle_cnt <= cycle_cnt +1;
+    ELSIF cycle_cnt > c_clear THEN
+      ram_out_wr_adr <= INCR_UVEC(prev_ram_out_wr_adr, 1);
+      nxt_cycle_cnt <= cycle_cnt +1;
+      IF ram_out_same_w_r_adr = '1' OR snk_in.sync = '1' THEN
+        sla_out_ram_miso.rddata(c_ram.dat_w-1 DOWNTO 0) <= (OTHERS => '0');
+        sla_out_ram_miso.rdval                          <= ram_out_rd_val;
+      ELSE
+        ram_out_rd_adr                          <= sla_in_ram_mosi.address(c_ram.adr_w-1 DOWNTO 0);
+        ram_out_rd_en                           <= sla_in_ram_mosi.rd;
+        sla_out_ram_miso.rddata(c_ram.dat_w-1 DOWNTO 0) <= ram_out_rd_dat;
+        sla_out_ram_miso.rdval                          <= ram_out_rd_val;
+      END IF;
+    ELSIF mm_adr_illegal_pp = '1' THEN
+      ram_out_rd_adr                          <= sla_in_ram_mosi.address(c_ram.adr_w-1 DOWNTO 0);
+      ram_out_rd_en                           <= sla_in_ram_mosi.rd;
+      sla_out_ram_miso.rddata(c_ram.dat_w-1 DOWNTO 0) <= (OTHERS => '0');
+      sla_out_ram_miso.rdval                          <= ram_out_rd_val;
+      nxt_cycle_cnt                           <= cycle_cnt +1;
+    ELSE
+      ram_out_rd_adr                          <= sla_in_ram_mosi.address(c_ram.adr_w-1 DOWNTO 0);
+      ram_out_rd_en                           <= sla_in_ram_mosi.rd;
+      sla_out_ram_miso.rddata(c_ram.dat_w-1 DOWNTO 0) <= ram_out_rd_dat;
+      sla_out_ram_miso.rdval                          <= ram_out_rd_val;
+      nxt_cycle_cnt                           <= cycle_cnt +1;
+    END IF;
+  END PROCESS;
+  
+  
+      
+
+END rtl;
diff --git a/libraries/dsp/st/src/vhdl/st_histogram_8_april.vhd b/libraries/dsp/st/src/vhdl/st_histogram_8_april.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..965564ea25c13c9cf8c3ca7feaf62bd5c7b1593b
--- /dev/null
+++ b/libraries/dsp/st/src/vhdl/st_histogram_8_april.vhd
@@ -0,0 +1,399 @@
+
+-- Daniel's suggested restructured st_hitogram.vhd.
+
+LIBRARY IEEE, common_lib, mm_lib, technology_lib, dp_lib;
+USE IEEE.std_logic_1164.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
+USE dp_lib.dp_stream_pkg.ALL;
+USE technology_lib.technology_select_pkg.ALL;
+
+ENTITY st_histogram_8_april IS
+  GENERIC (
+    g_in_data_w     : NATURAL := 14;   -- >= 9 when g_nof_bins is 512; (max. c_dp_stream_data_w =768)         <-- maybe just g_data_w ??
+    g_nof_bins      : NATURAL := 512;  -- is a power of 2 and g_nof_bins <= c_data_span; max. 512
+    g_nof_data      : NATURAL         
+  );                
+  PORT (            
+    dp_rst   : IN  STD_LOGIC;
+    dp_clk   : IN  STD_LOGIC;
+                    
+    -- Streaming    
+    snk_in   : IN  t_dp_sosi;
+    
+    -- DP clocked memory bus
+    ram_mosi : IN  t_mem_mosi;
+    ram_miso : OUT t_mem_miso 
+  );
+END st_histogram_8_april;
+
+
+ARCHITECTURE rtl OF st_histogram_8_april IS
+
+  CONSTANT c_adr_w : NATURAL := ceil_log2(g_nof_bins);
+  CONSTANT c_ram   : t_c_mem := (latency  => 1,
+                                 adr_w    => c_adr_w,          -- 9 bits needed to adress/select 512 adresses
+                                 dat_w    => c_word_w,         -- 32bit, def. in common_pkg; >= c_bin_w
+                                 nof_dat  => g_nof_bins,       -- 512 adresses with 32 bit words, so 512
+                                 init_sl  => '0');             -- MM side : sla_in, sla_out
+                                 
+--  CONSTANT c_mem_miso_setting     : t_mem_miso := (rddata => mem_miso_init,  -- c_mem_miso_rst; -- limit to 32 bit 
+--                                                   rdval => '0',
+--                                                   waitrequest => '0' );
+
+  CONSTANT c_adr_low_calc : INTEGER  := g_in_data_w-c_adr_w;          -- Calculation might yield a negative number
+  CONSTANT c_adr_low      : NATURAL  := largest(0, c_adr_low_calc);   -- Override any negative value of c_adr_low_calc
+  
+--  SIGNAL mem_miso_init    : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0) := (OTHERS => '0');
+
+  SIGNAL bin_reader_mosi          : t_mem_mosi := c_mem_mosi_rst;
+
+  SIGNAL nxt_bin_writer_mosi      : t_mem_mosi;
+  SIGNAL bin_writer_mosi          : t_mem_mosi;
+
+  SIGNAL nxt_bin_arbiter_wr_mosi  : t_mem_mosi;
+  SIGNAL bin_arbiter_wr_mosi      : t_mem_mosi;
+
+  SIGNAL nxt_bin_arbiter_rd_mosi  : t_mem_mosi;
+  SIGNAL bin_arbiter_rd_mosi      : t_mem_mosi;
+
+  SIGNAL common_ram_r_w_0_miso    : t_mem_miso := c_mem_miso_rst;
+  
+  SIGNAL init_phase           : STD_LOGIC := '1';
+  SIGNAL rd_cnt_allowed       : STD_LOGIC := '0';
+  SIGNAL rd_cnt_allowed_pp    : STD_LOGIC := '0';
+  SIGNAL nxt_rd_adr_cnt       : NATURAL := 0;
+  SIGNAL rd_adr_cnt           : NATURAL;-- := 0;
+  SIGNAL toggle_detect        : STD_LOGIC := '0';
+  SIGNAL toggle_detect_pp     : STD_LOGIC;
+  SIGNAL toggle_detect_false  : STD_LOGIC := '1';
+--  SIGNAL nxt_toggle_adr_cnt : NATURAL := 0;
+--  SIGNAL toggle_adr_cnt     : NATURAL;-- := 0;
+  SIGNAL nxt_prev_wrdata      : NATURAL;
+  SIGNAL prev_wrdata          : NATURAL;
+  SIGNAL prev_prev_wrdata     : NATURAL;
+  SIGNAL prev_prev_prev_wrdata: NATURAL;
+  SIGNAL sync_detect          : STD_LOGIC := '0';
+  SIGNAL sync_detect_pp       : STD_LOGIC;
+--  SIGNAL adr_w             : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO c_adr_low);
+  SIGNAL same_r_w_address     : STD_LOGIC;
+  SIGNAL same_r_w_address_pp  : STD_LOGIC;
+  
+  --pipelined signals
+  SIGNAL dp_pipeline_src_out_p    : t_dp_sosi;
+  SIGNAL dp_pipeline_src_out_pp   : t_dp_sosi;
+  SIGNAL prev_bin_reader_mosi     : t_mem_mosi := c_mem_mosi_rst ;
+  SIGNAL bin_reader_mosi_pp       : t_mem_mosi := c_mem_mosi_rst;
+  SIGNAL bin_reader_mosi_ppp      : t_mem_mosi := c_mem_mosi_rst;
+  
+  --debug signals
+--  SIGNAL nxt_dbg_sync_detect : STD_LOGIC;
+--  SIGNAL dbg_sync_detect     : STD_LOGIC;
+  SIGNAL dbg_state_string    : STRING(1 TO 3) := "   ";
+  SIGNAL dbg_snk_data        : STD_LOGIC_VECTOR(g_in_data_w-1 DOWNTO 0);
+
+  
+BEGIN 
+
+  -----------------------------------------------------------------------------
+  -- Bin reader: Convert snk_in data to bin_reader_mosi with read request
+  -- . in  : snk_in          (latency: 0)
+  -- . out : bin_reader_mosi (latency: 0)
+  -- . out : bin_reader_mosi_pp (latency: 2)
+  -- - out : rd_cnt_allowed_pp  (latency: 2)
+  -----------------------------------------------------------------------------
+  bin_reader_mosi.rd                          <= snk_in.valid; -- when 1, count allowed
+  bin_reader_mosi.address(c_adr_w-1 DOWNTO 0) <= snk_in.data(g_in_data_w-1 DOWNTO c_adr_low); 
+  
+  --snk_in pipeline
+  u_dp_pipeline_snk_in_1_cycle : ENTITY dp_lib.dp_pipeline
+  GENERIC MAP (
+    g_pipeline   => 1  -- 0 for wires, > 0 for registers, 
+  )
+  PORT MAP (
+    rst          => dp_rst,
+    clk          => dp_clk,
+    snk_in       => snk_in,
+    src_out      => dp_pipeline_src_out_p
+  );
+  
+  init_phase <= '0' WHEN dp_pipeline_src_out_p.sync = '1';
+  
+  u_dp_pipeline_snk_in_2_cycle : ENTITY dp_lib.dp_pipeline
+  GENERIC MAP (
+    g_pipeline   => 2  -- 0 for wires, > 0 for registers, 
+  )
+  PORT MAP (
+    rst          => dp_rst,
+    clk          => dp_clk,
+    snk_in       => snk_in,
+    src_out      => dp_pipeline_src_out_pp
+  );
+  
+  dbg_snk_data <= dp_pipeline_src_out_pp.data(g_in_data_w-1 DOWNTO 0);
+  
+  toggle_detect_false <= '0' WHEN dp_pipeline_src_out_pp.sync = '1';
+  sync_detect <= snk_in.valid WHEN (snk_in.sync='1' OR dp_pipeline_src_out_p.sync='1' OR dp_pipeline_src_out_pp.sync='1') ELSE '0';
+  
+--  u_dp_sync_detect_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       => sync_detect,
+--    src_out      => sync_detect_ppp
+--  );
+  
+  u_common_pipeline_sl_sync_detect_2_cycle : ENTITY common_lib.common_pipeline_sl
+  GENERIC MAP(
+    g_pipeline       => 2 -- 0 for wires, > 0 for registers, 
+  )
+  PORT MAP (
+    clk     => dp_clk,
+    in_dat  => sync_detect,
+    out_dat => sync_detect_pp
+  );
+  
+  --prev_bin_reader_mosi pipeline
+--  u_dp_pipeline_bin_reader_mosi_1_cycle : ENTITY dp_lib.dp_pipeline
+--  GENERIC MAP (
+--    g_pipeline   => 1  -- 0 for wires, > 0 for registers, 
+--  )
+--  PORT MAP (
+--    rst          => dp_rst,
+--    clk          => dp_clk,
+--    snk_in       => bin_reader_mosi,
+--    src_out      => prev_bin_reader_mosi
+--  );
+
+ 
+  u_common_pipeline_bin_reader_mosi_1_cycle : ENTITY common_lib.common_pipeline
+  GENERIC MAP (
+    g_representation => "UNSIGNED", --orig. signed
+    g_pipeline       => 1,
+    g_in_dat_w       => c_adr_w, -- c_mem_address_w
+    g_out_dat_w      => c_adr_w
+  )
+  PORT MAP (
+    clk     => dp_clk,
+    clken   => bin_reader_mosi.rd, -- '1',
+    in_dat  => STD_LOGIC_VECTOR(bin_reader_mosi.address(c_adr_w-1 DOWNTO 0)),
+    out_dat => prev_bin_reader_mosi.address(c_adr_w-1 DOWNTO 0)
+  );
+  
+  u_common_pipeline_bin_reader_mosi_2_cycle : ENTITY common_lib.common_pipeline  -- better to pipeline prev_bin_reader_mosi??
+  GENERIC MAP (
+    g_representation => "UNSIGNED", --orig. signed
+    g_pipeline       => 1,
+    g_in_dat_w       => c_adr_w,
+    g_out_dat_w      => c_adr_w
+  )
+  PORT MAP (
+    clk     => dp_clk,
+    in_dat  => STD_LOGIC_VECTOR(prev_bin_reader_mosi.address(c_adr_w-1 DOWNTO 0)),
+    out_dat => bin_reader_mosi_pp.address(c_adr_w-1 DOWNTO 0)
+  );
+  
+  u_common_pipeline_bin_reader_mosi_3_cycle : ENTITY common_lib.common_pipeline  -- better to pipeline prev_bin_reader_mosi??
+  GENERIC MAP (
+    g_representation => "UNSIGNED", --orig. signed
+    g_pipeline       => 2,
+    g_in_dat_w       => c_adr_w,
+    g_out_dat_w      => c_adr_w
+  )
+  PORT MAP (
+    clk     => dp_clk,
+    in_dat  => STD_LOGIC_VECTOR(prev_bin_reader_mosi.address(c_adr_w-1 DOWNTO 0)),
+    out_dat => bin_reader_mosi_ppp.address(c_adr_w-1 DOWNTO 0)
+  );
+  
+  
+  --bin_reader_mosi_pp pipeline
+--  u_dp_pipeline_bin_reader_mosi_2_cycle : ENTITY dp_lib.dp_pipeline
+--  GENERIC MAP (
+--    g_pipeline   => 2  -- 0 for wires, > 0 for registers, 
+--  )
+--  PORT MAP (
+--    rst          => dp_rst,
+--    clk          => dp_clk,
+--    snk_in       => bin_reader_mosi,
+--    src_out      => bin_reader_mosi_pp
+--  );
+  
+--  rd_cnt_allowed <= snk_in.valid WHEN (bin_reader_mosi.address = prev_bin_reader_mosi.address AND init_phase = '0') ELSE '0'; -- AND snk_in.sync='0'
+  rd_cnt_allowed <= snk_in.valid WHEN ( bin_reader_mosi.address = prev_bin_reader_mosi.address AND ( (dp_pipeline_src_out_p.sync='1' AND dp_pipeline_src_out_p.valid='1') OR (dp_pipeline_src_out_pp.sync='1' AND dp_pipeline_src_out_p.valid='1') ) )
+                                 ELSE snk_in.valid WHEN (bin_reader_mosi.address = prev_bin_reader_mosi.address AND init_phase='0' AND snk_in.sync='0')
+                                 ELSE '0';
+  
+  --rd_cnt_allowed_pp pipeline
+  u_common_pipeline_sl_rd_cnt_allowed : ENTITY common_lib.common_pipeline_sl
+  GENERIC MAP(
+    g_pipeline       => 2 -- 0 for wires, > 0 for registers, 
+  )
+  PORT MAP (
+    clk     => dp_clk,
+    in_dat  => rd_cnt_allowed,
+    out_dat => rd_cnt_allowed_pp
+  );
+  
+  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') ELSE '0'; --AND (snk_in.sync='0' OR dp_pipeline_src_out_p.sync='0')
+  
+  u_common_pipeline_sl_toggle_detect : ENTITY common_lib.common_pipeline_sl
+  GENERIC MAP(
+    g_pipeline       => 2 -- 0 for wires, > 0 for registers, 
+  )
+  PORT MAP (
+    clk     => dp_clk,
+    in_dat  => toggle_detect,
+    out_dat => toggle_detect_pp
+  );
+  
+  same_r_w_address <= snk_in.valid WHEN (bin_reader_mosi.address = bin_reader_mosi_ppp.address AND init_phase = '0' AND sync_detect = '0') ELSE '0';
+  
+  u_common_pipeline_sl_same_r_w_address : ENTITY common_lib.common_pipeline_sl
+  GENERIC MAP(
+    g_pipeline       => 2 -- 0 for wires, > 0 for registers, 
+  )
+  PORT MAP (
+    clk     => dp_clk,
+    in_dat  => same_r_w_address,
+    out_dat => same_r_w_address_pp
+  );
+
+
+  -----------------------------------------------------------------------------
+  -- Bin writer : increments current bin value and sets up write request
+  -- . in  : dp_pipeline_src_out_pp (latency: 2)
+  -- . in  : toggle_detect_pp      (latency: 2)
+  -- . in  : same_r_w_address_pp   (latency: 2)
+  -- . in  : bin_reader_mosi_pp    (latency: 2)
+  -- . in  : common_ram_r_w_0_miso (latency: 2)
+  -- . in  : rd_cnt_allowed_pp     (latency: 2)
+  -- . 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, rd_adr_cnt, init_phase, prev_wrdata, prev_prev_wrdata, sync_detect_pp, same_r_w_address_pp, dp_pipeline_src_out_pp.valid) IS
+  BEGIN
+    nxt_bin_writer_mosi <= c_mem_mosi_rst;
+    dbg_state_string <= "unv";
+    IF common_ram_r_w_0_miso.rdval='1' THEN -- OR rd_cnt_allowed_pp = '1'  -- when not same as last 2 adresses
+      nxt_bin_writer_mosi.wr      <= '1';
+      nxt_bin_writer_mosi.wrdata  <= INCR_UVEC(common_ram_r_w_0_miso.rddata, 1); -- c_word_w); -- depends on count case -- rd_adr_cnt
+      nxt_bin_writer_mosi.address <= bin_reader_mosi_pp.address; --TODO: what other input do we need for this? -- becomes bin_reader_mosi.address
+--      reset count? if toggle detected copy count to toggle counter
+      nxt_prev_wrdata             <= TO_UINT(common_ram_r_w_0_miso.rddata) + 1;
+--      nxt_rd_adr_cnt              <= 0;                                                   -- really necessary ??
+      dbg_state_string <= "val";
+--      IF bin_reader_mosi_pp.address = bin_reader_mosi.address THEN             -- Double implemented ?? toggle?
+--        nxt_toggle_adr_cnt <= INCR_UVEC(common_ram_r_w_0_miso.rddata, 1);      -- Double implemented ??
+    ELSIF toggle_detect_pp = '1' THEN -- dp_pipeline_src_out_pp: 2
+      nxt_bin_writer_mosi.wr      <= '1';
+      nxt_bin_writer_mosi.wrdata  <= TO_UVEC( (prev_prev_wrdata+1), c_mem_data_w); -- prev_wrdata + rd_adr_cnt + toggle_adr_cnt??? + 1  òf prev_prev_wrdata + 1 ??
+      nxt_bin_writer_mosi.address <= bin_reader_mosi_pp.address;
+--      nxt_toggle_adr_cnt          <= 0;
+      nxt_prev_wrdata             <= prev_prev_wrdata+1;
+      dbg_state_string <= "td ";
+      
+    ELSIF rd_cnt_allowed_pp = '1' THEN
+--      nxt_rd_adr_cnt              <= rd_adr_cnt + 1;                                                                                                   -- << !! is rd_adr_cnt really necessary? prev_wrdata might fulfill the need !!
+      nxt_bin_writer_mosi.wr      <= '1';
+--      IF sync_detect_ppp = '1' THEN
+--        nxt_bin_writer_mosi.wrdata <= TO_UVEC( (rd_adr_cnt + 1), c_mem_data_w); -- snk_in.sync (impossible); dp_pipeline_src_out_p (thus 1st cnt): 2 (cnt+1?); dp_pipeline_src_out_pp (1st or maybe 2nd cnt): cnt+1
+--        dbg_state_string <= "rs ";
+--      ELSE 
+        nxt_bin_writer_mosi.wrdata  <= TO_UVEC( (prev_wrdata + rd_adr_cnt + 1), c_mem_data_w); -- c_word_w); -- maybe RAM + cnt + 1 ??  -- only prev_wrdata + 1 necessary
+        nxt_prev_wrdata             <= prev_wrdata + 1;
+        dbg_state_string <= "r# ";
+--      END IF;
+      nxt_bin_writer_mosi.address <= bin_reader_mosi_pp.address;
+      
+    ELSIF sync_detect_pp = '1' THEN -- snk_in.sync at least -- good as it is!
+      nxt_bin_writer_mosi.wr      <= '1';
+      nxt_bin_writer_mosi.wrdata  <= TO_UVEC(1, c_mem_data_w); -- snk_in.sync: 1; dp_pipeline_src_out_p.sync (thus new adress): 1; dp_pipeline_src_out_pp.sync (thus new adress): 1
+      nxt_bin_writer_mosi.address <= bin_reader_mosi_pp.address;
+--      nxt_rd_adr_cnt              <= 0;                             -- really necessary ??
+      nxt_prev_wrdata             <= 1;
+      dbg_state_string  <= "sd ";
+      
+    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);
+      nxt_bin_writer_mosi.address <= bin_reader_mosi_pp.address;
+      nxt_prev_wrdata             <= prev_prev_prev_wrdata + 1;
+      dbg_state_string  <= "srw";
+    END IF;
+  END PROCESS; 
+
+  p_bin_writer_mosi : PROCESS(dp_clk, dp_rst, nxt_bin_writer_mosi, nxt_rd_adr_cnt, nxt_prev_wrdata, prev_wrdata, prev_prev_wrdata) IS
+  BEGIN
+    IF dp_rst = '1' THEN
+       bin_writer_mosi <= c_mem_mosi_rst;
+    ELSIF RISING_EDGE(dp_clk) THEN
+       bin_writer_mosi <= nxt_bin_writer_mosi;
+--       rd_adr_cnt      <= nxt_rd_adr_cnt;
+--       toggle_adr_cnt  <= nxt_toggle_adr_cnt;
+       prev_wrdata     <= nxt_prev_wrdata;
+       prev_prev_wrdata<= prev_wrdata;
+       prev_prev_prev_wrdata <= prev_prev_wrdata;
+    END IF;
+  END PROCESS;
+
+
+  -----------------------------------------------------------------------------
+  -- Bin Arbiter: Determine next RAM access
+  -- . in  : bin_reader_mosi      (latency: 0)
+  --       : init_phase           (latency: 0)
+  --       : prev_bin_reader_mosi (latency: 1)
+  --       : bin_writer_mosi      (latency: 3)
+  -- . out : bin_arbiter_rd_mosi (latency: 1)
+  -- .     : bin_arbiter_wr_mosi (latency: 4)
+  -----------------------------------------------------------------------------
+  nxt_bin_arbiter_wr_mosi <= bin_writer_mosi; --TODO - The rd and wr mosi should not have the same address.          v met 2 cycles rd mag, met 3 cycles niet, dus klopt dit wel?, moet hier niet bin_reader_mosi_pp staan? --AND !(A=B)
+  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';                                                                                       -- bin_writer_mosi(adress 3cycles ago?) .address when .rd='1' ????
+  nxt_bin_arbiter_rd_mosi.address <= bin_reader_mosi.address;
+
+  p_bin_arbiter_mosi : PROCESS(dp_clk, dp_rst, nxt_bin_arbiter_wr_mosi, nxt_bin_arbiter_rd_mosi) IS
+  BEGIN
+    IF dp_rst = '1' THEN
+      bin_arbiter_wr_mosi <= c_mem_mosi_rst;
+      bin_arbiter_rd_mosi <= c_mem_mosi_rst;
+    ELSIF RISING_EDGE(dp_clk) THEN
+      bin_arbiter_wr_mosi <= nxt_bin_arbiter_wr_mosi;
+      bin_arbiter_rd_mosi <= nxt_bin_arbiter_rd_mosi;
+    END IF;
+  END PROCESS;
+
+
+  -----------------------------------------------------------------------------
+  -- RAM that contains the bins
+  -- . in  : bin_arbiter_wr_mosi   (latency: 4)
+  -- . in  : bin_arbiter_rd_mosi   (latency: 1)
+  -- . out : common_ram_r_w_0_miso (latency: 2)
+  -----------------------------------------------------------------------------
+  common_ram_r_w_0: ENTITY common_lib.common_ram_r_w
+  GENERIC MAP (
+    g_technology     => c_tech_select_default,
+    g_ram            => c_ram,
+    g_init_file      => "UNUSED"
+  )
+  PORT MAP (
+    rst      => dp_rst, 
+    clk      => dp_clk,
+    clken    => '1', 
+    wr_en    => bin_arbiter_wr_mosi.wr,
+    wr_adr   => bin_arbiter_wr_mosi.address(c_adr_w-1 DOWNTO 0),
+    wr_dat   => bin_arbiter_wr_mosi.wrdata(c_word_w-1 DOWNTO 0),
+    rd_en    => bin_arbiter_rd_mosi.rd,
+    rd_adr   => bin_arbiter_rd_mosi.address(c_adr_w-1 DOWNTO 0),
+    rd_dat   => common_ram_r_w_0_miso.rddata(c_word_w-1 DOWNTO 0),
+    rd_val   => common_ram_r_w_0_miso.rdval
+  );
+
+
+  
+END rtl;
+
diff --git a/libraries/dsp/st/src/vhdl/st_histogram_reg.vhd b/libraries/dsp/st/src/vhdl/st_histogram_reg.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..98424485a4e1ca3439959fe4098c2b610cf9aa4e
--- /dev/null
+++ b/libraries/dsp/st/src/vhdl/st_histogram_reg.vhd
@@ -0,0 +1,115 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright 2020
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+-- 
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+-- 
+--     http://www.apache.org/licenses/LICENSE-2.0
+-- 
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- 
+-- Author: J.W.E. Oudman
+-- Purpose: Provide MM slave register for st_histogram
+-- Description: 
+--   Because the st_histogram component uses 2 RAM blocks that are swapped
+--   after every sync pulse, both blocks have to work in the dp clock domain
+--   and the Memory Mapped bus coming out of the component consequently also 
+--   works in the dp clock domain. 
+--   
+--   To convert the signals to the mm clock domain the common_reg_cross_domain
+--   component is used. Because the inner workings of that component is 
+--   dependent on some components that take time to reliably stabialize the 
+--   conversion takes 12 mm clock cycles before the next address may be 
+--   requested.
+--
+--
+--   [Alternative: shared dual clocked RAM block]
+--
+--
+-------------------------------------------------------------------------------
+
+LIBRARY IEEE, common_lib, dp_lib;-- mm_lib, technology_lib,
+USE IEEE.std_logic_1164.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
+USE dp_lib.dp_stream_pkg.ALL;
+--USE technology_lib.technology_select_pkg.ALL;
+
+ENTITY st_histogram_reg IS
+--  GENERIC (
+--    g_nof_bins      : NATURAL := 512;  -- is a power of 2 and g_nof_bins <= c_data_span; max. 512
+--    g_str           : STRING  := "freq.density"  -- to select output to MM bus ("frequency" or "freq.density")
+--  );                
+  PORT (            
+    dp_rst          : IN  STD_LOGIC;
+    dp_clk          : IN  STD_LOGIC;
+    mm_rst          : IN  STD_LOGIC;
+    mm_clk          : IN  STD_LOGIC;
+                    
+    -- DP clocked memory bus
+    mas_out_ram_mosi : OUT t_mem_mosi ;--:= c_mem_mosi_rst;  -- Beware, works in dp clock domain !
+    mas_in_ram_miso  : IN  t_mem_miso ;--:= c_mem_miso_rst;  --  ''                              !
+--    ram_st_histogram_mosi : OUT  t_mem_mosi;  -- Beware, works in dp clock domain !
+--    ram_st_histogram_miso : IN t_mem_miso;    --  ''                              !
+
+    -- Memory Mapped
+    ram_mosi : IN  t_mem_mosi;
+    ram_miso : OUT t_mem_miso
+  );
+END st_histogram_reg;
+
+ARCHITECTURE str OF st_histogram_reg IS
+  
+--  CONSTANT c_mm_reg : t_c_mem := (latency  => 1,
+--                                  adr_w    => 1,
+--                                  dat_w    => c_word_w,
+--                                  nof_dat  => 1,
+--                                  init_sl  => g_default_value);
+
+  
+BEGIN 
+  
+
+  u_common_reg_cross_domain_mosi_address : ENTITY common_lib.common_reg_cross_domain
+  PORT MAP (
+    in_rst     => mm_rst,
+    in_clk     => mm_clk,
+    
+    in_new     => ram_mosi.rd,
+    in_dat     => ram_mosi.address,
+
+    out_rst    => dp_rst,
+    out_clk    => dp_clk,
+
+    out_dat    => mas_out_ram_mosi.address,
+    out_new    => mas_out_ram_mosi.rd
+  );
+  
+  u_reg_cross_domain_miso_rddata : ENTITY common_lib.common_reg_cross_domain
+  PORT MAP (
+    in_rst     => dp_rst,
+    in_clk     => dp_clk,
+    
+    in_new     => mas_in_ram_miso.rdval,
+    in_dat     => mas_in_ram_miso.rddata,
+
+    out_rst    => mm_rst,
+    out_clk    => mm_clk,
+
+    out_dat    => ram_miso.rddata,
+    out_new    => ram_miso.rdval
+  );
+  
+END str;
diff --git a/libraries/dsp/st/tb/vhdl/tb_mms_st_histogram.vhd b/libraries/dsp/st/tb/vhdl/tb_mms_st_histogram.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..8c74592e65fa4a7776fe01c12e73c17808437444
--- /dev/null
+++ b/libraries/dsp/st/tb/vhdl/tb_mms_st_histogram.vhd
@@ -0,0 +1,302 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright 2020
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+-- 
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+-- 
+--     http://www.apache.org/licenses/LICENSE-2.0
+-- 
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- 
+-- Author: J.W.E. Oudman
+-- Purpose: Create a histogram from the input data and present it to the MM bus
+-- Description: 
+--  
+--
+--
+-------------------------------------------------------------------------------
+
+LIBRARY IEEE, common_lib, mm_lib, dp_lib;
+USE IEEE.std_logic_1164.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.tb_common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
+USE common_lib.tb_common_mem_pkg.ALL; 
+USE dp_lib.dp_stream_pkg.ALL;
+
+ENTITY tb_mms_st_histogram IS
+  GENERIC(
+    g_sync_length          : NATURAL := 338;
+    g_nof_sync             : NATURAL := 3;
+    g_data_w               : NATURAL := 4;
+    g_nof_bins             : NATURAL := 8;
+    g_nof_data             : NATURAL := 338;
+    g_str                  : STRING  := "freq.density";
+    g_valid_gap            : BOOLEAN := FALSE;
+    g_snk_in_data_sim_type : STRING  := "counter"  -- "counter" or "toggle"
+    );
+END tb_mms_st_histogram;
+
+
+ARCHITECTURE tb OF tb_mms_st_histogram IS
+  
+  CONSTANT c_adr_w              : NATURAL  := ceil_log2(g_nof_bins);
+  
+  CONSTANT c_mm_init_time       : NATURAL   := 5;
+  CONSTANT c_dp_inti_time       : NATURAL   := 5;
+  
+  SIGNAL tb_end                 : STD_LOGIC := '0';
+  SIGNAL first_sync             : STD_LOGIC := '0';
+
+  ----------------------------------------------------------------------------
+  -- Clocks and resets
+  ----------------------------------------------------------------------------   
+  CONSTANT c_mm_clk_period      : TIME := 20 ns;
+  CONSTANT c_dp_clk_period      : TIME := 5 ns;
+
+
+  SIGNAL mm_rst                 : STD_LOGIC := '1';
+  SIGNAL mm_clk                 : STD_LOGIC := '1';
+
+  SIGNAL dp_rst                 : STD_LOGIC;
+  SIGNAL dp_clk                 : STD_LOGIC := '1';
+  
+  
+  
+  
+  ----------------------------------------------------------------------------
+  -- Streaming Input
+  ----------------------------------------------------------------------------
+  
+  SIGNAL st_histogram_snk_in : t_dp_sosi;
+  
+  ----------------------------------------------------------------------------
+  -- Memory Mapped Input
+  ----------------------------------------------------------------------------
+  
+  SIGNAL st_histogram_ram_mosi : t_mem_mosi;
+  SIGNAL st_histogram_ram_miso : t_mem_miso;
+  
+  
+BEGIN 
+  
+  ----------------------------------------------------------------------------
+  -- Clock and reset generation
+  ----------------------------------------------------------------------------
+  mm_clk <= NOT mm_clk OR tb_end AFTER c_mm_clk_period/2;
+  mm_rst <= '1', '0' AFTER c_mm_clk_period*c_mm_init_time;
+
+  dp_clk <= NOT dp_clk OR tb_end AFTER c_dp_clk_period/2;
+  dp_rst <= '1', '0' AFTER c_dp_clk_period*c_dp_inti_time;
+  
+  
+  
+  
+  ----------------------------------------------------------------------------
+  -- Source: counter stimuli
+  ----------------------------------------------------------------------------
+  
+  p_data : PROCESS(dp_rst, dp_clk, st_histogram_snk_in)
+  BEGIN
+    IF g_snk_in_data_sim_type = "counter" THEN
+      IF dp_rst='1' THEN
+        st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= (OTHERS=>'0');
+      ELSIF rising_edge(dp_clk) AND st_histogram_snk_in.valid='1' THEN
+        st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= INCR_UVEC(st_histogram_snk_in.data(g_data_w-1 DOWNTO 0), 1);
+      END IF;
+    ELSIF g_snk_in_data_sim_type = "toggle" THEN
+      IF dp_rst='1' THEN
+        st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= (OTHERS=>'0');
+      ELSIF rising_edge(dp_clk) AND st_histogram_snk_in.valid='1' THEN
+        IF st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) = TO_UVEC(0, g_data_w) THEN
+          st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= TO_UVEC(1, g_data_w);
+        ELSE
+          st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= TO_UVEC(0, g_data_w);
+        END IF;
+      END IF;
+    END IF;
+  END PROCESS;
+  
+  p_stimuli : PROCESS
+  BEGIN
+    IF g_valid_gap = FALSE THEN
+--      dp_rst <= '1';
+      st_histogram_snk_in.sync <= '0';
+      st_histogram_snk_in.valid <= '0';
+      WAIT UNTIL rising_edge(dp_clk);
+--      FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
+--      dp_rst <= '0';
+      FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
+      st_histogram_snk_in.valid <= '1';
+      
+      
+      FOR I IN 0 TO g_nof_sync-1 LOOP
+        st_histogram_snk_in.sync <= '1';
+        WAIT UNTIL rising_edge(dp_clk);
+        st_histogram_snk_in.sync <= '0';
+        FOR I IN 0 TO g_sync_length-1 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
+        
+      END LOOP;
+      FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
+      tb_end <= '1';
+      WAIT;
+      
+    ELSIF g_valid_gap = TRUE THEN
+--      dp_rst <= '1';
+      st_histogram_snk_in.sync <= '0';
+      st_histogram_snk_in.valid <= '0';
+      WAIT UNTIL rising_edge(dp_clk);
+--      FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
+--      dp_rst <= '0';
+      FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
+      st_histogram_snk_in.valid <= '1';
+      
+      
+      FOR I IN 0 TO g_nof_sync-2 LOOP
+        st_histogram_snk_in.sync <= '1';
+        WAIT UNTIL rising_edge(dp_clk);
+        st_histogram_snk_in.sync <= '0';
+        FOR I IN 0 TO (g_sync_length/2)-1 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
+        st_histogram_snk_in.valid <= '0';
+        WAIT UNTIL rising_edge(dp_clk);
+        --WAIT UNTIL rising_edge(dp_clk);
+        --WAIT UNTIL rising_edge(dp_clk);
+        st_histogram_snk_in.valid <= '1';
+        FOR I IN 0 TO (g_sync_length/4)-1 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
+        st_histogram_snk_in.valid <= '0';
+        WAIT UNTIL rising_edge(dp_clk);
+        --st_histogram_snk_in.valid <= '0';
+        st_histogram_snk_in.sync <= '1';
+        WAIT UNTIL rising_edge(dp_clk);
+        st_histogram_snk_in.valid <= '1';
+        st_histogram_snk_in.sync <= '0';
+        FOR I IN 0 TO (g_sync_length/4)-1 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
+        
+      END LOOP;
+      FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
+      tb_end <= '1';
+      WAIT;
+    END IF;
+  END PROCESS;
+  
+  ----------------------------------------------------------------------------
+  -- Source: read MM bus stimuli
+  ----------------------------------------------------------------------------
+  
+--  p_mm_stimuli : PROCESS --(st_histogram_snk_in.sync)
+--  BEGIN
+--    IF mm_rst='1' THEN
+--      st_histogram_ram_mosi <= c_mem_mosi_rst;  --.address(c_adr_w-1 DOWNTO 0) <= (OTHERS=>'0');
+----    ELSIF rising_edge(mm_clk) THEN --AND st_histogram_snk_in.valid='1'
+--    ELSE
+--      IF first_sync = '0' THEN
+--        WAIT UNTIL st_histogram_snk_in.sync = '1';
+--        first_sync <= '1';
+--        -- wait till one RAM block is written
+--        FOR I IN 0 TO (g_sync_length/4) LOOP WAIT UNTIL rising_edge(mm_clk); END LOOP;
+--        -- wait for some more cycles
+--        FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(mm_clk); END LOOP;
+----      ELSIF rising_edge(mm_clk) THEN
+--      ELSE
+--        FOR I IN 0 TO g_nof_bins-1
+--        -- 
+--        st_histogram_ram_mosi.rd <= '1';
+--        st_histogram_ram_mosi.address(c_adr_w-1 DOWNTO 0) <= INCR_UVEC(st_histogram_ram_mosi.address(c_adr_w-1 DOWNTO 0), 1);
+--      END IF;
+--    END IF;
+--  END PROCESS;
+  
+  p_mm_stimuli : PROCESS --(st_histogram_snk_in.sync)
+  BEGIN
+    --IF mm_rst='1' THEN
+      st_histogram_ram_mosi <= c_mem_mosi_rst;  --.address(c_adr_w-1 DOWNTO 0) <= (OTHERS=>'0');
+--    ELSIF rising_edge(mm_clk) THEN --AND st_histogram_snk_in.valid='1'
+    --ELSE
+      --IF first_sync = '0' THEN
+        WAIT UNTIL st_histogram_snk_in.sync = '1';
+        --first_sync <= '1';
+        -- wait till one RAM block is written
+        FOR I IN 0 TO (g_sync_length/4) LOOP WAIT UNTIL rising_edge(mm_clk); END LOOP;
+        -- wait for some more cycles
+        FOR I IN 0 TO 2 LOOP WAIT UNTIL rising_edge(mm_clk); END LOOP;
+--      ELSIF rising_edge(mm_clk) THEN
+      --ELSE
+        FOR I IN 0 TO g_nof_bins-1 LOOP
+          proc_mem_mm_bus_rd(I, mm_clk, st_histogram_ram_mosi);
+          proc_common_wait_some_cycles(mm_clk, 11);
+          -- miso.rddata arrives
+        END LOOP;
+        -- 
+        --st_histogram_ram_mosi.rd <= '1';
+        --st_histogram_ram_mosi.address(c_adr_w-1 DOWNTO 0) <= INCR_UVEC(st_histogram_ram_mosi.address(c_adr_w-1 DOWNTO 0), 1);
+      --END IF;
+    --END IF;
+  END PROCESS;
+  
+--  -- Read data request to the MM bus
+--  -- Use proc_mem_mm_bus_rd_latency() to wait for the MM MISO rd_data signal
+--  -- to show the data after some read latency
+--  PROCEDURE proc_mem_mm_bus_rd(CONSTANT rd_addr : IN  NATURAL;
+--                               SIGNAL   mm_clk  : IN  STD_LOGIC;
+--                               SIGNAL   mm_miso : IN  t_mem_miso;
+--                               SIGNAL   mm_mosi : OUT t_mem_mosi) IS
+--  BEGIN
+--    mm_mosi.address <= TO_MEM_ADDRESS(rd_addr);
+--    proc_mm_access(mm_clk, mm_miso.waitrequest, mm_mosi.rd);
+--  END proc_mem_mm_bus_rd;
+
+---- Issues a rd or a wr MM access and wait for it to have finished
+--  PROCEDURE proc_mm_access(SIGNAL mm_clk     : IN  STD_LOGIC;
+--                           SIGNAL mm_waitreq : IN  STD_LOGIC;
+--                           SIGNAL mm_access  : OUT STD_LOGIC) IS
+--  BEGIN
+--    mm_access <= '1';
+--    WAIT UNTIL rising_edge(mm_clk);
+--    WHILE mm_waitreq='1' LOOP
+--      WAIT UNTIL rising_edge(mm_clk);
+--    END LOOP;
+--    mm_access <= '0';
+--  END proc_mm_access;
+
+--    proc_mem_mm_bus_rd(0, mm_clk, mm_mosi);   -- Read nof_early_syncs
+--    proc_common_wait_some_cycles(mm_clk, 1);
+--    mm_nof_early_syncs <= mm_miso.rddata(c_word_w-1 DOWNTO 0);
+  
+  ----------------------------------------------------------------------------
+  -- DUT: Device Under Test
+  ----------------------------------------------------------------------------
+  
+  u_mms_st_histogram : ENTITY work.mms_st_histogram
+  GENERIC MAP(
+    g_in_data_w  => g_data_w,
+    g_nof_bins   => g_nof_bins,
+    g_nof_data   => g_nof_data,
+    g_str        => g_str
+  )
+  PORT MAP (
+    dp_rst       => dp_rst,
+    dp_clk       => dp_clk,
+    mm_rst       => mm_rst,
+    mm_clk       => mm_clk,
+             
+    -- Streaming
+    snk_in       => st_histogram_snk_in,
+  
+    -- Memory Mapped
+    ram_mosi     => st_histogram_ram_mosi,
+    ram_miso     => st_histogram_ram_miso --OPEN
+  );
+  
+END tb;
diff --git a/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd b/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..e997850df3698990fdbd06a4a0badc7598ac386b
--- /dev/null
+++ b/libraries/dsp/st/tb/vhdl/tb_st_histogram.vhd
@@ -0,0 +1,307 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright 2020
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+-- 
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+-- 
+--     http://www.apache.org/licenses/LICENSE-2.0
+-- 
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- 
+-- Author: J.W.E. Oudman
+-- Purpose: Testing the st_histogram component on it's pecularities
+-- Description: 
+--   The st_histogram component is mainly about saving counter data and 
+--   making the saved data available for the MM master. The working of the 
+--   RAM blocks has a big influence on this. That is why the testbench is made
+--   to generate data that can make related problems with that vissible.
+--
+--   To know if there can constantly new data be witten to the RAM blocks 
+--   a simple counter is sufficient.
+--   
+--   Because there is a delay between requesting and writing back of data of 
+--   2 cycles and it is illegal to read and write on the same adres at the 
+--   same time, a special situation can happen where the addresses can toggle
+--   (e.g. 0; 1; 0; 1) which causes incorrect counting. To simulate this the 
+--   g_snk_in_data_sim_type can be set to 'toggle'
+--
+--   Only incoming data while snk_in.valid = '1' may be counted. To keep the
+--   simulation simple there is the option to let there be some gap's in the
+--   valid data (or not) where snk_in.valid = '0' by setting the g_valid_gap 
+--   to TRUE or FALSE.
+--
+-------------------------------------------------------------------------------
+
+LIBRARY IEEE, common_lib, mm_lib, dp_lib;
+USE IEEE.std_logic_1164.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
+USE common_lib.tb_common_pkg.ALL;
+USE dp_lib.dp_stream_pkg.ALL;
+
+ENTITY tb_st_histogram IS
+  GENERIC(
+    g_sync_length          : NATURAL := 200;
+    g_nof_sync             : NATURAL := 3;
+    g_data_w               : NATURAL := 4; --4 ; 1
+    g_nof_bins             : NATURAL := 8; --8 ; 2
+    g_nof_data             : NATURAL := 200;
+    --g_str                  : STRING  := "freq.density";
+    g_valid_gap            : BOOLEAN := TRUE;
+    g_snk_in_data_sim_type : STRING  := "counter"  -- "counter" or "toggle" or "same rw" or "mix"
+    );
+END tb_st_histogram;
+
+
+ARCHITECTURE tb OF tb_st_histogram IS
+  
+  CONSTANT c_adr_w              : NATURAL  := ceil_log2(g_nof_bins);
+  CONSTANT c_adr_low_calc       : INTEGER  := g_data_w-c_adr_w;             -- Calculation might yield a negative number
+  CONSTANT c_adr_low            : NATURAL  := largest(0, c_adr_low_calc);   -- Override any negative value of c_adr_low_calc
+  --SIGNAL position               : INTEGER range g_data_w'RANGE;
+
+  CONSTANT c_dp_inti_time       : NATURAL   := 5;
+  
+  SIGNAL tb_end                 : STD_LOGIC := '0';
+  SIGNAL pre_valid              : STD_LOGIC := '0';
+  SIGNAL prev_unvalid           : STD_LOGIC := '0';
+  SIGNAL init_phase             : STD_LOGIC := '1';
+  SIGNAL toggle_start           : STD_LOGIC := '0';
+  
+  
+  ----------------------------------------------------------------------------
+  -- Same read write test stimuli
+  ----------------------------------------------------------------------------
+  TYPE t_srw_arr IS ARRAY (NATURAL RANGE <>) OF INTEGER;
+  CONSTANT c_srw_arr            : t_srw_arr := (0,0,1,1,0,0,1,2,3, 1, 2, 3, 0, 3, 3, 0, 3);
+                                            --  1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17
+  
+  SIGNAL srw_index_cnt          : NATURAL   := 0;
+  
+  
+  ----------------------------------------------------------------------------
+  -- Clocks and resets
+  ----------------------------------------------------------------------------   
+  CONSTANT c_dp_clk_period      : TIME := 5 ns;
+
+  SIGNAL dp_rst                 : STD_LOGIC;
+  SIGNAL dp_clk                 : STD_LOGIC := '1';
+  
+  
+  
+  
+  ----------------------------------------------------------------------------
+  -- Streaming Input
+  ----------------------------------------------------------------------------
+  
+  SIGNAL st_histogram_snk_in : t_dp_sosi;
+  
+  
+BEGIN 
+  
+  ----------------------------------------------------------------------------
+  -- Clock and reset generation
+  ----------------------------------------------------------------------------
+  dp_clk <= NOT dp_clk OR tb_end AFTER c_dp_clk_period/2;
+  dp_rst <= '1', '0' AFTER c_dp_clk_period*c_dp_inti_time;
+  
+  
+  
+  
+  ----------------------------------------------------------------------------
+  -- Source: stimuli
+  --  st_histogram_snk_in.data    counter or toggle stimuli
+  --                     .valid   with or without gap's in valid stimuli
+  --                     .sync    sync stimuli
+  ---------------------------------------------------------------------------- 
+  
+  init_phase <= '0' WHEN st_histogram_snk_in.sync = '1';
+
+  p_data : PROCESS(dp_rst, dp_clk, st_histogram_snk_in)
+  BEGIN
+    IF g_snk_in_data_sim_type = "counter" THEN
+      IF dp_rst='1' THEN
+        st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= (OTHERS=>'0');
+      ELSIF rising_edge(dp_clk) AND pre_valid='1' THEN -- st_histogram_snk_in.valid='1' THEN  -- maybe needs init_cnt_start = '1' instead?
+        IF prev_unvalid = '0' THEN
+          st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= INCR_UVEC(st_histogram_snk_in.data(g_data_w-1 DOWNTO 0), 1);
+        ELSIF prev_unvalid = '1' THEN
+          st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= INCR_UVEC(st_histogram_snk_in.data(g_data_w-1 DOWNTO 0), -1);
+          prev_unvalid <= '0';
+        END IF;
+      ELSIF rising_edge(dp_clk) AND pre_valid='0' AND init_phase='0' THEN -- st_histogram_snk_in.valid='0' AND init_phase = '0' THEN
+        IF prev_unvalid = '0' THEN
+        st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= INCR_UVEC(st_histogram_snk_in.data(g_data_w-1 DOWNTO 0), 2);
+        prev_unvalid <= '1';
+        END IF;
+      END IF;
+      
+    ELSIF g_snk_in_data_sim_type = "toggle" THEN
+      IF dp_rst='1' THEN
+        st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= (OTHERS=>'0');
+      ELSIF rising_edge(dp_clk) AND st_histogram_snk_in.valid='1' THEN  -- maybe needs init_cnt_start = '1' instead?
+        IF st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) = TO_UVEC(0, g_data_w) THEN  -- c_adr_low
+          st_histogram_snk_in.data(c_adr_low) <= '1'; -- TO_UVEC(1, g_data_w); --g_data_w-1 DOWNTO 0
+        ELSE
+          st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= TO_UVEC(0, g_data_w);
+        END IF;
+      END IF;
+      
+    ELSIF g_snk_in_data_sim_type = "same rw" THEN
+      IF dp_rst='1' THEN
+        st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= (OTHERS=>'0');
+      ELSIF rising_edge(dp_clk) AND pre_valid='1' THEN -- AND init_phase='0'   didn't work
+        st_histogram_snk_in.data(g_data_w-1 DOWNTO c_adr_low) <= TO_UVEC(c_srw_arr(srw_index_cnt), c_adr_w); --placeholder !
+        IF srw_index_cnt = c_srw_arr'LENGTH -1 THEN
+          srw_index_cnt <= 0;
+        ELSE
+          srw_index_cnt <= srw_index_cnt+1;
+        END IF;
+      END IF;
+      
+    ELSIF g_snk_in_data_sim_type = "mix" THEN
+      IF toggle_start = '1' THEN
+        -- toggle part
+          IF dp_rst='1' THEN
+          st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= (OTHERS=>'0');
+        ELSIF rising_edge(dp_clk) AND st_histogram_snk_in.valid='1' THEN  -- maybe needs init_cnt_start = '1' instead?
+          IF st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) = TO_UVEC(0, g_data_w) THEN  -- c_adr_low
+            st_histogram_snk_in.data(c_adr_low) <= '1'; -- TO_UVEC(1, g_data_w); --g_data_w-1 DOWNTO 0
+          ELSE
+            st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= TO_UVEC(0, g_data_w);
+          END IF;
+        END IF;
+        -- end toggle part
+      ELSE
+        -- counter part
+        IF dp_rst='1' THEN
+          st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= (OTHERS=>'0');
+        ELSIF rising_edge(dp_clk) AND pre_valid='1' THEN -- st_histogram_snk_in.valid='1' THEN  -- maybe needs init_cnt_start = '1' instead?
+          IF prev_unvalid = '0' THEN
+            st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= INCR_UVEC(st_histogram_snk_in.data(g_data_w-1 DOWNTO 0), 1);
+          ELSIF prev_unvalid = '1' THEN
+            st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= INCR_UVEC(st_histogram_snk_in.data(g_data_w-1 DOWNTO 0), -1);
+            prev_unvalid <= '0';
+          END IF;
+        ELSIF rising_edge(dp_clk) AND pre_valid='0' AND init_phase='0' THEN -- st_histogram_snk_in.valid='0' AND init_phase = '0' THEN
+          IF prev_unvalid = '0' THEN
+            st_histogram_snk_in.data(g_data_w-1 DOWNTO 0) <= INCR_UVEC(st_histogram_snk_in.data(g_data_w-1 DOWNTO 0), 2);
+            prev_unvalid <= '1';
+          END IF;
+        END IF;
+        -- end counter part
+      END IF;
+    END IF;
+  END PROCESS;
+  
+  
+  p_stimuli : PROCESS
+  BEGIN
+    IF g_valid_gap = FALSE THEN
+    
+      -- initializing
+      st_histogram_snk_in.sync <= '0';
+      st_histogram_snk_in.valid <= '0';
+      WAIT UNTIL rising_edge(dp_clk);
+      FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
+      pre_valid <= '1';
+      st_histogram_snk_in.valid <= '1';
+      -- generating g_nof_sync sync pulses with g_sync_length cycles between
+      FOR I IN 0 TO g_nof_sync-1 LOOP
+        toggle_start <= '1';
+        st_histogram_snk_in.sync <= '1';
+        WAIT UNTIL rising_edge(dp_clk);
+        st_histogram_snk_in.sync <= '0';
+        proc_common_wait_some_cycles(dp_clk, 2);
+        toggle_start <= '0';
+        FOR I IN 0 TO g_sync_length-1 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP; -- -4 ipv -1 ?
+      END LOOP;
+      -- ending
+      FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
+      tb_end <= '1';
+      WAIT;
+      
+    ELSIF g_valid_gap = TRUE THEN
+    
+      -- initializing
+      st_histogram_snk_in.sync <= '0';
+      st_histogram_snk_in.valid <= '0';
+      WAIT UNTIL rising_edge(dp_clk);
+      FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
+      pre_valid <= '1';
+      st_histogram_snk_in.valid <= '1';
+      -- generating g_nof_sync-1 sync pulses with gaps in 'valid'
+      FOR I IN 0 TO g_nof_sync-2 LOOP
+        toggle_start <= '1';
+        st_histogram_snk_in.sync <= '1';
+        WAIT UNTIL rising_edge(dp_clk);
+        st_histogram_snk_in.sync <= '0';
+        proc_common_wait_some_cycles(dp_clk, 2);
+        toggle_start <= '0';
+        FOR I IN 0 TO (g_sync_length/2)-5 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP; -- -5 ipv -2 ?
+        pre_valid <= '0';
+        WAIT UNTIL rising_edge(dp_clk);
+        st_histogram_snk_in.valid <= '0';
+        pre_valid <= '1';                 -- gap 1 clock cycles
+        WAIT UNTIL rising_edge(dp_clk);
+        --WAIT UNTIL rising_edge(dp_clk); -- gap 2 clock cycles
+        --WAIT UNTIL rising_edge(dp_clk); -- gap 3 clock cycles
+        st_histogram_snk_in.valid <= '1';
+        FOR I IN 0 TO (g_sync_length/4)-2 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
+        pre_valid <= '0';
+        WAIT UNTIL rising_edge(dp_clk);
+        st_histogram_snk_in.valid <= '0';
+        WAIT UNTIL rising_edge(dp_clk);
+        --st_histogram_snk_in.valid <= '0'; -- gap while sync
+        st_histogram_snk_in.sync <= '1';
+        pre_valid <= '1';
+        WAIT UNTIL rising_edge(dp_clk);
+        st_histogram_snk_in.valid <= '1';
+        st_histogram_snk_in.sync <= '0';
+        FOR I IN 0 TO (g_sync_length/4)-1 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
+      END LOOP;
+      -- ending
+      FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(dp_clk); END LOOP;
+      tb_end <= '1';
+      WAIT;
+    END IF;
+  END PROCESS;
+  
+  
+  
+  ----------------------------------------------------------------------------
+  -- DUT: Device Under Test
+  ----------------------------------------------------------------------------
+  
+  u_st_histogram : ENTITY work.st_histogram_8_april
+  GENERIC MAP(
+    g_in_data_w  => g_data_w,
+    g_nof_bins   => g_nof_bins,
+    g_nof_data   => g_nof_data
+    --g_str        => g_str
+  )
+  PORT MAP (
+    dp_rst       => dp_rst,
+    dp_clk       => dp_clk,
+             
+    -- Streaming
+    snk_in       => st_histogram_snk_in,
+  
+    -- Memory Mapped
+    ram_mosi     => c_mem_mosi_rst,-- sla_in_
+    ram_miso     => OPEN -- sla_out_
+  );
+  
+END tb;