@@ -498,50 +498,96 @@ def _use_io_port(self, fragment: Fragment, port: _ast.IOPort):
498
498
if frag_info .parent is not None :
499
499
self ._use_io_port (frag_info .parent , port )
500
500
501
+ def _collect_used_signals_format (self , fragment : Fragment , fmt : _ast .Format ):
502
+ for chunk in fmt ._chunks :
503
+ if not isinstance (chunk , str ):
504
+ obj , _spec = chunk
505
+ self ._collect_used_signals_value (fragment , obj )
506
+
507
+ def _collect_used_signals_value (self , fragment : Fragment , value : _ast .Value ):
508
+ if isinstance (value , (_ast .Const , _ast .Initial , _ast .AnyValue )):
509
+ pass
510
+ elif isinstance (value , _ast .Signal ):
511
+ self ._use_signal (fragment , value )
512
+ elif isinstance (value , _ast .Operator ):
513
+ for op in value .operands :
514
+ self ._collect_used_signals_value (fragment , op )
515
+ elif isinstance (value , _ast .Slice ):
516
+ self ._collect_used_signals_value (fragment , value .value )
517
+ elif isinstance (value , _ast .Part ):
518
+ self ._collect_used_signals_value (fragment , value .value )
519
+ self ._collect_used_signals_value (fragment , value .offset )
520
+ elif isinstance (value , _ast .SwitchValue ):
521
+ self ._collect_used_signals_value (fragment , value .test )
522
+ for _patterns , elem in value .cases :
523
+ self ._collect_used_signals_value (fragment , elem )
524
+ elif isinstance (value , _ast .Concat ):
525
+ for part in value .parts :
526
+ self ._collect_used_signals_value (fragment , part )
527
+ else :
528
+ raise NotImplementedError # :nocov:
529
+
530
+ def _collect_used_signals_io_value (self , fragment : Fragment , value : _ast .IOValue ):
531
+ if isinstance (value , _ast .IOPort ):
532
+ self ._use_io_port (fragment , value )
533
+ elif isinstance (value , _ast .IOSlice ):
534
+ self ._collect_used_signals_io_value (fragment , value .value )
535
+ elif isinstance (value , _ast .IOConcat ):
536
+ for part in value .parts :
537
+ self ._collect_used_signals_io_value (fragment , part )
538
+ else :
539
+ raise NotImplementedError # :nocov:
540
+
541
+ def _collect_used_signals_stmt (self , fragment : Fragment , stmt : _ast .Statement ):
542
+ if isinstance (stmt , _ast .Assign ):
543
+ self ._collect_used_signals_value (fragment , stmt .lhs )
544
+ self ._collect_used_signals_value (fragment , stmt .rhs )
545
+ elif isinstance (stmt , _ast .Print ):
546
+ self ._collect_used_signals_format (fragment , stmt .message )
547
+ elif isinstance (stmt , _ast .Property ):
548
+ self ._collect_used_signals_value (fragment , stmt .test )
549
+ if stmt .message is not None :
550
+ self ._collect_used_signals_format (fragment , stmt .message )
551
+ elif isinstance (stmt , _ast .Switch ):
552
+ self ._collect_used_signals_value (fragment , stmt .test )
553
+ for _patterns , stmts , _src_loc in stmt .cases :
554
+ for s in stmts :
555
+ self ._collect_used_signals_stmt (fragment , s )
556
+ else :
557
+ raise NotImplementedError # :nocov:
558
+
501
559
def _collect_used_signals (self , fragment : Fragment ):
502
560
"""Collects used signals and IO ports for a fragment and all its subfragments."""
503
561
from . import _mem
504
562
if isinstance (fragment , _ir .Instance ):
505
563
for conn , kind in fragment .ports .values ():
506
564
if isinstance (conn , _ast .IOValue ):
507
- for port in conn ._ioports ():
508
- self ._use_io_port (fragment , port )
565
+ self ._collect_used_signals_io_value (fragment , conn )
509
566
elif isinstance (conn , _ast .Value ):
510
- for signal in conn ._rhs_signals ():
511
- self ._use_signal (fragment , signal )
567
+ self ._collect_used_signals_value (fragment , conn )
512
568
else :
513
569
assert False # :nocov:
514
570
elif isinstance (fragment , _ir .IOBufferInstance ):
515
- for port in fragment .port ._ioports ():
516
- self ._use_io_port (fragment , port )
571
+ self ._collect_used_signals_io_value (fragment , fragment .port )
517
572
if fragment .i is not None :
518
- for signal in fragment .i ._rhs_signals ():
519
- self ._use_signal (fragment , signal )
573
+ self ._collect_used_signals_value (fragment , fragment .i )
520
574
if fragment .o is not None :
521
- for signal in fragment .o ._rhs_signals ():
522
- self ._use_signal (fragment , signal )
523
- for signal in fragment .oe ._rhs_signals ():
524
- self ._use_signal (fragment , signal )
575
+ self ._collect_used_signals_value (fragment , fragment .o )
576
+ self ._collect_used_signals_value (fragment , fragment .oe )
525
577
elif isinstance (fragment , _mem .MemoryInstance ):
526
578
for port in fragment ._read_ports :
527
- for signal in port ._addr ._rhs_signals ():
528
- self ._use_signal (fragment , signal )
529
- for signal in port ._data ._rhs_signals ():
530
- self ._use_signal (fragment , signal )
531
- for signal in port ._en ._rhs_signals ():
532
- self ._use_signal (fragment , signal )
579
+ self ._collect_used_signals_value (fragment , port ._addr )
580
+ self ._collect_used_signals_value (fragment , port ._data )
581
+ self ._collect_used_signals_value (fragment , port ._en )
533
582
if port ._domain != "comb" :
534
583
domain = fragment .domains [port ._domain ]
535
584
self ._use_signal (fragment , domain .clk )
536
585
if domain .rst is not None :
537
586
self ._use_signal (fragment , domain .rst )
538
587
for port in fragment ._write_ports :
539
- for signal in port ._addr ._rhs_signals ():
540
- self ._use_signal (fragment , signal )
541
- for signal in port ._data ._rhs_signals ():
542
- self ._use_signal (fragment , signal )
543
- for signal in port ._en ._rhs_signals ():
544
- self ._use_signal (fragment , signal )
588
+ self ._collect_used_signals_value (fragment , port ._addr )
589
+ self ._collect_used_signals_value (fragment , port ._data )
590
+ self ._collect_used_signals_value (fragment , port ._en )
545
591
domain = fragment .domains [port ._domain ]
546
592
self ._use_signal (fragment , domain .clk )
547
593
if domain .rst is not None :
@@ -554,9 +600,7 @@ def _collect_used_signals(self, fragment: Fragment):
554
600
if domain .rst is not None :
555
601
self ._use_signal (fragment , domain .rst )
556
602
for statement in statements :
557
- for signal in statement ._lhs_signals () | statement ._rhs_signals ():
558
- if not isinstance (signal , (_ast .ClockSignal , _ast .ResetSignal )):
559
- self ._use_signal (fragment , signal )
603
+ self ._collect_used_signals_stmt (fragment , statement )
560
604
for subfragment , _name , _src_loc in fragment .subfragments :
561
605
self ._collect_used_signals (subfragment )
562
606
0 commit comments