AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Variables
udp_rarp_block.vhd
1 -- Builds outbound rarp request at random intervals...
2 --
3 -- Dave Sankey, June 2013
4 
5 library ieee;
6 use ieee.std_logic_1164.all;
7 use ieee.numeric_std.all;
8 
9 entity udp_rarp_block is
10  port (
11  mac_clk: in std_logic;
12  rst_macclk: in std_logic;
13  enable_125: in std_logic;
14  MAC_addr: in std_logic_vector(47 downto 0);
15  rarp_mode: in std_logic;
16  rarp_addr: out std_logic_vector(12 downto 0);
17  rarp_data: out std_logic_vector(7 downto 0);
18  rarp_end_addr: out std_logic_vector(12 downto 0);
19  rarp_send: out std_logic;
20  rarp_we: out std_logic
21  );
22 end udp_rarp_block;
23 
24 architecture rtl of udp_rarp_block is
25 
26  signal rarp_we_sig: std_logic;
27  signal address: unsigned(5 downto 0);
28  signal rarp_req, tick: std_logic;
29  signal rndm: std_logic_vector(4 downto 0);
30 
31 begin
32 
33  rarp_we <= rarp_we_sig;
34  rarp_addr <= std_logic_vector("0000000" & address);
35 
36 send_packet: process (mac_clk)
37  variable last_we, send_i: std_logic;
38  variable end_addr_i: std_logic_vector(12 downto 0);
39  begin
40  if rising_edge(mac_clk) then
41  if rarp_we_sig = '0' and last_we = '1' then
42  end_addr_i := std_logic_vector(to_unsigned(41, 13));
43  send_i := '1';
44  else
45  end_addr_i := (Others => '0');
46  send_i := '0';
47  end if;
48  last_we := rarp_we_sig;
49  rarp_end_addr <= end_addr_i
50 -- pragma translate_off
51  after 4 ns
52 -- pragma translate_on
53  ;
54  rarp_send <= send_i
55 -- pragma translate_off
56  after 4 ns
57 -- pragma translate_on
58  ;
59  end if;
60  end process;
61 
62 -- rarp:
63 -- Ethernet DST_MAC(6), SRC_MAC(6), Ether_Type = x"8035"
64 -- HTYPE = x"0001"
65 -- PTYPE = x"0800"
66 -- HLEN = x"06", PLEN = x"04"
67 -- OPER = x"0003"
68 -- SHA(6)
69 -- SPA(4)
70 -- THA(6)
71 -- TPA(4)
72 data_block: process(mac_clk)
73  variable data_buffer: std_logic_vector(335 downto 0);
74  variable we_buffer: std_logic_vector(41 downto 0);
75  begin
76  if rising_edge(mac_clk) then
77  if (rst_macclk = '1') then
78  we_buffer := (Others => '0');
79  elsif rarp_req = '1' then
80  data_buffer := x"FFFFFFFFFFFF" & MAC_addr & x"8035" & x"0001" &
81  x"0800" & x"06" & x"04" & x"0003" & MAC_addr & x"00000000" &
82  MAC_addr & x"00000000";
83  we_buffer := (Others => '1');
84  end if;
85  rarp_data <= data_buffer(335 downto 328)
86 -- pragma translate_off
87  after 4 ns
88 -- pragma translate_on
89  ;
90  rarp_we_sig <= we_buffer(41)
91 -- pragma translate_off
92  after 4 ns
93 -- pragma translate_on
94  ;
95  data_buffer := data_buffer(327 downto 0) & x"00";
96  we_buffer := we_buffer(40 downto 0) & '0';
97  end if;
98  end process;
99 
100 addr_block: process(mac_clk)
101  variable addr_int, next_addr: unsigned(5 downto 0);
102  variable counting: std_logic;
103  begin
104  if rising_edge(mac_clk) then
105  if rst_macclk = '1' then
106  next_addr := (Others => '0');
107  counting := '0';
108  elsif rarp_req = '1' then
109  counting := '1';
110  elsif rarp_we_sig = '0' then
111  next_addr := (Others => '0');
112  counting := '0';
113  end if;
114  addr_int := next_addr;
115  address <= addr_int
116 -- pragma translate_off
117  after 4 ns
118 -- pragma translate_on
119  ;
120  if counting = '1' then
121  next_addr := addr_int + 1;
122  end if;
123  end if;
124  end process;
125 
126 tick_counter: process(mac_clk)
127  variable counter_int: unsigned(23 downto 0);
128  variable tick_int: std_logic;
129  begin
130  if rising_edge(mac_clk) then
131  if (rst_macclk = '1') or (enable_125 = '0') then
132  counter_int := (Others => '0');
133  tick_int := '0';
134 -- tick goes at 8 Hz
135  elsif counter_int = x"FFFFFF" then
136 -- pragma translate_off
137 -- kludge for simulation in finite number of ticks!
138  elsif counter_int = x"00003F" then
139 -- pragma translate_on
140  counter_int := (Others => '0');
141  tick_int := '1';
142  else
143  counter_int := counter_int + 1;
144  tick_int := '0';
145  end if;
146  tick <= tick_int
147 -- pragma translate_off
148  after 4 ns
149 -- pragma translate_on
150  ;
151  end if;
152  end process;
153 
154 random: process(mac_clk)
155 -- xorshift rng based on http://b2d-f9r.blogspot.co.uk/2010/08/16-bit-xorshift-rng-now-with-more.html
156 -- using triplet 5, 3, 1 (next 5, 7, 4)
157  variable x, y, t : std_logic_vector(15 downto 0);
158  begin
159  if rising_edge(mac_clk) then
160  if rst_macclk = '1' then
161  x := MAC_addr(31 downto 16);
162  y := MAC_addr(15 downto 0);
163  elsif tick = '1' then
164  t := x xor (x(10 downto 0) & "00000");
165  x := y;
166  y := (y xor ("0" & y(15 downto 1))) xor (t xor ("000" & t(15 downto 3)));
167  end if;
168  rndm <= y(4 downto 0)
169 -- pragma translate_off
170  after 4 ns
171 -- pragma translate_on
172  ;
173  end if;
174  end process;
175 
176 rarp_req_block: process(mac_clk)
177  variable req_count, req_end: unsigned(5 downto 0);
178  variable rarp_req_int: std_logic;
179  begin
180  if rising_edge(mac_clk) then
181  if (rst_macclk = '1') or (enable_125 = '0') then
182  req_count := (Others => '0');
183 -- initial delay from bottom of MAC address...
184  req_end := unsigned("000" & MAC_addr(1 downto 0) & "1");
185 -- pragma translate_off
186 -- kludge for simulation in finite number of ticks!
187  req_end := to_unsigned(1, 6);
188 -- pragma translate_on
189  rarp_req_int := '0';
190  elsif req_count = req_end then
191  req_count := (Others => '0');
192  req_end := unsigned(rndm & "1");
193  rarp_req_int := RARP_mode;
194  elsif tick = '1' then
195  req_count := req_count + 1;
196  rarp_req_int := '0';
197  else
198  rarp_req_int := '0';
199  end if;
200  rarp_req <= rarp_req_int
201 -- pragma translate_off
202  after 4 ns
203 -- pragma translate_on
204  ;
205  end if;
206  end process;
207 
208 end rtl;