V0.8: Fix single bit reductions with 1'bz input.

This patch mirrors what was done in development to support single
bit reductions correctly.
This commit is contained in:
Cary R 2008-11-20 17:48:33 -08:00 committed by Stephen Williams
parent ddf68ca14c
commit f112b77d3b
4 changed files with 30 additions and 5 deletions

View File

@ -1483,6 +1483,7 @@ NetEConst* NetEUReduce::eval_tree()
verinum val = rval->value();
verinum::V res;
bool invert = false;
switch (op_) {
@ -1511,6 +1512,8 @@ NetEConst* NetEUReduce::eval_tree()
break;
}
case 'A':
invert = true;
case '&': {
res = verinum::V1;
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
@ -1518,6 +1521,8 @@ NetEConst* NetEUReduce::eval_tree()
break;
}
case 'N':
invert = true;
case '|': {
res = verinum::V0;
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
@ -1525,6 +1530,8 @@ NetEConst* NetEUReduce::eval_tree()
break;
}
case 'X':
invert = true;
case '^': {
/* Reduction XOR. */
unsigned ones = 0, unknown = 0;
@ -1540,17 +1547,17 @@ NetEConst* NetEUReduce::eval_tree()
break;
}
if (unknown)
return new NetEConst(verinum(verinum::Vx,1,true));
if (ones%2)
return new NetEConst(verinum(verinum::V1,1,true));
return new NetEConst(verinum(verinum::V0,1,true));
if (unknown) res = verinum::Vx;
else if (ones%2) res = verinum::V1;
else res = verinum::V0;
break;
}
default:
return 0;
}
if (invert) res = ~res;
return new NetEConst(verinum(res, 1));
}

View File

@ -2012,6 +2012,11 @@ static struct vector_info draw_unary_expr(ivl_expr_t exp, unsigned wid)
} else if (inv) {
assert(res.base >= 4);
fprintf(vvp_out, " %%inv %u, 1;\n", res.base);
} else {
/* We need to convert a 1'bz to 1'bx. */
assert(res.base >= 4);
fprintf(vvp_out, " %%inv %u, 1;\n", res.base);
fprintf(vvp_out, " %%inv %u, 1;\n", res.base);
}
/* If the result needs to be bigger then the calculated

View File

@ -956,6 +956,18 @@ verinum concat(const verinum&left, const verinum&right)
return res;
}
verinum::V operator ~ (verinum::V l)
{
switch(l) {
case verinum::V0:
return verinum::V1;
case verinum::V1:
return verinum::V0;
default:
return verinum::Vx;
}
}
verinum::V operator | (verinum::V l, verinum::V r)
{
if (l == verinum::V1)

View File

@ -113,6 +113,7 @@ extern verinum trim_vnum(const verinum&);
extern std::ostream& operator<< (std::ostream&, const verinum&);
extern std::ostream& operator<< (std::ostream&, verinum::V);
extern verinum::V operator ~ (verinum::V l);
extern verinum::V operator | (verinum::V l, verinum::V r);
extern verinum::V operator & (verinum::V l, verinum::V r);
extern verinum::V operator ^ (verinum::V l, verinum::V r);