diff --git a/tgt-vhdl/expr.cc b/tgt-vhdl/expr.cc index fbb4c7c65..f91df6485 100644 --- a/tgt-vhdl/expr.cc +++ b/tgt-vhdl/expr.cc @@ -87,21 +87,9 @@ static vhdl_expr *translate_unary(ivl_expr_t e) */ static vhdl_expr *translate_numeric(vhdl_expr *lhs, vhdl_expr *rhs, vhdl_binop_t op) -{ - int lwidth = lhs->get_type()->get_width(); - int rwidth = rhs->get_type()->get_width(); - - // May need to resize the left or right hand side - if (lwidth < rwidth) { - lhs = lhs->cast(rhs->get_type()); - lwidth = rwidth; - } - else if (rwidth < lwidth) { - rhs = rhs->cast(lhs->get_type()); - rwidth = lwidth; - } - - return new vhdl_binop_expr(lhs, op, rhs, vhdl_type::nsigned(lwidth)); +{ + vhdl_type *rtype = new vhdl_type(*lhs->get_type()); + return new vhdl_binop_expr(lhs, op, rhs, rtype); } static vhdl_expr *translate_relation(vhdl_expr *lhs, vhdl_expr *rhs, @@ -134,6 +122,15 @@ static vhdl_expr *translate_binary(ivl_expr_t e) vhdl_expr *rhs = translate_expr(ivl_expr_oper2(e)); if (NULL == rhs) return NULL; + + int lwidth = lhs->get_type()->get_width(); + int rwidth = rhs->get_type()->get_width(); + + // May need to resize the left or right hand side + if (lwidth < rwidth) + rhs = rhs->cast(lhs->get_type()); + else if (rwidth < lwidth) + lhs = lhs->cast(rhs->get_type()); // For === and !== we need to compare std_logic_vectors // rather than signeds diff --git a/tgt-vhdl/scope.cc b/tgt-vhdl/scope.cc index 3d0ecfa03..d06ea0a20 100644 --- a/tgt-vhdl/scope.cc +++ b/tgt-vhdl/scope.cc @@ -130,7 +130,7 @@ static void declare_signals(vhdl_arch *arch, ivl_scope_t scope) int nsigs = ivl_scope_sigs(scope); for (int i = 0; i < nsigs; i++) { ivl_signal_t sig = ivl_scope_sig(scope, i); - + int width = ivl_signal_width(sig); vhdl_type *sig_type; if (width == 1) diff --git a/tgt-vhdl/vhdl_syntax.cc b/tgt-vhdl/vhdl_syntax.cc index 555f40aa1..823262432 100644 --- a/tgt-vhdl/vhdl_syntax.cc +++ b/tgt-vhdl/vhdl_syntax.cc @@ -465,14 +465,8 @@ vhdl_expr *vhdl_expr::cast(const vhdl_type *to) if (to->get_name() == type_->get_name()) { if (to->get_width() == type_->get_width()) return this; // Identical - else { - vhdl_type *rtype = vhdl_type::nsigned(to->get_width()); - vhdl_fcall *resize = new vhdl_fcall("Resize", rtype); - resize->add_expr(this); - resize->add_expr(new vhdl_const_int(to->get_width())); - - return resize; - } + else + return resize(to->get_width()); } else if (to->get_name() == VHDL_TYPE_BOOLEAN) { // '1' is true all else are false @@ -495,6 +489,16 @@ vhdl_expr *vhdl_expr::cast(const vhdl_type *to) } } +vhdl_expr *vhdl_expr::resize(int newwidth) +{ + vhdl_type *rtype = vhdl_type::nsigned(newwidth); + vhdl_fcall *resize = new vhdl_fcall("Resize", rtype); + resize->add_expr(this); + resize->add_expr(new vhdl_const_int(newwidth)); + + return resize; +} + void vhdl_expr_list::add_expr(vhdl_expr *e) { exprs_.push_back(e); diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index 9d4bde8d3..54a54fb6e 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -36,6 +36,7 @@ public: const vhdl_type *get_type() const { return type_; } bool constant() const { return isconst_; } virtual vhdl_expr *cast(const vhdl_type *to); + virtual vhdl_expr *resize(int newwidth); private: vhdl_type *type_; bool isconst_;