1 // This is free and unencumbered software released into the public domain.
3 // Anyone is free to copy, modify, publish, use, compile, sell, or
4 // distribute this software, either in source code form or as a compiled
5 // binary, for any purpose, commercial or non-commercial, and by any
8 #include "kernel/yosys.h"
9 #include "kernel/sigtools.h"
16 PRIVATE_NAMESPACE_BEGIN
18 // this function is called for each module in the design
19 static void find_stub_nets(RTLIL::Design
*design
, RTLIL::Module
*module
, bool report_bits
)
21 // use a SigMap to convert nets to a unique representation
22 SigMap
sigmap(module
);
24 // count how many times a single-bit signal is used
25 std::map
<RTLIL::SigBit
, int> bit_usage_count
;
27 // count output lines for this module (needed only for summary output at the end)
30 log("Looking for stub wires in module %s:\n", RTLIL::id2cstr(module
->name
));
32 // For all ports on all cells
33 for (auto &cell_iter
: module
->cells_
)
34 for (auto &conn
: cell_iter
.second
->connections())
36 // Get the signals on the port
37 // (use sigmap to get a uniqe signal name)
38 RTLIL::SigSpec sig
= sigmap(conn
.second
);
40 // add each bit to bit_usage_count, unless it is a constant
43 bit_usage_count
[bit
]++;
46 // for each wire in the module
47 for (auto &wire_iter
: module
->wires_
)
49 RTLIL::Wire
*wire
= wire_iter
.second
;
51 // .. but only selected wires
52 if (!design
->selected(module
, wire
))
55 // add +1 usage if this wire actually is a port
56 int usage_offset
= wire
->port_id
> 0 ? 1 : 0;
58 // we will record which bits of the (possibly multi-bit) wire are stub signals
59 std::set
<int> stub_bits
;
61 // get a signal description for this wire and split it into separate bits
62 RTLIL::SigSpec sig
= sigmap(wire
);
64 // for each bit (unless it is a constant):
65 // check if it is used at least two times and add to stub_bits otherwise
66 for (int i
= 0; i
< GetSize(sig
); i
++)
67 if (sig
[i
].wire
!= NULL
&& (bit_usage_count
[sig
[i
]] + usage_offset
) < 2)
70 // continue if no stub bits found
71 if (stub_bits
.size() == 0)
74 // report stub bits and/or stub wires, don't report single bits
75 // if called with report_bits set to false.
76 if (GetSize(stub_bits
) == GetSize(sig
)) {
77 log(" found stub wire: %s\n", RTLIL::id2cstr(wire
->name
));
81 log(" found wire with stub bits: %s [", RTLIL::id2cstr(wire
->name
));
82 for (int bit
: stub_bits
)
83 log("%s%d", bit
== *stub_bits
.begin() ? "" : ", ", bit
);
87 // we have outputted a line, increment summary counter
93 log(" found %d stub wires or wires with stub bits.\n", line_count
);
95 log(" found %d stub wires.\n", line_count
);
98 // each pass contains a singleton object that is derived from Pass
99 struct StubnetsPass
: public Pass
{
100 StubnetsPass() : Pass("stubnets") { }
101 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) override
103 // variables to mirror information from passed options
104 bool report_bits
= 0;
106 log_header(design
, "Executing STUBNETS pass (find stub nets).\n");
110 for (argidx
= 1; argidx
< args
.size(); argidx
++) {
111 std::string arg
= args
[argidx
];
112 if (arg
== "-report_bits") {
119 // handle extra options (e.g. selection)
120 extra_args(args
, argidx
, design
);
122 // call find_stub_nets() for each module that is either
123 // selected as a whole or contains selected objects.
124 for (auto &it
: design
->modules_
)
125 if (design
->selected_module(it
.first
))
126 find_stub_nets(design
, it
.second
, report_bits
);
130 PRIVATE_NAMESPACE_END