Have scope auto-rename generate names that use the index numbers

In generate blocks such as for loops, there may be many generated
scopes that have the same generated name. But in these cases, there
is an index number in the hname that can be used. So do so.

(cherry picked from commit 81f54ec0cb)
This commit is contained in:
Stephen Williams 2015-09-29 17:44:28 -07:00
parent d9e09ceb59
commit 63d2059b85
4 changed files with 26 additions and 14 deletions

View File

@ -40,7 +40,7 @@ hname_t::hname_t(perm_string text, int num)
number_[0] = num; number_[0] = num;
} }
hname_t::hname_t(perm_string text, vector<int>&nums) hname_t::hname_t(perm_string text, const vector<int>&nums)
: name_(text), number_(nums) : name_(text), number_(nums)
{ {
} }

13
HName.h
View File

@ -42,7 +42,7 @@ class hname_t {
hname_t (); hname_t ();
explicit hname_t (perm_string text); explicit hname_t (perm_string text);
explicit hname_t (perm_string text, int num); explicit hname_t (perm_string text, int num);
explicit hname_t (perm_string text, std::vector<int>&nums); explicit hname_t (perm_string text, const std::vector<int>&nums);
hname_t (const hname_t&that); hname_t (const hname_t&that);
~hname_t(); ~hname_t();
@ -56,12 +56,12 @@ class hname_t {
size_t has_numbers() const; size_t has_numbers() const;
int peek_number(size_t idx) const; int peek_number(size_t idx) const;
const std::vector<int>&peek_numbers() const;
private: private:
perm_string name_; perm_string name_;
// If the number is anything other than INT_MIN, then this is // If this vector has size, then the numbers all together make
// the numeric part of the name. Otherwise, it is not part of // up part of the hierarchical name.
// the name at all.
std::vector<int> number_; std::vector<int> number_;
private: // not implemented private: // not implemented
@ -82,6 +82,11 @@ inline int hname_t::peek_number(size_t idx) const
return number_[idx]; return number_[idx];
} }
inline const std::vector<int>& hname_t::peek_numbers(void) const
{
return number_;
}
inline size_t hname_t::has_numbers() const inline size_t hname_t::has_numbers() const
{ {
return number_.size(); return number_.size();

View File

@ -5728,6 +5728,9 @@ bool PGenerate::elaborate(Design*des, NetScope*container) const
"generate " << scheme_type "generate " << scheme_type
<< " elaborating in scope " << scope_path(container) << " elaborating in scope " << scope_path(container)
<< "." << endl; << "." << endl;
cerr << get_fileline() << ": PGenerate::elaborate: "
"generate scope_name=" << scope_name
<< ", id_number=" << id_number << endl;
} }
// Handle the special case that this is a CASE scheme. In this // Handle the special case that this is a CASE scheme. In this
@ -5762,6 +5765,7 @@ bool PGenerate::elaborate(Design*des, NetScope*container) const
// scheme defined in the Verilog-2005 standard. // scheme defined in the Verilog-2005 standard.
const char*name = scope_name.str(); const char*name = scope_name.str();
if (name[0] == '$') { if (name[0] == '$') {
if (!scope->auto_name("genblk", '0', name + 4)) { if (!scope->auto_name("genblk", '0', name + 4)) {
cerr << get_fileline() << ": warning: Couldn't build" cerr << get_fileline() << ": warning: Couldn't build"
<< " unique name for unnamed generate block" << " unique name for unnamed generate block"

View File

@ -264,19 +264,20 @@ bool NetScope::auto_name(const char*prefix, char pad, const char* suffix)
assert(self != up_->children_.end()); assert(self != up_->children_.end());
assert(self->second == this); assert(self->second == this);
char tmp[32]; // This is to keep the pad attempts from being stuck in some
int pad_pos = strlen(prefix); // sort of infinite loop. This should not be a practical
int max_pos = sizeof(tmp) - strlen(suffix) - 1; // limit, but an extreme one.
strncpy(tmp, prefix, sizeof(tmp)); const size_t max_pad_attempts = 32 + strlen(prefix);
tmp[31] = 0;
string use_prefix = prefix;
// Try a variety of potential new names. Make sure the new // Try a variety of potential new names. Make sure the new
// name is not in the parent scope. Keep looking until we are // name is not in the parent scope. Keep looking until we are
// sure we have a unique name, or we run out of names to try. // sure we have a unique name, or we run out of names to try.
while (pad_pos <= max_pos) { while (use_prefix.size() <= max_pad_attempts) {
// Try this name... // Try this name...
strcat(tmp + pad_pos, suffix); string tmp = use_prefix + suffix;
hname_t new_name(lex_strings.make(tmp)); hname_t new_name(lex_strings.make(tmp.c_str()), name_.peek_numbers());
if (!up_->child(new_name)) { if (!up_->child(new_name)) {
// Ah, this name is unique. Rename myself, and // Ah, this name is unique. Rename myself, and
// change my name in the parent scope. // change my name in the parent scope.
@ -285,7 +286,9 @@ bool NetScope::auto_name(const char*prefix, char pad, const char* suffix)
up_->children_[name_] = this; up_->children_[name_] = this;
return true; return true;
} }
tmp[pad_pos++] = pad;
// Name collides, so try a different name.
use_prefix = use_prefix + pad;
} }
return false; return false;
} }