SURF  1.0
UdpEngineArp.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : UdpEngineArp.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2015-08-20
5 -- Last update: 2016-09-16
6 -------------------------------------------------------------------------------
7 -- Description: UDP Client's ARP Messaging Module
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 
26 --! @see entity
27  --! @ingroup ethernet_UdpEngine
28 entity UdpEngineArp is
29  generic (
30  TPD_G : time := 1 ns;
31  CLIENT_SIZE_G : positive := 1;
32  CLK_FREQ_G : real := 156.25E+06;
33  COMM_TIMEOUT_G : positive := 30);
34  port (
35  -- Local Configurations
36  localIp : in slv(31 downto 0); -- big-Endian configuration
37  -- Interface to ARP Engine
38  arpReqMasters : out AxiStreamMasterArray(CLIENT_SIZE_G-1 downto 0); -- Request via IP address
40  arpAckMasters : in AxiStreamMasterArray(CLIENT_SIZE_G-1 downto 0); -- Respond with MAC address
42  -- Interface to UDP Client engine(s)
43  clientRemoteDet : in slv(CLIENT_SIZE_G-1 downto 0);
46  -- Clock and Reset
47  clk : in sl;
48  rst : in sl);
49 end UdpEngineArp;
50 
51 architecture rtl of UdpEngineArp is
52 
53  constant TIMER_1_SEC_C : natural := getTimeRatio(CLK_FREQ_G, 1.0);
54  type TimerArray is array (natural range <>) of natural range 0 to COMM_TIMEOUT_G;
55 
56  type StateType is (
57  IDLE_S,
58  WAIT_S,
59  COMM_MONITOR_S);
60  type StateArray is array (natural range <>) of StateType;
61 
62  type RegType is record
66  timerEn : sl;
67  timer : natural range 0 to (TIMER_1_SEC_C-1);
68  arpTimers : TimerArray(CLIENT_SIZE_G-1 downto 0);
69  state : StateArray(CLIENT_SIZE_G-1 downto 0);
70  end record RegType;
71  constant REG_INIT_C : RegType := (
72  clientRemoteMac => (others => (others => '0')),
75  timerEn => '0',
76  timer => 0,
77  arpTimers => (others => 0),
78  state => (others => IDLE_S));
79 
80  signal r : RegType := REG_INIT_C;
81  signal rin : RegType;
82 
83 begin
84 
86  variable v : RegType;
87  variable i : natural;
88  begin
89  -- Latch the current value
90  v := r;
91 
92  -- Reset the flags
93  v.timerEn := '0';
94  for i in CLIENT_SIZE_G-1 downto 0 loop
96  if arpReqSlaves(i).tReady = '1' then
97  v.arpReqMasters(i).tValid := '0';
98  end if;
99  end loop;
100 
101 
102  -- Increment the timer
103  if r.timer = (TIMER_1_SEC_C-1) then
104  v.timer := 0;
105  v.timerEn := '1';
106  else
107  v.timer := r.timer + 1;
108  end if;
109 
110  -- Loop through the clients
111  for i in CLIENT_SIZE_G-1 downto 0 loop
112 
113  -- Update the timers
114  if (r.timerEn = '1') and (r.arpTimers(i) /= 0) then
115  -- Decrement the timers
116  v.arpTimers(i) := r.arpTimers(i) - 1;
117  end if;
118 
119  -- Update the IP address
120  v.arpReqMasters(i).tData(31 downto 0) := clientRemoteIp(i);
121 
122  -- Check for dynamic change in IP address
123  if (r.arpReqMasters(i).tData(31 downto 0) /= clientRemoteIp(i)) or (clientRemoteIp(i) = 0) then
124  -- Stop any outstanding requests
125  v.arpReqMasters(i).tValid := '0';
126  -- Reset the remote MAC address
127  v.clientRemoteMac(i) := (others => '0');
128  -- Next state
129  v.state(i) := IDLE_S;
130  else
131  -- State Machine
132  case r.state(i) is
133  ----------------------------------------------------------------------
134  when IDLE_S =>
135  -- Reset the counter
136  v.arpTimers(i) := 0;
137  -- Reset the remote MAC address
138  v.clientRemoteMac(i) := (others => '0');
139  -- Check if we have a non-zero IP address to request
140  if clientRemoteIp(i) /= 0 then
141  -- Make an ARP request
142  v.arpReqMasters(i).tValid := '1';
143  -- Next state
144  v.state(i) := WAIT_S;
145  end if;
146  ----------------------------------------------------------------------
147  when WAIT_S =>
148  -- Wait for the ARP response
149  if arpAckMasters(i).tValid = '1' then
150  -- Accept the data
151  v.arpAckSlaves(i).tReady := '1';
152  -- Latch the MAC address value
153  v.clientRemoteMac(i) := arpAckMasters(i).tData(47 downto 0);
154  -- Preset the timer
155  v.arpTimers(i) := COMM_TIMEOUT_G;
156  -- Next state
157  v.state(i) := COMM_MONITOR_S;
158  end if;
159  ----------------------------------------------------------------------
160  when COMM_MONITOR_S =>
161  -- Check for inbound client communication
162  if clientRemoteDet(i) = '1' then
163  -- Preset the timer
164  v.arpTimers(i) := COMM_TIMEOUT_G;
165  elsif r.arpTimers(i) = 0 then
166  -- Next state
167  v.state(i) := IDLE_S;
168  end if;
169  ----------------------------------------------------------------------
170  end case;
171  end if;
172  end loop;
173 
174  -- Reset
175  if (rst = '1') then
176  v := REG_INIT_C;
177  end if;
178 
179  -- Register the variable for next clock cycle
180  rin <= v;
181 
182  -- Outputs
186 
187  end process comb;
188 
189  seq : process (clk) is
190  begin
191  if rising_edge(clk) then
192  r <= rin after TPD_G;
193  end if;
194  end process seq;
195 
196 end rtl;
array(natural range <> ) of AxiStreamSlaveType AxiStreamSlaveArray
array(natural range <> ) of slv( 31 downto 0) Slv32Array
Definition: StdRtlPkg.vhd:379
out clientRemoteMacSlv48Array( CLIENT_SIZE_G- 1 downto 0)
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
array(natural range <> ) of slv( 47 downto 0) Slv48Array
Definition: StdRtlPkg.vhd:363
CLIENT_SIZE_Gpositive := 1
_library_ ieeeieee
Definition: UdpEngine.vhd:18
TPD_Gtime := 1 ns
CLK_FREQ_Greal := 156.25E+06
in clientRemoteDetslv( CLIENT_SIZE_G- 1 downto 0)
slv( 127 downto 0) tData
AxiStreamSlaveType :=(tReady => '0') AXI_STREAM_SLAVE_INIT_C
out arpReqMastersAxiStreamMasterArray( CLIENT_SIZE_G- 1 downto 0)
array(natural range <> ) of AxiStreamMasterType AxiStreamMasterArray
in clientRemoteIpSlv32Array( CLIENT_SIZE_G- 1 downto 0)
COMM_TIMEOUT_Gpositive := 30
in arpReqSlavesAxiStreamSlaveArray( CLIENT_SIZE_G- 1 downto 0)
out arpAckSlavesAxiStreamSlaveArray( CLIENT_SIZE_G- 1 downto 0)
in arpAckMastersAxiStreamMasterArray( CLIENT_SIZE_G- 1 downto 0)
std_logic_vector slv
Definition: StdRtlPkg.vhd:29