SURF  1.0
Chksum.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : Chksum.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2015-08-09
5 -- Last update: 2015-08-09
6 -------------------------------------------------------------------------------
7 -- Description: Calculates and checks the RUDP packet checksum.
8 -- Checksum for IP/UDP/TCP/RUDP.
9 -- Works with 64-bit word
10 -------------------------------------------------------------------------------
11 -- This file is part of 'SLAC Firmware Standard Library'.
12 -- It is subject to the license terms in the LICENSE.txt file found in the
13 -- top-level directory of this distribution and at:
14 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
15 -- No part of 'SLAC Firmware Standard Library', including this file,
16 -- may be copied, modified, propagated, or distributed except according to
17 -- the terms contained in the LICENSE.txt file.
18 -------------------------------------------------------------------------------
19 
20 library ieee;
21 use ieee.std_logic_1164.all;
22 use ieee.std_logic_unsigned.all;
23 use ieee.std_logic_arith.all;
24 
25 use work.StdRtlPkg.all;
26 
27 --! @see entity
28  --! @ingroup protocols_rssi
29 entity Chksum is
30  generic (
31  TPD_G : time := 1 ns;
32  --
33  DATA_WIDTH_G : positive := 64;
34  CSUM_WIDTH_G : positive := 16
35  );
36  port (
37  clk_i : in sl;
38  rst_i : in sl;
39 
40  -- Enables and initializes the calculations.
41  -- enable_i <= '1' enables the calculation.
42  -- the checksum value holds as long as enabled.
43  -- enable_i <= '0' initializes the calculation.
44  enable_i : in sl;
45 
46  -- Has to indicate valid data and defines the number of calculation clock cycles.
47  strobe_i : in sl;
48 
49  -- Length of checksumed data
50  length_i : in positive;
51 
52  -- Initial value of the sum
53  -- Calculation: init_i = (others=>'0')
54  -- Validation: init_i = Checksum value
55  init_i : in slv(CSUM_WIDTH_G-1 downto 0);
56 
57  -- Fixed to 2 octets (standard specification)
58  data_i : in slv(DATA_WIDTH_G-1 downto 0);
59 
60  -- Direct out 1 c-c delay
61  chksum_o : out slv(CSUM_WIDTH_G-1 downto 0);
62 
63  -- Indicates when the module is ready and the checksum is valid
64  valid_o : out sl;
65  -- Indicates if the calculated checksum is ok (valid upon valid_o='1')
66  check_o : out sl
67  );
68 end entity Chksum;
69 
70 architecture rtl of Chksum is
71 
72  constant RATIO_C : positive := DATA_WIDTH_G/CSUM_WIDTH_G;
73 
74  type RegType is record
75  sum : slv(CSUM_WIDTH_G+4 downto 0);
76  chksum : slv(CSUM_WIDTH_G downto 0);
77  lenCnt : natural;
78  valid : sl;
79  end record RegType;
80 
81  constant REG_INIT_C : RegType := (
82  sum => (others=>'0'),
83  chksum => (others=>'0'),
84  lenCnt => 0,
85  valid => '0'
86  );
87 
88  signal r : RegType := REG_INIT_C;
89  signal rin : RegType;
90 
91  signal s_dataWordSum : slv(CSUM_WIDTH_G+1 downto 0);
92 
93 
94 
95 begin
96  -- TODO make it generic
97  --data_i((CSUM_WIDTH_G-1)+(CSUM_WIDTH_G*I) downto CSUM_WIDTH_G*I);
98  s_dataWordSum <= "00"& data_i(63 downto 48) +
99  data_i(47 downto 32) +
100  data_i(31 downto 16) +
101  data_i(15 downto 0);
102 
103 
104 
105  comb : process (r, rst_i, enable_i, init_i, data_i, strobe_i, length_i, s_dataWordSum) is
106  variable v : RegType;
107  begin
108  v := r;
109 
110  -- Cumulative sum of the data_i while enabled
111  if ( enable_i = '0') then
112  v.sum := ("00000" & init_i);
113  v.lenCnt := 0;
114  v.valid := '0';
115  elsif ( r.lenCnt >= length_i) then
116  v.sum := r.sum;
117  v.lenCnt := r.lenCnt;
118  v.valid := '1';
119  elsif ( strobe_i = '1') then
120  -- Add new word sum
121  v.sum := r.sum + s_dataWordSum;
122  v.lenCnt := r.lenCnt +1;
123  v.valid := '0';
124  else
125  v.sum := r.sum;
126  v.lenCnt := r.lenCnt;
127  v.valid := '0';
128  end if;
129 
130  -- Add the sum carry bits
131  v.chksum := '0' & r.sum(CSUM_WIDTH_G-1 downto 0) + r.sum(CSUM_WIDTH_G+4 downto CSUM_WIDTH_G);
132  -- Add the checksum carry bit
133  v.chksum(CSUM_WIDTH_G-1 downto 0) := v.chksum(CSUM_WIDTH_G-1 downto 0) + v.chksum(CSUM_WIDTH_G);
134 
135  -- Checksum output (calculated with 2 c-c delay towards data)
136  -- Ones complement
137  chksum_o <= not r.chksum(CSUM_WIDTH_G-1 downto 0);
138 
139  if (rst_i = '1') then
140  v := REG_INIT_C;
141  end if;
142 
143  rin <= v;
144  -----------------------------------------------------------
145  end process comb;
146 
147  seq : process (clk_i) is
148  begin
149  if (rising_edge(clk_i)) then
150  r <= rin after TPD_G;
151  end if;
152  end process seq;
153  ---------------------------------------------------------------------
154  -- Output assignment
155  valid_o <= r.valid;
156  check_o <= '1' when (not r.chksum(CSUM_WIDTH_G-1 downto 0)) = (r.chksum'range => '0') else '0';
157  ---------------------------------------------------------------------
158 end architecture rtl;
CSUM_WIDTH_Gpositive := 16
Definition: Chksum.vhd:35
TPD_Gtime := 1 ns
Definition: Chksum.vhd:31
std_logic sl
Definition: StdRtlPkg.vhd:28
out check_osl
Definition: Chksum.vhd:67
in clk_isl
Definition: Chksum.vhd:37
in length_ipositive
Definition: Chksum.vhd:50
out chksum_oslv( CSUM_WIDTH_G- 1 downto 0)
Definition: Chksum.vhd:61
DATA_WIDTH_Gpositive := 64
Definition: Chksum.vhd:33
in data_islv( DATA_WIDTH_G- 1 downto 0)
Definition: Chksum.vhd:58
in enable_isl
Definition: Chksum.vhd:44
in init_islv( CSUM_WIDTH_G- 1 downto 0)
Definition: Chksum.vhd:55
in strobe_isl
Definition: Chksum.vhd:47
in rst_isl
Definition: Chksum.vhd:38
out valid_osl
Definition: Chksum.vhd:64
std_logic_vector slv
Definition: StdRtlPkg.vhd:29