Extract connection checking logic from expand_module in hierarchy.cc
authorRupert Swarbrick <rswarbrick@gmail.com>
Wed, 27 May 2020 14:54:42 +0000 (15:54 +0100)
committerZachary Snow <zachary.j.snow@gmail.com>
Tue, 20 Jul 2021 14:13:15 +0000 (10:13 -0400)
No functional change, but pulls more logic out of the expand_module
function.

passes/hierarchy/hierarchy.cc

index 2f7fc6d8a2f58cabe126ed253dea2d7e61545588..5839a6c759de04eddcfb8089bc6f7c46659d3830 100644 (file)
@@ -376,6 +376,69 @@ RTLIL::Module *get_module(RTLIL::Design                  &design,
        return nullptr;
 }
 
+// Try to read an IdString as a numbered connection name ("$123" or similar),
+// writing the result to dst. If the string isn't of the right format, ignore
+// dst and return false.
+bool read_id_num(RTLIL::IdString str, int *dst)
+{
+       log_assert(dst);
+
+       const char *c_str = str.c_str();
+       if (c_str[0] != '$' || !('0' <= c_str[1] && c_str[1] <= '9'))
+               return false;
+
+       *dst = atoi(c_str + 1);
+       return true;
+}
+
+// Check that the connections on the cell match those that are defined
+// on the type: each named connection should match the name of a port
+// and each positional connection should have an index smaller than
+// the number of ports.
+//
+// Also do the same checks on the specified parameters.
+void check_cell_connections(const RTLIL::Module &module, RTLIL::Cell &cell, RTLIL::Module &mod)
+{
+       int id;
+       for (auto &conn : cell.connections()) {
+               if (read_id_num(conn.first, &id)) {
+                       if (id <= 0 || id > GetSize(mod.ports))
+                               log_error("Module `%s' referenced in module `%s' in cell `%s' "
+                                         "has only %d ports, requested port %d.\n",
+                                         log_id(cell.type), log_id(&module), log_id(&cell),
+                                         GetSize(mod.ports), id);
+                       continue;
+               }
+
+               const RTLIL::Wire* wire = mod.wire(conn.first);
+               if (!wire || wire->port_id == 0) {
+                       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 (read_id_num(param.first, &id)) {
+                       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);
+                       continue;
+               }
+
+               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));
+               }
+       }
+}
+
 bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check, bool flag_simcheck, std::vector<std::string> &libdirs)
 {
        bool did_something = false;
@@ -433,29 +496,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
                if_expander.visit_connections(*cell, *mod);
 
                if (flag_check || flag_simcheck)
-               {
-                       for (auto &conn : cell->connections()) {
-                               if (conn.first[0] == '$' && '0' <= conn.first[1] && conn.first[1] <= '9') {
-                                       int id = atoi(conn.first.c_str()+1);
-                                       if (id <= 0 || id > GetSize(mod->ports))
-                                               log_error("Module `%s' referenced in module `%s' in cell `%s' has only %d ports, requested port %d.\n",
-                                                               log_id(cell->type), log_id(module), log_id(cell), GetSize(mod->ports), id);
-                               } else if (mod->wire(conn.first) == nullptr || mod->wire(conn.first)->port_id == 0)
-                                       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 (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));
-                       }
-
-               }
+                       check_cell_connections(*module, *cell, *mod);
 
                if (mod->get_blackbox_attribute()) {
                        if (flag_simcheck)