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);
case '-':
return translate_numeric(lhs, rhs, VHDL_BINOP_SUB);
case '*':
return translate_numeric(lhs, rhs, VHDL_BINOP_MULT);
case 'e':
return translate_relation(lhs, rhs, VHDL_BINOP_EQ);
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;
}
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)
{
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);
case IVL_LPM_RE_XNOR:
return draw_reduction_lpm(arch, lpm, "Reduce_XNOR", false);
case IVL_LPM_SIGN_EXT:
return draw_sign_extend_lpm(arch, lpm);
default:
error("Unsupported LPM type: %d", ivl_lpm_type(lpm));
return 1;

View File

@ -26,6 +26,7 @@
#include <cassert>
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
@ -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,
ivl_signal_t ignore = NULL)
{
std::cout << "nexus_to_expr " << ivl_nexus_name(nexus) << std::endl;
int nptrs = ivl_nexus_ptrs(nexus);
for (int i = 0; i < nptrs; 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);
}
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 {
// Ignore other types of nexus pointer

View File

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