diff --git a/tgt-vhdl/cast.cc b/tgt-vhdl/cast.cc index c6675c686..339e9c8ae 100644 --- a/tgt-vhdl/cast.cc +++ b/tgt-vhdl/cast.cc @@ -139,6 +139,22 @@ vhdl_expr *vhdl_expr::resize(int newwidth) return resize; } +vhdl_expr *vhdl_const_int::cast(const vhdl_type *to) +{ + if (to->get_name() == VHDL_TYPE_SIGNED + || to->get_name() == VHDL_TYPE_UNSIGNED) { + + const char *fname = to->get_name() == VHDL_TYPE_SIGNED + ? "To_Signed" : "To_Unsigned"; + vhdl_fcall *conv = new vhdl_fcall(fname, new vhdl_type(*to)); + conv->add_expr(this); + conv->add_expr(new vhdl_const_int(to->get_width())); + + return conv; + } + else + return vhdl_expr::cast(to); +} int vhdl_const_bits::bits_to_int() const { diff --git a/tgt-vhdl/logic.cc b/tgt-vhdl/logic.cc index 97acb9a16..80e5fe28e 100644 --- a/tgt-vhdl/logic.cc +++ b/tgt-vhdl/logic.cc @@ -71,8 +71,17 @@ static void bufif_logic(vhdl_arch *arch, ivl_net_logic_t log, bool if0) vhdl_expr *sel = nexus_to_var_ref(arch->get_scope(), ivl_logic_pin(log, 2)); assert(val); - vhdl_expr *on = new vhdl_const_bit(if0 ? '0' : '1'); - vhdl_expr *cmp = new vhdl_binop_expr(sel, VHDL_BINOP_EQ, on, NULL); + vhdl_expr *cmp; + if (ivl_logic_width(log) == 1) { + vhdl_expr *on = new vhdl_const_bit(if0 ? '0' : '1'); + cmp = new vhdl_binop_expr(sel, VHDL_BINOP_EQ, on, NULL); + } + else { + vhdl_expr *zero = (new vhdl_const_int(0))->cast(sel->get_type()); + vhdl_binop_t op = if0 ? VHDL_BINOP_EQ : VHDL_BINOP_NEQ; + cmp = new vhdl_binop_expr(sel, op, zero, NULL); + } + ivl_signal_t sig = find_signal_named(lhs->get_name(), arch->get_scope()); char zbit; @@ -87,8 +96,10 @@ static void bufif_logic(vhdl_arch *arch, ivl_net_logic_t log, bool if0) default: zbit = 'Z'; } - - vhdl_const_bit *z = new vhdl_const_bit(zbit); + + vhdl_expr *z = new vhdl_const_bit(zbit); + if (ivl_logic_width(log) > 1) + z = new vhdl_bit_spec_expr(NULL, z); vhdl_cassign_stmt *cass = new vhdl_cassign_stmt(lhs, z); cass->add_condition(val, cmp); diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index c1c63bd25..517d23f6c 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -202,6 +202,7 @@ public: vhdl_const_int(int64_t value) : vhdl_expr(vhdl_type::integer(), true), value_(value) {} void emit(std::ostream &of, int level) const; + vhdl_expr *cast(const vhdl_type *to); private: int64_t value_; };