2001-06-05 05:05:41 +02:00
|
|
|
/*
|
2005-01-16 05:19:08 +01:00
|
|
|
* Copyright (c) 2001-2005 Stephen Williams (steve@icarus.com)
|
2001-06-05 05:05:41 +02:00
|
|
|
*
|
|
|
|
|
* This source code is free software; you can redistribute it
|
|
|
|
|
* and/or modify it in source code form under the terms of the GNU
|
|
|
|
|
* General Public License as published by the Free Software
|
|
|
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
|
|
|
* any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
|
|
|
|
*/
|
2002-08-12 03:34:58 +02:00
|
|
|
#ifdef HAVE_CVS_IDENT
|
2005-02-19 03:41:23 +01:00
|
|
|
#ident "$Id: arith.cc,v 1.40 2005/02/19 02:41:23 steve Exp $"
|
2001-06-05 05:05:41 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
# include "arith.h"
|
|
|
|
|
# include "schedule.h"
|
2001-07-13 02:38:57 +02:00
|
|
|
# include <limits.h>
|
2001-10-16 05:06:18 +02:00
|
|
|
# include <stdio.h>
|
2001-06-05 05:05:41 +02:00
|
|
|
# include <assert.h>
|
2001-11-04 06:03:21 +01:00
|
|
|
# include <stdlib.h>
|
|
|
|
|
#ifdef HAVE_MALLOC_H
|
2001-10-31 05:27:46 +01:00
|
|
|
# include <malloc.h>
|
2001-11-04 06:03:21 +01:00
|
|
|
#endif
|
2001-06-05 05:05:41 +02:00
|
|
|
|
2004-12-11 03:31:25 +01:00
|
|
|
vvp_arith_::vvp_arith_(unsigned wid)
|
|
|
|
|
: wid_(wid), x_val_(wid)
|
2001-06-05 05:05:41 +02:00
|
|
|
{
|
2004-12-11 03:31:25 +01:00
|
|
|
for (unsigned idx = 0 ; idx < wid ; idx += 1)
|
|
|
|
|
x_val_.set_bit(idx, BIT4_X);
|
2005-01-22 02:06:20 +01:00
|
|
|
|
|
|
|
|
op_a_ = x_val_;
|
|
|
|
|
op_b_ = x_val_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void vvp_arith_::dispatch_operand_(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);
|
|
|
|
|
}
|
2001-10-31 05:27:46 +01:00
|
|
|
}
|
2001-10-16 04:47:37 +02:00
|
|
|
|
|
|
|
|
|
2001-10-31 05:27:46 +01:00
|
|
|
// Division
|
2001-10-16 04:47:37 +02:00
|
|
|
|
2005-02-19 02:32:52 +01:00
|
|
|
vvp_arith_div::vvp_arith_div(unsigned wid, bool signed_flag)
|
|
|
|
|
: vvp_arith_(wid), signed_flag_(signed_flag)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vvp_arith_div::~vvp_arith_div()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void vvp_arith_div::wide_(vvp_net_ptr_t ptr)
|
2001-10-31 05:27:46 +01:00
|
|
|
{
|
|
|
|
|
assert(0);
|
|
|
|
|
}
|
2001-10-16 04:47:37 +02:00
|
|
|
|
2005-02-19 02:32:52 +01:00
|
|
|
void vvp_arith_div::recv_vec4(vvp_net_ptr_t ptr, vvp_vector4_t bit)
|
|
|
|
|
{
|
|
|
|
|
dispatch_operand_(ptr, bit);
|
|
|
|
|
|
|
|
|
|
if (wid_ > 8 * sizeof(unsigned long)) {
|
|
|
|
|
wide_(ptr);
|
|
|
|
|
return ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2005-02-19 03:41:23 +01:00
|
|
|
bool negate = false;
|
|
|
|
|
/* If we are doing signed divide, then take the sign out of
|
|
|
|
|
the operands for now, and remember to put the sign back
|
|
|
|
|
later. */
|
|
|
|
|
if (signed_flag_) {
|
|
|
|
|
if (op_a_.value(op_a_.size()-1)) {
|
|
|
|
|
a = (-a) & ~ (-1UL << op_a_.size());
|
|
|
|
|
negate = !negate;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (op_b_.value(op_b_.size()-1)) {
|
|
|
|
|
b = (-b) & ~ (-1UL << op_b_.size());
|
|
|
|
|
negate = ! negate;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-02-19 02:32:52 +01:00
|
|
|
unsigned long val = a / b;
|
2005-02-19 03:41:23 +01:00
|
|
|
if (negate)
|
|
|
|
|
val = -val;
|
|
|
|
|
|
2005-02-19 02:32:52 +01:00
|
|
|
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);
|
2001-10-16 04:47:37 +02:00
|
|
|
|
2005-02-19 02:32:52 +01:00
|
|
|
val >>= 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vvp_send_vec4(ptr.ptr()->out, vval);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if 0
|
2001-10-31 05:27:46 +01:00
|
|
|
void vvp_arith_div::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
|
|
|
|
|
{
|
|
|
|
|
put(i, val);
|
|
|
|
|
vvp_ipoint_t base = ipoint_make(i,0);
|
2001-10-16 04:47:37 +02:00
|
|
|
|
2001-10-31 05:27:46 +01:00
|
|
|
if(wid_ > 8*sizeof(unsigned long)) {
|
|
|
|
|
wide(base, push);
|
|
|
|
|
return;
|
2001-10-16 04:47:37 +02:00
|
|
|
}
|
2001-06-17 01:45:05 +02:00
|
|
|
|
|
|
|
|
unsigned long a = 0, b = 0;
|
2004-06-30 04:15:57 +02:00
|
|
|
|
2001-06-17 01:45:05 +02:00
|
|
|
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
|
2001-10-31 05:27:46 +01:00
|
|
|
vvp_ipoint_t ptr = ipoint_index(base,idx);
|
2001-06-17 01:45:05 +02:00
|
|
|
functor_t obj = functor_index(ptr);
|
2004-10-04 03:10:51 +02:00
|
|
|
|
2001-10-31 05:27:46 +01:00
|
|
|
unsigned val = obj->ival;
|
|
|
|
|
if (val & 0xaa) {
|
|
|
|
|
output_x_(base, push);
|
2001-06-17 01:45:05 +02:00
|
|
|
return;
|
|
|
|
|
}
|
2004-10-04 03:10:51 +02:00
|
|
|
|
2001-10-31 05:27:46 +01:00
|
|
|
if (val & 0x01)
|
2003-08-01 02:58:34 +02:00
|
|
|
a += 1UL << idx;
|
2001-10-31 05:27:46 +01:00
|
|
|
if (val & 0x04)
|
2003-08-01 02:58:34 +02:00
|
|
|
b += 1UL << idx;
|
2001-10-31 05:27:46 +01:00
|
|
|
}
|
2001-06-17 01:45:05 +02:00
|
|
|
|
2004-06-30 04:15:57 +02:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2001-10-31 05:27:46 +01:00
|
|
|
if (b == 0) {
|
|
|
|
|
output_x_(base, push);
|
|
|
|
|
return;
|
2001-06-17 01:45:05 +02:00
|
|
|
}
|
|
|
|
|
|
2004-06-30 04:15:57 +02:00
|
|
|
unsigned long result = a / b;
|
|
|
|
|
if (sign_flip % 2 == 1)
|
|
|
|
|
result = 0 - result;
|
|
|
|
|
|
|
|
|
|
output_val_(base, push, result);
|
2001-10-31 05:27:46 +01:00
|
|
|
}
|
2005-02-19 02:32:52 +01:00
|
|
|
#endif
|
2001-10-31 05:27:46 +01:00
|
|
|
|
2002-01-03 05:19:01 +01:00
|
|
|
inline void vvp_arith_mod::wide(vvp_ipoint_t base, bool push)
|
|
|
|
|
{
|
|
|
|
|
assert(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void vvp_arith_mod::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
|
|
|
|
|
{
|
2004-12-11 03:31:25 +01:00
|
|
|
#if 0
|
2002-01-03 05:19:01 +01:00
|
|
|
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;
|
2004-10-04 03:10:51 +02:00
|
|
|
|
2002-01-03 05:19:01 +01:00
|
|
|
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
|
|
|
|
|
vvp_ipoint_t ptr = ipoint_index(base,idx);
|
|
|
|
|
functor_t obj = functor_index(ptr);
|
2004-10-04 03:10:51 +02:00
|
|
|
|
2002-01-03 05:19:01 +01:00
|
|
|
unsigned val = obj->ival;
|
|
|
|
|
if (val & 0xaa) {
|
|
|
|
|
output_x_(base, push);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2004-10-04 03:10:51 +02:00
|
|
|
|
2002-01-03 05:19:01 +01:00
|
|
|
if (val & 0x01)
|
2003-08-01 02:58:34 +02:00
|
|
|
a += 1UL << idx;
|
2002-01-03 05:19:01 +01:00
|
|
|
if (val & 0x04)
|
2003-08-01 02:58:34 +02:00
|
|
|
b += 1UL << idx;
|
2002-01-03 05:19:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (b == 0) {
|
|
|
|
|
output_x_(base, push);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
output_val_(base, push, a%b);
|
2004-12-11 03:31:25 +01:00
|
|
|
#else
|
|
|
|
|
fprintf(stderr, "XXXX forgot how to implement vvp_arith_mod::set\n");
|
|
|
|
|
#endif
|
2002-01-03 05:19:01 +01:00
|
|
|
}
|
|
|
|
|
|
2001-10-31 05:27:46 +01:00
|
|
|
// Multiplication
|
|
|
|
|
|
2005-01-28 06:34:25 +01:00
|
|
|
vvp_arith_mult::vvp_arith_mult(unsigned wid)
|
|
|
|
|
: vvp_arith_(wid)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vvp_arith_mult::~vvp_arith_mult()
|
2001-10-31 05:27:46 +01:00
|
|
|
{
|
2005-01-28 06:34:25 +01:00
|
|
|
}
|
|
|
|
|
|
2005-02-04 06:13:02 +01:00
|
|
|
void vvp_arith_mult::wide_(vvp_net_ptr_t ptr)
|
|
|
|
|
{
|
|
|
|
|
vvp_vector2_t a2 (op_a_);
|
|
|
|
|
vvp_vector2_t b2 (op_b_);
|
|
|
|
|
|
|
|
|
|
if (a2.is_NaN() || b2.is_NaN()) {
|
|
|
|
|
vvp_send_vec4(ptr.ptr()->out, x_val_);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vvp_vector2_t result = a2 * b2;
|
|
|
|
|
|
|
|
|
|
vvp_vector4_t res4 = vector2_to_vector4(result, wid_);
|
|
|
|
|
vvp_send_vec4(ptr.ptr()->out, res4);
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-28 06:34:25 +01:00
|
|
|
void vvp_arith_mult::recv_vec4(vvp_net_ptr_t ptr, vvp_vector4_t bit)
|
|
|
|
|
{
|
|
|
|
|
dispatch_operand_(ptr, bit);
|
|
|
|
|
|
2005-02-04 06:13:02 +01:00
|
|
|
if (wid_ > 8 * sizeof(unsigned long)) {
|
|
|
|
|
wide_(ptr);
|
|
|
|
|
return ;
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-28 06:34:25 +01:00
|
|
|
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_);
|
2005-02-04 06:13:02 +01:00
|
|
|
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
|
2005-01-28 06:34:25 +01:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2004-12-11 03:31:25 +01:00
|
|
|
#if 0
|
2005-01-28 06:34:25 +01:00
|
|
|
void vvp_arith_mult::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
|
|
|
|
|
{
|
2001-10-31 05:27:46 +01:00
|
|
|
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;
|
2001-06-17 01:45:05 +02:00
|
|
|
|
|
|
|
|
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
|
2001-10-31 05:27:46 +01:00
|
|
|
vvp_ipoint_t ptr = ipoint_index(base,idx);
|
2001-06-17 01:45:05 +02:00
|
|
|
functor_t obj = functor_index(ptr);
|
|
|
|
|
|
2001-10-31 05:27:46 +01:00
|
|
|
unsigned val = obj->ival;
|
|
|
|
|
if (val & 0xaa) {
|
|
|
|
|
output_x_(base, push);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2001-06-17 01:45:05 +02:00
|
|
|
|
2001-10-31 05:27:46 +01:00
|
|
|
if (val & 0x01)
|
2003-08-01 02:58:34 +02:00
|
|
|
a += 1UL << idx;
|
2001-10-31 05:27:46 +01:00
|
|
|
if (val & 0x04)
|
2003-08-01 02:58:34 +02:00
|
|
|
b += 1UL << idx;
|
2001-10-31 05:27:46 +01:00
|
|
|
}
|
2001-06-17 01:45:05 +02:00
|
|
|
|
2001-10-31 05:27:46 +01:00
|
|
|
output_val_(base, push, a*b);
|
|
|
|
|
}
|
2005-01-28 06:34:25 +01:00
|
|
|
#endif
|
2001-06-17 01:45:05 +02:00
|
|
|
|
2004-12-11 03:31:25 +01:00
|
|
|
#if 0
|
2001-10-31 05:27:46 +01:00
|
|
|
void vvp_arith_mult::wide(vvp_ipoint_t base, bool push)
|
|
|
|
|
{
|
2001-10-14 18:36:43 +02:00
|
|
|
unsigned char *a, *b, *sum;
|
|
|
|
|
a = new unsigned char[wid_];
|
|
|
|
|
b = new unsigned char[wid_];
|
|
|
|
|
sum = new unsigned char[wid_];
|
|
|
|
|
|
2003-08-01 02:58:34 +02:00
|
|
|
unsigned mxa = 0;
|
|
|
|
|
unsigned mxb = 0;
|
2001-10-14 18:36:43 +02:00
|
|
|
|
|
|
|
|
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
|
2001-10-31 05:27:46 +01:00
|
|
|
vvp_ipoint_t ptr = ipoint_index(base, idx);
|
2001-10-14 18:36:43 +02:00
|
|
|
functor_t obj = functor_index(ptr);
|
|
|
|
|
|
|
|
|
|
unsigned ival = obj->ival;
|
|
|
|
|
if (ival & 0xaa) {
|
2001-10-31 05:27:46 +01:00
|
|
|
output_x_(base, push);
|
2001-10-14 18:36:43 +02:00
|
|
|
delete[]sum;
|
|
|
|
|
delete[]b;
|
|
|
|
|
delete[]a;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2004-10-04 03:10:51 +02:00
|
|
|
if((a[idx] = ((ival & 0x01) != 0))) mxa=idx+1;
|
2001-10-14 18:36:43 +02:00
|
|
|
if((b[idx] = ((ival & 0x04) != 0))) mxb=idx;
|
2004-10-04 03:10:51 +02:00
|
|
|
sum[idx] = 0;
|
2001-10-14 18:36:43 +02:00
|
|
|
}
|
|
|
|
|
|
2003-08-01 02:58:34 +02:00
|
|
|
/* do the a*b multiply using the long method we learned in
|
|
|
|
|
grade school. We know at this point that there are no X or
|
|
|
|
|
Z values in the a or b vectors. */
|
|
|
|
|
|
|
|
|
|
for(unsigned i=0 ; i<=mxb ; i += 1) {
|
|
|
|
|
if(b[i]) {
|
|
|
|
|
unsigned char carry=0;
|
|
|
|
|
unsigned char temp;
|
|
|
|
|
|
|
|
|
|
for(unsigned j=0 ; j<=mxa ; j += 1) {
|
|
|
|
|
|
|
|
|
|
if((i+j) >= wid_)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
temp=sum[i+j] + a[j] + carry;
|
|
|
|
|
sum[i+j]=(temp&1);
|
|
|
|
|
carry=(temp>>1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-10-14 18:36:43 +02:00
|
|
|
|
|
|
|
|
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
|
2001-10-31 05:27:46 +01:00
|
|
|
vvp_ipoint_t ptr = ipoint_index(base,idx);
|
2001-10-14 18:36:43 +02:00
|
|
|
functor_t obj = functor_index(ptr);
|
|
|
|
|
|
2001-10-31 05:27:46 +01:00
|
|
|
unsigned val = sum[idx];
|
2001-10-14 18:36:43 +02:00
|
|
|
|
2001-12-06 04:31:24 +01:00
|
|
|
obj->put_oval(val, push);
|
2001-10-14 18:36:43 +02:00
|
|
|
}
|
|
|
|
|
|
2001-10-31 05:27:46 +01:00
|
|
|
delete[]sum;
|
|
|
|
|
delete[]b;
|
|
|
|
|
delete[]a;
|
2001-10-14 18:36:43 +02:00
|
|
|
}
|
2004-12-11 03:31:25 +01:00
|
|
|
#endif
|
2001-06-17 01:45:05 +02:00
|
|
|
|
2001-10-31 05:27:46 +01:00
|
|
|
// Addition
|
2001-06-29 03:20:20 +02:00
|
|
|
|
2004-12-11 03:31:25 +01:00
|
|
|
vvp_arith_sum::vvp_arith_sum(unsigned wid)
|
|
|
|
|
: vvp_arith_(wid)
|
2001-06-29 03:20:20 +02:00
|
|
|
{
|
2004-12-11 03:31:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vvp_arith_sum::~vvp_arith_sum()
|
|
|
|
|
{
|
|
|
|
|
}
|
2001-06-07 05:09:03 +02:00
|
|
|
|
2004-12-11 03:31:25 +01:00
|
|
|
void vvp_arith_sum::recv_vec4(vvp_net_ptr_t ptr, vvp_vector4_t bit)
|
|
|
|
|
{
|
2005-01-28 06:34:25 +01:00
|
|
|
dispatch_operand_(ptr, bit);
|
2001-06-29 03:20:20 +02:00
|
|
|
|
2004-12-11 03:31:25 +01:00
|
|
|
vvp_net_t*net = ptr.ptr();
|
2001-06-05 05:05:41 +02:00
|
|
|
|
2004-12-11 03:31:25 +01:00
|
|
|
vvp_vector4_t value (wid_);
|
|
|
|
|
|
|
|
|
|
/* Pad input vectors with this value to widen to the desired
|
|
|
|
|
output width. */
|
|
|
|
|
const vvp_bit4_t pad = BIT4_0;
|
|
|
|
|
|
|
|
|
|
vvp_bit4_t carry = BIT4_0;
|
2001-06-05 05:05:41 +02:00
|
|
|
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
|
2004-12-11 03:31:25 +01:00
|
|
|
vvp_bit4_t a = (idx >= op_a_.size())? pad : op_a_.value(idx);
|
|
|
|
|
vvp_bit4_t b = (idx >= op_b_.size())? pad : op_b_.value(idx);
|
|
|
|
|
vvp_bit4_t cur = add_with_carry(a, b, carry);
|
2001-06-05 05:05:41 +02:00
|
|
|
|
2004-12-11 03:31:25 +01:00
|
|
|
if (cur == BIT4_X) {
|
|
|
|
|
vvp_send_vec4(net->out, x_val_);
|
2001-06-05 05:05:41 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2004-12-11 03:31:25 +01:00
|
|
|
value.set_bit(idx, cur);
|
2001-06-05 05:05:41 +02:00
|
|
|
}
|
2001-06-29 03:20:20 +02:00
|
|
|
|
2004-12-11 03:31:25 +01:00
|
|
|
vvp_send_vec4(net->out, value);
|
2001-06-05 05:05:41 +02:00
|
|
|
}
|
|
|
|
|
|
2004-12-11 03:31:25 +01:00
|
|
|
vvp_arith_sub::vvp_arith_sub(unsigned wid)
|
|
|
|
|
: vvp_arith_(wid)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vvp_arith_sub::~vvp_arith_sub()
|
|
|
|
|
{
|
|
|
|
|
}
|
2001-06-07 05:09:03 +02:00
|
|
|
|
2001-07-13 02:38:57 +02:00
|
|
|
/*
|
2005-01-30 06:06:49 +01:00
|
|
|
* Subtraction works by adding the 2s complement of the B input 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.
|
2001-07-13 02:38:57 +02:00
|
|
|
*/
|
2004-12-11 03:31:25 +01:00
|
|
|
void vvp_arith_sub::recv_vec4(vvp_net_ptr_t ptr, vvp_vector4_t bit)
|
2001-06-07 05:09:03 +02:00
|
|
|
{
|
2005-01-22 02:06:20 +01:00
|
|
|
dispatch_operand_(ptr, bit);
|
2001-10-31 05:27:46 +01:00
|
|
|
|
2004-12-11 03:31:25 +01:00
|
|
|
vvp_net_t*net = ptr.ptr();
|
2001-07-13 02:38:57 +02:00
|
|
|
|
2004-12-11 03:31:25 +01:00
|
|
|
vvp_vector4_t value (wid_);
|
2001-06-07 05:09:03 +02:00
|
|
|
|
2004-12-11 03:31:25 +01:00
|
|
|
/* Pad input vectors with this value to widen to the desired
|
|
|
|
|
output width. */
|
|
|
|
|
const vvp_bit4_t pad = BIT4_1;
|
|
|
|
|
|
|
|
|
|
vvp_bit4_t carry = BIT4_1;
|
2001-06-07 05:09:03 +02:00
|
|
|
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
|
2004-12-11 03:31:25 +01:00
|
|
|
vvp_bit4_t a = (idx >= op_a_.size())? pad : op_a_.value(idx);
|
2005-01-30 06:06:49 +01:00
|
|
|
vvp_bit4_t b = (idx >= op_b_.size())? pad : ~op_b_.value(idx);
|
2004-12-11 03:31:25 +01:00
|
|
|
vvp_bit4_t cur = add_with_carry(a, b, carry);
|
2001-06-07 05:09:03 +02:00
|
|
|
|
2004-12-11 03:31:25 +01:00
|
|
|
if (cur == BIT4_X) {
|
|
|
|
|
vvp_send_vec4(net->out, x_val_);
|
2001-06-07 05:09:03 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2004-12-11 03:31:25 +01:00
|
|
|
value.set_bit(idx, cur);
|
2001-06-07 05:09:03 +02:00
|
|
|
}
|
2001-07-13 02:38:57 +02:00
|
|
|
|
2004-12-11 03:31:25 +01:00
|
|
|
vvp_send_vec4(net->out, value);
|
2001-06-07 05:09:03 +02:00
|
|
|
}
|
|
|
|
|
|
2005-01-22 02:06:20 +01:00
|
|
|
vvp_cmp_eeq::vvp_cmp_eeq(unsigned wid)
|
|
|
|
|
: vvp_arith_(wid)
|
|
|
|
|
{
|
|
|
|
|
}
|
2004-12-11 03:31:25 +01:00
|
|
|
|
2005-01-22 02:06:20 +01:00
|
|
|
void vvp_cmp_eeq::recv_vec4(vvp_net_ptr_t ptr, vvp_vector4_t bit)
|
|
|
|
|
{
|
|
|
|
|
dispatch_operand_(ptr, bit);
|
|
|
|
|
|
|
|
|
|
vvp_vector4_t eeq (1);
|
|
|
|
|
eeq.set_bit(0, BIT4_1);
|
|
|
|
|
|
|
|
|
|
assert(op_a_.size() == op_b_.size());
|
|
|
|
|
for (unsigned idx = 0 ; idx < op_a_.size() ; idx += 1)
|
|
|
|
|
if (op_a_.value(idx) != op_b_.value(idx)) {
|
|
|
|
|
eeq.set_bit(0, BIT4_0);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vvp_net_t*net = ptr.ptr();
|
|
|
|
|
vvp_send_vec4(net->out, eeq);
|
|
|
|
|
}
|
2004-12-11 03:31:25 +01:00
|
|
|
|
2004-06-16 18:33:25 +02:00
|
|
|
vvp_cmp_eq::vvp_cmp_eq(unsigned wid)
|
|
|
|
|
: vvp_arith_(wid)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-22 17:21:11 +01:00
|
|
|
/*
|
|
|
|
|
* Compare Vector a and Vector b. If in any bit position the a and b
|
|
|
|
|
* bits are known and different, then the result is 0. Otherwise, if
|
|
|
|
|
* there are X/Z bits anywhere in A or B, the result is X. Finally,
|
|
|
|
|
* the result is 1.
|
|
|
|
|
*/
|
|
|
|
|
void vvp_cmp_eq::recv_vec4(vvp_net_ptr_t ptr, vvp_vector4_t bit)
|
2004-06-16 18:33:25 +02:00
|
|
|
{
|
2005-01-22 17:21:11 +01:00
|
|
|
dispatch_operand_(ptr, bit);
|
2004-06-16 18:33:25 +02:00
|
|
|
|
2005-01-22 17:21:11 +01:00
|
|
|
assert(op_a_.size() == op_b_.size());
|
2004-06-16 18:33:25 +02:00
|
|
|
|
2005-01-22 17:21:11 +01:00
|
|
|
vvp_vector4_t res (1);
|
|
|
|
|
res.set_bit(0, BIT4_1);
|
|
|
|
|
|
|
|
|
|
for (unsigned idx = 0 ; idx < op_a_.size() ; idx += 1) {
|
|
|
|
|
vvp_bit4_t a = op_a_.value(idx);
|
|
|
|
|
vvp_bit4_t b = op_b_.value(idx);
|
|
|
|
|
|
|
|
|
|
if (a == BIT4_X)
|
|
|
|
|
res.set_bit(0, BIT4_X);
|
|
|
|
|
else if (a == BIT4_Z)
|
|
|
|
|
res.set_bit(0, BIT4_X);
|
|
|
|
|
else if (b == BIT4_X)
|
|
|
|
|
res.set_bit(0, BIT4_X);
|
|
|
|
|
else if (b == BIT4_Z)
|
|
|
|
|
res.set_bit(0, BIT4_X);
|
|
|
|
|
else if (a != b) {
|
|
|
|
|
res.set_bit(0, BIT4_0);
|
2004-06-16 18:33:25 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-22 17:21:11 +01:00
|
|
|
vvp_net_t*net = ptr.ptr();
|
|
|
|
|
vvp_send_vec4(net->out, res);
|
2004-06-16 18:33:25 +02:00
|
|
|
}
|
2005-01-22 17:21:11 +01:00
|
|
|
|
2004-06-16 18:33:25 +02:00
|
|
|
|
|
|
|
|
vvp_cmp_ne::vvp_cmp_ne(unsigned wid)
|
|
|
|
|
: vvp_arith_(wid)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-22 17:21:11 +01:00
|
|
|
/*
|
|
|
|
|
* Compare Vector a and Vector b. If in any bit position the a and b
|
|
|
|
|
* bits are known and different, then the result is 1. Otherwise, if
|
|
|
|
|
* there are X/Z bits anywhere in A or B, the result is X. Finally,
|
|
|
|
|
* the result is 0.
|
|
|
|
|
*/
|
|
|
|
|
void vvp_cmp_ne::recv_vec4(vvp_net_ptr_t ptr, vvp_vector4_t bit)
|
2004-06-16 18:33:25 +02:00
|
|
|
{
|
2005-01-22 17:21:11 +01:00
|
|
|
dispatch_operand_(ptr, bit);
|
2004-06-16 18:33:25 +02:00
|
|
|
|
2005-01-22 17:21:11 +01:00
|
|
|
assert(op_a_.size() == op_b_.size());
|
2004-06-16 18:33:25 +02:00
|
|
|
|
2005-01-22 17:21:11 +01:00
|
|
|
vvp_vector4_t res (1);
|
|
|
|
|
res.set_bit(0, BIT4_0);
|
|
|
|
|
|
|
|
|
|
for (unsigned idx = 0 ; idx < op_a_.size() ; idx += 1) {
|
|
|
|
|
vvp_bit4_t a = op_a_.value(idx);
|
|
|
|
|
vvp_bit4_t b = op_b_.value(idx);
|
|
|
|
|
|
|
|
|
|
if (a == BIT4_X)
|
|
|
|
|
res.set_bit(0, BIT4_X);
|
|
|
|
|
else if (a == BIT4_Z)
|
|
|
|
|
res.set_bit(0, BIT4_X);
|
|
|
|
|
else if (b == BIT4_X)
|
|
|
|
|
res.set_bit(0, BIT4_X);
|
|
|
|
|
else if (b == BIT4_Z)
|
|
|
|
|
res.set_bit(0, BIT4_X);
|
|
|
|
|
else if (a != b) {
|
|
|
|
|
res.set_bit(0, BIT4_1);
|
2004-06-16 18:33:25 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-22 17:21:11 +01:00
|
|
|
vvp_net_t*net = ptr.ptr();
|
|
|
|
|
vvp_send_vec4(net->out, res);
|
2004-06-16 18:33:25 +02:00
|
|
|
}
|
2005-01-22 17:21:11 +01:00
|
|
|
|
2004-06-16 18:33:25 +02:00
|
|
|
|
2004-09-22 18:44:07 +02:00
|
|
|
vvp_cmp_gtge_base_::vvp_cmp_gtge_base_(unsigned wid, bool flag)
|
2003-04-11 07:15:38 +02:00
|
|
|
: vvp_arith_(wid), signed_flag_(flag)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2005-01-16 05:19:08 +01:00
|
|
|
void vvp_cmp_gtge_base_::recv_vec4_base_(vvp_net_ptr_t ptr,
|
|
|
|
|
vvp_vector4_t bit,
|
|
|
|
|
vvp_bit4_t out_if_equal)
|
|
|
|
|
{
|
2005-01-22 18:36:15 +01:00
|
|
|
dispatch_operand_(ptr, bit);
|
2001-06-16 05:36:03 +02:00
|
|
|
|
2005-01-22 18:36:15 +01:00
|
|
|
vvp_bit4_t out = signed_flag_
|
|
|
|
|
? compare_gtge_signed(op_a_, op_b_, out_if_equal)
|
|
|
|
|
: compare_gtge(op_a_, op_b_, out_if_equal);
|
|
|
|
|
vvp_vector4_t val (1);
|
|
|
|
|
val.set_bit(0, out);
|
|
|
|
|
vvp_send_vec4(ptr.ptr()->out, val);
|
2001-06-15 06:07:57 +02:00
|
|
|
|
2005-01-22 18:36:15 +01:00
|
|
|
return;
|
2001-06-15 06:07:57 +02:00
|
|
|
}
|
2001-07-06 06:46:44 +02:00
|
|
|
|
2004-09-22 18:44:07 +02:00
|
|
|
|
|
|
|
|
vvp_cmp_ge::vvp_cmp_ge(unsigned wid, bool flag)
|
|
|
|
|
: vvp_cmp_gtge_base_(wid, flag)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-16 05:19:08 +01:00
|
|
|
void vvp_cmp_ge::recv_vec4(vvp_net_ptr_t ptr, vvp_vector4_t bit)
|
2004-09-22 18:44:07 +02:00
|
|
|
{
|
2005-01-16 05:19:08 +01:00
|
|
|
recv_vec4_base_(ptr, bit, BIT4_1);
|
2004-09-22 18:44:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vvp_cmp_gt::vvp_cmp_gt(unsigned wid, bool flag)
|
|
|
|
|
: vvp_cmp_gtge_base_(wid, flag)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-16 05:19:08 +01:00
|
|
|
void vvp_cmp_gt::recv_vec4(vvp_net_ptr_t ptr, vvp_vector4_t bit)
|
2004-09-22 18:44:07 +02:00
|
|
|
{
|
2005-01-16 05:19:08 +01:00
|
|
|
recv_vec4_base_(ptr, bit, BIT4_0);
|
2004-09-22 18:44:07 +02:00
|
|
|
}
|
2005-01-16 05:19:08 +01:00
|
|
|
|
2004-09-22 18:44:07 +02:00
|
|
|
|
2004-12-11 03:31:25 +01:00
|
|
|
#if 0
|
2001-10-31 05:27:46 +01:00
|
|
|
void vvp_shiftl::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
|
2001-07-06 06:46:44 +02:00
|
|
|
{
|
2001-10-31 05:27:46 +01:00
|
|
|
put(i, val);
|
|
|
|
|
vvp_ipoint_t base = ipoint_make(i,0);
|
|
|
|
|
|
|
|
|
|
unsigned amount = 0;
|
|
|
|
|
|
2001-07-06 06:46:44 +02:00
|
|
|
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
|
2001-10-31 05:27:46 +01:00
|
|
|
vvp_ipoint_t ptr = ipoint_index(base, idx);
|
2001-07-06 06:46:44 +02:00
|
|
|
functor_t fp = functor_index(ptr);
|
|
|
|
|
|
|
|
|
|
unsigned val = (fp->ival >> 2) & 0x03;
|
|
|
|
|
switch (val) {
|
|
|
|
|
case 0:
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
2001-10-31 05:27:46 +01:00
|
|
|
amount |= 1 << idx;
|
2001-07-06 06:46:44 +02:00
|
|
|
break;
|
|
|
|
|
default:
|
2001-10-31 05:27:46 +01:00
|
|
|
output_x_(base, push);
|
2001-07-06 06:46:44 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-10-31 05:27:46 +01:00
|
|
|
if (amount >= wid_) {
|
|
|
|
|
output_x_(base, push, 0);
|
|
|
|
|
return;
|
2001-07-06 06:46:44 +02:00
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
vvp_ipoint_t optr, iptr;
|
|
|
|
|
functor_t ofp, ifp;
|
|
|
|
|
|
2001-10-31 05:27:46 +01:00
|
|
|
for (unsigned idx = 0 ; idx < amount ; idx += 1) {
|
|
|
|
|
optr = ipoint_index(base, idx);
|
2001-07-06 06:46:44 +02:00
|
|
|
ofp = functor_index(optr);
|
2001-12-06 04:31:24 +01:00
|
|
|
ofp->put_oval(0, push);
|
2001-07-06 06:46:44 +02:00
|
|
|
}
|
|
|
|
|
|
2001-10-31 05:27:46 +01:00
|
|
|
for (unsigned idx = amount ; idx < wid_ ; idx += 1) {
|
|
|
|
|
optr = ipoint_index(base, idx);
|
2001-07-06 06:46:44 +02:00
|
|
|
ofp = functor_index(optr);
|
2001-10-31 05:27:46 +01:00
|
|
|
iptr = ipoint_index(base, idx - amount);
|
2001-07-06 06:46:44 +02:00
|
|
|
ifp = functor_index(iptr);
|
|
|
|
|
|
2001-12-06 04:31:24 +01:00
|
|
|
ofp->put_oval(ifp->ival & 3, push);
|
2001-07-06 06:46:44 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-12-11 03:31:25 +01:00
|
|
|
#endif
|
2001-07-06 06:46:44 +02:00
|
|
|
|
2004-12-11 03:31:25 +01:00
|
|
|
#if 0
|
2001-10-31 05:27:46 +01:00
|
|
|
void vvp_shiftr::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
|
2001-07-07 04:57:33 +02:00
|
|
|
{
|
2001-10-31 05:27:46 +01:00
|
|
|
put(i, val);
|
|
|
|
|
vvp_ipoint_t base = ipoint_make(i,0);
|
2001-07-07 04:57:33 +02:00
|
|
|
|
2001-10-31 05:27:46 +01:00
|
|
|
unsigned amount = 0;
|
2001-07-07 04:57:33 +02:00
|
|
|
|
|
|
|
|
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
|
2001-10-31 05:27:46 +01:00
|
|
|
vvp_ipoint_t ptr = ipoint_index(base, idx);
|
2001-07-07 04:57:33 +02:00
|
|
|
functor_t fp = functor_index(ptr);
|
|
|
|
|
|
|
|
|
|
unsigned val = (fp->ival >> 2) & 0x03;
|
|
|
|
|
switch (val) {
|
|
|
|
|
case 0:
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
2001-10-31 05:27:46 +01:00
|
|
|
amount |= 1 << idx;
|
2001-07-07 04:57:33 +02:00
|
|
|
break;
|
|
|
|
|
default:
|
2001-10-31 05:27:46 +01:00
|
|
|
output_x_(base, push);
|
2001-07-07 04:57:33 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-10-31 05:27:46 +01:00
|
|
|
if (amount >= wid_) {
|
|
|
|
|
output_x_(base, push, 0);
|
|
|
|
|
return;
|
2001-07-07 04:57:33 +02:00
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
vvp_ipoint_t optr, iptr;
|
|
|
|
|
functor_t ofp, ifp;
|
|
|
|
|
|
2001-10-31 05:27:46 +01:00
|
|
|
for (unsigned idx = 0 ; idx < (wid_-amount) ; idx += 1) {
|
|
|
|
|
optr = ipoint_index(base, idx);
|
2001-07-07 04:57:33 +02:00
|
|
|
ofp = functor_index(optr);
|
2001-10-31 05:27:46 +01:00
|
|
|
iptr = ipoint_index(base, idx + amount);
|
2001-07-07 04:57:33 +02:00
|
|
|
ifp = functor_index(iptr);
|
|
|
|
|
|
2001-12-06 04:31:24 +01:00
|
|
|
ofp->put_oval(ifp->ival & 3, push);
|
2001-07-07 04:57:33 +02:00
|
|
|
}
|
|
|
|
|
|
2001-10-31 05:27:46 +01:00
|
|
|
for (unsigned idx = wid_-amount; idx < wid_ ; idx += 1) {
|
|
|
|
|
optr = ipoint_index(base, idx);
|
2001-07-07 04:57:33 +02:00
|
|
|
ofp = functor_index(optr);
|
2001-12-06 04:31:24 +01:00
|
|
|
ofp->put_oval(0, push);
|
2001-07-07 04:57:33 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-12-11 03:31:25 +01:00
|
|
|
#endif
|
2001-07-07 04:57:33 +02:00
|
|
|
|
2001-06-05 05:05:41 +02:00
|
|
|
/*
|
|
|
|
|
* $Log: arith.cc,v $
|
2005-02-19 03:41:23 +01:00
|
|
|
* Revision 1.40 2005/02/19 02:41:23 steve
|
|
|
|
|
* Handle signed divide.
|
|
|
|
|
*
|
2005-02-19 02:32:52 +01:00
|
|
|
* Revision 1.39 2005/02/19 01:32:52 steve
|
|
|
|
|
* Implement .arith/div.
|
|
|
|
|
*
|
2005-02-04 06:13:02 +01:00
|
|
|
* Revision 1.38 2005/02/04 05:13:02 steve
|
|
|
|
|
* Add wide .arith/mult, and vvp_vector2_t vectors.
|
|
|
|
|
*
|
2005-01-30 06:06:49 +01:00
|
|
|
* Revision 1.37 2005/01/30 05:06:49 steve
|
|
|
|
|
* Get .arith/sub working.
|
|
|
|
|
*
|
2005-01-28 06:34:25 +01:00
|
|
|
* Revision 1.36 2005/01/28 05:34:25 steve
|
|
|
|
|
* Add vector4 implementation of .arith/mult.
|
|
|
|
|
*
|
2005-01-22 18:36:15 +01:00
|
|
|
* Revision 1.35 2005/01/22 17:36:15 steve
|
|
|
|
|
* .cmp/x supports signed magnitude compare.
|
|
|
|
|
*
|
2005-01-22 17:21:11 +01:00
|
|
|
* Revision 1.34 2005/01/22 16:21:11 steve
|
|
|
|
|
* Implement vectored CMP_EQ and NE
|
|
|
|
|
*
|
2005-01-22 02:06:20 +01:00
|
|
|
* Revision 1.33 2005/01/22 01:06:20 steve
|
|
|
|
|
* Implement the .cmp/eeq LPM node.
|
|
|
|
|
*
|
2005-01-16 05:19:08 +01:00
|
|
|
* Revision 1.32 2005/01/16 04:19:08 steve
|
|
|
|
|
* Reimplement comparators as vvp_vector4_t nodes.
|
|
|
|
|
*
|
2004-12-11 03:31:25 +01:00
|
|
|
* 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
|
|
|
|
|
* down this path.
|
2001-06-29 03:20:20 +02:00
|
|
|
*
|
2001-06-05 05:05:41 +02:00
|
|
|
*/
|
|
|
|
|
|