Various signal naming fixes for VHDL target

This avoids generating invalid VHDL signal names in the
following cases:
	- The name begins or ends with an underscore
	- The name contains two consecutive underscores
	- The name is the same as a component declaration
	- The name differs from another only in case
This commit is contained in:
Nick Gasson 2009-01-28 09:40:05 +00:00 committed by Stephen Williams
parent 497e095277
commit babc9c1352
5 changed files with 75 additions and 15 deletions

View File

@ -384,10 +384,28 @@ static void declare_logic(vhdl_arch *arch, ivl_scope_t scope)
*/
static string make_safe_name(ivl_signal_t sig)
{
const char *base = ivl_signal_basename(sig);
if (base[0] == '_')
return string("VL") + base;
string base(ivl_signal_basename(sig));
if (ivl_signal_local(sig))
base = "Tmp" + base;
if (base[0] == '_')
base = "Sig" + base;
if (*base.rbegin() == '_')
base += "Sig";
// Can't have two consecutive underscores
size_t pos = base.find("__");
while (pos != string::npos) {
base.replace(pos, 2, "_");
pos = base.find("__");
}
// A signal name may not be the same as a component name
if (find_entity(base) != NULL)
base += "_Sig";
// This is the complete list of VHDL reserved words
const char *vhdl_reserved[] = {
"abs", "access", "after", "alias", "all", "and", "architecture",
@ -407,14 +425,32 @@ static string make_safe_name(ivl_signal_t sig)
};
for (const char **p = vhdl_reserved; *p != NULL; p++) {
if (strcasecmp(*p, base) == 0) {
return string("VL_") + base;
if (strcasecmp(*p, base.c_str()) == 0) {
return "Sig_" + base;
break;
}
}
return string(base);
}
// Check if `name' differs from an existing name only in case and
// make it unique if it does.
static void avoid_name_collision(string& name, vhdl_scope* scope)
{
if (scope->name_collides(name)) {
name += "_";
ostringstream ss;
int i = 1;
do {
// Keep adding an extra number until we get a unique name
ss.str("");
ss << name << i++;
} while (scope->name_collides(ss.str()));
name = ss.str();
}
}
/*
* Declare all signals and ports for a scope.
*/
@ -428,6 +464,8 @@ static void declare_signals(vhdl_entity *ent, ivl_scope_t scope)
remember_signal(sig, ent->get_arch()->get_scope());
string name(make_safe_name(sig));
avoid_name_collision(name, ent->get_arch()->get_scope());
rename_signal(sig, name);
vhdl_type *sig_type;
@ -977,7 +1015,11 @@ static int draw_hierarchy(ivl_scope_t scope, void *_parent)
loc = inst_name.find(']', 0);
if (loc != string::npos)
inst_name.erase(loc, 1);
inst_name.erase(loc, 1);
// Make sure the name doesn't collide with anything we've
// already declared
avoid_name_collision(inst_name, parent_arch->get_scope());
vhdl_comp_inst *inst =
new vhdl_comp_inst(inst_name.c_str(), ent->get_name().c_str());

View File

@ -149,6 +149,19 @@ struct cmp_ent_name {
const string& name_;
};
// Find an entity given its name.
vhdl_entity* find_entity(const string& name)
{
entity_list_t::const_iterator it
= find_if(g_entities.begin(), g_entities.end(),
cmp_ent_name(name));
if (it != g_entities.end())
return *it;
else
return NULL;
}
// Find a VHDL entity given a Verilog module scope. The VHDL entity
// name should be the same as the Verilog module type name.
// Note that this will return NULL if no entity has been recorded
@ -157,14 +170,7 @@ vhdl_entity* find_entity(const ivl_scope_t scope)
{
assert(ivl_scope_type(scope) == IVL_SCT_MODULE);
entity_list_t::const_iterator it
= find_if(g_entities.begin(), g_entities.end(),
cmp_ent_name(ivl_scope_tname(scope)));
if (it != g_entities.end())
return *it;
else
return NULL;
return find_entity(ivl_scope_tname(scope));
}
// Add an entity/architecture pair to the list of entities to emit.

View File

@ -39,7 +39,8 @@ ivl_signal_t find_signal_named(const std::string &name, const vhdl_scope *scope)
// Manage the set of VHDL entities
void remember_entity(vhdl_entity *ent);
vhdl_entity *find_entity(const ivl_scope_t scope);
vhdl_entity* find_entity(const ivl_scope_t scope);
vhdl_entity* find_entity(const std::string& name);
void emit_all_entities(std::ostream& os, int max_depth);
void free_all_vhdl_objects();

View File

@ -74,6 +74,16 @@ bool vhdl_scope::have_declared(const std::string &name) const
return get_decl(name) != NULL;
}
// True if `name' differs in all but case from another declaration
bool vhdl_scope::name_collides(const string& name) const
{
const vhdl_decl* decl = get_decl(name);
if (decl)
return decl->get_name() != name;
else
return false;
}
bool vhdl_scope::contained_within(const vhdl_scope *other) const
{
if (this == other)

View File

@ -719,6 +719,7 @@ public:
void add_forward_decl(vhdl_decl *decl);
vhdl_decl *get_decl(const std::string &name) const;
bool have_declared(const std::string &name) const;
bool name_collides(const string& name) const;
bool contained_within(const vhdl_scope *other) const;
vhdl_scope *get_parent() const;