Improve error message for non-constant bit select in mixed assignment.
Report the conflict with the continuous assignment as the reason this is not allowed.
This commit is contained in:
parent
3a2a1fb93d
commit
dd082b849b
41
elab_lval.cc
41
elab_lval.cc
|
|
@ -293,7 +293,7 @@ NetAssign_*PEIdent::elaborate_lval_var_(Design *des, NetScope *scope,
|
||||||
// XXXX ivl_assert(*this, method_name.nil());
|
// XXXX ivl_assert(*this, method_name.nil());
|
||||||
ivl_assert(*this, tail_path.empty());
|
ivl_assert(*this, tail_path.empty());
|
||||||
|
|
||||||
bool need_const_idx = is_cassign || is_force || (reg->type()==NetNet::UNRESOLVED_WIRE);
|
bool need_const_idx = is_cassign || is_force;
|
||||||
|
|
||||||
if (reg->unpacked_dimensions() > 0)
|
if (reg->unpacked_dimensions() > 0)
|
||||||
return elaborate_lval_net_word_(des, scope, reg, need_const_idx, is_force);
|
return elaborate_lval_net_word_(des, scope, reg, need_const_idx, is_force);
|
||||||
|
|
@ -587,17 +587,10 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
|
||||||
|
|
||||||
if (debug_elaborate && (reg->type()==NetNet::UNRESOLVED_WIRE)) {
|
if (debug_elaborate && (reg->type()==NetNet::UNRESOLVED_WIRE)) {
|
||||||
cerr << get_fileline() << ": PEIdent::elaborate_lval_net_bit_: "
|
cerr << get_fileline() << ": PEIdent::elaborate_lval_net_bit_: "
|
||||||
<< "Try to assign bits of unresolved wire."
|
<< "Try to assign bits of variable which is also continuously assigned."
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notice that we might be assigning to an unresolved wire. This
|
|
||||||
// can happen if we are actually assigning to a variable that
|
|
||||||
// has a partial continuous assignment to it. If that is the
|
|
||||||
// case, then the bit select must be constant.
|
|
||||||
ivl_assert(*this, need_const_idx || (reg->type()!=NetNet::UNRESOLVED_WIRE));
|
|
||||||
|
|
||||||
|
|
||||||
if (prefix_indices.size()+2 <= reg->packed_dims().size()) {
|
if (prefix_indices.size()+2 <= reg->packed_dims().size()) {
|
||||||
// Special case: this is a slice of a multi-dimensional
|
// Special case: this is a slice of a multi-dimensional
|
||||||
// packed array. For example:
|
// packed array. For example:
|
||||||
|
|
@ -624,10 +617,17 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
|
||||||
lv->set_part(new NetEConst(verinum(loff)), lwid);
|
lv->set_part(new NetEConst(verinum(loff)), lwid);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ivl_assert(*this, reg->type()!=NetNet::UNRESOLVED_WIRE);
|
|
||||||
unsigned long lwid;
|
unsigned long lwid;
|
||||||
mux = normalize_variable_slice_base(prefix_indices, mux,
|
mux = normalize_variable_slice_base(prefix_indices, mux,
|
||||||
reg, lwid);
|
reg, lwid);
|
||||||
|
|
||||||
|
if ((reg->type()==NetNet::UNRESOLVED_WIRE) && !is_force) {
|
||||||
|
ivl_assert(*this, reg->coerced_to_uwire());
|
||||||
|
report_mixed_assignment_conflict_("slice");
|
||||||
|
des->errors += 1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
lv->set_part(mux, lwid);
|
lv->set_part(mux, lwid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -648,8 +648,6 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
|
||||||
lv->set_part(mux, &netvector_t::atom2s8);
|
lv->set_part(mux, &netvector_t::atom2s8);
|
||||||
|
|
||||||
} else if (mux) {
|
} else if (mux) {
|
||||||
ivl_assert(*this, reg->type()!=NetNet::UNRESOLVED_WIRE);
|
|
||||||
|
|
||||||
// Non-constant bit mux. Correct the mux for the range
|
// Non-constant bit mux. Correct the mux for the range
|
||||||
// of the vector, then set the l-value part select
|
// of the vector, then set the l-value part select
|
||||||
// expression.
|
// expression.
|
||||||
|
|
@ -661,15 +659,26 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
mux = normalize_variable_bit_base(prefix_indices, mux, reg);
|
mux = normalize_variable_bit_base(prefix_indices, mux, reg);
|
||||||
|
|
||||||
|
if ((reg->type()==NetNet::UNRESOLVED_WIRE) && !is_force) {
|
||||||
|
ivl_assert(*this, reg->coerced_to_uwire());
|
||||||
|
report_mixed_assignment_conflict_("bit select");
|
||||||
|
des->errors += 1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
lv->set_part(mux, 1);
|
lv->set_part(mux, 1);
|
||||||
|
|
||||||
} else if (reg->vector_width() == 1 && reg->sb_is_valid(prefix_indices,lsb)) {
|
} else if (reg->vector_width() == 1 && reg->sb_is_valid(prefix_indices,lsb)) {
|
||||||
// Constant bit mux that happens to select the only bit
|
// Constant bit mux that happens to select the only bit
|
||||||
// of the l-value. Don't bother with any select at all.
|
// of the l-value. Don't bother with any select at all.
|
||||||
|
// If there's a continuous assignment, it must be a conflict.
|
||||||
// NOTE: Don't know what to do about unresolved wires
|
if ((reg->type()==NetNet::UNRESOLVED_WIRE) && !is_force) {
|
||||||
// here, but they are probably wrong.
|
ivl_assert(*this, reg->coerced_to_uwire());
|
||||||
ivl_assert(*this, reg->type()!=NetNet::UNRESOLVED_WIRE);
|
report_mixed_assignment_conflict_("bit select");
|
||||||
|
des->errors += 1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Constant bit select that does something useful.
|
// Constant bit select that does something useful.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue