abc9 -keepff -> -dff; refactor dff operations
authorEddie Hung <eddie@fpgeh.com>
Thu, 2 Jan 2020 20:36:54 +0000 (12:36 -0800)
committerEddie Hung <eddie@fpgeh.com>
Thu, 2 Jan 2020 20:36:54 +0000 (12:36 -0800)
backends/aiger/xaiger.cc
passes/techmap/abc9.cc
techlibs/xilinx/abc9_map.v
techlibs/xilinx/synth_xilinx.cc

index 9c6152dff9b22951b4a2ef6f5969345e41f117d8..053f9d8359088b7546c578cb6feb18499968aba7 100644 (file)
@@ -82,7 +82,7 @@ struct XAigerWriter
        dict<SigBit, SigBit> not_map, alias_map;
        dict<SigBit, pair<SigBit, SigBit>> and_map;
        vector<SigBit> ci_bits, co_bits;
-       dict<SigBit, std::tuple<SigBit,int,int>> ff_bits;
+       dict<SigBit, Cell*> ff_bits;
        dict<SigBit, float> arrival_times;
 
        vector<pair<int, int>> aig_gates;
@@ -204,7 +204,6 @@ struct XAigerWriter
                dict<SigBit, pool<IdString>> bit_drivers, bit_users;
                TopoSort<IdString, RTLIL::sort_by_id_str> toposort;
                bool abc9_box_seen = false;
-               std::vector<Cell*> flop_boxes;
 
                for (auto cell : module->selected_cells()) {
                        if (cell->type == "$_NOT_")
@@ -236,14 +235,17 @@ struct XAigerWriter
                                continue;
                        }
 
-                       if (cell->type == "$__ABC9_FF_")
+                       if (cell->type == "$__ABC9_FF_" &&
+                                        // The presence of an abc9_mergeability attribute indicates
+                                        //   that we do want to pass this flop to ABC
+                                        cell->attributes.count("\\abc9_mergeability"))
                        {
                                SigBit D = sigmap(cell->getPort("\\D").as_bit());
                                SigBit Q = sigmap(cell->getPort("\\Q").as_bit());
                                unused_bits.erase(D);
                                undriven_bits.erase(Q);
                                alias_map[Q] = D;
-                               auto r = ff_bits.insert(std::make_pair(D, std::make_tuple(Q, 0, 2)));
+                               auto r YS_ATTRIBUTE(unused) = ff_bits.insert(std::make_pair(D, cell));
                                log_assert(r.second);
                                continue;
                        }
@@ -252,14 +254,25 @@ struct XAigerWriter
                        if (inst_module) {
                                bool abc9_box = inst_module->attributes.count("\\abc9_box_id");
                                bool abc9_flop = inst_module->get_bool_attribute("\\abc9_flop");
-                               // The lack of an abc9_mergeability attribute indicates that
-                               //   we do want to keep this flop, so do not treat it as a box
-                               if (abc9_flop && !cell->attributes.count("\\abc9_mergeability"))
+                               if (abc9_box && cell->get_bool_attribute("\\abc9_keep"))
                                        abc9_box = false;
 
                                for (const auto &conn : cell->connections()) {
                                        auto port_wire = inst_module->wire(conn.first);
 
+                                       if (abc9_box) {
+                                               // Ignore inout for the sake of topographical ordering
+                                               if (port_wire->port_input && !port_wire->port_output)
+                                                       for (auto bit : sigmap(conn.second))
+                                                               bit_users[bit].insert(cell->name);
+                                               if (port_wire->port_output)
+                                                       for (auto bit : sigmap(conn.second))
+                                                               bit_drivers[bit].insert(cell->name);
+
+                                               if (!abc9_flop)
+                                                       continue;
+                                       }
+
                                        if (port_wire->port_output) {
                                                int arrival = 0;
                                                auto it = port_wire->attributes.find("\\abc9_arrival");
@@ -272,25 +285,11 @@ struct XAigerWriter
                                                        for (auto bit : sigmap(conn.second))
                                                                arrival_times[bit] = arrival;
                                        }
-
-                                       if (abc9_box) {
-                                               // Ignore inout for the sake of topographical ordering
-                                               if (port_wire->port_input && !port_wire->port_output)
-                                                       for (auto bit : sigmap(conn.second))
-                                                               bit_users[bit].insert(cell->name);
-                                               if (port_wire->port_output)
-                                                       for (auto bit : sigmap(conn.second))
-                                                               bit_drivers[bit].insert(cell->name);
-                                       }
                                }
 
                                if (abc9_box) {
                                        abc9_box_seen = true;
-
                                        toposort.node(cell->name);
-
-                                       if (abc9_flop)
-                                               flop_boxes.push_back(cell);
                                        continue;
                                }
                        }
