Optimise some more

This commit is contained in:
Eddie Hung 2019-06-13 17:02:58 -07:00
parent d09d4e0706
commit bc22e2e3ee
1 changed files with 52 additions and 57 deletions

View File

@ -38,8 +38,8 @@ YOSYS_NAMESPACE_BEGIN
struct ConstEvalAig struct ConstEvalAig
{ {
RTLIL::Module *module; RTLIL::Module *module;
dict<RTLIL::SigBit, RTLIL::Const> values_map; dict<RTLIL::SigBit, RTLIL::State> values_map;
SigSet<RTLIL::Cell*> sig2driver; dict<RTLIL::SigBit, RTLIL::Cell*> sig2driver;
dict<SigBit, pool<RTLIL::SigBit>> sig2deps; dict<SigBit, pool<RTLIL::SigBit>> sig2deps;
ConstEvalAig(RTLIL::Module *module) : module(module) ConstEvalAig(RTLIL::Module *module) : module(module)
@ -52,8 +52,10 @@ struct ConstEvalAig
if (!ct.cell_known(it.second->type)) if (!ct.cell_known(it.second->type))
continue; continue;
for (auto &it2 : it.second->connections()) for (auto &it2 : it.second->connections())
if (ct.cell_output(it.second->type, it2.first)) if (ct.cell_output(it.second->type, it2.first)) {
sig2driver.insert(it2.second, it.second); auto r = sig2driver.insert(std::make_pair(it2.second, it.second));
log_assert(r.second);
}
} }
} }
@ -63,18 +65,19 @@ struct ConstEvalAig
sig2deps.clear(); sig2deps.clear();
} }
void set(RTLIL::SigSpec sig, RTLIL::Const value) void set(RTLIL::SigBit sig, RTLIL::State value)
{ {
#ifndef NDEBUG
auto it = values_map.find(sig); auto it = values_map.find(sig);
RTLIL::SigSpec current_val; #ifndef NDEBUG
if (it != values_map.end()) if (it != values_map.end()) {
current_val = it->second; RTLIL::State current_val = it->second;
for (int i = 0; i < GetSize(current_val); i++) log_assert(current_val == value);
log_assert(current_val[i].wire != NULL || current_val[i] == value.bits[i]); }
#endif #endif
for (int i = 0; i < GetSize(sig); i++) if (it != values_map.end())
values_map[sig[i]] = value[i]; it->second = value;
else
values_map[sig] = value;
} }
void set_incremental(RTLIL::SigSpec sig, RTLIL::Const value) void set_incremental(RTLIL::SigSpec sig, RTLIL::Const value)
@ -84,7 +87,7 @@ struct ConstEvalAig
for (int i = 0; i < GetSize(sig); i++) { for (int i = 0; i < GetSize(sig); i++) {
auto it = values_map.find(sig[i]); auto it = values_map.find(sig[i]);
if (it != values_map.end()) { if (it != values_map.end()) {
RTLIL::SigSpec current_val = it->second; RTLIL::State current_val = it->second;
if (current_val != value[i]) if (current_val != value[i])
for (auto dep : sig2deps[sig[i]]) for (auto dep : sig2deps[sig[i]])
values_map.erase(dep); values_map.erase(dep);
@ -99,40 +102,34 @@ struct ConstEvalAig
{ {
sig2deps[output].insert(output); sig2deps[output].insert(output);
std::set<RTLIL::Cell*> driver_cells; RTLIL::Cell *cell = sig2driver.at(output);
sig2driver.find(output, driver_cells); RTLIL::SigBit sig_a = cell->getPort("\\A");
for (auto cell : driver_cells) { sig2deps[sig_a].insert(sig2deps[output].begin(), sig2deps[output].end());
RTLIL::SigBit sig_a = cell->getPort("\\A"); if (!inputs.count(sig_a))
sig2deps[sig_a].insert(sig2deps[output].begin(), sig2deps[output].end()); compute_deps(sig_a, inputs);
if (!inputs.count(sig_a))
compute_deps(sig_a, inputs);
if (cell->type == "$_AND_") { if (cell->type == "$_AND_") {
RTLIL::SigSpec sig_b = cell->getPort("\\B"); RTLIL::SigSpec sig_b = cell->getPort("\\B");
sig2deps[sig_b].insert(sig2deps[output].begin(), sig2deps[output].end()); sig2deps[sig_b].insert(sig2deps[output].begin(), sig2deps[output].end());
if (!inputs.count(sig_b)) if (!inputs.count(sig_b))
compute_deps(sig_b, inputs); compute_deps(sig_b, inputs);
}
else if (cell->type == "$_NOT_") {
}
else log_abort();
} }
else if (cell->type == "$_NOT_") {
}
else log_abort();
} }
bool eval(RTLIL::Cell *cell) bool eval(RTLIL::Cell *cell)
{ {
RTLIL::SigSpec sig_y = cell->getPort("\\Y"); RTLIL::SigBit sig_y = cell->getPort("\\Y");
auto it = values_map.find(sig_y); if (values_map.count(sig_y))
if (it != values_map.end())
sig_y = it->second;
if (sig_y.is_fully_const())
return true; return true;
RTLIL::SigSpec sig_a = cell->getPort("\\A"); RTLIL::SigBit sig_a = cell->getPort("\\A");
if (sig_a.size() > 0 && !eval(sig_a)) if (!eval(sig_a))
return false; return false;
RTLIL::Const eval_ret; RTLIL::State eval_ret = RTLIL::Sx;
if (cell->type == "$_NOT_") { if (cell->type == "$_NOT_") {
if (sig_a == RTLIL::S0) eval_ret = RTLIL::S1; if (sig_a == RTLIL::S0) eval_ret = RTLIL::S1;
else if (sig_a == RTLIL::S1) eval_ret = RTLIL::S0; else if (sig_a == RTLIL::S1) eval_ret = RTLIL::S0;
@ -144,20 +141,18 @@ struct ConstEvalAig
} }
{ {
RTLIL::SigSpec sig_b = cell->getPort("\\B"); RTLIL::SigBit sig_b = cell->getPort("\\B");
if (sig_b.size() > 0 && !eval(sig_b)) if (!eval(sig_b))
return false; return false;
if (sig_b == RTLIL::S0) { if (sig_b == RTLIL::S0) {
eval_ret = RTLIL::S0; eval_ret = RTLIL::S0;
goto eval_end; goto eval_end;
} }
if (sig_a != RTLIL::State::S1 || sig_b != RTLIL::State::S1) { if (sig_a != RTLIL::S1 || sig_b != RTLIL::S1)
eval_ret = RTLIL::State::Sx;
goto eval_end; goto eval_end;
}
eval_ret = RTLIL::State::S1; eval_ret = RTLIL::S1;
} }
} }
else log_abort(); else log_abort();
@ -167,25 +162,23 @@ eval_end:
return true; return true;
} }
bool eval(RTLIL::SigSpec &sig) bool eval(RTLIL::SigBit &sig)
{ {
auto it = values_map.find(sig); auto it = values_map.find(sig);
if (it != values_map.end()) if (it != values_map.end()) {
sig = it->second; sig = it->second;
if (sig.is_fully_const())
return true; return true;
}
std::set<RTLIL::Cell*> driver_cells; RTLIL::Cell *cell = sig2driver.at(sig);
sig2driver.find(sig, driver_cells); if (!eval(cell))
for (auto cell : driver_cells) return false;
if (!eval(cell))
return false;
it = values_map.find(sig); it = values_map.find(sig);
if (it != values_map.end()) if (it != values_map.end()) {
sig = it->second; sig = it->second;
if (sig.is_fully_const())
return true; return true;
}
return false; return false;
} }
@ -411,9 +404,11 @@ void AigerReader::parse_xaiger()
for (int j = 0; j < (1 << cutLeavesM); ++j) { for (int j = 0; j < (1 << cutLeavesM); ++j) {
int gray = j ^ (j >> 1); int gray = j ^ (j >> 1);
ce.set_incremental(input_sig, RTLIL::Const{gray, static_cast<int>(cutLeavesM)}); ce.set_incremental(input_sig, RTLIL::Const{gray, static_cast<int>(cutLeavesM)});
RTLIL::SigSpec o(output_sig); RTLIL::SigBit o(output_sig);
ce.eval(o); bool success = ce.eval(o);
lut_mask[gray] = o.as_const()[0]; log_assert(success);
log_assert(o.wire == nullptr);
lut_mask[gray] = o.data;
} }
RTLIL::Cell *output_cell = module->cell(stringf("\\__%d__$and", rootNodeID)); RTLIL::Cell *output_cell = module->cell(stringf("\\__%d__$and", rootNodeID));
log_assert(output_cell); log_assert(output_cell);