ivl: Support for part selection in multidimensional packed ports assignment.

(cherry picked from commit b4baace4b1)
This commit is contained in:
Maciej Suminski 2016-02-15 15:12:40 +01:00 committed by Martin Whitaker
parent b2281b0e65
commit 30257e0914
2 changed files with 58 additions and 31 deletions

View File

@ -328,39 +328,66 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
return false; return false;
} }
long lidx_tmp = sig->sb_to_idx(prefix_indices, lsb); if (prefix_indices.size()+1 < sig->packed_dims().size()) {
long midx_tmp = sig->sb_to_idx(prefix_indices, msb); // Here we have a slice that doesn't have enough indices
/* Detect reversed indices of a part select. */ // to get to a single slice. For example:
if (lidx_tmp > midx_tmp) { // wire [9:0][5:1] foo
cerr << get_fileline() << ": error: Part select " // ... foo[4:3] ...
<< sig->name() << "[" << msb << ":" // Make this work by finding the indexed slices and
<< lsb << "] indices reversed." << endl; // creating a generated slice that spans the whole
cerr << get_fileline() << ": : Did you mean " // range.
<< sig->name() << "[" << lsb << ":" long loff, moff;
<< msb << "]?" << endl; unsigned long lwid, mwid;
long tmp = midx_tmp; bool lrc;
midx_tmp = lidx_tmp; lrc = sig->sb_to_slice(prefix_indices, lsb, loff, lwid);
lidx_tmp = tmp; ivl_assert(*this, lrc);
des->errors += 1; lrc = sig->sb_to_slice(prefix_indices, msb, moff, mwid);
} ivl_assert(*this, lrc);
ivl_assert(*this, lwid == mwid);
/* Warn about a part select that is out of range. */ if (moff > loff) {
if (midx_tmp >= (long)sig->vector_width() || lidx_tmp < 0) { lidx = loff;
cerr << get_fileline() << ": warning: Part select " midx = moff + mwid - 1;
<< sig->name(); } else {
if (sig->unpacked_dimensions() > 0) { lidx = moff;
cerr << "[]"; midx = loff + lwid - 1;
} }
cerr << "[" << msb << ":" << lsb } else {
<< "] is out of range." << endl; long lidx_tmp = sig->sb_to_idx(prefix_indices, lsb);
} long midx_tmp = sig->sb_to_idx(prefix_indices, msb);
/* This is completely out side the signal so just skip it. */
if (lidx_tmp >= (long)sig->vector_width() || midx_tmp < 0) {
return false;
}
midx = midx_tmp; /* Detect reversed indices of a part select. */
lidx = lidx_tmp; if (lidx_tmp > midx_tmp) {
cerr << get_fileline() << ": error: Part select "
<< sig->name() << "[" << msb << ":"
<< lsb << "] indices reversed." << endl;
cerr << get_fileline() << ": : Did you mean "
<< sig->name() << "[" << lsb << ":"
<< msb << "]?" << endl;
long tmp = midx_tmp;
midx_tmp = lidx_tmp;
lidx_tmp = tmp;
des->errors += 1;
}
/* Warn about a part select that is out of range. */
if (midx_tmp >= (long)sig->vector_width() || lidx_tmp < 0) {
cerr << get_fileline() << ": warning: Part select "
<< sig->name();
if (sig->unpacked_dimensions() > 0) {
cerr << "[]";
}
cerr << "[" << msb << ":" << lsb
<< "] is out of range." << endl;
}
/* This is completely out side the signal so just skip it. */
if (lidx_tmp >= (long)sig->vector_width() || midx_tmp < 0) {
return false;
}
midx = midx_tmp;
lidx = lidx_tmp;
}
break; break;
} }

View File

@ -1440,7 +1440,7 @@ bool evaluate_index_prefix(Design*des, NetScope*scope,
return false; return false;
} }
prefix_indices .push_back(tmp); prefix_indices.push_back(tmp);
delete texpr; delete texpr;
} }