@@ -321,61 +320,6 @@ struct XAigerWriter
                }
 
                if (abc9_box_seen) {
-                       dict<IdString, std::pair<IdString,int>> flop_q;
-                       for (auto cell : flop_boxes) {
-                               auto r = flop_q.insert(std::make_pair(cell->type, std::make_pair(IdString(), 0)));
-                               SigBit d;
-                               if (r.second) {
-                                       for (const auto &conn : cell->connections()) {
-                                               if (!conn.second.is_bit())
-                                                       continue;
-                                               d = conn.second;
-                                               if (!ff_bits.count(d))
-                                                       continue;
-
-                                               r.first->second.first = conn.first;
-                                               Module *inst_module = module->design->module(cell->type);
-                                               Wire *wire = inst_module->wire(conn.first);
-                                               log_assert(wire);
-                                               auto jt = wire->attributes.find("\\abc9_arrival");
-                                               if (jt != wire->attributes.end()) {
-                                                       if (jt->second.flags != 0)
-                                                               log_error("Attribute 'abc9_arrival' on port '%s' of module '%s' is not an integer.\n", log_id(wire), log_id(cell->type));
-                                                       r.first->second.second = jt->second.as_int();
-                                               }
-                                               log_assert(d == sigmap(d));
-                                               break;
-                                       }
-                               }
-                               else
-                                       d = cell->getPort(r.first->second.first);
-
-                               auto &rhs = ff_bits.at(d);
-
-                               auto it = cell->attributes.find(ID(abc9_mergeability));
-                               log_assert(it != cell->attributes.end());
-                               std::get<1>(rhs) = it->second.as_int();
-                               cell->attributes.erase(it);
-
-                               it = cell->attributes.find(ID(abc9_init));
-                               log_assert(it != cell->attributes.end());
-                               log_assert(GetSize(it->second) == 1);
-                               if (it->second[0] == State::S1)
-                                       std::get<2>(rhs) = 1;
-                               else if (it->second[0] == State::S0)
-                                       std::get<2>(rhs) = 0;
-                               else {
-                                       log_assert(it->second[0] == State::Sx);
-                                       std::get<2>(rhs) = 0;
-                               }
-                               cell->attributes.erase(it);
-
-                               const SigBit &q = std::get<0>(rhs);
-                               auto arrival = r.first->second.second;
-                               if (arrival)
-                                       arrival_times[q] = arrival;
-                       }
-
                        for (auto &it : bit_users)
                                if (bit_drivers.count(it.first))
                                        for (auto driver_cell : bit_drivers.at(it.first))
@@ -501,11 +445,11 @@ struct XAigerWriter
                                        }
                                }
 
-                               // Connect <cell>.$abc9_currQ (inserted by abc9_map.v) as an input to the flop box
+                               // Connect <cell>.abc9_ff.Q (inserted by abc9_map.v) as the last input to the flop box
                                if (box_module->get_bool_attribute("\\abc9_flop")) {
-                                       SigSpec rhs = module->wire(stringf("%s.$abc9_currQ", cell->name.c_str()));
+                                       SigSpec rhs = module->wire(stringf("%s.abc9_ff.Q", cell->name.c_str()));
                                        if (rhs.empty())
-                                               log_error("'%s.$abc9_currQ' is not a wire present in module '%s'.\n", log_id(cell), log_id(module));
+                                               log_error("'%s.abc9_ff.Q' is not a wire present in module '%s'.\n", log_id(cell), log_id(module));
 
                                        for (auto b : rhs) {
                                                SigBit I = sigmap(b);
@@ -553,7 +497,8 @@ struct XAigerWriter
                }
 
                for (const auto &i : ff_bits) {
-                       const SigBit &q = std::get<0>(i.second);
+                       const Cell *cell = i.second;
+                       const SigBit &q = sigmap(cell->getPort("\\Q"));
                        aig_m++, aig_i++;
                        log_assert(!aig_map.count(q));
                        aig_map[q] = 2*aig_m;
@@ -742,7 +687,7 @@ struct XAigerWriter
                                }
 
                                // For flops only, create an extra 1-bit input that drives a new wire
-                               //   called "<cell>.$abc9_currQ" that is used below
+                               //   called "<cell>.abc9_ff.Q" that is used below
                                if (box_module->get_bool_attribute("\\abc9_flop")) {
                                        log_assert(holes_cell);
 
@@ -754,7 +699,8 @@ struct XAigerWriter
                                                holes_wire->port_id = port_id++;
                                                holes_module->ports.push_back(holes_wire->name);
                                        }
-                                       Wire *w = holes_module->addWire(stringf("%s.$abc9_currQ", cell->name.c_str()));
+                                       Wire *w = holes_module->addWire(stringf("%s.abc9_ff.Q", cell->name.c_str()));
+                                       log_assert(w);
                                        holes_module->connect(w, holes_wire);
                                }
 
@@ -774,13 +720,25 @@ struct XAigerWriter
                        write_s_buffer(ff_bits.size());
 
                        for (const auto &i : ff_bits) {
-                               const SigBit &q = std::get<0>(i.second);
-                               int mergeability = std::get<1>(i.second);
+                               const SigBit &d = i.first;
+                               const Cell *cell = i.second;
+
+                               int mergeability = cell->attributes.at(ID(abc9_mergeability)).as_int();
                                log_assert(mergeability > 0);
                                write_r_buffer(mergeability);
-                               int init = std::get<2>(i.second);
-                               write_s_buffer(init);
-                               write_i_buffer(arrival_times.at(q, 0));
+
+                               Const init = cell->attributes.at(ID(abc9_init));
+                               log_assert(GetSize(init) == 1);
+                               if (init == State::S1)
+                                       write_s_buffer(1);
+                               else if (init == State::S0)
+                                       write_s_buffer(0);
+                               else {
+                                       log_assert(init == State::Sx);
+                                       write_s_buffer(0);
+                               }
+
+                               write_i_buffer(arrival_times.at(d, 0));
                                //write_o_buffer(0);
                        }
 
@@ -833,9 +791,9 @@ struct XAigerWriter
                                                log_assert(pos != std::string::npos);
                                                IdString driver = Q.wire->name.substr(0, pos);
                                                // And drive the signal that was previously driven by "DFF.Q" (typically
-                                               //   used to implement clock-enable functionality) with the "<cell>.$abc9_currQ"
+                                               //   used to implement clock-enable functionality) with the "<cell>.abc9_ff.Q"
                                                //   wire (which itself is driven an input port) we inserted above
-                                               Wire *currQ = holes_module->wire(stringf("%s.$abc9_currQ", driver.c_str()));
+                                               Wire *currQ = holes_module->wire(stringf("%s.abc9_ff.Q", driver.c_str()));
                                                log_assert(currQ);
                                                holes_module->connect(Q, currQ);
                                                continue;
index c3c8e0dbc1ce89f89c71d727a7af7dd95d56b238..6aa0b6f95ca076d42747b9a5388bba26f0a59c63 100644 (file)
@@ -249,7 +249,7 @@ struct abc9_output_filter
 };
 
 void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string script_file, std::string exe_file,
-               bool cleanup, vector<int> lut_costs, bool keepff, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode,
+               bool cleanup, vector<int> lut_costs, bool dff, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode,
                bool show_tempdir, std::string box_file, std::string lut_file,
                std::string wire_delay, bool nomfs
 )
@@ -347,7 +347,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip
                buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym");
                log_assert(!design->module(ID($__abc9__)));
                {
-                       AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */);
+                       AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, /*buffer.c_str()*/ "" /* map_filename */, true /* wideports */);
                        reader.parse_xaiger();
                }
                ifs.close();
@@ -430,7 +430,13 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip
                        if (jt == abc9_box.end())
                                jt = abc9_box.insert(std::make_pair(cell->type, box_module && box_module->attributes.count(ID(abc9_box_id)))).first;
                        if (jt->second) {
-                               if (!keepff || !box_module->get_bool_attribute("\\abc9_flop"))
+                               if (box_module->get_bool_attribute("\\abc9_flop")) {
+                                       if (dff)
+                                               boxes.emplace_back(cell);
+                                       else
+                                               box_module->set_bool_attribute("\\abc9_keep", false);
+                               }
+                               else
                                        boxes.emplace_back(cell);
                        }
                }
@@ -795,9 +801,9 @@ struct Abc9Pass : public Pass {
                log("        generate netlist using luts. Use the specified costs for luts with 1,\n");
                log("        2, 3, .. inputs.\n");
                log("\n");
-               log("    -keepff\n");
-               log("        do not represent (* abc9_flop *) modules as boxes (and thus do not perform\n");
-               log("        any form of sequential synthesis).\n");
+               log("    -dff\n");
+               log("        also pass $_ABC9_FF_ cells through ABC. modules with many clock domains\n");
+               log("        are marked as such and automatically partitioned by ABC.\n");
                log("\n");
                log("    -nocleanup\n");
                log("        when this option is used, the temporary files created by this pass\n");
@@ -837,7 +843,7 @@ struct Abc9Pass : public Pass {
 #endif
                std::string script_file, clk_str, box_file, lut_file;
                std::string delay_target, lutin_shared = "-S 1", wire_delay;
-               bool fast_mode = false, keepff = false, cleanup = true;
+               bool fast_mode = false, dff = false, cleanup = true;
                bool show_tempdir = false;
                bool nomfs = false;
                vector<int> lut_costs;
@@ -928,8 +934,8 @@ struct Abc9Pass : public Pass {
                                fast_mode = true;
                                continue;
                        }
-                       if (arg == "-keepff") {
-                               keepff = true;
+                       if (arg == "-dff") {
+                               dff = true;
                                continue;
                        }
                        if (arg == "-nocleanup") {
@@ -985,16 +991,14 @@ struct Abc9Pass : public Pass {
                        typedef SigSpec clkdomain_t;
                        dict<clkdomain_t, int> clk_to_mergeability;
 
-
-                       if (!keepff)
+                       if (dff)
                                for (auto cell : module->selected_cells()) {
-                                       auto inst_module = design->module(cell->type);
-                                       if (!inst_module || !inst_module->get_bool_attribute("\\abc9_flop"))
+                                       if (cell->type != "$__ABC9_FF_")
                                                continue;
 
-                                       Wire *abc9_clock_wire = module->wire(stringf("%s.$abc9_clock", cell->name.c_str()));
+                                       Wire *abc9_clock_wire = module->wire(stringf("%s.clock", cell->name.c_str()));
                                        if (abc9_clock_wire == NULL)
-                                               log_error("'%s$abc9_clock' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module));
+                                               log_error("'%s.clock' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module));
                                        SigSpec abc9_clock = assign_map(abc9_clock_wire);
 
                                        clkdomain_t key(abc9_clock);
@@ -1003,19 +1007,26 @@ struct Abc9Pass : public Pass {
                                        auto r2 YS_ATTRIBUTE(unused) = cell->attributes.insert(std::make_pair(ID(abc9_mergeability), r.first->second));
                                        log_assert(r2.second);
 
-                                       Wire *abc9_init_wire = module->wire(stringf("%s.$abc9_init", cell->name.c_str()));
+                                       Wire *abc9_init_wire = module->wire(stringf("%s.init", cell->name.c_str()));
                                        if (abc9_init_wire == NULL)
-                                               log_error("'%s.$abc9_init' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module));
+                                               log_error("'%s.init' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module));
                                        log_assert(GetSize(abc9_init_wire) == 1);
                                        SigSpec abc9_init = assign_map(abc9_init_wire);
                                        if (!abc9_init.is_fully_const())
-                                               log_error("'%s.$abc9_init' is not a constant wire present in module '%s'.\n", cell->name.c_str(), log_id(module));
+                                               log_error("'%s.init' is not a constant wire present in module '%s'.\n", cell->name.c_str(), log_id(module));
                                        r2 = cell->attributes.insert(std::make_pair(ID(abc9_init), abc9_init.as_const()));
                                        log_assert(r2.second);
                                }
+                       else
+                               for (auto cell : module->selected_cells()) {
+                                       auto inst_module = design->module(cell->type);
+                                       if (!inst_module || !inst_module->get_bool_attribute("\\abc9_flop"))
+                                               continue;
+                                       cell->set_bool_attribute("\\abc9_keep");
+                               }
 
                        design->selected_active_module = module->name.str();
-                       abc9_module(design, module, script_file, exe_file, cleanup, lut_costs, keepff,
+                       abc9_module(design, module, script_file, exe_file, cleanup, lut_costs, dff,
                                        delay_target, lutin_shared, fast_mode, show_tempdir,
                                        box_file, lut_file, wire_delay, nomfs);
                        design->selected_active_module.clear();
index 1b58c34c030f68d3fdbfb9acf90ec7bf019d3ea5..1d37952f582f985d9f853ccedc170bf00d63376e 100644 (file)
 //                ||                  ||
 //                ||      /\/\/\/\    ||
 //           D  -->>-----<        >   ||
-//           R  -->>-----<  Comb. >   ||        +----------+
-//          CE  -->>-----<  logic >--->>-- $Q --|$__ABC_FF_|--+-->> Q
-// $abc9_currQ +-->>-----<        >   ||        +----------+  |
-//             |  ||      \/\/\/\/    ||                      |
-//             |  ||                  ||                      |
-//             |  ++==================++                      |
-//             |                                              |
-//             +----------------------------------------------+
+//           R  -->>-----<  Comb. >   ||        +-----------+
+//          CE  -->>-----<  logic >--->>-- $Q --|$__ABC9_FF_|--+-->> Q
+//   abc9_ff.Q +-->>-----<        >   ||        +-----------+  |
+//             |  ||      \/\/\/\/    ||                       |
+//             |  ||                  ||                       |
+//             |  ++==================++                       |
+//             |                                               |
+//             +-----------------------------------------------+
 //
 // The purpose of the following FD* rules are to wrap the flop with:
 // (a) a special $__ABC9_FF_ in front of the FD*'s output, indicating to abc9
 //     the connectivity of its basic D-Q flop
 // (b) an optional $__ABC9_ASYNC_ cell in front of $__ABC_FF_'s output to
 //     capture asynchronous behaviour
-// (c) a special _TECHMAP_REPLACE_.$abc9_clock wire to capture its clock
+// (c) a special _TECHMAP_REPLACE_.abc9_ff.clock wire to capture its clock
 //     domain and polarity (used when partitioning the module so that `abc9' only
 //     performs sequential synthesis (with reachability analysis) correctly on
 //     one domain at a time) and also used to infer the optional delay target
 //     from the (* abc9_clock_period = %d *) attribute attached to any wire
 //     within
-// (d) a special _TECHMAP_REPLACE_.$abc9_init wire to encode the flop's initial
+// (d) a special _TECHMAP_REPLACE_.abc9_ff.init wire to encode the flop's initial
 //     state
-// (e) a special _TECHMAP_REPLACE_.$abc9_currQ wire that will be used for feedback
+// (e) a special _TECHMAP_REPLACE_.abc9_ff.Q wire that will be used for feedback
 //     into the (combinatorial) FD* cell to facilitate clock-enable behaviour
 //
 // In order to perform sequential synthesis, `abc9' also requires that
@@ -108,12 +108,12 @@ module FDRE (output Q, input C, CE, D, R);
     );
   end
   endgenerate
-  $__ABC9_FF_ abc_dff (.D($Q), .Q(QQ));
+  $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
 
   // Special signals
-  wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED};
-  wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0;
-  wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ;
+  wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
+  wire [0:0] abc9_ff.init = 1'b0;
+  wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
 endmodule
 module FDRE_1 (output Q, input C, CE, D, R);
   parameter [0:0] INIT = 1'b0;
@@ -135,12 +135,12 @@ module FDRE_1 (output Q, input C, CE, D, R);
     );
   end
   endgenerate
-  $__ABC9_FF_ abc_dff (.D($Q), .Q(QQ));
+  $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
 
   // Special signals
-  wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */};
-  wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0;
-  wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ;
+  wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
+  wire [0:0] abc9_ff.init = 1'b0;
+  wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
 endmodule
 
 module FDSE (output Q, input C, CE, D, S);
@@ -171,12 +171,12 @@ module FDSE (output Q, input C, CE, D, S);
       .D(D), .Q($Q), .C(C), .CE(CE), .S(S)
     );
   end endgenerate
-  $__ABC9_FF_ abc_dff (.D($Q), .Q(QQ));
+  $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
 
   // Special signals
-  wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED};
-  wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0;
-  wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ;
+  wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
+  wire [0:0] abc9_ff.init = 1'b0;
+  wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
 endmodule
 module FDSE_1 (output Q, input C, CE, D, S);
   parameter [0:0] INIT = 1'b1;
@@ -197,12 +197,12 @@ module FDSE_1 (output Q, input C, CE, D, S);
       .D(D), .Q($Q), .C(C), .CE(CE), .S(S)
     );
   end endgenerate
-  $__ABC9_FF_ abc_dff (.D($Q), .Q(QQ));
+  $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
 
   // Special signals
-  wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */};
-  wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0;
-  wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ;
+  wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
+  wire [0:0] abc9_ff.init = 1'b0;
+  wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
 endmodule
 
 module FDCE (output Q, input C, CE, D, CLR);
@@ -210,7 +210,7 @@ module FDCE (output Q, input C, CE, D, CLR);
   parameter [0:0] IS_C_INVERTED = 1'b0;
   parameter [0:0] IS_D_INVERTED = 1'b0;
   parameter [0:0] IS_CLR_INVERTED = 1'b0;
-  wire QQ, $Q, $abc9_currQ;
+  wire QQ, $Q, $QQ;
   generate if (INIT == 1'b1) begin
     assign Q = ~QQ;
     FDPE #(
@@ -227,7 +227,7 @@ module FDCE (output Q, input C, CE, D, CLR);
                                             //     $__ABC9_ASYNC1 below
     );
     // Since this is an async flop, async behaviour is dealt with here
-    $__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ));
+    $__ABC9_ASYNC1 abc_async (.A($QQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ));
   end
   else begin
     assign Q = QQ;
@@ -245,18 +245,18 @@ module FDCE (output Q, input C, CE, D, CLR);
                                            //     $__ABC9_ASYNC0 below
     );
     // Since this is an async flop, async behaviour is dealt with here
