From 3a2a1fb93dd8b7f0d55f77a4cee75aad6f1c86da Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Sat, 3 Feb 2024 21:16:57 +0000 Subject: [PATCH] Check for mixed assignment conflicts in procedural indexed part selects. --- elab_lval.cc | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/elab_lval.cc b/elab_lval.cc index 61ce9973e..fbc87963c 100644 --- a/elab_lval.cc +++ b/elab_lval.cc @@ -841,7 +841,7 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des, NetAssign_*lv, index_component_t::ctype_t use_sel, bool need_const_idx, - bool /*is_force*/) const + bool is_force) const { if (lv->sig()->data_type() == IVL_VT_STRING) { cerr << get_fileline() << ": error: Cannot index part select assign to a string ('" @@ -944,6 +944,14 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des, rel_base = reg->sb_to_idx(prefix_indices,lsv) + offset; } delete base; + if ((reg->type()==NetNet::UNRESOLVED_WIRE) && !is_force) { + ivl_assert(*this, reg->coerced_to_uwire()); + if (reg->test_part_driven(rel_base+wid-1, rel_base)) { + report_mixed_assignment_conflict_("part select"); + des->errors += 1; + return false; + } + } /* If we cover the entire lvalue just skip the select. */ if (rel_base == 0 && wid == reg->vector_width()) return true; base = new NetEConst(verinum(rel_base)); @@ -985,6 +993,12 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des, des->errors += 1; return false; } + if ((reg->type()==NetNet::UNRESOLVED_WIRE) && !is_force) { + ivl_assert(*this, reg->coerced_to_uwire()); + report_mixed_assignment_conflict_("part select"); + des->errors += 1; + return false; + } ivl_assert(*this, prefix_indices.size()+1 == reg->packed_dims().size()); /* Correct the mux for the range of the vector. */ if (use_sel == index_component_t::SEL_IDX_UP) {