From 0accab6ec4d56874865ecdba663f23a038305caa Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Fri, 28 Mar 2014 20:51:30 -0700 Subject: [PATCH] Handle non-overlapping assignments to unpacked arrays. --- elab_net.cc | 2 +- netlist.cc | 16 ++++++++++++---- netlist.h | 6 ++++-- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/elab_net.cc b/elab_net.cc index 7270a8aff..0f5deabfb 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -735,7 +735,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope, unsigned subnet_wid = midx-lidx+1; /* Check if the l-value bits are double-driven. */ - if (sig->type() == NetNet::UNRESOLVED_WIRE && sig->test_and_set_part_driver(midx,lidx)) { + if (sig->type() == NetNet::UNRESOLVED_WIRE && sig->test_and_set_part_driver(midx,lidx, widx_flag? widx : 0)) { cerr << get_fileline() << ": error: Unresolved net/uwire " << sig->name() << " cannot have multiple drivers." << endl; des->errors += 1; diff --git a/netlist.cc b/netlist.cc index e66c9c7c9..e43c52046 100644 --- a/netlist.cc +++ b/netlist.cc @@ -868,17 +868,25 @@ unsigned NetNet::peek_eref() const * Test each of the bits in the range, and set them. If any bits are * already set then return true. */ -bool NetNet::test_and_set_part_driver(unsigned pmsb, unsigned plsb) +bool NetNet::test_and_set_part_driver(unsigned pmsb, unsigned plsb, int widx) { if (lref_mask_.empty()) - lref_mask_.resize(vector_width()); + lref_mask_.resize(vector_width() * pin_count()); + + // If indexing a word that doesn't exist, then pretend this is + // never driven. + if (widx < 0) + return false; + if (widx >= (int)pin_count()) + return false; bool rc = false; + unsigned word_base = vector_width() * widx; for (unsigned idx = plsb ; idx <= pmsb ; idx += 1) { - if (lref_mask_[idx]) + if (lref_mask_[idx+word_base]) rc = true; else - lref_mask_[idx] = true; + lref_mask_[idx+word_base] = true; } return rc; diff --git a/netlist.h b/netlist.h index a373ff018..58d2e5d7f 100644 --- a/netlist.h +++ b/netlist.h @@ -750,8 +750,10 @@ class NetNet : public NetObj, public PortType { // Treating this node as a uwire, this function tests whether // any bits in the canonical part are already driven. This is - // only useful for UNRESOLVED_WIRE objects. - bool test_and_set_part_driver(unsigned msb, unsigned lsb); + // only useful for UNRESOLVED_WIRE objects. The msb and lsb + // are the part select of the signal, and the widx is the word + // index if this is an unpacked array. + bool test_and_set_part_driver(unsigned msb, unsigned lsb, int widx =0); unsigned get_refs() const;