AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
Main Page
Design Unit List
Files
File List
All
Classes
Files
Variables
src
common
IPBUS
ipbus2
ipbus_core
hdl
udp_build_payload.vhd
1
-- Builds outbound payload header
and
copies payload
2
--
3
-- Dave Sankey, August
2012
4
5
library
ieee
;
6
use
ieee.std_logic_1164.
all
;
7
use
ieee.numeric_std.
all
;
8
9
entity
udp_build_payload
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_payload
:
in
std_logic
;
18
pkt_byteswap
:
in
std_logic
;
19
outbyte
:
in
std_logic_vector
(
7
downto
0
)
;
20
payload_data
:
out
std_logic_vector
(
7
downto
0
)
;
21
payload_addr
:
out
std_logic_vector
(
12
downto
0
)
;
22
payload_we
:
out
std_logic
;
23
payload_send
:
out
std_logic
;
24
do_sum_payload
:
out
std_logic
;
25
clr_sum_payload
:
out
std_logic
;
26
int_data_payload
:
out
std_logic_vector
(
7
downto
0
)
;
27
int_valid_payload
:
out
std_logic
;
28
cksum
:
out
std_logic
;
29
ipbus_in_hdr
:
out
std_logic_vector
(
31
downto
0
)
30
)
;
31
end
udp_build_payload
;
32
33
architecture
rtl
of
udp_build_payload
is
34
35
signal
payload_we_sig
,
set_addr
,
send_pending
:
std_logic
;
36
signal
send_buf
,
load_buf
,
low_addr
,
next_low
,
byteswap
:
std_logic
;
37
signal
buf_to_load
:
std_logic_vector
(
15
downto
0
)
;
38
signal
address
,
addr_to_set
,
next_addr
:
unsigned
(
12
downto
0
)
;
39
signal
payload_data_sig
:
std_logic_vector
(
7
downto
0
)
;
40
41
begin
42
43
payload_we
<=
payload_we_sig
;
44
payload_data
<=
payload_data_sig
;
45
46
With
byteswap
select
payload_addr
<=
47
std_logic_vector
(
address
(
12
downto
2
)
&
not
address
(
1
downto
0
)
)
when
'
1
'
,
48
std_logic_vector
(
address
)
when
Others
;
49
50
send_packet:
process
(mac_clk)
51
variable
send_pending_i
,
send_i
,
last_we
:
std_logic
;
52
variable
state
,
next_state
:
integer
range
0
to
1
;
53
begin
54
if
rising_edge
(
mac_clk
)
then
55
if
rx_reset
=
'
1
'
then
56
next_state
:=
0
;
57
end
if
;
58
state
:=
next_state
;
59
case
state
is
60
when
0
=
>
61
send_i
:=
'
0
'
;
62
if
mac_rx_last
=
'
1
'
and
pkt_drop_payload
=
'
0
'
and
63
mac_rx_error
=
'
0
'
then
64
send_pending_i
:=
'
1
'
;
65
next_state
:=
1
;
66
else
67
send_pending_i
:=
'
0
'
;
68
end
if
;
69
when
1
=
>
70
if
payload_we_sig
=
'
0
'
and
last_we
=
'
1
'
then
71
send_i
:=
'
1
'
;
72
send_pending_i
:=
'
0
'
;
73
next_state
:=
0
;
74
else
75
send_i
:=
'
0
'
;
76
end
if
;
77
end
case
;
78
last_we
:=
payload_we_sig
;
79
payload_send
<=
send_i
80
-- pragma translate_off
81
after
4
ns
82
-- pragma translate_on
83
;
84
send_pending
<=
send_pending_i
85
-- pragma translate_off
86
after
4
ns
87
-- pragma translate_on
88
;
89
end
if
;
90
end
process
;
91
92
-- UDP payload:
93
-- Ethernet DST_MAC(
6
), SRC_MAC(
6
), Ether_Type = x"0800"
94
-- IP VERS = x"4", HL = x"5", TOS = x"00"
95
-- IP LEN
96
-- IP ID
97
-- IP FLAG-FRAG = x"4000"
98
-- IP TTL, PROTO = x"11"
99
-- IP CKSUM
100
-- IP SPA(
4
)
101
-- IP DPA(
4
)
102
-- UDP SRCPORT
103
-- UDP DSTPORT (
50001
)
104
-- UDP LEN
105
-- UDP CKSUM
106
-- UDP data...
107
set_address_block:
process
(mac_clk)
108
variable
addr_to_set_int
:
unsigned
(
5
downto
0
)
;
109
variable
set_addr_int
,
cksum_pending
:
std_logic
;
110
begin
111
if
rising_edge
(
mac_clk
)
then
112
if
(
rx_reset
=
'
1
'
)
then
113
set_addr_int := '1';
114
addr_to_set_int
:=
to_unsigned
(
12
,
6
)
;
115
cksum_pending
:=
'
0
'
;
116
elsif
pkt_drop_payload
=
'
0
'
then
117
if
mac_rx_last
=
'
1
'
then
118
set_addr_int := '1';
119
addr_to_set_int
:=
to_unsigned
(
4
,
6
)
;
120
cksum_pending
:=
'
1
'
;
121
elsif
mac_rx_valid
=
'
1
'
and
low_addr
=
'
1
'
then
122
-- Because address
is
buffered this logic needs
to
switch a byte early...
123
-- But don't forget we're offset by
4
+
2
bytes
for
payload word alignment!
124
case
to_integer
(
address
(
5
downto
0
)
)
is
125
-- RX Ethernet Dest MAC bytes
0
to
5
=> TX copy
to
Source MAC bytes
12
to
17
...
126
when
16
=
>
127
set_addr_int := '1';
128
addr_to_set_int
:=
to_unsigned
(
6
,
6
)
;
129
-- RX Ethernet Source MAC bytes
6
to
11
=> TX copy
to
Dest MAC bytes
6
to
11
...
130
when
10
=
>
131
set_addr_int := '1';
132
addr_to_set_int
:=
to_unsigned
(
18
,
6
)
;
133
-- RX Eth_Type tho'
to
IP cksum bytes
12
to
25
=> TX copy data bytes
18
to
31
...
134
when
30
=
>
135
set_addr_int := '1';
136
addr_to_set_int
:=
to_unsigned
(
36
,
6
)
;
137
-- RX IP sender addr bytes
26
to
29
=> TX copy
to
target addr bytes
36
to
39
...
138
when
38
=
>
139
set_addr_int := '1';
140
addr_to_set_int
:=
to_unsigned
(
32
,
6
)
;
141
-- RX IP target addr bytes
30
to
33
=> TX write sender addr bytes
32
to
35
...
142
when
34
=
>
143
set_addr_int := '1';
144
addr_to_set_int
:=
to_unsigned
(
42
,
6
)
;
145
-- RX UDP source
port
bytes
34
to
35
=> TX copy
to
dest
port
bytes
42
to
43
...
146
when
42
=
>
147
set_addr_int := '1';
148
addr_to_set_int
:=
to_unsigned
(
40
,
6
)
;
149
-- RX UDP dest
port
bytes
36
to
37
=> TX write source
port
bytes
40
to
41
...
150
when
40
=
>
151
set_addr_int := '1';
152
addr_to_set_int
:=
to_unsigned
(
44
,
6
)
;
153
-- RX UDP length
and
cksum bytes
38
to
41
=> TX write zeros bytes
44
to
47
...
154
when
Others
=
>
155
set_addr_int := '0';
156
addr_to_set_int
:=
(
Others
=
>
'
0
'
)
;
157
end
case
;
158
elsif
cksum_pending
=
'
1
'
and
low_addr
=
'
1
'
and
159
address
(
5
downto
0
)
=
"000100"
then
160
-- No more data => write cksum
and
length info...
161
set_addr_int := '1';
162
addr_to_set_int
:=
to_unsigned
(
0
,
6
)
;
163
cksum_pending
:=
'
0
'
;
164
else
165
set_addr_int := '0';
166
addr_to_set_int
:=
(
Others
=
>
'
0
'
)
;
167
end
if
;
168
else
169
set_addr_int := '0';
170
addr_to_set_int
:=
(
Others
=
>
'
0
'
)
;
171
end
if
;
172
set_addr <= set_addr_int
173
-- pragma translate_off
174
after
4
ns
175
-- pragma translate_on
176
;
177
addr_to_set
<=
"0000000"
&
addr_to_set_int
178
-- pragma translate_off
179
after
4
ns
180
-- pragma translate_on
181
;
182
end
if
;
183
end
process
;
184
185
build_packet:
process
(mac_clk)
186
variable
cksum_pending
:
std_logic
;
187
variable
buf_to_load_int
:
std_logic_vector
(
15
downto
0
)
;
188
variable
load_buf_int
,
send_buf_int
,
payload_we_i
:
std_logic
;
189
variable
payload_len
:
std_logic_vector
(
15
downto
0
)
;
190
begin
191
if
rising_edge
(
mac_clk
)
then
192
if
(
rx_reset
=
'
1
'
)
then
193
send_buf_int
:=
'
0
'
;
194
load_buf_int
:=
'
0
'
;
195
cksum_pending
:=
'
0
'
;
196
payload_len
:=
(
Others
=
>
'
0
'
)
;
197
buf_to_load_int
:=
(
Others
=
>
'
0
'
)
;
198
elsif
pkt_drop_payload
=
'
0
'
then
199
payload_we_i
:=
mac_rx_valid
or
cksum_pending
;
200
if
mac_rx_last
=
'
1
'
then
201
load_buf_int
:=
'
1
'
;
202
send_buf_int
:=
'
1
'
;
203
cksum_pending
:=
'
1
'
;
204
elsif
mac_rx_valid
=
'
1
'
and
low_addr
=
'
1
'
then
205
-- Because address
is
buffered this logic needs
to
switch a byte early...
206
-- But don't forget we're offset by
4
+
2
bytes
for
payload word alignment!
207
case
to_integer
(
address
(
5
downto
0
)
)
is
208
when
20
=
>
209
load_buf_int
:=
'
1
'
;
210
send_buf_int
:=
'
1
'
;
211
-- RX IP length => ignore
for
cksum, write zeros, capture packet length
212
when
22
=
>
213
send_buf_int
:=
'
0
'
;
214
when
28
=
>
215
send_buf_int
:=
'
1
'
;
216
-- RX IP cksum => ignore
for
cksum calc
and
write zeros
217
when
30
=
>
218
send_buf_int
:=
'
0
'
;
219
-- RX IP sender addr bytes
26
to
29
=> TX copy
to
target addr bytes
36
to
39
...
220
when
40
=
>
221
send_buf_int
:=
'
1
'
;
222
-- RX UDP length
and
cksum bytes
38
to
41
=> TX write zeros bytes
44
to
47
...
223
when
44
=
>
224
buf_to_load_int
(
7
downto
0
)
:=
outbyte
;
225
-- capture IP cksum value
and
start payload length calculation...
226
when
45
=
>
227
buf_to_load_int
(
15
downto
8
)
:=
outbyte
;
228
-- capture IP cksum value
and
continue payload length calculation...
229
when
46
=
>
230
send_buf_int
:=
'
0
'
;
231
when
52
=
>
232
-- capture payload length calculation...
233
payload_len
(
7
downto
0
)
:=
outbyte
;
234
when
53
=
>
235
-- capture payload length calculation...
236
payload_len
(
15
downto
8
)
:=
outbyte
;
237
-- RX rest
of
packet => TX copy rest
of
packet...
238
when
Others
=
>
239
load_buf_int
:=
'
0
'
;
240
end
case
;
241
-- No more data => write cksum
and
length info...
242
elsif
cksum_pending
=
'
1
'
and
low_addr
=
'
1
'
then
243
case
to_integer
(
address
(
5
downto
0
)
)
is
244
when
4
=
>
245
load_buf_int
:=
'
1
'
;
246
buf_to_load_int
:=
std_logic_vector
(
to_unsigned
(
12
,
16
)
)
;
247
when
0
=
>
248
load_buf_int
:=
'
1
'
;
249
buf_to_load_int
:=
payload_len
;
250
when
2
=
>
251
cksum_pending
:=
'
0
'
;
252
when
Others
=
>
253
load_buf_int
:=
'
0
'
;
254
end
case
;
255
else
256
load_buf_int
:=
'
0
'
;
257
end
if
;
258
else
259
payload_we_i
:=
'
0
'
;
260
end
if
;
261
payload_we_sig
<=
payload_we_i
262
-- pragma translate_off
263
after
4
ns
264
-- pragma translate_on
265
;
266
load_buf
<=
load_buf_int
267
-- pragma translate_off
268
after
4
ns
269
-- pragma translate_on
270
;
271
buf_to_load
<=
buf_to_load_int
272
-- pragma translate_off
273
after
4
ns
274
-- pragma translate_on
275
;
276
send_buf
<=
send_buf_int
277
-- pragma translate_off
278
after
4
ns
279
-- pragma translate_on
280
;
281
end
if
;
282
end
process
;
283
284
do_cksum:
process
(mac_clk)
285
variable
do_sum_int
,
clr_sum_int
,
cksum_int
,
int_valid_int
:
std_logic
;
286
variable
int_data_int
:
std_logic_vector
(
7
downto
0
)
;
287
variable
payload_len
:
std_logic_vector
(
15
downto
0
)
;
288
begin
289
if
rising_edge
(
mac_clk
)
then
290
if
(
rx_reset
=
'
1
'
)
then
291
do_sum_int
:=
'
0
'
;
292
clr_sum_int
:=
'
1
'
;
293
int_valid_int
:=
'
0
'
;
294
cksum_int
:=
'
1
'
;
295
int_data_int
:=
(
Others
=
>
'
0
'
)
;
296
payload_len
:=
(
Others
=
>
'
0
'
)
;
297
elsif
mac_rx_valid
=
'
1
'
and
pkt_drop_payload
=
'
0
'
and
low_addr
=
'
1
'
then
298
-- Because address
is
buffered this logic needs
to
switch a byte early...
299
-- But don't forget we're offset by
4
+
2
bytes
for
payload word alignment!
300
case
to_integer
(
address
(
5
downto
0
)
)
is
301
-- RX Ethernet Dest MAC bytes
0
to
5
=> TX copy
to
Source MAC bytes
12
to
17
...
302
when
18
=
>
303
do_sum_int
:=
'
1
'
;
304
clr_sum_int
:=
'
1
'
;
305
cksum_int
:=
'
1
'
;
306
-- RX IP header => start cksum calc - we'll redo length
and
cksum
when
we send...
307
when
20
=
>
308
do_sum_int
:=
'
0
'
;
309
-- RX IP length => ignore
for
cksum, write zeros, capture packet length
310
when
21
=
>
311
payload_len
(
15
downto
6
)
:=
"00"
&
mac_rx_data
;
312
-- RX IP length => ignore
for
cksum, write zeros, capture packet length
313
when
22
=
>
314
payload_len
(
5
downto
0
)
:=
mac_rx_data
(
7
downto
2
)
;
315
do_sum_int
:=
'
1
'
;
316
when
28
=
>
317
do_sum_int
:=
'
0
'
;
318
-- RX IP cksum => ignore
for
cksum calc
and
write zeros
319
when
30
=
>
320
do_sum_int
:=
'
1
'
;
321
-- RX IP sender addr bytes
26
to
29
=> TX copy
to
target addr bytes
36
to
39
...
322
when
34
=
>
323
do_sum_int
:=
'
0
'
;
324
-- cksum calculation complete...
325
-- RX UDP source
port
bytes
34
to
35
=> TX copy
to
dest
port
bytes
42
to
43
...
326
when
44
=
>
327
-- capture IP cksum value
and
start payload length calculation...
328
do_sum_int
:=
'
1
'
;
329
clr_sum_int
:=
'
1
'
;
330
cksum_int
:=
'
0
'
;
331
int_valid_int
:=
'
1
'
;
332
int_data_int
:=
payload_len
(
15
downto
8
)
;
333
-- RX UDP length
and
cksum bytes
38
to
41
=> TX write zeros bytes
44
to
47
...
334
when
45
=
>
335
-- capture IP cksum value
and
continue payload length calculation...
336
clr_sum_int
:=
'
0
'
;
337
int_valid_int
:=
'
1
'
;
338
int_data_int
:=
payload_len
(
7
downto
0
)
;
339
when
46
=
>
340
-- continue payload length calculation (loading -8)...
341
int_valid_int
:=
'
1
'
;
342
int_data_int
:=
x
"FF"
;
343
when
47
=
>
344
-- continue payload length calculation (loading -8)...
345
int_valid_int
:=
'
1
'
;
346
int_data_int
:=
x
"F8"
;
347
when
48
=
>
348
int_valid_int
:=
'
0
'
;
349
do_sum_int
:=
'
0
'
;
350
when
Others
=
>
351
clr_sum_int
:=
'
0
'
;
352
int_valid_int
:=
'
0
'
;
353
int_data_int
:=
(
Others
=
>
'
0
'
)
;
354
end
case
;
355
else
356
clr_sum_int
:=
'
0
'
;
357
int_valid_int
:=
'
0
'
;
358
int_data_int
:=
(
Others
=
>
'
0
'
)
;
359
end
if
;
360
do_sum_payload
<=
do_sum_int
361
-- pragma translate_off
362
after
4
ns
363
-- pragma translate_on
364
;
365
clr_sum_payload
<=
clr_sum_int
366
-- pragma translate_off
367
after
4
ns
368
-- pragma translate_on
369
;
370
int_data_payload
<=
int_data_int
371
-- pragma translate_off
372
after
4
ns
373
-- pragma translate_on
374
;
375
int_valid_payload
<=
int_valid_int
376
-- pragma translate_off
377
after
4
ns
378
-- pragma translate_on
379
;
380
cksum
<=
cksum_int
381
-- pragma translate_off
382
after
4
ns
383
-- pragma translate_on
384
;
385
end
if
;
386
end
process
;
387
388
next_addr_block:
process
(mac_clk)
389
variable
addr_int
,
next_addr_int
,
addr_to_set_buf
:
unsigned
(
12
downto
0
)
;
390
variable
set_addr_buf
,
next_low_int
:
std_logic
;
391
begin
392
if
rising_edge
(
mac_clk
)
then
393
if
set_addr
=
'
1
'
then
394
addr_to_set_buf
:=
addr_to_set
;
395
set_addr_buf := '1';
396
end
if
;
397
if
rx_reset
=
'
1
'
or
mac_rx_valid
=
'
1
'
or
send_pending
=
'
1
'
then
398
if
set_addr_buf
=
'
1
'
then
399
addr_int
:=
addr_to_set_buf
;
400
set_addr_buf := '0';
401
elsif
pkt_drop_payload
=
'
0
'
then
402
addr_int
:=
next_addr_int
;
403
end
if
;
404
end
if
;
405
next_addr_int
:=
addr_int
+
1
;
406
if
next_addr
(
12
downto
6
)
=
"0000000"
then
407
next_low_int
:=
'
1
'
;
408
else
409
next_low_int
:=
'
0
'
;
410
end
if
;
411
next_addr
<=
next_addr_int
412
-- pragma translate_off
413
after
4
ns
414
-- pragma translate_on
415
;
416
next_low
<=
next_low_int
417
-- pragma translate_off
418
after
4
ns
419
-- pragma translate_on
420
;
421
end
if
;
422
end
process
;
423
424
address_block:
process
(mac_clk)
425
variable
addr_int
,
addr_to_set_buf
:
unsigned
(
12
downto
0
)
;
426
variable
set_addr_buf
,
low_addr_i
:
std_logic
;
427
begin
428
if
rising_edge
(
mac_clk
)
then
429
if
set_addr
=
'
1
'
then
430
addr_to_set_buf
:=
addr_to_set
;
431
set_addr_buf := '1';
432
end
if
;
433
if
rx_reset
=
'
1
'
or
mac_rx_valid
=
'
1
'
or
send_pending
=
'
1
'
then
434
if
set_addr_buf
=
'
1
'
then
435
addr_int
:=
addr_to_set_buf
;
436
low_addr_i
:=
'
1
'
;
437
set_addr_buf := '0';
438
elsif
pkt_drop_payload
=
'
0
'
then
439
addr_int
:=
next_addr
;
440
low_addr_i
:=
next_low
;
441
end
if
;
442
end
if
;
443
address
<=
addr_int
444
-- pragma translate_off
445
after
4
ns
446
-- pragma translate_on
447
;
448
low_addr
<=
low_addr_i
449
-- pragma translate_off
450
after
4
ns
451
-- pragma translate_on
452
;
453
end
if
;
454
end
process
;
455
456
byteswap_block:
process
(mac_clk)
457
variable
set_addr_buf
,
byteswap_int
:
std_logic
;
458
begin
459
if
rising_edge
(
mac_clk
)
then
460
if
set_addr
=
'
1
'
then
461
set_addr_buf := '1';
462
end
if
;
463
if
rx_reset
=
'
1
'
or
mac_rx_valid
=
'
1
'
or
send_pending
=
'
1
'
then
464
if
set_addr_buf
=
'
1
'
then
465
byteswap_int
:=
'
0
'
;
466
set_addr_buf := '0';
467
elsif
next_low
=
'
1
'
and
next_addr
(
5
downto
0
)
=
to_unsigned
(
52
,
6
)
then
468
byteswap_int
:=
pkt_byteswap
;
469
end
if
;
470
end
if
;
471
byteswap
<=
byteswap_int
472
-- pragma translate_off
473
after
4
ns
474
-- pragma translate_on
475
;
476
end
if
;
477
end
process
;
478
479
write_data:
process
(mac_clk)
480
variable
shift_buf
:
std_logic_vector
(
15
downto
0
)
;
481
variable
data_to_send
:
std_logic_vector
(
7
downto
0
)
;
482
begin
483
if
rising_edge
(
mac_clk
)
then
484
data_to_send
:=
(
Others
=
>
'
0
'
)
;
485
if
load_buf
=
'
1
'
then
486
shift_buf
:=
buf_to_load
;
487
end
if
;
488
if
(
mac_rx_valid
=
'
1
'
or
send_pending
=
'
1
'
)
and
pkt_drop_payload
=
'
0
'
then
489
if
send_buf
=
'
1
'
then
490
data_to_send
:=
shift_buf
(
15
downto
8
)
;
491
else
492
data_to_send
:=
mac_rx_data
;
493
end
if
;
494
shift_buf
:=
shift_buf
(
7
downto
0
)
&
x
"00"
;
495
end
if
;
496
payload_data_sig
<=
data_to_send
497
-- pragma translate_off
498
after
4
ns
499
-- pragma translate_on
500
;
501
end
if
;
502
end
process
;
503
504
do_ipbus_hdr:
process
(mac_clk)
505
variable
ipbus_hdr_int
:
std_logic_vector
(
31
downto
0
)
;
506
begin
507
if
rising_edge
(
mac_clk
)
then
508
if
rx_reset
=
'
1
'
then
509
ipbus_hdr_int
:=
(
Others
=
>
'
0
'
)
;
510
elsif
low_addr
=
'
1
'
and
payload_we_sig
=
'
1
'
and
address
(
5
downto
2
)
=
"1100"
then
511
ipbus_hdr_int
:=
ipbus_hdr_int
(
23
downto
0
)
&
payload_data_sig
;
512
end
if
;
513
ipbus_in_hdr
<=
ipbus_hdr_int
514
-- pragma translate_off
515
after
4
ns
516
-- pragma translate_on
517
;
518
end
if
;
519
end
process
;
520
521
end
rtl
;
Generated on Sun Mar 6 2016 12:24:20 for AMC13 by
1.8.1