-    $__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ));
+    $__ABC9_ASYNC0 abc_async (.A($QQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ));
   end endgenerate
-  $__ABC9_FF_ abc_dff (.D($Q), .Q($abc9_currQ));
+  $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
 
   // Special signals
-  wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED};
-  wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0;
-  wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ;
+  wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
+  wire [0:0] abc9_ff.init = 1'b0;
+  wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
 endmodule
 module FDCE_1 (output Q, input C, CE, D, CLR);
   parameter [0:0] INIT = 1'b0;
-  wire QQ, $Q, $abc9_currQ;
+  wire QQ, $Q, $QQ;
   generate if (INIT == 1'b1) begin
     assign Q = ~QQ;
     FDPE_1 #(
@@ -269,7 +269,7 @@ module FDCE_1 (output Q, input C, CE, D, CLR);
                                             //     behaviour is captured by
                                             //     $__ABC9_ASYNC1 below
     );
-    $__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(CLR), .Y(QQ));
+    $__ABC9_ASYNC1 abc_async (.A($QQ), .S(CLR), .Y(QQ));
   end
   else begin
     assign Q = QQ;
@@ -283,14 +283,14 @@ module FDCE_1 (output Q, input C, CE, D, CLR);
                                            //     behaviour is captured by
                                            //     $__ABC9_ASYNC0 below
     );
-    $__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(CLR), .Y(QQ));
+    $__ABC9_ASYNC0 abc_async (.A($QQ), .S(CLR), .Y(QQ));
   end endgenerate
-  $__ABC9_FF_ abc_dff (.D($Q), .Q($abc9_currQ));
+  $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
 
   // Special signals
-  wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */};
-  wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0;
-  wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ;
+  wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
+  wire [0:0] abc9_ff.init = 1'b0;
+  wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
 endmodule
 
 module FDPE (output Q, input C, CE, D, PRE);
@@ -298,7 +298,7 @@ module FDPE (output Q, input C, CE, D, PRE);
   parameter [0:0] IS_C_INVERTED = 1'b0;
   parameter [0:0] IS_D_INVERTED = 1'b0;
   parameter [0:0] IS_PRE_INVERTED = 1'b0;
-  wire QQ, $Q, $abc9_currQ;
+  wire QQ, $Q, $QQ;
   generate if (INIT == 1'b1) begin
     assign Q = ~QQ;
     FDCE #(
@@ -314,7 +314,7 @@ module FDPE (output Q, input C, CE, D, PRE);
                                             //     behaviour is captured by
                                             //     $__ABC9_ASYNC0 below
     );
-    $__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ));
+    $__ABC9_ASYNC0 abc_async (.A($QQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ));
   end
   else begin
     assign Q = QQ;
@@ -331,18 +331,18 @@ module FDPE (output Q, input C, CE, D, PRE);
                                            //     behaviour is captured by
                                            //     $__ABC9_ASYNC1 below
     );
-    $__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ));
+    $__ABC9_ASYNC1 abc_async (.A($QQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ));
   end endgenerate
-  $__ABC9_FF_ abc_dff (.D($Q), .Q($abc9_currQ));
+  $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
 
   // Special signals
-  wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED};
-  wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0;
-  wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ;
+  wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
+  wire [0:0] abc9_ff.init = 1'b0;
+  wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
 endmodule
 module FDPE_1 (output Q, input C, CE, D, PRE);
   parameter [0:0] INIT = 1'b1;
-  wire QQ, $Q, $abc9_currQ;
+  wire QQ, $Q, $QQ;
   generate if (INIT == 1'b1) begin
     assign Q = ~QQ;
     FDCE_1 #(
@@ -355,7 +355,7 @@ module FDPE_1 (output Q, input C, CE, D, PRE);
                                             //     behaviour is captured by
                                             //     $__ABC9_ASYNC0 below
     );
-    $__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(PRE), .Y(QQ));
+    $__ABC9_ASYNC0 abc_async (.A($QQ), .S(PRE), .Y(QQ));
   end
   else begin
     assign Q = QQ;
@@ -369,14 +369,14 @@ module FDPE_1 (output Q, input C, CE, D, PRE);
                                            //     behaviour is captured by
                                            //     $__ABC9_ASYNC1 below
     );
-    $__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(PRE), .Y(QQ));
+    $__ABC9_ASYNC1 abc_async (.A($QQ), .S(PRE), .Y(QQ));
   end endgenerate
-  $__ABC9_FF_ abc_dff (.D($Q), .Q($abc9_currQ));
+  $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
 
   // Special signals
-  wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */};
-  wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0;
-  wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ;
+  wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
+  wire [0:0] abc9_ff.init = 1'b0;
+  wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
 endmodule
 `endif
 
index 10aa7be5f5dbb93fc383b54b794493ff6ad53e4f..af9f21756fd6f6122b939855d9c58fc3ab44464c 100644 (file)
@@ -108,7 +108,7 @@ struct SynthXilinxPass : public ScriptPass
                log("        flatten design before synthesis\n");
                log("\n");
                log("    -dff\n");
-               log("        enable sequential synthesis with 'abc9'\n");
+               log("        run 'abc9' with -dff option\n");
                log("\n");
                log("    -retime\n");
                log("        run 'abc' with -dff option\n");
@@ -559,8 +559,8 @@ struct SynthXilinxPass : public ScriptPass
                                        abc9_opts += " -lut +/xilinx/abc9_xc7_nowide.lut";
                                else
                                        abc9_opts += " -lut +/xilinx/abc9_xc7.lut";
-                               if (!dff_mode)
-                                       abc9_opts += " -keepff";
+                               if (dff_mode)
+                                       abc9_opts += " -dff";
                                run("abc9" + abc9_opts);
                                run("techmap -map +/xilinx/abc9_unmap.v");
                        }