diff --git a/libraries/io/eth/hdllib.cfg b/libraries/io/eth/hdllib.cfg
index 7f3ddcef911dd0a4f87e51ec945339df036cb37a..8c9e731ddc9c4a15fd45b4c995e40d4ec43769bf 100644
--- a/libraries/io/eth/hdllib.cfg
+++ b/libraries/io/eth/hdllib.cfg
@@ -7,6 +7,7 @@ hdl_lib_technology =
 synth_files =
     src/vhdl/eth_pkg.vhd
     src/vhdl/eth_checksum.vhd
+    src/vhdl/eth_checksum_10G.vhd
     src/vhdl/eth_hdr_store.vhd
     src/vhdl/eth_hdr_status.vhd
     src/vhdl/eth_hdr_ctrl.vhd
@@ -25,6 +26,7 @@ synth_files =
 test_bench_files = 
     src/vhdl/eth_statistics.vhd
     tb/vhdl/tb_eth_checksum.vhd
+    tb/vhdl/tb_eth_checksum_10G.vhd
     tb/vhdl/tb_eth_crc_ctrl.vhd
     tb/vhdl/tb_eth_hdr.vhd
     tb/vhdl/tb_eth.vhd
diff --git a/libraries/io/eth/src/vhdl/eth_checksum_10G.vhd b/libraries/io/eth/src/vhdl/eth_checksum_10G.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..19e45a8d07443d036b213d5d4c59dd984b8a4db6
--- /dev/null
+++ b/libraries/io/eth/src/vhdl/eth_checksum_10G.vhd
@@ -0,0 +1,177 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2010
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+-------------------------------------------------------------------------------
+
+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;
+USE work.eth_pkg.ALL;
+
+-- Purpose:
+--   Can be used to calculate the checksum for IPv4, ICMP and UDP, provided
+--   the correct words are provided between sop and eop. 
+-- Description:
+--   Determine the 16 bit 1-complement checksum according IPv4 to for the valid
+--   words between snk_in.sop and snk_in.eop, taking in account snk_in.empty.
+--   . For checksum verification the result should be 0 when the words are OK.
+--   . For checksum calculation the result should be used at the checksum field
+--     in the packet header.
+-- Remarks:
+--   . At the snk_in.sop the checksum is initialized to 0.
+--   . At the snk_in.eop the snk_in.empty LSBytes are padded with 0.
+--   . The words do not need to be provided in order, because the checksum is 
+--     based on addition.
+--   . Assume that snk_in.sop and snk_in.eop are only active when snk_in.valid
+--     is active.
+--   . Assume that between packets so from snk_in.eop to next snk_in.sop the
+--     snk_in.valid is inactive and that snk_in.valid is only active for new
+--     data.
+
+ENTITY eth_checksum_10G IS
+  PORT (
+    rst           : IN  STD_LOGIC;
+    clk           : IN  STD_LOGIC;
+    
+    snk_in        : IN  t_dp_sosi;
+    
+    checksum      : OUT STD_LOGIC_VECTOR(c_halfword_w-1 DOWNTO 0);
+    checksum_val  : OUT STD_LOGIC
+  );
+END eth_checksum_10G;
+
+
+ARCHITECTURE rtl OF eth_checksum_10G IS
+
+  SIGNAL in_data          : STD_LOGIC_VECTOR(c_longword_w-1 DOWNTO 0);
+  SIGNAL in_valid         : STD_LOGIC;
+  SIGNAL in_sop           : STD_LOGIC;
+  SIGNAL in_eop           : STD_LOGIC;
+  
+  SIGNAL prev_in_valid    : STD_LOGIC;
+  SIGNAL prev_in_eop      : STD_LOGIC;
+  SIGNAL prev_in_eop_dly  : STD_LOGIC;
+  
+  SIGNAL word_sum_cin     : UNSIGNED(1 DOWNTO 0);             -- carry in
+  SIGNAL word_sum_dat     : UNSIGNED(c_halfword_w-1 DOWNTO 0);
+  SIGNAL word_sum         : UNSIGNED(c_halfword_w+1 DOWNTO 0);
+  SIGNAL nxt_word_sum     : UNSIGNED(c_halfword_w+1 DOWNTO 0);
+  
+  SIGNAL sum_cin          : UNSIGNED(0 DOWNTO 0);             -- carry in
+  SIGNAL sum_dat          : UNSIGNED(c_halfword_w-1 DOWNTO 0);
+  SIGNAL sum              : UNSIGNED(c_halfword_w DOWNTO 0);
+  SIGNAL nxt_sum          : UNSIGNED(c_halfword_w DOWNTO 0);
+  
+  SIGNAL last_dat         : UNSIGNED(c_halfword_w-1 DOWNTO 0);
+  
+  SIGNAL i_checksum       : STD_LOGIC_VECTOR(checksum'RANGE);
+  SIGNAL nxt_checksum     : STD_LOGIC_VECTOR(checksum'RANGE);
+  SIGNAL i_checksum_val   : STD_LOGIC;
+  SIGNAL nxt_checksum_val : STD_LOGIC;
+  
+  SIGNAL data_p0 : STD_LOGIC_VECTOR(c_halfword_w+1 DOWNTO 0);
+  SIGNAL data_p1 : STD_LOGIC_VECTOR(c_halfword_w+1 DOWNTO 0);
+  SIGNAL data_p2 : STD_LOGIC_VECTOR(c_halfword_w+1 DOWNTO 0);
+  SIGNAL data_p3 : STD_LOGIC_VECTOR(c_halfword_w+1 DOWNTO 0);
+  
+BEGIN
+  
+  data_p0 <= "00" & in_data(c_longword_w   -1 DOWNTO c_halfword_w * 3);
+  data_p1 <= "00" & in_data(c_halfword_w*3 -1 DOWNTO c_halfword_w * 2);
+  data_p2 <= "00" & in_data(c_halfword_w*2 -1 DOWNTO c_halfword_w );
+  data_p3 <= "00" & in_data(c_halfword_w   -1 DOWNTO 0);
+  
+  checksum     <= i_checksum;
+  checksum_val <= i_checksum_val;
+  
+  p_clk : PROCESS(rst, clk)
+  BEGIN
+    IF rst='1' THEN
+      prev_in_valid   <= '0';
+      prev_in_eop     <= '0';
+      prev_in_eop_dly <= '0';
+      word_sum        <= (OTHERS=>'0');
+      sum             <= (OTHERS=>'0');
+      i_checksum      <= (OTHERS=>'0');
+      i_checksum_val  <= '0';
+    ELSIF rising_edge(clk) THEN
+      -- input
+      prev_in_valid   <= in_valid;
+      prev_in_eop     <= in_eop;
+      prev_in_eop_dly <= prev_in_eop;
+      -- internal
+      word_sum        <= nxt_word_sum;
+      sum             <= nxt_sum;
+      -- outputs
+      i_checksum      <= nxt_checksum;
+      i_checksum_val  <= nxt_checksum_val;
+    END IF;
+  END PROCESS;
+  
+  -- Combinatorial sink input
+  p_zero_empty : PROCESS(snk_in, in_eop)
+  BEGIN
+    in_data <= snk_in.data(c_longword_w-1 DOWNTO 0);
+    IF in_eop='1' THEN
+      CASE TO_INTEGER(UNSIGNED(snk_in.empty(c_eth_empty_w-1 DOWNTO 0))) IS
+        WHEN 1 => in_data <= snk_in.data(c_longword_w-1 DOWNTO   c_byte_w) & c_slv0(  c_byte_w-1 DOWNTO 0);
+        WHEN 2 => in_data <= snk_in.data(c_longword_w-1 DOWNTO 2*c_byte_w) & c_slv0(2*c_byte_w-1 DOWNTO 0);
+        WHEN 3 => in_data <= snk_in.data(c_longword_w-1 DOWNTO 3*c_byte_w) & c_slv0(3*c_byte_w-1 DOWNTO 0);
+        WHEN 4 => in_data <= snk_in.data(c_longword_w-1 DOWNTO 4*c_byte_w) & c_slv0(4*c_byte_w-1 DOWNTO 0);
+        WHEN 5 => in_data <= snk_in.data(c_longword_w-1 DOWNTO 5*c_byte_w) & c_slv0(5*c_byte_w-1 DOWNTO 0);
+        WHEN 6 => in_data <= snk_in.data(c_longword_w-1 DOWNTO 6*c_byte_w) & c_slv0(6*c_byte_w-1 DOWNTO 0);
+        WHEN 7 => in_data <= snk_in.data(c_longword_w-1 DOWNTO 7*c_byte_w) & c_slv0(7*c_byte_w-1 DOWNTO 0);
+        WHEN OTHERS => NULL;
+      END CASE;
+    END IF;
+  END PROCESS;
+
+  in_valid <= snk_in.valid;
+  in_sop   <= snk_in.sop;
+  in_eop   <= snk_in.eop;
+  
+  -- Word sum       
+  word_sum_cin <= (OTHERS => '0') WHEN in_sop='1' ELSE word_sum(c_halfword_w +1 DOWNTO c_halfword_w);
+  word_sum_dat    <= word_sum(c_halfword_w-1 DOWNTO 0);
+  nxt_word_sum    <= UNSIGNED(data_p0) +
+                     UNSIGNED(data_p1) +
+                     UNSIGNED(data_p2) +
+                     UNSIGNED(data_p3) + 
+                     word_sum_cin WHEN in_valid='1' ELSE 
+                     word_sum;
+                     
+  -- Accumulated sum
+  sum_cin(0)  <= sum(c_halfword_w);
+  sum_dat     <= sum(c_halfword_w-1 DOWNTO 0);
+  nxt_sum     <= (OTHERS=>'0')                            WHEN in_sop='1'        ELSE
+                 ('0' & sum_dat) + word_sum_dat + sum_cin WHEN prev_in_valid='1' ELSE
+                  sum;
+  
+  -- Accumulate the last carry
+  last_dat    <= sum(c_halfword_w-1 DOWNTO 0) + sum_cin;
+                    
+  -- Checksum is 1-complement of the sum
+  nxt_checksum     <= NOT(STD_LOGIC_VECTOR(last_dat)) WHEN prev_in_eop_dly='1' ELSE i_checksum;           
+  nxt_checksum_val <=                             '1' WHEN prev_in_eop_dly='1' ELSE
+                                                  '0' WHEN in_sop='1'          ELSE i_checksum_val;
+  
+END rtl;
diff --git a/libraries/io/eth/tb/vhdl/tb_eth_checksum_10G.vhd b/libraries/io/eth/tb/vhdl/tb_eth_checksum_10G.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..0c6a5a9829d389e7ec71ffe77cdd8bf3a65c4307
--- /dev/null
+++ b/libraries/io/eth/tb/vhdl/tb_eth_checksum_10G.vhd
@@ -0,0 +1,206 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2010
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+-------------------------------------------------------------------------------
+
+
+-- Purpose: Testbench for eth_checksum
+-- Description:
+--
+--   Example from Wiki IPv4. Use Hex 45000030442240008006442e8c7c19acae241e2b
+--   (20Bytes IP header) the c_exp_checksum then becomes:
+--
+--     4500 + 0030 + 4422 + 4000 + 8006 + 0000 + 8c7c + 19ac + ae24 + 1e2b = 2BBCF
+--     2 + BBCF = BBD1 = 1011101111010001, the 1'S of sum = 0100010000101110 = 442E
+--
+--   Verify that checksum=c_exp_checksum when checksum_val='1'
+--
+-- Usage:
+--   > as 10
+--   > run -all
+
+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;
+USE work.eth_pkg.ALL;
+
+
+ENTITY tb_eth_checksum_10G IS
+END tb_eth_checksum_10G;
+
+
+ARCHITECTURE tb OF tb_eth_checksum_10G IS
+
+  CONSTANT clk_period : TIME := 10 ns;  -- 100 MHz
+  
+  CONSTANT c_exp_checksum     : NATURAL := 16#442E#;
+  
+  -- Minimum nof clk cycles between eop and sop
+  CONSTANT c_checksum_latency : NATURAL := 3;
+  CONSTANT c_wait_eop_sop     : NATURAL := 10;  -- >= c_checksum_latency-1;
+
+  SIGNAL tb_end        : STD_LOGIC := '0';
+  SIGNAL clk           : STD_LOGIC := '1';
+  SIGNAL rst           : STD_LOGIC;
+  
+  SIGNAL src_out       : t_dp_sosi;
+  
+  SIGNAL checksum      : STD_LOGIC_VECTOR(c_halfword_w-1 DOWNTO 0);
+  SIGNAL checksum_val  : STD_LOGIC;
+    
+BEGIN
+
+  clk <= NOT clk OR tb_end AFTER clk_period/2;
+  rst <= '1', '0' AFTER 3*clk_period;
+  
+  p_stimuli : PROCESS
+  BEGIN
+    src_out.data  <= TO_DP_DATA(0);
+    src_out.valid <= '0';
+    src_out.sop   <= '0';
+    src_out.eop   <= '0';
+    src_out.empty <= TO_DP_EMPTY(0);
+    WAIT UNTIL rst='0';
+    WAIT UNTIL rising_edge(clk);
+    
+    ----------------------------------------------------------------------------
+    -- First
+    ----------------------------------------------------------------------------
+    src_out.sop   <= '1';
+    src_out.valid <= '1';
+    src_out.data  <= RESIZE_DP_DATA(X"4500003044224000");
+    WAIT UNTIL rising_edge(clk);
+    src_out.sop   <= '0';
+    src_out.data  <= RESIZE_DP_DATA(X"800600008c7c19ac");
+    WAIT UNTIL rising_edge(clk);
+    src_out.eop   <= '1';
+    src_out.data  <= RESIZE_DP_DATA(X"00000000ae241e2b");
+    WAIT UNTIL rising_edge(clk);
+    src_out.data  <= (OTHERS=>'0');
+    src_out.valid <= '0';
+    src_out.eop   <= '0';
+    -- Wait latency    
+    FOR I IN 0 TO c_wait_eop_sop-1 LOOP WAIT UNTIL rising_edge(clk); END LOOP;
+    
+    ----------------------------------------------------------------------------
+    -- Again with valid low for a few cycles
+    ----------------------------------------------------------------------------
+    src_out.sop   <= '1';
+    src_out.valid <= '1';
+    src_out.data  <= RESIZE_DP_DATA(X"4500003044224000");
+    WAIT UNTIL rising_edge(clk);
+    src_out.sop   <= '0';
+    src_out.data  <= RESIZE_DP_DATA(X"800600008c7c19ac");
+    
+    -- pause
+    src_out.valid <= '0';
+    FOR I IN 0 TO 1 LOOP WAIT UNTIL rising_edge(clk); END LOOP;
+    src_out.valid <= '1';
+    
+    WAIT UNTIL rising_edge(clk);
+    src_out.eop   <= '1';
+    src_out.data  <= RESIZE_DP_DATA(X"00000000ae241e2b");
+    WAIT UNTIL rising_edge(clk);
+    src_out.data  <= (OTHERS=>'0');
+    src_out.valid <= '0';
+    src_out.eop   <= '0';
+    -- Wait latency    
+    FOR I IN 0 TO c_wait_eop_sop-1 LOOP WAIT UNTIL rising_edge(clk); END LOOP;
+    
+    ----------------------------------------------------------------------------
+    -- Again with carry in within word_sum
+    ----------------------------------------------------------------------------
+    src_out.sop   <= '1';
+    src_out.valid <= '1';
+    src_out.data  <= RESIZE_DP_DATA(X"4500003044224000");
+--     WAIT UNTIL rising_edge(clk);
+--     src_out.data  <= RESIZE_DP_DATA(X"80060000");
+--     WAIT UNTIL rising_edge(clk);
+--     src_out.data  <= RESIZE_DP_DATA(X"8c7c19ac");
+    WAIT UNTIL rising_edge(clk);
+    src_out.sop   <= '0';
+    src_out.data  <= RESIZE_DP_DATA(X"80068c7c000019ac");
+    
+    -- pause
+    src_out.valid <= '0';
+    FOR I IN 0 TO 0 LOOP WAIT UNTIL rising_edge(clk); END LOOP;
+    src_out.valid <= '1';
+    
+    WAIT UNTIL rising_edge(clk);
+    src_out.eop   <= '1';
+    src_out.data  <= RESIZE_DP_DATA(X"00000000ae241e2b");
+    WAIT UNTIL rising_edge(clk);
+    src_out.data  <= (OTHERS=>'0');
+    src_out.valid <= '0';
+    src_out.eop   <= '0';
+    -- Wait latency    
+    FOR I IN 0 TO c_wait_eop_sop-1 LOOP WAIT UNTIL rising_edge(clk); END LOOP;
+    
+    ----------------------------------------------------------------------------
+    -- Again with empty = 2
+    ----------------------------------------------------------------------------
+    src_out.empty <= TO_DP_EMPTY(2);
+    src_out.sop   <= '1';
+    src_out.valid <= '1';
+    src_out.data  <= RESIZE_DP_DATA(X"4500003044224000");
+    WAIT UNTIL rising_edge(clk);
+    src_out.sop   <= '0';
+    src_out.data  <= RESIZE_DP_DATA(X"80061e2b8c7c19ac");  -- overwrite these "0000" with the last 2, now empty, bytes "1e2b", to keep the seem expected result
+    WAIT UNTIL rising_edge(clk);
+    src_out.eop   <= '1';
+    src_out.data  <= RESIZE_DP_DATA(X"00000000ae241e2b");
+    WAIT UNTIL rising_edge(clk);
+    src_out.data  <= (OTHERS=>'0');
+    src_out.valid <= '0';
+    src_out.eop   <= '0';
+    -- Wait latency    
+    FOR I IN 0 TO c_wait_eop_sop-1 LOOP WAIT UNTIL rising_edge(clk); END LOOP;
+    
+    tb_end <= '1';
+    ASSERT FALSE REPORT "Simulation tb_eth_checksum finished." SEVERITY NOTE;
+    WAIT;
+  END PROCESS;
+  
+  
+  p_verify : PROCESS
+  BEGIN
+    WAIT UNTIL rising_edge(clk);
+    IF checksum_val='1' THEN
+      ASSERT UNSIGNED(checksum)=c_exp_checksum REPORT "Wrong checksum" SEVERITY ERROR;
+    END IF;
+    IF tb_end='1' THEN
+      ASSERT checksum_val='1' REPORT "Checksum is not valid at tb_end" SEVERITY ERROR;
+    END IF;
+  END PROCESS;
+  
+  u_dut : ENTITY work.eth_checksum_10G
+  PORT MAP (
+    rst           => rst,
+    clk           => clk,
+    
+    snk_in        => src_out,
+    
+    checksum      => checksum,
+    checksum_val  => checksum_val
+  );
+
+END tb;