More VHDL naming fixes

This handles the cases where:
    * Instance names contain leading/trailing underscores
    * Instance names contain consecutive underscores
    * Module names contain consecutive underscores
    * Module names contain leading/trailing underscores
	* Ports may be inconsistently renamed
This commit is contained in:
Nick Gasson 2009-02-01 20:45:52 +00:00 committed by Stephen Williams
parent 501106dc92
commit f89f3dcbaf
5 changed files with 152 additions and 108 deletions

View File

@ -376,6 +376,28 @@ static void declare_logic(vhdl_arch *arch, ivl_scope_t scope)
draw_logic(arch, ivl_scope_log(scope, i)); draw_logic(arch, ivl_scope_log(scope, i));
} }
// Replace consecutive underscores with a single underscore
static void replace_consecutive_underscores(string& str)
{
size_t pos = str.find("__");
while (pos != string::npos) {
str.replace(pos, 2, "_");
pos = str.find("__");
}
}
// Return a valid VHDL name for a Verilog module
string valid_entity_name(const string& module_name)
{
string name(module_name);
replace_consecutive_underscores(name);
if (name[0] == '_')
name = "Mod" + name;
if (*name.rbegin() == '_')
name += "Mod";
return name;
}
// Make sure a signal name conforms to VHDL naming rules. // Make sure a signal name conforms to VHDL naming rules.
string make_safe_name(ivl_signal_t sig) string make_safe_name(ivl_signal_t sig)
{ {
@ -391,11 +413,7 @@ string make_safe_name(ivl_signal_t sig)
base += "Sig"; base += "Sig";
// Can't have two consecutive underscores // Can't have two consecutive underscores
size_t pos = base.find("__"); replace_consecutive_underscores(base);
while (pos != string::npos) {
base.replace(pos, 2, "_");
pos = base.find("__");
}
// A signal name may not be the same as a component name // A signal name may not be the same as a component name
if (find_entity(base) != NULL) if (find_entity(base) != NULL)
@ -446,16 +464,9 @@ static void avoid_name_collision(string& name, vhdl_scope* scope)
} }
} }
/* // Declare a single signal in a scope
* Declare all signals and ports for a scope. static void declare_one_signal(vhdl_entity *ent, ivl_signal_t sig)
*/
static void declare_signals(vhdl_entity *ent, ivl_scope_t scope)
{ {
debug_msg("Declaring signals in scope type %s", ivl_scope_tname(scope));
int nsigs = ivl_scope_sigs(scope);
for (int i = 0; i < nsigs; i++) {
ivl_signal_t sig = ivl_scope_sig(scope, i);
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));
@ -552,6 +563,29 @@ static void declare_signals(vhdl_entity *ent, ivl_scope_t scope)
default: default:
assert(false); assert(false);
} }
}
// Declare all signals and ports for a scope.
// This is done in two phases: first the ports are added then then
// internal signals. Making two passes like this ensures ports get
// first pick of names when there is a collision.
static void declare_signals(vhdl_entity *ent, ivl_scope_t scope)
{
debug_msg("Declaring signals in scope type %s", ivl_scope_tname(scope));
int nsigs = ivl_scope_sigs(scope);
for (int i = 0; i < nsigs; i++) {
ivl_signal_t sig = ivl_scope_sig(scope, i);
if (ivl_signal_port(sig) != IVL_SIP_NONE)
declare_one_signal(ent, sig);
}
for (int i = 0; i < nsigs; i++) {
ivl_signal_t sig = ivl_scope_sig(scope, i);
if (ivl_signal_port(sig) == IVL_SIP_NONE)
declare_one_signal(ent, sig);
} }
} }
@ -788,7 +822,7 @@ static void create_skeleton_entity_for(ivl_scope_t scope, int depth)
assert(ivl_scope_type(scope) == IVL_SCT_MODULE); assert(ivl_scope_type(scope) == IVL_SCT_MODULE);
// The type name will become the entity name // The type name will become the entity name
const char *tname = ivl_scope_tname(scope);; const string tname = valid_entity_name(ivl_scope_tname(scope));
// Verilog does not have the entity/architecture distinction // Verilog does not have the entity/architecture distinction
// so we always create a pair and associate the architecture // so we always create a pair and associate the architecture
@ -1022,6 +1056,15 @@ static int draw_hierarchy(ivl_scope_t scope, void *_parent)
if (loc != string::npos) if (loc != string::npos)
inst_name.erase(loc, 1); inst_name.erase(loc, 1);
// No leading or trailing underscores
if (inst_name[0] == '_')
inst_name = "Inst" + inst_name;
if (*inst_name.rbegin() == '_')
inst_name += "Inst";
// Can't have two consecutive underscores
replace_consecutive_underscores(inst_name);
// Make sure the name doesn't collide with anything we've // Make sure the name doesn't collide with anything we've
// already declared // already declared
avoid_name_collision(inst_name, parent_arch->get_scope()); avoid_name_collision(inst_name, parent_arch->get_scope());

View File

@ -170,7 +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);
return find_entity(ivl_scope_tname(scope)); return find_entity(valid_entity_name(ivl_scope_tname(scope)));
} }
// Add an entity/architecture pair to the list of entities to emit. // Add an entity/architecture pair to the list of entities to emit.

View File

@ -100,7 +100,7 @@ vhdl_scope *vhdl_scope::get_parent() const
return parent_; return parent_;
} }
vhdl_entity::vhdl_entity(const char *name, vhdl_arch *arch, int depth__) vhdl_entity::vhdl_entity(const string& name, vhdl_arch *arch, int depth__)
: depth(depth__), name_(name), arch_(arch) : depth(depth__), name_(name), arch_(arch)
{ {
arch->get_scope()->set_parent(&ports_); arch->get_scope()->set_parent(&ports_);

View File

@ -806,7 +806,7 @@ private:
*/ */
class vhdl_arch : public vhdl_element { class vhdl_arch : public vhdl_element {
public: public:
vhdl_arch(const char *entity, const char *name) vhdl_arch(const string& entity, const string& name)
: name_(name), entity_(entity) {} : name_(name), entity_(entity) {}
virtual ~vhdl_arch(); virtual ~vhdl_arch();
@ -828,7 +828,7 @@ private:
*/ */
class vhdl_entity : public vhdl_element { class vhdl_entity : public vhdl_element {
public: public:
vhdl_entity(const char *name, vhdl_arch *arch, int depth=0); vhdl_entity(const string& name, vhdl_arch *arch, int depth=0);
virtual ~vhdl_entity(); virtual ~vhdl_entity();
void emit(std::ostream &of, int level=0) const; void emit(std::ostream &of, int level=0) const;

View File

@ -28,6 +28,7 @@ ivl_design_t get_vhdl_design();
vhdl_var_ref *nexus_to_var_ref(vhdl_scope *arch_scope, ivl_nexus_t nexus); vhdl_var_ref *nexus_to_var_ref(vhdl_scope *arch_scope, ivl_nexus_t nexus);
vhdl_var_ref* readable_ref(vhdl_scope* scope, ivl_nexus_t nex); vhdl_var_ref* readable_ref(vhdl_scope* scope, ivl_nexus_t nex);
string make_safe_name(ivl_signal_t sig); string make_safe_name(ivl_signal_t sig);
string valid_entity_name(const string& module_name);
int draw_stask_display(vhdl_procedural *proc, stmt_container *container, int draw_stask_display(vhdl_procedural *proc, stmt_container *container,
ivl_statement_t stmt, bool newline = true); ivl_statement_t stmt, bool newline = true);