Pad CA bit arguments and make reductions and ! self-determined.
Binary bit based operators were not padding arguments if they had different widths. The reduction operators and ! were not correctly evaluating their arguments in a self-determined context.
This commit is contained in:
parent
8c1cca423d
commit
225fcf6bf0
18
elab_expr.cc
18
elab_expr.cc
|
|
@ -1743,13 +1743,23 @@ NetETernary*PETernary::elaborate_expr(Design*des, NetScope*scope,
|
|||
NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope,
|
||||
int expr_wid, bool) const
|
||||
{
|
||||
/* Reduction operators and ! always have a self determined width. */
|
||||
switch (op_) {
|
||||
case '!':
|
||||
case '&': // Reduction AND
|
||||
case '|': // Reduction OR
|
||||
case '^': // Reduction XOR
|
||||
case 'A': // Reduction NAND (~&)
|
||||
case 'N': // Reduction NOR (~|)
|
||||
case 'X': // Reduction NXOR (~^)
|
||||
expr_wid = -1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
NetExpr*ip = expr_->elaborate_expr(des, scope, expr_wid, false);
|
||||
if (ip == 0) return 0;
|
||||
|
||||
/* Should we evaluate expressions ahead of time,
|
||||
* just like in PEBinary::elaborate_expr() ?
|
||||
*/
|
||||
|
||||
NetExpr*tmp;
|
||||
switch (op_) {
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -3125,10 +3125,6 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
|
|||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const
|
||||
{
|
||||
NetExpr*expr = elab_and_eval(des, scope, expr_, width);
|
||||
if (expr == 0)
|
||||
return 0;
|
||||
|
||||
// Some unary operands allow the operand to be
|
||||
// self-determined, and some do not.
|
||||
unsigned owidth = 0;
|
||||
|
|
@ -3139,6 +3135,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
|
|||
break;
|
||||
}
|
||||
|
||||
NetExpr*expr = elab_and_eval(des, scope, expr_, owidth);
|
||||
if (expr == 0) return 0;
|
||||
|
||||
NetNet* sig = 0;
|
||||
NetLogic*gate;
|
||||
|
||||
|
|
|
|||
|
|
@ -157,46 +157,39 @@ NetNet* NetEBBits::synthesize(Design*des)
|
|||
NetScope*scope = lsig->scope();
|
||||
assert(scope);
|
||||
|
||||
if (lsig->vector_width() != rsig->vector_width()) {
|
||||
cerr << get_fileline() << ": internal error: bitwise (" << op_
|
||||
<< ") widths do not match: " << lsig->vector_width()
|
||||
<< " != " << rsig->vector_width() << endl;
|
||||
cerr << get_fileline() << ": : width="
|
||||
<< lsig->vector_width() << ": " << *left_ << endl;
|
||||
cerr << get_fileline() << ": : width="
|
||||
<< rsig->vector_width() << ": " << *right_ << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
unsigned width = lsig->vector_width();
|
||||
if (rsig->vector_width() > width) width = rsig->vector_width();
|
||||
|
||||
lsig = pad_to_width(des, lsig, width);
|
||||
rsig = pad_to_width(des, rsig, width);
|
||||
|
||||
assert(lsig->vector_width() == rsig->vector_width());
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, lsig->vector_width());
|
||||
NetNet::IMPLICIT, width);
|
||||
osig->local_flag(true);
|
||||
osig->data_type(expr_type());
|
||||
|
||||
perm_string oname = scope->local_symbol();
|
||||
unsigned wid = lsig->vector_width();
|
||||
NetLogic*gate;
|
||||
|
||||
switch (op()) {
|
||||
case '&':
|
||||
gate = new NetLogic(scope, oname, 3, NetLogic::AND, wid);
|
||||
gate = new NetLogic(scope, oname, 3, NetLogic::AND, width);
|
||||
break;
|
||||
case 'A':
|
||||
gate = new NetLogic(scope, oname, 3, NetLogic::NAND, wid);
|
||||
gate = new NetLogic(scope, oname, 3, NetLogic::NAND, width);
|
||||
break;
|
||||
case '|':
|
||||
gate = new NetLogic(scope, oname, 3, NetLogic::OR, wid);
|
||||
gate = new NetLogic(scope, oname, 3, NetLogic::OR, width);
|
||||
break;
|
||||
case '^':
|
||||
gate = new NetLogic(scope, oname, 3, NetLogic::XOR, wid);
|
||||
gate = new NetLogic(scope, oname, 3, NetLogic::XOR, width);
|
||||
break;
|
||||
case 'O':
|
||||
gate = new NetLogic(scope, oname, 3, NetLogic::NOR, wid);
|
||||
gate = new NetLogic(scope, oname, 3, NetLogic::NOR, width);
|
||||
break;
|
||||
case 'X':
|
||||
gate = new NetLogic(scope, oname, 3, NetLogic::XNOR, wid);
|
||||
gate = new NetLogic(scope, oname, 3, NetLogic::XNOR, width);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
|
|
|
|||
Loading…
Reference in New Issue