diff --git a/libraries/base/diag/src/vhdl/mms_diag_rx_seq.vhd b/libraries/base/diag/src/vhdl/mms_diag_rx_seq.vhd
index b7a4d348a96b67a2c5edb97f15717d3196cf00d0..2105fac3e6e27dd307cfa1d86e6fe502989c6e8c 100644
--- a/libraries/base/diag/src/vhdl/mms_diag_rx_seq.vhd
+++ b/libraries/base/diag/src/vhdl/mms_diag_rx_seq.vhd
@@ -1,6 +1,6 @@
  -------------------------------------------------------------------------------
 --
--- Copyright (C) 2010
+-- Copyright (C) 2015
 -- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
 -- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/>
 -- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
@@ -20,106 +20,216 @@
 --
 -------------------------------------------------------------------------------
 
+-- Purpose: Provide MM access via slave register to diag_rx_seq
+-- Description:
+--
+--   Each DP stream has its own diag_rx_seq and its own MM control register.
+--   The MM control registers are accessible via a single MM port thanks to
+--   the common_mem_mux. Each single MM control register is defined as:
+--
+--   31             24 23             16 15              8 7               0  wi
+--  |-----------------|-----------------|-----------------|-----------------|
+--  |                                            select = [1], enable = [0] |  0
+--  |-----------------------------------------------------------------------|
+--  |                                       res_val_n = [1], res_ok_n = [0] |  1
+--  |-----------------------------------------------------------------------|
+--
+-- . Results
+--   When res_val_n = '1' then no valid data is being received. When
+--   res_val_n = '0' then at least two valid data have been received so the
+--   diag_rx_seq can detect whether the subsequent data is ok. When res_ok_n
+--   = '0' then indeed all data that has been received so far is correct.
+--   When res_ok_n = '0' then at least 1 data word was received with errors.
+--   Once res_ok_n goes high it remains high.
+--
+-- . g_data_w and g_seq_dat_w
+--   The DP streaming data field is c_dp_stream_data_w bits wide but only
+--   g_data_w bits are used. The g_seq_dat_w must be >= 1 and <= g_data_w.
+--   If g_seq_dat_w < g_data_w then the data carries replicated copies of 
+--   the g_seq_dat_w. The maximum g_seq_dat_w depends on the pseudo random
+--   data width of the LFSR sequeces in common_lfsr_sequences_pkg and on
+--   whether timing closure can still be achieved for wider g_seq_dat_w.
+--   Thanks to the replication a smaller g_seq_dat_w can be used to provide
+--   CNTR or LFSR data for the DP data. If the higher bits do notmatch the 
+--   sequence in the lower bits, then the rx data is forced to -1, and that
+--   will then be detected and reported by u_diag_rx_seq as a sequence error.
+
+
 LIBRARY IEEE, common_lib, dp_lib;
 USE IEEE.std_logic_1164.ALL;
+USE IEEE.numeric_std.ALL;
 USE common_lib.common_pkg.ALL;
 USE common_lib.common_mem_pkg.ALL;
 USE dp_lib.dp_stream_pkg.ALL;
 
 ENTITY mms_diag_rx_seq IS
   GENERIC (
-    g_nof_diag_inst : NATURAL := 1;
-    g_dat_w         : NATURAL := c_word_w; -- >= 1, test data width
-    g_sim           : BOOLEAN := FALSE
+    g_nof_streams : NATURAL := 1;
+    g_seq_dat_w   : NATURAL := c_word_w;  -- >= 1, test sequence data width
+    g_data_w      : NATURAL := c_word_w   -- >= g_seq_dat_w, user data width
   );
   PORT (
     -- Clocks and reset
-    mm_rst         : IN  STD_LOGIC;
-    mm_clk         : IN  STD_LOGIC;
-    st_clk         : IN  STD_LOGIC;
+    mm_rst         : IN  STD_LOGIC;  -- reset synchronous with mm_clk
+    mm_clk         : IN  STD_LOGIC;  -- MM bus clock
+    dp_rst         : IN  STD_LOGIC;  -- reset synchronous with dp_clk
+    dp_clk         : IN  STD_LOGIC;  -- DP streaming bus clock
 
     -- Memory Mapped Slave
-    mm_sla_in      : IN  t_mem_mosi;  -- master out slave in
-    mm_sla_out     : OUT t_mem_miso;  -- master in slave out
+    reg_mosi       : IN  t_mem_mosi;   -- multiplexed port for g_nof_streams MM control/status registers
+    reg_miso       : OUT t_mem_miso;
 
     -- Streaming interface
-    rx_snk_in      : IN t_dp_sosi_arr(g_nof_diag_inst-1 DOWNTO 0)  -- source out sink in
+    rx_snk_in_arr  : IN t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0)
   );
 END mms_diag_rx_seq;
 
 
 ARCHITECTURE str OF mms_diag_rx_seq IS
 
-  CONSTANT c_latency     : NATURAL := 1; -- read latency
-  CONSTANT c_init_sl     : STD_LOGIC := '0';  -- optional, init all dat words to std_logic '0', '1' or 'X'
-  CONSTANT c_init_reg    : STD_LOGIC_VECTOR(c_mem_reg_init_w-1 DOWNTO 0) := (OTHERS => '0');
-  CONSTANT c_nof_mm_regs : NATURAL := 4+g_nof_diag_inst;
-  CONSTANT c_mm_addr_w   : NATURAL := ceil_log2(c_nof_mm_regs);
-
-  CONSTANT c_mem_rec     : t_c_mem  := (c_latency, c_mm_addr_w, c_word_w, c_nof_mm_regs, c_init_sl);
-
-  SIGNAL out_reg         : STD_LOGIC_VECTOR(c_nof_mm_regs*c_word_w-1 DOWNTO 0);
-  SIGNAL in_reg          : STD_LOGIC_VECTOR(c_nof_mm_regs*c_word_w-1 DOWNTO 0);
-
+  -- Define the actual size of the MM slave register
+  CONSTANT c_mm_reg      : t_c_mem  := (latency  => 1,
+                                        adr_w    => 1,
+                                        dat_w    => c_word_w,       -- Use MM bus data width = c_word_w = 32 for all MM registers
+                                        nof_dat  => 2,
+                                        init_sl  => '0');
+  
+  CONSTANT c_reg_slv_w   : NATURAL := c_mm_reg.nof_dat*c_mm_reg.dat_w;
+  
+  TYPE t_reg_arr  IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(c_reg_slv_w-1 DOWNTO 0);
+  TYPE t_seq_arr  IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(g_seq_dat_w-1 DOWNTO 0);
+  TYPE t_data_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0);
+  
+  -- Registers in dp_clk domain
+  SIGNAL ctrl_reg_arr        : t_reg_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>(OTHERS=>'0'));
+  SIGNAL stat_reg_arr        : t_reg_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>(OTHERS=>'0'));
+  
+  SIGNAL diag_en_arr         : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
+  SIGNAL diag_sel_arr        : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
+  
+  SIGNAL rx_seq_arr          : t_seq_arr(g_nof_streams-1 DOWNTO 0);
+  SIGNAL rx_seq_val_arr      : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
+  SIGNAL rx_data_arr         : t_data_arr(g_nof_streams-1 DOWNTO 0);
+  SIGNAL rx_data_val_arr     : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
+
+  SIGNAL diag_res_arr        : t_seq_arr(g_nof_streams-1 DOWNTO 0);
+  SIGNAL diag_res_val_arr    : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
+  
+  SIGNAL stat_res_ok_n_arr   : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
+  SIGNAL stat_res_val_n_arr  : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
+
+  SIGNAL reg_mosi_arr        : t_mem_mosi_arr(g_nof_streams-1 DOWNTO 0);
+  SIGNAL reg_miso_arr        : t_mem_miso_arr(g_nof_streams-1 DOWNTO 0);
+    
 BEGIN
 
