diff --git a/netlist.cc b/netlist.cc index 2fe8a76b0..80cec0840 100644 --- a/netlist.cc +++ b/netlist.cc @@ -17,18 +17,18 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: netlist.cc,v 1.252 2007/01/19 04:25:37 steve Exp $" +#ident "$Id: netlist.cc,v 1.253 2007/02/14 05:59:46 steve Exp $" #endif # include "config.h" # include -# include # include # include "compiler.h" # include "netlist.h" # include "netmisc.h" +# include "ivl_assert.h" ostream& operator<< (ostream&o, NetNet::Type t) @@ -2069,6 +2069,19 @@ const NetExpr* NetETernary::false_expr() const return false_val_; } +ivl_variable_type_t NetETernary::expr_type() const +{ + ivl_variable_type_t tru = true_val_->expr_type(); + ivl_variable_type_t fal = false_val_->expr_type(); + if (tru == IVL_VT_LOGIC && fal == IVL_VT_BOOL) + return IVL_VT_LOGIC; + if (tru == IVL_VT_BOOL && fal == IVL_VT_LOGIC) + return IVL_VT_LOGIC; + + ivl_assert(*this, tru == fal); + return tru; +} + NetEUnary::NetEUnary(char op, NetExpr*ex) : NetExpr(ex->expr_width()), op_(op), expr_(ex) { @@ -2192,6 +2205,9 @@ const NetProc*NetTaskDef::proc() const /* * $Log: netlist.cc,v $ + * Revision 1.253 2007/02/14 05:59:46 steve + * Handle type of ternary expressions properly. + * * Revision 1.252 2007/01/19 04:25:37 steve * Fix missing passive setting for array word pins. * diff --git a/netlist.h b/netlist.h index 2c6e88ce8..40483160b 100644 --- a/netlist.h +++ b/netlist.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: netlist.h,v 1.367 2007/02/02 04:33:00 steve Exp $" +#ident "$Id: netlist.h,v 1.368 2007/02/14 05:59:46 steve Exp $" #endif /* @@ -3015,6 +3015,7 @@ class NetETernary : public NetExpr { virtual NetETernary* dup_expr() const; virtual NetExpr* eval_tree(); + virtual ivl_variable_type_t expr_type() const; virtual NexusSet* nex_input(); virtual void expr_scan(struct expr_scan_t*) const; virtual void dump(ostream&) const; @@ -3472,6 +3473,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.368 2007/02/14 05:59:46 steve + * Handle type of ternary expressions properly. + * * Revision 1.367 2007/02/02 04:33:00 steve * Use inttypes.h instead of stdint.h for portability. * diff --git a/t-dll-expr.cc b/t-dll-expr.cc index 74f1429a8..d03f143f9 100644 --- a/t-dll-expr.cc +++ b/t-dll-expr.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: t-dll-expr.cc,v 1.44 2007/01/16 05:44:15 steve Exp $" +#ident "$Id: t-dll-expr.cc,v 1.45 2007/02/14 05:59:46 steve Exp $" #endif # include "config.h" @@ -366,7 +366,7 @@ void dll_target::expr_ternary(const NetETernary*net) assert(expr); expr->type_ = IVL_EX_TERNARY; - expr->value_= IVL_VT_VECTOR; + expr->value_= net->expr_type(); expr->width_ = net->expr_width(); expr->signed_ = net->has_sign()? 1 : 0; @@ -474,6 +474,9 @@ void dll_target::expr_unary(const NetEUnary*net) /* * $Log: t-dll-expr.cc,v $ + * Revision 1.45 2007/02/14 05:59:46 steve + * Handle type of ternary expressions properly. + * * Revision 1.44 2007/01/16 05:44:15 steve * Major rework of array handling. Memories are replaced with the * more general concept of arrays. The NetMemory and NetEMemory diff --git a/tgt-vvp/eval_real.c b/tgt-vvp/eval_real.c index 4bb97b1c8..463f4b5dd 100644 --- a/tgt-vvp/eval_real.c +++ b/tgt-vvp/eval_real.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: eval_real.c,v 1.17 2007/01/16 05:44:16 steve Exp $" +#ident "$Id: eval_real.c,v 1.18 2007/02/14 05:59:46 steve Exp $" #endif /* @@ -281,6 +281,56 @@ static int draw_signal_real(ivl_expr_t exp) } } +static int draw_ternary_real(ivl_expr_t exp) +{ + ivl_expr_t cond = ivl_expr_oper1(exp); + ivl_expr_t true_ex = ivl_expr_oper2(exp); + ivl_expr_t false_ex = ivl_expr_oper3(exp); + + struct vector_info tst; + + unsigned lab_true = local_count++; + unsigned lab_false = local_count++; + + int tru, fal; + int res = allocate_word(); + + tst = draw_eval_expr(cond, STUFF_OK_XZ|STUFF_OK_RO); + if ((tst.base >= 4) && (tst.wid > 1)) { + struct vector_info tmp; + + fprintf(vvp_out, " %%or/r %u, %u, %u;\n", + tst.base, tst.base, tst.wid); + + tmp = tst; + tmp.base += 1; + tmp.wid -= 1; + clr_vector(tmp); + + tst.wid = 1; + } + + fprintf(vvp_out, " %%jmp/0 T_%d.%d, %u;\n", + thread_count, lab_true, tst.base); + + tru = draw_eval_real(true_ex); + fprintf(vvp_out, " %%mov/wr %d, %d;\n", res, tru); + fprintf(vvp_out, " %%jmp T_%d.%d;\n", thread_count, lab_false); + clr_word(tru); + + fprintf(vvp_out, "T_%d.%d ;\n", thread_count, lab_true); + + fal = draw_eval_real(false_ex); + fprintf(vvp_out, " %%mov/wr %d, %d;\n", res, fal); + clr_word(fal); + + fprintf(vvp_out, "T_%d.%d ;\n", thread_count, lab_false); + + clr_vector(tst); + + return res; +} + int draw_eval_real(ivl_expr_t exp) { int res = 0; @@ -307,6 +357,10 @@ int draw_eval_real(ivl_expr_t exp) res = draw_signal_real(exp); break; + case IVL_EX_TERNARY: + res = draw_ternary_real(exp); + break; + case IVL_EX_UFUNC: res = draw_ufunc_real(exp); break; @@ -339,6 +393,9 @@ int draw_eval_real(ivl_expr_t exp) /* * $Log: eval_real.c,v $ + * Revision 1.18 2007/02/14 05:59:46 steve + * Handle type of ternary expressions properly. + * * Revision 1.17 2007/01/16 05:44:16 steve * Major rework of array handling. Memories are replaced with the * more general concept of arrays. The NetMemory and NetEMemory