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:
Cary R 2008-03-25 19:00:00 -07:00 committed by Stephen Williams
parent 8c1cca423d
commit 225fcf6bf0
3 changed files with 29 additions and 27 deletions

View File

@ -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:

View File

@ -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;

View File

@ -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);