Support indexed part selects that index sub-arrays (issue #497)
(cherry picked from commit 4af830187e)
This commit is contained in:
parent
cccf36d76f
commit
c0c46dc173
72
elab_expr.cc
72
elab_expr.cc
|
|
@ -5243,20 +5243,37 @@ NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope,
|
|||
NetExpr*ex;
|
||||
if (base_c->value().is_defined()) {
|
||||
long lsv = base_c->value().as_long();
|
||||
long offset = 0;
|
||||
long rel_base = 0;
|
||||
// Get the signal range.
|
||||
const vector<netrange_t>&packed = net->sig()->packed_dims();
|
||||
ivl_assert(*this, packed.size() == prefix_indices.size()+1);
|
||||
if (prefix_indices.size()+1 < net->sig()->packed_dims().size()) {
|
||||
// Here we are selecting one or more sub-arrays.
|
||||
// Make this work by finding the indexed sub-arrays 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, moff, mwid);
|
||||
ivl_assert(*this, lrc);
|
||||
lrc = net->sig()->sb_to_slice(prefix_indices, lsv+(wid/mwid)-1, loff, lwid);
|
||||
ivl_assert(*this, lrc);
|
||||
ivl_assert(*this, lwid == mwid);
|
||||
|
||||
// We want the last range, which is where we work.
|
||||
const netrange_t&rng = packed.back();
|
||||
if (rng.get_msb() < rng.get_lsb()) {
|
||||
offset = -wid + 1;
|
||||
if (moff > loff) {
|
||||
rel_base = loff;
|
||||
} else {
|
||||
rel_base = moff;
|
||||
}
|
||||
} else {
|
||||
long offset = 0;
|
||||
// We want the last range, which is where we work.
|
||||
const netrange_t&rng = packed.back();
|
||||
if (rng.get_msb() < rng.get_lsb()) {
|
||||
offset = -wid + 1;
|
||||
}
|
||||
rel_base = net->sig()->sb_to_idx(prefix_indices, lsv) + offset;
|
||||
}
|
||||
|
||||
long rel_base = net->sig()->sb_to_idx(prefix_indices, lsv);
|
||||
rel_base += offset;
|
||||
|
||||
// If the part select covers exactly the entire
|
||||
// vector, then do not bother with it. Return the
|
||||
// signal itself.
|
||||
|
|
@ -5347,19 +5364,36 @@ NetExpr* PEIdent::elaborate_expr_net_idx_do_(Design*des, NetScope*scope,
|
|||
NetExpr*ex;
|
||||
if (base_c->value().is_defined()) {
|
||||
long lsv = base_c->value().as_long();
|
||||
long offset = 0;
|
||||
long rel_base = 0;
|
||||
// Get the signal range.
|
||||
const vector<netrange_t>&packed = net->sig()->packed_dims();
|
||||
ivl_assert(*this, packed.size() == prefix_indices.size()+1);
|
||||
if (prefix_indices.size()+1 < net->sig()->packed_dims().size()) {
|
||||
// Here we are selecting one or more sub-arrays.
|
||||
// Make this work by finding the indexed sub-arrays 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, moff, mwid);
|
||||
ivl_assert(*this, lrc);
|
||||
lrc = net->sig()->sb_to_slice(prefix_indices, lsv-(wid/mwid)+1, loff, lwid);
|
||||
ivl_assert(*this, lrc);
|
||||
ivl_assert(*this, lwid == mwid);
|
||||
|
||||
// We want the last range, which is where we work.
|
||||
const netrange_t&rng = packed.back();
|
||||
if (rng.get_msb() > rng.get_lsb()) {
|
||||
offset = -wid + 1;
|
||||
}
|
||||
|
||||
long rel_base = net->sig()->sb_to_idx(prefix_indices, lsv);
|
||||
rel_base += offset;
|
||||
if (moff > loff) {
|
||||
rel_base = loff;
|
||||
} else {
|
||||
rel_base = moff;
|
||||
}
|
||||
} else {
|
||||
long offset = 0;
|
||||
// We want the last range, which is where we work.
|
||||
const netrange_t&rng = packed.back();
|
||||
if (rng.get_msb() > rng.get_lsb()) {
|
||||
offset = -wid + 1;
|
||||
}
|
||||
rel_base = net->sig()->sb_to_idx(prefix_indices, lsv) + offset;
|
||||
}
|
||||
|
||||
// If the part select covers exactly the entire
|
||||
// vector, then do not bother with it. Return the
|
||||
|
|
|
|||
44
elab_lval.cc
44
elab_lval.cc
|
|
@ -938,21 +938,45 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
|
|||
// we will handle it in the code generator.
|
||||
if (base_c->value().is_defined()) {
|
||||
long lsv = base_c->value().as_long();
|
||||
long offset = 0;
|
||||
long rel_base = 0;
|
||||
// Get the signal range.
|
||||
const vector<netrange_t>&packed = reg->packed_dims();
|
||||
ivl_assert(*this, packed.size() == prefix_indices.size()+1);
|
||||
if (prefix_indices.size()+1 < reg->packed_dims().size()) {
|
||||
// Here we are selecting one or more sub-arrays.
|
||||
// Make this work by finding the indexed sub-arrays and
|
||||
// creating a generated slice that spans the whole range.
|
||||
long loff, moff;
|
||||
unsigned long lwid, mwid;
|
||||
bool lrc;
|
||||
lrc = reg->sb_to_slice(prefix_indices, lsv, moff, mwid);
|
||||
ivl_assert(*this, lrc);
|
||||
if (use_sel == index_component_t::SEL_IDX_UP)
|
||||
lrc = reg->sb_to_slice(prefix_indices, lsv+wid-1, loff, lwid);
|
||||
else
|
||||
lrc = reg->sb_to_slice(prefix_indices, lsv-wid+1, loff, lwid);
|
||||
ivl_assert(*this, lrc);
|
||||
ivl_assert(*this, lwid == mwid);
|
||||
|
||||
// We want the last range, which is where we work.
|
||||
const netrange_t&rng = packed.back();
|
||||
if (((rng.get_msb() < rng.get_lsb()) &&
|
||||
use_sel == index_component_t::SEL_IDX_UP) ||
|
||||
((rng.get_msb() > rng.get_lsb()) &&
|
||||
use_sel == index_component_t::SEL_IDX_DO)) {
|
||||
offset = -wid + 1;
|
||||
if (moff > loff) {
|
||||
rel_base = loff;
|
||||
wid = moff + mwid - loff;
|
||||
} else {
|
||||
rel_base = moff;
|
||||
wid = loff + lwid - moff;
|
||||
}
|
||||
} else {
|
||||
long offset = 0;
|
||||
// We want the last range, which is where we work.
|
||||
const netrange_t&rng = packed.back();
|
||||
if (((rng.get_msb() < rng.get_lsb()) &&
|
||||
use_sel == index_component_t::SEL_IDX_UP) ||
|
||||
((rng.get_msb() > rng.get_lsb()) &&
|
||||
use_sel == index_component_t::SEL_IDX_DO)) {
|
||||
offset = -wid + 1;
|
||||
}
|
||||
rel_base = reg->sb_to_idx(prefix_indices,lsv) + offset;
|
||||
}
|
||||
delete base;
|
||||
long rel_base = reg->sb_to_idx(prefix_indices,lsv) + offset;
|
||||
/* 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));
|
||||
|
|
|
|||
101
elab_net.cc
101
elab_net.cc
|
|
@ -262,49 +262,74 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
|||
}
|
||||
|
||||
long midx_val = tmp->value().as_long();
|
||||
midx = sig->sb_to_idx(prefix_indices, midx_val);
|
||||
delete tmp_ex;
|
||||
if (prefix_indices.size()+1 < sig->packed_dims().size()) {
|
||||
// Here we are selecting one or more sub-arrays.
|
||||
// Make this work by finding the indexed sub-arrays and
|
||||
// creating a generated slice that spans the whole range.
|
||||
long loff, moff;
|
||||
unsigned long lwid, mwid;
|
||||
bool lrc;
|
||||
lrc = sig->sb_to_slice(prefix_indices, midx_val, moff, mwid);
|
||||
ivl_assert(*this, lrc);
|
||||
if (index_tail.sel == index_component_t::SEL_IDX_UP)
|
||||
lrc = sig->sb_to_slice(prefix_indices, midx_val+wid-1, loff, lwid);
|
||||
else
|
||||
lrc = sig->sb_to_slice(prefix_indices, midx_val-wid+1, loff, lwid);
|
||||
ivl_assert(*this, lrc);
|
||||
ivl_assert(*this, lwid == mwid);
|
||||
|
||||
if (index_tail.sel == index_component_t::SEL_IDX_UP)
|
||||
lidx = sig->sb_to_idx(prefix_indices, midx_val+wid-1);
|
||||
else
|
||||
lidx = sig->sb_to_idx(prefix_indices, midx_val-wid+1);
|
||||
|
||||
if (midx < lidx) {
|
||||
long tmpx = midx;
|
||||
midx = lidx;
|
||||
lidx = tmpx;
|
||||
}
|
||||
|
||||
/* Warn about an indexed part select that is out of range. */
|
||||
if (warn_ob_select && (lidx < 0)) {
|
||||
cerr << get_fileline() << ": warning: " << sig->name();
|
||||
if (sig->unpacked_dimensions() > 0) cerr << "[]";
|
||||
cerr << "[" << midx_val;
|
||||
if (index_tail.sel == index_component_t::SEL_IDX_UP) {
|
||||
cerr << "+:";
|
||||
if (moff > loff) {
|
||||
lidx = loff;
|
||||
midx = moff + mwid - 1;
|
||||
} else {
|
||||
cerr << "-:";
|
||||
lidx = moff;
|
||||
midx = loff + lwid - 1;
|
||||
}
|
||||
cerr << wid << "] is selecting before vector." << endl;
|
||||
}
|
||||
if (warn_ob_select && (midx >= (long)sig->vector_width())) {
|
||||
cerr << get_fileline() << ": warning: " << sig->name();
|
||||
if (sig->unpacked_dimensions() > 0) {
|
||||
cerr << "[]";
|
||||
}
|
||||
cerr << "[" << midx_val;
|
||||
if (index_tail.sel == index_component_t::SEL_IDX_UP) {
|
||||
cerr << "+:";
|
||||
} else {
|
||||
cerr << "-:";
|
||||
}
|
||||
cerr << wid << "] is selecting after vector." << endl;
|
||||
}
|
||||
} else {
|
||||
midx = sig->sb_to_idx(prefix_indices, midx_val);
|
||||
|
||||
/* This is completely out side the signal so just skip it. */
|
||||
if (lidx >= (long)sig->vector_width() || midx < 0) {
|
||||
return false;
|
||||
if (index_tail.sel == index_component_t::SEL_IDX_UP)
|
||||
lidx = sig->sb_to_idx(prefix_indices, midx_val+wid-1);
|
||||
else
|
||||
lidx = sig->sb_to_idx(prefix_indices, midx_val-wid+1);
|
||||
|
||||
if (midx < lidx) {
|
||||
long tmpx = midx;
|
||||
midx = lidx;
|
||||
lidx = tmpx;
|
||||
}
|
||||
|
||||
/* Warn about an indexed part select that is out of range. */
|
||||
if (warn_ob_select && (lidx < 0)) {
|
||||
cerr << get_fileline() << ": warning: " << sig->name();
|
||||
if (sig->unpacked_dimensions() > 0) cerr << "[]";
|
||||
cerr << "[" << midx_val;
|
||||
if (index_tail.sel == index_component_t::SEL_IDX_UP) {
|
||||
cerr << "+:";
|
||||
} else {
|
||||
cerr << "-:";
|
||||
}
|
||||
cerr << wid << "] is selecting before vector." << endl;
|
||||
}
|
||||
if (warn_ob_select && (midx >= (long)sig->vector_width())) {
|
||||
cerr << get_fileline() << ": warning: " << sig->name();
|
||||
if (sig->unpacked_dimensions() > 0) {
|
||||
cerr << "[]";
|
||||
}
|
||||
cerr << "[" << midx_val;
|
||||
if (index_tail.sel == index_component_t::SEL_IDX_UP) {
|
||||
cerr << "+:";
|
||||
} else {
|
||||
cerr << "-:";
|
||||
}
|
||||
cerr << wid << "] is selecting after vector." << endl;
|
||||
}
|
||||
|
||||
/* This is completely out side the signal so just skip it. */
|
||||
if (lidx >= (long)sig->vector_width() || midx < 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
|||
Loading…
Reference in New Issue