3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-05-09 16:55:49 +00:00
This commit is contained in:
Emil J 2025-05-09 09:06:25 +12:00 committed by GitHub
commit b49d839577
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -267,8 +267,8 @@ bool compare_signals(RTLIL::SigBit &s1, RTLIL::SigBit &s2, SigPool &regs, SigPoo
return regs.check(s2);
if (direct_wires.count(w1) != direct_wires.count(w2))
return direct_wires.count(w2) != 0;
if (conns.check_any(s1) != conns.check_any(s2))
return conns.check_any(s2);
if (conns.check(s1) != conns.check(s2))
return conns.check(s2);
}
if (w1->port_output != w2->port_output)
@ -298,26 +298,60 @@ bool check_public_name(RTLIL::IdString id)
return true;
}
bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbose)
bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool x_mode, bool verbose)
{
// `register_signals` and `connected_signals` will help us decide later on
// on picking representatives out of groups of connected signals
SigPool register_signals;
SigPool connected_signals;
std::vector<SigSpec> maybe_driven_signals;
if (!purge_mode)
for (auto &it : module->cells_) {
RTLIL::Cell *cell = it.second;
if (ct_reg.cell_known(cell->type)) {
bool clk2fflogic = cell->get_bool_attribute(ID(clk2fflogic));
for (auto &it2 : cell->connections())
if (clk2fflogic ? it2.first == ID::D : ct_reg.cell_output(cell->type, it2.first))
register_signals.add(it2.second);
if (clk2fflogic ? it2.first == ID::D : ct_reg.cell_output(cell->type, it2.first))
register_signals.add(it2.second);
}
for (auto &it2 : cell->connections())
connected_signals.add(it2.second);
connected_signals.add(it2.second);
}
SigMap assign_map(module);
if (x_mode) {
for (auto [_, cell] : module->cells_)
for (auto [port, sig] : cell->connections())
if (!ct_all.cell_known(cell->type) || ct_all.cell_output(cell->type, port)) {
log_debug("cell %s drives sig %s\n", log_id(cell), log_signal(sig));
maybe_driven_signals.push_back(sig);
}
SigPool maybe_driven_signals_bits;
for (auto sig : maybe_driven_signals) {
for (auto bit : sig) {
maybe_driven_signals_bits.add(assign_map(bit));
log_debug("bit %s (rep %s) is driven by cell output\n", log_signal(sig), log_signal(assign_map(sig)));
}
}
for (auto &it : module->wires_) {
RTLIL::SigSpec sig = it.second;
if (it.second->port_id != 0) {
maybe_driven_signals_bits.add(assign_map(sig));
log_debug("bit %s (rep %s) is driven by port input\n", log_signal(sig), log_signal(assign_map(sig)));
}
}
for (auto &it : module->wires_) {
RTLIL::SigSpec sig = it.second;
for (auto bit : sig) {
if (!maybe_driven_signals_bits.check(assign_map(bit))) {
log_debug("add conn %s <-> %s to assign_map\n", log_signal(bit), log_signal(SigBit(State::Sx)));
assign_map.add(bit, SigBit(State::Sx));
}
}
}
}
// construct a pool of wires which are directly driven by a known celltype,
// this will influence our choice of representatives
@ -594,7 +628,7 @@ bool rmunused_module_init(RTLIL::Module *module, bool verbose)
return did_something;
}
void rmunused_module(RTLIL::Module *module, bool purge_mode, bool verbose, bool rminit)
void rmunused_module(RTLIL::Module *module, bool purge_mode, bool x_mode, bool verbose, bool rminit)
{
if (verbose)
log("Finding unused cells or wires in module %s..\n", module->name.c_str());
@ -619,10 +653,10 @@ void rmunused_module(RTLIL::Module *module, bool purge_mode, bool verbose, bool
module->design->scratchpad_set_bool("opt.did_something", true);
rmunused_module_cells(module, verbose);
while (rmunused_module_signals(module, purge_mode, verbose)) { }
while (rmunused_module_signals(module, purge_mode, x_mode, verbose)) { }
if (rminit && rmunused_module_init(module, verbose))
while (rmunused_module_signals(module, purge_mode, verbose)) { }
while (rmunused_module_signals(module, purge_mode, x_mode, verbose)) { }
}
struct OptCleanPass : public Pass {
@ -643,10 +677,14 @@ struct OptCleanPass : public Pass {
log(" -purge\n");
log(" also remove internal nets if they have a public name\n");
log("\n");
log(" -x\n");
log(" handle unconnected bits as x-bit driven\n");
log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) override
{
bool purge_mode = false;
bool x_mode = false;
log_header(design, "Executing OPT_CLEAN pass (remove unused cells and wires).\n");
log_push();
@ -657,6 +695,10 @@ struct OptCleanPass : public Pass {
purge_mode = true;
continue;
}
if (args[argidx] == "-x") {
x_mode = true;
continue;
}
break;
}
extra_args(args, argidx, design);
@ -675,7 +717,7 @@ struct OptCleanPass : public Pass {
for (auto module : design->selected_whole_modules_warn()) {
if (module->has_processes_warn())
continue;
rmunused_module(module, purge_mode, true, true);
rmunused_module(module, purge_mode, x_mode, true, true);
}
if (count_rm_cells > 0 || count_rm_wires > 0)
@ -712,6 +754,7 @@ struct CleanPass : public Pass {
void execute(std::vector<std::string> args, RTLIL::Design *design) override
{
bool purge_mode = false;
bool x_mode = false;
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++) {
@ -719,6 +762,10 @@ struct CleanPass : public Pass {
purge_mode = true;
continue;
}
if (args[argidx] == "-x") {
x_mode = true;
continue;
}
break;
}
extra_args(args, argidx, design);
@ -737,7 +784,7 @@ struct CleanPass : public Pass {
for (auto module : design->selected_unboxed_whole_modules()) {
if (module->has_processes())
continue;
rmunused_module(module, purge_mode, ys_debug(), true);
rmunused_module(module, purge_mode, x_mode, ys_debug(), true);
}
log_suppressed();