Add wide .arith/mult, and vvp_vector2_t vectors.

This commit is contained in:
steve 2005-02-04 05:13:02 +00:00
parent 97f83ffbe3
commit b48abb2148
4 changed files with 212 additions and 6 deletions

View File

@ -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.37 2005/01/30 05:06:49 steve Exp $"
#ident "$Id: arith.cc,v 1.38 2005/02/04 05:13:02 steve Exp $"
#endif
# include "arith.h"
@ -180,10 +180,31 @@ vvp_arith_mult::~vvp_arith_mult()
{
}
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);
}
void vvp_arith_mult::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_);
@ -200,7 +221,7 @@ void vvp_arith_mult::recv_vec4(vvp_net_ptr_t ptr, vvp_vector4_t bit)
assert(wid_ <= 8*sizeof(val));
vvp_vector4_t vval (wid_);
for (int idx = 0 ; idx < wid_ ; idx += 1) {
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
if (val & 1)
vval.set_bit(idx, BIT4_1);
else
@ -652,6 +673,9 @@ void vvp_shiftr::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
/*
* $Log: arith.cc,v $
* Revision 1.38 2005/02/04 05:13:02 steve
* Add wide .arith/mult, and vvp_vector2_t vectors.
*
* Revision 1.37 2005/01/30 05:06:49 steve
* Get .arith/sub working.
*

View File

@ -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.24 2005/01/28 05:34:25 steve Exp $"
#ident "$Id: arith.h,v 1.25 2005/02/04 05:13:02 steve Exp $"
#endif
# include "functor.h"
@ -151,6 +151,8 @@ class vvp_arith_mult : public vvp_arith_ {
explicit vvp_arith_mult(unsigned wid);
~vvp_arith_mult();
void recv_vec4(vvp_net_ptr_t ptr, vvp_vector4_t bit);
private:
void wide_(vvp_net_ptr_t ptr);
};
class vvp_arith_sub : public vvp_arith_ {
@ -189,6 +191,9 @@ class vvp_shiftr : public vvp_arith_ {
/*
* $Log: arith.h,v $
* Revision 1.25 2005/02/04 05:13:02 steve
* Add wide .arith/mult, and vvp_vector2_t vectors.
*
* Revision 1.24 2005/01/28 05:34:25 steve
* Add vector4 implementation of .arith/mult.
*

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.12 2005/02/03 04:55:13 steve Exp $"
#ident "$Id: vvp_net.cc,v 1.13 2005/02/04 05:13:02 steve Exp $"
# include "vvp_net.h"
# include <stdio.h>
@ -330,6 +330,146 @@ bool vector4_to_value(const vvp_vector4_t&vec, unsigned long&val)
return true;
}
vvp_vector2_t::vvp_vector2_t()
{
vec_ = 0;
wid_ = 0;
}
vvp_vector2_t::vvp_vector2_t(unsigned long v, unsigned wid)
{
wid_ = wid;
const unsigned bits_per_word = 8 * sizeof(vec_[0]);
const unsigned words = (wid_ + bits_per_word-1) / bits_per_word;
vec_ = new unsigned long[words];
for (unsigned idx = 0 ; idx < words ; idx += 1)
vec_[idx] = 0;
}
vvp_vector2_t::vvp_vector2_t(const vvp_vector4_t&that)
{
wid_ = that.size();
const unsigned bits_per_word = 8 * sizeof(vec_[0]);
const unsigned words = (that.size() + bits_per_word-1) / bits_per_word;
if (words == 0) {
vec_ = 0;
wid_ = 0;
return;
}
vec_ = new unsigned long[words];
for (unsigned idx = 0 ; idx < words ; idx += 1)
vec_[idx] = 0;
for (unsigned idx = 0 ; idx < that.size() ; idx += 1) {
unsigned addr = idx / bits_per_word;
unsigned shift = idx % bits_per_word;
switch (that.value(idx)) {
case BIT4_0:
break;
case BIT4_1:
vec_[addr] |= 1 << shift;
break;
default:
delete[]vec_;
vec_ = 0;
wid_ = 0;
return;
}
}
}
vvp_vector2_t::~vvp_vector2_t()
{
if (vec_) delete[]vec_;
}
unsigned vvp_vector2_t::size() const
{
return wid_;
}
int vvp_vector2_t::value(unsigned idx) const
{
if (idx >= wid_)
return 0;
const unsigned bits_per_word = 8 * sizeof(vec_[0]);
unsigned addr = idx/bits_per_word;
unsigned mask = idx%bits_per_word;
if (vec_[addr] & (1UL<<mask))
return 1;
else
return 0;
}
bool vvp_vector2_t::is_NaN() const
{
return wid_ == 0;
}
/*
* Multiplication of two vector2 vectors returns a product as wide as
* the sum of the widths of the input vectors.
*/
vvp_vector2_t operator * (const vvp_vector2_t&a, const vvp_vector2_t&b)
{
const unsigned bits_per_word = 8 * sizeof(a.vec_[0]);
vvp_vector2_t r (0, a.size() + b.size());
assert(sizeof(unsigned long long) >= 2*sizeof(a.vec_[0]));
unsigned long long word_mask = (1ULL << bits_per_word) - 1ULL;
unsigned awords = (a.wid_ + bits_per_word - 1) / bits_per_word;
unsigned bwords = (b.wid_ + bits_per_word - 1) / bits_per_word;
unsigned rwords = (r.wid_ + bits_per_word - 1) / bits_per_word;
for (unsigned bdx = 0 ; bdx < bwords ; bdx += 1) {
unsigned long long tmpb = b.vec_[bdx];
if (tmpb == 0)
continue;
for (unsigned adx = 0 ; adx < awords ; adx += 1) {
unsigned long long tmpa = a.vec_[adx];
unsigned long long tmpr = tmpb * tmpa;
for (unsigned sdx = 0
; (adx+bdx+sdx) < rwords && tmpr > 0
; sdx += 1) {
unsigned long long sum = r.vec_[adx+bdx+sdx];
sum += tmpr & word_mask;
r.vec_[adx+bdx+sdx] = sum & word_mask;
sum >>= bits_per_word;
tmpr >>= bits_per_word;
tmpr += sum;
}
}
}
return r;
}
vvp_vector4_t vector2_to_vector4(const vvp_vector2_t&that, unsigned wid)
{
vvp_vector4_t res (wid);
for (unsigned idx = 0 ; idx < res.size() ; idx += 1) {
vvp_bit4_t bit = BIT4_0;
if (that.value(idx))
bit = BIT4_1;
res.set_bit(idx, bit);
}
return res;
}
vvp_vector8_t::vvp_vector8_t(const vvp_vector8_t&that)
{
size_ = that.size_;
@ -892,6 +1032,9 @@ vvp_bit4_t compare_gtge_signed(const vvp_vector4_t&a,
/*
* $Log: vvp_net.cc,v $
* Revision 1.13 2005/02/04 05:13:02 steve
* Add wide .arith/mult, and vvp_vector2_t vectors.
*
* Revision 1.12 2005/02/03 04:55:13 steve
* Add support for reduction logic gates.
*

View File

@ -1,7 +1,7 @@
#ifndef __vvp_net_H
#define __vvp_net_H
/*
* Copyright (c) 2004 Stephen Williams (steve@icarus.com)
* Copyright (c) 2004-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
@ -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.12 2005/02/03 04:55:13 steve Exp $"
#ident "$Id: vvp_net.h,v 1.13 2005/02/04 05:13:02 steve Exp $"
# include <assert.h>
@ -108,6 +108,37 @@ extern vvp_bit4_t compare_gtge_signed(const vvp_vector4_t&a,
*/
extern bool vector4_to_value(const vvp_vector4_t&a, unsigned long&val);
/* vvp_vector2_t
*/
class vvp_vector2_t {
friend vvp_vector2_t operator + (const vvp_vector2_t&,
const vvp_vector2_t&);
friend vvp_vector2_t operator * (const vvp_vector2_t&,
const vvp_vector2_t&);
public:
vvp_vector2_t();
vvp_vector2_t(const vvp_vector2_t&);
explicit vvp_vector2_t(const vvp_vector4_t&that);
vvp_vector2_t(unsigned long val, unsigned wid);
~vvp_vector2_t();
vvp_vector2_t operator = (const vvp_vector2_t&);
bool is_NaN() const;
unsigned size() const;
int value(unsigned idx) const;
private:
unsigned long*vec_;
unsigned wid_;
};
extern vvp_vector2_t operator + (const vvp_vector2_t&, const vvp_vector2_t&);
extern vvp_vector2_t operator * (const vvp_vector2_t&, const vvp_vector2_t&);
extern vvp_vector4_t vector2_to_vector4(const vvp_vector2_t&, unsigned wid);
/*
* This class represents a scaler value with strength. These are
* heavier then the simple vvp_bit4_t, but more information is
@ -511,6 +542,9 @@ class vvp_fun_signal : public vvp_net_fun_t {
/*
* $Log: vvp_net.h,v $
* Revision 1.13 2005/02/04 05:13:02 steve
* Add wide .arith/mult, and vvp_vector2_t vectors.
*
* Revision 1.12 2005/02/03 04:55:13 steve
* Add support for reduction logic gates.
*