Implement .resolv functors, and stub signals recv_vec8 method.

This commit is contained in:
steve 2004-12-31 06:00:06 +00:00
parent d1e2538aba
commit 34a14b983b
5 changed files with 176 additions and 175 deletions

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
*
* $Id: README.txt,v 1.50 2004/12/29 23:45:13 steve Exp $
* $Id: README.txt,v 1.51 2004/12/31 06:00:06 steve Exp $
*/
VVP SIMULATION ENGINE
@ -437,6 +437,9 @@ resolution function.
<label> .resolv tri0, <symbols_list>;
<label> .resolv tri1, <symbols_list>;
The output from the resolver is vvp_vector8_t value. That is, the
result is a vector with strength included.
PART SELECT STATEMENTS:

View File

@ -17,178 +17,15 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: resolv.cc,v 1.18 2004/12/11 02:31:30 steve Exp $"
#ident "$Id: resolv.cc,v 1.19 2004/12/31 06:00:06 steve Exp $"
#endif
# include "resolv.h"
# include "schedule.h"
# include "statistics.h"
# include <stdio.h>
# include <assert.h>
#if 0
/*
* A signal value is unambiguous if the top 4 bits and the bottom 4
* bits are identical. This means that the VSSSvsss bits of the 8bit
* value have V==v and SSS==sss.
*/
# define UNAMBIG(v) (((v) & 0x0f) == (((v) >> 4) & 0x0f))
# define STREN1(v) ( ((v)&0x80)? ((v)&0xf0) : (0x70 - ((v)&0xf0)) )
# define STREN0(v) ( ((v)&0x08)? ((v)&0x0f) : (0x07 - ((v)&0x0f)) )
# include <iostream>
static unsigned blend(unsigned a, unsigned b)
{
if (a == HiZ)
return b;
if (b == HiZ)
return a;
unsigned res = a;
if (UNAMBIG(a) && UNAMBIG(b)) {
/* If both signals are unambiguous, simply choose
the stronger. If they have the same strength
but different values, then this becomes
ambiguous. */
if (a == b) {
/* values are equal. do nothing. */
} else if ((b&0x07) > (res&0x07)) {
/* New value is stronger. Take it. */
res = b;
} else if ((b&0x77) == (res&0x77)) {
/* Strengths are the same. Make value ambiguous. */
res = (res&0x70) | (b&0x07) | 0x80;
} else {
/* Must be res is the stronger one. */
}
} else if (UNAMBIG(res)) {
unsigned tmp = 0;
if ((res&0x70) > (b&0x70))
tmp |= res&0xf0;
else
tmp |= b&0xf0;
if ((res&0x07) > (b&0x07))
tmp |= res&0x0f;
else
tmp |= b&0x0f;
res = tmp;
} else if (UNAMBIG(b)) {
/* If one of the signals is unambiguous, then it
will sweep up the weaker parts of the ambiguous
signal. The result may be ambiguous, or maybe not. */
unsigned tmp = 0;
if ((b&0x70) > (res&0x70))
tmp |= b&0xf0;
else
tmp |= res&0xf0;
if ((b&0x07) > (res&0x07))
tmp |= b&0x0f;
else
tmp |= res&0x0f;
res = tmp;
} else {
/* If both signals are ambiguous, then the result
has an even wider ambiguity. */
unsigned tmp = 0;
if (STREN1(b) > STREN1(res))
tmp |= b&0xf0;
else
tmp |= res&0xf0;
if (STREN0(b) < STREN0(res))
tmp |= b&0x0f;
else
tmp |= res&0x0f;
res = tmp;
}
/* Canonicalize the HiZ value. */
if ((res&0x77) == 0)
res = HiZ;
return res;
}
resolv_functor_s::resolv_functor_s(unsigned char pull)
{
count_functors_resolv += 1;
istr[0]=istr[1]=istr[2]=istr[3]=StX;
hiz_ = pull;
}
resolv_functor_s::~resolv_functor_s()
{
}
/*
* Resolve the strength values of the inputs, two at a time. Pairs of
* inputs are resolved with the blend function, and the final value is
* reduced to a 4-value result for propagation.
*/
void resolv_functor_s::set(vvp_ipoint_t i, bool push, unsigned, unsigned str)
{
unsigned pp = ipoint_port(i);
istr[pp] = str;
unsigned sval = hiz_;
sval = blend(sval, istr[0]);
sval = blend(sval, istr[1]);
sval = blend(sval, istr[2]);
sval = blend(sval, istr[3]);
unsigned val;
if (sval == HiZ) {
val = 3;
} else switch (sval & 0x88) {
case 0x00:
val = 0;
break;
case 0x88:
val = 1;
break;
default:
val = 2;
break;
}
/* If the output changes, then create a propagation event. */
// Do not propagate (push). Why? Because if, for example, a
// clock buffer is modeled as parallel inverters, the output
// must not show 'bx transitions when the inverters all propagate
// at the same time.
put_ostr(val, sval, false);
}
#else
resolv_functor::resolv_functor(vvp_scaler_t hiz_value)
: hiz_(hiz_value)
@ -199,15 +36,38 @@ resolv_functor::~resolv_functor()
{
}
void resolv_functor::recv_vec8(vvp_vector8_t vit)
void resolv_functor::recv_vec4(vvp_net_ptr_t port, vvp_vector4_t bit)
{
assert(0); // XXXX not implemented yet!
recv_vec8(port, vvp_vector8_t(bit, 6 /* STRONG */));
}
void resolv_functor::recv_vec8(vvp_net_ptr_t port, vvp_vector8_t bit)
{
unsigned pdx = port.port();
vvp_net_t*ptr = port.ptr();
val_[pdx] = bit;
vvp_vector8_t out (bit);
for (unsigned idx = 0 ; idx < 4 ; idx += 1) {
if (val_[idx].size() == 0)
continue;
if (idx == pdx)
continue;
out = resolve(out, val_[idx]);
}
vvp_send_vec8(ptr->out, out);
}
#endif
/*
* $Log: resolv.cc,v $
* Revision 1.19 2004/12/31 06:00:06 steve
* Implement .resolv functors, and stub signals recv_vec8 method.
*
* Revision 1.18 2004/12/11 02:31:30 steve
* Rework of internals to carry vectors through nexus instead
* of single bits. Make the ivl, tgt-vvp and vvp initial changes

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: resolv.h,v 1.9 2004/12/11 02:31:30 steve Exp $"
#ident "$Id: resolv.h,v 1.10 2004/12/31 06:00:06 steve Exp $"
#endif
# include "config.h"
@ -41,15 +41,19 @@ class resolv_functor : public vvp_net_fun_t {
explicit resolv_functor(vvp_scaler_t hiz_value);
~resolv_functor();
void recv_vec8(vvp_vector8_t bit);
void recv_vec4(vvp_net_ptr_t port, vvp_vector4_t bit);
void recv_vec8(vvp_net_ptr_t port, vvp_vector8_t bit);
private:
vvp_vector8_t driven_;
vvp_vector8_t val_[4];
vvp_scaler_t hiz_;
};
/*
* $Log: resolv.h,v $
* Revision 1.10 2004/12/31 06:00:06 steve
* Implement .resolv functors, and stub signals recv_vec8 method.
*
* Revision 1.9 2004/12/11 02:31:30 steve
* Rework of internals to carry vectors through nexus instead
* of single bits. Make the ivl, tgt-vvp and vvp initial changes

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.2 2004/12/15 17:16:08 steve Exp $"
#ident "$Id: vvp_net.cc,v 1.3 2004/12/31 06:00:06 steve Exp $"
# include "vvp_net.h"
# include <stdio.h>
@ -62,6 +62,18 @@ void vvp_send_vec4(vvp_net_ptr_t ptr, vvp_vector4_t val)
}
}
void vvp_send_vec8(vvp_net_ptr_t ptr, vvp_vector8_t val)
{
while (struct vvp_net_t*cur = ptr.ptr()) {
vvp_net_ptr_t next = cur->port[ptr.port()];
if (cur->fun)
cur->fun->recv_vec8(ptr, val);
ptr = next;
}
}
void vvp_send_real(vvp_net_ptr_t ptr, double val)
{
while (struct vvp_net_t*cur = ptr.ptr()) {
@ -190,6 +202,17 @@ void vvp_vector4_t::set_bit(unsigned idx, vvp_bit4_t val)
}
}
vvp_vector8_t::vvp_vector8_t(const vvp_vector8_t&that)
{
size_ = that.size_;
bits_ = new vvp_scaler_t[size_];
for (unsigned idx = 0 ; idx < size_ ; idx += 1)
bits_[idx] = that.bits_[idx];
}
vvp_vector8_t::vvp_vector8_t(unsigned size)
: size_(size)
{
@ -201,12 +224,63 @@ vvp_vector8_t::vvp_vector8_t(unsigned size)
bits_ = new vvp_scaler_t[size_];
}
vvp_vector8_t::vvp_vector8_t(const vvp_vector4_t&that, unsigned str)
: size_(that.size())
{
if (size_ == 0) {
bits_ = 0;
return;
}
bits_ = new vvp_scaler_t[size_];
for (unsigned idx = 0 ; idx < size_ ; idx += 1)
bits_[idx] = vvp_scaler_t (that.value(idx), str);
}
vvp_vector8_t::~vvp_vector8_t()
{
if (size_ > 0)
delete[]bits_;
}
vvp_vector8_t& vvp_vector8_t::operator= (const vvp_vector8_t&that)
{
if (size_ != that.size_) {
if (size_ > 0)
delete[]bits_;
size_ = 0;
}
if (that.size_ == 0) {
assert(size_ == 0);
return *this;
}
if (size_ == 0) {
size_ = that.size_;
bits_ = new vvp_scaler_t[size_];
}
for (unsigned idx = 0 ; idx < size_ ; idx += 1)
bits_[idx] = that.bits_[idx];
return *this;
}
vvp_scaler_t vvp_vector8_t::value(unsigned idx) const
{
assert(idx < size_);
return bits_[idx];
}
void vvp_vector8_t::set_bit(unsigned idx, vvp_scaler_t val)
{
assert(idx < size_);
bits_[idx] = val;
}
vvp_net_fun_t::vvp_net_fun_t()
{
}
@ -286,6 +360,13 @@ void vvp_fun_signal::recv_vec4(vvp_net_ptr_t ptr, vvp_vector4_t bit)
}
}
void vvp_fun_signal::recv_vec8(vvp_net_ptr_t ptr, vvp_vector8_t bit)
{
fprintf(stderr, "internal error: vvp_fun_signal "
"reducing vector8 input.\n");
recv_vec4(ptr, reduce4(bit));
}
void vvp_fun_signal::deassign()
{
continuous_assign_active_ = false;
@ -407,6 +488,21 @@ vvp_scaler_t::vvp_scaler_t()
value_ = 0;
}
vvp_bit4_t vvp_scaler_t::value() const
{
if (value_ == 0) {
return BIT4_Z;
} else switch (value_ & 0x88) {
case 0x00:
return BIT4_0;
case 0x88:
return BIT4_1;
default:
return BIT4_X;
}
}
vvp_scaler_t resolve(vvp_scaler_t a, vvp_scaler_t b)
{
// If the value is 0, that is the same as HiZ. In that case,
@ -507,8 +603,33 @@ vvp_scaler_t resolve(vvp_scaler_t a, vvp_scaler_t b)
return res;
}
vvp_vector8_t resolve(const vvp_vector8_t&a, const vvp_vector8_t&b)
{
assert(a.size() == b.size());
vvp_vector8_t out (a.size());
for (unsigned idx = 0 ; idx < out.size() ; idx += 1) {
out.set_bit(idx, resolve(a.value(idx), b.value(idx)));
}
return out;
}
vvp_vector4_t reduce4(const vvp_vector8_t&that)
{
vvp_vector4_t out (that.size());
for (unsigned idx = 0 ; idx < out.size() ; idx += 1)
out.set_bit(idx, that.value(idx).value());
return out;
}
/*
* $Log: vvp_net.cc,v $
* Revision 1.3 2004/12/31 06:00:06 steve
* Implement .resolv functors, and stub signals recv_vec8 method.
*
* Revision 1.2 2004/12/15 17:16:08 steve
* Add basic force/release capabilities.
*

View File

@ -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.3 2004/12/29 23:45:13 steve Exp $"
#ident "$Id: vvp_net.h,v 1.4 2004/12/31 06:00:06 steve Exp $"
# include <assert.h>
@ -123,11 +123,17 @@ extern vvp_scaler_t resolve(vvp_scaler_t a, vvp_scaler_t b);
* values. The 8 in the name is the number of possible distinct values
* a well defined bit may have. When you add in ambiguous values, the
* number of distinct values span the vvp_scaler_t.
*
* a vvp_vector8_t object can be created from a vvp_vector4_t and a
* strength value. The vvp_vector8_t bits have the values of the input
* vector, all with the strength specified.
*/
class vvp_vector8_t {
public:
explicit vvp_vector8_t(unsigned size =0);
// Make a vvp_vector8_t from a vector4 and a specified strength.
explicit vvp_vector8_t(const vvp_vector4_t&that, unsigned str);
~vvp_vector8_t();
@ -143,6 +149,9 @@ class vvp_vector8_t {
vvp_scaler_t*bits_;
};
extern vvp_vector8_t resolve(const vvp_vector8_t&a, const vvp_vector8_t&b);
extern vvp_vector4_t reduce4(const vvp_vector8_t&that);
/*
* This class implements a pointer that points to an item within a
* target. The ptr() method returns a pointer to the vvp_net_t, and
@ -253,7 +262,7 @@ struct vvp_net_t {
};
extern void vvp_send_vec4(vvp_net_ptr_t ptr, vvp_vector4_t val);
extern void vvp_send_vec8(vvp_net_ptr_t ptr, vvp_vector4_t val);
extern void vvp_send_vec8(vvp_net_ptr_t ptr, vvp_vector8_t val);
extern void vvp_send_real(vvp_net_ptr_t ptr, double val);
extern void vvp_send_long(vvp_net_ptr_t ptr, long val);
@ -412,6 +421,7 @@ class vvp_fun_signal : public vvp_net_fun_t {
explicit vvp_fun_signal(unsigned wid);
void recv_vec4(vvp_net_ptr_t port, vvp_vector4_t bit);
void recv_vec8(vvp_net_ptr_t port, vvp_vector8_t bit);
void recv_long(vvp_net_ptr_t port, long bit);
// Get information about the vector value.
@ -438,6 +448,9 @@ class vvp_fun_signal : public vvp_net_fun_t {
/*
* $Log: vvp_net.h,v $
* Revision 1.4 2004/12/31 06:00:06 steve
* Implement .resolv functors, and stub signals recv_vec8 method.
*
* Revision 1.3 2004/12/29 23:45:13 steve
* Add the part concatenation node (.concat).
*