Skip to content

Commit

Permalink
Improved fix for GitHub issue #112.
Browse files Browse the repository at this point in the history
This does a better job of setting the intermediate expression types
and widths when calculating the canonical index into a packed array.
It still doesn't properly handle out-of-bound indices (br953).
  • Loading branch information
martinwhitaker committed Jul 10, 2016
1 parent 1448210 commit 7f61227
Showing 1 changed file with 23 additions and 11 deletions.
34 changes: 23 additions & 11 deletions netmisc.cc
Expand Up @@ -203,7 +203,7 @@ static NetExpr* make_add_expr(NetExpr*expr, long val)
}

verinum val_v (val, expr->expr_width());
val_v.has_sign(true);
val_v.has_sign(expr->has_sign());

NetEConst*val_c = new NetEConst(val_v);
val_c->set_line(*expr);
Expand Down Expand Up @@ -236,7 +236,7 @@ static NetExpr* make_add_expr(const LineInfo*loc, NetExpr*expr1, NetExpr*expr2)
static NetExpr* make_sub_expr(long val, NetExpr*expr)
{
verinum val_v (val, expr->expr_width());
val_v.has_sign(true);
val_v.has_sign(expr->has_sign());

NetEConst*val_c = new NetEConst(val_v);
val_c->set_line(*expr);
Expand All @@ -254,7 +254,7 @@ static NetExpr* make_sub_expr(long val, NetExpr*expr)
static NetExpr* make_sub_expr(NetExpr*expr, long val)
{
verinum val_v (val, expr->expr_width());
val_v.has_sign(true);
val_v.has_sign(expr->has_sign());

NetEConst*val_c = new NetEConst(val_v);
val_c->set_line(*expr);
Expand All @@ -268,7 +268,7 @@ static NetExpr* make_sub_expr(NetExpr*expr, long val)


/*
* Multiple an existing expression by a signed positive number.
* Multiply an existing expression by a signed positive number.
* This does a lossless multiply, so the arguments will need to be
* sized to match the output size.
*/
Expand All @@ -277,7 +277,7 @@ static NetExpr* make_mult_expr(NetExpr*expr, unsigned long val)
const unsigned val_wid = ceil(log2((double)val)) ;
unsigned use_wid = expr->expr_width() + val_wid;
verinum val_v (val, use_wid);
val_v.has_sign(true);
val_v.has_sign(expr->has_sign());

NetEConst*val_c = new NetEConst(val_v);
val_c->set_line(*expr);
Expand Down Expand Up @@ -457,23 +457,35 @@ NetExpr *normalize_variable_slice_base(const list<long>&indices, NetExpr*base,
long loff;
reg->sb_to_slice(indices, sb, loff, lwid);

/* Calculate the space needed for the offset. */
unsigned min_wid = num_bits(-loff);
/* We need enough space for the larger of the offset or the
* base expression. */
if (min_wid < base->expr_width()) min_wid = base->expr_width();
/* Pad the base expression to the correct width. */
unsigned min_wid = base->expr_width();
if ((sb < 0) && !base->has_sign()) min_wid += 1;
if (min_wid < num_bits(pcur->get_lsb())) min_wid = pcur->get_lsb();
if (min_wid < num_bits(pcur->get_msb())) min_wid = pcur->get_msb();
base = pad_to_width(base, min_wid, *base);
if ((sb < 0) && !base->has_sign()) {
NetESelect *tmp = new NetESelect(base, 0 , min_wid);
tmp->set_line(*base);
tmp->cast_signed(true);
base = tmp;
}

if (pcur->get_msb() >= pcur->get_lsb()) {
if (pcur->get_lsb() != 0)
base = make_sub_expr(base, pcur->get_lsb());
base = make_mult_expr(base, lwid);
min_wid = base->expr_width();
if (min_wid < num_bits(loff)) min_wid = num_bits(loff);
if (loff != 0) min_wid += 1;
base = pad_to_width(base, min_wid, *base);
base = make_add_expr(base, loff);
} else {
if (pcur->get_msb() != 0)
base = make_sub_expr(base, pcur->get_msb());
base = make_mult_expr(base, lwid);
min_wid = base->expr_width();
if (min_wid < num_bits(loff)) min_wid = num_bits(loff);
if (loff != 0) min_wid += 1;
base = pad_to_width(base, min_wid, *base);
base = make_sub_expr(loff, base);
}
return base;
Expand Down

0 comments on commit 7f61227

Please sign in to comment.