Allow LPMs in port maps

This commit is contained in:
Nick Gasson 2008-07-07 20:41:29 +01:00
parent 2bb645e0bc
commit 860a74ddd8
3 changed files with 36 additions and 15 deletions

View File

@ -33,10 +33,6 @@ static vhdl_expr *draw_binop_lpm(vhdl_scope *scope, ivl_lpm_t lpm, vhdl_binop_t
if (NULL == rhs)
return NULL;
vhdl_var_ref *out = nexus_to_var_ref(scope, ivl_lpm_q(lpm, 0));
if (NULL == out)
return NULL;
vhdl_type *result_type = new vhdl_type(*lhs->get_type());
vhdl_expr *expr = new vhdl_binop_expr(lhs, op, rhs, result_type);
@ -75,6 +71,8 @@ static vhdl_expr *part_select_base(vhdl_scope *scope, ivl_lpm_t lpm)
static vhdl_expr *draw_part_select_vp_lpm(vhdl_scope *scope, ivl_lpm_t lpm)
{
std::cout << "Part select vp" << std::endl;
vhdl_var_ref *selfrom = nexus_to_var_ref(scope, ivl_lpm_data(lpm, 0));
if (NULL == selfrom)
return NULL;
@ -150,6 +148,8 @@ static vhdl_expr *draw_sign_extend_lpm(vhdl_scope *scope, ivl_lpm_t lpm)
vhdl_expr *lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm)
{
std::cout << "LPM type " << ivl_lpm_type(lpm) << std::endl;
switch (ivl_lpm_type(lpm)) {
case IVL_LPM_ADD:
return draw_binop_lpm(scope, lpm, VHDL_BINOP_ADD);
@ -193,10 +193,9 @@ int draw_lpm(vhdl_arch *arch, ivl_lpm_t lpm)
return 1;
vhdl_var_ref *out = nexus_to_var_ref(arch->get_scope(), ivl_lpm_q(lpm, 0));
if (NULL == out)
return 1;
if (out)
arch->add_stmt(new vhdl_cassign_stmt(out, f));
arch->add_stmt(new vhdl_cassign_stmt(out, f));
return 0;
}
}

View File

@ -89,10 +89,10 @@ static vhdl_expr *nexus_to_expr(vhdl_scope *arch_scope, ivl_nexus_t nexus,
return translate_logic(arch_scope, log);
}
else if ((lpm = ivl_nexus_ptr_lpm(nexus_ptr))) {
std::string basename("VL_");
basename += ivl_lpm_basename(lpm);
return new vhdl_var_ref(basename.c_str(), vhdl_type::std_logic());
std::cout << "LPM to expr" << std::endl;
vhdl_expr *e = lpm_to_expr(arch_scope, lpm);
if (e)
return e;
}
else {
// Ignore other types of nexus pointer
@ -104,10 +104,30 @@ static vhdl_expr *nexus_to_expr(vhdl_scope *arch_scope, ivl_nexus_t nexus,
vhdl_var_ref *nexus_to_var_ref(vhdl_scope *arch_scope, ivl_nexus_t nexus)
{
vhdl_expr *e = nexus_to_expr(arch_scope, nexus);
vhdl_var_ref *ref = dynamic_cast<vhdl_var_ref*>(e);
assert(ref);
return ref;
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;
if ((sig = ivl_nexus_ptr_sig(nexus_ptr))) {
if (!seen_signal_before(sig))
continue;
const char *signame = get_renamed_signal(sig).c_str();
vhdl_decl *decl = arch_scope->get_decl(signame);
if (NULL == decl)
continue; // Not in this scope
vhdl_type *type = new vhdl_type(*(decl->get_type()));
return new vhdl_var_ref(signame, type);
}
else {
// Ignore other types of nexus pointer
}
}
return NULL;
}
/*
@ -359,6 +379,7 @@ static void map_signal(ivl_signal_t to, vhdl_entity *parent,
ivl_nexus_t nexus = ivl_signal_nex(to, 0);
vhdl_expr *to_e = nexus_to_expr(parent->get_arch()->get_scope(), nexus, to);
assert(to_e);
// The expressions in a VHDL port map must be 'globally static'
// i.e. they can't be arbitrary expressions

View File

@ -17,6 +17,7 @@ int draw_stmt(vhdl_procedural *proc, stmt_container *container,
ivl_statement_t stmt);
int draw_lpm(vhdl_arch *arch, ivl_lpm_t lpm);
vhdl_expr *lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm);
vhdl_expr *translate_expr(ivl_expr_t e);
void remember_entity(vhdl_entity *ent);