mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-13 04:28:18 +00:00
Added removing of always inactive cells to "share" pass
This commit is contained in:
parent
8819493db4
commit
7b98e46ac3
|
@ -41,6 +41,8 @@ struct ShareWorker
|
||||||
CellTypes fwd_ct, cone_ct;
|
CellTypes fwd_ct, cone_ct;
|
||||||
ModWalker modwalker;
|
ModWalker modwalker;
|
||||||
|
|
||||||
|
std::set<RTLIL::Cell*> cells_to_remove;
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
// Find terminal bits -- i.e. bits that do not (exclusively) feed into a mux tree
|
// Find terminal bits -- i.e. bits that do not (exclusively) feed into a mux tree
|
||||||
|
@ -229,7 +231,7 @@ struct ShareWorker
|
||||||
|
|
||||||
std::map<RTLIL::Cell*, std::set<std::pair<RTLIL::SigSpec, RTLIL::Const>>> activation_patterns_cache;
|
std::map<RTLIL::Cell*, std::set<std::pair<RTLIL::SigSpec, RTLIL::Const>>> activation_patterns_cache;
|
||||||
|
|
||||||
bool sort_check_pattern(std::pair<RTLIL::SigSpec, RTLIL::Const> &p)
|
bool sort_check_activation_pattern(std::pair<RTLIL::SigSpec, RTLIL::Const> &p)
|
||||||
{
|
{
|
||||||
std::map<RTLIL::SigBit, RTLIL::State> p_bits;
|
std::map<RTLIL::SigBit, RTLIL::State> p_bits;
|
||||||
|
|
||||||
|
@ -253,7 +255,13 @@ struct ShareWorker
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::set<std::pair<RTLIL::SigSpec, RTLIL::Const>> &find_cell_activation_patterns(RTLIL::Cell *cell)
|
void optimize_activation_patterns(std::set<std::pair<RTLIL::SigSpec, RTLIL::Const>> & /* patterns */)
|
||||||
|
{
|
||||||
|
// TODO: Remove patterns that are contained in other patterns
|
||||||
|
// TODO: Consolidate pairs of patterns that only differ in the value for one signal bit
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::set<std::pair<RTLIL::SigSpec, RTLIL::Const>> &find_cell_activation_patterns(RTLIL::Cell *cell, const char *indent)
|
||||||
{
|
{
|
||||||
if (activation_patterns_cache.count(cell))
|
if (activation_patterns_cache.count(cell))
|
||||||
return activation_patterns_cache.at(cell);
|
return activation_patterns_cache.at(cell);
|
||||||
|
@ -276,7 +284,7 @@ struct ShareWorker
|
||||||
|
|
||||||
for (auto c : driven_cells)
|
for (auto c : driven_cells)
|
||||||
{
|
{
|
||||||
const std::set<std::pair<RTLIL::SigSpec, RTLIL::Const>> &c_patterns = find_cell_activation_patterns(c);
|
const std::set<std::pair<RTLIL::SigSpec, RTLIL::Const>> &c_patterns = find_cell_activation_patterns(c, indent);
|
||||||
|
|
||||||
if (c->type == "$mux" || c->type == "$pmux")
|
if (c->type == "$mux" || c->type == "$pmux")
|
||||||
{
|
{
|
||||||
|
@ -300,14 +308,14 @@ struct ShareWorker
|
||||||
for (auto p : c_patterns) {
|
for (auto p : c_patterns) {
|
||||||
for (int i = 0; i < SIZE(sig_s); i++)
|
for (int i = 0; i < SIZE(sig_s); i++)
|
||||||
p.first.append_bit(sig_s[i]), p.second.bits.push_back(RTLIL::State::S0);
|
p.first.append_bit(sig_s[i]), p.second.bits.push_back(RTLIL::State::S0);
|
||||||
if (sort_check_pattern(p))
|
if (sort_check_activation_pattern(p))
|
||||||
activation_patterns_cache[cell].insert(p);
|
activation_patterns_cache[cell].insert(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int idx : used_in_b_parts)
|
for (int idx : used_in_b_parts)
|
||||||
for (auto p : c_patterns) {
|
for (auto p : c_patterns) {
|
||||||
p.first.append_bit(sig_s[idx]), p.second.bits.push_back(RTLIL::State::S1);
|
p.first.append_bit(sig_s[idx]), p.second.bits.push_back(RTLIL::State::S1);
|
||||||
if (sort_check_pattern(p))
|
if (sort_check_activation_pattern(p))
|
||||||
activation_patterns_cache[cell].insert(p);
|
activation_patterns_cache[cell].insert(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -319,6 +327,12 @@ struct ShareWorker
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
optimize_activation_patterns(activation_patterns_cache[cell]);
|
||||||
|
if (activation_patterns_cache[cell].empty()) {
|
||||||
|
log("%sFound cell that is never activated: %s\n", indent, log_id(cell));
|
||||||
|
cells_to_remove.insert(cell);
|
||||||
|
}
|
||||||
|
|
||||||
return activation_patterns_cache[cell];
|
return activation_patterns_cache[cell];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,9 +389,14 @@ struct ShareWorker
|
||||||
|
|
||||||
log(" Analyzing resource sharing options for %s:\n", log_id(cell));
|
log(" Analyzing resource sharing options for %s:\n", log_id(cell));
|
||||||
|
|
||||||
const std::set<std::pair<RTLIL::SigSpec, RTLIL::Const>> &cell_activation_patterns = find_cell_activation_patterns(cell);
|
const std::set<std::pair<RTLIL::SigSpec, RTLIL::Const>> &cell_activation_patterns = find_cell_activation_patterns(cell, " ");
|
||||||
RTLIL::SigSpec cell_activation_signals = bits_from_activation_patterns(cell_activation_patterns);
|
RTLIL::SigSpec cell_activation_signals = bits_from_activation_patterns(cell_activation_patterns);
|
||||||
|
|
||||||
|
if (cell_activation_patterns.empty()) {
|
||||||
|
log (" Cell is never active. Sharing is pointless, we simply remove it.\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (cell_activation_patterns.count(std::pair<RTLIL::SigSpec, RTLIL::Const>())) {
|
if (cell_activation_patterns.count(std::pair<RTLIL::SigSpec, RTLIL::Const>())) {
|
||||||
log (" Cell is always active. Therefore no sharing is possible.\n");
|
log (" Cell is always active. Therefore no sharing is possible.\n");
|
||||||
continue;
|
continue;
|
||||||
|
@ -402,11 +421,17 @@ struct ShareWorker
|
||||||
{
|
{
|
||||||
log(" Analyzing resource sharing with %s:\n", log_id(other_cell));
|
log(" Analyzing resource sharing with %s:\n", log_id(other_cell));
|
||||||
|
|
||||||
const std::set<std::pair<RTLIL::SigSpec, RTLIL::Const>> &other_cell_activation_patterns = find_cell_activation_patterns(other_cell);
|
const std::set<std::pair<RTLIL::SigSpec, RTLIL::Const>> &other_cell_activation_patterns = find_cell_activation_patterns(other_cell, " ");
|
||||||
RTLIL::SigSpec other_cell_activation_signals = bits_from_activation_patterns(other_cell_activation_patterns);
|
RTLIL::SigSpec other_cell_activation_signals = bits_from_activation_patterns(other_cell_activation_patterns);
|
||||||
|
|
||||||
|
if (other_cell_activation_patterns.empty()) {
|
||||||
|
log (" Cell is never active. Sharing is pointless, we simply remove it.\n");
|
||||||
|
shareable_cells.erase(other_cell);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (other_cell_activation_patterns.count(std::pair<RTLIL::SigSpec, RTLIL::Const>())) {
|
if (other_cell_activation_patterns.count(std::pair<RTLIL::SigSpec, RTLIL::Const>())) {
|
||||||
log (" Cell is always active. Therefore no sharing is possible.\n");
|
log (" Cell is always active. Therefore no sharing is possible.\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,6 +509,15 @@ struct ShareWorker
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!cells_to_remove.empty()) {
|
||||||
|
log("Removing %d cells in module %s:\n", SIZE(cells_to_remove), log_id(module));
|
||||||
|
for (auto c : cells_to_remove) {
|
||||||
|
log(" Removing cell %s (%s).\n", log_id(c), log_id(c->type));
|
||||||
|
module->cells.erase(c->name);
|
||||||
|
delete c;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue