Permalink
Browse files

Runtime support for functor delays. (Stephan Boettcher)

  • Loading branch information...
1 parent 4d0b840 commit 4a74ae17958f7250e22c0ac888d9fbf5f426ed24 steve committed Nov 10, 2001
Showing with 413 additions and 26 deletions.
  1. +2 −2 vvp/Makefile.in
  2. +253 −0 vvp/delay.cc
  3. +120 −0 vvp/delay.h
  4. +5 −1 vvp/functor.cc
  5. +33 −23 vvp/functor.h
View
4 vvp/Makefile.in
@@ -16,7 +16,7 @@
# 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA
#
-#ident "$Id: Makefile.in,v 1.31 2001/11/06 03:07:21 steve Exp $"
+#ident "$Id: Makefile.in,v 1.32 2001/11/10 18:07:11 steve Exp $"
#
#
SHELL = /bin/sh
@@ -65,7 +65,7 @@ vpi_vthr_vector.o vvp_vpi.o
O = main.o parse.o parse_misc.o lexor.o arith.o bufif.o compile.o debug.o \
functor.o fvectors.o npmos.o resolv.o symbols.o codes.o vthread.o schedule.o \
-tables.o udp.o memory.o force.o event.o logic.o $V
+tables.o udp.o memory.o force.o event.o logic.o delay.o $V
vvp: $O
$(CXX) $(rdynamic) $(CXXFLAGS) $(LDFLAGS) -o vvp $O $(LIBS) $(dllib)
View
253 vvp/delay.cc
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2001 Stephan Boettcher <stephan@nevis.columbia.edu>
+ *
+ * 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: delay.cc,v 1.1 2001/11/10 18:07:11 steve Exp $"
+#endif
+
+#include "delay.h"
+#include <string.h>
+#include <assert.h>
+
+inline static unsigned dmin(unsigned d1, unsigned d2)
+{
+ return (d1 < d2) ? d1 : d2;
+}
+
+inline static unsigned dmax(unsigned d1, unsigned d2)
+{
+ return (d1 > d2) ? d1 : d2;
+}
+
+typedef const unsigned char tab_t;
+// 01 0x 0z 10 1x 1z x0 x1 xz z0 z1 zx
+static tab_t tab_1 [16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+static tab_t tab_4 [16] = { 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 3, 2, 1, 0, 3, 2};
+static tab_t tab_6 [16] = { 1, 0, 3, 2, 1, 0, 4, 2, 1, 0, 5, 2, 1, 0, 5, 2};
+static tab_t tab_12[16] = { 1, 0, 6, 2, 1, 0, 8, 4, 9, 7,11,10, 5, 3,11,10};
+
+inline unsigned vvp_delay_size(vvp_delay_t del)
+{
+ return del ? del->size() : 0;
+}
+
+inline vvp_delay_s::vvp_delay_s(const unsigned char *t)
+{
+ memcpy((void*)tab, (void*)t, sizeof(tab));
+}
+
+vvp_delay_s::vvp_delay_s(unsigned d)
+{
+ memcpy((void*)tab, (void*)tab_1, sizeof(tab));
+ del[0] = d;
+}
+vvp_delay_2_s::vvp_delay_2_s(unsigned r, unsigned f)
+ : vvp_delay_s(tab_4)
+{
+ del[0] = r;
+ del[1] = f;
+ del[2] = dmax(r, f);
+ del[3] = dmin(r, f);
+}
+
+vvp_delay_3_s::vvp_delay_3_s(unsigned r, unsigned f, unsigned z)
+ : vvp_delay_s(tab_6)
+{
+ del[0] = r;
+ del[1] = f;
+ del[2] = z;
+ del[3] = dmin(r, z);
+ del[4] = dmin(f, z);
+ del[5] = dmin(r, f);
+}
+
+vvp_delay_6_s::vvp_delay_6_s(unsigned r, unsigned f, unsigned rz,
+ unsigned zr, unsigned fz, unsigned zf)
+ : vvp_delay_12_s(r, f, rz, zr, fz, zf,
+ dmin(r, rz),
+ dmax(r, zr),
+ dmin(f, fz),
+ dmax(f, zf),
+ dmax(rz, fz),
+ dmin(zr, zf))
+{}
+
+vvp_delay_12_s::vvp_delay_12_s(unsigned r, unsigned f, unsigned rz,
+ unsigned zr, unsigned fz, unsigned zf,
+ unsigned rx, unsigned xr, unsigned fx,
+ unsigned xf, unsigned xz, unsigned zx)
+ : vvp_delay_s(tab_12)
+{
+ del[0] = r;
+ del[1] = f;
+ del[2] = rz;
+ del[3] = zr;
+ del[4] = fz;
+ del[5] = zf;
+ del[6] = rx;
+ del[7] = xr;
+ del[8] = fx;
+ del[9] = xf;
+ del[10] = xz;
+ del[11] = zx;
+}
+
+vvp_delay_t vvp_delay_new(unsigned n, unsigned *dels)
+{
+ switch (n) {
+ default:
+ assert(0);
+ case 0:
+ return 0;
+ case 1:
+ return new vvp_delay_s(dels[0]);
+ case 2:
+ return new vvp_delay_2_s(dels[0], dels[1]);
+ case 3:
+ return new vvp_delay_3_s(dels[0], dels[1], dels[2]);
+ case 6:
+ return new vvp_delay_6_s(dels[0], dels[1], dels[2],
+ dels[3], dels[4], dels[5]);
+ case 12:
+ return new vvp_delay_12_s(dels[0], dels[1], dels[2],
+ dels[3], dels[4], dels[5],
+ dels[6], dels[7], dels[8],
+ dels[9], dels[10], dels[11]);
+ }
+}
+
+void vvp_delay_delete(vvp_delay_t del)
+{
+ switch (vvp_delay_size(del)) {
+ case 1: delete del; break;
+ case 4: delete static_cast<vvp_delay_2_s *>(del); break;
+ case 6: delete static_cast<vvp_delay_3_s *>(del); break;
+ case 12: delete static_cast<vvp_delay_12_s *>(del); break;
+ }
+}
+
+vvp_delay_t vvp_delay_add(vvp_delay_t d1, vvp_delay_t d2)
+{
+ unsigned s1 = vvp_delay_size(d1);
+ unsigned s2 = vvp_delay_size(d2);
+ vvp_delay_t out = s1 > s2 ? d1 : d2;
+ if (s1==0 || s2==0)
+ return out;
+
+ vvp_delay_t oth = s1 > s2 ? d2 : d1;
+ unsigned s = s1 > s2 ? s1 : s2;
+ unsigned so = s1 > s2 ? s2 : s1;
+
+ if (s==so)
+ for (unsigned i=0; i<s; i++)
+ out->del[i] = oth->del[i];
+ else switch (so) {
+ case 1:
+ for (unsigned i=0; i<s; i++)
+ out->del[i] = oth->del[0];
+ break;
+
+ case 4:
+ switch (s) {
+ case 6:
+ out->del[0] = oth->del[0];
+ out->del[1] = oth->del[1];
+ out->del[2] = oth->del[4];
+ out->del[3] = oth->del[4];
+ out->del[4] = oth->del[4];
+ out->del[5] = oth->del[4];
+ break;
+ case 12:
+ out->del[ 0] = oth->del[0];
+ out->del[ 1] = oth->del[1];
+ out->del[ 2] = oth->del[0];
+ out->del[ 3] = oth->del[0];
+ out->del[ 4] = oth->del[1];
+ out->del[ 5] = oth->del[1];
+ out->del[ 6] = oth->del[0];
+ out->del[ 7] = oth->del[0];
+ out->del[ 8] = oth->del[1];
+ out->del[ 9] = oth->del[1];
+ out->del[10] = oth->del[2];
+ out->del[11] = oth->del[3];
+ break;
+ }
+ case 6:
+ out->del[ 0] = oth->del[0];
+ out->del[ 1] = oth->del[1];
+ out->del[ 2] = oth->del[2];
+ out->del[ 3] = oth->del[0];
+ out->del[ 4] = oth->del[2];
+ out->del[ 5] = oth->del[1];
+ out->del[ 6] = oth->del[3];
+ out->del[ 7] = oth->del[0];
+ out->del[ 8] = oth->del[4];
+ out->del[ 9] = oth->del[1];
+ out->del[10] = oth->del[2];
+ out->del[11] = oth->del[5];
+ break;
+ }
+
+ vvp_delay_delete(oth);
+ return out;
+}
+
+vvp_delay_t vvp_delay_set(vvp_delay_t tgt, vvp_delay_t src, unsigned mask)
+{
+ unsigned stgt = vvp_delay_size(tgt);
+ unsigned ssrc = vvp_delay_size(src);
+
+ if (stgt == 0)
+ return src;
+ if (ssrc == 0)
+ return tgt;
+
+ if (stgt == ssrc) {
+ for (unsigned i=0; i<stgt; i++)
+ if (!(mask & (1<<i)))
+ tgt->del[i] = src->del[i];
+
+ vvp_delay_delete(src);
+ return tgt;
+ }
+#if 0 // later
+ if (mask) {
+ static bool done_that = false;
+ if (!done_that) {
+ vvp_printf(VVP_PRINT_WARNING,
+ "Warning:"
+ " partial replacement of delay values"
+ " of different size"
+ " not supported\n"
+ " either replace all edges,"
+ " or specify the same number of values\n" );
+ done_that = true;
+ }
+ }
+#endif
+
+ vvp_delay_delete(tgt);
+ return src;
+}
+
+/*
+** $Log: delay.cc,v $
+** Revision 1.1 2001/11/10 18:07:11 steve
+** Runtime support for functor delays. (Stephan Boettcher)
+**
+*/
View
120 vvp/delay.h
@@ -0,0 +1,120 @@
+#ifndef __delay_H /* -*- c++ -*- */
+#define __delay_H
+/*
+ * Copyright (c) 2001 Stephan Boettcher <stephan@nevis.columbia.edu>
+ *
+ * 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: delay.h,v 1.1 2001/11/10 18:07:11 steve Exp $"
+#endif
+
+/*
+** vvp_delay_t del;
+**
+** del = vvp_delay_new(n, dels);
+** make a delay from n delay specs in array dels.
+** n = 0, 1, 2, 3, 6, 12.
+**
+** unsigned vvp_delay_get(del, from, to);
+** tells the delay for the edge (from->to).
+**
+** del = NULL;
+** new delay with zero delay.
+**
+** del = new vvp_delay_s(delay);
+** new delay with one spec for all edges.
+**
+** del = new vvp_delay_2_s(delay, delay);
+** new delay with two specs for rise and fall delays.
+**
+** del = new vvp_delay_3_s(delay);
+** new delay with three specs for rise, fall, and highz delays.
+**
+** del = new vvp_delay_6_s(delay, del...);
+** new delay with six specs for all 01z edge delays.
+**
+** del = new vvp_delay_12_s(delay, del...);
+** new delay with twelve specs for all edge delays.
+**
+** void vvp_delsy_delete(del);
+** delete a delay.
+**
+** del = vvp_delay_add(del1, del2);
+** add the delay spaces. del1 and del2 are deleted.
+**
+** del = vvp_delay_set(tgt, src, mask);
+** set then non-masked edges of delay tgt from src.
+** tgt and src are deleted.
+*/
+
+typedef struct vvp_delay_s *vvp_delay_t;
+
+struct vvp_delay_s {
+ vvp_delay_s(unsigned);
+ unsigned delay(unsigned char idx) { return del[tab[idx]]; }
+ unsigned size() { return tab[14]+1; }
+ protected:
+ vvp_delay_s(const unsigned char *t);
+ private:
+ unsigned char tab[16];
+ public:
+ unsigned del[1];
+};
+
+struct vvp_delay_2_s : public vvp_delay_s {
+ vvp_delay_2_s(unsigned, unsigned);
+ unsigned dell[4-1];
+};
+
+struct vvp_delay_3_s : public vvp_delay_s {
+ vvp_delay_3_s(unsigned, unsigned, unsigned);
+ unsigned dell[6-1];
+};
+
+struct vvp_delay_12_s : public vvp_delay_s {
+ vvp_delay_12_s(unsigned, unsigned, unsigned,
+ unsigned, unsigned, unsigned,
+ unsigned, unsigned, unsigned,
+ unsigned, unsigned, unsigned);
+ unsigned dell[12-1];
+};
+
+struct vvp_delay_6_s : public vvp_delay_12_s {
+ vvp_delay_6_s(unsigned, unsigned, unsigned,
+ unsigned, unsigned, unsigned);
+};
+
+inline static
+unsigned vvp_delay_get(vvp_delay_t del, unsigned char oval, unsigned char nval)
+{
+ unsigned char idx = nval | (oval << 2);
+ return del->delay(idx);
+}
+
+vvp_delay_t vvp_delay_new(unsigned n, unsigned *dels);
+void vvp_delay_delete(vvp_delay_t);
+vvp_delay_t vvp_delay_add(vvp_delay_t, vvp_delay_t);
+vvp_delay_t vvp_delay_set(vvp_delay_t tgt, vvp_delay_t src,
+ unsigned mask = 0);
+
+/*
+** $Log: delay.h,v $
+** Revision 1.1 2001/11/10 18:07:11 steve
+** Runtime support for functor delays. (Stephan Boettcher)
+**
+*/
+#endif // __delay_H
View
6 vvp/functor.cc
@@ -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.32 2001/11/06 03:07:22 steve Exp $"
+#ident "$Id: functor.cc,v 1.33 2001/11/10 18:07:11 steve Exp $"
#endif
# include "functor.h"
@@ -106,6 +106,7 @@ void functor_define(vvp_ipoint_t point, functor_t obj)
functor_s::functor_s()
{
+ delay = 0;
out = 0;
port[0] = 0;
port[1] = 0;
@@ -167,6 +168,9 @@ edge_inputs_functor_s::~edge_inputs_functor_s()
/*
* $Log: functor.cc,v $
+ * Revision 1.33 2001/11/10 18:07:11 steve
+ * Runtime support for functor delays. (Stephan Boettcher)
+ *
* Revision 1.32 2001/11/06 03:07:22 steve
* Code rearrange. (Stephan Boettcher)
*
View
56 vvp/functor.h
@@ -19,10 +19,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
-#ident "$Id: functor.h,v 1.38 2001/11/07 03:34:42 steve Exp $"
+#ident "$Id: functor.h,v 1.39 2001/11/10 18:07:12 steve Exp $"
#endif
# include "pointers.h"
+# include "delay.h"
/*
* Create a propagation event. The fun parameter points to the functor
@@ -149,6 +150,9 @@ extern void functor_define(vvp_ipoint_t point, functor_t obj);
struct functor_s {
functor_s();
virtual ~functor_s();
+
+ /* delay object */
+ vvp_delay_t delay;
/* This is the output for the device. */
vvp_ipoint_t out;
/* These are the input ports. */
@@ -215,6 +219,30 @@ inline void functor_s::propagate(bool push)
}
}
+inline void functor_s::put_ostr(bool push, unsigned val, unsigned str)
+{
+ if (val != oval || str != ostr) {
+
+ ostr = str;
+
+ if (inhibit)
+ return;
+
+ oval = val;
+
+ unsigned del;
+ if (delay)
+ del = vvp_delay_get(delay, oval, val);
+ else
+ del = 0;
+
+ if (del == 0 && push)
+ propagate(true);
+ else
+ schedule_functor(this, del);
+ }
+}
+
inline void functor_s::put_oval(bool push, unsigned val)
{
switch (val) {
@@ -231,29 +259,8 @@ inline void functor_s::put_oval(bool push, unsigned val)
ostr = 0x00;
break;
}
- if (inhibit)
- return;
- if (val != oval) {
- oval = val;
- if (push)
- propagate(true);
- else
- schedule_functor(this, 0);
- }
-}
-inline void functor_s::put_ostr(bool push, unsigned val, unsigned str)
-{
- if (val != oval || str != ostr) {
- ostr = str;
- if (inhibit)
- return;
- oval = val;
- if (push)
- propagate(true);
- else
- schedule_functor(this, 0);
- }
+ put_ostr(push, val, ostr);
}
/*
@@ -369,6 +376,9 @@ extern vvp_fvector_t vvp_fvector_continuous_new(unsigned size, vvp_ipoint_t p);
/*
* $Log: functor.h,v $
+ * Revision 1.39 2001/11/10 18:07:12 steve
+ * Runtime support for functor delays. (Stephan Boettcher)
+ *
* Revision 1.38 2001/11/07 03:34:42 steve
* Use functor pointers where vvp_ipoint_t is unneeded.
*

0 comments on commit 4a74ae1

Please sign in to comment.