Merge branch 'master' of ssh://steve-icarus@icarus.com/~steve-icarus/git/verilog
This commit is contained in:
commit
cb1f4f781f
|
|
@ -245,6 +245,8 @@ void draw_nexus(ivl_nexus_t nexus)
|
|||
ivl_lpm_signed(lpm) != 0);
|
||||
ostringstream ss;
|
||||
ss << "LPM" << ivl_lpm_basename(lpm);
|
||||
|
||||
if (!vhdl_scope->have_declared(ss.str()))
|
||||
vhdl_scope->add_decl(new vhdl_signal_decl(ss.str().c_str(), type));
|
||||
|
||||
link_scope_to_nexus_tmp(priv, vhdl_scope, ss.str());
|
||||
|
|
@ -382,9 +384,27 @@ 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);
|
||||
string base(ivl_signal_basename(sig));
|
||||
|
||||
if (ivl_signal_local(sig))
|
||||
base = "Tmp" + base;
|
||||
|
||||
if (base[0] == '_')
|
||||
return string("VL") + base;
|
||||
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[] = {
|
||||
|
|
@ -405,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.
|
||||
*/
|
||||
|
|
@ -426,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;
|
||||
|
|
@ -549,15 +589,14 @@ static void map_signal(ivl_signal_t to, vhdl_entity *parent,
|
|||
nexus_private_t *priv =
|
||||
static_cast<nexus_private_t*>(ivl_nexus_get_private(nexus));
|
||||
assert(priv);
|
||||
if (!visible_nexus(priv, arch_scope)) {
|
||||
// This nexus isn't attached to anything in the parent
|
||||
return;
|
||||
}
|
||||
|
||||
vhdl_expr *map_to = NULL;
|
||||
const string name(make_safe_name(to));
|
||||
|
||||
// We can only map ports to signals or constants
|
||||
if (visible_nexus(priv, arch_scope)) {
|
||||
vhdl_var_ref *ref = nexus_to_var_ref(parent->get_arch()->get_scope(), nexus);
|
||||
|
||||
string name = make_safe_name(to);
|
||||
|
||||
// If we're mapping an output of this entity to an output of
|
||||
// the child entity, then VHDL will not let us read the value
|
||||
// of the signal (i.e. it must pass straight through).
|
||||
|
|
@ -566,7 +605,6 @@ static void map_signal(ivl_signal_t to, vhdl_entity *parent,
|
|||
// and connect it to both ports.
|
||||
vhdl_decl* from_decl =
|
||||
parent->get_arch()->get_scope()->get_decl(ref->get_name());
|
||||
from_decl->print();
|
||||
if (!from_decl->is_readable()
|
||||
&& !arch_scope->have_declared(name + "_Readable")) {
|
||||
vhdl_decl* tmp_decl =
|
||||
|
|
@ -579,10 +617,21 @@ static void map_signal(ivl_signal_t to, vhdl_entity *parent,
|
|||
parent->get_arch()->add_stmt
|
||||
(new vhdl_cassign_stmt(from_decl->make_ref(), tmp_decl->make_ref()));
|
||||
|
||||
ref = tmp_decl->make_ref();
|
||||
map_to = tmp_decl->make_ref();
|
||||
}
|
||||
else
|
||||
map_to = ref;
|
||||
}
|
||||
else if (priv->const_driver && ivl_signal_port(to) == IVL_SIP_INPUT) {
|
||||
map_to = priv->const_driver;
|
||||
priv->const_driver = NULL;
|
||||
}
|
||||
else {
|
||||
// This nexus isn't attached to anything in the parent
|
||||
return;
|
||||
}
|
||||
|
||||
inst->map_port(name.c_str(), ref);
|
||||
inst->map_port(name, map_to);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -978,6 +1027,10 @@ static int draw_hierarchy(ivl_scope_t scope, void *_parent)
|
|||
if (loc != string::npos)
|
||||
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());
|
||||
port_map(scope, parent_ent, inst);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ 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 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)
|
||||
|
|
@ -238,7 +248,7 @@ vhdl_comp_inst::~vhdl_comp_inst()
|
|||
|
||||
}
|
||||
|
||||
void vhdl_comp_inst::map_port(const char *name, vhdl_expr *expr)
|
||||
void vhdl_comp_inst::map_port(const string& name, vhdl_expr *expr)
|
||||
{
|
||||
port_map_t pmap = { name, expr };
|
||||
mapping_.push_back(pmap);
|
||||
|
|
|
|||
|
|
@ -695,7 +695,7 @@ public:
|
|||
~vhdl_comp_inst();
|
||||
|
||||
void emit(std::ostream &of, int level) const;
|
||||
void map_port(const char *name, vhdl_expr *expr);
|
||||
void map_port(const string& name, vhdl_expr *expr);
|
||||
|
||||
const std::string &get_comp_name() const { return comp_name_; }
|
||||
const std::string &get_inst_name() const { return inst_name_; }
|
||||
|
|
@ -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