diff --git a/tgt-vhdl/lpm.cc b/tgt-vhdl/lpm.cc index bc6f92207..8778dff8a 100644 --- a/tgt-vhdl/lpm.cc +++ b/tgt-vhdl/lpm.cc @@ -38,7 +38,20 @@ static int draw_binop_lpm(vhdl_arch *arch, ivl_lpm_t lpm, vhdl_binop_t op) return 1; vhdl_type *result_type = new vhdl_type(*lhs->get_type()); - vhdl_binop_expr *expr = new vhdl_binop_expr(lhs, op, rhs, result_type); + vhdl_expr *expr = new vhdl_binop_expr(lhs, op, rhs, result_type); + + if (op == VHDL_BINOP_MULT) { + // Need to resize the output to the desired size, + // as this does not happen automatically in VHDL + + unsigned out_width = ivl_lpm_width(lpm); + vhdl_fcall *resize = + new vhdl_fcall("Resize", vhdl_type::nsigned(out_width)); + resize->add_expr(expr); + resize->add_expr(new vhdl_const_int(out_width)); + + expr = resize; + } arch->add_stmt(new vhdl_cassign_stmt(out, expr)); @@ -50,6 +63,10 @@ int draw_lpm(vhdl_arch *arch, ivl_lpm_t lpm) switch (ivl_lpm_type(lpm)) { case IVL_LPM_ADD: return draw_binop_lpm(arch, lpm, VHDL_BINOP_ADD); + case IVL_LPM_SUB: + return draw_binop_lpm(arch, lpm, VHDL_BINOP_SUB); + case IVL_LPM_MULT: + return draw_binop_lpm(arch, lpm, VHDL_BINOP_MULT); default: error("Unsupported LPM type: %d", ivl_lpm_type(lpm)); return 1; diff --git a/tgt-vhdl/vhdl_syntax.cc b/tgt-vhdl/vhdl_syntax.cc index a912e70b3..3935c0bd7 100644 --- a/tgt-vhdl/vhdl_syntax.cc +++ b/tgt-vhdl/vhdl_syntax.cc @@ -697,6 +697,12 @@ void vhdl_binop_expr::emit(std::ofstream &of, int level) const case VHDL_BINOP_ADD: of << " + "; break; + case VHDL_BINOP_SUB: + of << " - "; + break; + case VHDL_BINOP_MULT: + of << " * "; + break; } (*it)->emit(of, level); diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index 8e576cd42..50f70e5b0 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -59,6 +59,8 @@ enum vhdl_binop_t { VHDL_BINOP_EQ, VHDL_BINOP_NEQ, VHDL_BINOP_ADD, + VHDL_BINOP_SUB, + VHDL_BINOP_MULT, }; /*