Add sign extension LPM

This commit is contained in:
Nick Gasson 2008-07-07 19:27:52 +01:00
parent 0348664512
commit 47db80315c
4 changed files with 30 additions and 1 deletions

View File

@ -184,6 +184,8 @@ static vhdl_expr *translate_binary(ivl_expr_t e)
return translate_numeric(lhs, rhs, VHDL_BINOP_ADD); return translate_numeric(lhs, rhs, VHDL_BINOP_ADD);
case '-': case '-':
return translate_numeric(lhs, rhs, VHDL_BINOP_SUB); return translate_numeric(lhs, rhs, VHDL_BINOP_SUB);
case '*':
return translate_numeric(lhs, rhs, VHDL_BINOP_MULT);
case 'e': case 'e':
return translate_relation(lhs, rhs, VHDL_BINOP_EQ); return translate_relation(lhs, rhs, VHDL_BINOP_EQ);
case 'E': case 'E':

View File

@ -159,6 +159,23 @@ static int draw_reduction_lpm(vhdl_arch *arch, ivl_lpm_t lpm, const char *rfunc,
return 0; return 0;
} }
static int draw_sign_extend_lpm(vhdl_arch *arch, ivl_lpm_t lpm)
{
vhdl_expr *ref = nexus_to_var_ref(arch->get_scope(), ivl_lpm_data(lpm, 0));
if (NULL == ref)
return 1;
ref = ref->resize(ivl_lpm_width(lpm));
vhdl_var_ref *out = nexus_to_var_ref(arch->get_scope(), ivl_lpm_q(lpm, 0));
if (NULL == out)
return 1;
arch->add_stmt(new vhdl_cassign_stmt(out, ref));
return 0;
}
int draw_lpm(vhdl_arch *arch, ivl_lpm_t lpm) int draw_lpm(vhdl_arch *arch, ivl_lpm_t lpm)
{ {
switch (ivl_lpm_type(lpm)) { switch (ivl_lpm_type(lpm)) {
@ -188,6 +205,8 @@ int draw_lpm(vhdl_arch *arch, ivl_lpm_t lpm)
return draw_reduction_lpm(arch, lpm, "Reduce_XOR", false); return draw_reduction_lpm(arch, lpm, "Reduce_XOR", false);
case IVL_LPM_RE_XNOR: case IVL_LPM_RE_XNOR:
return draw_reduction_lpm(arch, lpm, "Reduce_XNOR", false); return draw_reduction_lpm(arch, lpm, "Reduce_XNOR", false);
case IVL_LPM_SIGN_EXT:
return draw_sign_extend_lpm(arch, lpm);
default: default:
error("Unsupported LPM type: %d", ivl_lpm_type(lpm)); error("Unsupported LPM type: %d", ivl_lpm_type(lpm));
return 1; return 1;

View File

@ -26,6 +26,7 @@
#include <cassert> #include <cassert>
static vhdl_expr *translate_logic(vhdl_scope *scope, ivl_net_logic_t log); static vhdl_expr *translate_logic(vhdl_scope *scope, ivl_net_logic_t log);
static std::string make_safe_name(ivl_signal_t sig);
/* /*
* Given a nexus find a constant value in it that can be used * Given a nexus find a constant value in it that can be used
@ -62,6 +63,8 @@ static vhdl_expr *nexus_to_const(ivl_nexus_t nexus)
static vhdl_expr *nexus_to_expr(vhdl_scope *arch_scope, ivl_nexus_t nexus, static vhdl_expr *nexus_to_expr(vhdl_scope *arch_scope, ivl_nexus_t nexus,
ivl_signal_t ignore = NULL) ivl_signal_t ignore = NULL)
{ {
std::cout << "nexus_to_expr " << ivl_nexus_name(nexus) << std::endl;
int nptrs = ivl_nexus_ptrs(nexus); int nptrs = ivl_nexus_ptrs(nexus);
for (int i = 0; i < nptrs; i++) { for (int i = 0; i < nptrs; i++) {
ivl_nexus_ptr_t nexus_ptr = ivl_nexus_ptr(nexus, i); ivl_nexus_ptr_t nexus_ptr = ivl_nexus_ptr(nexus, i);
@ -86,7 +89,10 @@ static vhdl_expr *nexus_to_expr(vhdl_scope *arch_scope, ivl_nexus_t nexus,
return translate_logic(arch_scope, log); return translate_logic(arch_scope, log);
} }
else if ((lpm = ivl_nexus_ptr_lpm(nexus_ptr))) { else if ((lpm = ivl_nexus_ptr_lpm(nexus_ptr))) {
error("LPM in nexus not implemented yet"); std::string basename("VL_");
basename += ivl_lpm_basename(lpm);
return new vhdl_var_ref(basename.c_str(), vhdl_type::std_logic());
} }
else { else {
// Ignore other types of nexus pointer // Ignore other types of nexus pointer

View File

@ -102,6 +102,8 @@ void remember_signal(ivl_signal_t sig, const vhdl_scope *scope)
{ {
assert(!seen_signal_before(sig)); assert(!seen_signal_before(sig));
std::cout << "remember_signal " << ivl_signal_name(sig) << std::endl;
signal_defn_t defn = { ivl_signal_basename(sig), scope }; signal_defn_t defn = { ivl_signal_basename(sig), scope };
g_known_signals[sig] = defn; g_known_signals[sig] = defn;
} }