Finish re-writing nexus code
This commit is contained in:
parent
c9454b346e
commit
744fbed783
|
|
@ -406,7 +406,7 @@ static vhdl_expr *translate_ufunc(ivl_expr_t e)
|
||||||
// A function is always declared in a module, which should have
|
// A function is always declared in a module, which should have
|
||||||
// a corresponding entity by this point: so we can get type
|
// a corresponding entity by this point: so we can get type
|
||||||
// information, etc. from the declaration
|
// information, etc. from the declaration
|
||||||
vhdl_entity *parent_ent = find_entity(ivl_scope_tname(parentscope));
|
vhdl_entity *parent_ent = find_entity(ivl_scope_name(parentscope));
|
||||||
assert(parent_ent);
|
assert(parent_ent);
|
||||||
|
|
||||||
const char *funcname = ivl_scope_tname(defscope);
|
const char *funcname = ivl_scope_tname(defscope);
|
||||||
|
|
|
||||||
|
|
@ -83,16 +83,8 @@ int draw_process(ivl_process_t proc, void *cd)
|
||||||
// A process should occur in a module scope, therefore it
|
// A process should occur in a module scope, therefore it
|
||||||
// should have already been assigned a VHDL entity
|
// should have already been assigned a VHDL entity
|
||||||
assert(ivl_scope_type(scope) == IVL_SCT_MODULE);
|
assert(ivl_scope_type(scope) == IVL_SCT_MODULE);
|
||||||
vhdl_entity *ent = find_entity(ivl_scope_tname(scope));
|
vhdl_entity *ent = find_entity(ivl_scope_name(scope));
|
||||||
assert(ent != NULL);
|
assert(ent != NULL);
|
||||||
|
|
||||||
// If the scope this process belongs to is the same as the
|
return generate_vhdl_process(ent, proc);
|
||||||
// VHDL entity was generated from, then create a VHDL process
|
|
||||||
// from this Verilog process. This ensures that each process
|
|
||||||
// is translated at most once, no matter how many times it
|
|
||||||
// appears in the hierarchy.
|
|
||||||
if (ent->get_derived_from() == scope_name)
|
|
||||||
return generate_vhdl_process(ent, proc);
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,90 +40,6 @@ void set_active_entity(vhdl_entity *ent)
|
||||||
g_active_entity = ent;
|
g_active_entity = ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The types of VHDL object a nexus can be converted into.
|
|
||||||
*/
|
|
||||||
enum vhdl_nexus_obj_t {
|
|
||||||
NEXUS_TO_VAR_REF = 1<<0,
|
|
||||||
NEXUS_TO_CONST = 1<<1,
|
|
||||||
NEXUS_TO_OTHER = 1<<2,
|
|
||||||
};
|
|
||||||
#define NEXUS_TO_ANY \
|
|
||||||
NEXUS_TO_VAR_REF | NEXUS_TO_CONST | NEXUS_TO_OTHER
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Given a nexus, generate a VHDL expression object to represent it.
|
|
||||||
* The allowed VHDL expression types are given by vhdl_nexus_obj_t.
|
|
||||||
*
|
|
||||||
* If a vhdl_var_ref is returned, the reference is guaranteed to be
|
|
||||||
* to a signal in arch_scope or its parent (the entity's ports).
|
|
||||||
*/
|
|
||||||
/*static vhdl_expr *nexus_to_expr(vhdl_scope *arch_scope, ivl_nexus_t nexus,
|
|
||||||
int allowed = NEXUS_TO_ANY)
|
|
||||||
{
|
|
||||||
int nptrs = ivl_nexus_ptrs(nexus);
|
|
||||||
for (int i = 0; i < nptrs; i++) {
|
|
||||||
ivl_nexus_ptr_t nexus_ptr = ivl_nexus_ptr(nexus, i);
|
|
||||||
|
|
||||||
ivl_signal_t sig;
|
|
||||||
ivl_net_logic_t log;
|
|
||||||
ivl_lpm_t lpm;
|
|
||||||
ivl_net_const_t con;
|
|
||||||
ivl_switch_t sw;
|
|
||||||
if ((allowed & NEXUS_TO_VAR_REF) &&
|
|
||||||
(sig = ivl_nexus_ptr_sig(nexus_ptr))) {
|
|
||||||
if (!seen_signal_before(sig) ||
|
|
||||||
(find_scope_for_signal(sig) != arch_scope
|
|
||||||
&& find_scope_for_signal(sig) != arch_scope->get_parent()))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const char *signame = get_renamed_signal(sig).c_str();
|
|
||||||
|
|
||||||
vhdl_decl *decl = arch_scope->get_decl(signame);
|
|
||||||
vhdl_type *type = new vhdl_type(*(decl->get_type()));
|
|
||||||
return new vhdl_var_ref(signame, type);
|
|
||||||
}
|
|
||||||
else if ((allowed & NEXUS_TO_OTHER) &&
|
|
||||||
(log = ivl_nexus_ptr_log(nexus_ptr))) {
|
|
||||||
return translate_logic(arch_scope, log);
|
|
||||||
}
|
|
||||||
else if ((allowed & NEXUS_TO_OTHER) &&
|
|
||||||
(lpm = ivl_nexus_ptr_lpm(nexus_ptr))) {
|
|
||||||
return lpm_output(arch_scope, lpm);
|
|
||||||
}
|
|
||||||
else if ((allowed & NEXUS_TO_CONST) &&
|
|
||||||
(con = ivl_nexus_ptr_con(nexus_ptr))) {
|
|
||||||
if (ivl_const_width(con) == 1)
|
|
||||||
return new vhdl_const_bit(ivl_const_bits(con)[0]);
|
|
||||||
else
|
|
||||||
return new vhdl_const_bits
|
|
||||||
(ivl_const_bits(con), ivl_const_width(con),
|
|
||||||
ivl_const_signed(con) != 0);
|
|
||||||
}
|
|
||||||
else if ((allowed & NEXUS_TO_OTHER) &&
|
|
||||||
(sw = ivl_nexus_ptr_switch(nexus_ptr))) {
|
|
||||||
std::cout << "SWITCH type=" << ivl_switch_type(sw) << std::endl;
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Ignore other types of nexus pointer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Guarantees the result will never be NULL.
|
|
||||||
*/
|
|
||||||
/*vhdl_var_ref *nexus_to_var_ref(vhdl_scope *arch_scope, ivl_nexus_t nexus)
|
|
||||||
{
|
|
||||||
return dynamic_cast<vhdl_var_ref*>
|
|
||||||
(nexus_to_expr(arch_scope, nexus, NEXUS_TO_VAR_REF));
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This represents the portion of a nexus that is visible within
|
* This represents the portion of a nexus that is visible within
|
||||||
* a VHDL scope. If that nexus portion does not contain a signal,
|
* a VHDL scope. If that nexus portion does not contain a signal,
|
||||||
|
|
@ -137,7 +53,6 @@ struct scope_nexus_t {
|
||||||
string tmpname; // A new temporary signal
|
string tmpname; // A new temporary signal
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This structure is stored in the private part of each nexus.
|
* This structure is stored in the private part of each nexus.
|
||||||
* It stores a scope_nexus_t for each VHDL scope which is
|
* It stores a scope_nexus_t for each VHDL scope which is
|
||||||
|
|
@ -211,11 +126,6 @@ void draw_nexus(ivl_nexus_t nexus)
|
||||||
ivl_signal_t sig;
|
ivl_signal_t sig;
|
||||||
if ((sig = ivl_nexus_ptr_sig(nexus_ptr))) {
|
if ((sig = ivl_nexus_ptr_sig(nexus_ptr))) {
|
||||||
cout << "signal " << ivl_signal_basename(sig) << endl;
|
cout << "signal " << ivl_signal_basename(sig) << endl;
|
||||||
|
|
||||||
if (!seen_signal_before(sig)) {
|
|
||||||
remember_signal(sig, NULL);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
vhdl_scope *scope = find_scope_for_signal(sig);
|
vhdl_scope *scope = find_scope_for_signal(sig);
|
||||||
|
|
||||||
|
|
@ -242,7 +152,7 @@ void draw_nexus(ivl_nexus_t nexus)
|
||||||
if ((log = ivl_nexus_ptr_log(nexus_ptr))) {
|
if ((log = ivl_nexus_ptr_log(nexus_ptr))) {
|
||||||
ivl_scope_t log_scope = ivl_logic_scope(log);
|
ivl_scope_t log_scope = ivl_logic_scope(log);
|
||||||
vhdl_scope *vhdl_scope =
|
vhdl_scope *vhdl_scope =
|
||||||
find_entity(ivl_scope_tname(log_scope))->get_arch()->get_scope();
|
find_entity(ivl_scope_name(log_scope))->get_arch()->get_scope();
|
||||||
|
|
||||||
cout << "logic " << ivl_logic_basename(log) << endl;
|
cout << "logic " << ivl_logic_basename(log) << endl;
|
||||||
|
|
||||||
|
|
@ -258,7 +168,7 @@ void draw_nexus(ivl_nexus_t nexus)
|
||||||
else if ((lpm = ivl_nexus_ptr_lpm(nexus_ptr))) {
|
else if ((lpm = ivl_nexus_ptr_lpm(nexus_ptr))) {
|
||||||
ivl_scope_t lpm_scope = ivl_lpm_scope(lpm);
|
ivl_scope_t lpm_scope = ivl_lpm_scope(lpm);
|
||||||
vhdl_scope *vhdl_scope =
|
vhdl_scope *vhdl_scope =
|
||||||
find_entity(ivl_scope_tname(lpm_scope))->get_arch()->get_scope();
|
find_entity(ivl_scope_name(lpm_scope))->get_arch()->get_scope();
|
||||||
|
|
||||||
cout << "LPM " << ivl_lpm_basename(lpm) << endl;
|
cout << "LPM " << ivl_lpm_basename(lpm) << endl;
|
||||||
|
|
||||||
|
|
@ -317,26 +227,25 @@ static void seen_nexus(ivl_nexus_t nexus)
|
||||||
* encountered before, the necessary code to connect up the nexus
|
* encountered before, the necessary code to connect up the nexus
|
||||||
* will be generated.
|
* will be generated.
|
||||||
*/
|
*/
|
||||||
vhdl_var_ref *nexus_to_var_ref(vhdl_scope *scope, ivl_nexus_t nexus)
|
vhdl_var_ref *nexus_to_var_ref(vhdl_scope *scope, ivl_nexus_t nexus)
|
||||||
{
|
{
|
||||||
cout << "nexus_to_var_ref " << ivl_nexus_name(nexus) << endl;
|
cout << "nexus_to_var_ref " << ivl_nexus_name(nexus) << endl;
|
||||||
|
|
||||||
seen_nexus(nexus);
|
seen_nexus(nexus);
|
||||||
|
|
||||||
nexus_private_t *priv =
|
nexus_private_t *priv =
|
||||||
static_cast<nexus_private_t*>(ivl_nexus_get_private(nexus));
|
static_cast<nexus_private_t*>(ivl_nexus_get_private(nexus));
|
||||||
string renamed(visible_nexus_signal_name(priv, scope));
|
string renamed(visible_nexus_signal_name(priv, scope));
|
||||||
|
|
||||||
cout << "--> signal " << renamed << endl;
|
cout << "--> signal " << renamed << endl;
|
||||||
|
|
||||||
vhdl_decl *decl = scope->get_decl(renamed);
|
vhdl_decl *decl = scope->get_decl(renamed);
|
||||||
assert(decl);
|
assert(decl);
|
||||||
|
|
||||||
vhdl_type *type = new vhdl_type(*(decl->get_type()));
|
vhdl_type *type = new vhdl_type(*(decl->get_type()));
|
||||||
return new vhdl_var_ref(renamed.c_str(), type);
|
return new vhdl_var_ref(renamed.c_str(), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert the inputs of a logic gate to a binary expression.
|
* Convert the inputs of a logic gate to a binary expression.
|
||||||
*/
|
*/
|
||||||
|
|
@ -470,9 +379,9 @@ static void declare_logic(vhdl_arch *arch, ivl_scope_t scope)
|
||||||
/*
|
/*
|
||||||
* Make sure a signal name conforms to VHDL naming rules.
|
* Make sure a signal name conforms to VHDL naming rules.
|
||||||
*/
|
*/
|
||||||
static std::string make_safe_name(ivl_signal_t sig)
|
static string make_safe_name(ivl_signal_t sig)
|
||||||
{
|
{
|
||||||
std::string name(ivl_signal_basename(sig));
|
string name(ivl_signal_basename(sig));
|
||||||
if (name[0] == '_')
|
if (name[0] == '_')
|
||||||
name.insert(0, "VL");
|
name.insert(0, "VL");
|
||||||
|
|
||||||
|
|
@ -702,7 +611,7 @@ static int draw_function(ivl_scope_t scope, ivl_scope_t parent)
|
||||||
assert(ivl_scope_type(scope) == IVL_SCT_FUNCTION);
|
assert(ivl_scope_type(scope) == IVL_SCT_FUNCTION);
|
||||||
|
|
||||||
// Find the containing entity
|
// Find the containing entity
|
||||||
vhdl_entity *ent = find_entity(ivl_scope_tname(parent));
|
vhdl_entity *ent = find_entity(ivl_scope_name(parent));
|
||||||
assert(ent);
|
assert(ent);
|
||||||
|
|
||||||
const char *funcname = ivl_scope_tname(scope);
|
const char *funcname = ivl_scope_tname(scope);
|
||||||
|
|
@ -773,7 +682,7 @@ static void create_skeleton_entity_for(ivl_scope_t scope)
|
||||||
vhdl_entity *ent = new vhdl_entity(tname, derived_from, arch);
|
vhdl_entity *ent = new vhdl_entity(tname, derived_from, arch);
|
||||||
|
|
||||||
// Build a comment to add to the entity/architecture
|
// Build a comment to add to the entity/architecture
|
||||||
std::ostringstream ss;
|
ostringstream ss;
|
||||||
ss << "Generated from Verilog module " << ivl_scope_tname(scope);
|
ss << "Generated from Verilog module " << ivl_scope_tname(scope);
|
||||||
|
|
||||||
arch->set_comment(ss.str());
|
arch->set_comment(ss.str());
|
||||||
|
|
@ -789,11 +698,9 @@ static void create_skeleton_entity_for(ivl_scope_t scope)
|
||||||
static int draw_skeleton_scope(ivl_scope_t scope, void *_parent)
|
static int draw_skeleton_scope(ivl_scope_t scope, void *_parent)
|
||||||
{
|
{
|
||||||
if (ivl_scope_type(scope) == IVL_SCT_MODULE) {
|
if (ivl_scope_type(scope) == IVL_SCT_MODULE) {
|
||||||
// Create this entity if it doesn't already exist
|
create_skeleton_entity_for(scope);
|
||||||
if (find_entity(ivl_scope_tname(scope)) == NULL) {
|
cout << "Created skeleton entity for " << ivl_scope_tname(scope)
|
||||||
create_skeleton_entity_for(scope);
|
<< " from instance " << ivl_scope_name(scope) << endl;
|
||||||
cout << "Created skeleton entity for " << ivl_scope_tname(scope) << endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ivl_scope_children(scope, draw_skeleton_scope, scope);
|
return ivl_scope_children(scope, draw_skeleton_scope, scope);
|
||||||
|
|
@ -802,11 +709,10 @@ static int draw_skeleton_scope(ivl_scope_t scope, void *_parent)
|
||||||
static int draw_all_signals(ivl_scope_t scope, void *_parent)
|
static int draw_all_signals(ivl_scope_t scope, void *_parent)
|
||||||
{
|
{
|
||||||
if (ivl_scope_type(scope) == IVL_SCT_MODULE) {
|
if (ivl_scope_type(scope) == IVL_SCT_MODULE) {
|
||||||
vhdl_entity *ent = find_entity(ivl_scope_tname(scope));
|
vhdl_entity *ent = find_entity(ivl_scope_name(scope));
|
||||||
assert(ent);
|
assert(ent);
|
||||||
|
|
||||||
if (ent->get_derived_from() == ivl_scope_name(scope))
|
declare_signals(ent, scope);
|
||||||
declare_signals(ent, scope);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ivl_scope_children(scope, draw_all_signals, scope);
|
return ivl_scope_children(scope, draw_all_signals, scope);
|
||||||
|
|
@ -819,12 +725,11 @@ static int draw_functions(ivl_scope_t scope, void *_parent)
|
||||||
{
|
{
|
||||||
ivl_scope_t parent = static_cast<ivl_scope_t>(_parent);
|
ivl_scope_t parent = static_cast<ivl_scope_t>(_parent);
|
||||||
if (ivl_scope_type(scope) == IVL_SCT_FUNCTION) {
|
if (ivl_scope_type(scope) == IVL_SCT_FUNCTION) {
|
||||||
vhdl_entity *ent = find_entity(ivl_scope_tname(parent));
|
vhdl_entity *ent = find_entity(ivl_scope_name(parent));
|
||||||
assert(ent);
|
assert(ent);
|
||||||
|
|
||||||
if (ent->get_derived_from() == ivl_scope_name(parent))
|
if (draw_function(scope, parent) != 0)
|
||||||
if (draw_function(scope, parent) != 0)
|
return 1;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ivl_scope_children(scope, draw_functions, scope);
|
return ivl_scope_children(scope, draw_functions, scope);
|
||||||
|
|
@ -841,37 +746,35 @@ static int draw_constant_drivers(ivl_scope_t scope, void *_parent)
|
||||||
ivl_scope_children(scope, draw_constant_drivers, scope);
|
ivl_scope_children(scope, draw_constant_drivers, scope);
|
||||||
|
|
||||||
if (ivl_scope_type(scope) == IVL_SCT_MODULE) {
|
if (ivl_scope_type(scope) == IVL_SCT_MODULE) {
|
||||||
vhdl_entity *ent = find_entity(ivl_scope_tname(scope));
|
vhdl_entity *ent = find_entity(ivl_scope_name(scope));
|
||||||
assert(ent);
|
assert(ent);
|
||||||
|
|
||||||
if (ent->get_derived_from() == ivl_scope_name(scope)) {
|
int nsigs = ivl_scope_sigs(scope);
|
||||||
int nsigs = ivl_scope_sigs(scope);
|
for (int i = 0; i < nsigs; i++) {
|
||||||
for (int i = 0; i < nsigs; i++) {
|
ivl_signal_t sig = ivl_scope_sig(scope, i);
|
||||||
ivl_signal_t sig = ivl_scope_sig(scope, i);
|
|
||||||
|
for (unsigned i = ivl_signal_array_base(sig);
|
||||||
|
i < ivl_signal_array_count(sig);
|
||||||
|
i++) {
|
||||||
|
// Make sure the nexus code is generated
|
||||||
|
ivl_nexus_t nex = ivl_signal_nex(sig, i);
|
||||||
|
seen_nexus(nex);
|
||||||
|
|
||||||
|
assert(i == 0); // TODO: Make work for more words
|
||||||
|
nexus_private_t *priv =
|
||||||
|
static_cast<nexus_private_t*>(ivl_nexus_get_private(nex));
|
||||||
|
assert(priv);
|
||||||
|
|
||||||
for (unsigned i = ivl_signal_array_base(sig);
|
if (priv->const_driver) {
|
||||||
i < ivl_signal_array_count(sig);
|
cout << "NEEDS CONST DRIVER!" << endl;
|
||||||
i++) {
|
cout << "(in scope " << ivl_scope_name(scope) << endl;
|
||||||
// Make sure the nexus code is generated
|
|
||||||
ivl_nexus_t nex = ivl_signal_nex(sig, i);
|
vhdl_var_ref *ref =
|
||||||
seen_nexus(nex);
|
nexus_to_var_ref(ent->get_arch()->get_scope(), nex);
|
||||||
|
|
||||||
assert(i == 0); // TODO: Make work for more words
|
ent->get_arch()->add_stmt
|
||||||
nexus_private_t *priv =
|
(new vhdl_cassign_stmt(ref, priv->const_driver));
|
||||||
static_cast<nexus_private_t*>(ivl_nexus_get_private(nex));
|
priv->const_driver = NULL;
|
||||||
assert(priv);
|
|
||||||
|
|
||||||
if (priv->const_driver) {
|
|
||||||
cout << "NEEDS CONST DRIVER!" << endl;
|
|
||||||
cout << "(in scope " << ivl_scope_name(scope) << endl;
|
|
||||||
|
|
||||||
vhdl_var_ref *ref =
|
|
||||||
nexus_to_var_ref(ent->get_arch()->get_scope(), nex);
|
|
||||||
|
|
||||||
ent->get_arch()->add_stmt
|
|
||||||
(new vhdl_cassign_stmt(ref, priv->const_driver));
|
|
||||||
priv->const_driver = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -883,17 +786,15 @@ static int draw_constant_drivers(ivl_scope_t scope, void *_parent)
|
||||||
static int draw_all_logic_and_lpm(ivl_scope_t scope, void *_parent)
|
static int draw_all_logic_and_lpm(ivl_scope_t scope, void *_parent)
|
||||||
{
|
{
|
||||||
if (ivl_scope_type(scope) == IVL_SCT_MODULE) {
|
if (ivl_scope_type(scope) == IVL_SCT_MODULE) {
|
||||||
vhdl_entity *ent = find_entity(ivl_scope_tname(scope));
|
vhdl_entity *ent = find_entity(ivl_scope_name(scope));
|
||||||
assert(ent);
|
assert(ent);
|
||||||
|
|
||||||
if (ent->get_derived_from() == ivl_scope_name(scope)) {
|
set_active_entity(ent);
|
||||||
set_active_entity(ent);
|
{
|
||||||
{
|
declare_logic(ent->get_arch(), scope);
|
||||||
declare_logic(ent->get_arch(), scope);
|
declare_lpm(ent->get_arch(), scope);
|
||||||
declare_lpm(ent->get_arch(), scope);
|
|
||||||
}
|
|
||||||
set_active_entity(NULL);
|
|
||||||
}
|
}
|
||||||
|
set_active_entity(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ivl_scope_children(scope, draw_all_logic_and_lpm, scope);
|
return ivl_scope_children(scope, draw_all_logic_and_lpm, scope);
|
||||||
|
|
@ -904,45 +805,43 @@ static int draw_hierarchy(ivl_scope_t scope, void *_parent)
|
||||||
if (ivl_scope_type(scope) == IVL_SCT_MODULE && _parent) {
|
if (ivl_scope_type(scope) == IVL_SCT_MODULE && _parent) {
|
||||||
ivl_scope_t parent = static_cast<ivl_scope_t>(_parent);
|
ivl_scope_t parent = static_cast<ivl_scope_t>(_parent);
|
||||||
|
|
||||||
vhdl_entity *ent = find_entity(ivl_scope_tname(scope));
|
vhdl_entity *ent = find_entity(ivl_scope_name(scope));
|
||||||
assert(ent);
|
assert(ent);
|
||||||
|
|
||||||
vhdl_entity *parent_ent = find_entity(ivl_scope_tname(parent));
|
vhdl_entity *parent_ent = find_entity(ivl_scope_name(parent));
|
||||||
assert(parent_ent);
|
assert(parent_ent);
|
||||||
|
|
||||||
if (parent_ent->get_derived_from() == ivl_scope_name(parent)) {
|
vhdl_arch *parent_arch = parent_ent->get_arch();
|
||||||
vhdl_arch *parent_arch = parent_ent->get_arch();
|
assert(parent_arch != NULL);
|
||||||
assert(parent_arch != NULL);
|
|
||||||
|
|
||||||
// Create a forward declaration for it
|
// Create a forward declaration for it
|
||||||
if (!parent_arch->get_scope()->have_declared(ent->get_name())) {
|
if (!parent_arch->get_scope()->have_declared(ent->get_name())) {
|
||||||
vhdl_decl *comp_decl = vhdl_component_decl::component_decl_for(ent);
|
vhdl_decl *comp_decl = vhdl_component_decl::component_decl_for(ent);
|
||||||
parent_arch->get_scope()->add_decl(comp_decl);
|
parent_arch->get_scope()->add_decl(comp_decl);
|
||||||
}
|
|
||||||
|
|
||||||
// And an instantiation statement
|
|
||||||
string inst_name(ivl_scope_basename(scope));
|
|
||||||
if (inst_name == ent->get_name()) {
|
|
||||||
// Cannot have instance name the same as type in VHDL
|
|
||||||
inst_name += "_Inst";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Need to replace any [ and ] characters that result
|
|
||||||
// from generate statements
|
|
||||||
string::size_type loc = inst_name.find('[', 0);
|
|
||||||
if (loc != string::npos)
|
|
||||||
inst_name.erase(loc, 1);
|
|
||||||
|
|
||||||
loc = inst_name.find(']', 0);
|
|
||||||
if (loc != string::npos)
|
|
||||||
inst_name.erase(loc, 1);
|
|
||||||
|
|
||||||
vhdl_comp_inst *inst =
|
|
||||||
new vhdl_comp_inst(inst_name.c_str(), ent->get_name().c_str());
|
|
||||||
port_map(scope, parent_ent, inst);
|
|
||||||
|
|
||||||
parent_arch->add_stmt(inst);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// And an instantiation statement
|
||||||
|
string inst_name(ivl_scope_basename(scope));
|
||||||
|
if (inst_name == ent->get_name()) {
|
||||||
|
// Cannot have instance name the same as type in VHDL
|
||||||
|
inst_name += "_Inst";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Need to replace any [ and ] characters that result
|
||||||
|
// from generate statements
|
||||||
|
string::size_type loc = inst_name.find('[', 0);
|
||||||
|
if (loc != string::npos)
|
||||||
|
inst_name.erase(loc, 1);
|
||||||
|
|
||||||
|
loc = inst_name.find(']', 0);
|
||||||
|
if (loc != string::npos)
|
||||||
|
inst_name.erase(loc, 1);
|
||||||
|
|
||||||
|
vhdl_comp_inst *inst =
|
||||||
|
new vhdl_comp_inst(inst_name.c_str(), ent->get_name().c_str());
|
||||||
|
port_map(scope, parent_ent, inst);
|
||||||
|
|
||||||
|
parent_arch->add_stmt(inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ivl_scope_children(scope, draw_hierarchy, scope);
|
return ivl_scope_children(scope, draw_hierarchy, scope);
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Maps a signal to the scope it is defined within. Also
|
* Maps a signal to the scope it is defined within. Also
|
||||||
|
|
@ -68,13 +69,13 @@ void error(const char *fmt, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find an entity given a type name.
|
* Find an entity given a scope name.
|
||||||
*/
|
*/
|
||||||
vhdl_entity *find_entity(const std::string &tname)
|
vhdl_entity *find_entity(const std::string &sname)
|
||||||
{
|
{
|
||||||
entity_list_t::const_iterator it;
|
entity_list_t::const_iterator it;
|
||||||
for (it = g_entities.begin(); it != g_entities.end(); ++it) {
|
for (it = g_entities.begin(); it != g_entities.end(); ++it) {
|
||||||
if ((*it)->get_name() == tname)
|
if ((*it)->get_derived_from() == sname)
|
||||||
return *it;
|
return *it;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -86,7 +87,7 @@ vhdl_entity *find_entity(const std::string &tname)
|
||||||
*/
|
*/
|
||||||
void remember_entity(vhdl_entity* ent)
|
void remember_entity(vhdl_entity* ent)
|
||||||
{
|
{
|
||||||
assert(find_entity(ent->get_name()) == NULL);
|
assert(find_entity(ent->get_derived_from()) == NULL);
|
||||||
g_entities.push_back(ent);
|
g_entities.push_back(ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -164,12 +165,19 @@ extern "C" int target_design(ivl_design_t des)
|
||||||
// only if there are no errors
|
// only if there are no errors
|
||||||
if (0 == g_errors) {
|
if (0 == g_errors) {
|
||||||
const char *ofname = ivl_design_flag(des, "-o");
|
const char *ofname = ivl_design_flag(des, "-o");
|
||||||
std::ofstream outfile(ofname);
|
ofstream outfile(ofname);
|
||||||
|
|
||||||
|
// Make sure we only emit one example of each type of entity
|
||||||
|
set<string> seen_entities;
|
||||||
|
|
||||||
for (entity_list_t::iterator it = g_entities.begin();
|
for (entity_list_t::iterator it = g_entities.begin();
|
||||||
it != g_entities.end();
|
it != g_entities.end();
|
||||||
++it)
|
++it) {
|
||||||
(*it)->emit(outfile);
|
if (seen_entities.find((*it)->get_name()) == seen_entities.end()) {
|
||||||
|
(*it)->emit(outfile);
|
||||||
|
seen_entities.insert((*it)->get_name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
outfile.close();
|
outfile.close();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ vhdl_expr *translate_expr(ivl_expr_t e);
|
||||||
vhdl_expr *translate_time_expr(ivl_expr_t e);
|
vhdl_expr *translate_time_expr(ivl_expr_t e);
|
||||||
|
|
||||||
void remember_entity(vhdl_entity *ent);
|
void remember_entity(vhdl_entity *ent);
|
||||||
vhdl_entity *find_entity(const string &tname);
|
vhdl_entity *find_entity(const string &sname);
|
||||||
|
|
||||||
ivl_design_t get_vhdl_design();
|
ivl_design_t get_vhdl_design();
|
||||||
vhdl_entity *get_active_entity();
|
vhdl_entity *get_active_entity();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue