AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Variables
udp_build_status.vhd
1 -- Builds outbound status packet
2 --
3 -- Dave Sankey, Jan 2013
4 
5 library ieee;
6 use ieee.std_logic_1164.all;
7 use ieee.numeric_std.all;
8 
9 entity udp_build_status is
10  port (
11  mac_clk: in std_logic;
12  rx_reset: in std_logic;
13  mac_rx_data: in std_logic_vector(7 downto 0);
14  mac_rx_valid: in std_logic;
15  mac_rx_last: in std_logic;
16  mac_rx_error: in std_logic;
17  pkt_drop_status: in std_logic;
18  status_block: in std_logic_vector(127 downto 0);
19  status_request: out std_logic;
20  status_data: out std_logic_vector(7 downto 0);
21  status_addr: out std_logic_vector(12 downto 0);
22  status_we: out std_logic;
23  status_end_addr: out std_logic_vector(12 downto 0);
24  status_send: out std_logic
25  );
26 end udp_build_status;
27 
28 architecture rtl of udp_build_status is
29 
30  signal set_addr: std_logic;
31  signal send_pending, send_buf, load_buf: std_logic;
32  signal address, addr_to_set: unsigned(6 downto 0);
33 
34 begin
35 
36  status_addr <= std_logic_vector("000000" & address);
37 
38 send_packet: process (mac_clk)
39  variable end_addr_i: std_logic_vector(12 downto 0);
40  begin
41  if rising_edge(mac_clk) then
42  if send_pending = '1' then
43  end_addr_i := std_logic_vector(to_unsigned(105, 13));
44  else
45  end_addr_i := (Others => '0');
46  end if;
47  status_end_addr <= end_addr_i
48 -- pragma translate_off
49  after 4 ns
50 -- pragma translate_on
51  ;
52  status_send <= send_pending
53 -- pragma translate_off
54  after 4 ns
55 -- pragma translate_on
56  ;
57  send_pending <= mac_rx_last and not (pkt_drop_status or mac_rx_error)
58 -- pragma translate_off
59  after 4 ns
60 -- pragma translate_on
61  ;
62  end if;
63  end process;
64 
65 good_packet_block: process (mac_clk)
66  begin
67  if rising_edge(mac_clk) then
68  status_we <= mac_rx_valid and not pkt_drop_status
69 -- pragma translate_off
70  after 4 ns
71 -- pragma translate_on
72  ;
73  end if;
74  end process;
75 
76 -- UDP status packet:
77 -- Ethernet DST_MAC(6), SRC_MAC(6), Ether_Type = x"0800"
78 -- IP VERS = x"4", HL = x"5", TOS = x"00"
79 -- IP LEN
80 -- IP ID
81 -- IP FLAG-FRAG = x"4000"
82 -- IP TTL, PROTO = x"11"
83 -- IP CKSUM
84 -- IP SPA(4)
85 -- IP DPA(4)
86 -- UDP SRCPORT
87 -- UDP DSTPORT (50002)
88 -- UDP LEN
89 -- UDP CKSUM
90 -- UDP data...
91 address_block: process (mac_clk)
92  variable addr_to_set_int: unsigned(6 downto 0);
93  variable set_addr_int: std_logic;
94  begin
95  if rising_edge(mac_clk) then
96  if (rx_reset = '1') then
97  set_addr_int := '1';
98  addr_to_set_int := to_unsigned(6, 7);
99  elsif (mac_rx_valid = '1') and (pkt_drop_status = '0') then
100 -- Because address is buffered this logic needs to switch a byte early...
101  case to_integer(address) is
102 -- RX Ethernet Dest MAC bytes 0 to 5 => TX copy to Source MAC bytes 6 to 11...
103  when 10 =>
104  set_addr_int := '1';
105  addr_to_set_int := to_unsigned(0, 7);
106 -- RX Ethernet Source MAC bytes 6 to 11 => TX copy to Dest MAC bytes 0 to 5...
107  when 4 =>
108  set_addr_int := '1';
109  addr_to_set_int := to_unsigned(12, 7);
110 -- RX Eth_Type tho' to IP cksum bytes 12 to 25 => TX copy data bytes 12 to 25...
111  when 24 =>
112  set_addr_int := '1';
113  addr_to_set_int := to_unsigned(30, 7);
114 -- RX IP sender addr bytes 26 to 29 => TX copy to target addr bytes 30 to 33...
115  when 32 =>
116  set_addr_int := '1';
117  addr_to_set_int := to_unsigned(26, 7);
118 -- RX IP target addr bytes 30 to 33 => TX write sender addr bytes 26 to 29...
119  when 28 =>
120  set_addr_int := '1';
121  addr_to_set_int := to_unsigned(36, 7);
122 -- RX UDP source port bytes 34 to 35 => TX copy to dest port bytes 36 to 37...
123  when 36 =>
124  set_addr_int := '1';
125  addr_to_set_int := to_unsigned(34, 7);
126 -- RX UDP dest port bytes 36 to 37 => TX write source port bytes 34 to 35...
127  when 34 =>
128  set_addr_int := '1';
129  addr_to_set_int := to_unsigned(38, 7);
130 -- RX rest of packet => TX copy rest of packet...
131  when Others =>
132  addr_to_set_int := (Others => '0');
133  set_addr_int := '0';
134  end case;
135  else
136  addr_to_set_int := (Others => '0');
137  set_addr_int := '0';
138  end if;
139  set_addr <= set_addr_int
140 -- pragma translate_off
141  after 4 ns
142 -- pragma translate_on
143  ;
144  addr_to_set <= addr_to_set_int
145 -- pragma translate_off
146  after 4 ns
147 -- pragma translate_on
148  ;
149  end if;
150  end process;
151 
152 next_addr: process(mac_clk)
153  variable addr_int, next_addr, addr_to_set_buf: unsigned(6 downto 0);
154  variable set_addr_buf: std_logic;
155  begin
156  if rising_edge(mac_clk) then
157  if set_addr = '1' then
158  addr_to_set_buf := addr_to_set;
159  set_addr_buf := '1';
160  end if;
161  if rx_reset = '1' or mac_rx_valid = '1' then
162  if set_addr_buf = '1' then
163  addr_int := addr_to_set_buf;
164  set_addr_buf := '0';
165  elsif pkt_drop_status = '0' then
166  addr_int := next_addr;
167  end if;
168  end if;
169  address <= addr_int
170 -- pragma translate_off
171  after 4 ns
172 -- pragma translate_on
173  ;
174  next_addr := addr_int + 1;
175  end if;
176  end process;
177 
178 load_data: process (mac_clk)
179  variable load_buf_int, next_load, send_buf_int, request_int: std_logic;
180  begin
181  if rising_edge(mac_clk) then
182  if rx_reset = '1' then
183  request_int := '0';
184  send_buf_int := '0';
185  next_load := '0';
186  elsif (mac_rx_valid = '1') and (pkt_drop_status = '0') then
187  load_buf_int := next_load;
188 -- Because address is buffered this logic needs to switch a byte early...
189  case to_integer(address) is
190 -- End of header, start sending (zeros for cksum)...
191  when 38 =>
192  request_int := '0';
193  send_buf_int := '1';
194  next_load := '0';
195 -- And prepare to load header buffer...
196  when 39 =>
197  request_int := '0';
198  next_load := '1';
199 -- request history buffer...
200  when 55 =>
201  request_int := '1';
202  next_load := '1';
203 -- request ipbus_in buffer...
204  when 71 =>
205  request_int := '1';
206  next_load := '1';
207 -- request ipbus_out buffer...
208  when 87 =>
209  request_int := '1';
210  next_load := '1';
211  when Others =>
212  request_int := '0';
213  next_load := '0';
214  end case;
215  else
216  request_int := '0';
217  load_buf_int := '0';
218  end if;
219  load_buf <= load_buf_int
220 -- pragma translate_off
221  after 4 ns
222 -- pragma translate_on
223  ;
224  send_buf <= send_buf_int
225 -- pragma translate_off
226  after 4 ns
227 -- pragma translate_on
228  ;
229  status_request <= request_int
230 -- pragma translate_off
231  after 4 ns
232 -- pragma translate_on
233  ;
234  end if;
235  end process;
236 
237 write_data: process(mac_clk)
238  variable shift_buf: std_logic_vector(127 downto 0);
239  variable data_to_send: std_logic_vector(7 downto 0);
240  begin
241  if rising_edge(mac_clk) then
242  if load_buf = '1' then
243  shift_buf := status_block;
244  end if;
245  if mac_rx_valid = '1' and pkt_drop_status = '0' then
246  if send_buf = '1' then
247  data_to_send := shift_buf(127 downto 120);
248  else
249  data_to_send := mac_rx_data;
250  end if;
251  shift_buf := shift_buf(119 downto 0) & x"00";
252  else
253  data_to_send := (Others => '0');
254  end if;
255  status_data <= data_to_send
256 -- pragma translate_off
257  after 4 ns
258 -- pragma translate_on
259  ;
260  end if;
261  end process;
262 
263 end rtl;