1 ------------------------------------------------------------------------------- 2 -- File : IpV4EngineRx.vhd 3 -- Company : SLAC National Accelerator Laboratory 4 -- Created : 2015-08-12 5 -- Last update: 2016-09-16 6 ------------------------------------------------------------------------------- 7 -- Description: IPv4 RX Engine Module 8 -- Note: IPv4 checksum checked in EthMac core 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_unsigned.
all;
22 use ieee.std_logic_arith.
all;
30 --! @ingroup ethernet_IpV4Engine 39 -- Interface to Ethernet Frame MUX/DEMUX 42 localhostMaster :
in AxiStreamMasterType;
43 localhostSlave :
out AxiStreamSlaveType;
44 -- Interface to Protocol Engine 62 type RegType is record 65 len : slv(15 downto 0);
66 protocol : slv(7 downto 0);
73 constant REG_INIT_C : RegType := ( 76 len => (others => '0'), 77 protocol => (others => '0'), 78 tKeep => (others => '0'), 79 tData => (others => '0'), 84 signal r : RegType := REG_INIT_C;
91 -- attribute dont_touch : string; 92 -- attribute dont_touch of r : signal is "TRUE"; 114 comb :
process (r,
rst, rxMaster, txSlave)
is 115 variable v : RegType;
118 -- Latch the current value 123 if (txSlave.tReady = '1') then 125 v.txMaster.tLast := '0';
126 v.txMaster.tUser := (others => '0');
127 v.txMaster.tKeep := (others => '1');
132 ---------------------------------------------------------------------- 135 if (rxMaster.tValid = '1') and (v.txMaster.tValid = '0') then 138 -- Check for SOF with no EOF 140 -- Latch the remote MAC address 141 v.txMaster.tData(47 downto 0) := rxMaster.tData(95 downto 48);
143 v.txMaster.tData(63 downto 48) := (others => '0');
145 v.state := IPV4_HDR0_S;
148 ---------------------------------------------------------------------- 151 if (rxMaster.tValid = '1') and (v.txMaster.tValid = '0') then 154 -- Check for non-VLAN 156 -- Calculate the IPV4 Pseudo Header length (in little Endian) 157 v.len(15 downto 8) := rxMaster.tData(7 downto 0);
-- IPV4_Length(15 downto 8) 158 v.len(7 downto 0) := rxMaster.tData(15 downto 8);
-- IPV4_Length(7 downto 0) 159 v.len := v.len - 20;
-- IPV4 Pseudo Header's length = protocol length - 20 Bytes 160 -- Latch the protocol value 161 v.protocol := rxMaster.tData(63 downto 56);
162 -- Source IP Address(31 downto 0) 163 v.txMaster.tData(95 downto 64) := rxMaster.tData(111 downto 80);
164 -- Destination IP Address(31 downto 16) 165 v.txMaster.tData(111 downto 96) := rxMaster.tData(127 downto 112);
167 -- Calculate the IPV4 Pseudo Header length (in little Endian) 168 v.len(15 downto 8) := rxMaster.tData(39 downto 32);
-- IPV4_Length(15 downto 8) 169 v.len(7 downto 0) := rxMaster.tData(47 downto 40);
-- IPV4_Length(7 downto 0) 170 v.len := v.len - 20;
-- IPV4 Pseudo Header's length = protocol length - 20 Bytes 171 -- Latch the protocol value 172 v.protocol := rxMaster.tData(95 downto 88);
173 -- Source IP Address(31 downto 16) 174 v.txMaster.tData(79 downto 64) := rxMaster.tData(127 downto 112);
176 -- Next state if protocol not detected during the "for loop" 178 -- Loop through the protocol buses 181 -- Latch the protocol bus pointer 182 v.txMaster.tDest := toSlv(i, 8);
183 -- Next state if protocol not detected 184 v.state := IPV4_HDR1_S;
188 ---------------------------------------------------------------------- 191 if (rxMaster.tValid = '1') and (v.txMaster.tValid = '0') then 196 -- Check for non-VLAN 198 -- Destination IP Address(15 downto 0) 199 v.txMaster.tData(127 downto 112) := rxMaster.tData(15 downto 0);
200 -- Track the leftovers 201 v.tData(7 downto 0) := x"00";
202 v.tData(15 downto 8) := r.protocol;
203 v.tData(23 downto 16) := r.len(15 downto 8);
204 v.tData(31 downto 24) := r.len(7 downto 0);
205 v.tData(127 downto 32) := rxMaster.tData(111 downto 16);
206 v.tKeep(3 downto 0) := "1111";
207 v.tKeep(15 downto 4) := rxMaster.tKeep(13 downto 2);
210 -- Check for no remainder 211 if (rxMaster.tKeep(15 downto 14) = 0) then 218 v.state := IPV4_HDR2_S;
223 -- Source IP Address(15 downto 0) 224 v.txMaster.tData(95 downto 80) := rxMaster.tData(15 downto 0);
225 -- Destination IP Address(31 downto 0) 226 v.txMaster.tData(127 downto 96) := rxMaster.tData(47 downto 16);
227 -- Track the leftovers 228 v.tData(7 downto 0) := x"00";
229 v.tData(15 downto 8) := r.protocol;
230 v.tData(23 downto 16) := r.len(15 downto 8);
231 v.tData(31 downto 24) := r.len(7 downto 0);
232 v.tData(111 downto 32) := rxMaster.tData(127 downto 48);
233 v.tKeep(3 downto 0) := "1111";
234 v.tKeep(13 downto 4) := rxMaster.tKeep(15 downto 6);
235 v.tKeep(15 downto 14) := "00";
239 if (rxMaster.tLast = '1') then 240 -- Check the leftovers 241 if (v.tKeep /= 0) then 246 v.txMaster.tLast := '1';
257 ---------------------------------------------------------------------- 260 if (rxMaster.tValid = '1') and (v.txMaster.tValid = '0') then 267 -- Track the leftovers 268 v.tData(15 downto 0) := rxMaster.tData(127 downto 112);
269 v.tKeep(1 downto 0) := rxMaster.tKeep(15 downto 14);
270 v.tKeep(15 downto 2) := (others => '0');
274 if (rxMaster.tLast = '1') then 275 -- Check the leftovers 276 if (v.tKeep /= 0) then 281 v.txMaster.tLast := '1';
291 ---------------------------------------------------------------------- 294 if (rxMaster.tValid = '1') and (v.txMaster.tValid = '0') then 299 -- Check for non-VLAN 302 v.txMaster.tData(15 downto 0) := r.tData(15 downto 0);
303 v.txMaster.tData(127 downto 16) := rxMaster.tData(111 downto 0);
304 v.txMaster.tKeep(1 downto 0) := r.tKeep(1 downto 0);
305 v.txMaster.tKeep(15 downto 2) := rxMaster.tKeep(13 downto 0);
306 -- Track the leftovers 307 v.tData(15 downto 0) := rxMaster.tData(127 downto 112);
308 v.tKeep(1 downto 0) := rxMaster.tKeep(15 downto 14);
313 v.txMaster.tData(111 downto 0) := r.tData(111 downto 0);
314 v.txMaster.tData(127 downto 112) := rxMaster.tData(15 downto 0);
315 v.txMaster.tKeep(13 downto 0) := r.tKeep(13 downto 0);
316 v.txMaster.tKeep(15 downto 14) := rxMaster.tKeep(1 downto 0);
317 -- Track the leftovers 318 v.tData(111 downto 0) := rxMaster.tData(127 downto 16);
319 v.tKeep(13 downto 0) := rxMaster.tKeep(15 downto 2);
324 if (v.tLast = '1') then 325 -- Check the leftover tKeep is not empty 326 if (v.tKeep /= 0) then 331 v.txMaster.tLast := '1';
338 ---------------------------------------------------------------------- 341 if (v.txMaster.tValid = '0') then 346 v.txMaster.tLast := '1';
351 ---------------------------------------------------------------------- 359 -- Register the variable for next clock cycle 363 rxSlave <= v.rxSlave;
367 seq :
process (
clk)
is 369 if rising_edge(clk) then 370 r <= rin after TPD_G;
PIPE_STAGES_Ginteger range 0 to 16:= 0
array(natural range <> ) of AxiStreamSlaveType AxiStreamSlaveArray
out ibIpv4SlaveAxiStreamSlaveType
in ibIpv4MasterAxiStreamMasterType
out ibProtocolMastersAxiStreamMasterArray( PROTOCOL_SIZE_G- 1 downto 0)
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
out mAxisMastersAxiStreamMasterArray( NUM_MASTERS_G- 1 downto 0)
out sAxisSlaveAxiStreamSlaveType
SIM_ERROR_HALT_Gboolean := false
out mAxisMasterAxiStreamMasterType
NUM_SLAVES_Ginteger range 1 to 32:= 4
AxiStreamSlaveType :=(tReady => '0') AXI_STREAM_SLAVE_INIT_C
in sAxisMasterAxiStreamMasterType
array(natural range <> ) of AxiStreamMasterType AxiStreamMasterArray
out localhostSlaveAxiStreamSlaveType
in mAxisSlavesAxiStreamSlaveArray( NUM_MASTERS_G- 1 downto 0)
slv( 7 downto 0) := x"11" UDP_C
PROTOCOL_SIZE_Gpositive := 1
array(natural range <> ) of slv( 7 downto 0) Slv8Array
in localhostMasterAxiStreamMasterType
in mAxisSlaveAxiStreamSlaveType
NUM_MASTERS_Ginteger range 1 to 32:= 12
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
in ibProtocolSlavesAxiStreamSlaveArray( PROTOCOL_SIZE_G- 1 downto 0)
PROTOCOL_GSlv8Array :=( 0=> UDP_C)
PIPE_STAGES_Ginteger range 0 to 16:= 0