abc9: add flop boxes to basic $_DFF_P_ and $_DFF_N_ too
authorEddie Hung <eddie@fpgeh.com>
Thu, 16 Apr 2020 17:24:02 +0000 (10:24 -0700)
committerEddie Hung <eddie@fpgeh.com>
Thu, 14 May 2020 17:33:56 +0000 (10:33 -0700)
passes/techmap/abc9.cc
passes/techmap/abc9_ops.cc
techlibs/common/Makefile.inc
techlibs/common/abc9_map.v [new file with mode: 0644]
techlibs/common/abc9_model.v
techlibs/common/abc9_unmap.v [new file with mode: 0644]
tests/various/abc9.ys

index fbb8356a5b65ed2a8ca22ff37f9a0d8825130bb7..911254aa6f71db7821fab48656bba1a2d6de58b7 100644 (file)
@@ -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)");
index 62007c61e7be624abf834f0d862191920da7fa63..976b6462ec5b661dc6d5a16ea822b3ae2fe65ca1 100644 (file)
@@ -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;
                }
index 7b1e4b43053db231fceec463caeb95e201232e5c..607e772a2289f9de1d5f1157938d4b4b9c9907ff 100644 (file)
@@ -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 (file)
index 0000000..b04a5b6
--- /dev/null
@@ -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
index 9e8048fafc650d150048750e158a0312248d81a2..41acf4d9776b7af3eb13092b946d861efc326ac3 100644 (file)
@@ -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 (file)
index 0000000..0fd0720
--- /dev/null
@@ -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
index 6e2415ad79450e559862fc65333092d5eb026d2b..7a3a503e4754c6e44205a0fbbbf53e1f44c328c7 100644 (file)
@@ -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