@@ -298,7 +298,7 @@ bool check_public_name(RTLIL::IdString id)
298
298
return true ;
299
299
}
300
300
301
- bool rmunused_module_signals (RTLIL::Module *module , bool purge_mode, bool verbose)
301
+ bool rmunused_module_signals (RTLIL::Module *module , bool purge_mode, bool x_mode, bool verbose)
302
302
{
303
303
// `register_signals` and `connected_signals` will help us decide later on
304
304
// on picking representatives out of groups of connected signals
@@ -311,39 +311,48 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos
311
311
if (ct_reg.cell_known (cell->type )) {
312
312
bool clk2fflogic = cell->get_bool_attribute (ID (clk2fflogic));
313
313
for (auto &it2 : cell->connections ())
314
- if (clk2fflogic ? it2.first == ID::D : ct_reg.cell_output (cell->type , it2.first ))
315
- register_signals.add (it2.second );
316
- }
317
- for (auto &it2 : cell->connections ()) {
318
- connected_signals.add (it2.second );
319
- if (!ct_all.cell_known (cell->type ) || ct_all.cell_output (cell->type , it2.first ))
320
- maybe_driven_signals.push_back (it2.second );
314
+ if (clk2fflogic ? it2.first == ID::D : ct_reg.cell_output (cell->type , it2.first ))
315
+ register_signals.add (it2.second );
321
316
}
317
+ for (auto &it2 : cell->connections ())
318
+ connected_signals.add (it2.second );
322
319
}
323
320
324
321
SigMap assign_map (module );
325
- SigPool maybe_driven_signals_bits;
322
+ if (x_mode) {
323
+ for (auto [_, cell] : module ->cells_ )
324
+ for (auto [port, sig] : cell->connections ())
325
+ if (!ct_all.cell_known (cell->type ) || ct_all.cell_output (cell->type , port)) {
326
+ log_debug (" cell %s drives sig %s\n " , log_id (cell), log_signal (sig));
327
+ maybe_driven_signals.push_back (sig);
328
+ }
329
+
330
+ SigPool maybe_driven_signals_bits;
326
331
327
- for (auto sig : maybe_driven_signals) {
328
- for (auto bit : sig) {
329
- maybe_driven_signals_bits.add (assign_map (bit));
332
+ for (auto sig : maybe_driven_signals) {
333
+ for (auto bit : sig) {
334
+ maybe_driven_signals_bits.add (assign_map (bit));
335
+ log_debug (" bit %s (rep %s) is driven by cell output\n " , log_signal (sig), log_signal (assign_map (sig)));
336
+ }
330
337
}
331
- }
332
- for (auto &it : module ->wires_ ) {
333
- RTLIL::SigSpec sig = it.second ;
334
- if (it.second ->port_id != 0 ) {
335
- maybe_driven_signals_bits.add (assign_map (sig));
338
+ for (auto &it : module ->wires_ ) {
339
+ RTLIL::SigSpec sig = it.second ;
340
+ if (it.second ->port_id != 0 ) {
341
+ maybe_driven_signals_bits.add (assign_map (sig));
342
+ log_debug (" bit %s (rep %s) is driven by port input\n " , log_signal (sig), log_signal (assign_map (sig)));
343
+ }
336
344
}
337
- }
338
- for ( auto &it : module -> wires_ ) {
339
- RTLIL::SigSpec sig = it. second ;
340
- for ( auto bit : sig ) {
341
- if (!maybe_driven_signals_bits. check ( assign_map (bit))) {
342
- log ( " add conn %s <-> %s to assign_map\n " , log_signal (bit), log_signal ( SigBit (State::Sx) ));
343
- assign_map. add (bit, SigBit (State::Sx));
345
+ for ( auto &it : module -> wires_ ) {
346
+ RTLIL::SigSpec sig = it. second ;
347
+ for ( auto bit : sig) {
348
+ if (!maybe_driven_signals_bits. check ( assign_map ( bit)) ) {
349
+ log_debug ( " add conn %s <-> %s to assign_map\n " , log_signal (bit), log_signal ( SigBit (State::Sx)));
350
+ assign_map. add (bit, SigBit (State::Sx));
351
+ }
344
352
}
345
353
}
346
354
}
355
+
347
356
// construct a pool of wires which are directly driven by a known celltype,
348
357
// this will influence our choice of representatives
349
358
pool<RTLIL::Wire*> direct_wires;
@@ -619,7 +628,7 @@ bool rmunused_module_init(RTLIL::Module *module, bool verbose)
619
628
return did_something;
620
629
}
621
630
622
- void rmunused_module (RTLIL::Module *module , bool purge_mode, bool verbose, bool rminit)
631
+ void rmunused_module (RTLIL::Module *module , bool purge_mode, bool x_mode, bool verbose, bool rminit)
623
632
{
624
633
if (verbose)
625
634
log (" Finding unused cells or wires in module %s..\n " , module ->name .c_str ());
@@ -644,10 +653,10 @@ void rmunused_module(RTLIL::Module *module, bool purge_mode, bool verbose, bool
644
653
module ->design ->scratchpad_set_bool (" opt.did_something" , true );
645
654
646
655
rmunused_module_cells (module , verbose);
647
- while (rmunused_module_signals (module , purge_mode, verbose)) { }
656
+ while (rmunused_module_signals (module , purge_mode, x_mode, verbose)) { }
648
657
649
658
if (rminit && rmunused_module_init (module , verbose))
650
- while (rmunused_module_signals (module , purge_mode, verbose)) { }
659
+ while (rmunused_module_signals (module , purge_mode, x_mode, verbose)) { }
651
660
}
652
661
653
662
struct OptCleanPass : public Pass {
@@ -668,10 +677,14 @@ struct OptCleanPass : public Pass {
668
677
log (" -purge\n " );
669
678
log (" also remove internal nets if they have a public name\n " );
670
679
log (" \n " );
680
+ log (" -x\n " );
681
+ log (" handle unconnected bits as x-bit driven\n " );
682
+ log (" \n " );
671
683
}
672
684
void execute (std::vector<std::string> args, RTLIL::Design *design) override
673
685
{
674
686
bool purge_mode = false ;
687
+ bool x_mode = false ;
675
688
676
689
log_header (design, " Executing OPT_CLEAN pass (remove unused cells and wires).\n " );
677
690
log_push ();
@@ -682,6 +695,10 @@ struct OptCleanPass : public Pass {
682
695
purge_mode = true ;
683
696
continue ;
684
697
}
698
+ if (args[argidx] == " -x" ) {
699
+ x_mode = true ;
700
+ continue ;
701
+ }
685
702
break ;
686
703
}
687
704
extra_args (args, argidx, design);
@@ -700,7 +717,7 @@ struct OptCleanPass : public Pass {
700
717
for (auto module : design->selected_whole_modules_warn ()) {
701
718
if (module ->has_processes_warn ())
702
719
continue ;
703
- rmunused_module (module , purge_mode, true , true );
720
+ rmunused_module (module , purge_mode, x_mode, true , true );
704
721
}
705
722
706
723
if (count_rm_cells > 0 || count_rm_wires > 0 )
@@ -737,13 +754,18 @@ struct CleanPass : public Pass {
737
754
void execute (std::vector<std::string> args, RTLIL::Design *design) override
738
755
{
739
756
bool purge_mode = false ;
757
+ bool x_mode = false ;
740
758
741
759
size_t argidx;
742
760
for (argidx = 1 ; argidx < args.size (); argidx++) {
743
761
if (args[argidx] == " -purge" ) {
744
762
purge_mode = true ;
745
763
continue ;
746
764
}
765
+ if (args[argidx] == " -x" ) {
766
+ x_mode = true ;
767
+ continue ;
768
+ }
747
769
break ;
748
770
}
749
771
extra_args (args, argidx, design);
@@ -762,7 +784,7 @@ struct CleanPass : public Pass {
762
784
for (auto module : design->selected_whole_modules ()) {
763
785
if (module ->has_processes ())
764
786
continue ;
765
- rmunused_module (module , purge_mode, ys_debug (), true );
787
+ rmunused_module (module , purge_mode, x_mode, ys_debug (), true );
766
788
}
767
789
768
790
log_suppressed ();
0 commit comments