-  gen_g_nof_diag_inst_times: FOR i IN 0 to g_nof_diag_inst-1 GENERATE
+  ASSERT g_data_w >= g_seq_dat_w REPORT "mms_diag_rx_seq: g_data_w < g_seq_dat_w is not allowed." SEVERITY FAILURE;
+  
+  gen_nof_streams: FOR I IN 0 to g_nof_streams-1 GENERATE
+  
+    -- no unreplicate needed
+    gen_one : IF g_data_w = g_seq_dat_w GENERATE
+      rx_seq_arr(I)     <= rx_snk_in_arr(i).data(g_seq_dat_w-1 DOWNTO 0);
+      rx_seq_val_arr(I) <= rx_snk_in_arr(i).valid;
+    END GENERATE;
+    
+    -- unreplicate needed
+    gen_unreplicate : IF g_data_w > g_seq_dat_w GENERATE
+      -- keep sequence in low bits and set high bits to '1' if they mismatch the corresponding bit in the sequence
+      rx_data_arr(I)     <= UNREPLICATE_DP_DATA(rx_snk_in_arr(i).data(g_data_w-1 DOWNTO 0), g_seq_dat_w);
+      rx_data_val_arr(I) <=                     rx_snk_in_arr(i).valid;
+      
+      -- keep sequence in low bits if the high bits match otherwise force low bits value to -1 to indicate the mismatch
+      p_rx_seq : PROCESS(dp_clk)
+      BEGIN
+        IF rising_edge(dp_clk) THEN  -- register to ease timing closure
+          IF UNSIGNED(rx_data_arr(I)(g_data_w-1 DOWNTO g_seq_dat_w))=0 THEN
+            rx_seq_arr(I) <= rx_data_arr(I)(g_seq_dat_w-1 DOWNTO 0);
+          ELSE
+            rx_seq_arr(I) <= TO_SVEC(-1, g_seq_dat_w);
+          END IF;
+          rx_seq_val_arr(I) <= rx_data_val_arr(I);
+        END IF;
+      END PROCESS;
+    END GENERATE;
+      
+    -- detect rx sequence errors
     u_diag_rx_seq: ENTITY WORK.diag_rx_seq
-      GENERIC MAP (
-        g_dat_w           => g_dat_w,
-        g_diag_res_w      => c_word_w+1
-      )
-      PORT MAP (
-        rst               => mm_rst,
-        clk               => st_clk,
-
-        -- Write and read back registers:
-        diag_en           => out_reg(           i), -- 0 to 31   (for 12 instances: 11 downto 0 used)
-        diag_sel          => out_reg(  c_word_w+i), -- 32 to 63  (for 12 instances: 43 downto 32 used)
-
-        -- Read only registers:
-        orv(diag_res)     => in_reg(2*c_word_w+i), -- 64 to 95   (for 12 instances: 75 downto 64 used)
-        diag_res_val      => in_reg(3*c_word_w+i), -- 96 to 127  (for 12 instances: 107 downto 96 used)
-
-        -- Streaming
-        in_dat            => rx_snk_in(i).data(c_word_w-1 DOWNTO 0),
-        in_val            => rx_snk_in(i).valid
-      );
-
-      -- Read-only registers for received data, starting from offset 4:
-      in_reg ( (4+i)*c_word_w+c_word_w-1 DOWNTO (4+i)*c_word_w) <= rx_snk_in(i).data(c_word_w-1 DOWNTO 0);
+    GENERIC MAP (
+      g_dat_w           => g_seq_dat_w,
+      g_diag_res_w      => g_seq_dat_w  -- do not use g_seq_dat_w+1 to include NOT diag_res_val in MSbit, instead use diag_res_val output
+    )
+    PORT MAP (
+      rst               => dp_rst,
+      clk               => dp_clk,
 
-  END GENERATE;
+      -- Write and read back registers:
+      diag_en           => diag_en_arr(I),
+      diag_sel          => diag_sel_arr(I),
+
+      -- Read only registers:
+      diag_res          => diag_res_arr(I),
+      diag_res_val      => diag_res_val_arr(I),
 
-  u_common_reg_r_w : ENTITY common_lib.common_reg_r_w
-    GENERIC MAP(
-      g_reg       => c_mem_rec,
-      g_init_reg  => c_init_reg
+      -- Streaming
+      in_dat            => rx_seq_arr(I),
+      in_val            => rx_seq_val_arr(I)
+    );
+    
+    -- Map diag_res to single bit and register it to ease timing closure
+    stat_res_ok_n_arr(I)  <= orv(diag_res_arr(I))    WHEN rising_edge(dp_clk);
+    stat_res_val_n_arr(I) <= NOT diag_res_val_arr(I) WHEN rising_edge(dp_clk);
+    
+    -- Register mapping
+    -- . write ctrl_reg_arr
+    diag_en_arr(I)   <= ctrl_reg_arr(I)(0);  -- address 0, data bit [0]
+    diag_sel_arr(I)  <= ctrl_reg_arr(I)(1);  -- address 0, data bit [1]
+                                             -- address 1, not used for control
+    -- . read stat_reg_arr
+    p_stat_reg_arr : PROCESS(ctrl_reg_arr, stat_res_ok_n_arr, stat_res_val_n_arr)
+    BEGIN
+      -- Default write / readback:
+      stat_reg_arr(I) <= ctrl_reg_arr(I);                    -- address 0, control read back
+      -- Status read only:
+      stat_reg_arr(I)(0+c_word_w) <= stat_res_ok_n_arr(I);   -- address 1, data bit [0]
+      stat_reg_arr(I)(1+c_word_w) <= stat_res_val_n_arr(I);  -- address 1, data bit [1]
+    END PROCESS;
+    
+    u_reg : ENTITY common_lib.common_reg_r_w_dc
+    GENERIC MAP (
+      g_cross_clock_domain => TRUE,
+      g_readback           => FALSE,  -- using FALSE fits for write/read or read only register
+      g_reg                => c_mm_reg
     )
-    PORT MAP(
-      rst             => mm_rst,
-      clk             => mm_clk,
-      clken           => '1',
-      -- control side
-      wr_en           => mm_sla_in.wr,
-      wr_adr          => mm_sla_in.address(c_mem_rec.adr_w-1 DOWNTO 0),
-      wr_dat          => mm_sla_in.wrdata(c_mem_rec.dat_w-1 DOWNTO 0),
-      rd_en           => mm_sla_in.rd,
-      rd_adr          => mm_sla_in.address(c_mem_rec.adr_w-1 DOWNTO 0),
-      rd_dat          => mm_sla_out.rddata(c_mem_rec.dat_w-1 DOWNTO 0),
-      rd_val          => OPEN,
-      -- data side
-      out_reg         => out_reg,
-      in_reg          => in_reg
+    PORT MAP (
+      -- Clocks and reset
+      mm_rst      => mm_rst,
+      mm_clk      => mm_clk,
+      st_rst      => dp_rst,
+      st_clk      => dp_clk,
+      
+      -- Memory Mapped Slave in mm_clk domain
+      sla_in      => reg_mosi_arr(I),
+      sla_out     => reg_miso_arr(I),
+      
+      -- MM registers in dp_clk domain
+      in_reg      => stat_reg_arr(I),
+      out_reg     => ctrl_reg_arr(I)
     );
- 
-  --Connect out_reg to in_reg for write and readback register:
-  in_reg(63 downto 0) <= out_reg(63 downto 0);
-
-  --Connect unused bits to hard zeroes, otherwise SOPC-builder generated cpu0-test benches will halt
-  in_reg(3*c_word_w-1 DOWNTO 2*c_word_w + g_nof_diag_inst) <= (OTHERS => '0'); --Unused bits in register diag_res
-  in_reg(4*c_word_w-1 DOWNTO 3*c_word_w + g_nof_diag_inst) <= (OTHERS => '0'); --Unused bits in register diag_res_val
- 
+  END GENERATE;
+
+  -- Combine the internal array of mm interfaces for the bg_data to one array that is connected to the port of the MM bus
+  u_mem_mux : ENTITY common_lib.common_mem_mux
+  GENERIC MAP (    
+    g_nof_mosi    => g_nof_streams,
+    g_mult_addr_w => c_mm_reg.adr_w
+  )
+  PORT MAP (
+    mosi     => reg_mosi,
+    miso     => reg_miso,
+    mosi_arr => reg_mosi_arr,
+    miso_arr => reg_miso_arr
+  );
 
 END str;
 
diff --git a/libraries/base/diag/src/vhdl/mms_diag_tx_seq.vhd b/libraries/base/diag/src/vhdl/mms_diag_tx_seq.vhd
index 766955d7d15c60f37a2b026de4fa3c0aff785091..f36ac1e53b28cd14d48e1d8eff2b6a5596871546 100644
--- a/libraries/base/diag/src/vhdl/mms_diag_tx_seq.vhd
+++ b/libraries/base/diag/src/vhdl/mms_diag_tx_seq.vhd
@@ -1,6 +1,6 @@
  -------------------------------------------------------------------------------
 --
--- Copyright (C) 2010
+-- Copyright (C) 2015
 -- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
 -- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/>
 -- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
@@ -20,6 +20,35 @@
 --
 -------------------------------------------------------------------------------
 
+-- Purpose: Provide MM access via slave register to diag_tx_seq
+-- Description:
+--
+--   Each DP stream has its own diag_tx_seq, because each stream can have its
+--   own flow control.
+--
+--   One MM control register sets all g_nof_streams:
+--
+--   31             24 23             16 15              8 7               0  wi
+--  |-----------------|-----------------|-----------------|-----------------|
+--  |                                            select = [1], enable = [0] |  0
+--  |-----------------------------------------------------------------------|
+--  |                                   init[31: 0]                         |  1
+--  |-----------------------------------------------------------------------|
+--
+-- . g_seq_dat_w
+--   The g_seq_dat_w must be >= 1. The DP streaming data field is
+--   c_dp_stream_data_w bits wide and the REPLICATE_DP_DATA() is used to wire
+--   the g_seq_dat_w from the u_diag_tx_seq to fill the entire DP data width.
+--   The maximum g_seq_dat_w depends on the pseudo random data width of the
+--   LFSR sequeces in common_lfsr_sequences_pkg and on whether timing closure
+--   can still be achieved for wider g_seq_dat_w. Thanks to the replication a
+--   smaller g_seq_dat_w can be used to provide CNTR or LFSR data for the DP
+--   data.
+--
+-- . diag_init
+--   Note that MM diag_init has c_word_w=32 bits, so if g_seq_dat_w is wider
+--   then the MSbits are 0 and if it is smaller, then the MSbits are ignored.
+
 LIBRARY IEEE, common_lib, dp_lib;
 USE IEEE.std_logic_1164.ALL;
 USE common_lib.common_pkg.ALL; 
@@ -28,92 +57,114 @@ USE dp_lib.dp_stream_pkg.ALL;
 
 ENTITY mms_diag_tx_seq IS
   GENERIC (
-    g_nof_diag_inst : NATURAL := 1;
-    g_dat_w         : NATURAL := c_word_w; -- >= 1, test data width
-    g_sim           : BOOLEAN := FALSE
+    g_nof_streams : NATURAL := 1;
+    g_seq_dat_w   : NATURAL := c_word_w  -- >= 1, test sequence data width
   );
   PORT (
     -- Clocks and reset
-    mm_rst         : IN  STD_LOGIC;
-    mm_clk         : IN  STD_LOGIC;
-    st_clk         : IN  STD_LOGIC; 
-
-    -- Memory Mapped Slave
-    mm_sla_in      : IN  t_mem_mosi;  -- master out slave in
-    mm_sla_out     : OUT t_mem_miso;  -- master in slave out
-
-    -- Streaming interface
-    tx_src_out     : OUT t_dp_sosi_arr(g_nof_diag_inst-1 DOWNTO 0);  -- source out sink in
-    tx_src_in      : IN  t_dp_siso_arr(g_nof_diag_inst-1 DOWNTO 0)  -- source in sink out
+    mm_rst         : IN  STD_LOGIC;  -- reset synchronous with mm_clk
+    mm_clk         : IN  STD_LOGIC;  -- MM bus clock
+    dp_rst         : IN  STD_LOGIC;  -- reset synchronous with dp_clk
+    dp_clk         : IN  STD_LOGIC;  -- DP streaming bus clock
+
+    -- MM interface
+    reg_mosi       : IN  t_mem_mosi;   -- single MM control register applied to all g_nof_streams
+    reg_miso       : OUT t_mem_miso;
+
+    -- DP streaming interface
+    tx_src_out_arr : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
+    tx_src_in_arr  : IN  t_dp_siso_arr(g_nof_streams-1 DOWNTO 0)
   );
 END mms_diag_tx_seq;
 
 
 ARCHITECTURE str OF mms_diag_tx_seq IS    
   
-  CONSTANT c_latency     : NATURAL := 1; -- read latency
-  CONSTANT c_init_sl     : STD_LOGIC := '0';  -- optional, init all dat words to std_logic '0', '1' or 'X'
-  CONSTANT c_init_reg    : STD_LOGIC_VECTOR(c_mem_reg_init_w-1 DOWNTO 0) := (OTHERS => '0');
-  CONSTANT c_nof_mm_regs : NATURAL := 2+g_nof_diag_inst;
-  CONSTANT c_mm_addr_w   : NATURAL := ceil_log2(c_nof_mm_regs);
+  -- Define the actual size of the MM slave register
+  CONSTANT c_mm_reg      : t_c_mem  := (latency  => 1,
+                                        adr_w    => 1,
+                                        dat_w    => c_word_w,       -- Use MM bus data width = c_word_w = 32 for all MM registers
+                                        nof_dat  => 2,
+                                        init_sl  => '0');
+
+  TYPE t_dat_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(g_seq_dat_w-1 DOWNTO 0);
+  TYPE t_replicate_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(c_dp_stream_data_w-1 DOWNTO 0);
   
-  CONSTANT c_mem_rec     : t_c_mem  := (c_latency, c_mm_addr_w, c_word_w, c_nof_mm_regs, c_init_sl);
-
-  SIGNAL out_reg         : STD_LOGIC_VECTOR(c_nof_mm_regs*c_word_w-1 DOWNTO 0);
-  SIGNAL in_reg          : STD_LOGIC_VECTOR(c_nof_mm_regs*c_word_w-1 DOWNTO 0);
+  -- Registers in dp_clk domain
+  SIGNAL ctrl_reg       : STD_LOGIC_VECTOR(c_mm_reg.nof_dat*c_mm_reg.dat_w-1 DOWNTO 0) := (OTHERS=>'0');
+  
+  SIGNAL diag_en        : STD_LOGIC;
+  SIGNAL diag_sel       : STD_LOGIC;
+  SIGNAL diag_init_mm   : STD_LOGIC_VECTOR(c_mm_reg.dat_w-1 DOWNTO 0) := (OTHERS=>'0');
+  SIGNAL diag_init      : STD_LOGIC_VECTOR(g_seq_dat_w-1 DOWNTO 0) := (OTHERS=>'0');
+  
+  SIGNAL tx_dat_arr     : t_dat_arr(g_nof_streams-1 DOWNTO 0);
+  SIGNAL tx_val_arr     : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
+  SIGNAL tx_req_arr     : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
 
+  SIGNAL tx_replicate_arr  : t_replicate_arr(g_nof_streams-1 DOWNTO 0);
+  
 BEGIN
 
-  gen_g_nof_diag_inst_times: FOR i IN 0 to g_nof_diag_inst-1 GENERATE
+  gen_nof_streams: FOR I IN 0 to g_nof_streams-1 GENERATE
     u_diag_tx_seq: ENTITY WORK.diag_tx_seq
-      GENERIC MAP (
-        g_dat_w    => g_dat_w
-      )
-      PORT MAP (
-        rst      => mm_rst,
-        clk      => st_clk,
-
-        -- Write and read back registers:
-        diag_en  => out_reg(           i), -- 0 to 31
-        diag_sel => out_reg(  c_word_w+i), -- 32 to 63
-        diag_dat => out_reg(3*c_word_w+i*c_word_w-1 DOWNTO 2*c_word_w+i*c_word_w), -- downto 64
-
-        -- Streaming
-        diag_req => tx_src_in(i).ready,
-        out_dat  => tx_src_out(i).data(c_word_w-1 DOWNTO 0),
-        out_val  => tx_src_out(i).valid
-      );
-    END GENERATE;
-
-  u_common_reg_r_w : ENTITY common_lib.common_reg_r_w 
-    GENERIC MAP(
-      g_reg       => c_mem_rec,
-      g_init_reg  => c_init_reg
+    GENERIC MAP (
+      g_dat_w    => g_seq_dat_w
     )
-    PORT MAP(
-      rst             => mm_rst,
-      clk             => mm_clk,
-      clken           => '1',
-      -- control side
-      wr_en           => mm_sla_in.wr,
-      wr_adr          => mm_sla_in.address(c_mem_rec.adr_w-1 DOWNTO 0),
-      wr_dat          => mm_sla_in.wrdata(c_mem_rec.dat_w-1 DOWNTO 0),
-      rd_en           => mm_sla_in.rd,
-      rd_adr          => mm_sla_in.address(c_mem_rec.adr_w-1 DOWNTO 0),
-      rd_dat          => mm_sla_out.rddata(c_mem_rec.dat_w-1 DOWNTO 0),
-      rd_val          => OPEN,
-      -- data side    
-      out_reg         => out_reg,
-      in_reg          => in_reg
+    PORT MAP (
+      rst      => dp_rst,
+      clk      => dp_clk,
+
+      -- Write and read back registers:
+      diag_en  => diag_en,
+      diag_sel => diag_sel,
+      diag_dat => diag_init,
+
+      -- Streaming
+      diag_req => tx_req_arr(I),
+      out_dat  => tx_dat_arr(I),
+      out_val  => tx_val_arr(I)
     );
+    
+    tx_req_arr(I) <= tx_src_in_arr(I).ready;
+    
+    
+    tx_replicate_arr(I) <= REPLICATE_DP_DATA(tx_dat_arr(I));
+    
+    -- for some reason the intermediate tx_replicate_arr() signal is needed, otherwise the assignment to the tx_src_out_arr().data field remains void in the Wave window
+    tx_src_out_arr(I).data  <= tx_replicate_arr(I);
+    tx_src_out_arr(I).valid <= tx_val_arr(I);
+  END GENERATE;
+
+  -- Register mapping
+  diag_en      <= ctrl_reg(                           0);  -- address 0, data bit [0]
+  diag_sel     <= ctrl_reg(                           1);  -- address 0, data bit [1]
+  diag_init_mm <= ctrl_reg(2*c_word_w-1 DOWNTO c_word_w);  -- address 1, data bits [31:0]
   
-  --Connect out_reg to in_reg for write and readback register:
-  in_reg(63 downto 0) <= out_reg(63 downto 0);
+  diag_init    <= RESIZE_UVEC(diag_init_mm, g_seq_dat_w);
+
+  u_reg : ENTITY common_lib.common_reg_r_w_dc
+  GENERIC MAP (
+    g_cross_clock_domain => TRUE,
+    g_readback           => TRUE,  -- using TRUE fits for write and readback register
+    g_reg                => c_mm_reg
+  )
+  PORT MAP (
+    -- Clocks and reset
+    mm_rst      => mm_rst,
+    mm_clk      => mm_clk,
+    st_rst      => dp_rst,
+    st_clk      => dp_clk,
+    
+    -- Memory Mapped Slave in mm_clk domain
+    sla_in      => reg_mosi,
+    sla_out     => reg_miso,
+    
+    -- MM registers in dp_clk domain
+    in_reg      => ctrl_reg,  -- connect out_reg to in_reg for write and readback register
+    out_reg     => ctrl_reg
+  );
   
-  --Connect unused bits to hard zeroes, otherwise SOPC-builder generated cpu0-test benches will halt  
-  in_reg((2+g_nof_diag_inst)*c_word_w-1 DOWNTO 2*c_word_w) <= (OTHERS => '0'); --diag_dat
-
- 
 END str;
 
 
diff --git a/libraries/base/diag/tb/vhdl/tb_diag_regression.vhd b/libraries/base/diag/tb/vhdl/tb_diag_regression.vhd
index 36ea670b44e2356de4aa417554614f4cde2551d5..9b225c3c546b4fc5c4739d483b40c82f1cc5eb3b 100644
--- a/libraries/base/diag/tb/vhdl/tb_diag_regression.vhd
+++ b/libraries/base/diag/tb/vhdl/tb_diag_regression.vhd
@@ -41,5 +41,6 @@ BEGIN
 
   u_tb_diag_block_gen             : ENTITY work.tb_diag_block_gen;
   u_tb_mms_diag_block_gen         : ENTITY work.tb_mms_diag_block_gen;
+  u_tb_mms_diag_seq               : ENTITY work.tb_mms_diag_seq;
   
 END tb;
diff --git a/libraries/base/diag/tb/vhdl/tb_mms_diag_seq.vhd b/libraries/base/diag/tb/vhdl/tb_mms_diag_seq.vhd
index 1b53ce598c9bc18b7585a15bef80670c1b95e86f..51388d04a32f07daadaeaa62f2e650058046bf75 100644
--- a/libraries/base/diag/tb/vhdl/tb_mms_diag_seq.vhd
+++ b/libraries/base/diag/tb/vhdl/tb_mms_diag_seq.vhd
@@ -1,6 +1,6 @@
 --------------------------------------------------------------------------------
 --
--- Copyright (C) 2010
+-- Copyright (C) 2015
 -- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
 -- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/>
 -- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
@@ -20,147 +20,394 @@
 --
 --------------------------------------------------------------------------------
 
+-- Purpose: Test bench for mms_diag_tx_seq --> mms_diag_rx_seq
+--   The tb is self-stopping and self-checking.
+-- Usage:
+--   > as 5
+--   > run -all
+
+
 LIBRARY IEEE, common_lib, dp_lib;
 USE IEEE.STD_LOGIC_1164.ALL;    
 USE IEEE.STD_LOGIC_UNSIGNED.ALL;
 USE IEEE.numeric_std.ALL;
 USE common_lib.common_pkg.ALL;
+USE common_lib.common_lfsr_sequences_pkg.ALL;
 USE common_lib.common_mem_pkg.ALL;
 USE common_lib.tb_common_mem_pkg.ALL;
+USE common_lib.tb_common_pkg.ALL;
 USE dp_lib.dp_stream_pkg.ALL;
+USE dp_lib.tb_dp_pkg.ALL;
 
 ENTITY tb_mms_diag_seq IS
+  GENERIC (   
+    -- general
+    g_flow_control_verify  : t_dp_flow_control_enum := e_active;  -- always active, random or pulse flow control
+    -- specific
+    g_data_w               : NATURAL  := 40;   -- >= g_seq_dat_w
+    g_seq_dat_w            : NATURAL  := 32
+  );
 END ENTITY tb_mms_diag_seq;
 
 ARCHITECTURE str of tb_mms_diag_seq IS
 
-  CONSTANT c_nof_diag_inst        : NATURAL := 1;  -- Enter number of diag instances here. Max = 32.
-  CONSTANT c_sim                  : BOOLEAN := TRUE;
+  CONSTANT c_nof_streams          : NATURAL := 1;
   
   CONSTANT mm_clk_period          : TIME := 8 ns;    -- 125 MHz
-  CONSTANT st_clk_period          : TIME := 5 ns;    -- 200 MHz
-
-  CONSTANT c_all_bits_high        : INTEGER := -1;
-  CONSTANT c_all_bits_low         : INTEGER := 0;
-
-  CONSTANT c_offset_rx_en         : NATURAL := 0;  --offsets relative to MM base address
-  CONSTANT c_offset_rx_mode       : NATURAL := 1;
-  CONSTANT c_offset_diag_res      : NATURAL := 2;
-  CONSTANT c_offset_diag_res_val  : NATURAL := 3;
-
-  CONSTANT c_offset_tx_en         : NATURAL := 0;
-  CONSTANT c_offset_tx_mode       : NATURAL := 1;
-  CONSTANT c_offset_tx_dat        : NATURAL := 2;
-
-  SIGNAL st_clk                   : STD_LOGIC := '0';
+  CONSTANT dp_clk_period          : TIME := 5 ns;    -- 200 MHz
+
+  PROCEDURE proc_readback(SIGNAL clk     : IN  STD_LOGIC;
+                          SIGNAL tx_miso : IN  t_mem_miso;
+                          SIGNAL tx_mosi : OUT t_mem_mosi;
+                          SIGNAL rx_miso : IN  t_mem_miso;
+                          SIGNAL rx_mosi : OUT t_mem_mosi;
+                          SIGNAL tx_init : OUT STD_LOGIC_VECTOR;
+                          SIGNAL tx_ctrl : OUT STD_LOGIC_VECTOR;
+                          SIGNAL rx_ctrl : OUT STD_LOGIC_VECTOR) IS
+  BEGIN
+    -- read back Tx data init
+    proc_mem_mm_bus_rd(1, clk, tx_miso, tx_mosi);
+    proc_mem_mm_bus_rd_latency(1, clk);
+    tx_init <= tx_miso.rddata(c_word_w-1 DOWNTO 0);
+    -- read back Tx control
+    proc_mem_mm_bus_rd(0, clk, tx_miso, tx_mosi);
+    proc_mem_mm_bus_rd_latency(1, clk);
+    tx_ctrl <= tx_miso.rddata(c_word_w-1 DOWNTO 0);
+    -- read back Rx control
+    proc_mem_mm_bus_rd(0, clk, rx_miso, rx_mosi);
+    proc_mem_mm_bus_rd_latency(1, clk);
+    rx_ctrl <= rx_miso.rddata(c_word_w-1 DOWNTO 0);
+  END proc_readback;
+
+  PROCEDURE proc_enable_tx(CONSTANT c_pattern : IN  STRING;    -- "PSRG", "CNTR"
+                           CONSTANT c_tx_init : IN  NATURAL;
+                           SIGNAL   mm_clk    : IN  STD_LOGIC;
+                           SIGNAL   dp_clk    : IN  STD_LOGIC;
+                           SIGNAL   tx_miso   : IN  t_mem_miso;  -- tx ctrl
+                           SIGNAL   tx_mosi   : OUT t_mem_mosi;
+                           SIGNAL   rx_miso   : IN  t_mem_miso;  -- rx ctrl
+                           SIGNAL   rx_mosi   : OUT t_mem_mosi;
+                           SIGNAL   tx_init : OUT STD_LOGIC_VECTOR;  -- readback
+                           SIGNAL   tx_ctrl : OUT STD_LOGIC_VECTOR;
+                           SIGNAL   rx_ctrl : OUT STD_LOGIC_VECTOR) IS
+    CONSTANT c_en   : NATURAL := 1;
+    VARIABLE v_sel  : NATURAL;
+    VARIABLE v_ctlr : NATURAL;
+  BEGIN
+    IF c_pattern="PSRG" THEN
+      v_sel  := 0;  -- pseudo random data
+    ELSE
+      v_sel  := 1;  -- counter data
+    END IF;
+    v_ctlr := v_sel * 2 + c_en;  -- bits [1:0]
+    -- Enable Tx
+    proc_mem_mm_bus_wr(0, v_ctlr, mm_clk, tx_miso, tx_mosi);
+    proc_mem_mm_bus_wr(1, c_tx_init, mm_clk, tx_miso, tx_mosi);
+    proc_common_wait_some_cycles(mm_clk, dp_clk, 10);  -- wait for clock domain crossing
+    proc_readback(mm_clk, tx_miso, tx_mosi, rx_miso, rx_mosi, tx_init, tx_ctrl, rx_ctrl);
+  END proc_enable_tx;
+  
+  PROCEDURE proc_enable_rx(CONSTANT c_pattern : IN  STRING;    -- "PSRG", "CNTR"
+                           SIGNAL   mm_clk    : IN  STD_LOGIC;
+                           SIGNAL   dp_clk    : IN  STD_LOGIC;
+                           SIGNAL   tx_miso   : IN  t_mem_miso;  -- tx ctrl
+                           SIGNAL   tx_mosi   : OUT t_mem_mosi;
+                           SIGNAL   rx_miso   : IN  t_mem_miso;  -- rx ctrl
+                           SIGNAL   rx_mosi   : OUT t_mem_mosi;
+                           SIGNAL   tx_init : OUT STD_LOGIC_VECTOR;  -- readback
+                           SIGNAL   tx_ctrl : OUT STD_LOGIC_VECTOR;
+                           SIGNAL   rx_ctrl : OUT STD_LOGIC_VECTOR) IS
+    CONSTANT c_en   : NATURAL := 1;
+    VARIABLE v_sel  : NATURAL;
+    VARIABLE v_ctlr : NATURAL;
+  BEGIN
+    IF c_pattern="PSRG" THEN
+      v_sel  := 0;  -- pseudo random data
+    ELSE
+      v_sel  := 1;  -- counter data
+    END IF;
+    v_ctlr := v_sel * 2 + c_en;  -- bits [1:0]
+    proc_mem_mm_bus_wr(0, v_ctlr, mm_clk, rx_miso, rx_mosi);
+    proc_common_wait_some_cycles(mm_clk, dp_clk, 10);  -- wait for clock domain crossing
+    proc_readback(mm_clk, tx_miso, tx_mosi, rx_miso, rx_mosi, tx_init, tx_ctrl, rx_ctrl);
+  END proc_enable_rx;
+  
+  PROCEDURE proc_disable_tx(SIGNAL   mm_clk  : IN  STD_LOGIC;
+                            SIGNAL   dp_clk  : IN  STD_LOGIC;
+                            SIGNAL   tx_miso : IN  t_mem_miso;  -- tx ctrl
+                            SIGNAL   tx_mosi : OUT t_mem_mosi;
+                            SIGNAL   rx_miso : IN  t_mem_miso;  -- rx ctrl
+                            SIGNAL   rx_mosi : OUT t_mem_mosi;
+                            SIGNAL   tx_init : OUT STD_LOGIC_VECTOR;  -- readback
+                            SIGNAL   tx_ctrl : OUT STD_LOGIC_VECTOR;
+                            SIGNAL   rx_ctrl : OUT STD_LOGIC_VECTOR) IS
+  BEGIN
+    proc_mem_mm_bus_wr(0, 0, mm_clk, tx_miso, tx_mosi);
+    proc_common_wait_some_cycles(mm_clk, dp_clk, 10);  -- wait for clock domain crossing
+    proc_readback(mm_clk, tx_miso, tx_mosi, rx_miso, rx_mosi, tx_init, tx_ctrl, rx_ctrl);
+  END proc_disable_tx;
+  
+  PROCEDURE proc_disable_rx(SIGNAL   mm_clk  : IN  STD_LOGIC;
+                            SIGNAL   dp_clk  : IN  STD_LOGIC;
+                            SIGNAL   tx_miso : IN  t_mem_miso;  -- tx ctrl
+                            SIGNAL   tx_mosi : OUT t_mem_mosi;
+                            SIGNAL   rx_miso : IN  t_mem_miso;  -- rx ctrl
+                            SIGNAL   rx_mosi : OUT t_mem_mosi;
+                            SIGNAL   tx_init : OUT STD_LOGIC_VECTOR;  -- readback
+                            SIGNAL   tx_ctrl : OUT STD_LOGIC_VECTOR;
+                            SIGNAL   rx_ctrl : OUT STD_LOGIC_VECTOR) IS
+  BEGIN
+    proc_mem_mm_bus_wr(0, 0, mm_clk, rx_miso, rx_mosi);
+    proc_common_wait_some_cycles(mm_clk, dp_clk, 10);  -- wait for clock domain crossing
+    proc_readback(mm_clk, tx_miso, tx_mosi, rx_miso, rx_mosi, tx_init, tx_ctrl, rx_ctrl);
+  END proc_disable_rx;
+
+  TYPE t_tb_mode_enum IS (
+    s_off,
+    s_expect_ok,
+    s_expect_error,
+    s_expect_no_result
+  );
+
+  PROCEDURE proc_read_and_verify_rx_stat(SIGNAL   clk       : IN    STD_LOGIC;
+                                         SIGNAL   mm_miso   : IN    t_mem_miso;
+                                         SIGNAL   mm_mosi   : OUT   t_mem_mosi;
+                                         SIGNAL   tb_mode   : INOUT t_tb_mode_enum;
+                                         SIGNAL   tb_verify : OUT   STD_LOGIC;
+                                         SIGNAL   rx_stat   : INOUT STD_LOGIC_VECTOR) IS
+  BEGIN
+    -- Read
+    proc_mem_mm_bus_rd(1, clk, mm_miso, mm_mosi);
+    proc_mem_mm_bus_rd_latency(1, clk);
+    rx_stat <= mm_miso.rddata(c_word_w-1 DOWNTO 0);
+    proc_common_wait_some_cycles(clk, 1);
+
+    -- Issue tb_verify pulse eg. to easy recognition in Wave window
+    tb_verify <= '1';
+    proc_common_wait_some_cycles(clk, 1);
+    tb_verify <= '0';
+    
+    -- Verify
+    IF tb_mode=s_expect_ok THEN
+      IF rx_stat(1)/='0' THEN
+        REPORT "Wrong diag result: no valid result." SEVERITY ERROR;
+      ELSIF rx_stat(0)/='0' THEN
+        REPORT "Wrong diag result: one or more data errors." SEVERITY ERROR;
+      END IF;
+    ELSIF tb_mode=s_expect_error THEN
+      IF rx_stat(1)/='0' THEN
+        REPORT "Wrong diag result: no valid result." SEVERITY ERROR;
+      ELSIF rx_stat(0)/='1' THEN
+        REPORT "Wrong diag result: must detect data errors." SEVERITY ERROR;
+      END IF;
+    ELSIF tb_mode=s_expect_no_result THEN
+      IF rx_stat(1)/='1' THEN
+        REPORT "Wrong diag result: must indicate no valid result." SEVERITY ERROR;
+      END IF;
+    ELSE
+      REPORT "Unknown verify mode" SEVERITY FAILURE;
+    END IF;
+  END proc_read_and_verify_rx_stat;
+  
+  SIGNAL random                   : STD_LOGIC_VECTOR(15 DOWNTO 0) := (OTHERS=>'0');  -- use different lengths to have different random sequences
+  SIGNAL pulse                    : STD_LOGIC;
+  SIGNAL ready                    : STD_LOGIC;
+  
+  SIGNAL tb_end                   : STD_LOGIC := '0';
+  SIGNAL tb_mode                  : t_tb_mode_enum := s_off;
+  SIGNAL tb_verify                : STD_LOGIC := '0';
+  SIGNAL mm_rst                   : STD_LOGIC;
   SIGNAL mm_clk                   : STD_LOGIC := '0';
-  SIGNAL sys_rst                  : STD_LOGIC := '1';
+  SIGNAL dp_rst                   : STD_LOGIC := '1';
+  SIGNAL dp_clk                   : STD_LOGIC := '0';
 
-  SIGNAL tx_mm_mosi               : t_mem_mosi;
-  SIGNAL tx_mm_miso               : t_mem_miso;
+  SIGNAL reg_tx_mosi              : t_mem_mosi := c_mem_mosi_rst;
+  SIGNAL reg_tx_miso              : t_mem_miso;
 
-  SIGNAL rx_mm_mosi               : t_mem_mosi;
-  SIGNAL rx_mm_miso               : t_mem_miso;
+  SIGNAL reg_rx_mosi              : t_mem_mosi := c_mem_mosi_rst;
+  SIGNAL reg_rx_miso              : t_mem_miso;
 
-  SIGNAL tx_src_out               : t_dp_sosi_arr(c_nof_diag_inst-1 DOWNTO 0);  -- source out sink in
-  SIGNAL tx_src_in                : t_dp_siso_arr(c_nof_diag_inst-1 DOWNTO 0);  -- source in sink out
+  SIGNAL tx_ctrl                  : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+  SIGNAL tx_init                  : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+  SIGNAL rx_ctrl                  : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+  SIGNAL rx_stat                  : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+  
+  SIGNAL tx_src_out_arr           : t_dp_sosi_arr(c_nof_streams-1 DOWNTO 0);
+  SIGNAL tx_src_in_arr            : t_dp_siso_arr(c_nof_streams-1 DOWNTO 0);
 
+  SIGNAL force_low_error          : STD_LOGIC;
+  SIGNAL force_replicate_error    : STD_LOGIC;
+  
+  SIGNAL rx_snk_in_arr            : t_dp_sosi_arr(c_nof_streams-1 DOWNTO 0);
+  
 BEGIN
 
-  sys_rst <= '0' AFTER 100 ns;
+  mm_rst <= '1', '0' AFTER mm_clk_period * 5;
+  dp_rst <= mm_rst WHEN rising_edge(dp_clk);
 
-  st_clk <= NOT mm_clk AFTER mm_clk_period/2;  -- Would be generated by SOPC if there was one.
-  mm_clk <= NOT mm_clk AFTER mm_clk_period/2; 
-  p_mm_wr : PROCESS
+  mm_clk <= NOT mm_clk OR tb_end AFTER mm_clk_period/2;
+  dp_clk <= NOT dp_clk OR tb_end AFTER dp_clk_period/2;
+   
+  ------------------------------------------------------------------------------
+  -- STREAM CONTROL
+  ------------------------------------------------------------------------------
+  
+  random <= func_common_random(random) WHEN rising_edge(dp_clk);
+                       
+  ready <= '1'                 WHEN g_flow_control_verify=e_active  ELSE
+           random(random'HIGH) WHEN g_flow_control_verify=e_random  ELSE
+           pulse               WHEN g_flow_control_verify=e_pulse;
+           
+  tx_src_in_arr <= func_dp_stream_arr_set(tx_src_in_arr, ready, "READY");
+                          
+  ------------------------------------------------------------------------------
+  -- Stimuli
+  ------------------------------------------------------------------------------
+  
+  p_stimuli : PROCESS
   BEGIN
-
-    tx_mm_miso <= c_mem_miso_rst;
-    tx_mm_mosi <= c_mem_mosi_rst;
-    rx_mm_miso <= c_mem_miso_rst;
-    rx_mm_mosi <= c_mem_mosi_rst;
+    force_low_error       <= '0';
+    force_replicate_error <= '0';
+    tb_mode <= s_off;
+    proc_common_wait_until_low(mm_clk, mm_rst);
+    proc_common_wait_some_cycles(mm_clk, 10);
+
+    -------------------------------------------------------------------------
+    -- Verify Tx and Rx on and both with the same pattern
+    -------------------------------------------------------------------------
+    tb_mode <= s_expect_ok;
+    proc_disable_tx(mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
+    proc_disable_rx(mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
+    proc_enable_tx("CNTR", 17, mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
+    proc_enable_rx("CNTR", mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
     
-    WHILE sys_rst='1' LOOP
-      WAIT UNTIL rising_edge(mm_clk);
-    END LOOP;
-
-    FOR I IN 0 TO 9 LOOP
-      WAIT UNTIL rising_edge(mm_clk);
-    END LOOP;
-
-    -- Enable DIAG TX sequencer, set modes of RX and TX to PRNG
-    proc_mem_mm_bus_wr(c_offset_tx_mode, c_all_bits_high, mm_clk, tx_mm_mosi);
-    proc_mem_mm_bus_wr(c_offset_tx_en, c_all_bits_high, mm_clk, tx_mm_mosi);
-    proc_mem_mm_bus_wr(c_offset_rx_mode, c_all_bits_high, mm_clk, rx_mm_mosi);
-
-    WAIT FOR 100 ns;
-
-    -- Receivers should have aligned to the data now. Enable the DIAG RX monitor.
-    proc_mem_mm_bus_wr(c_offset_rx_en, c_all_bits_high, mm_clk, rx_mm_mosi);
-
-    WAIT FOR 200 ns;
-
-    -- Now read the diagnostics result: first put the request on the bus.
-    proc_mem_mm_bus_rd(c_offset_diag_res, mm_clk, rx_mm_mosi);
-
-    -- Wait because of read latency
-    proc_mem_mm_bus_rd_latency(c_mem_reg_rd_latency, mm_clk);
-
-    -- Read data is now available in tx_mm_miso.rddata
-    FOR i in 0 to c_nof_diag_inst-1 LOOP -- All unconnected diag_res signals will of course be 'X' - only read the first c_nof_diag_inst bits.
-    ASSERT  rx_mm_miso.rddata(i) = '0'
-      REPORT " Uniboard: ************************ MM READ DIAG RESULT NOT ZERO! ************************" SEVERITY FAILURE;
-    END LOOP;
-
-    ASSERT FALSE
-      REPORT "Uniboard: MM read DIAG result OK." SEVERITY NOTE;
-
+    -- Run test and read and verify Rx status
+    proc_common_wait_some_cycles(mm_clk, 100);
+    proc_read_and_verify_rx_stat(mm_clk, reg_rx_miso, reg_rx_mosi, tb_mode, tb_verify, rx_stat);
+    
+    -------------------------------------------------------------------------
+    -- Verify Tx and Rx on but with different pattern
+    -------------------------------------------------------------------------
+    tb_mode <= s_expect_error;
+    proc_enable_tx("PSRG", 17, mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
+    
+    -- Run test and read and verify Rx status
+    proc_common_wait_some_cycles(mm_clk, 100);
+    proc_read_and_verify_rx_stat(mm_clk, reg_rx_miso, reg_rx_mosi, tb_mode, tb_verify, rx_stat);
+          
+    -------------------------------------------------------------------------
+    -- Verify Rx off
+    -------------------------------------------------------------------------
+    tb_mode <= s_expect_no_result;
+    proc_disable_rx(mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
+    
+    -- Run test and read and verify Rx status
+    proc_common_wait_some_cycles(mm_clk, 100);
+    proc_read_and_verify_rx_stat(mm_clk, reg_rx_miso, reg_rx_mosi, tb_mode, tb_verify, rx_stat);
+    
+    -------------------------------------------------------------------------
+    -- Verify Tx and Rx on with error in sequence low part
+    -------------------------------------------------------------------------
+    tb_mode <= s_expect_ok;
+    proc_disable_tx(mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
+    proc_disable_rx(mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
+    proc_enable_tx("CNTR", 17, mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
+    proc_enable_rx("CNTR", mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
+    
+    -- Run test and read and verify Rx status
+    proc_common_wait_some_cycles(mm_clk, 100);
+    proc_read_and_verify_rx_stat(mm_clk, reg_rx_miso, reg_rx_mosi, tb_mode, tb_verify, rx_stat);
+    
+    tb_mode <= s_expect_error;
+    proc_common_wait_some_cycles(dp_clk, 1);
+    force_low_error <= '1';
+    proc_common_wait_some_cycles(dp_clk, 1);
+    force_low_error <= '0';
+    proc_common_wait_some_cycles(mm_clk, 100);
+    proc_read_and_verify_rx_stat(mm_clk, reg_rx_miso, reg_rx_mosi, tb_mode, tb_verify, rx_stat);
+    
+    -------------------------------------------------------------------------
+    -- Verify Tx and Rx on with error in sequence replicate part
+    -------------------------------------------------------------------------
+    tb_mode <= s_expect_ok;
+    proc_disable_tx(mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
+    proc_disable_rx(mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
+    proc_enable_tx("CNTR", 17, mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
+    proc_enable_rx("CNTR", mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
+    
+    -- Run test and read and verify Rx status
+    proc_common_wait_some_cycles(mm_clk, 100);
+    proc_read_and_verify_rx_stat(mm_clk, reg_rx_miso, reg_rx_mosi, tb_mode, tb_verify, rx_stat);
+    
+    tb_mode <= s_expect_error;
+    proc_common_wait_some_cycles(dp_clk, 1);
+    force_replicate_error <= '1';
+    proc_common_wait_some_cycles(dp_clk, 1);
+    force_replicate_error <= '0';
+    proc_common_wait_some_cycles(mm_clk, 100);
+    proc_read_and_verify_rx_stat(mm_clk, reg_rx_miso, reg_rx_mosi, tb_mode, tb_verify, rx_stat);
+    
+    -------------------------------------------------------------------------
+    -- Both off
+    -------------------------------------------------------------------------
+    tb_mode <= s_off;
+    proc_disable_tx(mm_clk, dp_clk, reg_tx_miso, reg_tx_mosi, reg_rx_miso, reg_rx_mosi, tx_init, tx_ctrl, rx_ctrl);
+    proc_common_wait_some_cycles(mm_clk, 10);
+    tb_end <= '1';
     WAIT;
-
   END PROCESS;
-
+  
   u_mms_diag_tx_seq: ENTITY WORK.mms_diag_tx_seq
-    GENERIC MAP(
-      g_nof_diag_inst => c_nof_diag_inst,
-      g_dat_w         => c_word_w,
-      g_sim           => c_sim
-    )
-    PORT MAP(
-      -- Clocks and reset
-      mm_rst         => sys_rst,
-      mm_clk         => mm_clk,
-      st_clk         => st_clk,
-
-      -- Memory Mapped Slave
-      mm_sla_in      => tx_mm_mosi,  -- master out slave in
-      mm_sla_out     => tx_mm_miso,  -- master in slave out
-
-      -- Streaming interface
-      tx_src_out     => tx_src_out,
-      tx_src_in      => tx_src_in
-    );      
-
-  gen_ready_signals : FOR i IN 0 TO c_nof_diag_inst-1 GENERATE  -- Ready signals for all instantiated diag rx modules
-    tx_src_in(i).ready <= '1';
-  END GENERATE;
+  GENERIC MAP(
+    g_nof_streams => c_nof_streams,
+    g_seq_dat_w   => g_seq_dat_w
+  )
+  PORT MAP(
+    -- Clocks and reset
+    mm_rst         => mm_rst,
+    mm_clk         => mm_clk,
+    dp_rst         => dp_rst,
+    dp_clk         => dp_clk,
+
+    -- MM interface
+    reg_mosi       => reg_tx_mosi,
+    reg_miso       => reg_tx_miso,
+
+    -- DP streaming interface
+    tx_src_out_arr => tx_src_out_arr,
+    tx_src_in_arr  => tx_src_in_arr
+  );      
 
   u_mms_diag_rx_seq: ENTITY WORK.mms_diag_rx_seq
-    GENERIC MAP(
-      g_nof_diag_inst => c_nof_diag_inst,
-      g_dat_w         => c_word_w,
-      g_sim           => c_sim
-    )
-    PORT MAP(
-      -- Clocks and reset
-      mm_rst         => sys_rst,
-      mm_clk         => mm_clk,
-      st_clk         => st_clk,
-
-      -- Memory Mapped Slave
-      mm_sla_in      => rx_mm_mosi,  -- master out slave in
-      mm_sla_out     => rx_mm_miso,  -- master in slave out
-
-      -- Streaming interface
-      rx_snk_in      => tx_src_out
-    );      
-
+  GENERIC MAP(
+    g_nof_streams => c_nof_streams,
+    g_seq_dat_w   => g_seq_dat_w,
+    g_data_w      => g_data_w
+  )
+  PORT MAP(
+    -- Clocks and reset
+    mm_rst         => mm_rst,
+    mm_clk         => mm_clk,
+    dp_rst         => dp_rst,
+    dp_clk         => dp_clk,
+
+    -- MM interface
+    reg_mosi       => reg_rx_mosi,
+    reg_miso       => reg_rx_miso,
+
+    -- DP streaming interface
+    rx_snk_in_arr  => rx_snk_in_arr
+  );      
+
+  p_connect : PROCESS(tx_src_out_arr, force_low_error, force_replicate_error)
+  BEGIN
+    rx_snk_in_arr <= tx_src_out_arr;
+    IF force_low_error='1' THEN 
+      rx_snk_in_arr(0).data(0) <= NOT tx_src_out_arr(0).data(0);
+    END IF;
+    IF force_replicate_error='1' THEN 
+      rx_snk_in_arr(0).data(g_seq_dat_w) <= NOT tx_src_out_arr(0).data(g_seq_dat_w);
+    END IF;
+  END PROCESS;
+  
 END ARCHITECTURE str;