From f48a1fad1d73ac7f569e6c50c31592dd486bf8b9 Mon Sep 17 00:00:00 2001
From: Reinier van der Walle <walle@astron.nl>
Date: Fri, 21 Jul 2017 06:48:36 +0000
Subject: [PATCH] added comments

---
 .../io/eth/src/vhdl/eth_checksum_10g.vhd      | 103 ++++++++++--------
 1 file changed, 58 insertions(+), 45 deletions(-)

diff --git a/libraries/io/eth/src/vhdl/eth_checksum_10g.vhd b/libraries/io/eth/src/vhdl/eth_checksum_10g.vhd
index 17ba139d8a..0b6b283935 100644
--- a/libraries/io/eth/src/vhdl/eth_checksum_10g.vhd
+++ b/libraries/io/eth/src/vhdl/eth_checksum_10g.vhd
@@ -25,26 +25,15 @@ USE IEEE.std_logic_1164.ALL;
 USE IEEE.numeric_std.ALL;
 USE common_lib.common_pkg.ALL;
 USE dp_lib.dp_stream_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.
+----------------------------------------------------------------------------------
+-- Purpose:                                                                     --
+--   Can be used to calculate and insert the checksum for the IP header         --
+--   in a 10GbE package, if the correct longwords are provided.                 --
+-- Description:                                                                 --
+--   Determine the 16 bit 1-complement checksum according IPv4 to for the valid --
+--   words between snk_in.sop and the last ip header field.                     --
+--   After calculation, the checksum is inserted in the outgoing stream         --
+----------------------------------------------------------------------------------
 
 ENTITY eth_checksum_10g IS
   PORT (
@@ -61,23 +50,24 @@ END eth_checksum_10g;
 
 ARCHITECTURE rtl OF eth_checksum_10g IS
 
-  CONSTANT c_cin_w          : NATURAL := 4; --true_log2(c_nof_half_words - 1);
+  CONSTANT c_cin_w          : NATURAL := 4; --bit width of carry 
   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 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 cnt_clr, cnt_p_clr  : STD_LOGIC;
+  SIGNAL cnt_en, cnt_p_en    : STD_LOGIC;
+  SIGNAL count, count_p      : STD_LOGIC_VECTOR(31 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);
-
   
 BEGIN
+  -------------------------------------------------
+  -- process to calculate the ip_header_checksum --
+  -------------------------------------------------
   p_calc_chksum : PROCESS(clk)
   BEGIN
     IF rst = '1' THEN
       sum <= (OTHERS => '0');
-      --checksum <= (OTHERS => '0');
       
     ELSIF RISING_EDGE(clk) THEN
       IF cnt_clr = '1' THEN
@@ -85,37 +75,43 @@ BEGIN
       
       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 0 => -- 0 is the cycle after the sop due to the common_counter latency
+		        sum <= sum + UNSIGNED(snk_in.data(c_halfword_w-1 DOWNTO 0)); -- ip_version, ip_header_length, ip_services
 		      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));
+		        sum <= sum + UNSIGNED(snk_in.data(c_halfword_w*4 -1 DOWNTO c_halfword_w *3)) -- ip_total_length
+		                   + UNSIGNED(snk_in.data(c_halfword_w*3 -1 DOWNTO c_halfword_w *2)) -- ip_identification
+		                   + UNSIGNED(snk_in.data(c_halfword_w*2 -1 DOWNTO c_halfword_w))    -- ip_flags, ip_fragment_offset
+		                   + UNSIGNED(snk_in.data(c_halfword_w   -1 DOWNTO 0));              -- ip_time_to_live, ip_protocol
+		      WHEN 2 =>    -- skip ip_header_checksum
+		        sum <= sum + UNSIGNED(snk_in.data(c_halfword_w*3 -1 DOWNTO c_halfword_w *2)) -- ip_src_addr(1/2)
+		                   + UNSIGNED(snk_in.data(c_halfword_w*2 -1 DOWNTO c_halfword_w))    -- ip_src_addr(2/2)
+		                   + UNSIGNED(snk_in.data(c_halfword_w   -1 DOWNTO 0));              -- ip_dst_addr(1/2)
 		      WHEN 3 =>
-		        sum <= sum + UNSIGNED(snk_in.data(c_halfword_w*4 -1 DOWNTO c_halfword_w *3));
+		        sum <= sum + UNSIGNED(snk_in.data(c_halfword_w*4 -1 DOWNTO c_halfword_w *3));-- ip_dst_addr(2/2)
 
 		      WHEN OTHERS =>  		        
 		    END CASE;
       END IF;      
     END IF;
-  END PROCESS; 
+  END PROCESS;   
   
-  checksum <= NOT(STD_LOGIC_VECTOR(sum(c_halfword_w-1 DOWNTO 0)+sum(sum'HIGH DOWNTO c_halfword_w)));    
+  ---------------------------------------------------
+  -- process to insert checksum in outgoing stream --
+  --------------------------------------------------- 
+  checksum <= NOT(STD_LOGIC_VECTOR(sum(c_halfword_w-1 DOWNTO 0)+sum(sum'HIGH DOWNTO c_halfword_w))); -- checksum = inverted (sum + carry)  
   p_insert_chksum : PROCESS(dp_pipeline_src_out, checksum, count) 
   BEGIN
     src_out <= dp_pipeline_src_out;
-    IF TO_UINT(count) = 2+c_pipeline_delay THEN
+    IF TO_UINT(count_p) = 2 THEN
       src_out.data(c_halfword_w*4 -1 DOWNTO c_halfword_w *3) <= checksum;
     END IF;
   END PROCESS;      
   
-  cnt_en <= snk_in.valid;
-  cnt_clr <= snk_in.sop;    
+  -------------------------------------------------------------------------------------------
+  -- useing common_counter to keep track of the word alignment during checksum calculation --
+  -------------------------------------------------------------------------------------------
+  cnt_en <= snk_in.valid; -- only count when valid
+  cnt_clr <= snk_in.sop;  -- restart counter on sop  
   
   u_calc_counter : ENTITY common_lib.common_counter 
   PORT MAP (
@@ -124,8 +120,25 @@ BEGIN
     cnt_clr => cnt_clr,   
     cnt_en  => cnt_en,  
     count   => count   
-  );  
+  ); 
+  -----------------------------------------------------------------------------------------
+  -- useing common_counter to keep track of the word alignment during checksum insertion --
+  -----------------------------------------------------------------------------------------
+  cnt_p_en <= dp_pipeline_src_out.valid; -- only count when valid
+  cnt_p_clr <= dp_pipeline_src_out.sop;  -- restart counter on sop  
+  
+  u_pipe_counter : ENTITY common_lib.common_counter 
+  PORT MAP (
+    rst     => rst,     
+    clk     => clk,     
+    cnt_clr => cnt_p_clr,   
+    cnt_en  => cnt_p_en,  
+    count   => count_p   
+  ); 
   
+  --------------------------------------------------------------------------------
+  -- useing dp_pipeline to make room for the checksum calculation and insertion --
+  --------------------------------------------------------------------------------  
   u_dp_pipeline : ENTITY dp_lib.dp_pipeline
   GENERIC MAP (
     g_pipeline   => c_pipeline_delay 
-- 
GitLab