From 1d4ade80b2bb483e0578962a5553215f64a47a3b Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Fri, 14 Nov 2008 10:07:15 +0000 Subject: [PATCH] Fix select from non-variable-reference error (pr2281519) VHDL can't select bits from arbitrary expression so sometimes translating IVL_EX_SELECT would fail. This is easily fixed by replacing the select with a shift in this instance (and the resizing) --- tgt-vhdl/expr.cc | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/tgt-vhdl/expr.cc b/tgt-vhdl/expr.cc index e88d60935..5ac0073b5 100644 --- a/tgt-vhdl/expr.cc +++ b/tgt-vhdl/expr.cc @@ -451,20 +451,26 @@ static vhdl_expr *translate_select(ivl_expr_t e) return NULL; ivl_expr_t o2 = ivl_expr_oper2(e); - if (o2) { - vhdl_var_ref *from_var_ref = dynamic_cast(from); - if (NULL == from_var_ref) { - error("Can only select from variable reference"); - return NULL; - } - + if (o2) { vhdl_expr *base = translate_expr(ivl_expr_oper2(e)); if (NULL == base) return NULL; - vhdl_type integer(VHDL_TYPE_INTEGER); - from_var_ref->set_slice(base->cast(&integer), ivl_expr_width(e) - 1); - return from_var_ref; + vhdl_var_ref *from_var_ref = dynamic_cast(from); + if (NULL == from_var_ref) { + // We can't directly select bits from something that's not + // a variable reference in VHDL, but we can emulate the + // effect with a shift and a resize + return new vhdl_binop_expr(from, VHDL_BINOP_SR, base->to_integer(), + new vhdl_type(*from->get_type())); + } + else { + // We can use the more idomatic VHDL slice notation on a + // single variable reference + vhdl_type integer(VHDL_TYPE_INTEGER); + from_var_ref->set_slice(base->cast(&integer), ivl_expr_width(e) - 1); + return from_var_ref; + } } else return from->resize(ivl_expr_width(e)); @@ -634,7 +640,7 @@ vhdl_expr *translate_expr(ivl_expr_t e) { assert(e); ivl_expr_type_t type = ivl_expr_type(e); - + switch (type) { case IVL_EX_STRING: return translate_string(e);