From 898639d7bf933c8d49eac2870e9f2363c47d4543 Mon Sep 17 00:00:00 2001 From: steve Date: Thu, 5 Apr 2001 01:12:27 +0000 Subject: [PATCH] Get signed compares working correctly in vvp. --- ivl_target.h | 12 +++++++++- t-dll-api.cc | 10 ++++++++- t-dll-expr.cc | 7 +++++- t-dll.cc | 7 ++++-- tgt-stub/stub.c | 10 +++++++-- tgt-vvp/eval_expr.c | 30 ++++++++++++++++++++----- vvp/codes.h | 6 ++++- vvp/compile.cc | 6 ++++- vvp/vthread.cc | 55 ++++++++++++++++++++++++++++++++++++++++++++- 9 files changed, 128 insertions(+), 15 deletions(-) diff --git a/ivl_target.h b/ivl_target.h index 3375ebb5d..054558222 100644 --- a/ivl_target.h +++ b/ivl_target.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: ivl_target.h,v 1.47 2001/04/04 04:50:35 steve Exp $" +#ident "$Id: ivl_target.h,v 1.48 2001/04/05 01:12:27 steve Exp $" #endif #ifdef __cplusplus @@ -612,7 +612,13 @@ extern const char* ivl_scope_tname(ivl_scope_t net); * port direction. If the signal is not a port, it returns * IVL_SIP_NONE. * + * ivl_signal_signed + * A signal, which is a vector, may be signed. In Verilog 2000, any + * net or variable may be signed. This function returns true if the + * signal is signed. + * * ivl_signal_type + * Return the type of the signal, i.e. reg, wire, tri0, et al. * * ivl_signal_name * This function returns the fully scoped hierarchical name for the @@ -632,6 +638,7 @@ extern const char* ivl_scope_tname(ivl_scope_t net); extern ivl_nexus_t ivl_signal_pin(ivl_signal_t net, unsigned idx); extern unsigned ivl_signal_pins(ivl_signal_t net); extern ivl_signal_port_t ivl_signal_port(ivl_signal_t net); +extern int ivl_signal_signed(ivl_signal_t net); extern ivl_signal_type_t ivl_signal_type(ivl_signal_t net); extern const char* ivl_signal_name(ivl_signal_t net); extern const char* ivl_signal_basename(ivl_signal_t net); @@ -737,6 +744,9 @@ _END_DECL /* * $Log: ivl_target.h,v $ + * Revision 1.48 2001/04/05 01:12:27 steve + * Get signed compares working correctly in vvp. + * * Revision 1.47 2001/04/04 04:50:35 steve * Support forever loops in the tgt-vvp target. * diff --git a/t-dll-api.cc b/t-dll-api.cc index a8c3934bb..0ebf2870b 100644 --- a/t-dll-api.cc +++ b/t-dll-api.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: t-dll-api.cc,v 1.34 2001/04/04 04:50:35 steve Exp $" +#ident "$Id: t-dll-api.cc,v 1.35 2001/04/05 01:12:28 steve Exp $" #endif # include "t-dll.h" @@ -579,6 +579,11 @@ extern "C" ivl_signal_port_t ivl_signal_port(ivl_signal_t net) return net->port_; } +extern "C" int ivl_signal_signed(ivl_signal_t net) +{ + return net->signed_ != 0; +} + extern "C" ivl_signal_type_t ivl_signal_type(ivl_signal_t net) { return net->type_; @@ -836,6 +841,9 @@ extern "C" ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net) /* * $Log: t-dll-api.cc,v $ + * Revision 1.35 2001/04/05 01:12:28 steve + * Get signed compares working correctly in vvp. + * * Revision 1.34 2001/04/04 04:50:35 steve * Support forever loops in the tgt-vvp target. * diff --git a/t-dll-expr.cc b/t-dll-expr.cc index e1a325490..d872a1475 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 */ #if !defined(WINNT) & !defined(macintosh) -#ident "$Id: t-dll-expr.cc,v 1.9 2001/04/02 00:28:35 steve Exp $" +#ident "$Id: t-dll-expr.cc,v 1.10 2001/04/05 01:12:28 steve Exp $" #endif # include "t-dll.h" @@ -49,6 +49,7 @@ void dll_target::expr_binary(const NetEBinary*net) expr_->type_ = IVL_EX_BINARY; expr_->width_= net->expr_width(); + expr_->signed_ = net->has_sign()? 1 : 0; expr_->u_.binary_.op_ = net->op(); expr_->u_.binary_.lef_ = left; @@ -152,6 +153,7 @@ void dll_target::expr_signal(const NetESignal*net) expr_->type_ = IVL_EX_SIGNAL; expr_->width_= net->expr_width(); + expr_->signed_ = net->has_sign()? 1 : 0; expr_->u_.subsig_.name_ = strdup(net->name().c_str()); } @@ -173,6 +175,9 @@ void dll_target::expr_unary(const NetEUnary*net) /* * $Log: t-dll-expr.cc,v $ + * Revision 1.10 2001/04/05 01:12:28 steve + * Get signed compares working correctly in vvp. + * * Revision 1.9 2001/04/02 00:28:35 steve * Support the scope expression node. * diff --git a/t-dll.cc b/t-dll.cc index f8ec83612..e479cd61e 100644 --- a/t-dll.cc +++ b/t-dll.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: t-dll.cc,v 1.32 2001/04/01 01:48:21 steve Exp $" +#ident "$Id: t-dll.cc,v 1.33 2001/04/05 01:12:28 steve Exp $" #endif # include "compiler.h" @@ -616,7 +616,7 @@ void dll_target::signal(const NetNet*net) ivl_signal_t object. */ obj->width_ = net->pin_count(); - obj->signed_= 0; + obj->signed_= net->get_signed()? 1 : 0; switch (net->port_type()) { @@ -746,6 +746,9 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj }; /* * $Log: t-dll.cc,v $ + * Revision 1.33 2001/04/05 01:12:28 steve + * Get signed compares working correctly in vvp. + * * Revision 1.32 2001/04/01 01:48:21 steve * Redesign event information to support arbitrary edge combining. * diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index 5d4b91815..7354b6fdc 100644 --- a/tgt-stub/stub.c +++ b/tgt-stub/stub.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: stub.c,v 1.36 2001/04/03 04:50:37 steve Exp $" +#ident "$Id: stub.c,v 1.37 2001/04/05 01:12:28 steve Exp $" #endif /* @@ -210,10 +210,12 @@ static void show_statement(ivl_statement_t net, unsigned ind) } case IVL_ST_CONDIT: { + ivl_expr_t ex = ivl_stmt_cond_expr(net); ivl_statement_t t = ivl_stmt_cond_true(net); ivl_statement_t f = ivl_stmt_cond_false(net); fprintf(out, "%*sif (...)\n", ind, ""); + show_expression(ex, ind+4); if (t) show_statement(t, ind+4); else @@ -323,6 +325,7 @@ static void show_signal(ivl_signal_t net) unsigned pin; const char*type = "?"; const char*port = ""; + const char*sign = ivl_signal_signed(net)? "signed" : "unsigned"; switch (ivl_signal_type(net)) { case IVL_SIT_REG: @@ -348,7 +351,7 @@ static void show_signal(ivl_signal_t net) break; } - fprintf(out, " %s %s[%u] %s\n", type, port, + fprintf(out, " %s %s %s[%u] %s\n", type, sign, port, ivl_signal_pins(net), ivl_signal_basename(net)); for (pin = 0 ; pin < ivl_signal_pins(net) ; pin += 1) { @@ -506,6 +509,9 @@ DECLARE_CYGWIN_DLL(DllMain); /* * $Log: stub.c,v $ + * Revision 1.37 2001/04/05 01:12:28 steve + * Get signed compares working correctly in vvp. + * * Revision 1.36 2001/04/03 04:50:37 steve * Support non-blocking assignments. * diff --git a/tgt-vvp/eval_expr.c b/tgt-vvp/eval_expr.c index a5e331e55..f72f9ac74 100644 --- a/tgt-vvp/eval_expr.c +++ b/tgt-vvp/eval_expr.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: eval_expr.c,v 1.12 2001/04/02 03:47:49 steve Exp $" +#ident "$Id: eval_expr.c,v 1.13 2001/04/05 01:12:28 steve Exp $" #endif # include "vvp_priv.h" @@ -197,6 +197,8 @@ static struct vector_info draw_binary_expr_le(ivl_expr_t exp, unsigned wid) struct vector_info lv; struct vector_info rv; + char s_flag = (ivl_expr_signed(le) && ivl_expr_signed(re)) ? 's' : 'u'; + unsigned owid = ivl_expr_width(le); if (ivl_expr_width(re) > owid) owid = ivl_expr_width(re); @@ -205,17 +207,30 @@ static struct vector_info draw_binary_expr_le(ivl_expr_t exp, unsigned wid) rv = draw_eval_expr_wid(re, owid); switch (ivl_expr_opcode(exp)) { + case 'G': + assert(lv.wid == rv.wid); + fprintf(vvp_out, " %%cmp/%c %u, %u, %u;\n", s_flag, + rv.base, lv.base, lv.wid); + fprintf(vvp_out, " %%or 5, 4, 1;\n"); + break; + case 'L': assert(lv.wid == rv.wid); - fprintf(vvp_out, " %%cmp/u %u, %u, %u;\n", lv.base, - rv.base, lv.wid); + fprintf(vvp_out, " %%cmp/%c %u, %u, %u;\n", s_flag, + lv.base, rv.base, lv.wid); fprintf(vvp_out, " %%or 5, 4, 1;\n"); break; case '<': assert(lv.wid == rv.wid); - fprintf(vvp_out, " %%cmp/u %u, %u, %u;\n", lv.base, - rv.base, lv.wid); + fprintf(vvp_out, " %%cmp/%c %u, %u, %u;\n", s_flag, + lv.base, rv.base, lv.wid); + break; + + case '>': + assert(lv.wid == rv.wid); + fprintf(vvp_out, " %%cmp/%c %u, %u, %u;\n", s_flag, + rv.base, lv.base, lv.wid); break; default: @@ -303,7 +318,9 @@ static struct vector_info draw_binary_expr(ivl_expr_t exp, unsigned wid) break; case '<': + case '>': case 'L': /* <= */ + case 'G': /* >= */ rv = draw_binary_expr_le(exp, wid); break; @@ -553,6 +570,9 @@ struct vector_info draw_eval_expr(ivl_expr_t exp) /* * $Log: eval_expr.c,v $ + * Revision 1.13 2001/04/05 01:12:28 steve + * Get signed compares working correctly in vvp. + * * Revision 1.12 2001/04/02 03:47:49 steve * Evaluate binary & and | operators. * diff --git a/vvp/codes.h b/vvp/codes.h index de558d541..a10a8a816 100644 --- a/vvp/codes.h +++ b/vvp/codes.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: codes.h,v 1.15 2001/04/01 22:25:33 steve Exp $" +#ident "$Id: codes.h,v 1.16 2001/04/05 01:12:28 steve Exp $" #endif @@ -38,6 +38,7 @@ typedef bool (*vvp_code_fun)(vthread_t thr, vvp_code_t code); extern bool of_ADD(vthread_t thr, vvp_code_t code); extern bool of_AND(vthread_t thr, vvp_code_t code); extern bool of_ASSIGN(vthread_t thr, vvp_code_t code); +extern bool of_CMPS(vthread_t thr, vvp_code_t code); extern bool of_CMPU(vthread_t thr, vvp_code_t code); extern bool of_CMPX(vthread_t thr, vvp_code_t code); extern bool of_CMPZ(vthread_t thr, vvp_code_t code); @@ -105,6 +106,9 @@ extern void codespace_dump(FILE*fd); /* * $Log: codes.h,v $ + * Revision 1.16 2001/04/05 01:12:28 steve + * Get signed compares working correctly in vvp. + * * Revision 1.15 2001/04/01 22:25:33 steve * Add the reduction nor instruction. * diff --git a/vvp/compile.cc b/vvp/compile.cc index fa0da258c..70799713b 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: compile.cc,v 1.28 2001/04/01 22:25:33 steve Exp $" +#ident "$Id: compile.cc,v 1.29 2001/04/05 01:12:28 steve Exp $" #endif # include "compile.h" @@ -68,6 +68,7 @@ const static struct opcode_table_s opcode_table[] = { { "%add", of_ADD, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%and", of_AND, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%assign", of_ASSIGN, 3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} }, + { "%cmp/s", of_CMPS, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%cmp/u", of_CMPU, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%cmp/x", of_CMPX, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%cmp/z", of_CMPZ, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, @@ -712,6 +713,9 @@ void compile_dump(FILE*fd) /* * $Log: compile.cc,v $ + * Revision 1.29 2001/04/05 01:12:28 steve + * Get signed compares working correctly in vvp. + * * Revision 1.28 2001/04/01 22:25:33 steve * Add the reduction nor instruction. * diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 26d2e63c7..39e48d995 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 */ #if !defined(WINNT) -#ident "$Id: vthread.cc,v 1.21 2001/04/03 03:18:34 steve Exp $" +#ident "$Id: vthread.cc,v 1.22 2001/04/05 01:12:28 steve Exp $" #endif # include "vthread.h" @@ -208,6 +208,56 @@ bool of_ASSIGN(vthread_t thr, vvp_code_t cp) return true; } +bool of_CMPS(vthread_t thr, vvp_code_t cp) +{ + unsigned eq = 1; + unsigned eeq = 1; + unsigned lt = 0; + + unsigned idx1 = cp->bit_idx1; + unsigned idx2 = cp->bit_idx2; + + unsigned sig1 = thr_get_bit(thr, idx1 + cp->number - 1); + unsigned sig2 = thr_get_bit(thr, idx2 + cp->number - 1); + + for (unsigned idx = 0 ; idx < cp->number ; idx += 1) { + unsigned lv = thr_get_bit(thr, idx1); + unsigned rv = thr_get_bit(thr, idx2); + + if (lv > rv) { + lt = 0; + eeq = 0; + } else if (lv < rv) { + lt = 1; + eeq = 0; + } + if (eq != 2) { + if ((lv == 0) && (rv != 0)) + eq = 0; + if ((lv == 1) && (rv != 1)) + eq = 0; + if ((lv | rv) >= 2) + eq = 2; + } + + if (idx1 >= 4) idx1 += 1; + if (idx2 >= 4) idx2 += 1; + } + + if (eq == 2) + lt = 2; + else if ((sig1 == 1) && (sig2 == 0)) + lt = 1; + else if ((sig1 == 0) && (sig2 == 1)) + lt = 0; + + thr_put_bit(thr, 4, eq); + thr_put_bit(thr, 5, lt); + thr_put_bit(thr, 6, eeq); + + return true; +} + bool of_CMPU(vthread_t thr, vvp_code_t cp) { unsigned eq = 1; @@ -504,6 +554,9 @@ bool of_WAIT(vthread_t thr, vvp_code_t cp) /* * $Log: vthread.cc,v $ + * Revision 1.22 2001/04/05 01:12:28 steve + * Get signed compares working correctly in vvp. + * * Revision 1.21 2001/04/03 03:18:34 steve * support functor_set push for blocking assignment. *