@@ -29,17 +29,29 @@ def add_type(self, name, *fields, pad=True):
29
29
layout .append (("packet_pad" , self .alignment - misalignment ))
30
30
self .layouts [name ] = layout
31
31
32
+ def field_length (self , type_name , field_name ):
33
+ layout = self .layouts [type_name ]
34
+ for name , length in layout :
35
+ if name == field_name :
36
+ return length
37
+ raise KeyError
38
+
32
39
33
40
def get_m2s_layouts (alignment ):
41
+ if alignment > 128 :
42
+ short_data_len = alignment - 128 + 16
43
+ else :
44
+ short_data_len = 16
45
+
34
46
plm = PacketLayoutManager (alignment )
35
47
plm .add_type ("echo_request" )
36
48
plm .add_type ("set_time" , ("timestamp" , 64 ))
37
49
plm .add_type ("reset" , ("phy" , 1 ))
38
50
plm .add_type ("write" , ("timestamp" , 64 ),
39
51
("channel" , 16 ),
40
52
("address" , 16 ),
41
- ("data_len " , 8 ),
42
- ("short_data" , 8 ))
53
+ ("extra_data_cnt " , 8 ),
54
+ ("short_data" , short_data_len ))
43
55
plm .add_type ("fifo_space_request" , ("channel" , 16 ))
44
56
return plm
45
57
@@ -125,34 +137,33 @@ def __init__(self, frame, data, plm):
125
137
self .ws = ws
126
138
self .plm = plm
127
139
128
- # inputs
129
140
self .packet_buffer = Signal (max (layout_len (l )
130
141
for l in plm .layouts .values ()))
131
142
w_in_packet = len (self .packet_buffer )// ws
132
- self .packet_len = Signal (max = w_in_packet + 1 )
143
+ self .packet_last_n = Signal (max = w_in_packet )
144
+ self .packet_stb = Signal ()
145
+ self .packet_last = Signal ()
133
146
134
- # control
135
- self .stb = Signal ()
136
- self .done = Signal ()
147
+ self .raw_stb = Signal ()
148
+ self .raw_data = Signal (ws )
137
149
138
150
# # #
139
151
140
- packet_buffer_count = Signal (max = w_in_packet + 1 )
152
+ packet_buffer_count = Signal (max = w_in_packet )
153
+ self .comb += self .packet_last .eq (packet_buffer_count == self .packet_last_n )
141
154
self .sync += [
142
- self .done .eq (0 ),
143
155
frame .eq (0 ),
144
156
packet_buffer_count .eq (0 ),
145
-
146
- If (self .stb & ~ self .done ,
147
- If (packet_buffer_count == self .packet_len ,
148
- self .done .eq (1 )
149
- ).Else (
150
- frame .eq (1 ),
151
- Case (packet_buffer_count ,
152
- {i : data .eq (self .packet_buffer [i * ws :(i + 1 )* ws ])
153
- for i in range (w_in_packet )}),
154
- packet_buffer_count .eq (packet_buffer_count + 1 )
155
- )
157
+ If (self .packet_stb ,
158
+ frame .eq (1 ),
159
+ Case (packet_buffer_count ,
160
+ {i : data .eq (self .packet_buffer [i * ws :(i + 1 )* ws ])
161
+ for i in range (w_in_packet )}),
162
+ packet_buffer_count .eq (packet_buffer_count + 1 )
163
+ ),
164
+ If (self .raw_stb ,
165
+ frame .eq (1 ),
166
+ data .eq (self .raw_data )
156
167
)
157
168
]
158
169
@@ -170,8 +181,9 @@ def send(self, ty, **kwargs):
170
181
if kwargs :
171
182
raise ValueError
172
183
return [
184
+ self .packet_stb .eq (1 ),
173
185
self .packet_buffer .eq (value ),
174
- self .packet_len .eq (idx // self .ws )
186
+ self .packet_last_n .eq (idx // self .ws - 1 )
175
187
]
176
188
177
189
@@ -191,7 +203,7 @@ def __init__(self, link_layer):
191
203
self .write_timestamp = Signal (64 )
192
204
self .write_channel = Signal (16 )
193
205
self .write_address = Signal (16 )
194
- self .write_data = Signal (256 )
206
+ self .write_data = Signal (512 )
195
207
self .write_overflow = Signal ()
196
208
self .write_overflow_ack = Signal ()
197
209
self .write_underflow = Signal ()
@@ -212,6 +224,20 @@ def __init__(self, link_layer):
212
224
link_layer .tx_rt_frame , link_layer .tx_rt_data , tx_plm )
213
225
self .submodules += tx_dp
214
226
227
+ # RX write data buffer
228
+ write_data_buffer_load = Signal ()
229
+ write_data_buffer_cnt = Signal (max = 512 // ws + 1 )
230
+ write_data_buffer = Signal (512 )
231
+ self .sync += \
232
+ If (write_data_buffer_load ,
233
+ Case (write_data_buffer_cnt ,
234
+ {i : write_data_buffer [i * ws :(i + 1 )* ws ].eq (link_layer .rx_rt_data )
235
+ for i in range (512 // ws )}),
236
+ write_data_buffer_cnt .eq (write_data_buffer_cnt + 1 )
237
+ ).Else (
238
+ write_data_buffer_cnt .eq (0 )
239
+ )
240
+
215
241
# RX->TX
216
242
echo_req = Signal ()
217
243
err_set = Signal ()
@@ -241,7 +267,7 @@ def __init__(self, link_layer):
241
267
self .write_address .eq (
242
268
rx_dp .packet_as ["write" ].address ),
243
269
self .write_data .eq (
244
- rx_dp .packet_as ["write" ].short_data )
270
+ Cat ( rx_dp .packet_as ["write" ].short_data , write_data_buffer ) )
245
271
]
246
272
247
273
reset = Signal ()
@@ -287,8 +313,11 @@ def __init__(self, link_layer):
287
313
NextState ("INPUT" )
288
314
)
289
315
rx_fsm .act ("WRITE" ,
290
- self .write_stb .eq (1 ),
291
- NextState ("INPUT" )
316
+ write_data_buffer_load .eq (1 ),
317
+ If (write_data_buffer_cnt == rx_dp .packet_as ["write" ].extra_data_cnt ,
318
+ self .write_stb .eq (1 ),
319
+ NextState ("INPUT" )
320
+ )
292
321
)
293
322
rx_fsm .act ("FIFO_SPACE" ,
294
323
fifo_space_set .eq (1 ),
@@ -309,32 +338,27 @@ def __init__(self, link_layer):
309
338
)
310
339
tx_fsm .act ("ECHO" ,
311
340
tx_dp .send ("echo_reply" ),
312
- tx_dp .stb .eq (1 ),
313
- If (tx_dp .done , NextState ("IDLE" ))
341
+ If (tx_dp .packet_last , NextState ("IDLE" ))
314
342
)
315
343
tx_fsm .act ("FIFO_SPACE" ,
316
344
fifo_space_ack .eq (1 ),
317
345
tx_dp .send ("fifo_space_reply" , space = self .fifo_space ),
318
- tx_dp .stb .eq (1 ),
319
- If (tx_dp .done , NextState ("IDLE" ))
346
+ If (tx_dp .packet_last , NextState ("IDLE" ))
320
347
)
321
348
tx_fsm .act ("ERROR_WRITE_OVERFLOW" ,
322
349
self .write_overflow_ack .eq (1 ),
323
350
tx_dp .send ("error" , code = error_codes ["write_overflow" ]),
324
- tx_dp .stb .eq (1 ),
325
- If (tx_dp .done , NextState ("IDLE" ))
351
+ If (tx_dp .packet_last , NextState ("IDLE" ))
326
352
)
327
353
tx_fsm .act ("ERROR_WRITE_UNDERFLOW" ,
328
354
self .write_underflow_ack .eq (1 ),
329
355
tx_dp .send ("error" , code = error_codes ["write_underflow" ]),
330
- tx_dp .stb .eq (1 ),
331
- If (tx_dp .done , NextState ("IDLE" ))
356
+ If (tx_dp .packet_last , NextState ("IDLE" ))
332
357
)
333
358
tx_fsm .act ("ERROR" ,
334
359
err_ack .eq (1 ),
335
360
tx_dp .send ("error" , code = err_code ),
336
- tx_dp .stb .eq (1 ),
337
- If (tx_dp .done , NextState ("IDLE" ))
361
+ If (tx_dp .packet_last , NextState ("IDLE" ))
338
362
)
339
363
340
364
@@ -399,7 +423,7 @@ def __init__(self, link_layer, write_fifo_depth=4):
399
423
self .write_timestamp = Signal (64 )
400
424
self .write_channel = Signal (16 )
401
425
self .write_address = Signal (16 )
402
- self .write_data = Signal (256 )
426
+ self .write_data = Signal (512 )
403
427
404
428
# fifo space interface
405
429
# write with timestamp[48:] == 0xffff to make a fifo space request
@@ -437,23 +461,83 @@ def __init__(self, link_layer, write_fifo_depth=4):
437
461
438
462
# # #
439
463
440
- # CDC
464
+ # RX/TX datapath
465
+ assert len (link_layer .tx_rt_data ) == len (link_layer .rx_rt_data )
466
+ assert len (link_layer .tx_rt_data ) % 8 == 0
467
+ ws = len (link_layer .tx_rt_data )
468
+ tx_plm = get_m2s_layouts (ws )
469
+ tx_dp = ClockDomainsRenamer ("rtio" )(TransmitDatapath (
470
+ link_layer .tx_rt_frame , link_layer .tx_rt_data , tx_plm ))
471
+ self .submodules += tx_dp
472
+ rx_plm = get_s2m_layouts (ws )
473
+ rx_dp = ClockDomainsRenamer ("rtio_rx" )(ReceiveDatapath (
474
+ link_layer .rx_rt_frame , link_layer .rx_rt_data , rx_plm ))
475
+ self .submodules += rx_dp
476
+
477
+ # Write FIFO and extra data count
441
478
wfifo = ClockDomainsRenamer ({"write" : "sys" , "read" : "rtio" })(
442
- AsyncFIFO (64 + 16 + 16 + 256 , write_fifo_depth ))
479
+ AsyncFIFO (64 + 16 + 16 + 512 , write_fifo_depth ))
443
480
self .submodules += wfifo
444
- write_timestamp = Signal (64 )
445
- write_channel = Signal (16 )
446
- write_address = Signal (16 )
447
- write_data = Signal (256 )
481
+ write_timestamp_d = Signal (64 )
482
+ write_channel_d = Signal (16 )
483
+ write_address_d = Signal (16 )
484
+ write_data_d = Signal (512 )
448
485
self .comb += [
449
486
wfifo .we .eq (self .write_stb ),
450
487
self .write_ack .eq (wfifo .writable ),
451
488
wfifo .din .eq (Cat (self .write_timestamp , self .write_channel ,
452
489
self .write_address , self .write_data )),
453
- Cat (write_timestamp , write_channel ,
454
- write_address , write_data ).eq (wfifo .dout )
490
+ Cat (write_timestamp_d , write_channel_d ,
491
+ write_address_d , write_data_d ).eq (wfifo .dout )
492
+ ]
493
+
494
+ wfb_readable = Signal ()
495
+ wfb_re = Signal ()
496
+
497
+ self .comb += wfifo .re .eq (wfifo .readable & (~ wfb_readable | wfb_re ))
498
+ self .sync .rtio += \
499
+ If (wfifo .re ,
500
+ wfb_readable .eq (1 ),
501
+ ).Elif (wfb_re ,
502
+ wfb_readable .eq (0 ),
503
+ )
504
+
505
+ write_timestamp = Signal (64 )
506
+ write_channel = Signal (16 )
507
+ write_address = Signal (16 )
508
+ write_extra_data_cnt = Signal (8 )
509
+ write_data = Signal (512 )
510
+
511
+ self .sync .rtio += If (wfifo .re ,
512
+ write_timestamp .eq (write_timestamp_d ),
513
+ write_channel .eq (write_channel_d ),
514
+ write_address .eq (write_address_d ),
515
+ write_data .eq (write_data_d ))
516
+
517
+ short_data_len = tx_plm .field_length ("write" , "short_data" )
518
+ write_extra_data = Signal (512 )
519
+ self .comb += write_extra_data .eq (write_data [short_data_len :])
520
+ for i in range (512 // ws ):
521
+ self .sync .rtio += If (wfifo .re ,
522
+ If (write_extra_data [ws * i :ws * (i + 1 )] != 0 , write_extra_data_cnt .eq (i + 1 )))
523
+
524
+ extra_data_ce = Signal ()
525
+ extra_data_last = Signal ()
526
+ extra_data_counter = Signal (max = 512 // ws + 1 )
527
+ self .comb += [
528
+ Case (extra_data_counter ,
529
+ {i + 1 : tx_dp .raw_data .eq (write_extra_data [i * ws :(i + 1 )* ws ])
530
+ for i in range (512 // ws )}),
531
+ extra_data_last .eq (extra_data_counter == write_extra_data_cnt )
455
532
]
533
+ self .sync .rtio += \
534
+ If (extra_data_ce ,
535
+ extra_data_counter .eq (extra_data_counter + 1 ),
536
+ ).Else (
537
+ extra_data_counter .eq (1 )
538
+ )
456
539
540
+ # CDC
457
541
fifo_space_not = Signal ()
458
542
fifo_space = Signal (16 )
459
543
self .submodules += _CrossDomainNotification ("rtio_rx" ,
@@ -485,21 +569,8 @@ def __init__(self, link_layer, write_fifo_depth=4):
485
569
error_not , error_code ,
486
570
self .error_not , self .error_not_ack , self .error_code )
487
571
488
- # RX/TX datapath
489
- assert len (link_layer .tx_rt_data ) == len (link_layer .rx_rt_data )
490
- assert len (link_layer .tx_rt_data ) % 8 == 0
491
- ws = len (link_layer .tx_rt_data )
492
- tx_plm = get_m2s_layouts (ws )
493
- tx_dp = ClockDomainsRenamer ("rtio" )(TransmitDatapath (
494
- link_layer .tx_rt_frame , link_layer .tx_rt_data , tx_plm ))
495
- self .submodules += tx_dp
496
- rx_plm = get_s2m_layouts (ws )
497
- rx_dp = ClockDomainsRenamer ("rtio_rx" )(ReceiveDatapath (
498
- link_layer .rx_rt_frame , link_layer .rx_rt_data , rx_plm ))
499
- self .submodules += rx_dp
500
-
501
572
# TX FSM
502
- tx_fsm = ClockDomainsRenamer ("rtio" )(FSM (reset_state = "IDLE_WRITE " ))
573
+ tx_fsm = ClockDomainsRenamer ("rtio" )(FSM (reset_state = "IDLE " ))
503
574
self .submodules += tx_fsm
504
575
505
576
echo_sent_now = Signal ()
@@ -508,18 +579,12 @@ def __init__(self, link_layer, write_fifo_depth=4):
508
579
tsc_value_load = Signal ()
509
580
self .sync .rtio += If (tsc_value_load , tsc_value .eq (self .tsc_value ))
510
581
511
- tx_fsm .act ("IDLE_WRITE" ,
512
- tx_dp .send ("write" ,
513
- timestamp = write_timestamp ,
514
- channel = write_channel ,
515
- address = write_address ,
516
- short_data = write_data ),
517
- If (wfifo .readable ,
582
+ tx_fsm .act ("IDLE" ,
583
+ If (wfb_readable ,
518
584
If (write_timestamp [48 :] == 0xffff ,
519
585
NextState ("FIFO_SPACE" )
520
586
).Else (
521
- tx_dp .stb .eq (1 ),
522
- wfifo .re .eq (tx_dp .done )
587
+ NextState ("WRITE" )
523
588
)
524
589
).Else (
525
590
If (echo_stb ,
@@ -533,36 +598,56 @@ def __init__(self, link_layer, write_fifo_depth=4):
533
598
)
534
599
)
535
600
)
601
+ tx_fsm .act ("WRITE" ,
602
+ tx_dp .send ("write" ,
603
+ timestamp = write_timestamp ,
604
+ channel = write_channel ,
605
+ address = write_address ,
606
+ extra_data_cnt = write_extra_data_cnt ,
607
+ short_data = write_data [:short_data_len ]),
608
+ If (tx_dp .packet_last ,
609
+ If (write_extra_data_cnt == 0 ,
610
+ wfb_re .eq (1 ),
611
+ NextState ("IDLE" )
612
+ ).Else (
613
+ NextState ("WRITE_EXTRA" )
614
+ )
615
+ )
616
+ )
617
+ tx_fsm .act ("WRITE_EXTRA" ,
618
+ tx_dp .raw_stb .eq (1 ),
619
+ extra_data_ce .eq (1 ),
620
+ If (extra_data_last ,
621
+ wfb_re .eq (1 ),
622
+ NextState ("IDLE" )
623
+ )
624
+ )
536
625
tx_fsm .act ("FIFO_SPACE" ,
537
626
tx_dp .send ("fifo_space_request" , channel = write_channel ),
538
- tx_dp .stb .eq (1 ),
539
- If (tx_dp .done ,
540
- wfifo .re .eq (1 ),
541
- NextState ("IDLE_WRITE" )
627
+ If (tx_dp .packet_last ,
628
+ wfb_re .eq (1 ),
629
+ NextState ("IDLE" )
542
630
)
543
631
)
544
632
tx_fsm .act ("ECHO" ,
545
633
tx_dp .send ("echo_request" ),
546
- tx_dp .stb .eq (1 ),
547
- If (tx_dp .done ,
634
+ If (tx_dp .packet_last ,
548
635
echo_ack .eq (1 ),
549
- NextState ("IDLE_WRITE " )
636
+ NextState ("IDLE " )
550
637
)
551
638
)
552
639
tx_fsm .act ("SET_TIME" ,
553
640
tx_dp .send ("set_time" , timestamp = tsc_value ),
554
- tx_dp .stb .eq (1 ),
555
- If (tx_dp .done ,
641
+ If (tx_dp .packet_last ,
556
642
set_time_ack .eq (1 ),
557
- NextState ("IDLE_WRITE " )
643
+ NextState ("IDLE " )
558
644
)
559
645
)
560
646
tx_fsm .act ("RESET" ,
561
647
tx_dp .send ("reset" , phy = reset_phy ),
562
- tx_dp .stb .eq (1 ),
563
- If (tx_dp .done ,
648
+ If (tx_dp .packet_last ,
564
649
reset_ack .eq (1 ),
565
- NextState ("IDLE_WRITE " )
650
+ NextState ("IDLE " )
566
651
)
567
652
)
568
653
0 commit comments