Fix the evaluation of constant ternary expressions.

This commit is contained in:
steve 2004-09-10 23:51:42 +00:00
parent 5e627c9adc
commit d1dac0017d
3 changed files with 68 additions and 14 deletions

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: compiler.h,v 1.23 2004/09/05 17:44:41 steve Exp $"
#ident "$Id: compiler.h,v 1.24 2004/09/10 23:51:42 steve Exp $"
#endif
# include <list>
@ -82,6 +82,7 @@ extern bool warn_portbinding;
extern bool verbose_flag;
extern bool debug_scopes;
extern bool debug_eval_tree;
/* Path to a directory useful for finding subcomponents. */
extern const char*basedir;
@ -134,6 +135,9 @@ extern int load_sys_func_table(const char*path);
/*
* $Log: compiler.h,v $
* Revision 1.24 2004/09/10 23:51:42 steve
* Fix the evaluation of constant ternary expressions.
*
* Revision 1.23 2004/09/05 17:44:41 steve
* Add support for module instance arrays.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: eval_tree.cc,v 1.60 2004/02/20 06:22:56 steve Exp $"
#ident "$Id: eval_tree.cc,v 1.61 2004/09/10 23:51:42 steve Exp $"
#endif
# include "config.h"
@ -1305,18 +1305,50 @@ NetExpr* NetETernary::eval_tree()
if (c == 0)
return 0;
/* Check the boolean value of the constant condition
expression. Note that the X case is handled explicitly, so
we must differentiate. */
verinum cond_value = c->value();
bool true_flag = false;
bool x_flag = false;
for (unsigned idx = 0 ; idx < cond_value.len() ; idx += 1) {
switch (cond_value.get(idx)) {
case verinum::V1:
true_flag = true;
break;
case verinum::V0:
break;
default:
x_flag = true;
}
}
/* If the condition is 1 or 0, return the true or false
expression. Try to evaluate the expression down as far as
we can. */
if (c->value().get(0) == verinum::V1)
if (true_flag) {
if (debug_eval_tree) {
cerr << get_line() << ": debug: Evaluate ternary with "
<< "constant condition value: " << c->value() << endl;
cerr << get_line() << ": : Selecting true case: "
<< *true_val_ << endl;
}
return true_val_->dup_expr();
}
if (c->value().get(0) == verinum::V0)
if (! x_flag) {
if (debug_eval_tree) {
cerr << get_line() << ": debug: Evaluate ternary with "
<< "constant condition value: " << c->value() << endl;
cerr << get_line() << ": : Selecting false case: "
<< *true_val_ << endl;
}
return false_val_->dup_expr();
}
/* Here we have a more complex case. We need to evaluate both
expressions down to constants then compare the values to
@ -1332,13 +1364,15 @@ NetExpr* NetETernary::eval_tree()
return 0;
unsigned size = t->expr_width();
assert(size == f->expr_width());
unsigned tsize = t->expr_width();
unsigned fsize = f->expr_width();
/* Size of the result is the size of the widest operand. */
unsigned rsize = tsize > fsize? tsize : fsize;
verinum val (verinum::V0, size);
for (unsigned idx = 0 ; idx < size ; idx += 1) {
verinum::V tv = t->value().get(idx);
verinum::V fv = f->value().get(idx);
verinum val (verinum::V0, rsize);
for (unsigned idx = 0 ; idx < rsize ; idx += 1) {
verinum::V tv = idx < tsize? t->value().get(idx) : verinum::V0;
verinum::V fv = idx < rsize? f->value().get(idx) : verinum::V0;
if (tv == fv)
val.set(idx, tv);
@ -1346,6 +1380,13 @@ NetExpr* NetETernary::eval_tree()
val.set(idx, verinum::Vx);
}
if (debug_eval_tree) {
cerr << get_line() << ": debug: Evaluate ternary with "
<< "constant condition value: " << c->value() << endl;
cerr << get_line() << ": : Blending cases to get "
<< val << endl;
}
NetEConst*rc = new NetEConst(val);
rc->set_line(*this);
return rc;
@ -1510,6 +1551,9 @@ NetEConst* NetEUReduce::eval_tree()
/*
* $Log: eval_tree.cc,v $
* Revision 1.61 2004/09/10 23:51:42 steve
* Fix the evaluation of constant ternary expressions.
*
* Revision 1.60 2004/02/20 06:22:56 steve
* parameter keys are per_strings.
*

10
main.cc
View File

@ -19,7 +19,7 @@ const char COPYRIGHT[] =
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: main.cc,v 1.83 2004/09/05 17:44:42 steve Exp $"
#ident "$Id: main.cc,v 1.84 2004/09/10 23:51:42 steve Exp $"
#endif
# include "config.h"
@ -110,7 +110,7 @@ bool error_implicit = false;
* Debug message class flags.
*/
bool debug_scopes = false;
bool debug_eval_tree = false;
/*
* Verbose messages enabled.
*/
@ -307,6 +307,9 @@ static void read_iconfig_file(const char*ipath)
if (strcmp(cp, "scope") == 0) {
debug_scopes = true;
cerr << "debug: Enable scope debug" << endl;
} else if (strcmp(cp,"eval_tree") == 0) {
debug_eval_tree = true;
cerr << "debug: Enable eval_tree debug" << endl;
} else {
}
@ -737,6 +740,9 @@ int main(int argc, char*argv[])
/*
* $Log: main.cc,v $
* Revision 1.84 2004/09/10 23:51:42 steve
* Fix the evaluation of constant ternary expressions.
*
* Revision 1.83 2004/09/05 17:44:42 steve
* Add support for module instance arrays.
*