diff options
-rw-r--r-- | passes/techmap/abc9.cc | 19 | ||||
-rw-r--r-- | passes/techmap/abc9_ops.cc | 26 | ||||
-rw-r--r-- | techlibs/common/Makefile.inc | 2 | ||||
-rw-r--r-- | techlibs/common/abc9_map.v | 21 | ||||
-rw-r--r-- | techlibs/common/abc9_model.v | 20 | ||||
-rw-r--r-- | techlibs/common/abc9_unmap.v | 12 | ||||
-rw-r--r-- | tests/various/abc9.ys | 12 |
7 files changed, 88 insertions, 24 deletions
diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index fbb8356a5..911254aa6 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -314,23 +314,24 @@ struct Abc9Pass : public ScriptPass } } 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 -load $abc9"); + run("design -delete $abc9"); + run("select -unset $abc9_flops"); + if (did_something) { // techmap user design into submod + $_DFF_[NP]_ + run("techmap -wb -max_iter 1 -map %$abc9_map -map +/abc9_map.v"); 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 { - run("design -load $abc9"); - run("design -delete $abc9"); - run("select -unset $abc9_flops"); - } + else + run("techmap -wb -max_iter 1 -map +/abc9_map.v"); + } } if (check_label("pre")) { + run("read_verilog -icells -lib -specify +/abc9_model.v"); run("scc -set_attr abc9_scc_id {}"); if (help_mode) run("abc9_ops -mark_scc -prep_delays -prep_xaiger [-dff]", "(option for -dff)"); diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 62007c61e..976b6462e 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -128,7 +128,7 @@ void prep_dff_hier(RTLIL::Design *design) Design *unmap_design = new Design; - for (auto module : design->selected_modules()) + for (auto module : design->modules()) for (auto cell : module->cells()) { auto inst_module = design->module(cell->type); if (inst_module && inst_module->attributes.count(ID::abc9_flop)) { @@ -219,17 +219,23 @@ void prep_dff_map(RTLIL::Design *design) 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_)); + // Add dummy buffers for all module inputs/outputs + // to ensure that these ports exists in the flop box + // created by later submod pass + for (auto port_name : module->ports) { + auto port = module->wire(port_name); + log_assert(GetSize(port) == 1); + auto c = module->addBufGate(NEW_ID, port, module->addWire(NEW_ID)); + // Need to set (* keep *) otherwise opt_clean + // inside submod will blow it away + c->set_bool_attribute(ID::keep); + } + // Add an additional buffer that drives $_DFF_[NP]_.D + // so that the flop box will have an output 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); + auto c = module->addBufGate(NEW_ID, D, w); + c->set_bool_attribute(ID::keep); dff_cell->setPort(ID::D, w); D = w; } diff --git a/techlibs/common/Makefile.inc b/techlibs/common/Makefile.inc index 7b1e4b430..607e772a2 100644 --- a/techlibs/common/Makefile.inc +++ b/techlibs/common/Makefile.inc @@ -30,4 +30,6 @@ $(eval $(call add_share_file,share,techlibs/common/cmp2lut.v)) $(eval $(call add_share_file,share,techlibs/common/cells.lib)) $(eval $(call add_share_file,share,techlibs/common/mul2dsp.v)) $(eval $(call add_share_file,share,techlibs/common/abc9_model.v)) +$(eval $(call add_share_file,share,techlibs/common/abc9_map.v)) +$(eval $(call add_share_file,share,techlibs/common/abc9_unmap.v)) $(eval $(call add_share_file,share,techlibs/common/cmp2lcu.v)) diff --git a/techlibs/common/abc9_map.v b/techlibs/common/abc9_map.v new file mode 100644 index 000000000..b04a5b64f --- /dev/null +++ b/techlibs/common/abc9_map.v @@ -0,0 +1,21 @@ +(* techmap_celltype = "$_DFF_N_ $_DFF_P_" *) +module $_DFF_x_(input C, D, output Q); + parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx; + parameter _TECHMAP_CELLTYPE_ = ""; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + wire _TECHMAP_FAIL_ = 1; + else if (_TECHMAP_CELLTYPE_ == "$_DFF_N_") begin + wire D_; + $__DFF_N__$abc9_flop #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.C(C), .D(D), .Q(Q), .n1(D_)); + $_DFF_N_ ff (.C(C), .D(D_), .Q(Q)); + end + else if (_TECHMAP_CELLTYPE_ == "$_DFF_P_") begin + wire D_; + $__DFF_P__$abc9_flop #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.C(C), .D(D), .Q(Q), .n1(D_)); + $_DFF_P_ ff (.C(C), .D(D_), .Q(Q)); + end + else if (_TECHMAP_CELLTYPE_ != "") + $error("Unrecognised _TECHMAP_CELLTYPE_"); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1; +endmodule diff --git a/techlibs/common/abc9_model.v b/techlibs/common/abc9_model.v index 9e8048faf..41acf4d97 100644 --- a/techlibs/common/abc9_model.v +++ b/techlibs/common/abc9_model.v @@ -5,3 +5,23 @@ module \$__ABC9_DELAY (input I, output O); (I => O) = DELAY; endspecify endmodule + +(* abc9_flop, abc9_box, lib_whitebox *) +module $__DFF_N__$abc9_flop(input C, D, Q, (* init=INIT *) output n1); + parameter [0:0] INIT = 1'bx; + assign n1 = D; + specify + $setup(D, posedge C, 0); + (posedge C => (n1:D)) = 0; + endspecify +endmodule + +(* abc9_flop, abc9_box, lib_whitebox *) +module $__DFF_P__$abc9_flop(input C, D, Q, (* init=INIT *) output n1); + parameter [0:0] INIT = 1'bx; + assign n1 = D; + specify + $setup(D, posedge C, 0); + (posedge C => (n1:D)) = 0; + endspecify +endmodule diff --git a/techlibs/common/abc9_unmap.v b/techlibs/common/abc9_unmap.v new file mode 100644 index 000000000..0fd07207d --- /dev/null +++ b/techlibs/common/abc9_unmap.v @@ -0,0 +1,12 @@ +(* techmap_celltype = "$__DFF_N__$abc9_flop $__DFF_P__$abc9_flop" *) +module $__DFF_x__$abc9_flop (input C, D, Q, (* init = INIT *) output n1); + parameter [0:0] INIT = 1'bx; + parameter _TECHMAP_CELLTYPE_ = ""; + generate if (_TECHMAP_CELLTYPE_ == "$__DFF_N__$abc9_flop") + $_DFF_N_ _TECHMAP_REPLACE_ (.C(C), .D(D), .Q(Q)); + else if (_TECHMAP_CELLTYPE_ == "$__DFF_P__$abc9_flop") + $_DFF_P_ _TECHMAP_REPLACE_ (.C(C), .D(D), .Q(Q)); + else if (_TECHMAP_CELLTYPE_ != "") + $error("Unrecognised _TECHMAP_CELLTYPE_"); + endgenerate +endmodule diff --git a/tests/various/abc9.ys b/tests/various/abc9.ys index 6e2415ad7..7a3a503e4 100644 --- a/tests/various/abc9.ys +++ b/tests/various/abc9.ys @@ -45,14 +45,16 @@ sat -seq 10 -verify -prove-asserts -show-ports miter design -reset read_verilog -icells <<EOT module abc9_test036(input clk, d, output q); -(* keep *) reg w; -$__ABC9_FF_ ff(.D(d), .Q(w)); -wire \ff.clock = clk; -wire \ff.init = 1'b0; +(* keep, init=1'b0 *) wire w; +$_DFF_P_ ff(.C(clk), .D(d), .Q(w)); assign q = w; endmodule EOT -abc9 -lut 4 -dff +equiv_opt abc9 -lut 4 -dff +design -load postopt +cd abc9_test036 +select -assert-count 1 t:$_DFF_P_ +select -assert-none t:* t:$_DFF_P_ %d design -reset |