mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-13 04:28:18 +00:00
Improved handling of "keep" attributes in hierarchical designs in opt_clean
This commit is contained in:
parent
bc468cb6f2
commit
c43f38c81b
|
@ -30,7 +30,55 @@ PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
using RTLIL::id2cstr;
|
using RTLIL::id2cstr;
|
||||||
|
|
||||||
CellTypes ct, ct_reg, ct_all;
|
struct keep_cache_t
|
||||||
|
{
|
||||||
|
Design *design;
|
||||||
|
dict<Module*, bool> cache;
|
||||||
|
|
||||||
|
void reset(Design *design = nullptr)
|
||||||
|
{
|
||||||
|
this->design = design;
|
||||||
|
cache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool query(Module *module)
|
||||||
|
{
|
||||||
|
log_assert(design != nullptr);
|
||||||
|
|
||||||
|
if (module == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (cache.count(module))
|
||||||
|
return cache.at(module);
|
||||||
|
|
||||||
|
cache[module] = true;
|
||||||
|
if (!module->get_bool_attribute("\\keep")) {
|
||||||
|
bool found_keep = false;
|
||||||
|
for (auto cell : module->cells())
|
||||||
|
if (query(cell)) found_keep = true;
|
||||||
|
cache[module] = found_keep;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cache[module];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool query(Cell *cell)
|
||||||
|
{
|
||||||
|
if (cell->type.in("$memwr", "$meminit", "$assert", "$assume"))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (cell->has_keep_attr())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (cell->module && cell->module->design)
|
||||||
|
return query(cell->module->design->module(cell->type));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
keep_cache_t keep_cache;
|
||||||
|
CellTypes ct_reg, ct_all;
|
||||||
int count_rm_cells, count_rm_wires;
|
int count_rm_cells, count_rm_wires;
|
||||||
|
|
||||||
void rmunused_module_cells(Module *module, bool verbose)
|
void rmunused_module_cells(Module *module, bool verbose)
|
||||||
|
@ -42,12 +90,12 @@ void rmunused_module_cells(Module *module, bool verbose)
|
||||||
for (auto &it : module->cells_) {
|
for (auto &it : module->cells_) {
|
||||||
Cell *cell = it.second;
|
Cell *cell = it.second;
|
||||||
for (auto &it2 : cell->connections()) {
|
for (auto &it2 : cell->connections()) {
|
||||||
if (!ct.cell_input(cell->type, it2.first))
|
if (!ct_all.cell_input(cell->type, it2.first))
|
||||||
for (auto bit : sigmap(it2.second))
|
for (auto bit : sigmap(it2.second))
|
||||||
if (bit.wire != nullptr)
|
if (bit.wire != nullptr)
|
||||||
wire2driver[bit].insert(cell);
|
wire2driver[bit].insert(cell);
|
||||||
}
|
}
|
||||||
if (cell->type.in("$memwr", "$meminit", "$assert", "$assume") || cell->has_keep_attr())
|
if (keep_cache.query(cell))
|
||||||
queue.insert(cell);
|
queue.insert(cell);
|
||||||
else
|
else
|
||||||
unused.insert(cell);
|
unused.insert(cell);
|
||||||
|
@ -67,7 +115,7 @@ void rmunused_module_cells(Module *module, bool verbose)
|
||||||
pool<SigBit> bits;
|
pool<SigBit> bits;
|
||||||
for (auto cell : queue)
|
for (auto cell : queue)
|
||||||
for (auto &it : cell->connections())
|
for (auto &it : cell->connections())
|
||||||
if (!ct.cell_output(cell->type, it.first))
|
if (!ct_all.cell_output(cell->type, it.first))
|
||||||
for (auto bit : sigmap(it.second))
|
for (auto bit : sigmap(it.second))
|
||||||
bits.insert(bit);
|
bits.insert(bit);
|
||||||
|
|
||||||
|
@ -193,7 +241,7 @@ void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos
|
||||||
for (auto &it2 : cell->connections_) {
|
for (auto &it2 : cell->connections_) {
|
||||||
assign_map.apply(it2.second);
|
assign_map.apply(it2.second);
|
||||||
used_signals.add(it2.second);
|
used_signals.add(it2.second);
|
||||||
if (!ct.cell_output(cell->type, it2.first))
|
if (!ct_all.cell_output(cell->type, it2.first))
|
||||||
used_signals_nodrivers.add(it2.second);
|
used_signals_nodrivers.add(it2.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -345,15 +393,7 @@ struct OptCleanPass : public Pass {
|
||||||
}
|
}
|
||||||
extra_args(args, argidx, design);
|
extra_args(args, argidx, design);
|
||||||
|
|
||||||
ct.setup_internals();
|
keep_cache.reset(design);
|
||||||
ct.setup_internals_mem();
|
|
||||||
ct.setup_stdcells();
|
|
||||||
ct.setup_stdcells_mem();
|
|
||||||
|
|
||||||
for (auto module : design->modules()) {
|
|
||||||
if (module->get_bool_attribute("\\blackbox"))
|
|
||||||
ct.setup_module(module);
|
|
||||||
}
|
|
||||||
|
|
||||||
ct_reg.setup_internals_mem();
|
ct_reg.setup_internals_mem();
|
||||||
ct_reg.setup_stdcells_mem();
|
ct_reg.setup_stdcells_mem();
|
||||||
|
@ -370,7 +410,7 @@ struct OptCleanPass : public Pass {
|
||||||
design->sort();
|
design->sort();
|
||||||
design->check();
|
design->check();
|
||||||
|
|
||||||
ct.clear();
|
keep_cache.reset();
|
||||||
ct_reg.clear();
|
ct_reg.clear();
|
||||||
ct_all.clear();
|
ct_all.clear();
|
||||||
log_pop();
|
log_pop();
|
||||||
|
@ -409,15 +449,7 @@ struct CleanPass : public Pass {
|
||||||
if (argidx < args.size())
|
if (argidx < args.size())
|
||||||
extra_args(args, argidx, design);
|
extra_args(args, argidx, design);
|
||||||
|
|
||||||
ct.setup_internals();
|
keep_cache.reset(design);
|
||||||
ct.setup_internals_mem();
|
|
||||||
ct.setup_stdcells();
|
|
||||||
ct.setup_stdcells_mem();
|
|
||||||
|
|
||||||
for (auto module : design->modules()) {
|
|
||||||
if (module->get_bool_attribute("\\blackbox"))
|
|
||||||
ct.setup_module(module);
|
|
||||||
}
|
|
||||||
|
|
||||||
ct_reg.setup_internals_mem();
|
ct_reg.setup_internals_mem();
|
||||||
ct_reg.setup_stdcells_mem();
|
ct_reg.setup_stdcells_mem();
|
||||||
|
@ -440,7 +472,7 @@ struct CleanPass : public Pass {
|
||||||
design->sort();
|
design->sort();
|
||||||
design->check();
|
design->check();
|
||||||
|
|
||||||
ct.clear();
|
keep_cache.reset();
|
||||||
ct_reg.clear();
|
ct_reg.clear();
|
||||||
ct_all.clear();
|
ct_all.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -866,8 +866,7 @@ endmodule
|
||||||
|
|
||||||
// SiliconBlue Device Configuration Cells
|
// SiliconBlue Device Configuration Cells
|
||||||
|
|
||||||
(* blackbox *)
|
(* blackbox, keep *)
|
||||||
(* keep *)
|
|
||||||
module SB_WARMBOOT (
|
module SB_WARMBOOT (
|
||||||
input BOOT,
|
input BOOT,
|
||||||
input S1,
|
input S1,
|
||||||
|
|
Loading…
Reference in a new issue