Propagate strength-values instead of drive strengths.

This commit is contained in:
steve 2001-05-30 03:02:35 +00:00
parent b79da2c4d6
commit 19251f7a79
8 changed files with 225 additions and 164 deletions

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: compile.cc,v 1.68 2001/05/24 04:20:10 steve Exp $"
#ident "$Id: compile.cc,v 1.69 2001/05/30 03:02:35 steve Exp $"
#endif
# include "compile.h"
@ -271,37 +271,37 @@ static void inputs_connect(vvp_ipoint_t fdx, unsigned argc, struct symb_s*argv)
if (strcmp(argv[idx].text, "C<0>") == 0) {
free(argv[idx].text);
functor_put_input(iobj, idx, 0, 6, 6);
functor_put_input(iobj, idx, 0, St0);
continue;
}
if (strcmp(argv[idx].text, "C<pu0>") == 0) {
free(argv[idx].text);
functor_put_input(iobj, idx, 0, 5, 5);
functor_put_input(iobj, idx, 0, Pu0);
continue;
}
if (strcmp(argv[idx].text, "C<1>") == 0) {
free(argv[idx].text);
functor_put_input(iobj, idx, 1, 6, 6);
functor_put_input(iobj, idx, 1, St1);
continue;
}
if (strcmp(argv[idx].text, "C<pu1>") == 0) {
free(argv[idx].text);
functor_put_input(iobj, idx, 1, 5, 5);
functor_put_input(iobj, idx, 1, Pu1);
continue;
}
if (strcmp(argv[idx].text, "C<x>") == 0) {
free(argv[idx].text);
functor_put_input(iobj, idx, 2, 6, 6);
functor_put_input(iobj, idx, 2, StX);
continue;
}
if (strcmp(argv[idx].text, "C<z>") == 0) {
free(argv[idx].text);
functor_put_input(iobj, idx, 3, 6, 6);
functor_put_input(iobj, idx, 3, HiZ);
continue;
}
@ -1207,6 +1207,9 @@ vvp_ipoint_t debug_lookup_functor(const char*name)
/*
* $Log: compile.cc,v $
* Revision 1.69 2001/05/30 03:02:35 steve
* Propagate strength-values instead of drive strengths.
*
* Revision 1.68 2001/05/24 04:20:10 steve
* Add behavioral modulus.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: debug.cc,v 1.2 2001/05/08 23:32:26 steve Exp $"
#ident "$Id: debug.cc,v 1.3 2001/05/30 03:02:35 steve Exp $"
#endif
/*
@ -91,15 +91,13 @@ static void cmd_functor(unsigned argc, char*argv[])
}
printf("out pointer = 0x%x\n", fp->out);
printf("input values = %c %c %c %c\n",
bitval_tab[fp->ival&3],
bitval_tab[(fp->ival>>2)&3],
bitval_tab[(fp->ival>>4)&3],
bitval_tab[(fp->ival>>6)&3]);
printf("out value = %c (%s0 %s1)\n",
bitval_tab[fp->oval],
strength_tab[fp->odrive0],
strength_tab[fp->odrive1]);
printf("input values = %c (%02x) %c (%02x) %c (%02x) %c (%02x)\n",
bitval_tab[fp->ival&3], fp->istr[0],
bitval_tab[(fp->ival>>2)&3], fp->istr[1],
bitval_tab[(fp->ival>>4)&3], fp->istr[2],
bitval_tab[(fp->ival>>6)&3], fp->istr[3]);
printf("out value = %c (%02x)\n",
bitval_tab[fp->oval], 0 /*xxxx*/);
}
}
@ -169,6 +167,9 @@ void breakpoint(void)
#endif
/*
* $Log: debug.cc,v $
* Revision 1.3 2001/05/30 03:02:35 steve
* Propagate strength-values instead of drive strengths.
*
* Revision 1.2 2001/05/08 23:32:26 steve
* Add to the debugger the ability to view and
* break on functors.

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: functor.cc,v 1.20 2001/05/12 20:38:06 steve Exp $"
#ident "$Id: functor.cc,v 1.21 2001/05/30 03:02:35 steve Exp $"
#endif
# include "functor.h"
@ -134,21 +134,15 @@ functor_t functor_index(vvp_ipoint_t point)
return functor_table[point]->table[index1]->table + index0;
}
void functor_put_input(functor_t fp, unsigned pp, unsigned val,
unsigned drive0, unsigned drive1)
void functor_put_input(functor_t fp, unsigned pp, unsigned val, unsigned str)
{
/* Change the bits of the input. */
static const unsigned char ival_mask[4] = { 0xfc, 0xf3, 0xcf, 0x3f };
unsigned char imask = ival_mask[pp];
fp->ival = (fp->ival & imask) | ((val & 3) << (2*pp));
/* change the bits of the drive. */
static const unsigned drive_mask[4] = { 0xffffc0, 0xfff03f,
0xfc0fff, 0x03ffff };
unsigned dmask = drive_mask[pp];
fp->idrive = (fp->idrive & dmask)
| (drive1 << (3+6*pp))
| (drive0 << 6*pp);
/* Save the strength aware input value. */
fp->istr[pp] = str;
}
static void functor_set_mode0(vvp_ipoint_t ptr, functor_t fp, bool push)
@ -251,19 +245,14 @@ static void functor_set_mode2(functor_t fp)
* output. If the output changes any, then generate the necessary
* propagation events to pass the output on.
*/
void functor_set(vvp_ipoint_t ptr, unsigned bit,
unsigned drive0, unsigned drive1,
bool push)
void functor_set(vvp_ipoint_t ptr, unsigned bit, unsigned str, bool push)
{
functor_t fp = functor_index(ptr);
unsigned pp = ipoint_port(ptr);
assert(fp);
assert(drive0 <= 8);
assert(drive1 <= 8);
/* Store the value and strengths in the input bits. */
functor_put_input(fp, pp, bit, drive0, drive1);
functor_put_input(fp, pp, bit, str);
switch (fp->mode) {
case 0:
@ -319,11 +308,28 @@ void functor_propagate(vvp_ipoint_t ptr)
unsigned drive0 = fp->odrive0;
unsigned drive1 = fp->odrive1;
unsigned str;
switch (oval) {
case 0:
str = 0x00 | (drive0<<0) | (drive0<<4);
break;
case 1:
str = 0x88 | (drive1<<0) | (drive1<<4);
break;
case 2:
str = 0x80 | (drive0<<0) | (drive1<<4);
break;
case 3:
str = 0x00;
break;
}
vvp_ipoint_t idx = fp->out;
while (idx) {
functor_t idxp = functor_index(idx);
vvp_ipoint_t next = idxp->port[ipoint_port(idx)];
functor_set(idx, oval, drive0, drive1);
functor_set(idx, oval, str, false);
idx = next;
}
}
@ -354,6 +360,9 @@ const unsigned char ft_var[16] = {
/*
* $Log: functor.cc,v $
* Revision 1.21 2001/05/30 03:02:35 steve
* Propagate strength-values instead of drive strengths.
*
* Revision 1.20 2001/05/12 20:38:06 steve
* A resolver that understands some simple strengths.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: functor.h,v 1.22 2001/05/12 20:38:06 steve Exp $"
#ident "$Id: functor.h,v 1.23 2001/05/30 03:02:35 steve Exp $"
#endif
# include "pointers.h"
@ -83,14 +83,14 @@
* methods for receiving and retrieving values. See the vvp_fobj_s
* definition below.
*
* STRENGTHS:
* DRIVE STRENGTHS:
*
* The normal functor (modes 0, 1 and 2) is not aware of strengths. It
* generates strength simply by virtue of having strength
* specifications.
* specifications. The drive strength specification includes a drive0
* and drive1 strength, each with 8 possible values (that can be
* represented in 3 bits) as given in this table:
*
* When the bit value is read out of the functor, only the val bits
* are read. There are 8 drive values available in the 3 bits:
* HiZ = 0,
* SMALL = 1,
* MEDIUM = 2,
@ -100,7 +100,14 @@
* STRONG = 6,
* SUPPLY = 7
*
* Only mode-42 functors are strength-aware.
* OUTPUT STRENGTHS:
*
* The strength-aware outputs are specified as an 8 bit value, that is
* two 4 bit numbers. The value is encoded with two drive strengths (0-7)
* and two drive values (0 or 1). Each nibble contains three bits of
* strength and one bit of value, like so: VSSS. The high nible has
* the strength-value closest to supply1, and the low nibble has the
* strength-value closest to supply0.
*/
struct functor_s {
@ -115,11 +122,11 @@ struct functor_s {
vvp_ipoint_t out;
/* These are the input ports. */
vvp_ipoint_t port[4];
/* These are the input values. */
/* Input with strengths, for strength aware functors. */
unsigned char istr[4];
/* Input values without strengths. */
unsigned ival : 8;
/* Input strengths, for strength aware functors. */
unsigned idrive : 4*6;
/* Output value (low bits, and drive1 and drive0 strength. */
/* Output value (low bits) and drive1 and drive0 strength. */
unsigned oval : 2;
unsigned odrive0 : 3;
unsigned odrive1 : 3;
@ -137,6 +144,15 @@ struct functor_s {
typedef struct functor_s *functor_t;
enum strength_e {
HiZ = 0x00,
St0 = 0x66, /* St0-St0 */
Pu0 = 0x55, /* Pu0-Pu0 */
St1 = 0x66|0x88, /* St1 - St1 */
Pu1 = 0x55|0x88, /* Pu1 - Pu1 */
StX = 0x66|0x80, /* St0 - St1 */
};
/*
* This a an `obj' structute for mode-42 functors.
* Each instance implements the get and set methods in a type specific
@ -200,9 +216,12 @@ extern vvp_ipoint_t functor_allocate(unsigned wid);
* This function is used by the compile time to initialize the value
* of an input, and by the run time to manipulate the bits of the
* input in a uniform manner.
*
* The val parameter is the 2bit representation of the input value,
* and the str is a strength aware version.
*/
extern void functor_put_input(functor_t fp, unsigned pp, unsigned val,
unsigned drive0, unsigned drive1);
extern void functor_put_input(functor_t fp, unsigned pp,
unsigned val, unsigned str);
/*
* functor_set sets the addressed input to the specified value, and
@ -210,13 +229,12 @@ extern void functor_put_input(functor_t fp, unsigned pp, unsigned val,
* propagation events are created. Propagation calls further
* functor_set methods for the functors connected to the output.
*
* The val contains 2 bits two represent the 4-value bit. The drive0
* and drive1 values are also passed, and typically just stored in the
* The val contains 2 bits two represent the 4-value bit. The str
* version is also passed, and typically just stored in the
* functor.
*/
extern void functor_set(vvp_ipoint_t point, unsigned val,
unsigned drive0, unsigned drive1,
bool push=false);
unsigned str, bool push);
/*
* Read the value of the functor. In fact, only the *value* is read --
@ -264,6 +282,9 @@ extern const unsigned char ft_var[];
/*
* $Log: functor.h,v $
* Revision 1.23 2001/05/30 03:02:35 steve
* Propagate strength-values instead of drive strengths.
*
* Revision 1.22 2001/05/12 20:38:06 steve
* A resolver that understands some simple strengths.
*

View File

@ -17,104 +17,104 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: resolv.cc,v 1.2 2001/05/12 20:38:06 steve Exp $"
#ident "$Id: resolv.cc,v 1.3 2001/05/30 03:02:35 steve Exp $"
#endif
# include "resolv.h"
# include "schedule.h"
static void blend(unsigned&val, unsigned&drv0, unsigned drv1,
unsigned inp, unsigned inp0, unsigned inp1)
/*
* 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)) )
static unsigned blend(unsigned a, unsigned b)
{
switch (val) {
case 3:
val = inp;
drv0 = inp0;
drv1 = inp1;
break;
if (a == HiZ)
return b;
case 0:
switch (inp) {
case 0:
if (drv0 < inp0)
drv0 = inp0;
break;
if (b == HiZ)
return a;
case 1:
if (drv0 < inp1) {
val = 1;
drv1 = inp1;
}
break;
unsigned res = a;
case 2:
if (drv0 < inp1) {
val = 2;
if (drv0 < inp0)
drv0 = inp0;
if (drv1 < inp1)
drv0 = inp1;
}
break;
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. */
}
break;
case 1:
switch (inp) {
case 0:
if (drv1 < inp0) {
val = 0;
drv1 = inp1;
}
break;
} else if (UNAMBIG(res) || UNAMBIG(b)) {
case 1:
if (drv1 < inp1) {
drv1 = inp1;
}
break;
/* 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. */
case 2:
if (drv1 < inp0) {
val = 2;
if (drv0 < inp0)
drv0 = inp0;
if (drv1 < inp1)
drv0 = inp1;
}
break;
}
break;
unsigned tmp = 0;
if ((res&0x70) > (b&0x70))
tmp |= res&0xf0;
else
tmp |= b&0xf0;
case 2:
switch (inp) {
case 0:
if (drv1 < inp0) {
val = 0;
drv0 = inp0;
drv1 = inp1;
}
break;
if ((res&0x07) > (b&0x07))
tmp |= res&0x0f;
else
tmp |= b&0x0f;
case 1:
if (drv0 < inp1) {
val = 1;
drv0 = inp0;
drv1 = inp1;
}
break;
res = tmp;
case 2:
if (drv0 < inp0)
drv0 = inp0;
if (drv1 < inp1)
drv0 = inp1;
break;
}
break;
} 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;
}
/* Cannonicalize the HiZ value. */
if ((res&0x77) == 0)
res = HiZ;
return res;
}
/*
@ -124,31 +124,31 @@ static void blend(unsigned&val, unsigned&drv0, unsigned drv1,
*/
void vvp_resolv_s::set(vvp_ipoint_t ptr, functor_t fp, bool push)
{
unsigned val = (fp->ival >> 0) & 3;
unsigned drv0 = (fp->idrive >> 0) & 7;
unsigned drv1 = (fp->idrive >> 3) & 7;
unsigned val = fp->istr[0];
blend(val, drv0, drv1,
(fp->ival >> 2) & 3,
(fp->idrive >> 6) & 7,
(fp->idrive >> 9) & 7);
val = blend(val, fp->istr[1]);
val = blend(val, fp->istr[2]);
val = blend(val, fp->istr[3]);
blend(val, drv0, drv1,
(fp->ival >> 4) & 3,
(fp->idrive >>12) & 7,
(fp->idrive >>15) & 7);
unsigned oval;
if (val == HiZ) {
oval = 3;
blend(val, drv0, drv1,
(fp->ival >> 6) & 3,
(fp->idrive >>18) & 7,
(fp->idrive >>21) & 7);
fp->odrive0 = drv0;
fp->odrive1 = drv1;
} else switch (val & 0x88) {
case 0x00:
oval = 0;
break;
case 0x88:
oval = 1;
break;
default:
oval = 2;
break;
}
/* If the output changes, then create a propagation event. */
if (val != fp->oval) {
fp->oval = val;
if (oval != fp->oval) {
fp->oval = oval;
if (push)
functor_propagate(ptr);
else
@ -158,6 +158,9 @@ void vvp_resolv_s::set(vvp_ipoint_t ptr, functor_t fp, bool push)
/*
* $Log: resolv.cc,v $
* Revision 1.3 2001/05/30 03:02:35 steve
* Propagate strength-values instead of drive strengths.
*
* Revision 1.2 2001/05/12 20:38:06 steve
* A resolver that understands some simple strengths.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: schedule.cc,v 1.9 2001/05/08 23:32:26 steve Exp $"
#ident "$Id: schedule.cc,v 1.10 2001/05/30 03:02:35 steve Exp $"
#endif
# include "schedule.h"
@ -255,7 +255,20 @@ void schedule_simulate(void)
break;
case TYPE_ASSIGN:
functor_set(cur->fun, cur->val, 6, 6);
switch (cur->val) {
case 0:
functor_set(cur->fun, cur->val, St0, false);
break;
case 1:
functor_set(cur->fun, cur->val, St1, false);
break;
case 2:
functor_set(cur->fun, cur->val, StX, false);
break;
case 3:
functor_set(cur->fun, cur->val, HiZ, false);
break;
}
break;
case TYPE_GEN:
@ -271,6 +284,9 @@ void schedule_simulate(void)
/*
* $Log: schedule.cc,v $
* Revision 1.10 2001/05/30 03:02:35 steve
* Propagate strength-values instead of drive strengths.
*
* Revision 1.9 2001/05/08 23:32:26 steve
* Add to the debugger the ability to view and
* break on functors.

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: vpi_signal.cc,v 1.14 2001/05/22 04:08:49 steve Exp $"
#ident "$Id: vpi_signal.cc,v 1.15 2001/05/30 03:02:35 steve Exp $"
#endif
/*
@ -301,7 +301,7 @@ static vpiHandle signal_put_value(vpiHandle ref, s_vpi_value*vp,
long val = vp->value.integer;
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
functor_set(ipoint_index(rfp->bits,idx), val&1,
6, 6, true);
(val&1)? St1 : St0, true);
val >>= 1;
}
break;
@ -310,16 +310,16 @@ static vpiHandle signal_put_value(vpiHandle ref, s_vpi_value*vp,
case vpiScalarVal:
switch (vp->value.scalar) {
case vpi0:
functor_set(rfp->bits, 0, 6, 6, true);
functor_set(rfp->bits, 0, St0, true);
break;
case vpi1:
functor_set(rfp->bits, 1, 6, 6, true);
functor_set(rfp->bits, 1, St1, true);
break;
case vpiX:
functor_set(rfp->bits, 2, 6, 6, true);
functor_set(rfp->bits, 2, StX, true);
break;
case vpiZ:
functor_set(rfp->bits, 3, 6, 6, true);
functor_set(rfp->bits, 3, HiZ, true);
break;
default:
assert(0);
@ -336,19 +336,19 @@ static vpiHandle signal_put_value(vpiHandle ref, s_vpi_value*vp,
switch (bit) {
case 0: /* zero */
functor_set(ipoint_index(rfp->bits,idx),
0, 6, 6, true);
0, St0, true);
break;
case 1: /* one */
functor_set(ipoint_index(rfp->bits,idx),
1, 6, 6, true);
1, St1, true);
break;
case 2: /* z */
functor_set(ipoint_index(rfp->bits,idx),
3, 6, 6, true);
3, HiZ, true);
break;
case 3: /* x */
functor_set(ipoint_index(rfp->bits,idx),
2, 6, 6, true);
2, StX, true);
break;
}
aval >>= 1;
@ -432,6 +432,9 @@ vpiHandle vpip_make_net(char*name, int msb, int lsb, bool signed_flag,
/*
* $Log: vpi_signal.cc,v $
* Revision 1.15 2001/05/30 03:02:35 steve
* Propagate strength-values instead of drive strengths.
*
* Revision 1.14 2001/05/22 04:08:49 steve
* correctly interpret signed decimal values.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: vthread.cc,v 1.41 2001/05/24 04:20:10 steve Exp $"
#ident "$Id: vthread.cc,v 1.42 2001/05/30 03:02:35 steve Exp $"
#endif
# include "vthread.h"
@ -879,10 +879,12 @@ bool of_OR(vthread_t thr, vvp_code_t cp)
return true;
}
static const unsigned char strong_values[4] = {St0, St1, StX, HiZ};
bool of_SET(vthread_t thr, vvp_code_t cp)
{
unsigned char bit_val = thr_get_bit(thr, cp->bit_idx1);
functor_set(cp->iptr, bit_val, 6, 6, true);
functor_set(cp->iptr, bit_val, strong_values[bit_val], true);
return true;
}
@ -1045,6 +1047,9 @@ bool of_ZOMBIE(vthread_t thr, vvp_code_t)
/*
* $Log: vthread.cc,v $
* Revision 1.42 2001/05/30 03:02:35 steve
* Propagate strength-values instead of drive strengths.
*
* Revision 1.41 2001/05/24 04:20:10 steve
* Add behavioral modulus.
*