if (check_label("dff", "(only if -dff)")) {
if (dff_mode || help_mode) {
run("abc9_ops -prep_dff_hier"); // derive all used (* abc9_flop *) modules,
- // create stubs in $abc9_unmap design
+ // create stubs in $abc9_unmap design
run("design -stash $abc9");
run("design -copy-from $abc9 @$abc9_flops"); // copy derived modules in
run("proc");
run("wbflip");
run("techmap");
run("opt");
+ if (!help_mode)
+ active_design->scratchpad_unset("abc9_ops.prep_dff_map.did_something");
run("abc9_ops -prep_dff_map"); // rewrite specify
- // select all $_DFF_[NP]_
- // then select all its fanins
- // then select all fanouts of all that
- // lastly remove $_DFF_[NP]_ cells
- run("setattr -set submod \"$abc9_flop\" t:$_DFF_?_ %ci* %co* t:$_DFF_?_ %d");
- run("submod");
- run("design -copy-to $abc9 *_$abc9_flop"); // copy submod out
- run("delete *_$abc9_flop");
- if (help_mode) {
- run("foreach module in design");
- run(" rename <module-name>_$abc9_flop _TECHMAP_REPLACE_");
+ bool did_something = help_mode || active_design->scratchpad_get_bool("abc9_ops.prep_dff_map.did_something");
+ if (did_something) {
+ // select all $_DFF_[NP]_
+ // then select all its fanins
+ // then select all fanouts of all that
+ // lastly remove $_DFF_[NP]_ cells
+ run("setattr -set submod \"$abc9_flop\" t:$_DFF_?_ %ci* %co* t:$_DFF_?_ %d");
+ run("submod");
+ run("design -copy-to $abc9 *_$abc9_flop"); // copy submod out
+ run("delete *_$abc9_flop");
+ if (help_mode) {
+ run("foreach module in design");
+ run(" rename <module-name>_$abc9_flop _TECHMAP_REPLACE_");
+ }
+ else {
+ // Rename all submod-s to _TECHMAP_REPLACE_ to inherit name + attrs
+ for (auto module : active_design->selected_modules()) {
+ active_design->selected_active_module = module->name.str();
+ if (module->cell(stringf("%s_$abc9_flop", module->name.c_str())))
+ run(stringf("rename %s_$abc9_flop _TECHMAP_REPLACE_", module->name.c_str()));
+ }
+ }
+ run("design -stash $abc9_map");
+ run("design -load $abc9");
+ run("design -delete $abc9");
+ run("select -unset $abc9_flops");
+ run("techmap -wb -map %$abc9_map"); // techmap user design into submod + $_DFF_[NP]_
+ run("design -delete $abc9_map");
+ run("setattr -mod -set whitebox 1 -set abc9_flop 1 -set abc9_box 1 *_$abc9_flop");
+ run("abc9_ops -prep_dff_unmap"); // implement $abc9_unmap design
}
else {
- // Rename all submod-s to _TECHMAP_REPLACE_ to inherit name + attrs
- for (auto module : active_design->selected_modules()) {
- active_design->selected_active_module = module->name.str();
- run(stringf("rename %s_$abc9_flop _TECHMAP_REPLACE_", module->name.c_str()));
- }
+ run("design -load $abc9");
+ run("design -delete $abc9");
+ run("select -unset $abc9_flops");
}
- run("design -stash $abc9_map");
- run("design -load $abc9");
- run("design -delete $abc9");
- run("select -unset $abc9_flops");
- run("abc9_ops -prep_dff_unmap"); // implement $abc9_unmap design
- run("techmap -map %$abc9_map"); // techmap user design into submod + $_DFF_[NP]_
- run("design -delete $abc9_map");
- run("setattr -mod -set whitebox 1 -set abc9_flop 1 -set abc9_box 1 *_$abc9_flop");
}
}
void prep_dff_map(RTLIL::Design *design)
{
+ Design *unmap_design = saved_designs.at("$abc9_unmap");
+
for (auto module : design->modules()) {
vector<Cell*> specify_cells;
SigBit D, Q;
Cell* dff_cell = nullptr;
+
+ // If module has a public name (i.e. not $paramod) and it doesn't exist
+ // in the $abc9_unmap then it means only derived modules were
+ // instantiated, so make this a blackbox
+ if (module->name[0] == '\\' && !unmap_design->module(module->name.str() + "_$abc9_flop")) {
+ module->makeblackbox();
+ module->set_bool_attribute(ID::blackbox, false);
+ module->set_bool_attribute(ID::whitebox, true);
+ continue;
+ }
+
for (auto cell : module->cells())
if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_))) {
if (dff_cell)
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->set_bool_attribute(ID::blackbox, false);
auto wire = module->addWire(ID(_TECHMAP_FAIL_));
wire->set_bool_attribute(ID::keep);
D = w;
}
- if (GetSize(specify_cells) == 0) {
- log_warning("Module '%s' marked (* abc9_flop *) contains no specify timing information.\n", log_id(module));
- }
- else {
- // Rewrite $specify cells that end with $_DFF_[NP]_.Q
- // to $_DFF_[NP]_.D since it will be moved into
- // the submodule
- for (auto cell : specify_cells) {
- auto DST = cell->getPort(ID::DST);
- DST.replace(Q, D);
- cell->setPort(ID::DST, DST);
- }
+ if (GetSize(specify_cells) == 0)
+ log_error("Module '%s' marked (* abc9_flop *) contains no specify timing information.\n", log_id(module));
+
+ // Rewrite $specify cells that end with $_DFF_[NP]_.Q
+ // to $_DFF_[NP]_.D since it will be moved into
+ // the submodule
+ for (auto cell : specify_cells) {
+ auto DST = cell->getPort(ID::DST);
+ DST.replace(Q, D);
+ cell->setPort(ID::DST, DST);
}
+
+ design->scratchpad_set_bool("abc9_ops.prep_dff_map.did_something", true);
+
continue_outer_loop: ;
}
}
EOT
equiv_opt -assert -multiclock -map +/xilinx/cells_sim.v synth_xilinx -abc9 -dff -noiopad -noclkbuf
design -load postopt
+select -assert-count 6 t:FD*
select -assert-count 6 c:fd2 c:fd3 c:fd4 c:fd6 c:fd7 c:fd8
EOT
equiv_opt -assert -multiclock -map +/xilinx/cells_sim.v synth_xilinx -abc9 -dff -noiopad -noclkbuf
design -load postopt
+select -assert-count 4 t:FD*
select -assert-count 4 c:fd3 c:fd4 c:fd7 c:fd8
logger -expect warning "Module '\$paramod\\FDSE_1\\INIT=1' contains a \$_DFF_N_ cell .*" 1
equiv_opt -assert -multiclock -map +/xilinx/cells_sim.v synth_xilinx -abc9 -dff -noiopad -noclkbuf
design -load postopt
-#select -assert-count 4 c:fd3 c:fd4 c:fd7 c:fd8
+select -assert-count 8 t:FD*
logger -expect-no-warnings