diff --git a/elaborate.cc b/elaborate.cc index e546df3c9..24d182198 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -3553,6 +3553,17 @@ bool PGenerate::elaborate(Design*des, NetScope*container) const if (scope->parent() != container) continue; + // If this was an unnamed generate block, replace its + // temporary name with a name generated using the naming + // scheme defined in the Verilog-2005 standard. + const char*name = scope_name.str(); + if (name[0] == '$') { + if (!scope->auto_name("genblk", '0', name + 4)) { + cerr << get_line() << ": warning: Couldn't build" + << " unique name for unnamed generate block" + << " - using internal name " << name << endl; + } + } if (debug_elaborate) cerr << get_line() << ": debug: Elaborate in " << "scope " << scope_path(scope) << endl; diff --git a/net_scope.cc b/net_scope.cc index bfef2e33f..75f16e457 100644 --- a/net_scope.cc +++ b/net_scope.cc @@ -90,6 +90,24 @@ NetExpr* NetScope::set_parameter(perm_string key, NetExpr*expr, return res; } +bool NetScope::auto_name(const char*prefix, char pad, const char* suffix) +{ + char tmp[32]; + int pad_pos = strlen(prefix); + int max_pos = sizeof(tmp) - strlen(suffix) - 1; + strncpy(tmp, prefix, sizeof(tmp)); + while (pad_pos <= max_pos) { + strcat(tmp + pad_pos, suffix); + hname_t new_name(lex_strings.make(tmp)); + if (!up_->child(new_name)) { + name_ = new_name; + return true; + } + tmp[pad_pos++] = pad; + } + return false; +} + /* * Return false if this creates a new parameter. */ diff --git a/netlist.h b/netlist.h index 1cc118439..a9a1fd4a0 100644 --- a/netlist.h +++ b/netlist.h @@ -3189,6 +3189,12 @@ class NetScope : public Attrib { NetScope(NetScope*up, const hname_t&name, TYPE t); ~NetScope(); + /* Rename the scope using the name generated by inserting as + many pad characters as required between prefix and suffix + to make the name unique in the parent scope. Return false + if a unique name couldn't be generated. */ + bool auto_name(const char* prefix, char pad, const char* suffix); + /* Parameters exist within a scope, and these methods allow one to manipulate the set. In these cases, the name is the *simple* name of the parameter, the hierarchy is implicit in diff --git a/pform.cc b/pform.cc index 26abc70d8..8ea0437ab 100644 --- a/pform.cc +++ b/pform.cc @@ -417,8 +417,11 @@ void pform_endgenerate() assert(pform_cur_generate != 0); assert(pform_cur_module); - // If there is no explicit block name, then use a default - // internal name. + // If there is no explicit block name then generate a temporary + // name. This will be replaced by the correct name later, once + // we know all the explicit names in the surrounding scope. If + // the naming scheme used here is changed, PGenerate::elaborate + // must be changed to match. if (pform_cur_generate->scope_name == 0) { char tmp[16]; snprintf(tmp, sizeof tmp, "$gen%d", pform_cur_generate->id_number);