diff --git a/tgt-vvp/eval_real.c b/tgt-vvp/eval_real.c index eba2cfce7..b0176b0a7 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.21 2007/06/07 03:20:15 steve Exp $" +#ident "$Id: eval_real.c,v 1.22 2007/06/12 02:36:58 steve Exp $" #endif /* @@ -142,6 +142,17 @@ static int draw_realnum_real(ivl_expr_t exp) unsigned long mant; int sign = 0; + /* Handle the special case that the value is +-inf. */ + if (isinf(value)) { + if (value > 0) + fprintf(vvp_out, " %%loadi/wr %d, 0, %d; load=+inf\n", + res, 0x3fff); + else + fprintf(vvp_out, " %%loadi/wr %d, 0, %d; load=-inf\n", + res, 0x7fff); + return res; + } + if (value < 0) { sign = 0x4000; value *= -1; @@ -426,6 +437,9 @@ int draw_eval_real(ivl_expr_t exp) /* * $Log: eval_real.c,v $ + * Revision 1.22 2007/06/12 02:36:58 steve + * handle constant inf values. + * * Revision 1.21 2007/06/07 03:20:15 steve * Properly handle signed conversion to real * diff --git a/vvp/opcodes.txt b/vvp/opcodes.txt index b8efff1d6..bb2d5d91d 100644 --- a/vvp/opcodes.txt +++ b/vvp/opcodes.txt @@ -1,7 +1,7 @@ /* * Copyright (c) 2001-2003 Stephen Williams (steve@icarus.com) * - * $Id: opcodes.txt,v 1.77 2007/06/07 03:20:16 steve Exp $ + * $Id: opcodes.txt,v 1.78 2007/06/12 02:36:58 steve Exp $ */ @@ -433,9 +433,12 @@ auto-increment feature. This opcode loads an immediate value, floating point, into the word register selected by . The mantissa is an unsigned integer value, up to 32 bits, that multiplied by 2**(-0x1000) to make a real -value. The sign bit is OR-ed into the value at bit 0x2000, and +value. The sign bit is OR-ed into the value at bit 0x4000, and is removed from the before calculating the real value. +If ==0x3fff and == 0, the value is +inf. +If ==0x7fff and == 0, the value is -inf. +If --0x3fff and != 0, the value is NaN. * %mod , , * %mod/s , , diff --git a/vvp/vthread.cc b/vvp/vthread.cc index de2355270..3523c03f6 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vthread.cc,v 1.164 2007/06/07 03:20:16 steve Exp $" +#ident "$Id: vthread.cc,v 1.165 2007/06/12 02:36:58 steve Exp $" #endif # include "config.h" @@ -2194,6 +2194,22 @@ bool of_LOADI_WR(vthread_t thr, vvp_code_t cp) unsigned idx = cp->bit_idx[0]; double mant = cp->number; int exp = cp->bit_idx[1]; + + // Detect +infinity + if (exp==0x3fff && cp->number==0) { + thr->words[idx].w_real = INFINITY; + return true; + } + // Detect -infinity + if (exp==0x7fff && cp->number==0) { + thr->words[idx].w_real = -INFINITY; + return true; + } + // Detect NaN + if ( (exp&0x3fff) == 0x3fff ) { + thr->words[idx].w_real = NAN; + } + double sign = (exp & 0x4000)? -1.0 : 1.0; exp &= 0x1fff; @@ -3473,6 +3489,9 @@ bool of_JOIN_UFUNC(vthread_t thr, vvp_code_t cp) /* * $Log: vthread.cc,v $ + * Revision 1.165 2007/06/12 02:36:58 steve + * handle constant inf values. + * * Revision 1.164 2007/06/07 03:20:16 steve * Properly handle signed conversion to real * diff --git a/vvp/vvp_net.cc b/vvp/vvp_net.cc index 20d536347..e8ef2e059 100644 --- a/vvp/vvp_net.cc +++ b/vvp/vvp_net.cc @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#ident "$Id: vvp_net.cc,v 1.63 2007/04/15 02:07:24 steve Exp $" +#ident "$Id: vvp_net.cc,v 1.64 2007/06/12 02:36:58 steve Exp $" # include "config.h" # include "vvp_net.h" @@ -630,6 +630,8 @@ bool vector4_to_value(const vvp_vector4_t&vec, double&val, bool signed_flag) return true; } + bool flag = true; + if (vec.value(vec.size()-1) != BIT4_1) { signed_flag = false; } @@ -647,7 +649,7 @@ bool vector4_to_value(const vvp_vector4_t&vec, double&val, bool signed_flag) res += pow(2.0, (int)idx); break; default: - return false; + flag = false; } } res *= -1.0; @@ -660,12 +662,12 @@ bool vector4_to_value(const vvp_vector4_t&vec, double&val, bool signed_flag) res += pow(2.0, (int)idx); break; default: - return false; + flag = false; } } } val = res; - return true; + return flag; } template T coerce_to_width(const T&that, unsigned width) @@ -2293,6 +2295,9 @@ vvp_bit4_t compare_gtge_signed(const vvp_vector4_t&a, /* * $Log: vvp_net.cc,v $ + * Revision 1.64 2007/06/12 02:36:58 steve + * handle constant inf values. + * * Revision 1.63 2007/04/15 02:07:24 steve * Fix div/mod calculation that caused a hang for some divisions. * diff --git a/vvp/vvp_net.h b/vvp/vvp_net.h index 396cb2773..db46c5746 100644 --- a/vvp/vvp_net.h +++ b/vvp/vvp_net.h @@ -18,7 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#ident "$Id: vvp_net.h,v 1.57 2007/03/22 16:08:19 steve Exp $" +#ident "$Id: vvp_net.h,v 1.58 2007/06/12 02:36:58 steve Exp $" # include "config.h" # include @@ -254,8 +254,10 @@ template extern T coerce_to_width(const T&that, unsigned width); /* * These functions extract the value of the vector as a native type, * if possible, and return true to indicate success. If the vector has - * any X or Z bits, the resulting value will be unchanged and the - * return value becomes false to indicate an error. + * any X or Z bits, the resulting value will have 0 bits in their + * place (this follows the rules of Verilog conversions from vector4 + * to real and integers) and the return value becomes false to + * indicate an error. */ extern bool vector4_to_value(const vvp_vector4_t&a, unsigned long&val); extern bool vector4_to_value(const vvp_vector4_t&a, double&val, bool is_signed); @@ -1040,6 +1042,9 @@ inline void vvp_send_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&val, /* * $Log: vvp_net.h,v $ + * Revision 1.58 2007/06/12 02:36:58 steve + * handle constant inf values. + * * Revision 1.57 2007/03/22 16:08:19 steve * Spelling fixes from Larry *