diff --git a/tgt-vhdl/cast.cc b/tgt-vhdl/cast.cc index d01016c6a..d99575de8 100644 --- a/tgt-vhdl/cast.cc +++ b/tgt-vhdl/cast.cc @@ -221,13 +221,13 @@ vhdl_expr *vhdl_const_int::to_vector(vhdl_type_name_t name, int w) return vhdl_expr::to_vector(name, w); } -int vhdl_const_bits::bits_to_int() const +int64_t 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--) { + int64_t result = 0, bit; + for (int i = sizeof(int64_t)*8 - 1; i >= 0; i--) { if (i > (int)value_.size() - 1) - bit = msb == '1' ? 1 : 0; + bit = (msb == '1' && signed_) ? 1 : 0; else bit = value_[i] == '1' ? 1 : 0; result = (result << 1) | bit; diff --git a/tgt-vhdl/vhdl_syntax.cc b/tgt-vhdl/vhdl_syntax.cc index 2aeea3f3a..fd00fb38f 100644 --- a/tgt-vhdl/vhdl_syntax.cc +++ b/tgt-vhdl/vhdl_syntax.cc @@ -26,6 +26,9 @@ #include #include #include +#include + +using namespace std; vhdl_scope::vhdl_scope() : parent_(NULL), init_(false), sig_assign_(true) @@ -564,17 +567,36 @@ vhdl_const_bits::vhdl_const_bits(const char *value, int width, bool issigned) value_.push_back(*value++); } +// True if char is not '1' or '0' +static bool is_meta_bit(char c) +{ + return c != '1' && c != '0'; +} + +// True if the bit strings contains characters other than '1' and '0' +bool vhdl_const_bits::has_meta_bits() const +{ + return find_if(value_.begin(), value_.end(), is_meta_bit) != value_.end(); +} + void vhdl_const_bits::emit(std::ostream &of, int level) const { if (qualified_) - of << (signed_ ? "signed" : "unsigned") << "'(\""; - else - of << "\""; + of << (signed_ ? "signed" : "unsigned") << "'("; - // The bits appear to be in reverse order - std::string::const_reverse_iterator it; - for (it = value_.rbegin(); it != value_.rend(); ++it) - of << vl_to_vhdl_bit(*it); + // If it's a width we can write in hex, prefer that over binary + size_t bits = value_.size(); + if (!signed_ && !has_meta_bits() && bits <= 64 && bits % 4 == 0) { + int64_t ival = bits_to_int(); + of << "X\"" << hex << setfill('0') << setw(bits / 4) << ival; + } + else { + of << "\""; + + std::string::const_reverse_iterator it; + for (it = value_.rbegin(); it != value_.rend(); ++it) + of << vl_to_vhdl_bit(*it); + } of << (qualified_ ? "\")" : "\""); } @@ -586,7 +608,7 @@ void vhdl_const_bit::emit(std::ostream &of, int level) const void vhdl_const_int::emit(std::ostream &of, int level) const { - of << value_; + of << dec << value_; // We need to find a way to display a comment, since $time, etc. add one. } @@ -597,7 +619,7 @@ void vhdl_const_bool::emit(std::ostream &of, int level) const void vhdl_const_time::emit(std::ostream &of, int level) const { - of << value_; + of << dec << value_; switch (units_) { case TIME_UNIT_NS: of << " ns"; diff --git a/tgt-vhdl/vhdl_syntax.hh b/tgt-vhdl/vhdl_syntax.hh index a36fdfa48..6cb14b939 100644 --- a/tgt-vhdl/vhdl_syntax.hh +++ b/tgt-vhdl/vhdl_syntax.hh @@ -181,8 +181,9 @@ public: vhdl_expr *to_vector(vhdl_type_name_t name, int w); vhdl_expr *resize(int w); private: - int bits_to_int() const; + int64_t bits_to_int() const; char sign_bit() const; + bool has_meta_bits() const; std::string value_; bool qualified_, signed_;