diff --git a/compiler.h b/compiler.h index d444d2617..ec62aff60 100644 --- a/compiler.h +++ b/compiler.h @@ -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 @@ -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. * diff --git a/eval_tree.cc b/eval_tree.cc index 0dcf75418..b9dc35660 100644 --- a/eval_tree.cc +++ b/eval_tree.cc @@ -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. * diff --git a/main.cc b/main.cc index 4858cf7c3..191fe115f 100644 --- a/main.cc +++ b/main.cc @@ -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. *