Handle ranges of slices.
This commit is contained in:
parent
48b186576e
commit
69de1da172
31
elab_expr.cc
31
elab_expr.cc
|
|
@ -3668,8 +3668,35 @@ NetExpr* PEIdent::elaborate_expr_net_part_(Design*des, NetScope*scope,
|
|||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
long sb_lsb = net->sig()->sb_to_idx(prefix_indices, lsv);
|
||||
long sb_msb = net->sig()->sb_to_idx(prefix_indices, msv);
|
||||
long sb_lsb, sb_msb;
|
||||
if (prefix_indices.size()+1 < net->sig()->packed_dims().size()) {
|
||||
// Here we have a slice that doesn't have enough indices
|
||||
// to get to a single slice. For example:
|
||||
// wire [9:0][5:1] foo
|
||||
// ... foo[4:3] ...
|
||||
// Make this work by finding the indexed slices and
|
||||
// creating a generated slice that spans the whole
|
||||
// range.
|
||||
long loff, moff;
|
||||
unsigned long lwid, mwid;
|
||||
bool lrc;
|
||||
lrc = net->sig()->sb_to_slice(prefix_indices, lsv, loff, lwid);
|
||||
lrc = net->sig()->sb_to_slice(prefix_indices, msv, moff, mwid);
|
||||
|
||||
if (moff > loff) {
|
||||
sb_lsb = loff;
|
||||
sb_msb = moff + mwid - 1;
|
||||
} else {
|
||||
sb_lsb = moff;
|
||||
sb_msb = loff + lwid - 1;
|
||||
}
|
||||
} else {
|
||||
// This case, the prefix indices are enough to index
|
||||
// down to a single bit/slice.
|
||||
ivl_assert(*this, prefix_indices.size()+1 == net->sig()->packed_dims().size());
|
||||
sb_lsb = net->sig()->sb_to_idx(prefix_indices, lsv);
|
||||
sb_msb = net->sig()->sb_to_idx(prefix_indices, msv);
|
||||
}
|
||||
|
||||
if (sb_msb < sb_lsb) {
|
||||
cerr << get_fileline() << ": error: part select " << net->name();
|
||||
|
|
|
|||
45
elab_lval.cc
45
elab_lval.cc
|
|
@ -560,25 +560,38 @@ bool PEIdent::elaborate_lval_net_part_(Design*des,
|
|||
|
||||
const vector<netrange_t>&packed = reg->packed_dims();
|
||||
|
||||
// Part selects cannot select slices. So there must be enough
|
||||
// prefix_indices to get all the way to the final dimension.
|
||||
long loff, moff;
|
||||
long wid;
|
||||
if (prefix_indices.size()+1 < packed.size()) {
|
||||
cerr << get_fileline() << ": error: Cannot select a range "
|
||||
<< "of slices from a packed array." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
// If there are fewer indices then there are packed
|
||||
// dimensions, then this is a range of slices. Calculate
|
||||
// it into a big slice.
|
||||
bool lrc;
|
||||
unsigned long tmp_lwid, tmp_mwid;
|
||||
lrc = reg->sb_to_slice(prefix_indices,lsb, loff, tmp_lwid);
|
||||
lrc = reg->sb_to_slice(prefix_indices,msb, moff, tmp_mwid);
|
||||
|
||||
long loff = reg->sb_to_idx(prefix_indices,lsb);
|
||||
long moff = reg->sb_to_idx(prefix_indices,msb);
|
||||
long wid = moff - loff + 1;
|
||||
if (loff < moff) {
|
||||
moff = moff + tmp_mwid - 1;
|
||||
} else {
|
||||
long ltmp = moff;
|
||||
moff = loff + tmp_lwid - 1;
|
||||
loff = ltmp;
|
||||
}
|
||||
wid = moff - loff + 1;
|
||||
|
||||
if (moff < loff) {
|
||||
cerr << get_fileline() << ": error: part select "
|
||||
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
|
||||
<< " is reversed." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
} else {
|
||||
loff = reg->sb_to_idx(prefix_indices,lsb);
|
||||
moff = reg->sb_to_idx(prefix_indices,msb);
|
||||
wid = moff - loff + 1;
|
||||
|
||||
if (moff < loff) {
|
||||
cerr << get_fileline() << ": error: part select "
|
||||
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
|
||||
<< " is reversed." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Special case: The range winds up selecting the entire
|
||||
|
|
|
|||
Loading…
Reference in New Issue