Add vector4 implementation of .arith/mult.
This commit is contained in:
parent
dfb7c7ba6f
commit
a121e703f3
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* $Id: README.txt,v 1.54 2005/01/22 01:06:20 steve Exp $
|
||||
* $Id: README.txt,v 1.55 2005/01/28 05:34:25 steve Exp $
|
||||
*/
|
||||
|
||||
VVP SIMULATION ENGINE
|
||||
|
|
@ -541,7 +541,11 @@ input vectors will be padded if needed to get the desired output width.
|
|||
<label> .arith/div <wid>, <A>, <B>;
|
||||
<label> .arith/mod <wid>, <A>, <B>;
|
||||
|
||||
In all cases, there are no width limits, so long as the width is fixed.
|
||||
In all cases, there are no width limits, so long as the width is
|
||||
fixed.
|
||||
|
||||
NOTE: The .arith/mult inputs are not necessarily the width of the
|
||||
output. I have not decided how to handle this.
|
||||
|
||||
STRUCTURAL COMPARE STATEMENTS:
|
||||
|
||||
|
|
|
|||
66
vvp/arith.cc
66
vvp/arith.cc
|
|
@ -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.35 2005/01/22 17:36:15 steve Exp $"
|
||||
#ident "$Id: arith.cc,v 1.36 2005/01/28 05:34:25 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "arith.h"
|
||||
|
|
@ -171,9 +171,51 @@ void vvp_arith_mod::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
|
|||
|
||||
// Multiplication
|
||||
|
||||
vvp_arith_mult::vvp_arith_mult(unsigned wid)
|
||||
: vvp_arith_(wid)
|
||||
{
|
||||
}
|
||||
|
||||
vvp_arith_mult::~vvp_arith_mult()
|
||||
{
|
||||
}
|
||||
|
||||
void vvp_arith_mult::recv_vec4(vvp_net_ptr_t ptr, vvp_vector4_t bit)
|
||||
{
|
||||
dispatch_operand_(ptr, bit);
|
||||
|
||||
unsigned long a;
|
||||
if (! vector4_to_value(op_a_, a)) {
|
||||
vvp_send_vec4(ptr.ptr()->out, x_val_);
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned long b;
|
||||
if (! vector4_to_value(op_b_, b)) {
|
||||
vvp_send_vec4(ptr.ptr()->out, x_val_);
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned long val = a * b;
|
||||
assert(wid_ <= 8*sizeof(val));
|
||||
|
||||
vvp_vector4_t vval (wid_);
|
||||
for (int idx = 0 ; idx < wid_ ; idx += 1) {
|
||||
if (val & 1)
|
||||
vval.set_bit(idx, BIT4_1);
|
||||
else
|
||||
vval.set_bit(idx, BIT4_0);
|
||||
|
||||
val >>= 1;
|
||||
}
|
||||
|
||||
vvp_send_vec4(ptr.ptr()->out, vval);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
void vvp_arith_mult::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
|
||||
{
|
||||
#if 0
|
||||
put(i, val);
|
||||
vvp_ipoint_t base = ipoint_make(i,0);
|
||||
|
||||
|
|
@ -201,10 +243,8 @@ void vvp_arith_mult::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
|
|||
}
|
||||
|
||||
output_val_(base, push, a*b);
|
||||
#else
|
||||
fprintf(stderr, "XXXX forgot how to implement vvp_arith_mult::set\n");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
void vvp_arith_mult::wide(vvp_ipoint_t base, bool push)
|
||||
|
|
@ -284,18 +324,7 @@ vvp_arith_sum::~vvp_arith_sum()
|
|||
|
||||
void vvp_arith_sum::recv_vec4(vvp_net_ptr_t ptr, vvp_vector4_t bit)
|
||||
{
|
||||
unsigned port = ptr.port();
|
||||
|
||||
switch (port) {
|
||||
case 0:
|
||||
op_a_ = bit;
|
||||
break;
|
||||
case 1:
|
||||
op_b_ = bit;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
dispatch_operand_(ptr, bit);
|
||||
|
||||
vvp_net_t*net = ptr.ptr();
|
||||
|
||||
|
|
@ -623,6 +652,9 @@ void vvp_shiftr::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
|
|||
|
||||
/*
|
||||
* $Log: arith.cc,v $
|
||||
* Revision 1.36 2005/01/28 05:34:25 steve
|
||||
* Add vector4 implementation of .arith/mult.
|
||||
*
|
||||
* Revision 1.35 2005/01/22 17:36:15 steve
|
||||
* .cmp/x supports signed magnitude compare.
|
||||
*
|
||||
|
|
|
|||
76
vvp/arith.h
76
vvp/arith.h
|
|
@ -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.23 2005/01/22 16:21:11 steve Exp $"
|
||||
#ident "$Id: arith.h,v 1.24 2005/01/28 05:34:25 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "functor.h"
|
||||
|
|
@ -53,20 +53,6 @@ class vvp_arith_ : public vvp_net_fun_t {
|
|||
vvp_vector4_t x_val_;
|
||||
};
|
||||
|
||||
/*
|
||||
* This class is functor for arithmetic sum. Inputs that come
|
||||
* in cause the 4-input summation to be calculated, and output
|
||||
* functors that are affected cause propagations.
|
||||
*/
|
||||
class vvp_arith_mult : public vvp_arith_ {
|
||||
|
||||
public:
|
||||
explicit vvp_arith_mult(unsigned wid) : vvp_arith_(wid) {}
|
||||
|
||||
void set(vvp_ipoint_t i, bool push, unsigned val, unsigned str);
|
||||
void wide(vvp_ipoint_t base, bool push);
|
||||
};
|
||||
|
||||
class vvp_arith_div : public vvp_arith_ {
|
||||
|
||||
public:
|
||||
|
|
@ -89,27 +75,11 @@ class vvp_arith_mod : public vvp_arith_ {
|
|||
void wide(vvp_ipoint_t base, bool push);
|
||||
};
|
||||
|
||||
class vvp_arith_sum : public vvp_arith_ {
|
||||
|
||||
public:
|
||||
explicit vvp_arith_sum(unsigned wid);
|
||||
~vvp_arith_sum();
|
||||
|
||||
public:
|
||||
virtual void recv_vec4(vvp_net_ptr_t port, vvp_vector4_t bit);
|
||||
|
||||
};
|
||||
|
||||
class vvp_arith_sub : public vvp_arith_ {
|
||||
|
||||
public:
|
||||
explicit vvp_arith_sub(unsigned wid);
|
||||
~vvp_arith_sub();
|
||||
|
||||
public:
|
||||
virtual void recv_vec4(vvp_net_ptr_t port, vvp_vector4_t bit);
|
||||
|
||||
};
|
||||
/* vvp_cmp_* objects...
|
||||
* the vvp_cmp_* objects all are special vvp_arith_ objects in that
|
||||
* their widths are only for their inputs. The output widths are all
|
||||
* exactly 1 bit.
|
||||
*/
|
||||
|
||||
class vvp_cmp_eeq : public vvp_arith_ {
|
||||
|
||||
|
|
@ -170,6 +140,37 @@ class vvp_cmp_gt : public vvp_cmp_gtge_base_ {
|
|||
void recv_vec4(vvp_net_ptr_t ptr, vvp_vector4_t bit);
|
||||
};
|
||||
|
||||
/*
|
||||
* NOTE: The inputs to the vvp_arith_mult are not necessarily the same
|
||||
* width as the output. This is different from the typical vvp_arith_
|
||||
* object. Perhaps that means this isn't quite a vvp_arith_ object?
|
||||
*/
|
||||
class vvp_arith_mult : public vvp_arith_ {
|
||||
|
||||
public:
|
||||
explicit vvp_arith_mult(unsigned wid);
|
||||
~vvp_arith_mult();
|
||||
void recv_vec4(vvp_net_ptr_t ptr, vvp_vector4_t bit);
|
||||
};
|
||||
|
||||
class vvp_arith_sub : public vvp_arith_ {
|
||||
|
||||
public:
|
||||
explicit vvp_arith_sub(unsigned wid);
|
||||
~vvp_arith_sub();
|
||||
virtual void recv_vec4(vvp_net_ptr_t port, vvp_vector4_t bit);
|
||||
|
||||
};
|
||||
|
||||
class vvp_arith_sum : public vvp_arith_ {
|
||||
|
||||
public:
|
||||
explicit vvp_arith_sum(unsigned wid);
|
||||
~vvp_arith_sum();
|
||||
virtual void recv_vec4(vvp_net_ptr_t port, vvp_vector4_t bit);
|
||||
|
||||
};
|
||||
|
||||
class vvp_shiftl : public vvp_arith_ {
|
||||
|
||||
public:
|
||||
|
|
@ -188,6 +189,9 @@ class vvp_shiftr : public vvp_arith_ {
|
|||
|
||||
/*
|
||||
* $Log: arith.h,v $
|
||||
* Revision 1.24 2005/01/28 05:34:25 steve
|
||||
* Add vector4 implementation of .arith/mult.
|
||||
*
|
||||
* Revision 1.23 2005/01/22 16:21:11 steve
|
||||
* Implement vectored CMP_EQ and NE
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.182 2005/01/22 16:21:11 steve Exp $"
|
||||
#ident "$Id: compile.cc,v 1.183 2005/01/28 05:34:25 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "arith.h"
|
||||
|
|
@ -832,7 +832,7 @@ void compile_arith_div(char*label, long wid, bool signed_flag,
|
|||
assert( wid > 0 );
|
||||
|
||||
if ((long)argc != 2*wid) {
|
||||
fprintf(stderr, "%s; .arith has wrong number of symbols\n", label);
|
||||
fprintf(stderr, "%s; .arith/div has wrong number of symbols\n", label);
|
||||
compile_errors += 1;
|
||||
return;
|
||||
}
|
||||
|
|
@ -848,7 +848,7 @@ void compile_arith_mod(char*label, long wid,
|
|||
assert( wid > 0 );
|
||||
|
||||
if ((long)argc != 2*wid) {
|
||||
fprintf(stderr, "%s; .arith has wrong number of symbols\n", label);
|
||||
fprintf(stderr, "%s; .arith/mod has wrong number of symbols\n", label);
|
||||
compile_errors += 1;
|
||||
return;
|
||||
}
|
||||
|
|
@ -863,14 +863,13 @@ void compile_arith_mult(char*label, long wid,
|
|||
{
|
||||
assert( wid > 0 );
|
||||
|
||||
if ((long)argc != 2*wid) {
|
||||
fprintf(stderr, "%s; .arith has wrong number of symbols\n", label);
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "%s .arith/mult has wrong number of symbols\n", label);
|
||||
compile_errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
vvp_arith_ *arith = new vvp_arith_mult(wid);
|
||||
|
||||
make_arith(arith, label, wid, argc, argv);
|
||||
}
|
||||
|
||||
|
|
@ -1578,6 +1577,9 @@ void compile_param_string(char*label, char*name, char*str, char*value)
|
|||
|
||||
/*
|
||||
* $Log: compile.cc,v $
|
||||
* Revision 1.183 2005/01/28 05:34:25 steve
|
||||
* Add vector4 implementation of .arith/mult.
|
||||
*
|
||||
* Revision 1.182 2005/01/22 16:21:11 steve
|
||||
* Implement vectored CMP_EQ and NE
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: vthread.cc,v 1.126 2005/01/22 00:58:22 steve Exp $"
|
||||
#ident "$Id: vthread.cc,v 1.127 2005/01/28 05:34:25 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -1541,21 +1541,31 @@ bool of_IX_LOAD(vthread_t thr, vvp_code_t cp)
|
|||
*/
|
||||
bool of_IX_GET(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
unsigned index = cp->bit_idx[0];
|
||||
unsigned base = cp->bit_idx[1];
|
||||
unsigned width = cp->number;
|
||||
|
||||
unsigned long v = 0;
|
||||
bool unknown_flag = false;
|
||||
|
||||
for (unsigned i = 0; i<cp->number; i++) {
|
||||
unsigned char vv = thr_get_bit(thr, cp->bit_idx[1] + i);
|
||||
for (unsigned i = 0 ; i<width ; i += 1) {
|
||||
unsigned char vv = thr_get_bit(thr, base);
|
||||
if (vv&2) {
|
||||
v = 0UL;
|
||||
unknown_flag = true;
|
||||
break;
|
||||
}
|
||||
|
||||
v |= vv << i;
|
||||
|
||||
if (base >= 4)
|
||||
base += 1;
|
||||
}
|
||||
thr->words[cp->bit_idx[0]].w_int = v;
|
||||
thr->words[index].w_int = v;
|
||||
|
||||
/* Set bit 4 as a flag if the input is unknown. */
|
||||
thr_put_bit(thr, 4, unknown_flag? 1 : 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -2734,7 +2744,12 @@ bool of_SHIFTL_I0(vthread_t thr, vvp_code_t cp)
|
|||
}
|
||||
|
||||
/*
|
||||
* This is an unsigned right shift.
|
||||
* This is an unsigned right shift:
|
||||
*
|
||||
* %shiftr/i0 <bit>, <wid>
|
||||
*
|
||||
* The vector at address <bit> with width <wid> is shifted right a
|
||||
* number of bits stored in index/word register 0.
|
||||
*/
|
||||
bool of_SHIFTR_I0(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
|
|
@ -3052,6 +3067,9 @@ bool of_JOIN_UFUNC(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
/*
|
||||
* $Log: vthread.cc,v $
|
||||
* Revision 1.127 2005/01/28 05:34:25 steve
|
||||
* Add vector4 implementation of .arith/mult.
|
||||
*
|
||||
* Revision 1.126 2005/01/22 00:58:22 steve
|
||||
* Implement the %load/x instruction.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.8 2005/01/22 17:36:15 steve Exp $"
|
||||
#ident "$Id: vvp_net.cc,v 1.9 2005/01/28 05:34:25 steve Exp $"
|
||||
|
||||
# include "vvp_net.h"
|
||||
# include <stdio.h>
|
||||
|
|
@ -224,6 +224,29 @@ void vvp_vector4_t::set_bit(unsigned idx, vvp_bit4_t val)
|
|||
}
|
||||
}
|
||||
|
||||
bool vector4_to_value(const vvp_vector4_t&vec, unsigned long&val)
|
||||
{
|
||||
unsigned long res = 0;
|
||||
unsigned long msk = 1;
|
||||
|
||||
for (unsigned idx = 0 ; idx < vec.size() ; idx += 1) {
|
||||
switch (vec.value(idx)) {
|
||||
case BIT4_0:
|
||||
break;
|
||||
case BIT4_1:
|
||||
res |= msk;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
msk <<= 1UL;
|
||||
}
|
||||
|
||||
val = res;
|
||||
return true;
|
||||
}
|
||||
|
||||
vvp_vector8_t::vvp_vector8_t(const vvp_vector8_t&that)
|
||||
{
|
||||
size_ = that.size_;
|
||||
|
|
@ -786,6 +809,9 @@ vvp_bit4_t compare_gtge_signed(const vvp_vector4_t&a,
|
|||
|
||||
/*
|
||||
* $Log: vvp_net.cc,v $
|
||||
* Revision 1.9 2005/01/28 05:34:25 steve
|
||||
* Add vector4 implementation of .arith/mult.
|
||||
*
|
||||
* Revision 1.8 2005/01/22 17:36:15 steve
|
||||
* .cmp/x supports signed magnitude compare.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.8 2005/01/22 17:36:15 steve Exp $"
|
||||
#ident "$Id: vvp_net.h,v 1.9 2005/01/28 05:34:25 steve Exp $"
|
||||
|
||||
# include <assert.h>
|
||||
|
||||
|
|
@ -91,6 +91,14 @@ extern vvp_bit4_t compare_gtge_signed(const vvp_vector4_t&a,
|
|||
const vvp_vector4_t&b,
|
||||
vvp_bit4_t val_if_equal);
|
||||
|
||||
/*
|
||||
* These functions extract the value of the vector as a native type,
|
||||
* if possible, and return true to indicate success. If the vector has
|
||||
* any X or Z bits, the resulting value will be unchanged and the
|
||||
* return value becomes false to indicate an error.
|
||||
*/
|
||||
extern bool vector4_to_value(const vvp_vector4_t&a, unsigned long&val);
|
||||
|
||||
/*
|
||||
* This class represents a scaler value with strength. These are
|
||||
* heavier then the simple vvp_bit4_t, but more information is
|
||||
|
|
@ -494,6 +502,9 @@ class vvp_fun_signal : public vvp_net_fun_t {
|
|||
|
||||
/*
|
||||
* $Log: vvp_net.h,v $
|
||||
* Revision 1.9 2005/01/28 05:34:25 steve
|
||||
* Add vector4 implementation of .arith/mult.
|
||||
*
|
||||
* Revision 1.8 2005/01/22 17:36:15 steve
|
||||
* .cmp/x supports signed magnitude compare.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue