mirror of https://github.com/YosysHQ/yosys.git
abc9_ops: -prep_dff_map to cope with plain $_DFF_[NP]_ flops
This commit is contained in:
parent
c10757a8ea
commit
a1ae5845f8
|
@ -134,15 +134,24 @@ void prep_dff_hier(RTLIL::Design *design)
|
||||||
for (auto module : design->selected_modules())
|
for (auto module : design->selected_modules())
|
||||||
for (auto cell : module->cells()) {
|
for (auto cell : module->cells()) {
|
||||||
auto inst_module = design->module(cell->type);
|
auto inst_module = design->module(cell->type);
|
||||||
if (inst_module && inst_module->get_bool_attribute(ID::abc9_flop)) {
|
if (inst_module && inst_module->attributes.count(ID::abc9_flop)) {
|
||||||
modules_sel.select(inst_module);
|
if (inst_module->get_blackbox_attribute(true /* ignore_wb */))
|
||||||
|
log_error("Module '%s' with (* abc9_flop *) is not a whitebox.\n", log_id(inst_module));
|
||||||
// Derive modules for all instantiations of (* abc9_flop *)
|
// Derive modules for all instantiations of (* abc9_flop *)
|
||||||
auto derived_type = inst_module->derive(design, cell->parameters);
|
auto derived_type = inst_module->derive(design, cell->parameters);
|
||||||
|
auto derived_module = design->module(derived_type);
|
||||||
|
if (!derived_module->get_bool_attribute(ID::abc9_flop))
|
||||||
|
continue;
|
||||||
// And remember one representative cell (for its parameters)
|
// And remember one representative cell (for its parameters)
|
||||||
if (modules_sel.selected_modules.insert(derived_type).second)
|
if (!modules_sel.selected_whole_module(derived_type)) {
|
||||||
|
if (derived_type != cell->type)
|
||||||
|
modules_sel.select(inst_module);
|
||||||
|
|
||||||
|
modules_sel.select(derived_module);
|
||||||
cells_sel.select(module, cell);
|
cells_sel.select(module, cell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void prep_dff_map(RTLIL::Design *design)
|
void prep_dff_map(RTLIL::Design *design)
|
||||||
|
@ -150,19 +159,20 @@ void prep_dff_map(RTLIL::Design *design)
|
||||||
for (auto module : design->modules()) {
|
for (auto module : design->modules()) {
|
||||||
vector<Cell*> specify_cells;
|
vector<Cell*> specify_cells;
|
||||||
SigBit D, Q;
|
SigBit D, Q;
|
||||||
|
Cell* dff_cell = nullptr;
|
||||||
for (auto cell : module->cells())
|
for (auto cell : module->cells())
|
||||||
if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_))) {
|
if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_))) {
|
||||||
if (D != SigBit())
|
if (dff_cell)
|
||||||
log_error("More than one $_DFF_[NP]_ cell found in module '%s' marked (* abc9_flop *)\n", log_id(module));
|
log_error("More than one $_DFF_[NP]_ cell found in module '%s' marked (* abc9_flop *)\n", log_id(module));
|
||||||
D = cell->getPort(ID::D);
|
dff_cell = cell;
|
||||||
Q = cell->getPort(ID::Q);
|
|
||||||
|
|
||||||
// Block sequential synthesis on cells with (* init = 1 *)
|
// Block sequential synthesis on cells with (* init *) != 1'b0
|
||||||
// because ABC9 doesn't support them
|
// because ABC9 doesn't support them
|
||||||
|
Q = cell->getPort(ID::Q);
|
||||||
log_assert(GetSize(Q.wire) == 1);
|
log_assert(GetSize(Q.wire) == 1);
|
||||||
Const init = Q.wire->attributes.at(ID::init, State::Sx);
|
Const init = Q.wire->attributes.at(ID::init, State::Sx);
|
||||||
log_assert(GetSize(init) == 1);
|
log_assert(GetSize(init) == 1);
|
||||||
if (init == State::S1) {
|
if (init != State::S0) {
|
||||||
log_warning("Module '%s' contains a %s cell with non-zero initial state -- this is not unsupported for ABC9 sequential synthesis. Treating as a blackbox.\n", log_id(module), log_id(cell->type));
|
log_warning("Module '%s' contains a %s cell with non-zero initial state -- this is not unsupported for ABC9 sequential synthesis. Treating as a blackbox.\n", log_id(module), log_id(cell->type));
|
||||||
|
|
||||||
module->makeblackbox();
|
module->makeblackbox();
|
||||||
|
@ -176,9 +186,26 @@ void prep_dff_map(RTLIL::Design *design)
|
||||||
}
|
}
|
||||||
else if (cell->type.in(ID($specify2), ID($specify3), ID($specrule)))
|
else if (cell->type.in(ID($specify2), ID($specify3), ID($specrule)))
|
||||||
specify_cells.emplace_back(cell);
|
specify_cells.emplace_back(cell);
|
||||||
if (D == SigBit())
|
if (!dff_cell)
|
||||||
log_error("$_DFF_[NP]_ cell not found in module '%s' marked (* abc9_flop *)\n", log_id(module));
|
log_error("$_DFF_[NP]_ cell not found in module '%s' marked (* abc9_flop *)\n", log_id(module));
|
||||||
|
|
||||||
|
D = dff_cell->getPort(ID::D);
|
||||||
|
|
||||||
|
// Add a dummy enable mux feeding DFF.D to ensure that:
|
||||||
|
// (i) a driving cell exists, so that 'submod' will have
|
||||||
|
// an output port
|
||||||
|
// (ii) DFF.Q will exist in this submodule
|
||||||
|
{
|
||||||
|
auto c = module->addCell(NEW_ID, ID($_MUX_));
|
||||||
|
auto w = module->addWire(NEW_ID);
|
||||||
|
c->setPort(ID::A, D);
|
||||||
|
c->setPort(ID::B, Q);
|
||||||
|
c->setPort(ID::S, State::S0);
|
||||||
|
c->setPort(ID::Y, w);
|
||||||
|
dff_cell->setPort(ID::D, w);
|
||||||
|
D = w;
|
||||||
|
}
|
||||||
|
|
||||||
// Rewrite $specify cells that end with $_DFF_[NP]_.Q
|
// Rewrite $specify cells that end with $_DFF_[NP]_.Q
|
||||||
// to $_DFF_[NP]_.D since it will be moved into
|
// to $_DFF_[NP]_.D since it will be moved into
|
||||||
// the submodule
|
// the submodule
|
||||||
|
@ -253,7 +280,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto inst_module = design->module(cell->type);
|
auto inst_module = design->module(cell->type);
|
||||||
bool abc9_flop = inst_module && inst_module->get_bool_attribute(ID::abc9_flop);
|
bool abc9_flop = inst_module && inst_module->attributes.count(ID::abc9_flop);
|
||||||
if (abc9_flop && !dff)
|
if (abc9_flop && !dff)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -339,7 +366,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
|
||||||
log_assert(cell);
|
log_assert(cell);
|
||||||
|
|
||||||
RTLIL::Module* box_module = design->module(cell->type);
|
RTLIL::Module* box_module = design->module(cell->type);
|
||||||
if (!box_module || (!box_module->get_bool_attribute(ID::abc9_box) && !box_module->get_bool_attribute(ID::abc9_flop)))
|
if (!box_module || !box_module->get_bool_attribute(ID::abc9_box))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
cell->attributes[ID::abc9_box_seq] = box_count++;
|
cell->attributes[ID::abc9_box_seq] = box_count++;
|
||||||
|
@ -967,7 +994,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
|
||||||
SigSpec outputs = std::move(jt->second);
|
SigSpec outputs = std::move(jt->second);
|
||||||
mapped_cell->connections_.erase(jt);
|
mapped_cell->connections_.erase(jt);
|
||||||
|
|
||||||
auto abc9_flop = box_module->attributes.count(ID::abc9_flop);
|
auto abc9_flop = box_module->get_bool_attribute(ID::abc9_flop);
|
||||||
if (!abc9_flop) {
|
if (!abc9_flop) {
|
||||||
for (const auto &i : inputs)
|
for (const auto &i : inputs)
|
||||||
bit_users[i].insert(mapped_cell->name);
|
bit_users[i].insert(mapped_cell->name);
|
||||||
|
|
Loading…
Reference in New Issue