Reimplement comparators as vvp_vector4_t nodes.
This commit is contained in:
parent
ead2481793
commit
1c3668ea7f
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* $Id: README.txt,v 1.52 2005/01/09 20:11:15 steve Exp $
|
||||
* $Id: README.txt,v 1.53 2005/01/16 04:19:08 steve Exp $
|
||||
*/
|
||||
|
||||
VVP SIMULATION ENGINE
|
||||
|
|
@ -550,19 +550,17 @@ 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/eq <wid>, <symbols_list>;
|
||||
<label> .cmp/ne <wid>, <symbols_list>;
|
||||
<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>;
|
||||
<label> .cmp/eq <wid>, <A>, <B>;
|
||||
<label> .cmp/ne <wid>, <A>, <B>;
|
||||
<label> .cmp/ge <wid>, <A>, <B>;
|
||||
<label> .cmp/gt <wid>, <A>, <B>;
|
||||
<label> .cmp/ge.s <wid>, <A>, <B>;
|
||||
<label> .cmp/gt.s <wid>, <A>, <B>;
|
||||
|
||||
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 1f the comparison is true, 0 if false, and x
|
||||
otherwise. The plain versions do unsigned comparison, but the ".s"
|
||||
versions to signed comparisons. (Eqlality doesn't need to care about
|
||||
sign.)
|
||||
Whereas the arithmetic statements generate an outpout the width if
|
||||
<wid>, the comparisons produce a single bit vector result. The plain
|
||||
versions do unsigned comparison, but the ".s" versions to signed
|
||||
comparisons. (Eqlality doesn't need to care about sign.)
|
||||
|
||||
|
||||
STRUCTURAL SHIFTER STATEMENTS:
|
||||
|
|
|
|||
123
vvp/arith.cc
123
vvp/arith.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2005 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -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.31 2004/12/11 02:31:29 steve Exp $"
|
||||
#ident "$Id: arith.cc,v 1.32 2005/01/16 04:19:08 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "arith.h"
|
||||
|
|
@ -438,91 +438,35 @@ vvp_cmp_gtge_base_::vvp_cmp_gtge_base_(unsigned wid, bool flag)
|
|||
{
|
||||
}
|
||||
|
||||
#if 0
|
||||
void vvp_cmp_gtge_base_::set_base(vvp_ipoint_t i,
|
||||
bool push,
|
||||
unsigned val,
|
||||
unsigned,
|
||||
unsigned out_if_equal)
|
||||
|
||||
void vvp_cmp_gtge_base_::recv_vec4_base_(vvp_net_ptr_t ptr,
|
||||
vvp_vector4_t bit,
|
||||
vvp_bit4_t out_if_equal)
|
||||
{
|
||||
put(i, val);
|
||||
vvp_ipoint_t base = ipoint_make(i,0);
|
||||
// XXXX For now, do not support signed compare.
|
||||
assert(! signed_flag_);
|
||||
|
||||
unsigned out_val = out_if_equal;
|
||||
|
||||
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;
|
||||
}
|
||||
switch (ptr.port()) {
|
||||
case 0:
|
||||
op_a_ = bit;
|
||||
break;
|
||||
case 1:
|
||||
op_b_ = bit;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
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;
|
||||
goto check_for_x_complete;
|
||||
}
|
||||
|
||||
unsigned a = (val & 0x01)? 1 : 0;
|
||||
unsigned b = (val & 0x04)? 1 : 0;
|
||||
|
||||
if (a > b) {
|
||||
out_val = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (a < b) {
|
||||
out_val = 0;
|
||||
break;
|
||||
}
|
||||
vvp_bit4_t out = compare_gtge(op_a_, op_b_, out_if_equal);
|
||||
if (out == BIT4_X) {
|
||||
vvp_send_vec4(ptr.ptr()->out, x_val_);
|
||||
} else {
|
||||
vvp_vector4_t val (1);
|
||||
val.set_bit(0, out);
|
||||
vvp_send_vec4(ptr.ptr()->out, val);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
vvp_cmp_ge::vvp_cmp_ge(unsigned wid, bool flag)
|
||||
|
|
@ -530,25 +474,21 @@ vvp_cmp_ge::vvp_cmp_ge(unsigned wid, bool flag)
|
|||
{
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
void vvp_cmp_ge::set(vvp_ipoint_t i, bool push, unsigned val, unsigned str)
|
||||
void vvp_cmp_ge::recv_vec4(vvp_net_ptr_t ptr, vvp_vector4_t bit)
|
||||
{
|
||||
set_base(i, push, val, str, 1);
|
||||
recv_vec4_base_(ptr, bit, BIT4_1);
|
||||
}
|
||||
#endif
|
||||
|
||||
vvp_cmp_gt::vvp_cmp_gt(unsigned wid, bool flag)
|
||||
: vvp_cmp_gtge_base_(wid, flag)
|
||||
{
|
||||
}
|
||||
|
||||
#if 0
|
||||
void vvp_cmp_gt::set(vvp_ipoint_t i, bool push, unsigned val, unsigned str)
|
||||
void vvp_cmp_gt::recv_vec4(vvp_net_ptr_t ptr, vvp_vector4_t bit)
|
||||
{
|
||||
set_base(i, push, val, str, 0);
|
||||
recv_vec4_base_(ptr, bit, BIT4_0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
void vvp_shiftl::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
|
||||
|
|
@ -654,6 +594,9 @@ void vvp_shiftr::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
|
|||
|
||||
/*
|
||||
* $Log: arith.cc,v $
|
||||
* Revision 1.32 2005/01/16 04:19:08 steve
|
||||
* Reimplement comparators as vvp_vector4_t nodes.
|
||||
*
|
||||
* Revision 1.31 2004/12/11 02:31:29 steve
|
||||
* Rework of internals to carry vectors through nexus instead
|
||||
* of single bits. Make the ivl, tgt-vvp and vvp initial changes
|
||||
|
|
|
|||
29
vvp/arith.h
29
vvp/arith.h
|
|
@ -19,14 +19,18 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: arith.h,v 1.20 2004/12/11 02:31:29 steve Exp $"
|
||||
#ident "$Id: arith.h,v 1.21 2005/01/16 04:19:08 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "functor.h"
|
||||
# include "vvp_net.h"
|
||||
|
||||
// base class for arithmetic functors
|
||||
|
||||
/*
|
||||
* Base class for arithmetic functors.
|
||||
* The wid constructor is used to size the output. This includes
|
||||
* precalculating an X value. Most arithmetic nodes can handle
|
||||
* whatever width comes in, given the knowledge of the output width.
|
||||
*/
|
||||
class vvp_arith_ : public vvp_net_fun_t {
|
||||
|
||||
public:
|
||||
|
|
@ -115,14 +119,19 @@ class vvp_cmp_ne : public vvp_arith_ {
|
|||
|
||||
};
|
||||
|
||||
/*
|
||||
* This base class implements both GT and GE comparisons. The derived
|
||||
* GT and GE call the recv_vec4_base_ method with a different
|
||||
* out_if_equal argument that reflects the different expectations.
|
||||
*/
|
||||
class vvp_cmp_gtge_base_ : public vvp_arith_ {
|
||||
|
||||
public:
|
||||
explicit vvp_cmp_gtge_base_(unsigned wid, bool signed_flag);
|
||||
|
||||
protected:
|
||||
void set_base(vvp_ipoint_t i, bool push, unsigned val, unsigned str,
|
||||
unsigned out_if_equal);
|
||||
void recv_vec4_base_(vvp_net_ptr_t ptr, vvp_vector4_t bit,
|
||||
vvp_bit4_t out_if_equal);
|
||||
private:
|
||||
bool signed_flag_;
|
||||
};
|
||||
|
|
@ -131,18 +140,17 @@ class vvp_cmp_ge : public vvp_cmp_gtge_base_ {
|
|||
|
||||
public:
|
||||
explicit vvp_cmp_ge(unsigned wid, bool signed_flag);
|
||||
void set(vvp_ipoint_t i, bool push, unsigned val, unsigned str);
|
||||
|
||||
private:
|
||||
void recv_vec4(vvp_net_ptr_t ptr, vvp_vector4_t bit);
|
||||
|
||||
};
|
||||
|
||||
class vvp_cmp_gt : public vvp_cmp_gtge_base_ {
|
||||
|
||||
public:
|
||||
explicit vvp_cmp_gt(unsigned wid, bool signed_flag);
|
||||
void set(vvp_ipoint_t i, bool push, unsigned val, unsigned str);
|
||||
|
||||
private:
|
||||
void recv_vec4(vvp_net_ptr_t ptr, vvp_vector4_t bit);
|
||||
};
|
||||
|
||||
class vvp_shiftl : public vvp_arith_ {
|
||||
|
|
@ -163,6 +171,9 @@ class vvp_shiftr : public vvp_arith_ {
|
|||
|
||||
/*
|
||||
* $Log: arith.h,v $
|
||||
* Revision 1.21 2005/01/16 04:19:08 steve
|
||||
* Reimplement comparators as vvp_vector4_t nodes.
|
||||
*
|
||||
* Revision 1.20 2004/12/11 02:31:29 steve
|
||||
* Rework of internals to carry vectors through nexus instead
|
||||
* of single bits. Make the ivl, tgt-vvp and vvp initial changes
|
||||
|
|
|
|||
|
|
@ -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.179 2004/12/31 05:54:46 steve Exp $"
|
||||
#ident "$Id: compile.cc,v 1.180 2005/01/16 04:19:08 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "arith.h"
|
||||
|
|
@ -945,8 +945,8 @@ void compile_cmp_ge(char*label, long wid, bool signed_flag,
|
|||
{
|
||||
assert( wid > 0 );
|
||||
|
||||
if ((long)argc != 2*wid) {
|
||||
fprintf(stderr, "%s; .cmp has wrong number of symbols\n", label);
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "%s .cmp/ge has wrong number of symbols\n", label);
|
||||
compile_errors += 1;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1564,6 +1564,9 @@ void compile_param_string(char*label, char*name, char*str, char*value)
|
|||
|
||||
/*
|
||||
* $Log: compile.cc,v $
|
||||
* Revision 1.180 2005/01/16 04:19:08 steve
|
||||
* Reimplement comparators as vvp_vector4_t nodes.
|
||||
*
|
||||
* Revision 1.179 2004/12/31 05:54:46 steve
|
||||
* Fix uninitialized fun pointer for resolver nodes.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.5 2005/01/09 20:11:16 steve Exp $"
|
||||
#ident "$Id: vvp_net.cc,v 1.6 2005/01/16 04:19:08 steve Exp $"
|
||||
|
||||
# include "vvp_net.h"
|
||||
# include <stdio.h>
|
||||
|
|
@ -663,8 +663,71 @@ vvp_vector4_t reduce4(const vvp_vector8_t&that)
|
|||
return out;
|
||||
}
|
||||
|
||||
vvp_bit4_t compare_gtge(const vvp_vector4_t&lef, const vvp_vector4_t&rig,
|
||||
vvp_bit4_t out_if_equal)
|
||||
{
|
||||
unsigned min_size = lef.size();
|
||||
if (rig.size() < min_size)
|
||||
min_size = rig.size();
|
||||
|
||||
// If one of the inputs is nil, treat is as all X values, and
|
||||
// that makes the result BIT4_X.
|
||||
if (min_size == 0)
|
||||
return BIT4_X;
|
||||
|
||||
// As per the IEEE1364 definition of >, >=, < and <=, if there
|
||||
// are any X or Z values in either of the operand vectors,
|
||||
// then the result of the compare is BIT4_X.
|
||||
|
||||
// Check for X/Z in the left operand
|
||||
for (unsigned idx = 0 ; idx < lef.size() ; idx += 1) {
|
||||
vvp_bit4_t bit = lef.value(idx);
|
||||
if (bit == BIT4_X)
|
||||
return BIT4_X;
|
||||
if (bit == BIT4_Z)
|
||||
return BIT4_X;
|
||||
}
|
||||
|
||||
// Check for X/Z in the right operand
|
||||
for (unsigned idx = 0 ; idx < rig.size() ; idx += 1) {
|
||||
vvp_bit4_t bit = rig.value(idx);
|
||||
if (bit == BIT4_X)
|
||||
return BIT4_X;
|
||||
if (bit == BIT4_Z)
|
||||
return BIT4_Z;
|
||||
}
|
||||
|
||||
for (unsigned idx = lef.size() ; idx > rig.size() ; idx -= 1) {
|
||||
if (lef.value(idx-1) == BIT4_1)
|
||||
return BIT4_1;
|
||||
}
|
||||
|
||||
for (unsigned idx = rig.size() ; idx > lef.size() ; idx -= 1) {
|
||||
if (rig.value(idx-1) == BIT4_1)
|
||||
return BIT4_0;
|
||||
}
|
||||
|
||||
for (unsigned idx = min_size ; idx > 0 ; idx -= 1) {
|
||||
vvp_bit4_t lv = lef.value(idx-1);
|
||||
vvp_bit4_t rv = rig.value(idx-1);
|
||||
|
||||
if (lv == rv)
|
||||
continue;
|
||||
|
||||
if (lv == BIT4_1)
|
||||
return BIT4_1;
|
||||
else
|
||||
return BIT4_0;
|
||||
}
|
||||
|
||||
return out_if_equal;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: vvp_net.cc,v $
|
||||
* Revision 1.6 2005/01/16 04:19:08 steve
|
||||
* Reimplement comparators as vvp_vector4_t nodes.
|
||||
*
|
||||
* Revision 1.5 2005/01/09 20:11:16 steve
|
||||
* Add the .part/pv node and related functionality.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.6 2005/01/09 20:11:16 steve Exp $"
|
||||
#ident "$Id: vvp_net.h,v 1.7 2005/01/16 04:19:08 steve Exp $"
|
||||
|
||||
# include <assert.h>
|
||||
|
||||
|
|
@ -82,6 +82,10 @@ class vvp_vector4_t {
|
|||
};
|
||||
};
|
||||
|
||||
vvp_bit4_t compare_gtge(const vvp_vector4_t&a,
|
||||
const vvp_vector4_t&b,
|
||||
vvp_bit4_t val_if_equal);
|
||||
|
||||
/*
|
||||
* This class represents a scaler value with strength. These are
|
||||
* heavier then the simple vvp_bit4_t, but more information is
|
||||
|
|
@ -485,6 +489,9 @@ class vvp_fun_signal : public vvp_net_fun_t {
|
|||
|
||||
/*
|
||||
* $Log: vvp_net.h,v $
|
||||
* Revision 1.7 2005/01/16 04:19:08 steve
|
||||
* Reimplement comparators as vvp_vector4_t nodes.
|
||||
*
|
||||
* Revision 1.6 2005/01/09 20:11:16 steve
|
||||
* Add the .part/pv node and related functionality.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue