Implement .arith/mod.
This commit is contained in:
parent
313502f360
commit
bae8507c90
143
vvp/arith.cc
143
vvp/arith.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: arith.cc,v 1.41 2005/03/09 05:52:04 steve Exp $"
|
#ident "$Id: arith.cc,v 1.42 2005/03/12 06:42:28 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "arith.h"
|
# include "arith.h"
|
||||||
|
|
@ -128,109 +128,87 @@ void vvp_arith_div::recv_vec4(vvp_net_ptr_t ptr, vvp_vector4_t bit)
|
||||||
vvp_send_vec4(ptr.ptr()->out, vval);
|
vvp_send_vec4(ptr.ptr()->out, vval);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
void vvp_arith_div::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
|
vvp_arith_mod::vvp_arith_mod(unsigned wid, bool sf)
|
||||||
|
: vvp_arith_(wid), signed_flag_(sf)
|
||||||
{
|
{
|
||||||
put(i, val);
|
|
||||||
vvp_ipoint_t base = ipoint_make(i,0);
|
|
||||||
|
|
||||||
if(wid_ > 8*sizeof(unsigned long)) {
|
|
||||||
wide(base, push);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long a = 0, b = 0;
|
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
|
|
||||||
vvp_ipoint_t ptr = ipoint_index(base,idx);
|
|
||||||
functor_t obj = functor_index(ptr);
|
|
||||||
|
|
||||||
unsigned val = obj->ival;
|
|
||||||
if (val & 0xaa) {
|
|
||||||
output_x_(base, push);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (val & 0x01)
|
|
||||||
a += 1UL << idx;
|
|
||||||
if (val & 0x04)
|
|
||||||
b += 1UL << idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned sign_flip = 0;
|
|
||||||
if (signed_flag_) {
|
|
||||||
if (a & (1UL << (wid_ - 1))) {
|
|
||||||
a ^= ~(-1UL << wid_);
|
|
||||||
a += 1;
|
|
||||||
sign_flip += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b & (1UL << (wid_ - 1))) {
|
|
||||||
b ^= ~(-1UL << wid_);
|
|
||||||
b += 1;
|
|
||||||
sign_flip += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b == 0) {
|
|
||||||
output_x_(base, push);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long result = a / b;
|
|
||||||
if (sign_flip % 2 == 1)
|
|
||||||
result = 0 - result;
|
|
||||||
|
|
||||||
output_val_(base, push, result);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
inline void vvp_arith_mod::wide(vvp_ipoint_t base, bool push)
|
vvp_arith_mod::~vvp_arith_mod()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void vvp_arith_mod::wide_(vvp_net_ptr_t ptr)
|
||||||
{
|
{
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vvp_arith_mod::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
|
void vvp_arith_mod::recv_vec4(vvp_net_ptr_t ptr, vvp_vector4_t bit)
|
||||||
{
|
{
|
||||||
#if 0
|
dispatch_operand_(ptr, bit);
|
||||||
put(i, val);
|
|
||||||
vvp_ipoint_t base = ipoint_make(i,0);
|
|
||||||
|
|
||||||
if(wid_ > 8*sizeof(unsigned long)) {
|
if (wid_ > 8 * sizeof(unsigned long)) {
|
||||||
wide(base, push);
|
wide_(ptr);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long a;
|
||||||
|
if (! vector4_to_value(op_a_, a)) {
|
||||||
|
vvp_send_vec4(ptr.ptr()->out, x_val_);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long a = 0, b = 0;
|
unsigned long b;
|
||||||
|
if (! vector4_to_value(op_b_, b)) {
|
||||||
|
vvp_send_vec4(ptr.ptr()->out, x_val_);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
|
bool negate = false;
|
||||||
vvp_ipoint_t ptr = ipoint_index(base,idx);
|
/* If we are doing signed divide, then take the sign out of
|
||||||
functor_t obj = functor_index(ptr);
|
the operands for now, and remember to put the sign back
|
||||||
|
later. */
|
||||||
unsigned val = obj->ival;
|
if (signed_flag_) {
|
||||||
if (val & 0xaa) {
|
if (op_a_.value(op_a_.size()-1)) {
|
||||||
output_x_(base, push);
|
a = (-a) & ~ (-1UL << op_a_.size());
|
||||||
return;
|
negate = !negate;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (val & 0x01)
|
if (op_b_.value(op_b_.size()-1)) {
|
||||||
a += 1UL << idx;
|
b = (-b) & ~ (-1UL << op_b_.size());
|
||||||
if (val & 0x04)
|
negate = ! negate;
|
||||||
b += 1UL << idx;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b == 0) {
|
if (b == 0) {
|
||||||
output_x_(base, push);
|
vvp_vector4_t xval (wid_);
|
||||||
|
for (unsigned idx = 0 ; idx < wid_ ; idx += 1)
|
||||||
|
xval.set_bit(idx, BIT4_X);
|
||||||
|
|
||||||
|
vvp_send_vec4(ptr.ptr()->out, xval);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
output_val_(base, push, a%b);
|
unsigned long val = a % b;
|
||||||
#else
|
if (negate)
|
||||||
fprintf(stderr, "XXXX forgot how to implement vvp_arith_mod::set\n");
|
val = -val;
|
||||||
#endif
|
|
||||||
|
assert(wid_ <= 8*sizeof(val));
|
||||||
|
|
||||||
|
vvp_vector4_t vval (wid_);
|
||||||
|
for (unsigned 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Multiplication
|
// Multiplication
|
||||||
|
|
||||||
vvp_arith_mult::vvp_arith_mult(unsigned wid)
|
vvp_arith_mult::vvp_arith_mult(unsigned wid)
|
||||||
|
|
@ -760,6 +738,9 @@ void vvp_shiftr::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: arith.cc,v $
|
* $Log: arith.cc,v $
|
||||||
|
* Revision 1.42 2005/03/12 06:42:28 steve
|
||||||
|
* Implement .arith/mod.
|
||||||
|
*
|
||||||
* Revision 1.41 2005/03/09 05:52:04 steve
|
* Revision 1.41 2005/03/09 05:52:04 steve
|
||||||
* Handle case inequality in netlists.
|
* Handle case inequality in netlists.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
15
vvp/arith.h
15
vvp/arith.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: arith.h,v 1.27 2005/03/09 05:52:04 steve Exp $"
|
#ident "$Id: arith.h,v 1.28 2005/03/12 06:42:28 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "functor.h"
|
# include "functor.h"
|
||||||
|
|
@ -67,10 +67,12 @@ class vvp_arith_div : public vvp_arith_ {
|
||||||
class vvp_arith_mod : public vvp_arith_ {
|
class vvp_arith_mod : public vvp_arith_ {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit vvp_arith_mod(unsigned wid) : vvp_arith_(wid) {}
|
explicit vvp_arith_mod(unsigned wid, bool signed_flag);
|
||||||
|
~vvp_arith_mod();
|
||||||
void set(vvp_ipoint_t i, bool push, unsigned val, unsigned str);
|
void recv_vec4(vvp_net_ptr_t ptr, vvp_vector4_t bit);
|
||||||
void wide(vvp_ipoint_t base, bool push);
|
private:
|
||||||
|
void wide_(vvp_net_ptr_t ptr);
|
||||||
|
bool signed_flag_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* vvp_cmp_* objects...
|
/* vvp_cmp_* objects...
|
||||||
|
|
@ -197,6 +199,9 @@ class vvp_shiftr : public vvp_arith_ {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: arith.h,v $
|
* $Log: arith.h,v $
|
||||||
|
* Revision 1.28 2005/03/12 06:42:28 steve
|
||||||
|
* Implement .arith/mod.
|
||||||
|
*
|
||||||
* Revision 1.27 2005/03/09 05:52:04 steve
|
* Revision 1.27 2005/03/09 05:52:04 steve
|
||||||
* Handle case inequality in netlists.
|
* Handle case inequality in netlists.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: compile.cc,v 1.192 2005/03/12 04:27:42 steve Exp $"
|
#ident "$Id: compile.cc,v 1.193 2005/03/12 06:42:28 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "arith.h"
|
# include "arith.h"
|
||||||
|
|
@ -897,13 +897,13 @@ void compile_arith_mod(char*label, long wid,
|
||||||
{
|
{
|
||||||
assert( wid > 0 );
|
assert( wid > 0 );
|
||||||
|
|
||||||
if ((long)argc != 2*wid) {
|
if (argc != 2) {
|
||||||
fprintf(stderr, "%s; .arith/mod has wrong number of symbols\n", label);
|
fprintf(stderr, "%s .arith/mod has wrong number of symbols\n", label);
|
||||||
compile_errors += 1;
|
compile_errors += 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vvp_arith_ *arith = new vvp_arith_mod(wid);
|
vvp_arith_ *arith = new vvp_arith_mod(wid, false);
|
||||||
|
|
||||||
make_arith(arith, label, wid, argc, argv);
|
make_arith(arith, label, wid, argc, argv);
|
||||||
}
|
}
|
||||||
|
|
@ -1661,6 +1661,9 @@ void compile_param_string(char*label, char*name, char*str, char*value)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: compile.cc,v $
|
* $Log: compile.cc,v $
|
||||||
|
* Revision 1.193 2005/03/12 06:42:28 steve
|
||||||
|
* Implement .arith/mod.
|
||||||
|
*
|
||||||
* Revision 1.192 2005/03/12 04:27:42 steve
|
* Revision 1.192 2005/03/12 04:27:42 steve
|
||||||
* Implement VPI access to signal strengths,
|
* Implement VPI access to signal strengths,
|
||||||
* Fix resolution of ambiguous drive pairs,
|
* Fix resolution of ambiguous drive pairs,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue