@@ -498,50 +498,96 @@ def _use_io_port(self, fragment: Fragment, port: _ast.IOPort):
498498 if frag_info .parent is not None :
499499 self ._use_io_port (frag_info .parent , port )
500500
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+
501559 def _collect_used_signals (self , fragment : Fragment ):
502560 """Collects used signals and IO ports for a fragment and all its subfragments."""
503561 from . import _mem
504562 if isinstance (fragment , _ir .Instance ):
505563 for conn , kind in fragment .ports .values ():
506564 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 )
509566 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 )
512568 else :
513569 assert False # :nocov:
514570 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 )
517572 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 )
520574 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 )
525577 elif isinstance (fragment , _mem .MemoryInstance ):
526578 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 )
533582 if port ._domain != "comb" :
534583 domain = fragment .domains [port ._domain ]
535584 self ._use_signal (fragment , domain .clk )
536585 if domain .rst is not None :
537586 self ._use_signal (fragment , domain .rst )
538587 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 )
545591 domain = fragment .domains [port ._domain ]
546592 self ._use_signal (fragment , domain .clk )
547593 if domain .rst is not None :
@@ -554,9 +600,7 @@ def _collect_used_signals(self, fragment: Fragment):
554600 if domain .rst is not None :
555601 self ._use_signal (fragment , domain .rst )
556602 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 )
560604 for subfragment , _name , _src_loc in fragment .subfragments :
561605 self ._collect_used_signals (subfragment )
562606
0 commit comments