Add signed versions of .cmp/gt/ge

This commit is contained in:
steve 2003-04-11 05:15:38 +00:00
parent 58f2fe73c8
commit 2c1e36ae9a
7 changed files with 118 additions and 24 deletions

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
*
* $Id: README.txt,v 1.43 2003/03/10 23:37:07 steve Exp $
* $Id: README.txt,v 1.44 2003/04/11 05:15:38 steve Exp $
*/
VVP SIMULATION ENGINE
@ -502,11 +502,14 @@ similar:
<label> .cmp/ge <wid>, <symbols_list>;
<label> .cmp/gt <wid>, <symbols_list>;
<label> .cmp/ge.s <wid>, <symbols_list>;
<label> .cmp/gt.s <wid>, <symbols_list>;
Whereas the arithmetic statements create an array of functor outputs,
there is only one useful functor output for the comparators. That
functor output is 1 of the comparison is true, 0 if false, and x
otherwise.
otherwise. The plain versions do unsigned comparison, but the ".s"
versions to signed comparisons.
STRUCTURAL SHIFTER STATEMENTS:

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: arith.cc,v 1.24 2002/08/12 01:35:07 steve Exp $"
#ident "$Id: arith.cc,v 1.25 2003/04/11 05:15:38 steve Exp $"
#endif
# include "arith.h"
@ -380,6 +380,11 @@ void vvp_arith_sub::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
output_val_(base, push);
}
vvp_cmp_ge::vvp_cmp_ge(unsigned wid, bool flag)
: vvp_arith_(wid), signed_flag_(flag)
{
}
void vvp_cmp_ge::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
{
@ -415,21 +420,54 @@ void vvp_cmp_ge::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
put_oval(out_val, push);
}
vvp_cmp_gt::vvp_cmp_gt(unsigned wid, bool flag)
: vvp_arith_(wid), signed_flag_(flag)
{
}
void vvp_cmp_gt::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
{
put(i, val);
vvp_ipoint_t base = ipoint_make(i,0);
unsigned out_val = 0;
for (unsigned idx = wid_ ; idx > 0 ; idx -= 1) {
unsigned idx = wid_;
/* If this is a signed compare, then check the MSB of the
input vectors. If they are different, then the values are
on the different sides of zero, and we know the result. */
if (signed_flag_) {
vvp_ipoint_t ptr = ipoint_index(base, wid_-1);
functor_t obj = functor_index(ptr);
unsigned val = obj->ival;
if (val & 0x0a) {
out_val = 2;
goto check_for_x_complete;
}
unsigned a = (val & 0x01)? 1 : 0;
unsigned b = (val & 0x04)? 1 : 0;
/* If a==0 and b==1, then a>=0 and b<0 so return true.
If a==1 and b==0, then a<0 and b>=0 so return false.
It turns out that out_val=b gets the right result. */
if (a ^ b) {
out_val = b;
idx = wid_-1;
goto check_for_x;
}
}
for (idx = wid_ ; idx > 0 ; idx -= 1) {
vvp_ipoint_t ptr = ipoint_index(base, idx-1);
functor_t obj = functor_index(ptr);
unsigned val = obj->ival;
if (val & 0x0a) {
out_val = 2;
break;
goto check_for_x_complete;
}
unsigned a = (val & 0x01)? 1 : 0;
@ -446,6 +484,24 @@ void vvp_cmp_gt::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
}
}
check_for_x:
/* Continue further checking bits, looking for unknown
results. */
while ((idx > 0) && (out_val != 2)) {
vvp_ipoint_t ptr = ipoint_index(base, idx-1);
functor_t obj = functor_index(ptr);
unsigned val = obj->ival;
if (val & 0x0a) {
out_val = 2;
break;
}
idx -= 1;
}
check_for_x_complete:
put_oval(out_val, push);
}
@ -551,6 +607,9 @@ void vvp_shiftr::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
/*
* $Log: arith.cc,v $
* Revision 1.25 2003/04/11 05:15:38 steve
* Add signed versions of .cmp/gt/ge
*
* Revision 1.24 2002/08/12 01:35:07 steve
* conditional ident string using autoconfig.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: arith.h,v 1.14 2002/08/12 01:35:07 steve Exp $"
#ident "$Id: arith.h,v 1.15 2003/04/11 05:15:38 steve Exp $"
#endif
# include "functor.h"
@ -104,17 +104,21 @@ class vvp_arith_sub : public vvp_wide_arith_ {
class vvp_cmp_ge : public vvp_arith_ {
public:
explicit vvp_cmp_ge(unsigned wid) : vvp_arith_(wid) {}
explicit vvp_cmp_ge(unsigned wid, bool signed_flag);
void set(vvp_ipoint_t i, bool push, unsigned val, unsigned str);
private:
bool signed_flag_;
};
class vvp_cmp_gt : public vvp_arith_ {
public:
explicit vvp_cmp_gt(unsigned wid) : vvp_arith_(wid) {}
explicit vvp_cmp_gt(unsigned wid, bool signed_flag);
void set(vvp_ipoint_t i, bool push, unsigned val, unsigned str);
private:
bool signed_flag_;
};
class vvp_shiftl : public vvp_arith_ {
@ -135,6 +139,9 @@ class vvp_shiftr : public vvp_arith_ {
/*
* $Log: arith.h,v $
* Revision 1.15 2003/04/11 05:15:38 steve
* Add signed versions of .cmp/gt/ge
*
* Revision 1.14 2002/08/12 01:35:07 steve
* conditional ident string using autoconfig.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: compile.cc,v 1.158 2003/03/28 02:33:56 steve Exp $"
#ident "$Id: compile.cc,v 1.159 2003/04/11 05:15:38 steve Exp $"
#endif
# include "arith.h"
@ -906,7 +906,8 @@ void compile_arith_sum(char*label, long wid, unsigned argc, struct symb_s*argv)
make_arith(arith, label, wid, argc, argv);
}
void compile_cmp_ge(char*label, long wid, unsigned argc, struct symb_s*argv)
void compile_cmp_ge(char*label, long wid, bool signed_flag,
unsigned argc, struct symb_s*argv)
{
assert( wid > 0 );
@ -916,12 +917,13 @@ void compile_cmp_ge(char*label, long wid, unsigned argc, struct symb_s*argv)
return;
}
vvp_arith_ *arith = new vvp_cmp_ge(wid);
vvp_arith_ *arith = new vvp_cmp_ge(wid, signed_flag);
make_arith(arith, label, wid, argc, argv);
}
void compile_cmp_gt(char*label, long wid, unsigned argc, struct symb_s*argv)
void compile_cmp_gt(char*label, long wid, bool signed_flag,
unsigned argc, struct symb_s*argv)
{
assert( wid > 0 );
@ -931,7 +933,7 @@ void compile_cmp_gt(char*label, long wid, unsigned argc, struct symb_s*argv)
return;
}
vvp_arith_ *arith = new vvp_cmp_gt(wid);
vvp_arith_ *arith = new vvp_cmp_gt(wid, signed_flag);
make_arith(arith, label, wid, argc, argv);
}
@ -1528,6 +1530,9 @@ void compile_param_string(char*label, char*name, char*str, char*value)
/*
* $Log: compile.cc,v $
* Revision 1.159 2003/04/11 05:15:38 steve
* Add signed versions of .cmp/gt/ge
*
* Revision 1.158 2003/03/28 02:33:56 steve
* Add support for division of real operands.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: compile.h,v 1.50 2003/03/10 23:37:07 steve Exp $"
#ident "$Id: compile.h,v 1.51 2003/04/11 05:15:39 steve Exp $"
#endif
# include <stdio.h>
@ -107,9 +107,9 @@ extern void compile_arith_sum(char*label, long width,
unsigned argc, struct symb_s*argv);
extern void compile_arith_sub(char*label, long width,
unsigned argc, struct symb_s*argv);
extern void compile_cmp_ge(char*label, long width,
extern void compile_cmp_ge(char*label, long width, bool signed_flag,
unsigned argc, struct symb_s*argv);
extern void compile_cmp_gt(char*label, long width,
extern void compile_cmp_gt(char*label, long width, bool signed_flag,
unsigned argc, struct symb_s*argv);
extern void compile_shiftl(char*label, long width,
unsigned argc, struct symb_s*argv);
@ -264,6 +264,9 @@ extern void compile_net(char*label, char*name,
/*
* $Log: compile.h,v $
* Revision 1.51 2003/04/11 05:15:39 steve
* Add signed versions of .cmp/gt/ge
*
* Revision 1.50 2003/03/10 23:37:07 steve
* Direct support for string parameters.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: lexor.lex,v 1.39 2003/03/10 23:37:07 steve Exp $"
#ident "$Id: lexor.lex,v 1.40 2003/04/11 05:15:39 steve Exp $"
#endif
# include "parse_misc.h"
@ -89,7 +89,9 @@
".arith/sub" { return K_ARITH_SUB; }
".arith/sum" { return K_ARITH_SUM; }
".cmp/ge" { return K_CMP_GE; }
".cmp/ge.s" { return K_CMP_GE_S; }
".cmp/gt" { return K_CMP_GT; }
".cmp/gt.s" { return K_CMP_GT_S; }
".event" { return K_EVENT; }
".event/or" { return K_EVENT_OR; }
".functor" { return K_FUNCTOR; }
@ -177,6 +179,9 @@ int yywrap()
/*
* $Log: lexor.lex,v $
* Revision 1.40 2003/04/11 05:15:39 steve
* Add signed versions of .cmp/gt/ge
*
* Revision 1.39 2003/03/10 23:37:07 steve
* Direct support for string parameters.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: parse.y,v 1.52 2003/03/10 23:37:07 steve Exp $"
#ident "$Id: parse.y,v 1.53 2003/04/11 05:15:39 steve Exp $"
#endif
# include "parse_misc.h"
@ -58,7 +58,7 @@ extern FILE*yyin;
%token K_ARITH_DIV K_ARITH_MOD K_ARITH_MULT K_ARITH_SUB K_ARITH_SUM
%token K_CMP_GE K_CMP_GT
%token K_CMP_GE K_CMP_GE_S K_CMP_GT K_CMP_GT_S
%token K_EVENT K_EVENT_OR K_FUNCTOR K_NET K_NET_S K_PARAM
%token K_RESOLV K_SCOPE K_SHIFTL K_SHIFTR K_THREAD K_TIMESCALE K_UFUNC
%token K_UDP K_UDP_C K_UDP_S
@ -217,12 +217,21 @@ statement
| T_LABEL K_CMP_GE T_NUMBER ',' symbols ';'
{ struct symbv_s obj = $5;
compile_cmp_ge($1, $3, obj.cnt, obj.vect);
compile_cmp_ge($1, $3, false, obj.cnt, obj.vect);
}
| T_LABEL K_CMP_GE_S T_NUMBER ',' symbols ';'
{ struct symbv_s obj = $5;
compile_cmp_ge($1, $3, true, obj.cnt, obj.vect);
}
| T_LABEL K_CMP_GT T_NUMBER ',' symbols ';'
{ struct symbv_s obj = $5;
compile_cmp_gt($1, $3, obj.cnt, obj.vect);
compile_cmp_gt($1, $3, false, obj.cnt, obj.vect);
}
| T_LABEL K_CMP_GT_S T_NUMBER ',' symbols ';'
{ struct symbv_s obj = $5;
compile_cmp_gt($1, $3, true, obj.cnt, obj.vect);
}
@ -575,6 +584,9 @@ int compile_design(const char*path)
/*
* $Log: parse.y,v $
* Revision 1.53 2003/04/11 05:15:39 steve
* Add signed versions of .cmp/gt/ge
*
* Revision 1.52 2003/03/10 23:37:07 steve
* Direct support for string parameters.
*