SURF  1.0
IcmpEngine.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : IcmpEngine.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2016-08-16
5 -- Last update: 2016-09-16
6 -------------------------------------------------------------------------------
7 -- Description: ICMP Engine (A.K.A. "ping" protocol)
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 -------------------------------------------------------------------------------
17 
18 library ieee;
19 use ieee.std_logic_1164.all;
20 use ieee.std_logic_unsigned.all;
21 use ieee.std_logic_arith.all;
22 
23 use work.StdRtlPkg.all;
24 use work.AxiStreamPkg.all;
25 use work.SsiPkg.all;
26 use work.EthMacPkg.all;
27 
28 --! @see entity
29  --! @ingroup ethernet_IpV4Engine
30 entity IcmpEngine is
31  generic (
32  TPD_G : time := 1 ns);
33  port (
34  -- Local Configurations
35  localIp : in slv(31 downto 0); -- big-Endian configuration
36  -- Interface to ICMP Engine
41  -- Clock and Reset
42  clk : in sl;
43  rst : in sl);
44 end IcmpEngine;
45 
46 architecture rtl of IcmpEngine is
47 
48  type StateType is (
49  IDLE_S,
50  RX_HDR_S,
51  TX_HDR_S,
52  MOVE_S);
53 
54  type RegType is record
55  tData : slv(127 downto 0);
56  checksum : slv(15 downto 0);
59  state : StateType;
60  end record RegType;
61  constant REG_INIT_C : RegType := (
62  tData => (others => '0'),
63  checksum => (others => '0'),
66  state => IDLE_S);
67 
68  signal r : RegType := REG_INIT_C;
69  signal rin : RegType;
70 
71  -- attribute dont_touch : string;
72  -- attribute dont_touch of r : signal is "TRUE";
73 
74 begin
75 
76  comb : process (ibIcmpMaster, localIp, obIcmpSlave, r, rst) is
77  variable v : RegType;
78  variable eofe : sl;
79  begin
80  -- Latch the current value
81  v := r;
82 
83  -- Reset the flags
85  if obIcmpSlave.tReady = '1' then
86  v.obIcmpMaster.tValid := '0';
87  v.obIcmpMaster.tLast := '0';
88  v.obIcmpMaster.tUser := (others => '0');
89  v.obIcmpMaster.tKeep := (others => '1');
90  end if;
91 
92  -- Update the variable
93  eofe := ssiGetUserEofe(EMAC_AXIS_CONFIG_C, ibIcmpMaster);
94 
95  ------------------------------------------------
96  -- Notes: Non-Standard IPv4 Pseudo Header Format
97  ------------------------------------------------
98  -- tData[0][47:0] = Remote MAC Address
99  -- tData[0][63:48] = zeros
100  -- tData[0][95:64] = Remote IP Address
101  -- tData[0][127:96] = Local IP address
102  -- tData[1][7:0] = zeros
103  -- tData[1][15:8] = Protocol Type = ICMP
104  -- tData[1][31:16] = IPv4 Pseudo header length
105  -- tData[1][39:32] = Type of message
106  -- tData[1][47:40] = Code
107  -- tData[1][63:48] = Checksum
108  -- tData[1][95:64] = ICMP Header
109  -- tData[1][127:96] = ICMP Datagram
110  ------------------------------------------------
111 
112  -- State Machine
113  case r.state is
114  ----------------------------------------------------------------------
115  when IDLE_S =>
116  -- Check for data
117  if (ibIcmpMaster.tValid = '1') then
118  -- Accept the data
119  v.ibIcmpSlave.tReady := '1';
120  -- Check for SOF with no EOF
121  if (ssiGetUserSof(EMAC_AXIS_CONFIG_C, ibIcmpMaster) = '1') and (ibIcmpMaster.tLast = '0') then
122  -- Copy IPv4 base header
123  v.tData(63 downto 0) := ibIcmpMaster.tData(63 downto 0);
124  -- Swap the IP addresses
125  v.tData(95 downto 64) := ibIcmpMaster.tData(127 downto 96); -- SRC IP
126  v.tData(127 downto 96) := ibIcmpMaster.tData(95 downto 64); -- DST IP
127  if ibIcmpMaster.tData(127 downto 96) = localIp then
128  -- Next state
129  v.state := RX_HDR_S;
130  end if;
131  end if;
132  end if;
133  ----------------------------------------------------------------------
134  when RX_HDR_S =>
135  -- Check for data
136  if (ibIcmpMaster.tValid = '1') and (v.obIcmpMaster.tValid = '0') then
137  -- Check for Echo request
138  if (ibIcmpMaster.tData(47 downto 32) = x"0008") then
139  -- Map the inbound checksum to little Endian
140  v.checksum(15 downto 8) := ibIcmpMaster.tData(55 downto 48);
141  v.checksum(7 downto 0) := ibIcmpMaster.tData(63 downto 56);
142  -- Update the checksum for outbound data packet
143  v.checksum := v.checksum + x"0800";
144  ---------------------------------------------------------
145  -- Note: To save FPGA resources, we do NOT cache the data
146  -- for properly calculating the checksum. Instead,
147  -- we calculate the outbound checksum with respect
148  -- to the inbound checksum and assume that the
149  -- computer interface will probably check our
150  -- outbound packet.
151  ---------------------------------------------------------
152  -- Send the IPv4 base header
153  v.obIcmpMaster.tValid := '1';
154  v.obIcmpMaster.tData := r.tData;
155  ssiSetUserSof(EMAC_AXIS_CONFIG_C, v.obIcmpMaster, '1');
156  -- Next state
157  v.state := TX_HDR_S;
158  else
159  -- Next state
160  v.state := IDLE_S;
161  end if;
162  end if;
163  ----------------------------------------------------------------------
164  when TX_HDR_S =>
165  -- Check for data
166  if (ibIcmpMaster.tValid = '1') and (v.obIcmpMaster.tValid = '0') then
167  -- Accept the data
168  v.ibIcmpSlave.tReady := '1';
169  -- Send the IPv4 base header
170  v.obIcmpMaster.tValid := '1';
171  v.obIcmpMaster.tData(31 downto 0) := ibIcmpMaster.tData(31 downto 0);
172  v.obIcmpMaster.tData(47 downto 32) := x"0000"; -- Echo reply
173  v.obIcmpMaster.tData(55 downto 48) := r.checksum(15 downto 8);
174  v.obIcmpMaster.tData(63 downto 56) := r.checksum(7 downto 0);
175  v.obIcmpMaster.tData(127 downto 64) := ibIcmpMaster.tData(127 downto 64);
178  if ibIcmpMaster.tLast = '1' then
179  -- Echo back EOFE
180  ssiSetUserEofe(EMAC_AXIS_CONFIG_C, v.obIcmpMaster, eofe);
181  -- Next state
182  v.state := IDLE_S;
183  else
184  -- Next state
185  v.state := MOVE_S;
186  end if;
187  end if;
188  ----------------------------------------------------------------------
189  when MOVE_S =>
190  -- Check for data
191  if (ibIcmpMaster.tValid = '1') and (v.obIcmpMaster.tValid = '0') then
192  -- Accept the data
193  v.ibIcmpSlave.tReady := '1';
194  -- Send the IPv4 base header
195  v.obIcmpMaster.tValid := '1';
199  if ibIcmpMaster.tLast = '1' then
200  -- Echo back EOFE
201  ssiSetUserEofe(EMAC_AXIS_CONFIG_C, v.obIcmpMaster, eofe);
202  -- Next state
203  v.state := IDLE_S;
204  end if;
205  end if;
206  ----------------------------------------------------------------------
207  end case;
208 
209  -- Reset
210  if (rst = '1') then
211  v := REG_INIT_C;
212  end if;
213 
214  -- Register the variable for next clock cycle
215  rin <= v;
216 
217  -- Outputs
220 
221  end process comb;
222 
223  seq : process (clk) is
224  begin
225  if rising_edge(clk) then
226  r <= rin after TPD_G;
227  end if;
228  end process seq;
229 
230 end rtl;
out obIcmpMasterAxiStreamMasterType
Definition: IcmpEngine.vhd:39
in obIcmpSlaveAxiStreamSlaveType
Definition: IcmpEngine.vhd:40
std_logic sl
Definition: StdRtlPkg.vhd:28
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
sl eofe
Definition: SsiPkg.vhd:74
in clksl
Definition: IcmpEngine.vhd:42
slv( 15 downto 0) tKeep
in localIpslv( 31 downto 0)
Definition: IcmpEngine.vhd:35
in rstsl
Definition: IcmpEngine.vhd:43
slv( 127 downto 0) tData
AxiStreamSlaveType :=(tReady => '0') AXI_STREAM_SLAVE_INIT_C
out ibIcmpSlaveAxiStreamSlaveType
Definition: IcmpEngine.vhd:38
slv( 127 downto 0) tUser
TPD_Gtime := 1 ns
Definition: IcmpEngine.vhd:32
in ibIcmpMasterAxiStreamMasterType
Definition: IcmpEngine.vhd:37
_library_ ieeeieee
Definition: ArpEngine.vhd:18
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
Definition: EthMacPkg.vhd:58
std_logic_vector slv
Definition: StdRtlPkg.vhd:29