Handle indexed bit select of packed arrays.
This handles a few cases where the non-constant bit selects are in the final index. This doesn't handle all the cases of packed arrays, but it handles some common cases.
This commit is contained in:
parent
4287fc4b50
commit
6eeef8311f
|
|
@ -3514,8 +3514,7 @@ NetExpr* PEIdent::elaborate_expr_net_bit_(Design*des, NetScope*scope,
|
|||
// complicated task because we need to generate
|
||||
// expressions to convert calculated bit select
|
||||
// values to canonical values that are used internally.
|
||||
assert(sig_packed.size() == 1);
|
||||
mux = normalize_variable_base(mux, sig_packed, 1, true);
|
||||
mux = normalize_variable_bit_base(prefix_indices, mux, net->sig());
|
||||
|
||||
NetESelect*ss = new NetESelect(net, mux, 1);
|
||||
ss->set_line(*this);
|
||||
|
|
|
|||
|
|
@ -408,7 +408,7 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
|
|||
// Non-constant bit mux. Correct the mux for the range
|
||||
// of the vector, then set the l-value part select
|
||||
// expression.
|
||||
mux = normalize_variable_base(mux, reg->packed_dims(), 1, true);
|
||||
mux = normalize_variable_bit_base(prefix_indices, mux, reg);
|
||||
lv->set_part(mux, 1);
|
||||
|
||||
} else if (reg->vector_width() == 1 && reg->sb_is_valid(prefix_indices,lsb)) {
|
||||
|
|
|
|||
28
netmisc.cc
28
netmisc.cc
|
|
@ -239,10 +239,13 @@ static unsigned num_bits(long arg)
|
|||
|
||||
/*
|
||||
* This routine generates the normalization expression needed for a variable
|
||||
* bit select or a variable base expression for an indexed part select.
|
||||
* bit select or a variable base expression for an indexed part
|
||||
* select. This function doesn't actually look at the variable
|
||||
* dimensions, it just does the final calculation using msb/lsb of the
|
||||
* last slice, and the off of the slice in the variable.
|
||||
*/
|
||||
NetExpr *normalize_variable_base(NetExpr *base, long msb, long lsb,
|
||||
unsigned long wid, bool is_up)
|
||||
unsigned long wid, bool is_up, long soff)
|
||||
{
|
||||
long offset = lsb;
|
||||
|
||||
|
|
@ -275,13 +278,13 @@ NetExpr *normalize_variable_base(NetExpr *base, long msb, long lsb,
|
|||
base = tmp;
|
||||
}
|
||||
/* Normalize the expression. */
|
||||
base = make_sub_expr(offset, base);
|
||||
base = make_sub_expr(offset+soff, base);
|
||||
} else {
|
||||
/* Correct the offset if needed. */
|
||||
if (!is_up) offset += wid - 1;
|
||||
/* If the offset is zero then just return the base (index)
|
||||
* expression. */
|
||||
if (offset == 0) return base;
|
||||
if ((soff-offset) == 0) return base;
|
||||
/* Calculate the space needed for the offset. */
|
||||
unsigned min_wid = num_bits(-offset);
|
||||
/* We need enough space for the larger of the offset or the
|
||||
|
|
@ -304,7 +307,7 @@ NetExpr *normalize_variable_base(NetExpr *base, long msb, long lsb,
|
|||
base = tmp;
|
||||
}
|
||||
/* Normalize the expression. */
|
||||
base = make_add_expr(base, -offset);
|
||||
base = make_add_expr(base, soff-offset);
|
||||
}
|
||||
|
||||
return base;
|
||||
|
|
@ -325,6 +328,21 @@ NetExpr *normalize_variable_base(NetExpr *base,
|
|||
return normalize_variable_base(base, rng.msb, rng.lsb, wid, is_up);
|
||||
}
|
||||
|
||||
NetExpr *normalize_variable_bit_base(const list<long>&indices, NetExpr*base,
|
||||
const NetNet*reg)
|
||||
{
|
||||
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, 1, true, slice_off);
|
||||
}
|
||||
|
||||
NetExpr *normalize_variable_slice_base(const list<long>&indices, NetExpr*base,
|
||||
const NetNet*reg, unsigned long&lwid)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -99,10 +99,15 @@ extern NetNet*crop_to_width(Design*des, NetNet*n, unsigned w);
|
|||
* the provided vector/array information.
|
||||
*/
|
||||
extern NetExpr*normalize_variable_base(NetExpr *base, long msb, long lsb,
|
||||
unsigned long wid, bool is_up);
|
||||
unsigned long wid, bool is_up,
|
||||
long slice_off =0);
|
||||
extern NetExpr*normalize_variable_base(NetExpr *base,
|
||||
const list<NetNet::range_t>&dims,
|
||||
unsigned long wid, bool is_up);
|
||||
|
||||
extern NetExpr*normalize_variable_bit_base(const list<long>&indices, NetExpr *base,
|
||||
const NetNet*reg);
|
||||
|
||||
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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue