Skip to content

Commit

Permalink
Improve error message for non-constant bit select in mixed assignment.
Browse files Browse the repository at this point in the history
Report the conflict with the continuous assignment as the reason this
is not allowed.
  • Loading branch information
martinwhitaker committed Feb 3, 2024
1 parent 3a2a1fb commit dd082b8
Showing 1 changed file with 25 additions and 16 deletions.
41 changes: 25 additions & 16 deletions elab_lval.cc
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ NetAssign_*PEIdent::elaborate_lval_var_(Design *des, NetScope *scope,
// XXXX ivl_assert(*this, method_name.nil());
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)
return elaborate_lval_net_word_(des, scope, reg, need_const_idx, is_force);
Expand Down Expand Up @@ -587,17 +587,10 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,

if (debug_elaborate && (reg->type()==NetNet::UNRESOLVED_WIRE)) {
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;
}

// 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()) {
// Special case: this is a slice of a multi-dimensional
// packed array. For example:
Expand All @@ -624,10 +617,17 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
lv->set_part(new NetEConst(verinum(loff)), lwid);

} else {
ivl_assert(*this, reg->type()!=NetNet::UNRESOLVED_WIRE);
unsigned long lwid;
mux = normalize_variable_slice_base(prefix_indices, mux,
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);
}

Expand All @@ -648,8 +648,6 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
lv->set_part(mux, &netvector_t::atom2s8);

} else if (mux) {
ivl_assert(*this, reg->type()!=NetNet::UNRESOLVED_WIRE);

// Non-constant bit mux. Correct the mux for the range
// of the vector, then set the l-value part select
// expression.
Expand All @@ -661,15 +659,26 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
return false;
}
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);

} else if (reg->vector_width() == 1 && reg->sb_is_valid(prefix_indices,lsb)) {
// Constant bit mux that happens to select the only bit
// of the l-value. Don't bother with any select at all.

// NOTE: Don't know what to do about unresolved wires
// here, but they are probably wrong.
ivl_assert(*this, reg->type()!=NetNet::UNRESOLVED_WIRE);
// If there's a continuous assignment, it must be a conflict.
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;
}

} else {
// Constant bit select that does something useful.
Expand Down

0 comments on commit dd082b8

Please sign in to comment.