diff --git a/libraries/io/eth/src/vhdl/eth_tester_rx.vhd b/libraries/io/eth/src/vhdl/eth_tester_rx.vhd
index 7342cbedfaf04361ef60ba18867371acbe802619..1a4463bf01485c53f1ff5cbd7d91e253f33908b1 100644
--- a/libraries/io/eth/src/vhdl/eth_tester_rx.vhd
+++ b/libraries/io/eth/src/vhdl/eth_tester_rx.vhd
@@ -19,7 +19,7 @@
 -------------------------------------------------------------------------------
 -- AUthor: E. Kooistra
 -- Purpose: Test the 1GbE interface by sending and counting received packets.
--- Description: Part of eth_tester, see detailed design in [1]
+-- Description: Rx part of eth_tester, see detailed design in [1]
 --
 -- References:
 -- [1] https://support.astron.nl/confluence/display/L2M/L6+FWLIB+Design+Document%3A+ETH+tester+unit+for+1GbE
@@ -29,6 +29,7 @@ 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 work.eth_tester_pkg.ALL;
 
@@ -60,13 +61,60 @@ ARCHITECTURE str OF eth_tester_rx IS
 
   CONSTANT c_nof_total_counts     : NATURAL := 2;
 
-  SIGNAL decoded_sosi             : t_dp_sosi;
-  SIGNAL crc_corrupt              : STD_LOGIC := '0';
+  SIGNAL rx_offload_sosi     : t_dp_sosi;
+  SIGNAL decoded_sosi        : t_dp_sosi;
+  SIGNAL crc_corrupt         : STD_LOGIC := '0';
 
-  SIGNAL in_strobe_arr            : STD_LOGIC_VECTOR(c_nof_total_counts-1 DOWNTO 0);
+  SIGNAL in_strobe_arr       : STD_LOGIC_VECTOR(c_nof_total_counts-1 DOWNTO 0);
+
+  SIGNAL hdr_fields_out_slv  : STD_LOGIC_VECTOR(1023 DOWNTO 0);
+  SIGNAL hdr_fields_raw_slv  : STD_LOGIC_VECTOR(1023 DOWNTO 0);
+  SIGNAL hdr_fields_out_rec  : t_eth_tester_header;
+  SIGNAL hdr_fields_raw_rec  : t_eth_tester_header;
 
 BEGIN
 
+  -------------------------------------------------------------------------------
+  -- Rx ETH/UDP/IP packets with packed BG data
+  -------------------------------------------------------------------------------
+
+  u_dp_offload_rx : ENTITY dp_lib.dp_offload_rx
+  GENERIC MAP (
+    g_nof_streams   => 1,
+    g_data_w        => c_word_w,
+    g_symbol_w      => c_octet_w,
+    g_hdr_field_arr => c_eth_tester_hdr_field_arr,
+    g_remove_crc    => FALSE,
+    g_crc_nof_words => 1
+  )
+  PORT MAP (
+    mm_rst    => mm_rst,
+    mm_clk    => mm_clk,
+
+    dp_rst    => st_rst,
+    dp_clk    => st_clk,
+
+    snk_in_arr(0)         => rx_udp_sosi,
+    src_out_arr(0)        => rx_offload_sosi,
+
+    hdr_fields_out_arr(0) => hdr_fields_out_slv,  -- Valid at src_out_arr(i).sop, use for sosi.sync
+    hdr_fields_raw_arr(0) => hdr_fields_raw_slv   -- Valid at src_out_arr(i).sop and beyond, use for sosi.bsn
+  );
+
+  -- View record in Wave Window
+  hdr_fields_out_rec <= func_eth_tester_map_header(hdr_fields_out_slv);
+  hdr_fields_raw_rec <= func_eth_tester_map_header(hdr_fields_raw_slv);
+
+  p_set_meta: PROCESS(rx_offload_sosi, hdr_fields_out_slv, hdr_fields_raw_slv)
+  BEGIN
+    decoded_sosi      <= rx_offload_sosi;
+    decoded_sosi.sync <=            sl(hdr_fields_out_slv(field_hi(c_eth_tester_hdr_field_arr, "dp_sync") DOWNTO field_lo(c_eth_tester_hdr_field_arr, "dp_sync")));
+    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;
+
+  -------------------------------------------------------------------------------
+  -- Rx packet monitors
+  -------------------------------------------------------------------------------
 
   u_mms_dp_bsn_monitor_v2 : ENTITY dp_lib.mms_dp_bsn_monitor_v2
   GENERIC MAP (
@@ -102,8 +150,8 @@ BEGIN
     END IF;
   END PROCESS;
 
-  in_strobe_arr(0) <= decoded_sosi.sop;
-  in_strobe_arr(1) <= crc_corrupt;
+  in_strobe_arr(0) <= decoded_sosi.sop;  -- count total nof Rx packets
+  in_strobe_arr(1) <= crc_corrupt;       -- count total nof corrupted Rx packets
 
   u_dp_strobe_total_count : ENTITY dp_lib.dp_strobe_total_count
   GENERIC MAP (