abc9: rework submod -- since it won't move (* keep *) cells
authorEddie Hung <eddie@fpgeh.com>
Wed, 22 Apr 2020 00:25:15 +0000 (17:25 -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

index 93751e0bca26c9296771900a5f7ae29842faf10d..147d6e572d417226a85cded8b8161983f56dcbf9 100644 (file)
@@ -309,9 +309,6 @@ struct Abc9Pass : public ScriptPass
                                        run("setattr -set submod \"$abc9_flop\" t:$_DFF_?_ %ci* %co* t:$_DFF_?_ %d", "       (only if -dff)");
                                        run("submod", "                                                                    (only if -dff)");
                                        run("setattr -mod -set whitebox 1 -set abc9_flop 1 -set abc9_box 1 *_$abc9_flop", "(only if -dff)");
-                                       run("abc9_ops -prep_dff_unmap", "                                                  (only if -dff)");
-                                       run("design -copy-to $abc9 *_$abc9_flop", "                                        (only if -dff)"); // copy submod out
-                                       run("delete *_$abc9_flop", "                                                       (only if -dff)");
                                        if (help_mode) {
                                                run("foreach module in design");
                                                run("    rename <module-name>_$abc9_flop _TECHMAP_REPLACE_", "                     (only if -dff)");
@@ -323,7 +320,11 @@ struct Abc9Pass : public ScriptPass
                                                        if (module->cell(stringf("%s_$abc9_flop", module->name.c_str())))
                                                                run(stringf("rename %s_$abc9_flop _TECHMAP_REPLACE_", module->name.c_str()));
                                                }
+                                               active_design->selected_active_module.clear();
                                        }
+                                       run("abc9_ops -prep_dff_unmap", "                                                  (only if -dff)");
+                                       run("design -copy-to $abc9 *_$abc9_flop", "                                        (only if -dff)"); // copy submod out
+                                       run("delete *_$abc9_flop", "                                                       (only if -dff)");
                                }
                        }
                        run("design -stash $abc9_map");
index b3f5b991934c9db7b58bfb5f80fe590b7a138fe4..5521bdf621264f5522b8bcb7ee6d015b2014b0fc 100644 (file)
@@ -474,22 +474,11 @@ void prep_dff_submod(RTLIL::Design *design)
                                specify_cells.emplace_back(cell);
                log_assert(dff_cell);
 
-               // 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
+               // Add an always-enabled CE mux that drives $_DFF_[NP]_.D so that:
+               //   (a) flop box will have an output
+               //   (b) $_DFF_[NP]_.Q will be present as an input
                SigBit D = module->addWire(NEW_ID);
-               Cell *c = module->addBufGate(NEW_ID, dff_cell->getPort(ID::D), D);
-               c->set_bool_attribute(ID::keep);
+               module->addMuxGate(NEW_ID, dff_cell->getPort(ID::D), Q, State::S0, D);
                dff_cell->setPort(ID::D, D);
 
                // Rewrite $specify cells that end with $_DFF_[NP]_.Q
@@ -513,26 +502,31 @@ void prep_dff_unmap(RTLIL::Design *design)
                if (!module->get_bool_attribute(ID::abc9_flop) || module->get_bool_attribute(ID::abc9_box))
                        continue;
 
-               auto unmap_module = unmap_design->addModule(module->name.str() + "_$abc9_flop");
-               auto replace_cell = unmap_module->addCell(ID::_TECHMAP_REPLACE_, module->name);
+               // Make sure the box module has all the same ports present on flop cell
+               auto replace_cell = module->cell(ID::_TECHMAP_REPLACE_);
+               log_assert(replace_cell);
+               auto box_module = design->module(module->name.str() + "_$abc9_flop");
+               log_assert(box_module);
                for (auto port_name : module->ports) {
-                       auto w = unmap_module->addWire(port_name, module->wire(port_name));
-                       // Do not propagate (* init *) values inside the box
-                       if (w->port_output)
-                               w->attributes.erase(ID::init);
-                       replace_cell->setPort(port_name, w);
+                       auto port = module->wire(port_name);
+                       auto box_port = box_module->wire(port_name);
+                       if (box_port) {
+                               // Do not propagate init -- already captured by box
+                               box_port->attributes.erase(ID::init);
+                               continue;
+                       }
+                       log_assert(port->port_input);
+                       box_module->addWire(port_name, port);
+                       replace_cell->setPort(port_name, port);
                }
+               box_module->fixup_ports();
 
-               // Add new ports appearing in "_$abc9_flop"
-               auto box_module = design->module(unmap_module->name);
-               log_assert(box_module);
+               auto unmap_module = unmap_design->addModule(box_module->name);
+               replace_cell = unmap_module->addCell(ID::_TECHMAP_REPLACE_, module->name);
                for (auto port_name : box_module->ports) {
-                       auto port = box_module->wire(port_name);
-                       auto unmap_port = unmap_module->wire(port_name);
-                       if (!unmap_port)
-                               unmap_port = unmap_module->addWire(port_name, port);
-                       else
-                               unmap_port->port_id = port->port_id;
+                       auto w = unmap_module->addWire(port_name, box_module->wire(port_name));
+                       if (module->wire(port_name))
+                               replace_cell->setPort(port_name, w);
                }
                unmap_module->ports = box_module->ports;
                unmap_module->check();