Fix nexus_to_expr where nexus has IVL_LPM_SELECT_PV

This commit is contained in:
Nick Gasson 2008-07-14 11:53:38 +01:00
parent 78ee61558d
commit e331e4831b
3 changed files with 78 additions and 39 deletions

View File

@ -23,7 +23,7 @@
#include <iostream>
#include <cassert>
static vhdl_expr *draw_concat_lpm(vhdl_scope *scope, ivl_lpm_t lpm)
static vhdl_expr *concat_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm)
{
vhdl_type *result_type =
vhdl_type::type_for(ivl_lpm_width(lpm), ivl_lpm_signed(lpm) != 0);
@ -41,7 +41,7 @@ static vhdl_expr *draw_concat_lpm(vhdl_scope *scope, ivl_lpm_t lpm)
return expr;
}
static vhdl_expr *draw_binop_lpm(vhdl_scope *scope, ivl_lpm_t lpm, vhdl_binop_t op)
static vhdl_expr *binop_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm, vhdl_binop_t op)
{
vhdl_type *result_type =
vhdl_type::type_for(ivl_lpm_width(lpm), ivl_lpm_signed(lpm) != 0);
@ -88,7 +88,7 @@ static vhdl_expr *part_select_base(vhdl_scope *scope, ivl_lpm_t lpm)
return off->cast(&integer);
}
static vhdl_expr *draw_part_select_vp_lpm(vhdl_scope *scope, ivl_lpm_t lpm)
static vhdl_expr *part_select_vp_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm)
{
vhdl_var_ref *selfrom = nexus_to_var_ref(scope, ivl_lpm_data(lpm, 0));
if (NULL == selfrom)
@ -102,26 +102,40 @@ static vhdl_expr *draw_part_select_vp_lpm(vhdl_scope *scope, ivl_lpm_t lpm)
return selfrom;
}
static vhdl_expr *part_select_pv_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm)
{
vhdl_expr *off = part_select_base(scope, lpm);;
if (NULL == off)
return NULL;
vhdl_var_ref *out = nexus_to_var_ref(scope, ivl_lpm_q(lpm, 0));
if (NULL == out)
return NULL;
out->set_slice(off, ivl_lpm_width(lpm) - 1);
return out;
}
static int draw_part_select_pv_lpm(vhdl_arch *arch, ivl_lpm_t lpm)
{
vhdl_var_ref *selfrom = nexus_to_var_ref(arch->get_scope(), ivl_lpm_data(lpm, 0));
if (NULL == selfrom)
return 1;
vhdl_var_ref *out;
vhdl_var_ref *selfrom;
if (NULL == (out = nexus_to_var_ref(arch->get_scope(), ivl_lpm_q(lpm, 0)))
|| NULL == (selfrom = nexus_to_var_ref(arch->get_scope(), ivl_lpm_data(lpm, 0)))) {
// Not continuous assignment to signal: ignore it
return 0;
}
vhdl_expr *off = part_select_base(arch->get_scope(), lpm);;
if (NULL == off)
return 1;
vhdl_var_ref *out = nexus_to_var_ref(arch->get_scope(), ivl_lpm_q(lpm, 0));
if (NULL == out)
return 1;
out->set_slice(off, ivl_lpm_width(lpm) - 1);
arch->add_stmt(new vhdl_cassign_stmt(out, selfrom));
return 0;
}
static vhdl_expr *draw_ufunc_lpm(vhdl_scope *scope, ivl_lpm_t lpm)
static vhdl_expr *ufunc_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm)
{
vhdl_fcall *fcall = new vhdl_fcall(ivl_lpm_basename(lpm), NULL);
@ -136,7 +150,7 @@ static vhdl_expr *draw_ufunc_lpm(vhdl_scope *scope, ivl_lpm_t lpm)
return fcall;
}
static vhdl_expr *draw_reduction_lpm(vhdl_scope *scope, ivl_lpm_t lpm,
static vhdl_expr *reduction_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm,
const char *rfunc, bool invert)
{
vhdl_fcall *fcall = new vhdl_fcall(rfunc, vhdl_type::std_logic());
@ -154,7 +168,7 @@ static vhdl_expr *draw_reduction_lpm(vhdl_scope *scope, ivl_lpm_t lpm,
return fcall;
}
static vhdl_expr *draw_sign_extend_lpm(vhdl_scope *scope, ivl_lpm_t lpm)
static vhdl_expr *sign_extend_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm)
{
vhdl_expr *ref = nexus_to_var_ref(scope, ivl_lpm_data(lpm, 0));
if (ref)
@ -163,35 +177,62 @@ static vhdl_expr *draw_sign_extend_lpm(vhdl_scope *scope, ivl_lpm_t lpm)
return NULL;
}
static vhdl_expr *array_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm)
{
ivl_signal_t array = ivl_lpm_array(lpm);
if (!seen_signal_before(array))
return NULL;
const char *renamed = get_renamed_signal(array).c_str();
vhdl_decl *adecl = scope->get_decl(renamed);
assert(adecl);
vhdl_type *atype = new vhdl_type(*adecl->get_type());
vhdl_expr *select = nexus_to_var_ref(scope, ivl_lpm_select(lpm));
if (NULL == select)
return NULL;
vhdl_var_ref *ref = new vhdl_var_ref(renamed, atype);
ref->set_slice(select);
return ref;
}
vhdl_expr *lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm)
{
switch (ivl_lpm_type(lpm)) {
case IVL_LPM_ADD:
return draw_binop_lpm(scope, lpm, VHDL_BINOP_ADD);
return binop_lpm_to_expr(scope, lpm, VHDL_BINOP_ADD);
case IVL_LPM_SUB:
return draw_binop_lpm(scope, lpm, VHDL_BINOP_SUB);
return binop_lpm_to_expr(scope, lpm, VHDL_BINOP_SUB);
case IVL_LPM_MULT:
return draw_binop_lpm(scope, lpm, VHDL_BINOP_MULT);
return binop_lpm_to_expr(scope, lpm, VHDL_BINOP_MULT);
case IVL_LPM_CONCAT:
return draw_concat_lpm(scope, lpm);
return concat_lpm_to_expr(scope, lpm);
case IVL_LPM_PART_VP:
return draw_part_select_vp_lpm(scope, lpm);
return part_select_vp_lpm_to_expr(scope, lpm);
case IVL_LPM_PART_PV:
return part_select_pv_lpm_to_expr(scope, lpm);
case IVL_LPM_UFUNC:
return draw_ufunc_lpm(scope, lpm);
return ufunc_lpm_to_expr(scope, lpm);
case IVL_LPM_RE_AND:
return draw_reduction_lpm(scope, lpm, "Reduce_AND", false);
return reduction_lpm_to_expr(scope, lpm, "Reduce_AND", false);
case IVL_LPM_RE_NAND:
return draw_reduction_lpm(scope, lpm, "Reduce_AND", true);
return reduction_lpm_to_expr(scope, lpm, "Reduce_AND", true);
case IVL_LPM_RE_NOR:
return draw_reduction_lpm(scope, lpm, "Reduce_OR", true);
return reduction_lpm_to_expr(scope, lpm, "Reduce_OR", true);
case IVL_LPM_RE_OR:
return draw_reduction_lpm(scope, lpm, "Reduce_OR", false);
return reduction_lpm_to_expr(scope, lpm, "Reduce_OR", false);
case IVL_LPM_RE_XOR:
return draw_reduction_lpm(scope, lpm, "Reduce_XOR", false);
return reduction_lpm_to_expr(scope, lpm, "Reduce_XOR", false);
case IVL_LPM_RE_XNOR:
return draw_reduction_lpm(scope, lpm, "Reduce_XNOR", false);
return reduction_lpm_to_expr(scope, lpm, "Reduce_XNOR", false);
case IVL_LPM_SIGN_EXT:
return draw_sign_extend_lpm(scope, lpm);
return sign_extend_lpm_to_expr(scope, lpm);
case IVL_LPM_ARRAY:
return array_lpm_to_expr(scope, lpm);
default:
error("Unsupported LPM type: %d", ivl_lpm_type(lpm));
return NULL;

View File

@ -48,7 +48,7 @@ enum vhdl_nexus_obj_t {
*/
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);
@ -59,12 +59,12 @@ static vhdl_expr *nexus_to_expr(vhdl_scope *arch_scope, ivl_nexus_t nexus,
ivl_net_const_t con;
ivl_switch_t sw;
if ((allowed & NEXUS_TO_VAR_REF) &&
(sig = ivl_nexus_ptr_sig(nexus_ptr))) {
(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);
@ -77,9 +77,7 @@ static vhdl_expr *nexus_to_expr(vhdl_scope *arch_scope, ivl_nexus_t nexus,
}
else if ((allowed & NEXUS_TO_OTHER) &&
(lpm = ivl_nexus_ptr_lpm(nexus_ptr))) {
vhdl_expr *e = lpm_to_expr(arch_scope, lpm);
assert(e);
return e;
return lpm_to_expr(arch_scope, lpm);
}
else if ((allowed & NEXUS_TO_CONST) &&
(con = ivl_nexus_ptr_con(nexus_ptr))) {
@ -99,7 +97,7 @@ static vhdl_expr *nexus_to_expr(vhdl_scope *arch_scope, ivl_nexus_t nexus,
// Ignore other types of nexus pointer
}
}
return NULL;
}
@ -108,10 +106,8 @@ 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_var_ref *ref = dynamic_cast<vhdl_var_ref*>
return dynamic_cast<vhdl_var_ref*>
(nexus_to_expr(arch_scope, nexus, NEXUS_TO_VAR_REF));
assert(ref);
return ref;
}
/*
@ -241,9 +237,9 @@ static void declare_signals(vhdl_entity *ent, ivl_scope_t scope)
vhdl_type *sig_type =
vhdl_type::type_for(ivl_signal_width(sig), ivl_signal_signed(sig) != 0);
std::string name = make_safe_name(sig);
string name(make_safe_name(sig));
rename_signal(sig, name);
ivl_signal_port_t mode = ivl_signal_port(sig);
switch (mode) {
case IVL_SIP_NONE:
@ -254,7 +250,7 @@ static void declare_signals(vhdl_entity *ent, ivl_scope_t scope)
// This may be found in the signal's nexus
// TODO: Make this work for multiple words
vhdl_expr *init =
nexus_to_expr(ent->get_scope(), ivl_signal_nex(sig, 0),
nexus_to_expr(ent->get_scope(), ivl_signal_nex(sig, 0),
NEXUS_TO_CONST);
if (init != NULL)
decl->set_initial(init);

View File

@ -9,6 +9,8 @@
#include <string>
using namespace std;
void error(const char *fmt, ...);
int draw_scope(ivl_scope_t scope, void *_parent);