OpenCores
URL https://opencores.org/ocsvn/funbase_ip_library/funbase_ip_library/trunk

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.hwp.interface/] [udp_ip/] [1.0/] [vhd/] [ip_checksum.vhd] - Rev 145

Compare with Previous | Blame | View Log

-------------------------------------------------------------------------------
-- Title      : IP checksum counter
-- Project    : 
-------------------------------------------------------------------------------
-- File       : ip_checksum.vhd
-- Author     : Jussi Nieminen  <niemin95@galapagosinkeiju.cs.tut.fi>
-- Company    : 
-- Last update: 2009/09/29
-- Platform   : 
-------------------------------------------------------------------------------
-- Description: Counts 1's complement checksum for IP header
-------------------------------------------------------------------------------
-- Revisions  :
-- Date        Version  Author  Description
-- 2009/09/29  1.0      niemin95        Created
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.udp_ip_pkg.all;
 
entity ip_checksum is
 
  generic (
    -- this comes from the protocol, flags etc. field that are currently constants
    pre_counted_part_g : std_logic_vector( ip_checksum_w_c-1 downto 0 ) := (others => '0')
    );
 
  port (
    total_length_field_in : in  std_logic_vector( 15 downto 0 );
    source_addr_field_in  : in  std_logic_vector( ip_addr_w_c-1 downto 0 );
    dest_addr_field_in    : in  std_logic_vector( ip_addr_w_c-1 downto 0 );
    header_checksum_out   : out std_logic_vector( ip_checksum_w_c-1 downto 0 )
    );
 
end ip_checksum;
 
 
architecture rtl of ip_checksum is
 
  -- currently we have 5 additions, which means that the overflowing part of
  -- the additions can be at most 3-bits wide
  constant middle_sum_w_c : integer := ip_checksum_w_c + 3;
  signal   middle_sum_int : integer range 0 to 2**middle_sum_w_c-1;
  signal   middle_sum_slv : std_logic_vector( middle_sum_w_c-1 downto 0 );
 
  subtype addend_integer is integer range 0 to 2**ip_checksum_w_c-1;
  signal length_int           : addend_integer;
  signal source_addr_high_int : addend_integer;
  signal source_addr_low_int  : addend_integer;
  signal dest_addr_high_int   : addend_integer;
  signal dest_addr_low_int    : addend_integer;
 
-------------------------------------------------------------------------------
begin  -- rtl
-------------------------------------------------------------------------------
 
  middle_sum_slv <= std_logic_vector( to_unsigned( middle_sum_int, middle_sum_w_c ));
 
  length_int           <= to_integer( unsigned( total_length_field_in ));
  source_addr_high_int <= to_integer( unsigned( source_addr_field_in( ip_addr_w_c-1 downto 16 ) ));
  source_addr_low_int  <= to_integer( unsigned( source_addr_field_in( 15 downto 0 ) ));
  dest_addr_high_int   <= to_integer( unsigned( dest_addr_field_in( ip_addr_w_c-1 downto 16 ) ));
  dest_addr_low_int    <= to_integer( unsigned( dest_addr_field_in( 15 downto 0 ) ));
 
 
  count_checksum : process (length_int, source_addr_high_int, source_addr_low_int,
                            dest_addr_high_int, dest_addr_low_int, middle_sum_slv)
 
    variable middle_sum_v : std_logic_vector( ip_checksum_w_c downto 0 );
    variable final_sum_v : integer range 0 to 2**ip_checksum_w_c - 1;
    variable final_checksum_v : std_logic_vector( ip_checksum_w_c-1 downto 0 );
 
  begin  -- process count_checksum
 
    middle_sum_int <= to_integer( unsigned( pre_counted_part_g ))+
                      length_int + source_addr_high_int + source_addr_low_int +
                      dest_addr_high_int + dest_addr_low_int;
 
    middle_sum_v :=
      std_logic_vector( to_unsigned(
        to_integer( unsigned( middle_sum_slv( ip_checksum_w_c-1 downto 0 ) )) +
        to_integer( unsigned( middle_sum_slv( middle_sum_w_c-1 downto ip_checksum_w_c ) )),
        ip_checksum_w_c+1 ));
 
    final_sum_v := to_integer( unsigned( middle_sum_v( ip_checksum_w_c-1 downto 0 ) )) +
                   to_integer( unsigned( middle_sum_v( ip_checksum_w_c downto ip_checksum_w_c ) ));
 
    final_checksum_v := not std_logic_vector( to_unsigned( final_sum_v, ip_checksum_w_c ));
 
    header_checksum_out <= final_checksum_v;
 
  end process count_checksum;
 
 
end rtl;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.