Support non-constant indexed part select of packed arrays.
This commit is contained in:
parent
5e067bd651
commit
77f168cf28
11
elab_expr.cc
11
elab_expr.cc
|
|
@ -3299,13 +3299,12 @@ NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope,
|
|||
return ss;
|
||||
}
|
||||
|
||||
if (net->sig()->packed_dims().size() > 1) {
|
||||
cerr << get_fileline() << ": sorry: Indexed part select of packed arrays not supported here." << endl;
|
||||
des->errors += 1;
|
||||
return net;
|
||||
}
|
||||
|
||||
base = normalize_variable_base(base, net->msi(), net->lsi(), wid, true);
|
||||
ivl_assert(*this, prefix_indices.size()+1 == net->sig()->packed_dims().size());
|
||||
|
||||
// Convert the non-constant part select index expression into
|
||||
// an expression that returns a canonical base.
|
||||
base = normalize_variable_part_base(prefix_indices, base, net->sig(), wid, true);
|
||||
|
||||
NetESelect*ss = new NetESelect(net, base, wid, IVL_SEL_IDX_UP);
|
||||
ss->set_line(*this);
|
||||
|
|
|
|||
16
elab_lval.cc
16
elab_lval.cc
|
|
@ -598,22 +598,16 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (reg->packed_dims().size() > 1) {
|
||||
cerr << get_fileline() << ": sorry: "
|
||||
<< "Indexed part select of packed arrays not supported nere." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
ivl_assert(*this, prefix_indices.size()+1 == reg->packed_dims().size());
|
||||
/* Correct the mux for the range of the vector. */
|
||||
if (use_sel == index_component_t::SEL_IDX_UP) {
|
||||
base = normalize_variable_base(base, reg->packed_dims(),
|
||||
wid, true);
|
||||
base = normalize_variable_part_base(prefix_indices, base,
|
||||
reg, wid, true);
|
||||
sel_type = IVL_SEL_IDX_UP;
|
||||
} else {
|
||||
// This is assumed to be a SEL_IDX_DO.
|
||||
base = normalize_variable_base(base, reg->packed_dims(),
|
||||
wid, false);
|
||||
base = normalize_variable_part_base(prefix_indices, base,
|
||||
reg, wid, false);
|
||||
sel_type = IVL_SEL_IDX_DOWN;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
16
netmisc.cc
16
netmisc.cc
|
|
@ -343,6 +343,22 @@ NetExpr *normalize_variable_bit_base(const list<long>&indices, NetExpr*base,
|
|||
return normalize_variable_base(base, rng.msb, rng.lsb, 1, true, slice_off);
|
||||
}
|
||||
|
||||
NetExpr *normalize_variable_part_base(const list<long>&indices, NetExpr*base,
|
||||
const NetNet*reg,
|
||||
unsigned long wid, bool is_up)
|
||||
{
|
||||
const list<NetNet::range_t>&packed_dims = reg->packed_dims();
|
||||
ivl_assert(*base, indices.size()+1 == packed_dims.size());
|
||||
|
||||
// Get the canonical offset of the slice within which we are
|
||||
// addressing. We need that address as a slice offset to
|
||||
// calculate the proper complete address
|
||||
const NetNet::range_t&rng = packed_dims.back();
|
||||
long slice_off = reg->sb_to_idx(indices, rng.lsb);
|
||||
|
||||
return normalize_variable_base(base, rng.msb, rng.lsb, wid, is_up, slice_off);
|
||||
}
|
||||
|
||||
NetExpr *normalize_variable_slice_base(const list<long>&indices, NetExpr*base,
|
||||
const NetNet*reg, unsigned long&lwid)
|
||||
{
|
||||
|
|
|
|||
32
netmisc.h
32
netmisc.h
|
|
@ -105,11 +105,43 @@ extern NetExpr*normalize_variable_base(NetExpr *base,
|
|||
const list<NetNet::range_t>&dims,
|
||||
unsigned long wid, bool is_up);
|
||||
|
||||
/*
|
||||
* Calculate a canonicalizing expression for a bit select, when the
|
||||
* base expression is the last index of an otherwise complete bit
|
||||
* select. For example:
|
||||
* reg [3:0][7:0] foo;
|
||||
* ... foo[1][x] ...
|
||||
* base is (x) and the generated expression will be (x+8).
|
||||
*/
|
||||
extern NetExpr*normalize_variable_bit_base(const list<long>&indices, NetExpr *base,
|
||||
const NetNet*reg);
|
||||
|
||||
/*
|
||||
* This is similar to normalize_variable_bit_base, but the tail index
|
||||
* it a base and width, instead of a bit. This is used for handling
|
||||
* indexed part selects:
|
||||
* reg [3:0][7:0] foo;
|
||||
* ... foo[1][x +: 2]
|
||||
* base is (x), wid input is (2), and is_up is (true). The output
|
||||
* expression is (x+8).
|
||||
*/
|
||||
extern NetExpr *normalize_variable_part_base(const list<long>&indices, NetExpr*base,
|
||||
const NetNet*reg,
|
||||
unsigned long wid, bool is_up);
|
||||
/*
|
||||
* Calculate a canonicalizing expression for a slice select. The
|
||||
* indices array is less then needed to fully address a bit, so the
|
||||
* result is a slice of the packed array. The return value is an
|
||||
* expression that gets to the base of the slice, and (lwid) becomes
|
||||
* the width of the slice, in bits. For example:
|
||||
* reg [4:1][7:0] foo
|
||||
* ...foo[x]...
|
||||
* base is (x) and the generated expression will be (x*8 - 8), with
|
||||
* lwid set to (8).
|
||||
*/
|
||||
extern NetExpr*normalize_variable_slice_base(const list<long>&indices, NetExpr *base,
|
||||
const NetNet*reg, unsigned long&lwid);
|
||||
|
||||
extern NetExpr*normalize_variable_array_base(NetExpr *base, long offset,
|
||||
unsigned count);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue