hierarchy: Convert positional parameters to named.
authorMarcelina Kościelnicka <mwk@0x04.net>
Thu, 16 Apr 2020 15:38:55 +0000 (17:38 +0200)
committerMarcelina Kościelnicka <mwk@0x04.net>
Tue, 21 Apr 2020 17:09:00 +0000 (19:09 +0200)
Fixes #1821.

passes/hierarchy/hierarchy.cc
tests/various/hierarchy_param.ys [new file with mode: 0644]

index 3880b19fea4659c8a6b99be1e5842134fb028c2d..95d74d1eb2b9dd25f4d7829d4d9f9d0bd4863070 100644 (file)
@@ -334,10 +334,16 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
                                        log_error("Module `%s' referenced in module `%s' in cell `%s' does not have a port named '%s'.\n",
                                                        log_id(cell->type), log_id(module), log_id(cell), log_id(conn.first));
                        }
-                       for (auto &param : cell->parameters)
-                               if (mod->avail_parameters.count(param.first) == 0 && param.first[0] != '$' && strchr(param.first.c_str(), '.') == NULL)
+                       for (auto &param : cell->parameters) {
+                               if (param.first[0] == '$' && '0' <= param.first[1] && param.first[1] <= '9') {
+                                       int id = atoi(param.first.c_str()+1);
+                                       if (id <= 0 || id > GetSize(mod->avail_parameters))
+                                               log_error("Module `%s' referenced in module `%s' in cell `%s' has only %d parameters, requested parameter %d.\n",
+                                                               log_id(cell->type), log_id(module), log_id(cell), GetSize(mod->avail_parameters), id);
+                               } else if (mod->avail_parameters.count(param.first) == 0 && param.first[0] != '$' && strchr(param.first.c_str(), '.') == NULL)
                                        log_error("Module `%s' referenced in module `%s' in cell `%s' does not have a parameter named '%s'.\n",
                                                        log_id(cell->type), log_id(module), log_id(cell), log_id(param.first));
+                       }
 
                }
                }
@@ -939,7 +945,8 @@ struct HierarchyPass : public Pass {
 
                        for (auto mod : design->modules())
                        for (auto cell : mod->cells()) {
-                               if (design->module(cell->type) == nullptr)
+                               RTLIL::Module *cell_mod = design->module(cell->type);
+                               if (cell_mod == nullptr)
                                        continue;
                                for (auto &conn : cell->connections())
                                        if (conn.first[0] == '$' && '0' <= conn.first[1] && conn.first[1] <= '9') {
@@ -947,6 +954,23 @@ struct HierarchyPass : public Pass {
                                                pos_work.push_back(std::pair<RTLIL::Module*,RTLIL::Cell*>(mod, cell));
                                                break;
                                        }
+
+                               pool<std::pair<IdString, IdString>> params_rename;
+                               for (const auto &p : cell->parameters) {
+                                       if (p.first[0] == '$' && '0' <= p.first[1] && p.first[1] <= '9') {
+                                               int id = atoi(p.first.c_str()+1);
+                                               if (id <= 0 || id > GetSize(cell_mod->avail_parameters)) {
+                                                       log("  Failed to map positional parameter %d of cell %s.%s (%s).\n",
+                                                                       id, RTLIL::id2cstr(mod->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type));
+                                               } else {
+                                                       params_rename.insert(std::make_pair(p.first, cell_mod->avail_parameters[id - 1]));
+                                               }
+                                       }
+                               }
+                               for (const auto &p : params_rename) {
+                                       cell->setParam(p.second, cell->getParam(p.first));
+                                       cell->unsetParam(p.first);
+                               }
                        }
 
                        for (auto module : pos_mods)
diff --git a/tests/various/hierarchy_param.ys b/tests/various/hierarchy_param.ys
new file mode 100644 (file)
index 0000000..d703bb7
--- /dev/null
@@ -0,0 +1,23 @@
+read_verilog <<EOT
+
+module bb (...);
+parameter A = "abc";
+parameter B = 1;
+parameter C = 2;
+input a;
+output b;
+endmodule
+
+module top (...);
+input a;
+output b;
+bb #("def", 3) my_bb (a, b);
+endmodule
+
+EOT
+
+hierarchy -top top
+dump
+
+select -assert-count 1 t:bb r:A=def %i
+select -assert-count 1 t:bb r:B=3 %i