}
}
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)");
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)) {
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;
}
$(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))
--- /dev/null
+(* 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
(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
--- /dev/null
+(* 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
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