Add .cmp statements for structural comparison.
This commit is contained in:
parent
7009dc8d9b
commit
e002b1c1c4
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* $Id: README.txt,v 1.28 2001/06/15 03:28:30 steve Exp $
|
||||
* $Id: README.txt,v 1.29 2001/06/15 04:07:57 steve Exp $
|
||||
*/
|
||||
|
||||
VVP SIMULATION ENGINE
|
||||
|
|
@ -436,6 +436,23 @@ number of symbols must be an even multiple of the width of the operator.
|
|||
Subtraction is similar to addition, except that the 2nd, 3rd and 4th
|
||||
vectors are subtracted from the first.
|
||||
|
||||
|
||||
STRUCTURAL COMPARE STATEMENTS:
|
||||
|
||||
The arithmetic statements handle various arithmetic operators that
|
||||
have wide outputs, but the comparators have single bit output, so they
|
||||
are implemented a bit differently. The syntax, however, is very
|
||||
similar:
|
||||
|
||||
<label> .cmp/ge <wid>, <symbols_list>;
|
||||
<label> .cmp/gt <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.
|
||||
|
||||
|
||||
THREAD STATEMENTS:
|
||||
|
||||
Thread statements create the initial threads for a simulation. These
|
||||
|
|
|
|||
87
vvp/arith.cc
87
vvp/arith.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: arith.cc,v 1.2 2001/06/07 03:09:03 steve Exp $"
|
||||
#ident "$Id: arith.cc,v 1.3 2001/06/15 04:07:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "arith.h"
|
||||
|
|
@ -154,8 +154,93 @@ void vvp_arith_sub::set(vvp_ipoint_t i, functor_t f, bool push)
|
|||
}
|
||||
}
|
||||
|
||||
vvp_cmp_ge::vvp_cmp_ge(vvp_ipoint_t b, unsigned w)
|
||||
: vvp_arith_(b, w)
|
||||
{
|
||||
}
|
||||
|
||||
void vvp_cmp_ge::set(vvp_ipoint_t i, functor_t f, bool push)
|
||||
{
|
||||
functor_t base_obj = functor_index(base_);
|
||||
assert(wid_ <= sizeof(unsigned long));
|
||||
unsigned long a = 0, b = 0;
|
||||
unsigned out_val = 0;
|
||||
|
||||
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
|
||||
vvp_ipoint_t ptr = ipoint_index(base_,idx);
|
||||
functor_t obj = functor_index(ptr);
|
||||
|
||||
unsigned ival = obj->ival;
|
||||
if (ival & 0x0a) {
|
||||
out_val = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ival & 0x01)
|
||||
a += 1 << idx;
|
||||
if (ival & 0x04)
|
||||
b += 1 << idx;
|
||||
}
|
||||
|
||||
|
||||
if (out_val == 0)
|
||||
out_val = (a >= b) ? 1 : 0;
|
||||
|
||||
if (out_val != base_obj->oval) {
|
||||
base_obj->oval = out_val;
|
||||
if (push)
|
||||
functor_propagate(base_);
|
||||
else
|
||||
schedule_functor(base_, 0);
|
||||
}
|
||||
}
|
||||
|
||||
vvp_cmp_gt::vvp_cmp_gt(vvp_ipoint_t b, unsigned w)
|
||||
: vvp_arith_(b, w)
|
||||
{
|
||||
}
|
||||
|
||||
void vvp_cmp_gt::set(vvp_ipoint_t i, functor_t f, bool push)
|
||||
{
|
||||
functor_t base_obj = functor_index(base_);
|
||||
assert(wid_ <= sizeof(unsigned long));
|
||||
unsigned long a = 0, b = 0;
|
||||
unsigned out_val = 0;
|
||||
|
||||
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
|
||||
vvp_ipoint_t ptr = ipoint_index(base_,idx);
|
||||
functor_t obj = functor_index(ptr);
|
||||
|
||||
unsigned ival = obj->ival;
|
||||
if (ival & 0x0a) {
|
||||
out_val = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ival & 0x01)
|
||||
a += 1 << idx;
|
||||
if (ival & 0x04)
|
||||
b += 1 << idx;
|
||||
}
|
||||
|
||||
|
||||
if (out_val == 0)
|
||||
out_val = (a > b) ? 1 : 0;
|
||||
|
||||
if (out_val != base_obj->oval) {
|
||||
base_obj->oval = out_val;
|
||||
if (push)
|
||||
functor_propagate(base_);
|
||||
else
|
||||
schedule_functor(base_, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: arith.cc,v $
|
||||
* Revision 1.3 2001/06/15 04:07:58 steve
|
||||
* Add .cmp statements for structural comparison.
|
||||
*
|
||||
* Revision 1.2 2001/06/07 03:09:03 steve
|
||||
* Implement .arith/sub subtraction.
|
||||
*
|
||||
|
|
|
|||
28
vvp/arith.h
28
vvp/arith.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: arith.h,v 1.2 2001/06/07 03:09:03 steve Exp $"
|
||||
#ident "$Id: arith.h,v 1.3 2001/06/15 04:07:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "functor.h"
|
||||
|
|
@ -71,8 +71,34 @@ class vvp_arith_sub : public vvp_arith_ {
|
|||
vvp_arith_sub& operator= (const vvp_arith_sub&);
|
||||
};
|
||||
|
||||
class vvp_cmp_ge : public vvp_arith_ {
|
||||
|
||||
public:
|
||||
explicit vvp_cmp_ge(vvp_ipoint_t b, unsigned wid);
|
||||
|
||||
void set(vvp_ipoint_t i, functor_t f, bool push);
|
||||
|
||||
private: // not implemented
|
||||
vvp_cmp_ge(const vvp_cmp_ge&);
|
||||
vvp_cmp_ge& operator= (const vvp_cmp_ge&);
|
||||
};
|
||||
|
||||
class vvp_cmp_gt : public vvp_arith_ {
|
||||
|
||||
public:
|
||||
explicit vvp_cmp_gt(vvp_ipoint_t b, unsigned wid);
|
||||
|
||||
void set(vvp_ipoint_t i, functor_t f, bool push);
|
||||
|
||||
private: // not implemented
|
||||
vvp_cmp_gt(const vvp_cmp_gt&);
|
||||
vvp_cmp_gt& operator= (const vvp_cmp_gt&);
|
||||
};
|
||||
/*
|
||||
* $Log: arith.h,v $
|
||||
* Revision 1.3 2001/06/15 04:07:58 steve
|
||||
* Add .cmp statements for structural comparison.
|
||||
*
|
||||
* Revision 1.2 2001/06/07 03:09:03 steve
|
||||
* Implement .arith/sub subtraction.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.75 2001/06/15 03:28:31 steve Exp $"
|
||||
#ident "$Id: compile.cc,v 1.76 2001/06/15 04:07:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "arith.h"
|
||||
|
|
@ -488,6 +488,46 @@ void compile_arith_sum(char*label, long wid, unsigned argc, struct symb_s*argv)
|
|||
|
||||
}
|
||||
|
||||
void compile_cmp_ge(char*label, long wid, unsigned argc, struct symb_s*argv)
|
||||
{
|
||||
assert( wid > 0 );
|
||||
|
||||
if (argc != 2*wid) {
|
||||
fprintf(stderr, "%s; .cmp has wrong number of symbols\n", label);
|
||||
compile_errors += 1;
|
||||
free(label);
|
||||
return;
|
||||
}
|
||||
|
||||
vvp_ipoint_t fdx = functor_allocate(wid);
|
||||
define_functor_symbol(label, fdx);
|
||||
|
||||
vvp_cmp_ge*cmp = new vvp_cmp_ge(fdx, wid);
|
||||
|
||||
connect_arith_inputs(fdx, wid, cmp, argc, argv);
|
||||
|
||||
}
|
||||
|
||||
void compile_cmp_gt(char*label, long wid, unsigned argc, struct symb_s*argv)
|
||||
{
|
||||
assert( wid > 0 );
|
||||
|
||||
if (argc != 2*wid) {
|
||||
fprintf(stderr, "%s; .cmp has wrong number of symbols\n", label);
|
||||
compile_errors += 1;
|
||||
free(label);
|
||||
return;
|
||||
}
|
||||
|
||||
vvp_ipoint_t fdx = functor_allocate(wid);
|
||||
define_functor_symbol(label, fdx);
|
||||
|
||||
vvp_cmp_gt*cmp = new vvp_cmp_gt(fdx, wid);
|
||||
|
||||
connect_arith_inputs(fdx, wid, cmp, argc, argv);
|
||||
|
||||
}
|
||||
|
||||
void compile_resolver(char*label, char*type, unsigned argc, struct symb_s*argv)
|
||||
{
|
||||
vvp_ipoint_t fdx = functor_allocate(1);
|
||||
|
|
@ -1340,6 +1380,9 @@ vvp_ipoint_t debug_lookup_functor(const char*name)
|
|||
|
||||
/*
|
||||
* $Log: compile.cc,v $
|
||||
* Revision 1.76 2001/06/15 04:07:58 steve
|
||||
* Add .cmp statements for structural comparison.
|
||||
*
|
||||
* Revision 1.75 2001/06/15 03:28:31 steve
|
||||
* Change the VPI call process so that loaded .vpi modules
|
||||
* use a function table instead of implicit binding.
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: compile.h,v 1.26 2001/06/15 03:28:31 steve Exp $"
|
||||
#ident "$Id: compile.h,v 1.27 2001/06/15 04:07:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <stdio.h>
|
||||
|
|
@ -70,12 +70,17 @@ extern void compile_resolver(char*label, char*type,
|
|||
unsigned argc, struct symb_s*argv);
|
||||
|
||||
/*
|
||||
* This is called by the parser to make an adder.
|
||||
* This is called by the parser to make the various arithmetic and
|
||||
* comparison functors.
|
||||
*/
|
||||
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,
|
||||
unsigned argc, struct symb_s*argv);
|
||||
extern void compile_cmp_gt(char*label, long width,
|
||||
unsigned argc, struct symb_s*argv);
|
||||
|
||||
|
||||
extern void compile_vpi_symbol(const char*label, vpiHandle obj);
|
||||
|
|
@ -191,6 +196,9 @@ extern void compile_net(char*label, char*name,
|
|||
|
||||
/*
|
||||
* $Log: compile.h,v $
|
||||
* Revision 1.27 2001/06/15 04:07:58 steve
|
||||
* Add .cmp statements for structural comparison.
|
||||
*
|
||||
* Revision 1.26 2001/06/15 03:28:31 steve
|
||||
* Change the VPI call process so that loaded .vpi modules
|
||||
* use a function table instead of implicit binding.
|
||||
|
|
|
|||
|
|
@ -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.20 2001/06/07 03:09:03 steve Exp $"
|
||||
#ident "$Id: lexor.lex,v 1.21 2001/06/15 04:07:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "parse_misc.h"
|
||||
|
|
@ -67,6 +67,8 @@
|
|||
/* These are some keywords that are recognized. */
|
||||
".arith/sub" { return K_ARITH_SUB; }
|
||||
".arith/sum" { return K_ARITH_SUM; }
|
||||
".cmp/ge" { return K_CMP_GE; }
|
||||
".cmp/gt" { return K_CMP_GT; }
|
||||
".event" { return K_EVENT; }
|
||||
".event/or" { return K_EVENT_OR; }
|
||||
".functor" { return K_FUNCTOR; }
|
||||
|
|
@ -142,6 +144,9 @@ int yywrap()
|
|||
|
||||
/*
|
||||
* $Log: lexor.lex,v $
|
||||
* Revision 1.21 2001/06/15 04:07:58 steve
|
||||
* Add .cmp statements for structural comparison.
|
||||
*
|
||||
* Revision 1.20 2001/06/07 03:09:03 steve
|
||||
* Implement .arith/sub subtraction.
|
||||
*
|
||||
|
|
|
|||
18
vvp/parse.y
18
vvp/parse.y
|
|
@ -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.30 2001/06/15 03:28:31 steve Exp $"
|
||||
#ident "$Id: parse.y,v 1.31 2001/06/15 04:07:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "parse_misc.h"
|
||||
|
|
@ -54,7 +54,8 @@ extern FILE*yyin;
|
|||
};
|
||||
|
||||
|
||||
%token K_ARITH_SUB K_ARITH_SUM K_EVENT K_EVENT_OR K_FUNCTOR K_NET K_NET_S
|
||||
%token K_ARITH_SUB K_ARITH_SUM K_CMP_GE K_CMP_GT
|
||||
%token K_EVENT K_EVENT_OR K_FUNCTOR K_NET K_NET_S
|
||||
%token K_RESOLV K_SCOPE K_THREAD
|
||||
%token K_UDP K_UDP_C K_UDP_S
|
||||
%token K_MEM K_MEM_P K_MEM_I
|
||||
|
|
@ -166,6 +167,16 @@ statement
|
|||
compile_arith_sum($1, $3, obj.cnt, obj.vect);
|
||||
}
|
||||
|
||||
| T_LABEL K_CMP_GE T_NUMBER ',' symbols ';'
|
||||
{ struct symbv_s obj = $5;
|
||||
compile_cmp_ge($1, $3, 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);
|
||||
}
|
||||
|
||||
|
||||
/* Event statements take a label, a type (the first T_SYMBOL) and a
|
||||
list of inputs. If the type is instead a string, then we have a
|
||||
|
|
@ -458,6 +469,9 @@ int compile_design(const char*path)
|
|||
|
||||
/*
|
||||
* $Log: parse.y,v $
|
||||
* Revision 1.31 2001/06/15 04:07:58 steve
|
||||
* Add .cmp statements for structural comparison.
|
||||
*
|
||||
* Revision 1.30 2001/06/15 03:28:31 steve
|
||||
* Change the VPI call process so that loaded .vpi modules
|
||||
* use a function table instead of implicit binding.
|
||||
|
|
|
|||
Loading…
Reference in New Issue