diff --git a/libraries/io/eth/src/vhdl/eth_tester_rx.vhd b/libraries/io/eth/src/vhdl/eth_tester_rx.vhd
index 1a4463bf01485c53f1ff5cbd7d91e253f33908b1..cf82b173b2913808f2de2ad15514806019f24ddf 100644
--- a/libraries/io/eth/src/vhdl/eth_tester_rx.vhd
+++ b/libraries/io/eth/src/vhdl/eth_tester_rx.vhd
@@ -24,13 +24,14 @@
 -- References:
 -- [1] https://support.astron.nl/confluence/display/L2M/L6+FWLIB+Design+Document%3A+ETH+tester+unit+for+1GbE
 
-LIBRARY IEEE, common_lib, dp_lib;
+LIBRARY IEEE, common_lib, dp_lib, diag_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 common_lib.common_field_pkg.ALL;
 USE dp_lib.dp_stream_pkg.ALL;
+USE diag_lib.diag_pkg.ALL;
 USE work.eth_tester_pkg.ALL;
 
 ENTITY eth_tester_rx IS
@@ -59,10 +60,22 @@ END eth_tester_rx;
 
 ARCHITECTURE str OF eth_tester_rx IS
 
-  CONSTANT c_nof_total_counts     : NATURAL := 2;
+  CONSTANT c_nof_total_counts     : NATURAL := 3;  -- 0 = nof_sop, 1 = nof_valid, 2 = nof_crc_corrupt
 
+  CONSTANT c_empty_w              : NATURAL := 2;  -- for 0, 1, 2, 3 empty octets per word
+  CONSTANT c_fifo_fill            : NATURAL := c_eth_tester_bg_block_len_max / c_word_sz;  -- = 9000 / 4 = 2250
+  CONSTANT c_fifo_size            : NATURAL := true_log_pow2(c_fifo_fill);  -- = 4096
+
+  SIGNAL rx_udp_data         : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
   SIGNAL rx_offload_sosi     : t_dp_sosi;
+  SIGNAL rx_offload_data     : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
   SIGNAL decoded_sosi        : t_dp_sosi;
+  SIGNAL decoded_data        : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+  SIGNAL rx_fifo_siso        : t_dp_siso;
+  SIGNAL rx_fifo_sosi        : t_dp_sosi;
+  SIGNAL rx_fifo_data        : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+  SIGNAL unpacked_sosi       : t_dp_sosi;
+  SIGNAL unpacked_data       : STD_LOGIC_VECTOR(c_octet_w-1 DOWNTO 0);
   SIGNAL crc_corrupt         : STD_LOGIC := '0';
 
   SIGNAL in_strobe_arr       : STD_LOGIC_VECTOR(c_nof_total_counts-1 DOWNTO 0);
@@ -74,6 +87,12 @@ ARCHITECTURE str OF eth_tester_rx IS
 
 BEGIN
 
+  -- View sosi.data in Wave Window
+  rx_udp_data     <= rx_udp_sosi.data(c_word_w-1 DOWNTO 0);
+  rx_offload_data <= rx_offload_sosi.data(c_word_w-1 DOWNTO 0);
+  rx_fifo_data    <= rx_fifo_sosi.data(c_word_w-1 DOWNTO 0);
+  unpacked_data   <= unpacked_sosi.data(c_octet_w-1 DOWNTO 0);
+
   -------------------------------------------------------------------------------
   -- Rx ETH/UDP/IP packets with packed BG data
   -------------------------------------------------------------------------------
@@ -112,6 +131,43 @@ BEGIN
     decoded_sosi.bsn  <= RESIZE_DP_BSN(hdr_fields_raw_slv(field_hi(c_eth_tester_hdr_field_arr, "dp_bsn" ) DOWNTO field_lo(c_eth_tester_hdr_field_arr, "dp_bsn")));
   END PROCESS;
 
+  u_rx_fifo : ENTITY dp_lib.dp_fifo_sc
+  GENERIC MAP (
+    g_data_w         => c_word_w,
+    g_bsn_w          => c_diag_bg_bsn_init_w,  -- = 64 bit
+    g_empty_w        => c_empty_w,
+    g_use_bsn        => TRUE,
+    g_use_empty      => TRUE,
+    g_use_sync       => TRUE,
+    g_fifo_size      => c_fifo_size
+  )
+  PORT MAP (
+    rst         => st_rst,
+    clk         => st_clk,
+    -- ST sink
+    snk_in      => decoded_sosi,
+    -- ST source
+    src_in      => rx_fifo_siso,
+    src_out     => rx_fifo_sosi
+  );
+
+  u_unpack : ENTITY dp_lib.dp_repack_data  -- unpack 32b words into 8b octets
+  GENERIC MAP (
+    g_in_dat_w       => c_word_w,  -- = 32
+    g_in_nof_words   => 1,
+    g_in_symbol_w    => c_octet_w,
+    g_out_dat_w      => c_octet_w,  -- = 8
+    g_out_nof_words  => c_word_sz,  -- = 4
+    g_out_symbol_w   => c_octet_w
+  )
+  PORT MAP (
+    rst              => st_rst,
+    clk              => st_clk,
+    snk_out          => rx_fifo_siso,
+    snk_in           => rx_fifo_sosi,
+    src_out          => unpacked_sosi
+  );
+
   -------------------------------------------------------------------------------
   -- Rx packet monitors
   -------------------------------------------------------------------------------
@@ -133,25 +189,15 @@ BEGIN
     dp_clk         => st_clk,
     ref_sync       => ref_sync,
 
-    in_sosi_arr(0) => decoded_sosi
+    in_sosi_arr(0) => unpacked_sosi
   );
 
-  p_crc_corrupt : PROCESS(st_clk)
-     VARIABLE v_I   : NATURAL;
-     VARIABLE v_crc : STD_LOGIC_VECTOR(c_octet_w-1 DOWNTO 0);
-  BEGIN
-    IF rising_edge(st_clk) THEN
-      v_I := TO_UINT(decoded_sosi.empty(1 DOWNTO 0));
-      v_crc := decoded_sosi.data((v_I + 1)*c_octet_w-1 DOWNTO v_I*c_octet_w);
-      crc_corrupt <= '0';
-      IF decoded_sosi.eop = '1' AND UNSIGNED(v_crc) /= 0 THEN
-        crc_corrupt <= '1';
-      END IF;
-    END IF;
-  END PROCESS;
+  -- Rx CRC result is available at last octet
+  crc_corrupt <= '1' WHEN rising_edge(st_clk) AND unpacked_sosi.eop = '1' AND UNSIGNED(unpacked_data) /= 0 ELSE '0';
 
-  in_strobe_arr(0) <= decoded_sosi.sop;  -- count total nof Rx packets
-  in_strobe_arr(1) <= crc_corrupt;       -- count total nof corrupted Rx packets
+  in_strobe_arr(0) <= unpacked_sosi.sop;    -- count total nof Rx packets
+  in_strobe_arr(1) <= unpacked_sosi.valid;  -- count total nof Rx valid octets
+  in_strobe_arr(2) <= crc_corrupt;          -- count total nof corrupted Rx packets
 
   u_dp_strobe_total_count : ENTITY dp_lib.dp_strobe_total_count
   GENERIC MAP (
@@ -163,7 +209,7 @@ BEGIN
     dp_rst        => st_rst,
     dp_clk        => st_clk,
 
-    ref_sync      => decoded_sosi.sync,
+    ref_sync      => unpacked_sosi.sync,
     in_strobe_arr => in_strobe_arr,
 
     mm_rst        => mm_rst,