Added expose -dff
authorClifford Wolf <clifford@clifford.at>
Thu, 6 Feb 2014 14:48:42 +0000 (15:48 +0100)
committerClifford Wolf <clifford@clifford.at>
Thu, 6 Feb 2014 14:48:42 +0000 (15:48 +0100)
passes/sat/expose.cc

index ac87e5a170203cb66da47a37fc7b4221570516b6..f840122844d38a9b793a9b8957a87704aed06a7e 100644 (file)
@@ -18,6 +18,8 @@
  */
 
 #include "kernel/register.h"
+#include "kernel/celltypes.h"
+#include "kernel/sigtools.h"
 #include "kernel/rtlil.h"
 #include "kernel/log.h"
 
@@ -57,6 +59,26 @@ static bool compare_cells(RTLIL::Cell *cell1, RTLIL::Cell *cell2)
        return true;
 }
 
+static void find_dff_wires(std::set<std::string> &dff_wires, RTLIL::Module *module)
+{
+       CellTypes ct;
+       ct.setup_internals_mem();
+       ct.setup_stdcells_mem();
+
+       SigMap sigmap(module);
+       SigPool dffsignals;
+
+       for (auto &it : module->cells) {
+               if (ct.cell_known(it.second->type) && it.second->connections.count("\\Q"))
+                       dffsignals.add(sigmap(it.second->connections.at("\\Q")));
+       }
+
+       for (auto &it : module->wires) {
+               if (dffsignals.check_any(it.second))
+                       dff_wires.insert(it.first);
+       }
+}
+
 struct ExposePass : public Pass {
        ExposePass() : Pass("expose", "convert internal signals to module ports") { }
        virtual void help()
@@ -68,6 +90,9 @@ struct ExposePass : public Pass {
                log("This command exposes all selected internal signals of a module as additional\n");
                log("outputs.\n");
                log("\n");
+               log("    -dff\n");
+               log("        only consider wires that are directly driven by register cell.\n");
+               log("\n");
                log("    -shared\n");
                log("        only expose those signals that are shared ammong the selected modules.\n");
                log("        this is useful for preparing modules for equivialence checking.\n");
@@ -81,6 +106,7 @@ struct ExposePass : public Pass {
        {
                bool flag_shared = false;
                bool flag_evert = false;
+               bool flag_dff = false;
 
                size_t argidx;
                for (argidx = 1; argidx < args.size(); argidx++)
@@ -93,6 +119,10 @@ struct ExposePass : public Pass {
                                flag_evert = true;
                                continue;
                        }
+                       if (args[argidx] == "-dff") {
+                               flag_dff = true;
+                               continue;
+                       }
                        break;
                }
                extra_args(args, argidx, design);
@@ -111,11 +141,16 @@ struct ExposePass : public Pass {
                                if (!design->selected(module))
                                        continue;
 
+                               std::set<std::string> dff_wires;
+                               if (flag_dff)
+                                       find_dff_wires(dff_wires, module);
+
                                if (first_module == NULL)
                                {
                                        for (auto &it : module->wires)
                                                if (design->selected(module, it.second) && consider_wire(it.second))
-                                                       shared_wires.insert(it.first);
+                                                       if (!flag_dff || dff_wires.count(it.first))
+                                                               shared_wires.insert(it.first);
 
                                        if (flag_evert)
                                                for (auto &it : module->cells)
@@ -143,6 +178,8 @@ struct ExposePass : public Pass {
                                                        goto delete_shared_wire;
                                                if (!compare_wires(first_module->wires.at(it), wire))
                                                        goto delete_shared_wire;
+                                               if (flag_dff && !dff_wires.count(it))
+                                                       goto delete_shared_wire;
 
                                                if (0)
                                        delete_shared_wire:
@@ -186,6 +223,10 @@ struct ExposePass : public Pass {
                        if (!design->selected(module))
                                continue;
 
+                       std::set<std::string> dff_wires;
+                       if (flag_dff && !flag_shared)
+                               find_dff_wires(dff_wires, module);
+
                        for (auto &it : module->wires)
                        {
                                if (flag_shared) {
@@ -194,6 +235,8 @@ struct ExposePass : public Pass {
                                } else {
                                        if (!design->selected(module, it.second) || !consider_wire(it.second))
                                                continue;
+                                       if (flag_dff && !dff_wires.count(it.first))
+                                               continue;
                                }
 
                                if (!it.second->port_output) {