SystemVerilog 'N bit vectors.
Adds a is_single_ flag to the verinum class to indicate it came from a 'N bit vector and needs to be handled accordingly.
This commit is contained in:
parent
97d2389cb0
commit
b6ff4039b1
|
|
@ -3166,7 +3166,7 @@ unsigned PENumber::test_width(Design*, NetScope*, width_mode_t&mode)
|
||||||
min_width_ = 1;
|
min_width_ = 1;
|
||||||
signed_flag_ = value_->has_sign();
|
signed_flag_ = value_->has_sign();
|
||||||
|
|
||||||
if ((mode < LOSSLESS) && !value_->has_len())
|
if ((mode < LOSSLESS) && !value_->has_len() && !value_->is_single())
|
||||||
mode = LOSSLESS;
|
mode = LOSSLESS;
|
||||||
|
|
||||||
return expr_width_;
|
return expr_width_;
|
||||||
|
|
|
||||||
19
lexor.lex
19
lexor.lex
|
|
@ -329,6 +329,14 @@ TU [munpf]
|
||||||
return BASED_NUMBER; }
|
return BASED_NUMBER; }
|
||||||
\'[sS]?[hH][ \t]*[0-9a-fA-FxzXZ_\?]+ { yylval.number = make_unsized_hex(yytext);
|
\'[sS]?[hH][ \t]*[0-9a-fA-FxzXZ_\?]+ { yylval.number = make_unsized_hex(yytext);
|
||||||
return BASED_NUMBER; }
|
return BASED_NUMBER; }
|
||||||
|
\'[01xzXZ] {
|
||||||
|
if (generation_flag < GN_VER2005_SV) {
|
||||||
|
cerr << yylloc.text << ":" << yylloc.first_line << ": warning: "
|
||||||
|
<< "Using SystemVerilog 'N bit vector. Use at least "
|
||||||
|
<< "-g2005-sv to remove this warning." << endl;
|
||||||
|
}
|
||||||
|
yylval.number = make_unsized_binary(yytext);
|
||||||
|
return BASED_NUMBER; }
|
||||||
|
|
||||||
[0-9][0-9_]* {
|
[0-9][0-9_]* {
|
||||||
yylval.number = make_unsized_dec(yytext);
|
yylval.number = make_unsized_dec(yytext);
|
||||||
|
|
@ -684,6 +692,7 @@ void lex_end_table()
|
||||||
verinum*make_unsized_binary(const char*txt)
|
verinum*make_unsized_binary(const char*txt)
|
||||||
{
|
{
|
||||||
bool sign_flag = false;
|
bool sign_flag = false;
|
||||||
|
bool single_flag = false;
|
||||||
const char*ptr = txt;
|
const char*ptr = txt;
|
||||||
assert(*ptr == '\'');
|
assert(*ptr == '\'');
|
||||||
ptr += 1;
|
ptr += 1;
|
||||||
|
|
@ -693,8 +702,13 @@ verinum*make_unsized_binary(const char*txt)
|
||||||
ptr += 1;
|
ptr += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(tolower(*ptr) == 'b');
|
assert((tolower(*ptr) == 'b') || (generation_flag >= GN_VER2005_SV));
|
||||||
ptr += 1;
|
if (tolower(*ptr) == 'b') {
|
||||||
|
ptr += 1;
|
||||||
|
} else {
|
||||||
|
assert(sign_flag == false);
|
||||||
|
single_flag = true;
|
||||||
|
}
|
||||||
|
|
||||||
while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
|
while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
|
||||||
ptr += 1;
|
ptr += 1;
|
||||||
|
|
@ -734,6 +748,7 @@ verinum*make_unsized_binary(const char*txt)
|
||||||
|
|
||||||
verinum*out = new verinum(bits, size, false);
|
verinum*out = new verinum(bits, size, false);
|
||||||
out->has_sign(sign_flag);
|
out->has_sign(sign_flag);
|
||||||
|
out->is_single(single_flag);
|
||||||
delete[]bits;
|
delete[]bits;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
27
verinum.cc
27
verinum.cc
|
|
@ -43,12 +43,12 @@ extern "C" long int lround(double x)
|
||||||
static verinum::V add_with_carry(verinum::V l, verinum::V r, verinum::V&c);
|
static verinum::V add_with_carry(verinum::V l, verinum::V r, verinum::V&c);
|
||||||
|
|
||||||
verinum::verinum()
|
verinum::verinum()
|
||||||
: bits_(0), nbits_(0), has_len_(false), has_sign_(false), string_flag_(false)
|
: bits_(0), nbits_(0), has_len_(false), has_sign_(false), is_single_(false), string_flag_(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
verinum::verinum(const V*bits, unsigned nbits, bool has_len__)
|
verinum::verinum(const V*bits, unsigned nbits, bool has_len__)
|
||||||
: has_len_(has_len__), has_sign_(false), string_flag_(false)
|
: has_len_(has_len__), has_sign_(false), is_single_(false), string_flag_(false)
|
||||||
{
|
{
|
||||||
nbits_ = nbits;
|
nbits_ = nbits;
|
||||||
bits_ = new V [nbits];
|
bits_ = new V [nbits];
|
||||||
|
|
@ -111,7 +111,7 @@ static string process_verilog_string_quotes(const string&str)
|
||||||
}
|
}
|
||||||
|
|
||||||
verinum::verinum(const string&s)
|
verinum::verinum(const string&s)
|
||||||
: has_len_(true), has_sign_(false), string_flag_(true)
|
: has_len_(true), has_sign_(false), is_single_(false), string_flag_(true)
|
||||||
{
|
{
|
||||||
string str = process_verilog_string_quotes(s);
|
string str = process_verilog_string_quotes(s);
|
||||||
nbits_ = str.length() * 8;
|
nbits_ = str.length() * 8;
|
||||||
|
|
@ -149,7 +149,7 @@ verinum::verinum(const string&s)
|
||||||
}
|
}
|
||||||
|
|
||||||
verinum::verinum(verinum::V val, unsigned n, bool h)
|
verinum::verinum(verinum::V val, unsigned n, bool h)
|
||||||
: has_len_(h), has_sign_(false), string_flag_(false)
|
: has_len_(h), has_sign_(false), is_single_(false), string_flag_(false)
|
||||||
{
|
{
|
||||||
nbits_ = n;
|
nbits_ = n;
|
||||||
bits_ = new V[nbits_];
|
bits_ = new V[nbits_];
|
||||||
|
|
@ -158,7 +158,7 @@ verinum::verinum(verinum::V val, unsigned n, bool h)
|
||||||
}
|
}
|
||||||
|
|
||||||
verinum::verinum(uint64_t val, unsigned n)
|
verinum::verinum(uint64_t val, unsigned n)
|
||||||
: has_len_(true), has_sign_(false), string_flag_(false)
|
: has_len_(true), has_sign_(false), is_single_(false), string_flag_(false)
|
||||||
{
|
{
|
||||||
nbits_ = n;
|
nbits_ = n;
|
||||||
bits_ = new V[nbits_];
|
bits_ = new V[nbits_];
|
||||||
|
|
@ -171,7 +171,7 @@ verinum::verinum(uint64_t val, unsigned n)
|
||||||
/* The second argument is not used! It is there to make this
|
/* The second argument is not used! It is there to make this
|
||||||
* constructor unique. */
|
* constructor unique. */
|
||||||
verinum::verinum(double val, bool)
|
verinum::verinum(double val, bool)
|
||||||
: has_len_(false), has_sign_(true), string_flag_(false)
|
: has_len_(false), has_sign_(true), is_single_(false), string_flag_(false)
|
||||||
{
|
{
|
||||||
bool is_neg = false;
|
bool is_neg = false;
|
||||||
double fraction;
|
double fraction;
|
||||||
|
|
@ -281,6 +281,7 @@ verinum::verinum(const verinum&that)
|
||||||
bits_ = new V[nbits_];
|
bits_ = new V[nbits_];
|
||||||
has_len_ = that.has_len_;
|
has_len_ = that.has_len_;
|
||||||
has_sign_ = that.has_sign_;
|
has_sign_ = that.has_sign_;
|
||||||
|
is_single_ = that.is_single_;
|
||||||
for (unsigned idx = 0 ; idx < nbits_ ; idx += 1)
|
for (unsigned idx = 0 ; idx < nbits_ ; idx += 1)
|
||||||
bits_[idx] = that.bits_[idx];
|
bits_[idx] = that.bits_[idx];
|
||||||
}
|
}
|
||||||
|
|
@ -292,6 +293,7 @@ verinum::verinum(const verinum&that, unsigned nbits)
|
||||||
bits_ = new V[nbits_];
|
bits_ = new V[nbits_];
|
||||||
has_len_ = true;
|
has_len_ = true;
|
||||||
has_sign_ = that.has_sign_;
|
has_sign_ = that.has_sign_;
|
||||||
|
is_single_ = false;
|
||||||
|
|
||||||
unsigned copy = nbits;
|
unsigned copy = nbits;
|
||||||
if (copy > that.nbits_)
|
if (copy > that.nbits_)
|
||||||
|
|
@ -300,7 +302,7 @@ verinum::verinum(const verinum&that, unsigned nbits)
|
||||||
bits_[idx] = that.bits_[idx];
|
bits_[idx] = that.bits_[idx];
|
||||||
|
|
||||||
if (copy < nbits_) {
|
if (copy < nbits_) {
|
||||||
if (has_sign_) {
|
if (has_sign_ || that.is_single_) {
|
||||||
for (unsigned idx = copy ; idx < nbits_ ; idx += 1)
|
for (unsigned idx = copy ; idx < nbits_ ; idx += 1)
|
||||||
bits_[idx] = bits_[idx-1];
|
bits_[idx] = bits_[idx-1];
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -311,7 +313,7 @@ verinum::verinum(const verinum&that, unsigned nbits)
|
||||||
}
|
}
|
||||||
|
|
||||||
verinum::verinum(int64_t that)
|
verinum::verinum(int64_t that)
|
||||||
: has_len_(false), has_sign_(true), string_flag_(false)
|
: has_len_(false), has_sign_(true), is_single_(false), string_flag_(false)
|
||||||
{
|
{
|
||||||
int64_t tmp;
|
int64_t tmp;
|
||||||
|
|
||||||
|
|
@ -348,6 +350,7 @@ verinum& verinum::operator= (const verinum&that)
|
||||||
|
|
||||||
has_len_ = that.has_len_;
|
has_len_ = that.has_len_;
|
||||||
has_sign_ = that.has_sign_;
|
has_sign_ = that.has_sign_;
|
||||||
|
is_single_ = that.is_single_;
|
||||||
string_flag_ = that.string_flag_;
|
string_flag_ = that.string_flag_;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -570,9 +573,9 @@ verinum pad_to_width(const verinum&that, unsigned width)
|
||||||
}
|
}
|
||||||
|
|
||||||
verinum::V pad = that[that.len()-1];
|
verinum::V pad = that[that.len()-1];
|
||||||
if (pad==verinum::V1 && !that.has_sign())
|
if (pad==verinum::V1 && !that.has_sign() && !that.is_single())
|
||||||
pad = verinum::V0;
|
pad = verinum::V0;
|
||||||
if (that.has_len() && !that.has_sign()) {
|
if (that.has_len() && !that.has_sign() && !that.is_single()) {
|
||||||
if (pad==verinum::Vx)
|
if (pad==verinum::Vx)
|
||||||
pad = verinum::V0;
|
pad = verinum::V0;
|
||||||
if (pad==verinum::Vz)
|
if (pad==verinum::Vz)
|
||||||
|
|
@ -606,9 +609,9 @@ verinum cast_to_width(const verinum&that, unsigned width)
|
||||||
}
|
}
|
||||||
|
|
||||||
verinum::V pad = that[that.len()-1];
|
verinum::V pad = that[that.len()-1];
|
||||||
if (pad==verinum::V1 && !that.has_sign())
|
if (pad==verinum::V1 && !that.has_sign() && !that.is_single())
|
||||||
pad = verinum::V0;
|
pad = verinum::V0;
|
||||||
if (that.has_len() && !that.has_sign()) {
|
if (that.has_len() && !that.has_sign() && !that.is_single()) {
|
||||||
if (pad==verinum::Vx)
|
if (pad==verinum::Vx)
|
||||||
pad = verinum::V0;
|
pad = verinum::V0;
|
||||||
if (pad==verinum::Vz)
|
if (pad==verinum::Vz)
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,10 @@ class verinum {
|
||||||
bool has_sign(bool flag) { has_sign_ = flag; return has_sign_; }
|
bool has_sign(bool flag) { has_sign_ = flag; return has_sign_; }
|
||||||
bool has_sign() const { return has_sign_; }
|
bool has_sign() const { return has_sign_; }
|
||||||
|
|
||||||
|
// A number "is single" if it comes from a SystemVerilog 'N bit vector
|
||||||
|
bool is_single(bool flag) { is_single_ = flag; return is_single_; }
|
||||||
|
bool is_single() const { return is_single_; }
|
||||||
|
|
||||||
// A number is "defined" if there are no x or z bits in its value.
|
// A number is "defined" if there are no x or z bits in its value.
|
||||||
bool is_defined() const;
|
bool is_defined() const;
|
||||||
bool is_zero() const;
|
bool is_zero() const;
|
||||||
|
|
@ -103,6 +107,7 @@ class verinum {
|
||||||
unsigned nbits_;
|
unsigned nbits_;
|
||||||
bool has_len_;
|
bool has_len_;
|
||||||
bool has_sign_;
|
bool has_sign_;
|
||||||
|
bool is_single_;
|
||||||
|
|
||||||
// These are some convenience flags that help us do a better
|
// These are some convenience flags that help us do a better
|
||||||
// job of pretty-printing values.
|
// job of pretty-printing values.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue