mirror of
https://github.com/YosysHQ/yosys
synced 2025-06-03 12:51:23 +00:00
Move ConstEvalAig to aigerparse.cc
This commit is contained in:
parent
75d89e56cf
commit
d09d4e0706
2 changed files with 161 additions and 160 deletions
|
@ -35,6 +35,162 @@
|
||||||
|
|
||||||
YOSYS_NAMESPACE_BEGIN
|
YOSYS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
struct ConstEvalAig
|
||||||
|
{
|
||||||
|
RTLIL::Module *module;
|
||||||
|
dict<RTLIL::SigBit, RTLIL::Const> values_map;
|
||||||
|
SigSet<RTLIL::Cell*> sig2driver;
|
||||||
|
dict<SigBit, pool<RTLIL::SigBit>> sig2deps;
|
||||||
|
|
||||||
|
ConstEvalAig(RTLIL::Module *module) : module(module)
|
||||||
|
{
|
||||||
|
CellTypes ct;
|
||||||
|
ct.setup_internals();
|
||||||
|
ct.setup_stdcells();
|
||||||
|
|
||||||
|
for (auto &it : module->cells_) {
|
||||||
|
if (!ct.cell_known(it.second->type))
|
||||||
|
continue;
|
||||||
|
for (auto &it2 : it.second->connections())
|
||||||
|
if (ct.cell_output(it.second->type, it2.first))
|
||||||
|
sig2driver.insert(it2.second, it.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
values_map.clear();
|
||||||
|
sig2deps.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(RTLIL::SigSpec sig, RTLIL::Const value)
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
auto it = values_map.find(sig);
|
||||||
|
RTLIL::SigSpec current_val;
|
||||||
|
if (it != values_map.end())
|
||||||
|
current_val = it->second;
|
||||||
|
for (int i = 0; i < GetSize(current_val); i++)
|
||||||
|
log_assert(current_val[i].wire != NULL || current_val[i] == value.bits[i]);
|
||||||
|
#endif
|
||||||
|
for (int i = 0; i < GetSize(sig); i++)
|
||||||
|
values_map[sig[i]] = value[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_incremental(RTLIL::SigSpec sig, RTLIL::Const value)
|
||||||
|
{
|
||||||
|
log_assert(GetSize(sig) == GetSize(value));
|
||||||
|
|
||||||
|
for (int i = 0; i < GetSize(sig); i++) {
|
||||||
|
auto it = values_map.find(sig[i]);
|
||||||
|
if (it != values_map.end()) {
|
||||||
|
RTLIL::SigSpec current_val = it->second;
|
||||||
|
if (current_val != value[i])
|
||||||
|
for (auto dep : sig2deps[sig[i]])
|
||||||
|
values_map.erase(dep);
|
||||||
|
it->second = value[i];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
values_map[sig[i]] = value[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void compute_deps(RTLIL::SigBit output, const pool<RTLIL::SigBit> &inputs)
|
||||||
|
{
|
||||||
|
sig2deps[output].insert(output);
|
||||||
|
|
||||||
|
std::set<RTLIL::Cell*> driver_cells;
|
||||||
|
sig2driver.find(output, driver_cells);
|
||||||
|
for (auto cell : driver_cells) {
|
||||||
|
RTLIL::SigBit sig_a = cell->getPort("\\A");
|
||||||
|
sig2deps[sig_a].insert(sig2deps[output].begin(), sig2deps[output].end());
|
||||||
|
if (!inputs.count(sig_a))
|
||||||
|
compute_deps(sig_a, inputs);
|
||||||
|
|
||||||
|
if (cell->type == "$_AND_") {
|
||||||
|
RTLIL::SigSpec sig_b = cell->getPort("\\B");
|
||||||
|
sig2deps[sig_b].insert(sig2deps[output].begin(), sig2deps[output].end());
|
||||||
|
if (!inputs.count(sig_b))
|
||||||
|
compute_deps(sig_b, inputs);
|
||||||
|
}
|
||||||
|
else if (cell->type == "$_NOT_") {
|
||||||
|
}
|
||||||
|
else log_abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool eval(RTLIL::Cell *cell)
|
||||||
|
{
|
||||||
|
RTLIL::SigSpec sig_y = cell->getPort("\\Y");
|
||||||
|
auto it = values_map.find(sig_y);
|
||||||
|
if (it != values_map.end())
|
||||||
|
sig_y = it->second;
|
||||||
|
if (sig_y.is_fully_const())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
RTLIL::SigSpec sig_a = cell->getPort("\\A");
|
||||||
|
if (sig_a.size() > 0 && !eval(sig_a))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
RTLIL::Const eval_ret;
|
||||||
|
if (cell->type == "$_NOT_") {
|
||||||
|
if (sig_a == RTLIL::S0) eval_ret = RTLIL::S1;
|
||||||
|
else if (sig_a == RTLIL::S1) eval_ret = RTLIL::S0;
|
||||||
|
}
|
||||||
|
else if (cell->type == "$_AND_") {
|
||||||
|
if (sig_a == RTLIL::S0) {
|
||||||
|
eval_ret = RTLIL::S0;
|
||||||
|
goto eval_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
RTLIL::SigSpec sig_b = cell->getPort("\\B");
|
||||||
|
if (sig_b.size() > 0 && !eval(sig_b))
|
||||||
|
return false;
|
||||||
|
if (sig_b == RTLIL::S0) {
|
||||||
|
eval_ret = RTLIL::S0;
|
||||||
|
goto eval_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sig_a != RTLIL::State::S1 || sig_b != RTLIL::State::S1) {
|
||||||
|
eval_ret = RTLIL::State::Sx;
|
||||||
|
goto eval_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
eval_ret = RTLIL::State::S1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else log_abort();
|
||||||
|
|
||||||
|
eval_end:
|
||||||
|
set(sig_y, eval_ret);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool eval(RTLIL::SigSpec &sig)
|
||||||
|
{
|
||||||
|
auto it = values_map.find(sig);
|
||||||
|
if (it != values_map.end())
|
||||||
|
sig = it->second;
|
||||||
|
if (sig.is_fully_const())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
std::set<RTLIL::Cell*> driver_cells;
|
||||||
|
sig2driver.find(sig, driver_cells);
|
||||||
|
for (auto cell : driver_cells)
|
||||||
|
if (!eval(cell))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
it = values_map.find(sig);
|
||||||
|
if (it != values_map.end())
|
||||||
|
sig = it->second;
|
||||||
|
if (sig.is_fully_const())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
AigerReader::AigerReader(RTLIL::Design *design, std::istream &f, RTLIL::IdString module_name, RTLIL::IdString clk_name, std::string map_filename, bool wideports)
|
AigerReader::AigerReader(RTLIL::Design *design, std::istream &f, RTLIL::IdString module_name, RTLIL::IdString clk_name, std::string map_filename, bool wideports)
|
||||||
: design(design), f(f), clk_name(clk_name), map_filename(map_filename), wideports(wideports)
|
: design(design), f(f), clk_name(clk_name), map_filename(map_filename), wideports(wideports)
|
||||||
{
|
{
|
||||||
|
@ -249,13 +405,15 @@ void AigerReader::parse_xaiger()
|
||||||
log_assert(wire);
|
log_assert(wire);
|
||||||
input_sig.append(wire);
|
input_sig.append(wire);
|
||||||
}
|
}
|
||||||
|
ce.clear();
|
||||||
|
ce.compute_deps(output_sig, input_sig.to_sigbit_pool());
|
||||||
RTLIL::Const lut_mask(RTLIL::State::Sx, 1 << input_sig.size());
|
RTLIL::Const lut_mask(RTLIL::State::Sx, 1 << input_sig.size());
|
||||||
for (int j = 0; j < (1 << cutLeavesM); ++j) {
|
for (int j = 0; j < (1 << cutLeavesM); ++j) {
|
||||||
ce.clear();
|
int gray = j ^ (j >> 1);
|
||||||
ce.set(input_sig, RTLIL::Const{j, static_cast<int>(cutLeavesM)});
|
ce.set_incremental(input_sig, RTLIL::Const{gray, static_cast<int>(cutLeavesM)});
|
||||||
RTLIL::SigSpec o(output_sig);
|
RTLIL::SigSpec o(output_sig);
|
||||||
ce.eval(o);
|
ce.eval(o);
|
||||||
lut_mask[j] = o.as_const()[0];
|
lut_mask[gray] = o.as_const()[0];
|
||||||
}
|
}
|
||||||
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);
|
||||||
|
|
|
@ -390,163 +390,6 @@ struct ConstEval
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ConstEvalAig
|
|
||||||
{
|
|
||||||
RTLIL::Module *module;
|
|
||||||
//SigMap assign_map;
|
|
||||||
SigMap values_map;
|
|
||||||
//SigPool stop_signals;
|
|
||||||
SigSet<RTLIL::Cell*> sig2driver;
|
|
||||||
//std::set<RTLIL::Cell*> busy;
|
|
||||||
//std::vector<SigMap> stack;
|
|
||||||
//RTLIL::State defaultval;
|
|
||||||
|
|
||||||
ConstEvalAig(RTLIL::Module *module /*, RTLIL::State defaultval = RTLIL::State::Sm*/) : module(module) /*, assign_map(module), defaultval(defaultval)*/
|
|
||||||
{
|
|
||||||
CellTypes ct;
|
|
||||||
ct.setup_internals();
|
|
||||||
ct.setup_stdcells();
|
|
||||||
|
|
||||||
for (auto &it : module->cells_) {
|
|
||||||
if (!ct.cell_known(it.second->type))
|
|
||||||
continue;
|
|
||||||
for (auto &it2 : it.second->connections())
|
|
||||||
if (ct.cell_output(it.second->type, it2.first))
|
|
||||||
sig2driver.insert(/*assign_map*/(it2.second), it.second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
values_map.clear();
|
|
||||||
//stop_signals.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
//void push()
|
|
||||||
//{
|
|
||||||
// stack.push_back(values_map);
|
|
||||||
//}
|
|
||||||
|
|
||||||
//void pop()
|
|
||||||
//{
|
|
||||||
// values_map.swap(stack.back());
|
|
||||||
// stack.pop_back();
|
|
||||||
//}
|
|
||||||
|
|
||||||
void set(RTLIL::SigSpec sig, RTLIL::Const value)
|
|
||||||
{
|
|
||||||
//assign_map.apply(sig);
|
|
||||||
#ifndef NDEBUG
|
|
||||||
RTLIL::SigSpec current_val = values_map(sig);
|
|
||||||
for (int i = 0; i < GetSize(current_val); i++)
|
|
||||||
log_assert(current_val[i].wire != NULL || current_val[i] == value.bits[i]);
|
|
||||||
#endif
|
|
||||||
values_map.add(sig, RTLIL::SigSpec(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
//void stop(RTLIL::SigSpec sig)
|
|
||||||
//{
|
|
||||||
// assign_map.apply(sig);
|
|
||||||
// stop_signals.add(sig);
|
|
||||||
//}
|
|
||||||
|
|
||||||
bool eval(RTLIL::Cell *cell /*, RTLIL::SigSpec &undef*/)
|
|
||||||
{
|
|
||||||
RTLIL::SigSpec sig_y = values_map(/*assign_map*/(cell->getPort("\\Y")));
|
|
||||||
if (sig_y.is_fully_const())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
RTLIL::SigSpec sig_a = cell->getPort("\\A");
|
|
||||||
if (sig_a.size() > 0 && !eval(sig_a /*, undef, cell*/))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
RTLIL::Const eval_ret;
|
|
||||||
if (cell->type == "$_NOT_") {
|
|
||||||
if (sig_a == RTLIL::S0) eval_ret = RTLIL::S1;
|
|
||||||
else if (sig_a == RTLIL::S1) eval_ret = RTLIL::S0;
|
|
||||||
}
|
|
||||||
else if (cell->type == "$_AND_") {
|
|
||||||
if (sig_a == RTLIL::S0) {
|
|
||||||
eval_ret = RTLIL::S0;
|
|
||||||
goto eval_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
RTLIL::SigSpec sig_b = cell->getPort("\\B");
|
|
||||||
if (sig_b.size() > 0 && !eval(sig_b /*, undef, cell*/))
|
|
||||||
return false;
|
|
||||||
if (sig_b == RTLIL::S0) {
|
|
||||||
eval_ret = RTLIL::S0;
|
|
||||||
goto eval_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sig_a != RTLIL::State::S1 || sig_b != RTLIL::State::S1) {
|
|
||||||
eval_ret = RTLIL::State::Sx;
|
|
||||||
goto eval_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
eval_ret = RTLIL::State::S1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else log_abort();
|
|
||||||
|
|
||||||
|
|
||||||
eval_end:
|
|
||||||
set(sig_y, eval_ret);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool eval(RTLIL::SigSpec &sig /*, RTLIL::SigSpec &undef, RTLIL::Cell *busy_cell = NULL*/)
|
|
||||||
{
|
|
||||||
//assign_map.apply(sig);
|
|
||||||
values_map.apply(sig);
|
|
||||||
|
|
||||||
if (sig.is_fully_const())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
//if (stop_signals.check_any(sig)) {
|
|
||||||
// undef = stop_signals.extract(sig);
|
|
||||||
// return false;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//if (busy_cell) {
|
|
||||||
// if (busy.count(busy_cell) > 0) {
|
|
||||||
// undef = sig;
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// busy.insert(busy_cell);
|
|
||||||
//}
|
|
||||||
|
|
||||||
std::set<RTLIL::Cell*> driver_cells;
|
|
||||||
sig2driver.find(sig, driver_cells);
|
|
||||||
for (auto cell : driver_cells) {
|
|
||||||
if (!eval(cell /*, undef*/)) {
|
|
||||||
//if (busy_cell)
|
|
||||||
// busy.erase(busy_cell);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//if (busy_cell)
|
|
||||||
// busy.erase(busy_cell);
|
|
||||||
|
|
||||||
values_map.apply(sig);
|
|
||||||
if (sig.is_fully_const())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
//for (auto &c : sig.chunks())
|
|
||||||
// if (c.wire != NULL)
|
|
||||||
// undef.append(c);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//bool eval(RTLIL::SigSpec &sig)
|
|
||||||
//{
|
|
||||||
// RTLIL::SigSpec undef;
|
|
||||||
// return eval(sig, undef);
|
|
||||||
//}
|
|
||||||
};
|
|
||||||
|
|
||||||
YOSYS_NAMESPACE_END
|
YOSYS_NAMESPACE_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue