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
Variables
src
common
IPBUS
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 Wed Apr 18 2018 10:55:28 for AMC13 by
1.8.1