From abc2952ac6c6984167d681fa68e26f5150b51a71 Mon Sep 17 00:00:00 2001
From: Reinier van der Walle <walle@astron.nl>
Date: Thu, 20 Jul 2017 12:21:03 +0000
Subject: [PATCH]

---
 .../io/eth/src/vhdl/eth_checksum_10G.vhd      | 183 +++++++-----------
 1 file changed, 75 insertions(+), 108 deletions(-)

diff --git a/libraries/io/eth/src/vhdl/eth_checksum_10G.vhd b/libraries/io/eth/src/vhdl/eth_checksum_10G.vhd
index 19e45a8d07..f18ca271ba 100644
--- a/libraries/io/eth/src/vhdl/eth_checksum_10G.vhd
+++ b/libraries/io/eth/src/vhdl/eth_checksum_10G.vhd
@@ -25,7 +25,6 @@ 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
@@ -47,131 +46,99 @@ USE work.eth_pkg.ALL;
 --     snk_in.valid is inactive and that snk_in.valid is only active for new
 --     data.
 
-ENTITY eth_checksum_10G IS
+ENTITY eth_checksum_10G_tx IS
   PORT (
     rst           : IN  STD_LOGIC;
     clk           : IN  STD_LOGIC;
     
+    src_out       : OUT t_dp_sosi;
     snk_in        : IN  t_dp_sosi;
     
-    checksum      : OUT STD_LOGIC_VECTOR(c_halfword_w-1 DOWNTO 0);
-    checksum_val  : OUT STD_LOGIC
+    src_in        : IN  t_dp_siso;
+    snk_out       : OUT t_dp_siso
   );
-END eth_checksum_10G;
+END eth_checksum_10G_tx;
 
+ARCHITECTURE rtl OF eth_checksum_10G_tx IS
 
-ARCHITECTURE rtl OF eth_checksum_10G IS
+  CONSTANT c_cin_w          : NATURAL := 4; --true_log2(c_nof_half_words - 1);
+  CONSTANT c_pipeline_delay : NATURAL := 2;
+
+  SIGNAL sum         : UNSIGNED(c_halfword_w + c_cin_w -1 DOWNTO 0) := (OTHERS => '0');
+  SIGNAL checksum    : STD_LOGIC_VECTOR(c_halfword_w-1 DOWNTO 0);
+  SIGNAL dp_pipeline_src_out : t_dp_sosi;
+  SIGNAL cnt_clr     : STD_LOGIC;
+  SIGNAL cnt_en      : STD_LOGIC;
+  SIGNAL count       : STD_LOGIC_VECTOR(31 DOWNTO 0);
 
-  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)
+  p_calc_chksum : PROCESS(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;
+    IF rst = '1' THEN
+      sum <= (OTHERS => '0');
+      --checksum <= (OTHERS => '0');
+      
+    ELSIF RISING_EDGE(clk) THEN
+      IF cnt_clr = '1' THEN
+        sum <= (OTHERS => '0');
+      
+      ELSIF cnt_en = '1' THEN
+	      CASE TO_UINT(count) IS
+		      WHEN 0 =>
+		        sum <= sum + UNSIGNED(snk_in.data(c_halfword_w-1 DOWNTO 0));
+		      WHEN 1 =>
+		        sum <= sum + UNSIGNED(snk_in.data(c_halfword_w*4 -1 DOWNTO c_halfword_w *3))
+		                   + UNSIGNED(snk_in.data(c_halfword_w*3 -1 DOWNTO c_halfword_w *2))
+		                   + UNSIGNED(snk_in.data(c_halfword_w*2 -1 DOWNTO c_halfword_w))
+		                   + UNSIGNED(snk_in.data(c_halfword_w   -1 DOWNTO 0));
+		      WHEN 2 =>
+		        sum <= sum + UNSIGNED(snk_in.data(c_halfword_w*3 -1 DOWNTO c_halfword_w *2))
+		                   + UNSIGNED(snk_in.data(c_halfword_w*2 -1 DOWNTO c_halfword_w))
+		                   + UNSIGNED(snk_in.data(c_halfword_w   -1 DOWNTO 0));
+		      WHEN 3 =>
+		        sum <= sum + UNSIGNED(snk_in.data(c_halfword_w*4 -1 DOWNTO c_halfword_w *3));
+
+		      WHEN OTHERS =>  		        
+		    END CASE;
+      END IF;      
     END IF;
-  END PROCESS;
+  END PROCESS; 
   
-  -- Combinatorial sink input
-  p_zero_empty : PROCESS(snk_in, in_eop)
+  checksum <= NOT(STD_LOGIC_VECTOR(sum(c_halfword_w-1 DOWNTO 0)+sum(sum'HIGH DOWNTO c_halfword_w)));    
+  p_insert_chksum : PROCESS(dp_pipeline_src_out, checksum, count) 
   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;
+    src_out <= dp_pipeline_src_out;
+    IF TO_UINT(count) = 2+c_pipeline_delay THEN
+      src_out.data(c_halfword_w*4 -1 DOWNTO c_halfword_w *3) <= checksum;
     END IF;
-  END PROCESS;
-
-  in_valid <= snk_in.valid;
-  in_sop   <= snk_in.sop;
-  in_eop   <= snk_in.eop;
+  END PROCESS;      
   
-  -- 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;
+  cnt_en <= snk_in.valid;
+  cnt_clr <= snk_in.sop;    
   
-  -- 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;
+  u_calc_counter : ENTITY common_lib.common_counter 
+  PORT MAP (
+    rst     => rst,     
+    clk     => clk,     
+    cnt_clr => cnt_clr,   
+    cnt_en  => cnt_en,  
+    count   => count   
+  );  
   
+  u_dp_pipeline : ENTITY dp_lib.dp_pipeline
+  GENERIC MAP (
+    g_pipeline   => c_pipeline_delay 
+  )
+  PORT MAP (
+    rst          => rst,
+    clk          => clk,
+    -- ST sink
+    snk_out      => snk_out, 
+    snk_in       => snk_in, 
+    -- ST source
+    src_in       => src_in, 
+    src_out      => dp_pipeline_src_out
+  );
+        
 END rtl;
-- 
GitLab