AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Variables
udp_status_buffer.vhd
1 -- Accumulates status info and passes dollops to udp_build_status
2 --
3 -- Dave Sankey, Jan 2013
4 
5 library ieee;
6 use ieee.std_logic_1164.all;
7 use ieee.numeric_std.all;
8 
10  generic(
11  BUFWIDTH: natural := 0;
12  ADDRWIDTH: natural := 0
13  );
14  port (
15  mac_clk: in std_logic;
16  rst_macclk: in std_logic;
17  rst_ipb_125: in std_logic;
18  rx_reset: in std_logic;
19  ipbus_in_hdr: in std_logic_vector(31 downto 0);
20  ipbus_out_hdr: in std_logic_vector(31 downto 0);
21  ipbus_out_valid: in std_logic;
22  mac_rx_error: in std_logic;
23  mac_rx_last: in std_logic;
24  mac_tx_error: in std_logic;
25  mac_tx_last: in std_logic;
26  pkt_broadcast: in std_logic;
27  pkt_drop_arp: in std_logic;
28  pkt_drop_ipbus: in std_logic;
29  pkt_drop_payload: in std_logic;
30  pkt_drop_ping: in std_logic;
31  pkt_drop_rarp: in std_logic;
32  pkt_drop_reliable: in std_logic;
33  pkt_drop_resend: in std_logic;
34  pkt_drop_status: in std_logic;
35  pkt_rcvd: in std_logic;
36  req_not_found: in std_logic;
37  rx_ram_sent: in std_logic;
38  rx_req_send_125: in std_logic;
39  rxpayload_dropped: in std_logic;
40  rxram_dropped: in std_logic;
41  status_request: in std_logic;
42  tx_ram_written: in std_logic;
43  udpram_send: in std_logic;
44  next_pkt_id: out std_logic_vector(15 downto 0);
45  status_block: out std_logic_vector(127 downto 0)
46  );
47 end udp_status_buffer;
48 
49 architecture rtl of udp_status_buffer is
50 
51  signal header, history, ipbus_in, ipbus_out: std_logic_vector(127 downto 0);
52  signal tick: integer range 0 to 3;
53  signal ready, async_event: std_logic;
54  signal async_data: std_logic_vector(4 downto 0);
55 
56 begin
57 
58 With tick select status_block <=
59  history when 1,
60  ipbus_in when 2,
61  ipbus_out when 3,
62  header when Others;
63 
64 select_block: process (mac_clk)
65  begin
66  if rising_edge(mac_clk) then
67  if rx_reset = '1' then
68  tick <= 0
69 -- pragma translate_off
70  after 4 ns
71 -- pragma translate_on
72  ;
73  elsif status_request = '1' then
74  tick <= tick + 1
75 -- pragma translate_off
76  after 4 ns
77 -- pragma translate_on
78  ;
79  end if;
80  end if;
81  end process;
82 
83 header_block: process (mac_clk)
84  variable next_pkt_id_int, bufsize, nbuf: unsigned(15 downto 0);
85  begin
86  if rising_edge(mac_clk) then
87  if rst_macclk = '1' then
88  bufsize := to_unsigned((2**ADDRWIDTH) - 8, 16);
89  nbuf := to_unsigned(2**BUFWIDTH, 16);
90  next_pkt_id_int := to_unsigned(1, 16);
91  header <= x"200000F1" & x"0000" &
92  std_logic_vector(bufsize) & x"0000" &
93  std_logic_vector(nbuf) & x"200001F0"
94 -- pragma translate_off
95  after 4 ns
96 -- pragma translate_on
97  ;
98  elsif pkt_rcvd = '1' and pkt_drop_reliable = '0' then
99  if next_pkt_id_int = x"FFFF" then
100  next_pkt_id_int := to_unsigned(1, 16);
101  else
102  next_pkt_id_int := next_pkt_id_int + 1;
103  end if;
104  header(31 downto 0) <= x"20" & std_logic_vector(next_pkt_id_int) & x"F0"
105 -- pragma translate_off
106  after 4 ns
107 -- pragma translate_on
108  ;
109  end if;
110  next_pkt_id <= std_logic_vector(next_pkt_id_int)
111 -- pragma translate_off
112  after 4 ns
113 -- pragma translate_on
114  ;
115  end if;
116  end process;
117 
118 history_block: process (mac_clk)
119  variable last_rst_ipb, new_event, event_pending, async_ready,
120  async_pending: std_logic;
121  variable event_data: std_logic_vector(7 downto 0);
122  variable rarp_arp_ping_ipbus: std_logic_vector(3 downto 0);
123  variable async_payload: std_logic_vector(4 downto 0);
124  variable payload_status_resend: std_logic_vector(2 downto 0);
125  begin
126  if rising_edge(mac_clk) then
127  if rst_macclk = '1' then
128  event_pending := '0';
129  async_pending := '0';
130  history <= (Others => '0')
131 -- pragma translate_off
132  after 4 ns
133 -- pragma translate_on
134  ;
135  end if;
136  new_event := '0';
137  async_ready := '1';
138  if rst_ipb_125 = '1' and not last_rst_ipb = '1' then
139  new_event := '1';
140  event_data := x"01";
141  end if;
142  if mac_rx_last = '1' then
143  rarp_arp_ping_ipbus := pkt_drop_rarp & pkt_drop_arp &
144  pkt_drop_ping & pkt_drop_ipbus;
145  payload_status_resend := pkt_drop_payload & pkt_drop_status &
146  pkt_drop_resend;
147  case rarp_arp_ping_ipbus is
148  when "0111" =>
149  event_data := x"08";
150  when "1011" =>
151  event_data := x"07";
152  when "1101" =>
153  event_data := x"06";
154  when "1110" =>
155  case payload_status_resend is
156  when "011" =>
157  event_data := x"02";
158  when "101" =>
159  event_data := x"03";
160  when "110" =>
161  event_data := x"04";
162  when Others =>
163  event_data := x"05";
164  end case;
165  when Others =>
166  if pkt_broadcast = '0' then
167  event_data := x"0F";
168  end if;
169  end case;
170  if mac_rx_error = '1' then
171  event_data(7 downto 4) := x"8";
172  end if;
173  event_pending := '1';
174  end if;
175  if event_pending = '1' then
176  if rxpayload_dropped = '1' or rxram_dropped = '1' or
177  req_not_found = '1' then
178  event_data(7 downto 4) := x"4";
179  elsif rx_reset = '1' then
180  new_event := '1';
181  end if;
182  end if;
183  if async_event = '1' then
184  async_pending := '1';
185  async_payload := async_data;
186  end if;
187  if new_event = '1' then
188  event_pending := '0';
189  async_ready := '0';
190  history <= history(119 downto 0) & event_data
191 -- pragma translate_off
192  after 4 ns
193 -- pragma translate_on
194  ;
195  elsif async_pending = '1' then
196  async_pending := '0';
197  history <= history(119 downto 0) & "000" & async_payload
198 -- pragma translate_off
199  after 4 ns
200 -- pragma translate_on
201  ;
202  end if;
203  ready <= async_ready
204 -- pragma translate_off
205  after 4 ns
206 -- pragma translate_on
207  ;
208  last_rst_ipb := rst_ipb_125;
209  end if;
210  end process;
211 
212 async_history_block: process(mac_clk)
213  variable send, sent, written, tx_event, tx_send, tx_sent, tx_error,
214  last_tx_last, got_event: std_logic;
215  variable event: std_logic_vector(4 downto 0);
216  begin
217  if rising_edge(mac_clk) then
218  if rst_macclk = '1' then
219  send := '0';
220  sent := '0';
221  written := '0';
222  tx_send := '0';
223  tx_sent := '0';
224  tx_error := '0';
225  last_tx_last := '0';
226  got_event := '0';
227  event := (Others => '0');
228  end if;
229 -- latch all events
230  if rx_req_send_125 = '1' then
231  send := '1';
232  end if;
233  if rx_ram_sent = '1' then
234  sent := '1';
235  end if;
236  if tx_ram_written = '1' then
237  written := '1';
238  end if;
239  if udpram_send = '1' then
240  tx_send := '1';
241  end if;
242  if mac_tx_last = '1' and last_tx_last = '0' then
243  tx_sent := '1';
244  tx_error := mac_tx_error;
245  end if;
246  last_tx_last := mac_tx_last;
247 -- peel off events if OK
248  event := (Others => '0');
249  got_event := '0';
250  if ready = '1' then
251  got_event := '1';
252  if sent = '1' or written = '1' then
253  event := "010" & written & sent;
254  sent := '0';
255  written := '0';
256  elsif send = '1' then
257  event := '0' & x"C";
258  send := '0';
259  elsif tx_send = '1' then
260  event := '0' & x"D";
261  tx_send := '0';
262  elsif tx_sent = '1' then
263  event := tx_error & x"E";
264  tx_sent := '0';
265  tx_error := '0';
266  else
267  got_event := '0';
268  end if;
269  end if;
270  async_event <= got_event
271 -- pragma translate_off
272  after 4 ns
273 -- pragma translate_on
274  ;
275  async_data <= event
276 -- pragma translate_off
277  after 4 ns
278 -- pragma translate_on
279  ;
280  end if;
281  end process;
282 
283 ipbus_in_block: process (mac_clk)
284  begin
285  if rising_edge(mac_clk) then
286  if rst_macclk = '1' then
287  ipbus_in <= (Others => '0')
288 -- pragma translate_off
289  after 4 ns
290 -- pragma translate_on
291  ;
292  end if;
293  if pkt_rcvd = '1' then
294  ipbus_in <= ipbus_in(95 downto 0) & ipbus_in_hdr
295 -- pragma translate_off
296  after 4 ns
297 -- pragma translate_on
298  ;
299  end if;
300  end if;
301  end process;
302 
303 ipbus_out_block: process (mac_clk)
304  begin
305  if rising_edge(mac_clk) then
306  if rst_macclk = '1' then
307  ipbus_out <= (Others => '0')
308 -- pragma translate_off
309  after 4 ns
310 -- pragma translate_on
311  ;
312  elsif ipbus_out_valid = '1' then
313  ipbus_out <= ipbus_out(95 downto 0) & ipbus_out_hdr
314 -- pragma translate_off
315  after 4 ns
316 -- pragma translate_on
317  ;
318  end if;
319  end if;
320  end process;
321 
322 end rtl;