From 3cc201834653eea8a409fef69a6b82e13a4b6bb3 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Thu, 22 Jan 2009 21:58:01 +0000 Subject: [PATCH] Emit VHDL hex constants for some unsigned bits strings This patch changes the output of VHDL unsigned bit strings which are 4, 8, 16, 32, or 64 bits to use VHDL hex string constants. So the following: "00000001" Becomes X"01" Which is much easier to read --- tgt-vhdl/cast.cc | 8 ++++---- tgt-vhdl/vhdl_syntax.cc | 40 +++++++++++++++++++++++++++++++--------- tgt-vhdl/vhdl_syntax.hh | 3 ++- 3 files changed, 37 insertions(+), 14 deletions(-) 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_;