1 ------------------------------------------------------------------------------- 2 -- File : EthMacRxCsum.vhd 3 -- Company : SLAC National Accelerator Laboratory 4 -- Created : 2016-09-08 5 -- Last update: 2017-02-22 6 ------------------------------------------------------------------------------- 7 -- Description: RX Checksum Hardware Offloading Engine 8 -- https://docs.google.com/spreadsheets/d/1_1M1keasfq8RLmRYHkO0IlRhMq5YZTgJ7OGrWvkib8I/edit?usp=sharing 9 ------------------------------------------------------------------------------- 10 -- This file is part of 'SLAC Firmware Standard Library'. 11 -- It is subject to the license terms in the LICENSE.txt file found in the 12 -- top-level directory of this distribution and at: 13 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. 14 -- No part of 'SLAC Firmware Standard Library', including this file, 15 -- may be copied, modified, propagated, or distributed except according to 16 -- the terms contained in the LICENSE.txt file. 17 ------------------------------------------------------------------------------- 20 use ieee.std_logic_1164.
all;
21 use ieee.std_logic_arith.
all;
22 use ieee.std_logic_unsigned.
all;
29 --! @ingroup ethernet_EthMacCore 43 -- Inbound data from MAC 50 constant MAX_FRAME_SIZE_C : := ite(JUMBO_G, 9000, 1500);
59 type RegType is record 60 valid : slv(1 downto 0);
68 byteCnt : range 0 to (MAX_FRAME_SIZE_C + 32);
-- MTU size + padding 80 constant REG_INIT_C : RegType := ( 81 valid => (others => '0'), 83 fragDet => (others => '0'), 84 eofeDet => (others => '0'), 85 ipv4Det => (others => '0'), 86 udpDet => (others => '0'), 87 tcpDet => (others => '0'), 90 ipv4Hdr => (others => (others => '0')), 91 ipv4Len => (others => (others => '0')), 92 protLen => (others => (others => '0')), 93 protCsum => (others => (others => '0')), 95 tKeep => (others => '0'), 96 tData => (others => '0'), 101 signal r : RegType := REG_INIT_C;
102 signal rin : RegType;
106 -- attribute dont_touch : string; 107 -- attribute dont_touch of r : signal is "TRUE"; 112 variable v : RegType;
115 -- Latch the current value 129 dummy(0), -- Unused in RX CSUM 131 dummy(1));
-- Unused in RX CSUM 133 -- Pipeline alignment to GetEthMacCsum() 145 v.tKeep := (others => '0');
149 -- Check for tLast in pipeline 151 -- Check if IPv4 is detected and being checked 153 -- Forward the result of checksum calculation 157 -- Check if UDP is detected and being checked 159 -- Forward the result of checksum calculation 162 -- Check for mismatch in IPv4 length with UDP length 164 -- Set the error flags 169 -- Check if TCP is detected and being checked 171 -- Forward the result of checksum calculation 179 ---------------------------------------------------------------------- 181 -- Reset the flags and counter 188 -- Check for valid data 196 -- Check for EtherType = IPV4 = 0x0800 201 -- Fill in the IPv4 header checksum 202 v.ipv4Hdr(0) := sAxisMaster.tData(119 downto 112);
-- IPVersion + Header length 206 v.state := IPV4_HDR0_S;
209 ---------------------------------------------------------------------- 211 -- Check for valid data 217 -- Set the error flag if IPv4 is detected and being checked 224 -- Fill in the IPv4 header checksum 229 v.ipv4Hdr(6) := sAxisMaster.tData(39 downto 32);
-- Flags(2 downto 0) and Fragment Offsets(12 downto 8) 230 v.ipv4Hdr(7) := sAxisMaster.tData(47 downto 40);
-- Fragment Offsets(7 downto 0) 233 v.ipv4Hdr(10) := sAxisMaster.tData(71 downto 64);
-- IPV4_Checksum(15 downto 8) 234 v.ipv4Hdr(11) := sAxisMaster.tData(79 downto 72);
-- IPV4_Checksum(7 downto 0) 239 v.ipv4Hdr(16) := sAxisMaster.tData(119 downto 112);
-- Destination IP Address 240 v.ipv4Hdr(17) := sAxisMaster.tData(127 downto 120);
-- Destination IP Address 241 -- Fill in the TCP/UDP checksum 243 v.tKeep(7 downto 0) := (others => '1');
245 -- Check for EtherType = IPV4 = 0x0800 250 -- Fill in the IPv4 header checksum 251 v.ipv4Hdr(0) := sAxisMaster.tData(23 downto 16);
-- IPVersion + Header length 253 v.ipv4Hdr(2) := sAxisMaster.tData(39 downto 32);
-- IPV4_Length(15 downto 8) 257 v.ipv4Hdr(6) := sAxisMaster.tData(71 downto 64);
-- Flags(2 downto 0) and Fragment Offsets(12 downto 8) 258 v.ipv4Hdr(7) := sAxisMaster.tData(79 downto 72);
-- Fragment Offsets(7 downto 0) 261 v.ipv4Hdr(10) := sAxisMaster.tData(103 downto 96);
-- IPV4_Checksum(15 downto 8) 262 v.ipv4Hdr(11) := sAxisMaster.tData(111 downto 104);
-- IPV4_Checksum(7 downto 0) 265 -- Fill in the TCP/UDP checksum 267 v.tKeep(3 downto 0) := (others => '1');
269 -- Latch the IPv4 length value 270 v.ipv4Len(0)(15 downto 8) := v.ipv4Hdr(2);
271 v.ipv4Len(0)(7 downto 0) := v.ipv4Hdr(3);
272 -- Check for UDP protocol 273 if (v.ipv4Hdr(9) = UDP_C) then 276 -- Check for TCP protocol 277 if (v.ipv4Hdr(9) = TCP_C) then 280 -- Check for fragmentation 281 if (v.ipv4Hdr(6)(7) = '1') or (v.ipv4Hdr(6)(4 downto 0) /= 0) or (v.ipv4Hdr(7) /= 0) then 287 v.state := IPV4_HDR1_S;
290 ---------------------------------------------------------------------- 292 -- Check for valid data 296 -- Fill in the TCP/UDP checksum 301 -- Fill in the IPv4 header checksum 304 -- Check for UDP data with inbound checksum 305 if (r.ipv4Det(0) = '1') and (r.udpDet(0) = '1') then 306 -- Mask off inbound UDP checksum 308 -- Latch the inbound UDP checksum 311 -- Latch the inbound UDP length 315 -- Track the number of bytes (include IPv4 header offset from previous state) 318 -- Fill in the IPv4 header checksum 325 -- Check for UDP data with inbound checksum 326 if (r.ipv4Det(0) = '1') and (r.udpDet(0) = '1') then 327 -- Mask off inbound UDP checksum 329 -- Latch the inbound UDP checksum 332 -- Latch the inbound UDP length 336 -- Track the number of bytes (include IPv4 header offset from previous state) 348 ---------------------------------------------------------------------- 350 -- Check for valid data 354 -- Fill in the TCP/UDP checksum 357 -- Check for TCP data with inbound checksum 358 if (r.ipv4Det(0) = '1') and (r.tcpDet(0) = '1') and (r.tcpFlag = '0') then 361 -- Calculate TCP length from IPv4 length 362 v.protLen(0) := r.ipv4Len(0) - 20;
365 -- Mask off inbound TCP checksum 367 -- Latch the inbound TCP checksum 371 -- Mask off inbound TCP checksum 373 -- Latch the inbound TCP checksum 378 -- Track the number of bytes 382 -- Check for overflow condition 386 -- Set the error flag 389 v.state := BLOWOFF_S;
396 ---------------------------------------------------------------------- 398 -- Check for a valid EOF 403 ---------------------------------------------------------------------- 406 -- Check for first TUSER on the output AXIS stream 408 -- Set the fragmentation flag 419 -- Register the variable for next clock cycle 430 if rising_edge(ethClk) then 431 r <= rin after TPD_G;
out mAxisMasterAxiStreamMasterType
slv( 7 downto 0) := x"06" TCP_C
slv( 15 downto 0) := x"0008" IPV4_TYPE_C
AxiStreamMasterType :=(tValid => '0',tData =>( others => '0'),tStrb =>( others => '1'),tKeep =>( others => '1'),tLast => '0',tDest =>( others => '0'),tId =>( others => '0'),tUser =>( others => '0')) AXI_STREAM_MASTER_INIT_C
integer := 3 EMAC_UDPERR_BIT_C
integer := 2 EMAC_TCPERR_BIT_C
integer := 0 EMAC_FRAG_BIT_C
EthMacCsumAccumType :=(step =>( others => '0'),sum1 =>( others =>( others => '0')),sum3 =>( others => '0'),sum5 =>( others => '0')) ETH_MAC_CSUM_ACCUM_INIT_C
natural := 3 EMAC_CSUM_PIPELINE_C
integer := 0 EMAC_EOFE_BIT_C
integer := 1 EMAC_SOF_BIT_C
in sAxisMasterAxiStreamMasterType
array(natural range <> ) of AxiStreamMasterType AxiStreamMasterArray
array(natural range <> ) of slv( 15 downto 0) Slv16Array
slv( 7 downto 0) := x"11" UDP_C
integer := 1 EMAC_IPERR_BIT_C
array(natural range <> ) of slv( 7 downto 0) Slv8Array
AxiStreamConfigType :=(TSTRB_EN_C => false,TDATA_BYTES_C => 16,TDEST_BITS_C => 8,TID_BITS_C => 0,TKEEP_MODE_C => TKEEP_COMP_C,TUSER_BITS_C => 4,TUSER_MODE_C => TUSER_FIRST_LAST_C) EMAC_AXIS_CONFIG_C
array(natural range <> ) of EthMacCsumAccumType EthMacCsumAccumArray