From a7cbb382488e21be6796d6ea59ac1a8a6534e7e9 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sun, 5 Oct 2008 13:49:07 +0100 Subject: [PATCH] Fix resizing of constant bit vectors Emitting a VHDL expression like Resize("01", 32) is ambiguous between interpreting "01" as a Signed or an Unsigned. There's no point actually outputting this as we can sign-extend the constant value in the code generator, which is what this patch does. --- tgt-vhdl/cast.cc | 19 +++++++++++++++++-- tgt-vhdl/vhdl_syntax.hh | 2 ++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/tgt-vhdl/cast.cc b/tgt-vhdl/cast.cc index d56b6de09..e3006e9e0 100644 --- a/tgt-vhdl/cast.cc +++ b/tgt-vhdl/cast.cc @@ -222,7 +222,7 @@ vhdl_expr *vhdl_const_int::to_vector(vhdl_type_name_t name, int w) } int vhdl_const_bits::bits_to_int() const -{ +{ char msb = value_[value_.size() - 1]; int result = 0, bit; for (int i = sizeof(int)*8 - 1; i >= 0; i--) { @@ -248,6 +248,11 @@ vhdl_expr *vhdl_const_bits::to_std_logic() return new vhdl_const_bit(lsb); } +char vhdl_const_bits::sign_bit() const +{ + return signed_ ? value_[value_.length()-1] : '0'; +} + vhdl_expr *vhdl_const_bits::to_vector(vhdl_type_name_t name, int w) { if (name == VHDL_TYPE_STD_LOGIC_VECTOR) { @@ -256,7 +261,7 @@ vhdl_expr *vhdl_const_bits::to_vector(vhdl_type_name_t name, int w) } else if (name == VHDL_TYPE_SIGNED || name == VHDL_TYPE_UNSIGNED) { // Extend with sign bit - value_.resize(w, value_[0]); + value_.resize(w, sign_bit()); return this; } else @@ -268,6 +273,16 @@ vhdl_expr *vhdl_const_bits::to_integer() return new vhdl_const_int(bits_to_int()); } +vhdl_expr *vhdl_const_bits::resize(int w) +{ + // Rather than generating a call to Resize, when can just sign-extend + // the bits here. As well as looking better, this avoids any ambiguity + // between which of the signed/unsigned versions of Resize to use. + + value_.resize(w, sign_bit()); + return this; +} + vhdl_expr *vhdl_const_bit::to_integer() { return new vhdl_const_int(bit_ == '1' ? 1 : 0); diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index 371b1e701..0c0d9bf25 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -175,8 +175,10 @@ public: vhdl_expr *to_integer(); vhdl_expr *to_std_logic(); vhdl_expr *to_vector(vhdl_type_name_t name, int w); + vhdl_expr *resize(int w); private: int bits_to_int() const; + char sign_bit() const; std::string value_; bool qualified_, signed_;