Remove width restriction on subtraction.
This commit is contained in:
parent
3154f07817
commit
15a952a143
76
vvp/arith.cc
76
vvp/arith.cc
|
|
@ -17,14 +17,15 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: arith.cc,v 1.10 2001/07/11 02:27:21 steve Exp $"
|
#ident "$Id: arith.cc,v 1.11 2001/07/13 00:38:57 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "arith.h"
|
# include "arith.h"
|
||||||
# include "schedule.h"
|
# include "schedule.h"
|
||||||
|
# include <limits.h>
|
||||||
# include <assert.h>
|
# include <assert.h>
|
||||||
|
|
||||||
# include <stdio.h>
|
|
||||||
|
|
||||||
vvp_arith_::vvp_arith_(vvp_ipoint_t b, unsigned w)
|
vvp_arith_::vvp_arith_(vvp_ipoint_t b, unsigned w)
|
||||||
: base_(b), wid_(w)
|
: base_(b), wid_(w)
|
||||||
|
|
@ -138,6 +139,7 @@ void vvp_arith_sum::set(vvp_ipoint_t i, functor_t f, bool push)
|
||||||
tmp += 1;
|
tmp += 1;
|
||||||
|
|
||||||
// Add in the carry carried over.
|
// Add in the carry carried over.
|
||||||
|
assert(tmp < (ULONG_MAX/2));
|
||||||
tmp += carry;
|
tmp += carry;
|
||||||
// Put the next bit into the sum,
|
// Put the next bit into the sum,
|
||||||
sum_[page] |= ((tmp&1) << pbit);
|
sum_[page] |= ((tmp&1) << pbit);
|
||||||
|
|
@ -181,13 +183,31 @@ void vvp_arith_sum::set(vvp_ipoint_t i, functor_t f, bool push)
|
||||||
vvp_arith_sub::vvp_arith_sub(vvp_ipoint_t b, unsigned w)
|
vvp_arith_sub::vvp_arith_sub(vvp_ipoint_t b, unsigned w)
|
||||||
: vvp_arith_(b, w)
|
: vvp_arith_(b, w)
|
||||||
{
|
{
|
||||||
|
sum_ = new unsigned long[(w+1) / 8*sizeof(unsigned long) + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vvp_arith_sub::~vvp_arith_sub()
|
||||||
|
{
|
||||||
|
delete[]sum_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Subtraction works by adding the 2s complement of the B, C and D
|
||||||
|
* inputs from the A input. The 2s complement is the 1s complement
|
||||||
|
* plus one, so we further reduce the operation to adding in the
|
||||||
|
* inverted value and adding a correction.
|
||||||
|
*/
|
||||||
void vvp_arith_sub::set(vvp_ipoint_t i, functor_t f, bool push)
|
void vvp_arith_sub::set(vvp_ipoint_t i, functor_t f, bool push)
|
||||||
{
|
{
|
||||||
assert(wid_ <= 8*sizeof(unsigned long));
|
unsigned page = 0;
|
||||||
|
unsigned pbit = 0;
|
||||||
|
|
||||||
unsigned long sum = 0;
|
/* There are 3 values subtracted from the first parameter, so
|
||||||
|
there are three 2s complements, so three ~X +1. That's why
|
||||||
|
the carry starts with 3. */
|
||||||
|
unsigned long carry = 3;
|
||||||
|
|
||||||
|
sum_[0] = 0;
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
|
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
|
||||||
vvp_ipoint_t ptr = ipoint_index(base_,idx);
|
vvp_ipoint_t ptr = ipoint_index(base_,idx);
|
||||||
|
|
@ -199,25 +219,47 @@ void vvp_arith_sub::set(vvp_ipoint_t i, functor_t f, bool push)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned tmp = 0;
|
// Accumulate the sum of the input bits. Add in the
|
||||||
|
// first value, and the ones complement of the other values.
|
||||||
|
unsigned long tmp = 0;
|
||||||
if (ival & 0x01)
|
if (ival & 0x01)
|
||||||
tmp += 1;
|
tmp += 1;
|
||||||
if (ival & 0x04)
|
if (! (ival & 0x04))
|
||||||
tmp -= 1;
|
tmp += 1;
|
||||||
if (ival & 0x10)
|
if (! (ival & 0x10))
|
||||||
tmp -= 1;
|
tmp += 1;
|
||||||
if (ival & 0x40)
|
if (! (ival & 0x40))
|
||||||
tmp -= 1;
|
tmp += 1;
|
||||||
|
|
||||||
sum += (tmp << idx);
|
// Add in the carry carried over.
|
||||||
|
assert(tmp < (ULONG_MAX/2));
|
||||||
|
tmp += carry;
|
||||||
|
// Put the next bit into the sum,
|
||||||
|
sum_[page] |= ((tmp&1) << pbit);
|
||||||
|
// ... and carry the remaining bits.
|
||||||
|
carry = tmp >> 1;
|
||||||
|
|
||||||
|
pbit += 1;
|
||||||
|
if (pbit == 8 * sizeof sum_[page]) {
|
||||||
|
pbit = 0;
|
||||||
|
page += 1;
|
||||||
|
sum_[page] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
page = 0;
|
||||||
|
pbit = 0;
|
||||||
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
|
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
|
||||||
vvp_ipoint_t ptr = ipoint_index(base_,idx);
|
vvp_ipoint_t ptr = ipoint_index(base_,idx);
|
||||||
functor_t obj = functor_index(ptr);
|
functor_t obj = functor_index(ptr);
|
||||||
|
|
||||||
unsigned oval = sum & 1;
|
unsigned oval = (sum_[page] >> pbit) & 1;
|
||||||
sum >>= 1;
|
|
||||||
|
pbit += 1;
|
||||||
|
if (pbit == 8 * sizeof sum_[page]) {
|
||||||
|
pbit = 0;
|
||||||
|
page += 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (obj->oval == oval)
|
if (obj->oval == oval)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -229,6 +271,7 @@ void vvp_arith_sub::set(vvp_ipoint_t i, functor_t f, bool push)
|
||||||
else
|
else
|
||||||
schedule_functor(ptr, 0);
|
schedule_functor(ptr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vvp_cmp_ge::vvp_cmp_ge(vvp_ipoint_t b, unsigned w)
|
vvp_cmp_ge::vvp_cmp_ge(vvp_ipoint_t b, unsigned w)
|
||||||
|
|
@ -466,6 +509,9 @@ void vvp_shiftr::set(vvp_ipoint_t i, functor_t f, bool push)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: arith.cc,v $
|
* $Log: arith.cc,v $
|
||||||
|
* Revision 1.11 2001/07/13 00:38:57 steve
|
||||||
|
* Remove width restriction on subtraction.
|
||||||
|
*
|
||||||
* Revision 1.10 2001/07/11 02:27:21 steve
|
* Revision 1.10 2001/07/11 02:27:21 steve
|
||||||
* Add support for REadOnlySync and monitors.
|
* Add support for REadOnlySync and monitors.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: arith.h,v 1.7 2001/07/07 02:57:33 steve Exp $"
|
#ident "$Id: arith.h,v 1.8 2001/07/13 00:38:57 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "functor.h"
|
# include "functor.h"
|
||||||
|
|
@ -79,9 +79,13 @@ class vvp_arith_sub : public vvp_arith_ {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit vvp_arith_sub(vvp_ipoint_t b, unsigned wid);
|
explicit vvp_arith_sub(vvp_ipoint_t b, unsigned wid);
|
||||||
|
virtual ~vvp_arith_sub();
|
||||||
|
|
||||||
void set(vvp_ipoint_t i, functor_t f, bool push);
|
void set(vvp_ipoint_t i, functor_t f, bool push);
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned long*sum_;
|
||||||
|
|
||||||
private: // not implemented
|
private: // not implemented
|
||||||
vvp_arith_sub(const vvp_arith_sub&);
|
vvp_arith_sub(const vvp_arith_sub&);
|
||||||
vvp_arith_sub& operator= (const vvp_arith_sub&);
|
vvp_arith_sub& operator= (const vvp_arith_sub&);
|
||||||
|
|
@ -143,6 +147,9 @@ class vvp_shiftr : public vvp_arith_ {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: arith.h,v $
|
* $Log: arith.h,v $
|
||||||
|
* Revision 1.8 2001/07/13 00:38:57 steve
|
||||||
|
* Remove width restriction on subtraction.
|
||||||
|
*
|
||||||
* Revision 1.7 2001/07/07 02:57:33 steve
|
* Revision 1.7 2001/07/07 02:57:33 steve
|
||||||
* Add the .shift/r functor.
|
* Add the .shift/r functor.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue