Reimplement comparators as vvp_vector4_t nodes.

This commit is contained in:
steve 2005-01-16 04:19:08 +00:00
parent ead2481793
commit 1c3668ea7f
6 changed files with 142 additions and 117 deletions

View File

@ -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:

View File

@ -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

View File

@ -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

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.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.
*

View File

@ -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.
*

View File

@ -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.
*