diff --git a/libraries/dsp/si/hdllib.cfg b/libraries/dsp/si/hdllib.cfg
index 218fb87f7a66bf69a85dd6ab648f882d3ccb7dbc..b9c5b293a1aec62f6d333dd08119ea202fc3ca15 100755
--- a/libraries/dsp/si/hdllib.cfg
+++ b/libraries/dsp/si/hdllib.cfg
@@ -11,7 +11,7 @@ test_bench_files =
     tb/vhdl/tb_si.vhd 
 
 regression_test_vhdl = 
-    #tb/vhdl/tb_si.vhd   -- tb is not self checking yet
+    tb/vhdl/tb_si.vhd
 
 
 [modelsim_project_file]
diff --git a/libraries/dsp/si/src/vhdl/si.vhd b/libraries/dsp/si/src/vhdl/si.vhd
index f4230bfecee6688021854090a4185d7adb30aade..14d61189ce30513a56070e74e5c0680a2387f789 100755
--- a/libraries/dsp/si/src/vhdl/si.vhd
+++ b/libraries/dsp/si/src/vhdl/si.vhd
@@ -29,26 +29,22 @@
 --   where n = 0 is the first sample in the FFT block. For more information
 --   see section 4.19 in LOFAR_ASTRON_SDD_018_RSP_Firmware_DD.pdf.
 -- Remark:
--- . Ported from LOFAR1 rsp
+-- . Ported from LOFAR1 rsp. Then rewrote code to use t_dp_sosi.
 -------------------------------------------------------------------------------
 
-LIBRARY IEEE;
+LIBRARY IEEE, common_lib, dp_lib;
 USE IEEE.STD_LOGIC_1164.ALL;
-USE IEEE.NUMERIC_STD.ALL;
+USE common_lib.common_pkg.ALL;
+USE dp_lib.dp_stream_pkg.ALL;
 
 ENTITY si IS
   GENERIC (
+    g_pipeline  : NATURAL := 1;   -- 0 for wires, 1 for output pipeline
     g_dat_w     : NATURAL := 18
   );
   PORT (
-    in_dat      : IN  STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0);
-    in_val      : IN  STD_LOGIC;
-    in_sop      : IN  STD_LOGIC;
-    in_sync     : IN  STD_LOGIC;
-    out_dat     : OUT STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0);
-    out_val     : OUT STD_LOGIC;
-    out_sop     : OUT STD_LOGIC;
-    out_sync    : OUT STD_LOGIC;
+    in_sosi     : IN  t_dp_sosi;
+    out_sosi    : OUT t_dp_sosi;
     si_en       : IN  STD_LOGIC;
     clk         : IN  STD_LOGIC;
     rst         : IN  STD_LOGIC
@@ -57,54 +53,56 @@ END si;
 
 ARCHITECTURE rtl OF si IS
 
-  CONSTANT c_dat_max   : INTEGER :=  2**(g_dat_w-1)-1;
-  CONSTANT c_dat_min   : INTEGER := -2**(g_dat_w-1);
-  
-  SIGNAL nxt_out_dat   : STD_LOGIC_VECTOR(out_dat'RANGE);
   SIGNAL plus          : STD_LOGIC;
-  SIGNAL nxt_plus      : STD_LOGIC;
+  SIGNAL plus_reg      : STD_LOGIC;
   SIGNAL si_plus       : STD_LOGIC;
+  SIGNAL si_sosi       : t_dp_sosi;
 
 BEGIN
 
-  reg_si : PROCESS(rst, clk)
+  p_reg : PROCESS(rst, clk)
   BEGIN
     IF rst='1' THEN
-      out_val   <= '0';
-      out_sop   <= '0';
-      out_sync  <= '0';
-      plus      <= '1';
+      plus_reg  <= '1';
     ELSIF rising_edge(clk) THEN
-      out_dat   <= nxt_out_dat;
-      out_val   <= in_val;
-      out_sop   <= in_sop;
-      out_sync  <= in_sync;
-      plus      <= nxt_plus;
+      plus_reg  <= plus;
     END IF;
   END PROCESS;
-    
-  si_control : PROCESS (plus, in_sop, in_val)
+  
+  -- Control -1**n to start with +1 at sop and then toggle at every valid
+  p_si_control : PROCESS (plus_reg, in_sosi)
   BEGIN
-    nxt_plus <= plus;
-    IF in_sop = '1' THEN
-      nxt_plus <= '1';
-    ELSIF in_val = '1' THEN
-      nxt_plus <= NOT plus;
+    plus <= plus_reg;
+    IF in_sosi.sop = '1' THEN
+      plus <= '1';
+    ELSIF in_sosi.valid = '1' THEN
+      plus <= NOT plus_reg;
     END IF;
   END PROCESS;
   
+  -- Use SI when enabled, else pass on input
   si_plus <= plus WHEN si_en = '1' ELSE '1';
 
-  si_data : PROCESS (si_plus, in_dat)
+  si_data : PROCESS (si_plus, in_sosi)
   BEGIN
-    nxt_out_dat <= in_dat;
+    si_sosi <= in_sosi;
     IF si_plus = '0' THEN
-      nxt_out_dat <= STD_LOGIC_VECTOR(-SIGNED(in_dat));
-      -- Clip -c_dat_min to c_dat_max instead of wrapping to c_dat_min
-      IF SIGNED(in_dat) = c_dat_min THEN
-        nxt_out_dat <= STD_LOGIC_VECTOR(TO_SIGNED(c_dat_max, g_dat_w));
-      END IF;
+      si_sosi.data <= NEGATE_SVEC(in_sosi.data, g_dat_w);
+      si_sosi.re   <= NEGATE_SVEC(in_sosi.re, g_dat_w);
+      si_sosi.im   <= NEGATE_SVEC(in_sosi.im, g_dat_w);
     END IF;
   END PROCESS;
+
+  -- Output
+  u_pipeline : ENTITY dp_lib.dp_pipeline
+  GENERIC MAP (
+    g_pipeline  => g_pipeline
+  )
+  PORT MAP (
+    rst     => rst,
+    clk     => clk,
+    snk_in  => si_sosi,
+    src_out => out_sosi
+  );
   
 END rtl;
diff --git a/libraries/dsp/si/tb/vhdl/tb_si.vhd b/libraries/dsp/si/tb/vhdl/tb_si.vhd
index 1a455af2cadb8be83d011922424a7a7ebdc667e9..462b6b6a8a1b9a671e1b3ed8852ea70431f384d8 100755
--- a/libraries/dsp/si/tb/vhdl/tb_si.vhd
+++ b/libraries/dsp/si/tb/vhdl/tb_si.vhd
@@ -25,12 +25,13 @@
 -- Description:
 --   Test bench for si.vhd.
 -- Remark:
--- . Ported from LOFAR1 rsp
--- . The tb is self-stopping, but not self checking.
+-- . Ported from LOFAR1 rsp. Made the tb self-stopping and self-checking.
 
-LIBRARY IEEE, common_lib;
+LIBRARY IEEE, common_lib, dp_lib;
 USE IEEE.STD_LOGIC_1164.ALL;
 USE common_lib.common_pkg.ALL;
+USE common_lib.tb_common_pkg.ALL;
+USE dp_lib.dp_stream_pkg.ALL;
 
 ENTITY tb_si IS
 END tb_si;
@@ -40,10 +41,14 @@ ARCHITECTURE tb OF tb_si IS
   CONSTANT c_clk_period   : TIME := 10 ns;
 
   CONSTANT c_dat_w        : NATURAL := 5;
-  CONSTANT c_block_size   : NATURAL := 19;
+  CONSTANT c_max          : INTEGER :=  2**(c_dat_w-1)-1;
+  CONSTANT c_min          : INTEGER := -2**(c_dat_w-1);
+  CONSTANT c_block_size   : NATURAL := 9;
 
-  SIGNAL in_dat         : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
-  SIGNAL nxt_in_dat     : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
+  SIGNAL in_sosi        : t_dp_sosi;
+  SIGNAL out_sosi       : t_dp_sosi;
+
+  SIGNAL in_dat         : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0) := (OTHERS => '0');
   SIGNAL in_val         : STD_LOGIC;
   SIGNAL in_sop         : STD_LOGIC;
   SIGNAL in_sync        : STD_LOGIC;
@@ -57,7 +62,8 @@ ARCHITECTURE tb OF tb_si IS
   SIGNAL tb_end         : STD_LOGIC := '0';
 
   SIGNAL toggle         : STD_LOGIC;
-  SIGNAL nxt_toggle     : STD_LOGIC;
+  SIGNAL clip_even      : STD_LOGIC;
+  SIGNAL clip_odd       : STD_LOGIC;
 
 BEGIN
 
@@ -65,45 +71,48 @@ BEGIN
   clk <= NOT(clk) OR tb_end AFTER c_clk_period/2;
   
   u_si : ENTITY work.si
