Handle non-overlapping assignments to unpacked arrays.

This commit is contained in:
Stephen Williams 2014-03-28 20:51:30 -07:00
parent e55e832ea0
commit 0accab6ec4
3 changed files with 17 additions and 7 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;