diff --git a/libraries/io/eth/src/vhdl/eth.vhd b/libraries/io/eth/src/vhdl/eth.vhd
index 3bc629d3d421d5a28b5259d37520ea1d7f455346..04dcd650ac50b462b64b433c7cf78dc61c5e1b5b 100644
--- a/libraries/io/eth/src/vhdl/eth.vhd
+++ b/libraries/io/eth/src/vhdl/eth.vhd
@@ -638,7 +638,7 @@ BEGIN
     g_sim          => g_sim,
     g_sim_level    => g_sim_level,
     g_sim_tx       => TRUE,
-    g_sim_rx       => sel_a_b(g_sim_level=1, FALSE, TRUE) -- TX only when using fast behavioural model
+    g_sim_rx       => TRUE
   )
   PORT MAP (
     -- Clocks and reset
diff --git a/libraries/io/eth/tb/vhdl/tb_eth.vhd b/libraries/io/eth/tb/vhdl/tb_eth.vhd
index 9a8005019d277a3372d5766bd14dc1faeba66dce..22387c22d9d90beb359e0e2513ef85bd8ef065a2 100644
--- a/libraries/io/eth/tb/vhdl/tb_eth.vhd
+++ b/libraries/io/eth/tb/vhdl/tb_eth.vhd
@@ -61,6 +61,8 @@ ENTITY tb_eth IS
   GENERIC (
     g_technology_dut : NATURAL := c_tech_select_default;
     g_technology_lcu : NATURAL := c_tech_select_default;
+    g_sim            : BOOLEAN := TRUE;
+    g_sim_level      : NATURAL := 1;      -- when g_sim = TRUE, then 0 = use IP; 1 = use fast serdes model
     g_frm_discard_en : BOOLEAN := FALSE;  -- when TRUE discard frame types that would otherwise have to be discarded by the Nios MM master
     g_flush_test_en  : BOOLEAN := FALSE;  -- when TRUE send many large frames to enforce flush in eth_buffer
     g_tb_end         : BOOLEAN := TRUE;   -- when TRUE then tb_end ends this simulation, else a higher multi-testbench will end the simulation
@@ -81,7 +83,7 @@ ARCHITECTURE tb OF tb_eth IS
 
   CONSTANT sys_clk_period       : TIME := 10 ns;  -- 100 MHz
   CONSTANT eth_clk_period       : TIME :=  8 ns;  -- 125 MHz
-  CONSTANT cable_delay          : TIME := 12 ns;
+  CONSTANT cable_delay          : TIME := sel_a_b(g_sim_level=0, 12 ns, 0 ns);
 
   CONSTANT c_cross_clock_domain : BOOLEAN := TRUE;  -- use FALSE when mm_clk and st_clk are the same, else use TRUE to cross the clock domain
   
@@ -256,9 +258,11 @@ ARCHITECTURE tb OF tb_eth IS
   SIGNAL lcu_tx_en           : STD_LOGIC := '1';
   SIGNAL lcu_tx_siso         : t_dp_siso;
   SIGNAL lcu_tx_sosi         : t_dp_sosi;
+  SIGNAL lcu_tx_sosi_data    : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
   SIGNAL lcu_tx_mac_in       : t_tech_tse_tx_mac;
   SIGNAL lcu_tx_mac_out      : t_tech_tse_tx_mac;
   SIGNAL lcu_rx_sosi         : t_dp_sosi;
+  SIGNAL lcu_rx_sosi_data    : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
   SIGNAL lcu_rx_siso         : t_dp_siso;
   SIGNAL lcu_rx_mac_out      : t_tech_tse_rx_mac;
   SIGNAL lcu_txp             : STD_LOGIC;
@@ -421,6 +425,11 @@ BEGIN
   ------------------------------------------------------------------------------
   -- LCU
   ------------------------------------------------------------------------------
+  
+  -- Debug signal to more easily view sosi.data in Wave Window
+  lcu_tx_sosi_data <= lcu_tx_sosi.data(c_word_w-1 DOWNTO 0);
+  lcu_rx_sosi_data <= lcu_rx_sosi.data(c_word_w-1 DOWNTO 0);
+  
   p_lcu_setup : PROCESS
   BEGIN
     lcu_init <= '1';
@@ -535,7 +544,9 @@ BEGIN
   GENERIC MAP (
     g_technology         => g_technology_dut,
     g_cross_clock_domain => c_cross_clock_domain,
-    g_frm_discard_en     => g_frm_discard_en
+    g_frm_discard_en     => g_frm_discard_en,
+    g_sim                => g_sim,
+    g_sim_level          => g_sim_level
   )
   PORT MAP (
     -- Clocks and reset
@@ -570,6 +581,12 @@ BEGIN
   );
 
   lcu : ENTITY tech_tse_lib.tech_tse
+  GENERIC MAP (
+    g_sim          => g_sim,
+    g_sim_level    => g_sim_level,
+    g_sim_tx       => TRUE,
+    g_sim_rx       => TRUE
+  )
   PORT MAP (
     -- Clocks and reset
     mm_rst         => mm_rst,
@@ -619,6 +636,10 @@ BEGIN
       rx_timeout <= rx_timeout + 1;
       IF lcu_rx_sosi.valid='1' THEN
         rx_timeout <= 0;
+      ELSIF rx_pkt_cnt>0 THEN
+        IF tx_pkt_cnt=rx_pkt_cnt + rx_pkt_discarded_cnt + TO_UINT(rx_pkt_flushed_cnt) THEN
+          rx_end <= '1';  -- do not wait for rx_timeout if all expected packets have been received
+        END IF;
       ELSIF rx_timeout>5000 THEN  -- sufficiently large value determined by trial
         rx_end <= '1';
       END IF;
diff --git a/libraries/io/eth/tb/vhdl/tb_tb_eth.vhd b/libraries/io/eth/tb/vhdl/tb_tb_eth.vhd
index 86527014f8420484d39d6edf38b0fb6007c0b2d8..e3339f2fabef00d36a8b3ae8ee3aa645335f6154 100644
--- a/libraries/io/eth/tb/vhdl/tb_tb_eth.vhd
+++ b/libraries/io/eth/tb/vhdl/tb_tb_eth.vhd
@@ -53,6 +53,8 @@ BEGIN
 
 -- g_technology_dut : NATURAL := c_tech_select_default;
 -- g_technology_lcu : NATURAL := c_tech_select_default;
+-- g_sim            : BOOLEAN := FALSE;
+-- g_sim_level      : NATURAL := 0;      -- when g_sim = TRUE, then 0 = use IP; 1 = use fast serdes model
 -- g_frm_discard_en : BOOLEAN := TRUE;   -- when TRUE discard frame types that would otherwise have to be discarded by the Nios MM master
 -- g_flush_test_en  : BOOLEAN := FALSE;  -- when TRUE send many large frames to enforce flush in eth_buffer
 -- g_tb_end         : BOOLEAN := TRUE;   -- when TRUE then tb_end ends this simulation, else a higher multi-testbench will end the simulation
@@ -63,12 +65,13 @@ BEGIN
 -- --   g_data_type = c_tb_tech_tse_data_type_udp      = 4
 -- g_data_type : NATURAL := c_tb_tech_tse_data_type_udp
   
-  u_use_symbols     : ENTITY work.tb_eth GENERIC MAP (g_technology_dut, c_technology_lcu, FALSE, FALSE, FALSE, c_tb_tech_tse_data_type_symbols) PORT MAP (tb_end_vec(0));
-  u_use_counter     : ENTITY work.tb_eth GENERIC MAP (g_technology_dut, c_technology_lcu, FALSE, FALSE, FALSE, c_tb_tech_tse_data_type_counter) PORT MAP (tb_end_vec(1));
-  u_use_arp         : ENTITY work.tb_eth GENERIC MAP (g_technology_dut, c_technology_lcu,  TRUE, FALSE, FALSE, c_tb_tech_tse_data_type_arp    ) PORT MAP (tb_end_vec(2));
-  u_use_ping        : ENTITY work.tb_eth GENERIC MAP (g_technology_dut, c_technology_lcu,  TRUE, FALSE, FALSE, c_tb_tech_tse_data_type_ping   ) PORT MAP (tb_end_vec(3));
-  u_use_udp         : ENTITY work.tb_eth GENERIC MAP (g_technology_dut, c_technology_lcu,  TRUE, FALSE, FALSE, c_tb_tech_tse_data_type_udp    ) PORT MAP (tb_end_vec(4));
-  u_use_udp_flush   : ENTITY work.tb_eth GENERIC MAP (g_technology_dut, c_technology_lcu,  TRUE,  TRUE, FALSE, c_tb_tech_tse_data_type_udp    ) PORT MAP (tb_end_vec(5));
+  u_use_symbols     : ENTITY work.tb_eth GENERIC MAP (g_technology_dut, c_technology_lcu, FALSE, 0, FALSE, FALSE, FALSE, c_tb_tech_tse_data_type_symbols) PORT MAP (tb_end_vec(0));
+  u_use_counter     : ENTITY work.tb_eth GENERIC MAP (g_technology_dut, c_technology_lcu, FALSE, 0, FALSE, FALSE, FALSE, c_tb_tech_tse_data_type_counter) PORT MAP (tb_end_vec(1));
+  u_use_arp         : ENTITY work.tb_eth GENERIC MAP (g_technology_dut, c_technology_lcu, FALSE, 0,  TRUE, FALSE, FALSE, c_tb_tech_tse_data_type_arp    ) PORT MAP (tb_end_vec(2));
+  u_use_ping        : ENTITY work.tb_eth GENERIC MAP (g_technology_dut, c_technology_lcu, FALSE, 0,  TRUE, FALSE, FALSE, c_tb_tech_tse_data_type_ping   ) PORT MAP (tb_end_vec(3));
+  u_use_udp_0       : ENTITY work.tb_eth GENERIC MAP (g_technology_dut, c_technology_lcu,  TRUE, 0,  TRUE, FALSE, FALSE, c_tb_tech_tse_data_type_udp    ) PORT MAP (tb_end_vec(4));
+  u_use_udp_1       : ENTITY work.tb_eth GENERIC MAP (g_technology_dut, c_technology_lcu,  TRUE, 1,  TRUE, FALSE, FALSE, c_tb_tech_tse_data_type_udp    ) PORT MAP (tb_end_vec(5));
+  u_use_udp_flush   : ENTITY work.tb_eth GENERIC MAP (g_technology_dut, c_technology_lcu,  TRUE, 1,  TRUE,  TRUE, FALSE, c_tb_tech_tse_data_type_udp    ) PORT MAP (tb_end_vec(6));
   
   tb_end <= '1' WHEN tb_end_vec=c_tb_end_vec ELSE '0';
   
diff --git a/libraries/technology/tse/hdllib.cfg b/libraries/technology/tse/hdllib.cfg
index 72a5ce131ed6b2709cd31234ac31e6f8831a3181..16e4ca1d98ab05f818c7883830d9f5e52afa986a 100644
--- a/libraries/technology/tse/hdllib.cfg
+++ b/libraries/technology/tse/hdllib.cfg
@@ -35,9 +35,10 @@ test_bench_files =
     sim_tse.vhd
     tb_tech_tse_pkg.vhd
     tb_tech_tse.vhd
+    tb_tb_tech_tse.vhd
 
 regression_test_vhdl = 
-    tb_tech_tse.vhd
+    tb_tb_tech_tse.vhd
 
 
 [modelsim_project_file]
diff --git a/libraries/technology/tse/sim_tse.vhd b/libraries/technology/tse/sim_tse.vhd
index 9ae20025277303acf57013b3d96e0796e6c639c6..425729e11a0e5d0ece6791b3efc30c4a111096bc 100644
--- a/libraries/technology/tse/sim_tse.vhd
+++ b/libraries/technology/tse/sim_tse.vhd
@@ -23,9 +23,15 @@
 -- Author:
 -- . Daniel van der Schuur
 -- Purpose:
--- . Drop-in simulation model for tech_tse.vhd.
+-- . Drop-in behavioral simulation model for tech_tse.vhd.
 -- Description:
--- . Basically just a wrapper around sim_tse.
+-- . The simulation model is based on tech_transceiver_lib.sim_transceiver_gx
+--   and is about a factor 4 faster than the IP simulation model.
+-- Remark:
+-- . Default use g_tx_crc=TRUE, to model TSE IP in ETH on UniBoard1, UniBoard2
+-- . Connect eth_txp/eth_rxp directly to host rxp/txp without a TRANSPORT delay,
+--   because the sim_transceiver_gx model requries that both sides of a link
+--   are in phase.
 
 LIBRARY IEEE, common_lib, dp_lib, tech_transceiver_lib;
 USE IEEE.std_logic_1164.ALL;
@@ -37,6 +43,7 @@ USE work.tech_tse_pkg.ALL;
 ENTITY sim_tse IS 
   GENERIC(
     g_tx         : BOOLEAN;
+    g_tx_crc     : BOOLEAN := TRUE;  -- model append CRC by TSE MAC, CRC value = 0
     g_rx         : BOOLEAN
   );      
   PORT(
@@ -77,17 +84,34 @@ END sim_tse;
 
 ARCHITECTURE str OF sim_tse IS
 
+  CONSTANT c_crc_sz : NATURAL := 4;  -- CRC word has 4 octets
+
   SIGNAL tr_clk     : STD_LOGIC;
   SIGNAL tr_rst     : STD_LOGIC;
 
   SIGNAL tx_snk_rst : STD_LOGIC;
   SIGNAL rx_src_rst : STD_LOGIC;
 
-  SIGNAL sim_transceiver_gx_tx_snk_in_arr  : t_dp_sosi_arr(0 DOWNTO 0);
-  SIGNAL sim_transceiver_gx_tx_snk_out_arr : t_dp_siso_arr(0 DOWNTO 0);
+  SIGNAL tx_fifo_sosi  : t_dp_sosi := c_dp_sosi_rst;
+  SIGNAL tx_fifo_siso  : t_dp_siso := c_dp_siso_hold;
+  
+  TYPE t_reg IS RECORD
+    crc_sosi : t_dp_sosi;
+    crc_cnt  : NATURAL RANGE 0 TO c_crc_sz;
+  END RECORD;
+  
+  SIGNAL crc_siso      : t_dp_siso := c_dp_siso_hold;
+  SIGNAL r             : t_reg;
+  SIGNAL nxt_r         : t_reg;
+
+  SIGNAL tx_pkt_sosi   : t_dp_sosi := c_dp_sosi_rst;
+  SIGNAL tx_pkt_siso   : t_dp_siso := c_dp_siso_hold;
+  
+  SIGNAL gx_tx_snk_in_arr  : t_dp_sosi_arr(0 DOWNTO 0);
+  SIGNAL gx_tx_snk_out_arr : t_dp_siso_arr(0 DOWNTO 0);
 
-  SIGNAL sim_transceiver_gx_rx_src_out_arr : t_dp_sosi_arr(0 DOWNTO 0);
-  SIGNAL sim_transceiver_gx_rx_src_in_arr  : t_dp_siso_arr(0 DOWNTO 0);
+  SIGNAL gx_rx_src_out_arr : t_dp_sosi_arr(0 DOWNTO 0);
+  SIGNAL gx_rx_src_in_arr  : t_dp_siso_arr(0 DOWNTO 0);
 
 BEGIN
 
@@ -123,10 +147,95 @@ BEGIN
     snk_in      => tx_snk_in,
     snk_out     => tx_snk_out,
 
-    src_out     => sim_transceiver_gx_tx_snk_in_arr(0),
-    src_in      => sim_transceiver_gx_tx_snk_out_arr(0)
+    src_out     => tx_fifo_sosi,
+    src_in      => tx_fifo_siso
   );        
 
+  no_tx_crc : IF NOT g_tx_crc GENERATE
+    gx_tx_snk_in_arr(0) <= tx_fifo_sosi;
+    tx_fifo_siso        <= gx_tx_snk_out_arr(0);
+  END GENERATE;
+  
+  gen_tx_crc : IF g_tx_crc GENERATE
+    -----------------------------------------------------------------------------
+    -- Model Tx CRC by appending four zero octets at end of Tx packet
+    -----------------------------------------------------------------------------
+    --
+    -- The p_crc_comb implementation is based on the following timing diagram:
+    --                        _   _   _   _   _   _   _   _   _
+    --   tr_clk             _| |_| |_| |_| |_| |_| |_| |_| |_| 
+    --                      ___________________________________
+    --   tx_fifo_siso.ready 
+    --                      _________
+    --   tx_fifo_sosi.valid          |_________________________
+    --                            ___
+    --   tx_fifo_sosi.eop   _____|   |_________________________
+    --                      _____                 _____________
+    --   crc_siso.ready          |_______________|
+    --                                _______________
+    --   crc_sosi.valid     _________|               |_________  
+    --                                            ___
+    --   crc_sosi.eop       _____________________|   |_________
+    --                      
+    --   crc_cnt             | 0 | 0 | 1 | 2 | 3 | 0 | 0 | 0 | 
+    --                      _________________________
+    --   tx_pkt_sosi.valid                           |_________
+    --                                            ___
+    --   tx_pkt_sosi.eop    _____________________|   |_________
+    --                         
+   
+    tx_fifo_siso.ready <= tx_pkt_siso.ready AND crc_siso.ready;
+    
+    p_tx_pkt_sosi : PROCESS(tx_fifo_sosi, r)
+    BEGIN
+      -- start with tx_fifo_sosi packet
+      tx_pkt_sosi <= tx_fifo_sosi;
+      -- append CRC = 0 at end of tx_fifo_sosi packet
+      IF r.crc_sosi.valid = '1' THEN
+        tx_pkt_sosi.data <= TO_DP_DATA(0);
+      END IF;
+      tx_pkt_sosi.valid <= tx_fifo_sosi.valid OR r.crc_sosi.valid;
+      tx_pkt_sosi.eop   <= r.crc_sosi.eop;
+    END PROCESS;
+    
+    p_crc_comb : PROCESS(tx_fifo_sosi, r)
+      VARIABLE v : t_reg;
+    BEGIN
+      crc_siso.ready <= '1';
+      v := r;
+      v.crc_sosi.valid := '0';
+      v.crc_sosi.eop := '0';
+      IF tx_fifo_sosi.eop = '1' THEN
+        crc_siso.ready <= '0';
+        v.crc_sosi.valid := '1';
+        v.crc_cnt := 1;
+      END IF;
+      IF r.crc_cnt > 0 THEN
+        crc_siso.ready <= '0';
+        v.crc_sosi.valid := '1';
+        v.crc_cnt := r.crc_cnt + 1;
+      END IF;
+      IF r.crc_cnt = c_crc_sz-1 THEN
+        v.crc_sosi.eop := '1';
+        v.crc_cnt := 0;
+      END IF;
+      nxt_r <= v;
+    END PROCESS;
+  
+    p_crc_reg : PROCESS(tr_rst, tr_clk)
+    BEGIN
+      IF tr_rst = '1' THEN
+        r <= (c_dp_sosi_rst, 0);
+      ELSIF rising_edge(tr_clk) THEN
+        r <= nxt_r;    
+      END IF;
+    END PROCESS;
+    
+    gx_tx_snk_in_arr(0) <= tx_pkt_sosi;
+    tx_pkt_siso         <= gx_tx_snk_out_arr(0);
+    
+  END GENERATE;
+  
   -------------------------------------------------------------------------------
   -- Transceiver sim model
   -- . Inside this model, tr_clk = tx_clk = rx_clk. We're using its output 
@@ -148,13 +257,13 @@ BEGIN
     tx_clk(0)       => tr_clk,
     tx_rst(0)       => tr_rst,
 
-    tx_sosi_arr     => sim_transceiver_gx_tx_snk_in_arr,
-    tx_siso_arr     => sim_transceiver_gx_tx_snk_out_arr,
+    tx_sosi_arr     => gx_tx_snk_in_arr,
+    tx_siso_arr     => gx_tx_snk_out_arr,
     tx_dataout(0)   => eth_txp,
 
     rx_datain(0)    => eth_rxp,
-    rx_sosi_arr     => sim_transceiver_gx_rx_src_out_arr,
-    rx_siso_arr     => sim_transceiver_gx_rx_src_in_arr
+    rx_sosi_arr     => gx_rx_src_out_arr,
+    rx_siso_arr     => gx_rx_src_in_arr
   );  
 
   -------------------------------------------------------------------------------
@@ -186,8 +295,8 @@ BEGIN
     rd_rst      => rx_src_rst,
     rd_clk      => rx_src_clk,
 
-    snk_in      => sim_transceiver_gx_rx_src_out_arr(0),
-    snk_out     => sim_transceiver_gx_rx_src_in_arr(0),
+    snk_in      => gx_rx_src_out_arr(0),
+    snk_out     => gx_rx_src_in_arr(0),
 
     src_out     => rx_src_out,
     src_in      => rx_src_in
diff --git a/libraries/technology/tse/tb_tb_tech_tse.vhd b/libraries/technology/tse/tb_tb_tech_tse.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..1ad6cdc0e6456d141e36ab00fa3a90029ba03c6b
--- /dev/null
+++ b/libraries/technology/tse/tb_tb_tech_tse.vhd
@@ -0,0 +1,73 @@
+-------------------------------------------------------------------------------
+--
+-- 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: E. Kooistra
+-- Purpose: Multi-testbench for tech_tse
+-- Description:
+--   Verify tech_tse for different data types
+-- Usage:
+--   > as 3
+--   > run -all
+
+LIBRARY IEEE, technology_lib, tech_tse_lib;
+USE IEEE.std_logic_1164.ALL;
+USE technology_lib.technology_pkg.ALL;
+USE technology_lib.technology_select_pkg.ALL;
+USE tech_tse_lib.tb_tech_tse_pkg.ALL;
+
+
+ENTITY tb_tb_tech_tse IS
+END tb_tb_tech_tse;
+
+
+ARCHITECTURE tb OF tb_tb_tech_tse IS
+
+  CONSTANT c_tech : NATURAL := c_tech_select_default;
+  
+  CONSTANT c_tb_end_vec : STD_LOGIC_VECTOR(15 DOWNTO 0) := (OTHERS=>'1');
+  SIGNAL   tb_end_vec   : STD_LOGIC_VECTOR(15 DOWNTO 0) := c_tb_end_vec;  -- sufficiently long to fit all tb instances
+  SIGNAL   tb_end       : STD_LOGIC := '0';
+  
+BEGIN
+
+-- g_technology : NATURAL := c_tech_select_default;
+-- --   g_data_type = c_tb_tech_tse_data_type_symbols  = 0
+-- --   g_data_type = c_tb_tech_tse_data_type_counter  = 1
+-- g_data_type  : NATURAL := c_tb_tech_tse_data_type_symbols;
+-- g_sim        : BOOLEAN := TRUE;
+-- g_sim_level  : NATURAL := 1;    -- 0 = use IP; 1 = use fast serdes model;
+-- g_tb_end     : BOOLEAN := TRUE  -- when TRUE then tb_end ends this simulation, else a higher multi-testbench will end the simulation
+  
+  u_ip           : ENTITY work.tb_tech_tse GENERIC MAP (c_tech, c_tb_tech_tse_data_type_symbols, FALSE, 0, FALSE) PORT MAP (tb_end_vec(0));
+  u_sim_level_0  : ENTITY work.tb_tech_tse GENERIC MAP (c_tech, c_tb_tech_tse_data_type_symbols,  TRUE, 0, FALSE) PORT MAP (tb_end_vec(1));
+  u_sim_level_1  : ENTITY work.tb_tech_tse GENERIC MAP (c_tech, c_tb_tech_tse_data_type_symbols,  TRUE, 1, FALSE) PORT MAP (tb_end_vec(2));
+  
+  tb_end <= '1' WHEN tb_end_vec=c_tb_end_vec ELSE '0';
+  
+  p_tb_end : PROCESS
+  BEGIN
+    WAIT UNTIL tb_end='1';
+    WAIT FOR 1 ns;
+    REPORT "Multi tb simulation finished." SEVERITY FAILURE;
+    WAIT;
+  END PROCESS;
+END tb;
diff --git a/libraries/technology/tse/tb_tech_tse.vhd b/libraries/technology/tse/tb_tech_tse.vhd
index 70e680667963218ca7ba41abaed4edbf96dae500..ce074ce5673c8b798bdc26a7f934adb1e5cebddd 100644
--- a/libraries/technology/tse/tb_tech_tse.vhd
+++ b/libraries/technology/tse/tb_tech_tse.vhd
@@ -48,7 +48,13 @@ ENTITY tb_tech_tse IS
     g_technology : NATURAL := c_tech_select_default;
     --   g_data_type = c_tb_tech_tse_data_type_symbols  = 0
     --   g_data_type = c_tb_tech_tse_data_type_counter  = 1
-    g_data_type  : NATURAL := c_tb_tech_tse_data_type_symbols
+    g_data_type  : NATURAL := c_tb_tech_tse_data_type_symbols;
+    g_sim        : BOOLEAN := TRUE;
+    g_sim_level  : NATURAL := 1;    -- 0 = use IP; 1 = use fast serdes model;
+    g_tb_end     : BOOLEAN := TRUE  -- when TRUE then tb_end ends this simulation, else a higher multi-testbench will end the simulation
+  );
+  PORT (
+    tb_end : OUT STD_LOGIC
   );
 END tb_tech_tse;
 
@@ -60,7 +66,7 @@ ARCHITECTURE tb OF tb_tech_tse IS
   
   CONSTANT sys_clk_period       : TIME := 10 ns;  -- 100 MHz
   CONSTANT eth_clk_period       : TIME :=  8 ns;  -- 125 MHz
-  CONSTANT cable_delay          : TIME := 12 ns;
+  CONSTANT cable_delay          : TIME := sel_a_b(g_sim_level=0, 12 ns, 0 ns);
 
   CONSTANT c_promis_en          : BOOLEAN := FALSE;
   CONSTANT c_tx_ready_latency   : NATURAL := c_tech_tse_tx_ready_latency;  -- 0, 1 are supported, must match TSE MAC c_tech_tse_tx_ready_latency
@@ -84,7 +90,6 @@ ARCHITECTURE tb OF tb_tech_tse IS
   
   -- Clocks and reset
   SIGNAL rx_end            : STD_LOGIC := '0';
-  SIGNAL tb_end            : STD_LOGIC := '0';
   SIGNAL eth_clk           : STD_LOGIC := '0';  -- tse reference clock
   SIGNAL sys_clk           : STD_LOGIC := '0';  -- system clock
   SIGNAL st_clk            : STD_LOGIC;         -- stream clock
@@ -214,7 +219,9 @@ BEGIN
   dut : ENTITY work.tech_tse
   GENERIC MAP (
     g_technology => g_technology,
-    g_ETH_PHY    => "LVDS" -- "LVDS" (default): uses LVDS IOs for ctrl_unb_common, "XCVR": uses tranceiver PHY
+    g_ETH_PHY    => "LVDS",  -- "LVDS" (default): uses LVDS IOs for ctrl_unb_common, "XCVR": uses tranceiver PHY
+    g_sim        => g_sim,
+    g_sim_level  => g_sim_level     -- 0 = use IP; 1 = use fast serdes model;
   )
   PORT MAP (
     -- Clocks and reset
@@ -259,6 +266,7 @@ BEGIN
   
   p_verify : PROCESS
   BEGIN
+    tb_end <= '0';
     WAIT UNTIL rx_end='1';
     -- Verify that all transmitted packets have been received
     IF tx_pkt_cnt=0 THEN
@@ -269,14 +277,13 @@ BEGIN
       REPORT "Not all transmitted packets were received." SEVERITY ERROR;
     END IF;
     tb_end <= '1';
-    WAIT;
-  END PROCESS;
-  
-  p_tb_end : PROCESS  
-  BEGIN
-    WAIT UNTIL tb_end='1';
+    
     WAIT FOR 1 ns;
-    REPORT "Simulation finished." SEVERITY FAILURE;
+    IF g_tb_end=FALSE THEN
+      REPORT "Tb simulation finished." SEVERITY NOTE;
+    ELSE
+      REPORT "Tb simulation finished." SEVERITY FAILURE;
+    END IF;
     WAIT;
   END PROCESS;
   
diff --git a/libraries/technology/tse/tech_tse.vhd b/libraries/technology/tse/tech_tse.vhd
index 2afb13310bedc7f45b639377ae86dce758164165..8f9ef2a1969d0ad8969015e3149699b40944e757 100644
--- a/libraries/technology/tse/tech_tse.vhd
+++ b/libraries/technology/tse/tech_tse.vhd
@@ -34,7 +34,7 @@ ENTITY tech_tse IS
     g_technology   : NATURAL := c_tech_select_default;
     g_ETH_PHY      : STRING  := "LVDS"; -- "LVDS" (default): uses LVDS IOs for ctrl_unb_common, "XCVR": uses tranceiver PHY
     g_sim          : BOOLEAN := FALSE;
-    g_sim_level    : NATURAL := 0;     -- 0 = use IP; 1 = use fast serdes model;
+    g_sim_level    : NATURAL := 0;     -- 0 = use IP model (equivalent to g_sim = FALSE); 1 = use fast serdes model;
     g_sim_tx       : BOOLEAN := TRUE;
     g_sim_rx       : BOOLEAN := TRUE
   );