ivl: Fixed slice base calculation

when range is rising (e.g. logic [0:3] arr) or when it
starts with a non-zero integer (e.g. logic [4:1] arr).

(cherry picked from commit de775975e8)
This commit is contained in:
Maciej Suminski 2016-03-01 16:17:07 +01:00 committed by Martin Whitaker
parent 161cebb178
commit b2281b0e65
1 changed files with 35 additions and 7 deletions

View File

@ -248,6 +248,25 @@ static NetExpr* make_sub_expr(long val, NetExpr*expr)
return res;
}
/*
* Subtract a signed constant from an existing expression.
*/
static NetExpr* make_sub_expr(NetExpr*expr, long val)
{
verinum val_v (val, expr->expr_width());
val_v.has_sign(true);
NetEConst*val_c = new NetEConst(val_v);
val_c->set_line(*expr);
NetEBAdd*res = new NetEBAdd('-', expr, val_c, expr->expr_width(),
expr->has_sign());
res->set_line(*expr);
return res;
}
/*
* Multiple an existing expression by a signed positive number.
* This does a lossless multiply, so the arguments will need to be
@ -434,17 +453,26 @@ NetExpr *normalize_variable_slice_base(const list<long>&indices, NetExpr*base,
-- pcur;
}
long sb;
if (pcur->get_msb() >= pcur->get_lsb())
sb = pcur->get_lsb();
else
sb = pcur->get_msb();
long sb = min(pcur->get_lsb(), pcur->get_msb());
long loff;
reg->sb_to_slice(indices, sb, loff, lwid);
bool idx_incr = pcur->get_msb() < pcur->get_lsb();
if(pcur->get_lsb() != 0) {
// Adjust the base for the case when the array range does not start from 0
if(idx_incr)
base = make_sub_expr(pcur->get_lsb(), base);
else
base = make_sub_expr(base, pcur->get_lsb());
}
base = make_mult_expr(base, lwid);
base = make_add_expr(base, loff);
// TODO I do not see any influence of the lines below to the test suite
if(!idx_incr)
base = make_add_expr(base, loff);
return base;
}