1 ------------------------------------------------------------------------------- 2 -- File : ArpEngine.vhd 3 -- Company : SLAC National Accelerator Laboratory 4 -- Created : 2015-08-12 5 -- Last update: 2016-09-16 6 ------------------------------------------------------------------------------- 7 -- Description: ARP Engine 8 ------------------------------------------------------------------------------- 9 -- This file is part of 'SLAC Firmware Standard Library'. 10 -- It is subject to the license terms in the LICENSE.txt file found in the 11 -- top-level directory of this distribution and at: 12 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. 13 -- No part of 'SLAC Firmware Standard Library', including this file, 14 -- may be copied, modified, propagated, or distributed except according to 15 -- the terms contained in the LICENSE.txt file. 16 ------------------------------------------------------------------------------- 19 use ieee.std_logic_1164.
all;
20 use ieee.std_logic_unsigned.
all;
21 use ieee.std_logic_arith.
all;
29 --! @ingroup ethernet_IpV4Engine 37 -- Local Configuration 38 localMac :
in slv(
47 downto 0);
39 localIp :
in slv(
31 downto 0);
40 -- Interface to Client Engine(s) 45 -- Interface to Ethernet Frame MUX/DEMUX 58 constant BROADCAST_MAC_C : slv(47 downto 0) := (others => '1');
59 constant HARDWWARE_TYPE_C : slv(15 downto 0) := x"0100";
-- HardwareType = ETH = 0x0001 60 constant PROTOCOL_TYPE_C : slv(15 downto 0) := x"0008";
-- ProtocolType = IP = 0x0800 61 constant HARDWWARE_LEN_C : slv(7 downto 0) := x"06";
-- HardwareLength = 6 (6 Bytes/MAC) 62 constant PROTOCOL_LEN_C : slv(7 downto 0) := x"04";
-- ProtocolLength = 4 (6 Bytes/IP) 63 constant ARP_REQ_C : slv(15 downto 0) := x"0100";
-- OpCode = ARP Request = 0x0001 64 constant ARP_REPLY_C : slv(15 downto 0) := x"0200";
-- OpCode = ARP Reply = 0x0002 65 constant TIMER_1_SEC_C : := getTimeRatio(CLK_FREQ_G, 1.
0);
74 type RegType is record 86 constant REG_INIT_C : RegType := ( 88 tData => (others => (others => '0')), 93 arpTimers => (others => 0), 98 signal r : RegType := REG_INIT_C;
101 -- attribute dont_touch : string; 102 -- attribute dont_touch of r : signal is "TRUE"; 107 variable v : RegType;
110 -- Latch the current value 127 if r.arpTimers(i) /= 0 then 128 -- Decrement the timers 129 v.arpTimers(i) := r.arpTimers(i) - 1;
135 ---------------------------------------------------------------------- 139 -- Check for inbound data 144 -- Increment the counter 148 v.reqCnt := r.reqCnt + 1;
150 -- Check the tValid and timer 153 v.arpTimers(r.reqCnt) := TIMER_1_SEC_C;
154 -- Check if localhost 161 ------------------------ 162 -- Checking for non-VLAN 163 ------------------------ 165 v.tData(0)(47 downto 0) := BROADCAST_MAC_C;
168 v.tData(0)(127 downto 112) := HARDWWARE_TYPE_C;
169 v.tData(1)(15 downto 0) := PROTOCOL_TYPE_C;
170 v.tData(1)(23 downto 16) := HARDWWARE_LEN_C;
171 v.tData(1)(31 downto 24) := PROTOCOL_LEN_C;
172 v.tData(1)(47 downto 32) := ARP_REQ_C;
175 v.tData(2)(47 downto 0) := BROADCAST_MAC_C;
177 v.tData(2)(127 downto 80) := (others => '0');
182 v.tData(0)(47 downto 0) := BROADCAST_MAC_C;
185 v.tData(0)(127 downto 122) := (others => '0');
187 v.tData(1)(31 downto 16) := HARDWWARE_TYPE_C;
188 v.tData(1)(47 downto 32) := PROTOCOL_TYPE_C;
189 v.tData(1)(55 downto 48) := HARDWWARE_LEN_C;
190 v.tData(1)(63 downto 56) := PROTOCOL_LEN_C;
191 v.tData(1)(79 downto 64) := ARP_REQ_C;
194 v.tData(2)(79 downto 32) := BROADCAST_MAC_C;
196 v.tData(2)(127 downto 112) := (others => '0');
203 ---------------------------------------------------------------------- 213 -- Increment the counter 223 -- Increment the counter 233 -- Increment the counter 236 -- Check for EOFE error 248 -- Check for EOFE error 259 ---------------------------------------------------------------------- 261 -- Default next state 265 ------------------------ 266 -- Checking for non-VLAN 267 ------------------------ 269 if (r.tData(0)(127 downto 112) = HARDWWARE_TYPE_C) -- Check for valid Hardware type 270 and (r.tData(1)(15 downto 0) = PROTOCOL_TYPE_C) -- Check for valid Protocol type 271 and (r.tData(1)(23 downto 16) = HARDWWARE_LEN_C) -- Check for valid Hardware Length 272 and (r.tData(1)(31 downto 24) = PROTOCOL_LEN_C) then -- Check for valid Protocol Length 273 -- Check OP-CODE = ARP Request 274 if (r.tData(1)(47 downto 32) = ARP_REQ_C) then 275 -- Check if the target IP address matches local address 277 -- Modified the local buffer to become a reply packet 278 v.tData(0)(47 downto 0) := r.tData(0)(95 downto 48);
280 v.tData(1)(47 downto 32) := ARP_REPLY_C;
283 v.tData(2)(47 downto 0) := r.tData(1)(95 downto 48);
284 v.tData(2)(79 downto 48) := r.tData(1)(127 downto 96);
285 v.tData(2)(127 downto 80) := (others => '0');
289 -- Check OP-CODE = ARP Reply 290 elsif (r.tData(1)(47 downto 32) = ARP_REPLY_C) then 291 -- Check if the target IP + MAC address matches local address 302 if (r.tData(1)(31 downto 16) = HARDWWARE_TYPE_C) -- Check for valid Hardware type 303 and (r.tData(1)(47 downto 32) = PROTOCOL_TYPE_C) -- Check for valid Protocol type 304 and (r.tData(1)(55 downto 48) = HARDWWARE_LEN_C) -- Check for valid Hardware Length 305 and (r.tData(1)(63 downto 56) = PROTOCOL_LEN_C) then -- Check for valid Protocol Length 306 -- Check OP-CODE = ARP Request 307 if (r.tData(1)(79 downto 64) = ARP_REQ_C) then 308 -- Check if the target IP address matches local address 310 -- Modified the local buffer to become a reply packet 311 v.tData(0)(47 downto 0) := r.tData(0)(95 downto 48);
313 v.tData(1)(79 downto 64) := ARP_REPLY_C;
316 v.tData(2)(79 downto 32) := r.tData(1)(127 downto 80);
317 v.tData(2)(111 downto 80) := r.tData(2)(31 downto 0);
318 v.tData(2)(127 downto 112) := (others => '0');
322 -- Check OP-CODE = ARP Reply 323 elsif (r.tData(1)(79 downto 64) = ARP_REPLY_C) then 324 -- Check if the target IP + MAC address matches local address 332 ---------------------------------------------------------------------- 336 ------------------------ 337 -- Checking for non-VLAN 338 ------------------------ 340 -- Check if Source's IP address match request IP address 347 v.arpTimers(r.ackCnt) := 0;
350 -- Check if Source's IP address match request IP address 357 v.arpTimers(r.ackCnt) := 0;
368 v.ackCnt := r.ackCnt + 1;
370 ---------------------------------------------------------------------- 372 -- Check if ready to move data 373 if v.txArpMaster.tValid = '0' then 375 v.txArpMaster.tValid := '1';
377 -- Increment the counter 383 v.txArpMaster.tLast := '1';
386 v.txArpMaster.tKeep := x"03FF";
388 v.txArpMaster.tKeep := x"3FFF";
394 ---------------------------------------------------------------------- 402 -- Register the variable for next clock cycle 413 seq :
process (
clk)
is 415 if rising_edge(clk) then 416 r <= rin after TPD_G;
array(natural range <> ) of AxiStreamSlaveType AxiStreamSlaveArray
in localIpslv( 31 downto 0)
CLIENT_SIZE_Gpositive := 1
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
in localMacslv( 47 downto 0)
CLK_FREQ_Greal := 156.25E+06
out ibArpSlaveAxiStreamSlaveType
slv( 15 downto 0) := x"0608" ARP_TYPE_C
array(natural range <> ) of natural NaturalArray
AxiStreamSlaveType :=(tReady => '0') AXI_STREAM_SLAVE_INIT_C
out obArpMasterAxiStreamMasterType
in ibArpMasterAxiStreamMasterType
array(natural range <> ) of slv( 127 downto 0) Slv128Array
out arpAckMastersAxiStreamMasterArray( CLIENT_SIZE_G- 1 downto 0)
array(natural range <> ) of AxiStreamMasterType AxiStreamMasterArray
out arpReqSlavesAxiStreamSlaveArray( CLIENT_SIZE_G- 1 downto 0)
slv( 15 downto 0) := x"0081" VLAN_TYPE_C
in arpReqMastersAxiStreamMasterArray( CLIENT_SIZE_G- 1 downto 0)
in obArpSlaveAxiStreamSlaveType
in arpAckSlavesAxiStreamSlaveArray( CLIENT_SIZE_G- 1 downto 0)
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