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
|
||||
Enable or disable (default) strict compliance with the standard rules
|
||||
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
|
||||
.B -I\fIincludedir\fP
|
||||
Append directory \fIincludedir\fP to list of directories searched
|
||||
|
|
|
|||
|
|
@ -4721,11 +4721,15 @@ unsigned PENumber::test_width(Design*, NetScope*, width_mode_t&mode)
|
|||
{
|
||||
expr_type_ = IVL_VT_LOGIC;
|
||||
expr_width_ = value_->len();
|
||||
min_width_ = expr_width_;
|
||||
signed_flag_ = value_->has_sign();
|
||||
|
||||
if ((mode < LOSSLESS) && !value_->has_len() && !value_->is_single())
|
||||
if (!value_->has_len() && !value_->is_single()) {
|
||||
if (gn_strict_expr_width_flag)
|
||||
expr_width_ = integer_width;
|
||||
else if (mode < LOSSLESS)
|
||||
mode = LOSSLESS;
|
||||
}
|
||||
min_width_ = expr_width_;
|
||||
|
||||
return expr_width_;
|
||||
}
|
||||
|
|
|
|||
28
lexor.lex
28
lexor.lex
|
|
@ -801,6 +801,22 @@ void lex_end_table()
|
|||
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)
|
||||
{
|
||||
bool sign_flag = false;
|
||||
|
|
@ -858,6 +874,9 @@ verinum*make_unsized_binary(const char*txt)
|
|||
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);
|
||||
out->has_sign(sign_flag);
|
||||
out->is_single(single_flag);
|
||||
|
|
@ -926,6 +945,9 @@ verinum*make_unsized_octal(const char*txt)
|
|||
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);
|
||||
out->has_sign(sign_flag);
|
||||
delete[]bits;
|
||||
|
|
@ -1003,6 +1025,9 @@ verinum*make_unsized_hex(const char*txt)
|
|||
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);
|
||||
out->has_sign(sign_flag);
|
||||
delete[]bits;
|
||||
|
|
@ -1192,6 +1217,9 @@ verinum*make_unsized_dec(const char*ptr)
|
|||
number represents we do not check for extra bits. */
|
||||
// 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);
|
||||
res->has_sign(signed_flag);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue