Restore some master branch fixes lost in the vec4-stack merge.

This commit is contained in:
Martin Whitaker 2014-12-07 12:10:15 +00:00
parent 105521b547
commit 60ab1daa1f
2 changed files with 20 additions and 28 deletions

View File

@ -201,16 +201,15 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
verinum one_value ((uint64_t)1, enum_width); verinum one_value ((uint64_t)1, enum_width);
one_value.has_sign(enum_type->signed_flag); one_value.has_sign(enum_type->signed_flag);
// Find the maximum allowed enumeration value. // Find the maximum allowed enumeration value.
verinum min_value (0);
verinum max_value (0); verinum max_value (0);
if (enum_type->signed_flag) { if (enum_type->signed_flag) {
min_value = -pow(verinum(2), verinum(enum_width-1));
max_value = pow(verinum(2), verinum(enum_width-1)) - one_value; max_value = pow(verinum(2), verinum(enum_width-1)) - one_value;
} else { } else {
max_value = pow(verinum(2), verinum(enum_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); max_value.has_sign(enum_type->signed_flag);
// Variable to indicate when a defined value wraps.
bool implicit_wrapped = false;
// Process the enumeration definition. // Process the enumeration definition.
for (list<named_pexpr_t>::const_iterator cur = enum_type->names->begin() for (list<named_pexpr_t>::const_iterator cur = enum_type->names->begin()
; cur != enum_type->names->end() ; ++ cur, name_idx += 1) { ; cur != enum_type->names->end() ; ++ cur, name_idx += 1) {
@ -229,6 +228,8 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
continue; continue;
} }
cur_value = val_const->value(); cur_value = val_const->value();
// Clear the implicit wrapped flag if a parameter is given.
implicit_wrapped = false;
// A 2-state value can not have a constant with X/Z bits. // A 2-state value can not have a constant with X/Z bits.
if (enum_type->base_type==IVL_VT_BOOL && if (enum_type->base_type==IVL_VT_BOOL &&
@ -335,24 +336,8 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
continue; continue;
} }
// Cast any undefined bits to zero so the comparisons below // Check to see if an implicitly wrapped value is used.
// return just true (1) or false (0). if (implicit_wrapped) {
verinum two_state_value = cur_value;
two_state_value.cast_to_int2();
// The enumeration value must fit into the enumeration bits.
if (!cur_value.is_defined()) {
if (cur_value.len() > (unsigned long)use_enum->packed_width()) {
cerr << use_enum->get_fileline()
<< ": error: Enumeration name " << cur->name
<< " value=" << cur_value
<< " is too wide for enumeration base type." << endl;
des->errors += 1;
}
} else if ((two_state_value > max_value) ||
(cur_value.has_sign() && (two_state_value < min_value))) {
cerr << use_enum->get_fileline() cerr << use_enum->get_fileline()
<< ": error: Enumeration name " << cur->name << ": error: Enumeration name " << cur->name
<< " has an inferred value that overflowed." << endl; << " has an inferred value that overflowed." << endl;
@ -385,6 +370,7 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
// In case the next name has an implicit value, // In case the next name has an implicit value,
// increment the current value by one. // increment the current value by one.
if (cur_value.is_defined()) { if (cur_value.is_defined()) {
if (cur_value == max_value) implicit_wrapped = true;
cur_value = cur_value + one_value; cur_value = cur_value + one_value;
} }
} }

View File

@ -531,18 +531,24 @@ bool NetCase::synth_async(Design*des, NetScope*scope,
statement_map[sel_idx] = items_[item].statement; statement_map[sel_idx] = items_[item].statement;
} }
// The mux_size is the number of inputs that are selected. // The minimum selector width is the number of inputs that
unsigned mux_size = max_guard_value + 1; // are selected, rounded up to the nearest power of 2.
unsigned sel_need = ceil(log2(mux_size)); unsigned sel_need = ceil(log2(max_guard_value + 1));
// If the sel_width can select more than just the explicit // If the sel_width can select more than just the explicit
// guard values, and there is a default statement, then adjust // guard values, and there is a default statement, then adjust
// the mux size to allow for the implicit selections. // the sel_need to allow for the implicit selections.
if (statement_default && (sel_width > sel_need)) { if (statement_default && (sel_width > sel_need))
sel_need += 1; sel_need += 1;
ivl_assert(*this, sel_need < sizeof mux_size);
mux_size = 1<<sel_need; // The mux size is always an exact power of 2.
if (sel_need >= 8*sizeof(unsigned)) {
cerr << get_fileline() << ": sorry: mux select width of "
<< sel_need << " bits is too large for synthesis." << endl;
des->errors += 1;
return false;
} }
unsigned mux_size = 1U << sel_need;
if (debug_synth2) { if (debug_synth2) {
cerr << get_fileline() << ": NetCase::synth_async: " cerr << get_fileline() << ": NetCase::synth_async: "