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:
parent
497e095277
commit
babc9c1352
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue