Make the bufif0 and bufif1 gates strength aware,

and accurately propagate strengths of outputs.
This commit is contained in:
steve 2001-05-31 04:12:43 +00:00
parent 19251f7a79
commit 1e9184f0f9
9 changed files with 287 additions and 35 deletions

View File

@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
#ident "$Id: Makefile.in,v 1.20 2001/05/20 15:09:40 steve Exp $"
#ident "$Id: Makefile.in,v 1.21 2001/05/31 04:12:43 steve Exp $"
#
#
SHELL = /bin/sh
@ -62,7 +62,7 @@ V = vpi_modules.o vpi_const.o vpi_iter.o vpi_mcd.o vpi_priv.o \
vpi_scope.o vpi_signal.o vpi_tasks.o vpi_time.o vpi_memory.o \
vpi_vthr_vector.o
O = main.o parse.o parse_misc.o lexor.o compile.o debug.o functor.o \
O = main.o parse.o parse_misc.o lexor.o bufif.o compile.o debug.o functor.o \
resolv.o symbols.o codes.o vthread.o schedule.o tables.o udp.o memory.o $V
vvp: $O

148
vvp/bufif.cc Normal file
View File

@ -0,0 +1,148 @@
/*
* Copyright (c) 2001 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
* 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
*/
#if !defined(WINNT)
#ident "$Id: bufif.cc,v 1.1 2001/05/31 04:12:43 steve Exp $"
#endif
# include "bufif.h"
# include "functor.h"
# include "schedule.h"
void vvp_bufif0_s::set(vvp_ipoint_t ptr, functor_t fp, bool push)
{
unsigned in0 = fp->ival & 0x03;
unsigned in1 = (fp->ival >> 2) & 0x03;
unsigned char out0 = 0x00 | (fp->odrive0<<0) | (fp->odrive0<<4);
unsigned char out1 = 0x88 | (fp->odrive1<<0) | (fp->odrive1<<4);
unsigned char outX = 0x80 | (fp->odrive1<<0) | (fp->odrive0<<4);
unsigned char outH = 0x88 | (fp->odrive1<<4) | (0);
unsigned char outL = 0x00 | (fp->odrive1<<0) | (0);
switch (in1) {
case 0:
switch (in0) {
case 0:
fp->oval = 0;
fp->ostr = out0;
break;
case 1:
fp->oval = 1;
fp->ostr = out1;
break;
default:
fp->oval = 2;
fp->ostr = outX;
break;
}
break;
case 1:
fp->oval = 3;
fp->ostr = HiZ;
break;
default:
fp->oval = 2;
switch (in0) {
case 0:
fp->ostr = outL;
break;
case 1:
fp->ostr = outH;
break;
default:
fp->ostr = outX;
break;
}
break;
}
if (push)
functor_propagate(ptr);
else
schedule_functor(ptr, 0);
}
void vvp_bufif1_s::set(vvp_ipoint_t ptr, functor_t fp, bool push)
{
unsigned in0 = fp->ival & 0x03;
unsigned in1 = (fp->ival >> 2) & 0x03;
unsigned char out0 = 0x00 | (fp->odrive0<<0) | (fp->odrive0<<4);
unsigned char out1 = 0x88 | (fp->odrive1<<0) | (fp->odrive1<<4);
unsigned char outX = 0x80 | (fp->odrive1<<0) | (fp->odrive0<<4);
unsigned char outH = 0x88 | (fp->odrive1<<4) | (0);
unsigned char outL = 0x00 | (fp->odrive1<<0) | (0);
switch (in1) {
case 1:
switch (in0) {
case 0:
fp->oval = 0;
fp->ostr = out0;
break;
case 1:
fp->oval = 1;
fp->ostr = out1;
break;
default:
fp->oval = 2;
fp->ostr = outX;
break;
}
break;
case 0:
fp->oval = 3;
fp->ostr = HiZ;
break;
default:
fp->oval = 2;
switch (in0) {
case 0:
fp->ostr = outL;
break;
case 1:
fp->ostr = outH;
break;
default:
fp->ostr = outX;
break;
}
break;
}
if (push)
functor_propagate(ptr);
else
schedule_functor(ptr, 0);
}
/*
* $Log: bufif.cc,v $
* Revision 1.1 2001/05/31 04:12:43 steve
* Make the bufif0 and bufif1 gates strength aware,
* and accurately propagate strengths of outputs.
*
*/

50
vvp/bufif.h Normal file
View File

@ -0,0 +1,50 @@
#ifndef __bufif_H
#define __bufif_H
/*
* Copyright (c) 2001 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
* 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
*/
#if !defined(WINNT)
#ident "$Id: bufif.h,v 1.1 2001/05/31 04:12:43 steve Exp $"
#endif
# include "functor.h"
class vvp_bufif0_s : public vvp_fobj_s {
public:
virtual void set(vvp_ipoint_t i, functor_t f, bool push);
private: // not implemented
};
class vvp_bufif1_s : public vvp_fobj_s {
public:
virtual void set(vvp_ipoint_t i, functor_t f, bool push);
private: // not implemented
};
/*
* $Log: bufif.h,v $
* Revision 1.1 2001/05/31 04:12:43 steve
* Make the bufif0 and bufif1 gates strength aware,
* and accurately propagate strengths of outputs.
*
*/
#endif

View File

@ -17,9 +17,10 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: compile.cc,v 1.69 2001/05/30 03:02:35 steve Exp $"
#ident "$Id: compile.cc,v 1.70 2001/05/31 04:12:43 steve Exp $"
#endif
# include "bufif.h"
# include "compile.h"
# include "functor.h"
# include "resolv.h"
@ -355,10 +356,12 @@ void compile_functor(char*label, char*type, unsigned argc, struct symb_s*argv)
obj->table = ft_BUF;
} else if (strcmp(type, "BUFIF0") == 0) {
obj->table = ft_BUFIF0;
obj->obj = new vvp_bufif0_s;
obj->mode = M42;
} else if (strcmp(type, "BUFIF1") == 0) {
obj->table = ft_BUFIF1;
obj->obj = new vvp_bufif1_s;
obj->mode = M42;
} else if (strcmp(type, "MUXZ") == 0) {
obj->table = ft_MUXZ;
@ -1207,6 +1210,10 @@ vvp_ipoint_t debug_lookup_functor(const char*name)
/*
* $Log: compile.cc,v $
* Revision 1.70 2001/05/31 04:12:43 steve
* Make the bufif0 and bufif1 gates strength aware,
* and accurately propagate strengths of outputs.
*
* Revision 1.69 2001/05/30 03:02:35 steve
* Propagate strength-values instead of drive strengths.
*

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.3 2001/05/30 03:02:35 steve Exp $"
#ident "$Id: debug.cc,v 1.4 2001/05/31 04:12:43 steve Exp $"
#endif
/*
@ -97,7 +97,7 @@ static void cmd_functor(unsigned argc, char*argv[])
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*/);
bitval_tab[fp->oval], fp->ostr);
}
}
@ -167,6 +167,10 @@ void breakpoint(void)
#endif
/*
* $Log: debug.cc,v $
* Revision 1.4 2001/05/31 04:12:43 steve
* Make the bufif0 and bufif1 gates strength aware,
* and accurately propagate strengths of outputs.
*
* Revision 1.3 2001/05/30 03:02:35 steve
* Propagate strength-values instead of drive strengths.
*

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.21 2001/05/30 03:02:35 steve Exp $"
#ident "$Id: functor.cc,v 1.22 2001/05/31 04:12:43 steve Exp $"
#endif
# include "functor.h"
@ -155,6 +155,22 @@ static void functor_set_mode0(vvp_ipoint_t ptr, functor_t fp, bool push)
/* If the output changes, then create a propagation event. */
if (out != fp->oval) {
fp->oval = out;
switch (out) {
case 0:
fp->ostr = 0x00 | (fp->odrive0<<0) | (fp->odrive0<<4);
break;
case 1:
fp->ostr = 0x88 | (fp->odrive1<<0) | (fp->odrive1<<4);
break;
case 2:
fp->ostr = 0x80 | (fp->odrive0<<0) | (fp->odrive1<<4);
break;
case 3:
fp->ostr = 0x00;
break;
}
if (push)
functor_propagate(ptr);
else
@ -305,31 +321,14 @@ void functor_propagate(vvp_ipoint_t ptr)
{
functor_t fp = functor_index(ptr);
unsigned char oval = fp->oval;
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;
}
unsigned char ostr = fp->ostr;
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, str, false);
functor_set(idx, oval, ostr, false);
idx = next;
}
}
@ -360,6 +359,10 @@ const unsigned char ft_var[16] = {
/*
* $Log: functor.cc,v $
* Revision 1.22 2001/05/31 04:12:43 steve
* Make the bufif0 and bufif1 gates strength aware,
* and accurately propagate strengths of outputs.
*
* Revision 1.21 2001/05/30 03:02:35 steve
* Propagate strength-values instead of drive 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.23 2001/05/30 03:02:35 steve Exp $"
#ident "$Id: functor.h,v 1.24 2001/05/31 04:12:43 steve Exp $"
#endif
# include "pointers.h"
@ -100,6 +100,9 @@
* STRONG = 6,
* SUPPLY = 7
*
* The output value (oval) is combined with the drive specifications
* to make a fully strength aware output, as described below.
*
* OUTPUT STRENGTHS:
*
* The strength-aware outputs are specified as an 8 bit value, that is
@ -108,6 +111,11 @@
* 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.
*
* The functor calculates, when it operates, a 4-value output into
* oval and a fully strength aware value into ostr. The mode-0
* functors use the odrive0 and odrive1 fields to form the strength
* value.
*/
struct functor_s {
@ -130,13 +138,16 @@ struct functor_s {
unsigned oval : 2;
unsigned odrive0 : 3;
unsigned odrive1 : 3;
/* Strength form of the output value. */
unsigned ostr : 8;
#if defined(WITH_DEBUG)
/* True if this functor triggers a breakpoint. */
unsigned breakpoint : 1;
#endif
/* functor mode: 0 == table ; 1 == event ; 2 == named event */
unsigned char mode;
unsigned mode : 2;
union {
unsigned char old_ival; // mode 3
};
@ -173,7 +184,7 @@ enum strength_e {
* it happens when it happens.
*/
#define M42 42
#define M42 3
struct vvp_fobj_s {
virtual unsigned get(vvp_ipoint_t i, functor_t f);
@ -282,6 +293,10 @@ extern const unsigned char ft_var[];
/*
* $Log: functor.h,v $
* Revision 1.24 2001/05/31 04:12:43 steve
* Make the bufif0 and bufif1 gates strength aware,
* and accurately propagate strengths of outputs.
*
* Revision 1.23 2001/05/30 03:02:35 steve
* Propagate strength-values instead of drive strengths.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: resolv.cc,v 1.3 2001/05/30 03:02:35 steve Exp $"
#ident "$Id: resolv.cc,v 1.4 2001/05/31 04:12:43 steve Exp $"
#endif
# include "resolv.h"
@ -118,9 +118,9 @@ static unsigned blend(unsigned a, unsigned b)
}
/*
* For now, cheat and resolve the values without using the actual
* strengths. The strengths are not yet available to the inputs, so
* this is all we can do for now.
* 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 vvp_resolv_s::set(vvp_ipoint_t ptr, functor_t fp, bool push)
{
@ -146,6 +146,8 @@ void vvp_resolv_s::set(vvp_ipoint_t ptr, functor_t fp, bool push)
break;
}
fp->ostr = val;
/* If the output changes, then create a propagation event. */
if (oval != fp->oval) {
fp->oval = oval;
@ -158,6 +160,10 @@ void vvp_resolv_s::set(vvp_ipoint_t ptr, functor_t fp, bool push)
/*
* $Log: resolv.cc,v $
* Revision 1.4 2001/05/31 04:12:43 steve
* Make the bufif0 and bufif1 gates strength aware,
* and accurately propagate strengths of outputs.
*
* Revision 1.3 2001/05/30 03:02:35 steve
* Propagate strength-values instead of drive strengths.
*

View File

@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: udp.cc,v 1.4 2001/05/06 03:51:37 steve Exp $"
#ident "$Id: udp.cc,v 1.5 2001/05/31 04:12:43 steve Exp $"
#endif
#include "udp.h"
@ -33,6 +33,21 @@ void vvp_udp_s::set(vvp_ipoint_t ptr, functor_t fp, bool)
{
unsigned char out = propagate_(ptr);
switch (out) {
case 0:
fp->ostr = 0x00 | (fp->odrive0<<0) | (fp->odrive0<<4);
break;
case 1:
fp->ostr = 0x88 | (fp->odrive1<<0) | (fp->odrive1<<4);
break;
case 2:
fp->ostr = 0x80 | (fp->odrive0<<0) | (fp->odrive1<<4);
break;
case 3:
fp->ostr = 0x00;
break;
}
if (out != fp->oval)
{
fp->oval = out;
@ -208,6 +223,10 @@ unsigned char vvp_udp_s::propagate_(vvp_ipoint_t uix)
/*
* $Log: udp.cc,v $
* Revision 1.5 2001/05/31 04:12:43 steve
* Make the bufif0 and bufif1 gates strength aware,
* and accurately propagate strengths of outputs.
*
* Revision 1.4 2001/05/06 03:51:37 steve
* Regularize the mode-42 functor handling.
*