Check enum trimmed bits for values with undefined bits
If an enumeration constant has undefined bits then we need to verify that the bits that are trimmed match the MSB of the remaining bits.
This commit is contained in:
parent
e7df9774aa
commit
4f62a0d1f2
|
|
@ -189,16 +189,18 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
|||
verinum cur_value (0);
|
||||
verinum one_value (1);
|
||||
size_t name_idx = 0;
|
||||
// Find the enumeration width.
|
||||
long raw_width = use_enum->packed_width();
|
||||
assert(raw_width > 0);
|
||||
unsigned enum_width = (unsigned)raw_width;
|
||||
// Find the minimum and maximum allowed enumeration values.
|
||||
verinum min_value (0);
|
||||
verinum max_value (0);
|
||||
if (enum_type->signed_flag) {
|
||||
min_value = -pow(verinum(2), verinum(use_enum->packed_width()-1));
|
||||
max_value = pow(verinum(2), verinum(use_enum->packed_width()-1)) -
|
||||
one_value;
|
||||
min_value = -pow(verinum(2), verinum(enum_width-1));
|
||||
max_value = pow(verinum(2), verinum(enum_width-1)) - one_value;
|
||||
} else {
|
||||
max_value = pow(verinum(2), verinum(use_enum->packed_width())) -
|
||||
one_value;
|
||||
max_value = pow(verinum(2), verinum(enum_width)) - one_value;
|
||||
}
|
||||
min_value.has_sign(true);
|
||||
max_value.has_sign(enum_type->signed_flag);
|
||||
|
|
@ -246,7 +248,7 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
|||
(cur_value.has_sign() && (two_state_value < min_value))) {
|
||||
cerr << use_enum->get_fileline()
|
||||
<< ": error: Enumeration name " << cur->name
|
||||
<< " cannot have a value equal to " << cur_value
|
||||
<< " cannot have an out of range value " << cur_value
|
||||
<< "." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
|
@ -264,15 +266,31 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
|||
// The values are explicitly sized to the width of the
|
||||
// base type of the enumeration.
|
||||
verinum tmp_val (0);
|
||||
if (cur_value.len() < (unsigned long)use_enum->packed_width()) {
|
||||
if (cur_value.len() < enum_width) {
|
||||
// Pad the current value if it is narrower than the final
|
||||
// width of the enum.
|
||||
tmp_val = pad_to_width (cur_value, use_enum->packed_width());
|
||||
tmp_val = pad_to_width (cur_value, enum_width);
|
||||
tmp_val.has_len(true);
|
||||
} else {
|
||||
// Truncate an oversized value. We report out of bound
|
||||
// values above. This may create duplicates.
|
||||
tmp_val = verinum(cur_value, use_enum->packed_width());
|
||||
// defined values above. Undefined values need to be
|
||||
// checked here. This may create duplicates.
|
||||
tmp_val = verinum(cur_value, enum_width);
|
||||
// For an undefined value verify that all the trimmed bits
|
||||
// match the MSB of the final enumeration value.
|
||||
if (! cur_value.is_defined()) for (unsigned idx = enum_width;
|
||||
idx < cur_value.len();
|
||||
idx += 1) {
|
||||
if (cur_value[idx] != tmp_val[enum_width-1]) {
|
||||
cerr << use_enum->get_fileline()
|
||||
<< ": error: Enumeration name " << cur->name
|
||||
<< " cannot have trimmed bits that do not "
|
||||
<< "match the enumeration MSB " << cur_value
|
||||
<< "." << endl;
|
||||
des->errors += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
tmp_val.has_sign(enum_type->signed_flag);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue