diff --git a/libraries/base/dp/hdllib.cfg b/libraries/base/dp/hdllib.cfg
index 48865ad1dbd81ac2513b08448297ce8eb0e75d85..12f9c56edd7f921d5751fab385dcaca33cfa8365 100644
--- a/libraries/base/dp/hdllib.cfg
+++ b/libraries/base/dp/hdllib.cfg
@@ -36,6 +36,7 @@ synth_files =
     src/vhdl/dp_block_select.vhd
     src/vhdl/dp_block_validate_channel.vhd
     src/vhdl/mms_dp_block_select.vhd
+    src/vhdl/dp_calculate_crc.vhd
     src/vhdl/dp_force_data_parallel.vhd
     src/vhdl/mms_dp_force_data_parallel.vhd
     src/vhdl/mms_dp_force_data_parallel_arr.vhd
@@ -215,6 +216,7 @@ test_bench_files =
     tb/vhdl/tb_dp_block_gen_valid_arr.vhd
     tb/vhdl/tb_dp_block_from_mm.vhd
     tb/vhdl/tb_dp_block_validate_channel.vhd
+    tb/vhdl/tb_dp_calculate_crc.vhd
     tb/vhdl/tb_dp_bsn_align.vhd
     tb/vhdl/tb_mms_dp_bsn_align.vhd
     tb/vhdl/tb_dp_bsn_align_v2.vhd
@@ -305,6 +307,7 @@ test_bench_files =
     tb/vhdl/tb_tb_dp_block_gen_valid_arr.vhd
     tb/vhdl/tb_tb_dp_block_from_mm.vhd
     tb/vhdl/tb_tb_dp_block_validate_channel.vhd
+    tb/vhdl/tb_tb_dp_calculate_crc.vhd
     tb/vhdl/tb_tb_dp_bsn_align.vhd
     tb/vhdl/tb_tb_dp_bsn_align_v2.vhd
     tb/vhdl/tb_tb_mmp_dp_bsn_align_v2.vhd
@@ -371,6 +374,7 @@ regression_test_vhdl =
     tb/vhdl/tb_mms_dp_bsn_source.vhd
     tb/vhdl/tb_mms_dp_bsn_source_v2.vhd
     tb/vhdl/tb_mmp_dp_bsn_sync_scheduler.vhd
+    tb/vhdl/tb_tb_dp_calculate_crc.vhd
     tb/vhdl/tb_tb_dp_block_select.vhd
     tb/vhdl/tb_tb_dp_block_validate_length.vhd
     tb/vhdl/tb_tb_dp_block_validate_err.vhd
diff --git a/libraries/base/dp/src/vhdl/dp_calculate_crc.vhd b/libraries/base/dp/src/vhdl/dp_calculate_crc.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..0d5b8f137dc334e1a872abd527375ebd853216b9
--- /dev/null
+++ b/libraries/base/dp/src/vhdl/dp_calculate_crc.vhd
@@ -0,0 +1,116 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright 2023
+-- 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
+-- Date: 17 April 2023
+-- Purpose: Calculate CRC per block of data
+-- Description:
+--   The calculated blk_crc of a block is available immediately after the
+--   snk_in.eop of that block.
+
+LIBRARY IEEE, common_lib, easics_lib;
+USE IEEE.std_logic_1164.ALL;
+USE common_lib.common_pkg.ALL;
+USE work.dp_stream_pkg.ALL;
+
+USE easics_lib.PCK_CRC8_D8.ALL;
+USE easics_lib.PCK_CRC16_D16.ALL;
+USE easics_lib.PCK_CRC28_D28.ALL;
+USE easics_lib.PCK_CRC32_D32.ALL;
+USE easics_lib.PCK_CRC32_D64.ALL;
+
+
+ENTITY dp_calculate_crc IS
+  GENERIC (
+    g_data_w  : NATURAL := 32;
+    g_crc_w   : NATURAL := 32
+  );
+  PORT (
+    rst          : IN  STD_LOGIC;
+    clk          : IN  STD_LOGIC;
+    -- ST sink
+    snk_in       : IN  t_dp_sosi;
+    blk_crc      : OUT STD_LOGIC_VECTOR(g_crc_w-1 DOWNTO 0)
+  );
+END dp_calculate_crc;
+
+
+ARCHITECTURE rtl OF dp_calculate_crc IS
+
+  CONSTANT c_crc_init : STD_LOGIC_VECTOR(g_crc_w-1 DOWNTO 0) := (OTHERS=>'1');
+  
+  FUNCTION func_next_crc(data, crc : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
+    VARIABLE v_crc : STD_LOGIC_VECTOR(g_crc_w-1 DOWNTO 0) := c_crc_init;
+  BEGIN
+    IF    g_data_w =  8 AND g_crc_w =  8 THEN v_crc := nextCRC8_D8(data, crc);
+    ELSIF g_data_w = 16 AND g_crc_w = 16 THEN v_crc := nextCRC16_D16(data, crc);
+    ELSIF g_data_w = 28 AND g_crc_w = 28 THEN v_crc := nextCRC28_D28(data, crc);
+    ELSIF g_data_w = 32 AND g_crc_w = 32 THEN v_crc := nextCRC32_D32(data, crc);
+    ELSIF g_data_w = 64 AND g_crc_w = 32 THEN v_crc := nextCRC32_D64(data, crc);
+    ELSE
+      REPORT "Data width and CRC width combination not supported (yet)" SEVERITY FAILURE;
+    END IF;
+    RETURN v_crc;
+  END func_next_crc;
+
+  SIGNAL data         : STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0);
+  SIGNAL calc_crc     : STD_LOGIC_VECTOR(g_crc_w-1 DOWNTO 0);
+  SIGNAL nxt_calc_crc : STD_LOGIC_VECTOR(g_crc_w-1 DOWNTO 0);
+  SIGNAL i_blk_crc    : STD_LOGIC_VECTOR(g_crc_w-1 DOWNTO 0);
+  SIGNAL nxt_blk_crc  : STD_LOGIC_VECTOR(g_crc_w-1 DOWNTO 0);
+
+BEGIN
+
+  data <= snk_in.data(g_data_w-1 DOWNTO 0);
+
+  blk_crc <= i_blk_crc;
+
+  p_clk : PROCESS(rst, clk)
+  BEGIN
+    IF rst='1' THEN
+      calc_crc   <= c_crc_init;
+      i_blk_crc  <= c_crc_init;
+    ELSIF rising_edge(clk) THEN
+      calc_crc   <= nxt_calc_crc;
+      i_blk_crc  <= nxt_blk_crc;
+    END IF;
+  END PROCESS;
+
+  p_crc : PROCESS(data, calc_crc, i_blk_crc, snk_in)
+    VARIABLE v_crc : STD_LOGIC_VECTOR(g_crc_w-1 DOWNTO 0);
+  BEGIN
+    v_crc := func_next_crc(data, calc_crc);
+
+    -- Calculate CRC per block
+    nxt_calc_crc <= calc_crc;
+    IF snk_in.sop = '1' THEN  -- restart CRC at begin of block
+      nxt_calc_crc <= func_next_crc(data, c_crc_init);
+    ELSIF snk_in.valid = '1' THEN  -- calculate CRC during block
+      nxt_calc_crc <= v_crc;
+    END IF;
+
+    -- Hold CRC of previous block, available after eop
+    nxt_blk_crc <= i_blk_crc;
+    IF snk_in.eop = '1' THEN
+      nxt_blk_crc <= v_crc;
+    END IF;
+  END PROCESS;
+
+END rtl;
diff --git a/libraries/base/dp/tb/vhdl/tb_dp_calculate_crc.vhd b/libraries/base/dp/tb/vhdl/tb_dp_calculate_crc.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..4af23cbdfa3aca5f9a2dca7bc319a8df55f1b794
--- /dev/null
+++ b/libraries/base/dp/tb/vhdl/tb_dp_calculate_crc.vhd
@@ -0,0 +1,154 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright 2023
+-- 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: Eric Kooistra
+-- Date: 17 Apr 2023
+-- Purpose:
+-- . Test bench for dp_calculate_crc.
+-- Description:
+--   Verify that CRC is the same if the data in the blocks is the same, for
+--   one specific combination of g_data_w, g_crc_w and c_nof_data_per_blk.
+--   Assume that CRC calculation itself is OK, because it is used before.
+-- Usage:
+-- . as 5
+-- . run -all
+
+LIBRARY IEEE, common_lib;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.numeric_std.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_str_pkg.ALL;
+USE common_lib.common_lfsr_sequences_pkg.ALL;
+USE common_lib.tb_common_pkg.ALL;
+USE work.dp_stream_pkg.ALL;
+USE work.tb_dp_pkg.ALL;
+
+ENTITY tb_dp_calculate_crc IS
+  GENERIC (
+    g_data_w      : NATURAL := 28;
+    g_crc_w       : NATURAL := 28;
+    g_gap_size    : NATURAL := 10
+  );
+END tb_dp_calculate_crc;
+
+
+ARCHITECTURE tb OF tb_dp_calculate_crc IS
+
+  ------------------------------------------------------------------------------
+  -- Clock & reset
+  ------------------------------------------------------------------------------
+  CONSTANT c_clk_period   : TIME := 5 ns;
+
+  CONSTANT c_nof_sync            : NATURAL :=  1;
+  CONSTANT c_nof_blk_per_sync    : NATURAL :=  5;
+  CONSTANT c_nof_data_per_blk    : NATURAL :=  9;
+  
+  SIGNAL clk              : STD_LOGIC := '1';
+  SIGNAL rst              : STD_LOGIC := '1';
+  SIGNAL stimuli_end      : STD_LOGIC := '0';
+  SIGNAL tb_end           : STD_LOGIC := '0';
+  
+  SIGNAL stimuli_sosi     : t_dp_sosi;
+  SIGNAL snk_in           : t_dp_sosi;
+  
+  SIGNAL blk_crc          : STD_LOGIC_VECTOR(g_crc_w-1 DOWNTO 0);
+
+  SIGNAL new_crc          : STD_LOGIC;
+
+  -- Expected specific value obtained from simulation
+  SIGNAL exp_crc_28       : STD_LOGIC_VECTOR(28-1 DOWNTO 0) := X"ABDE9EB";
+
+BEGIN
+  
+  ------------------------------------------------------------------------------
+  -- Clock & reset
+  ------------------------------------------------------------------------------
+  clk <= (NOT clk) OR tb_end AFTER c_clk_period/2;
+  rst <= '1', '0' AFTER c_clk_period*7;
+  
+  ------------------------------------------------------------------------------
+  -- Stimuli: 
+  ------------------------------------------------------------------------------
+
+  -- Generate snk_in with data frames
+  u_stimuli : ENTITY work.dp_stream_stimuli
+  GENERIC MAP (
+    g_sync_period => c_nof_blk_per_sync,
+    g_nof_repeat  => c_nof_blk_per_sync * c_nof_sync,
+    g_pkt_len     => c_nof_data_per_blk,
+    g_pkt_gap     => g_gap_size
+  )
+  PORT MAP (
+    rst           => rst,
+    clk           => clk,
+  
+    -- Generate stimuli
+    src_out       => stimuli_sosi,
+
+    -- End of stimuli
+    tb_end        => stimuli_end
+  );
+
+  -- Use same dat for every block to verify restart of CRC calculation
+  p_snk_in : PROCESS(stimuli_sosi)
+  BEGIN
+    snk_in      <= stimuli_sosi;
+    snk_in.data <= TO_DP_DATA(TO_UINT(stimuli_sosi.data) MOD c_nof_data_per_blk);
+  END PROCESS;
+
+  ------------------------------------------------------------------------------
+  -- DUT
+  ------------------------------------------------------------------------------     
+  u_crc : ENTITY work.dp_calculate_crc
+  GENERIC MAP (
+    g_data_w => g_data_w,
+    g_crc_w  => g_crc_w
+  )
+  PORT MAP (
+    rst      => rst,
+    clk      => clk,
+    -- ST sink
+    snk_in   => snk_in,
+    blk_crc  => blk_crc
+  );
+
+  ------------------------------------------------------------------------------
+  -- Verifycation
+  ------------------------------------------------------------------------------
+  new_crc <= snk_in.eop WHEN rising_edge(clk);
+
+  p_verify : PROCESS(clk)
+  BEGIN
+    IF rising_edge(clk) THEN
+      IF new_crc = '1' THEN
+        --IF g_data_w = 28 AND g_crc_w = 28 AND c_nof_data_per_blk = 9 THEN
+          IF blk_crc = exp_crc_28 THEN
+            REPORT "OK CRC value." SEVERITY NOTE;
+          ELSE
+            REPORT "Wrong CRC value." SEVERITY ERROR;
+          END IF;
+        --END IF;
+      END IF;
+    END IF;
+  END PROCESS;
+
+  tb_end <= '0', stimuli_end AFTER 10*c_clk_period;
+  
+END tb;
diff --git a/libraries/base/dp/tb/vhdl/tb_tb_dp_calculate_crc.vhd b/libraries/base/dp/tb/vhdl/tb_tb_dp_calculate_crc.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..17713141fe5edf7b711c05a65ab6d92772e7344a
--- /dev/null
+++ b/libraries/base/dp/tb/vhdl/tb_tb_dp_calculate_crc.vhd
@@ -0,0 +1,57 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright 2023
+-- 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: Eric Kooistra
+-- Date: 17 Apr 2023
+-- Purpose:
+-- . Multi test bench for dp_calculate_crc.
+-- Description:
+-- Usage:
+-- . as 5
+-- . run -all
+
+LIBRARY IEEE, common_lib;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.numeric_std.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_str_pkg.ALL;
+USE common_lib.common_lfsr_sequences_pkg.ALL;
+USE common_lib.tb_common_pkg.ALL;
+USE work.dp_stream_pkg.ALL;
+USE work.tb_dp_pkg.ALL;
+
+ENTITY tb_tb_dp_calculate_crc IS
+END tb_tb_dp_calculate_crc;
+
+
+ARCHITECTURE tb OF tb_tb_dp_calculate_crc IS
+
+  SIGNAL tb_end : STD_LOGIC := '0';  -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end'
+
+BEGIN
+  
+  --  g_data_w      : NATURAL := 28;
+  --  g_crc_w       : NATURAL := 28;
+  --  g_gap_size    : NATURAL := 10
+
+  u_no_gap : ENTITY work.tb_dp_calculate_crc GENERIC MAP (28, 28, 0);
+  u_gap    : ENTITY work.tb_dp_calculate_crc GENERIC MAP (28, 28, 10);
+
+END tb;
diff --git a/libraries/external/easics/hdllib.cfg b/libraries/external/easics/hdllib.cfg
index d507bd6a5bb7f49cbd926d327a4d231e12a3c043..75ed2ad88540f3d415bd70b13f3efe6d2cc1fb51 100644
--- a/libraries/external/easics/hdllib.cfg
+++ b/libraries/external/easics/hdllib.cfg
@@ -23,15 +23,18 @@ synth_files =
     src/vhdl/PCK_CRC32_D20.vhd
     src/vhdl/PCK_CRC32_D24.vhd
     src/vhdl/PCK_CRC32_D32.vhd
+    src/vhdl/PCK_CRC32_D32_eth.vhd
     src/vhdl/PCK_CRC32_D36.vhd
     src/vhdl/PCK_CRC32_D40.vhd
     src/vhdl/PCK_CRC32_D48.vhd
     src/vhdl/PCK_CRC32_D64.vhd
+    src/vhdl/PCK_CRC32_D64_eth.vhd
     src/vhdl/PCK_CRC32_D72.vhd
     src/vhdl/PCK_CRC32_D128.vhd
     src/vhdl/PCK_CRC32_D256.vhd
     src/vhdl/PCK_CRC32_D512.vhd
     src/vhdl/PCK_CRC32_D1024.vhd
+    src/vhdl/PCK_CRC28_D28.vhd
     src/vhdl/PCK_CRC16_D4.vhd
     src/vhdl/PCK_CRC16_D8.vhd
     src/vhdl/PCK_CRC16_D9.vhd
@@ -40,7 +43,11 @@ synth_files =
     src/vhdl/PCK_CRC16_D18.vhd
     src/vhdl/PCK_CRC16_D20.vhd
     src/vhdl/PCK_CRC16_D24.vhd
+    src/vhdl/PCK_CRC16_D28.vhd
+    src/vhdl/PCK_CRC16_D28_usb.vhd
     src/vhdl/PCK_CRC16_D32.vhd
+    src/vhdl/PCK_CRC16_D32_usb.vhd
+    src/vhdl/PCK_CRC16_D32_x25.vhd
     src/vhdl/PCK_CRC16_D36.vhd
     src/vhdl/PCK_CRC16_D48.vhd
     src/vhdl/PCK_CRC16_D64.vhd