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)
|
static string make_safe_name(ivl_signal_t sig)
|
||||||
{
|
{
|
||||||
const char *base = ivl_signal_basename(sig);
|
string base(ivl_signal_basename(sig));
|
||||||
if (base[0] == '_')
|
|
||||||
return string("VL") + base;
|
|
||||||
|
|
||||||
|
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
|
// This is the complete list of VHDL reserved words
|
||||||
const char *vhdl_reserved[] = {
|
const char *vhdl_reserved[] = {
|
||||||
"abs", "access", "after", "alias", "all", "and", "architecture",
|
"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++) {
|
for (const char **p = vhdl_reserved; *p != NULL; p++) {
|
||||||
if (strcasecmp(*p, base) == 0) {
|
if (strcasecmp(*p, base.c_str()) == 0) {
|
||||||
return string("VL_") + base;
|
return "Sig_" + base;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return string(base);
|
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.
|
* 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());
|
remember_signal(sig, ent->get_arch()->get_scope());
|
||||||
|
|
||||||
string name(make_safe_name(sig));
|
string name(make_safe_name(sig));
|
||||||
|
avoid_name_collision(name, ent->get_arch()->get_scope());
|
||||||
|
|
||||||
rename_signal(sig, name);
|
rename_signal(sig, name);
|
||||||
|
|
||||||
vhdl_type *sig_type;
|
vhdl_type *sig_type;
|
||||||
|
|
@ -977,7 +1015,11 @@ static int draw_hierarchy(ivl_scope_t scope, void *_parent)
|
||||||
|
|
||||||
loc = inst_name.find(']', 0);
|
loc = inst_name.find(']', 0);
|
||||||
if (loc != string::npos)
|
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 =
|
vhdl_comp_inst *inst =
|
||||||
new vhdl_comp_inst(inst_name.c_str(), ent->get_name().c_str());
|
new vhdl_comp_inst(inst_name.c_str(), ent->get_name().c_str());
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,19 @@ struct cmp_ent_name {
|
||||||
const string& 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
|
// Find a VHDL entity given a Verilog module scope. The VHDL entity
|
||||||
// name should be the same as the Verilog module type name.
|
// name should be the same as the Verilog module type name.
|
||||||
// Note that this will return NULL if no entity has been recorded
|
// 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);
|
assert(ivl_scope_type(scope) == IVL_SCT_MODULE);
|
||||||
|
|
||||||
entity_list_t::const_iterator it
|
return find_entity(ivl_scope_tname(scope));
|
||||||
= 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add an entity/architecture pair to the list of entities to emit.
|
// 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
|
// Manage the set of VHDL entities
|
||||||
void remember_entity(vhdl_entity *ent);
|
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 emit_all_entities(std::ostream& os, int max_depth);
|
||||||
void free_all_vhdl_objects();
|
void free_all_vhdl_objects();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,16 @@ bool vhdl_scope::have_declared(const std::string &name) const
|
||||||
return get_decl(name) != NULL;
|
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
|
bool vhdl_scope::contained_within(const vhdl_scope *other) const
|
||||||
{
|
{
|
||||||
if (this == other)
|
if (this == other)
|
||||||
|
|
|
||||||
|
|
@ -719,6 +719,7 @@ public:
|
||||||
void add_forward_decl(vhdl_decl *decl);
|
void add_forward_decl(vhdl_decl *decl);
|
||||||
vhdl_decl *get_decl(const std::string &name) const;
|
vhdl_decl *get_decl(const std::string &name) const;
|
||||||
bool have_declared(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;
|
bool contained_within(const vhdl_scope *other) const;
|
||||||
vhdl_scope *get_parent() const;
|
vhdl_scope *get_parent() const;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue