Merge branch 'master' of ssh://steve-icarus@icarus.com/~steve-icarus/git/verilog

This commit is contained in:
Stephen Williams 2009-01-28 20:12:46 -08:00
commit cb1f4f781f
5 changed files with 120 additions and 49 deletions

View File

@ -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);

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

@ -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();

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)
@ -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);

View File

@ -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;