-  GENERIC MAP(
+  GENERIC MAP (
+    g_pipeline  => 0,
     g_dat_w     => c_dat_w
   )
   PORT MAP(
-    in_dat      => in_dat,
-    in_val      => in_val,
-    in_sop      => in_sop,
-    in_sync     => in_sync,
-    out_dat     => out_dat,
-    out_val     => out_val,
-    out_sop     => out_sop,
-    out_sync    => out_sync,
+    in_sosi     => in_sosi,
+    out_sosi    => out_sosi,
     si_en       => si_en,
     clk         => clk,
     rst         => rst
   );
   
-  reg_stimuli : PROCESS(rst, clk)
+  -- wires
+  in_sosi.sync  <= in_sync;
+  in_sosi.sop   <= in_sop;
+  in_sosi.valid <= in_val;
+  in_sosi.data  <= RESIZE_DP_SDATA(in_dat);
+  in_sosi.re    <= TO_DP_DSP_DATA(0);
+  in_sosi.im    <= TO_DP_DSP_DATA(0);
+
+  out_sync <= out_sosi.sync;
+  out_sop  <= out_sosi.sop;
+  out_val  <= out_sosi.valid;
+  out_dat  <= out_sosi.data(c_dat_w-1 DOWNTO 0);
+
+  -- Create in_dat with equal value per pair
+  p_clk : PROCESS(rst, clk)
   BEGIN
     IF rst='1' THEN
       in_dat   <= (OTHERS => '0');
       toggle   <= '0';
     ELSIF rising_edge(clk) THEN
-      in_dat   <= nxt_in_dat;
-      toggle   <= nxt_toggle;
+      IF in_val='1' THEN
+        IF toggle='1' THEN
+          in_dat <= INCR_UVEC(in_dat, 1);
+        END IF;
+        toggle <= NOT toggle;
+      END IF;
     END IF;
   END PROCESS;
 
-  nxt_toggle <= NOT toggle;
-  
-  data_counter : PROCESS (toggle, in_dat)
-  BEGIN
-    nxt_in_dat <= in_dat;
-    IF toggle = '1' THEN
-      nxt_in_dat <= INCR_UVEC(in_dat, 1);
-    END IF;
-  END PROCESS;
-  
-  PROCESS
+  p_stimuli : PROCESS
   BEGIN
     si_en   <= '1';
     in_sop  <= '0';
@@ -112,42 +121,63 @@ BEGIN
     WAIT FOR 10*c_clk_period;
 
     -- pulse in_sync, to check that it is passed on
-    -- sop followed by valid data
+    -- pulse sop and continue with valid data
     in_sync <= '1';
     in_sop  <= '1';
-    in_val  <= '0';
+    in_val  <= '1';
     WAIT FOR c_clk_period;
     in_sync <= '0';
     in_sop  <= '0';
-    in_val  <= '1';
     WAIT FOR c_block_size*c_clk_period;
     
-    -- insert a single valid low cycle
+    -- insert some valid low cycles
     in_val  <= '0';
-    WAIT FOR c_clk_period;
-    in_val  <= '1';
-    WAIT FOR c_block_size*c_clk_period;
-        
-    -- insert an out of phase resync sop cycle
-    in_sop  <= '1';
+    WAIT FOR 3*c_clk_period;
     in_val  <= '1';
-    WAIT FOR c_clk_period;
-    in_sop  <= '0';
-    in_val  <= '1';
-    WAIT FOR c_block_size*c_clk_period;
-    
-    -- insert an in phase resync sop cycle
-    in_sop  <= '1';
-    in_val  <= '1';
-    WAIT FOR c_clk_period;
-    in_sop  <= '0';
-    in_val  <= '1';
-    WAIT FOR c_block_size*c_clk_period;
+
+    -- some more blocks
+    FOR I IN 0 TO 15 LOOP
+      in_sop <= '1';
+      WAIT FOR c_clk_period;
+      in_sop <= '0';
+      WAIT FOR c_block_size*c_clk_period;
+    END LOOP;
     
     tb_end <= '1';
     WAIT;
-    
   END PROCESS;
+
+  p_verify : PROCESS
+    VARIABLE v_even      : INTEGER;
+    VARIABLE v_odd       : INTEGER;
+    VARIABLE v_clip_even : STD_LOGIC;
+    VARIABLE v_clip_odd  : STD_LOGIC;
+  BEGIN
+    -- verify per pair
+    WAIT FOR c_clk_period;
+    proc_common_wait_until_high(clk, out_val);
+    v_even := TO_SINT(out_dat);
+    WAIT FOR c_clk_period;
+    proc_common_wait_until_high(clk, out_val);
+    v_odd := TO_SINT(out_dat);
+    -- identify clip wrap of -c_min to +c_max
+    IF v_even = c_max AND v_odd = c_min THEN v_clip_even := '1'; ELSE v_clip_even := '0'; END IF;
+    IF v_even = c_min AND v_odd = c_max THEN v_clip_odd  := '1'; ELSE v_clip_odd  := '0'; END IF;
+    clip_even <= v_clip_even;  -- show in wave window (only cycle late)
+    clip_odd  <= v_clip_odd;   -- show in wave window (only cycle late)
+    -- compare pair
+    IF tb_end = '0' THEN
+      IF v_even /= -v_odd THEN
+        IF NOT (v_clip_even = '1') THEN
+          IF NOT (v_clip_odd = '1') THEN
+            REPORT "Wrong negate value" SEVERITY ERROR;
+	  END IF;
+	END IF;
+      END IF;
+    ELSE
+      WAIT;
+    END IF;
+  END PROCESS; 
   
 END tb;