diff --git a/vvp/arith.cc b/vvp/arith.cc index 7a5e5f565..2be4e4353 100644 --- a/vvp/arith.cc +++ b/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.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. * diff --git a/vvp/arith.h b/vvp/arith.h index d89dce862..1144dba54 100644 --- a/vvp/arith.h +++ b/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.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. * diff --git a/vvp/vvp_net.cc b/vvp/vvp_net.cc index 994e85efd..0e7fd0b3a 100644 --- a/vvp/vvp_net.cc +++ b/vvp/vvp_net.cc @@ -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 @@ -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<= 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. * diff --git a/vvp/vvp_net.h b/vvp/vvp_net.h index ca9c5b5b8..cd30376e9 100644 --- a/vvp/vvp_net.h +++ b/vvp/vvp_net.h @@ -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 @@ -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. *