Use input default values in hierarchy pass
authorClifford Wolf <clifford@clifford.at>
Wed, 19 Jun 2019 09:49:20 +0000 (11:49 +0200)
committerClifford Wolf <clifford@clifford.at>
Wed, 19 Jun 2019 09:49:20 +0000 (11:49 +0200)
Signed-off-by: Clifford Wolf <clifford@clifford.at>
passes/hierarchy/hierarchy.cc

index 24e64a9b28f4451a45db28c8827c1b7d02026f5d..213437c01e3077f5dabb14a077a335911a4e2afb 100644 (file)
@@ -591,6 +591,9 @@ struct HierarchyPass : public Pass {
                log("        module instances when the width does not match the module port. This\n");
                log("        option disables this behavior.\n");
                log("\n");
+               log("    -nodefaults\n");
+               log("        do not resolve input port default values\n");
+               log("\n");
                log("    -nokeep_asserts\n");
                log("        per default this pass sets the \"keep\" attribute on all modules\n");
                log("        that directly or indirectly contain one or more formal properties.\n");
@@ -645,6 +648,7 @@ struct HierarchyPass : public Pass {
                bool generate_mode = false;
                bool keep_positionals = false;
                bool keep_portwidths = false;
+               bool nodefaults = false;
                bool nokeep_asserts = false;
                std::vector<std::string> generate_cells;
                std::vector<generate_port_decl_t> generate_ports;
@@ -712,6 +716,10 @@ struct HierarchyPass : public Pass {
                                keep_portwidths = true;
                                continue;
                        }
+                       if (args[argidx] == "-nodefaults") {
+                               nodefaults = true;
+                               continue;
+                       }
                        if (args[argidx] == "-nokeep_asserts") {
                                nokeep_asserts = true;
                                continue;
@@ -940,6 +948,36 @@ struct HierarchyPass : public Pass {
                        }
                }
 
+               if (!nodefaults)
+               {
+                       dict<IdString, dict<IdString, Const>> defaults_db;
+
+                       for (auto module : design->modules())
+                               for (auto wire : module->wires())
+                                       if (wire->port_input && wire->attributes.count("\\defaultvalue"))
+                                               defaults_db[module->name][wire->name] = wire->attributes.at("\\defaultvalue");
+
+                       for (auto module : design->modules())
+                               for (auto cell : module->cells())
+                               {
+                                       if (defaults_db.count(cell->type) == 0)
+                                               continue;
+
+                                       if (keep_positionals) {
+                                               bool found_positionals = false;
+                                               for (auto &conn : cell->connections())
+                                                       if (conn.first[0] == '$' && '0' <= conn.first[1] && conn.first[1] <= '9')
+                                                               found_positionals = true;
+                                               if (found_positionals)
+                                                       continue;
+                                       }
+
+                                       for (auto &it : defaults_db.at(cell->type))
+                                               if (!cell->hasPort(it.first))
+                                                       cell->setPort(it.first, it.second);
+                               }
+               }
+
                std::set<Module*> blackbox_derivatives;
                std::vector<Module*> design_modules = design->modules();