diff --git a/elab_expr.cc b/elab_expr.cc index 5b9b13a18..9fef90d7f 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -167,6 +167,8 @@ NetExpr* PEBinary::elaborate_expr_base_(Design*des, case 'a': case 'o': + lp = condition_reduce(lp); + rp = condition_reduce(rp); tmp = new NetEBLogic(op_, lp, rp); tmp->set_line(*this); break; diff --git a/elaborate.cc b/elaborate.cc index ddf5725aa..06f08fe97 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -2045,14 +2045,8 @@ NetProc* PCondit::elaborate(Design*des, NetScope*scope) const return 0; } - if (expr->expr_width() > 1) { - assert(expr->expr_width() > 1); - verinum zero (verinum::V0, expr->expr_width()); - NetEConst*ezero = new NetEConst(zero); - ezero->set_width(expr->expr_width()); - NetEBComp*cmp = new NetEBComp('n', expr, ezero); - expr = cmp; - } + // Make sure the condition expression evaluates to a condition. + expr = condition_reduce(expr); // Well, I actually need to generate code to handle the // conditional, so elaborate. diff --git a/netmisc.cc b/netmisc.cc index 1c8d7d4b3..258858a9f 100644 --- a/netmisc.cc +++ b/netmisc.cc @@ -123,6 +123,25 @@ NetExpr* make_sub_expr(long val, NetExpr*expr) return res; } +NetExpr* condition_reduce(NetExpr*expr) +{ + if (expr->expr_width() == 1) + return expr; + + verinum zero (verinum::V0, expr->expr_width()); + + NetEConst*ezero = new NetEConst(zero); + ezero->cast_signed(expr->has_sign()); + ezero->set_line(*expr); + ezero->set_width(expr->expr_width()); + + NetEBComp*cmp = new NetEBComp('n', expr, ezero); + cmp->cast_signed(false); + cmp->set_line(*expr); + + return cmp; +} + NetExpr* elab_and_eval(Design*des, NetScope*scope, const PExpr*pe, int expr_wid, int prune_width) { diff --git a/netmisc.h b/netmisc.h index a29221f9c..1633396c2 100644 --- a/netmisc.h +++ b/netmisc.h @@ -64,6 +64,13 @@ extern NetNet*pad_to_width(Design*des, NetNet*n, unsigned w); extern NetNet*pad_to_width_signed(Design*des, NetNet*n, unsigned w); +/* + * Take the input expression and return a variation that assures that + * the expression is 1-bit wide and logical. This reflects the needs + * of conditions i.e. for "if" statements or logical operators. + */ +extern NetExpr*condition_reduce(NetExpr*expr); + /* * This function transforms an expression by cropping the high bits * off with a part select. The result has the width w passed in. This