Extend -gstrict-expr-width to cover unsized numbers.
To be strictly compliant with the standard and compatible with other EDA tools, unsized numbers should be treated as having a fixed size (the same size as an integer). The -gstrict-expr-width option is extended to allow the user to enable this behaviour.
This commit is contained in:
parent
141a23690e
commit
7e82a37fa3
|
|
@ -129,7 +129,9 @@ standard compliant behavior (with some loss in performance).
|
||||||
.B -gstrict-expr-width\fI|\fP-gno-strict-expr-width
|
.B -gstrict-expr-width\fI|\fP-gno-strict-expr-width
|
||||||
Enable or disable (default) strict compliance with the standard rules
|
Enable or disable (default) strict compliance with the standard rules
|
||||||
for determining expression bit lengths. When disabled, the RHS of a
|
for determining expression bit lengths. When disabled, the RHS of a
|
||||||
parameter assignment is evaluated as a lossless expression.
|
parameter assignment is evaluated as a lossless expression, as is any
|
||||||
|
expression containing an unsized constant number, and unsized constant
|
||||||
|
numbers are not truncated to integer width.
|
||||||
.TP 8
|
.TP 8
|
||||||
.B -I\fIincludedir\fP
|
.B -I\fIincludedir\fP
|
||||||
Append directory \fIincludedir\fP to list of directories searched
|
Append directory \fIincludedir\fP to list of directories searched
|
||||||
|
|
|
||||||
10
elab_expr.cc
10
elab_expr.cc
|
|
@ -4721,11 +4721,15 @@ unsigned PENumber::test_width(Design*, NetScope*, width_mode_t&mode)
|
||||||
{
|
{
|
||||||
expr_type_ = IVL_VT_LOGIC;
|
expr_type_ = IVL_VT_LOGIC;
|
||||||
expr_width_ = value_->len();
|
expr_width_ = value_->len();
|
||||||
min_width_ = expr_width_;
|
|
||||||
signed_flag_ = value_->has_sign();
|
signed_flag_ = value_->has_sign();
|
||||||
|
|
||||||
if ((mode < LOSSLESS) && !value_->has_len() && !value_->is_single())
|
if (!value_->has_len() && !value_->is_single()) {
|
||||||
mode = LOSSLESS;
|
if (gn_strict_expr_width_flag)
|
||||||
|
expr_width_ = integer_width;
|
||||||
|
else if (mode < LOSSLESS)
|
||||||
|
mode = LOSSLESS;
|
||||||
|
}
|
||||||
|
min_width_ = expr_width_;
|
||||||
|
|
||||||
return expr_width_;
|
return expr_width_;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
28
lexor.lex
28
lexor.lex
|
|
@ -801,6 +801,22 @@ void lex_end_table()
|
||||||
BEGIN(INITIAL);
|
BEGIN(INITIAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned truncate_to_integer_width(verinum::V*bits, unsigned size)
|
||||||
|
{
|
||||||
|
if (size <= integer_width) return size;
|
||||||
|
|
||||||
|
verinum::V pad = bits[size-1];
|
||||||
|
if (pad == verinum::V1) pad = verinum::V0;
|
||||||
|
|
||||||
|
for (unsigned idx = integer_width; idx < size; idx += 1) {
|
||||||
|
if (bits[idx] != pad) {
|
||||||
|
yywarn(yylloc, "Unsized numeric constant truncated to integer width.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return integer_width;
|
||||||
|
}
|
||||||
|
|
||||||
verinum*make_unsized_binary(const char*txt)
|
verinum*make_unsized_binary(const char*txt)
|
||||||
{
|
{
|
||||||
bool sign_flag = false;
|
bool sign_flag = false;
|
||||||
|
|
@ -858,6 +874,9 @@ verinum*make_unsized_binary(const char*txt)
|
||||||
ptr += 1;
|
ptr += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gn_strict_expr_width_flag && (based_size == 0))
|
||||||
|
size = truncate_to_integer_width(bits, size);
|
||||||
|
|
||||||
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);
|
out->is_single(single_flag);
|
||||||
|
|
@ -926,6 +945,9 @@ verinum*make_unsized_octal(const char*txt)
|
||||||
ptr += 1;
|
ptr += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gn_strict_expr_width_flag && (based_size == 0))
|
||||||
|
size = truncate_to_integer_width(bits, size);
|
||||||
|
|
||||||
verinum*out = new verinum(bits, size, false);
|
verinum*out = new verinum(bits, size, false);
|
||||||
out->has_sign(sign_flag);
|
out->has_sign(sign_flag);
|
||||||
delete[]bits;
|
delete[]bits;
|
||||||
|
|
@ -1003,6 +1025,9 @@ verinum*make_unsized_hex(const char*txt)
|
||||||
ptr += 1;
|
ptr += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gn_strict_expr_width_flag && (based_size == 0))
|
||||||
|
size = truncate_to_integer_width(bits, size);
|
||||||
|
|
||||||
verinum*out = new verinum(bits, size, false);
|
verinum*out = new verinum(bits, size, false);
|
||||||
out->has_sign(sign_flag);
|
out->has_sign(sign_flag);
|
||||||
delete[]bits;
|
delete[]bits;
|
||||||
|
|
@ -1192,6 +1217,9 @@ verinum*make_unsized_dec(const char*ptr)
|
||||||
number represents we do not check for extra bits. */
|
number represents we do not check for extra bits. */
|
||||||
// if (based_size > 0) { }
|
// if (based_size > 0) { }
|
||||||
|
|
||||||
|
if (gn_strict_expr_width_flag && (based_size == 0))
|
||||||
|
size = truncate_to_integer_width(bits, size);
|
||||||
|
|
||||||
verinum*res = new verinum(bits, size, false);
|
verinum*res = new verinum(bits, size, false);
|
||||||
res->has_sign(signed_flag);
|
res->has_sign(signed_flag);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue