From 4a74ae17958f7250e22c0ac888d9fbf5f426ed24 Mon Sep 17 00:00:00 2001 From: steve Date: Sat, 10 Nov 2001 18:07:11 +0000 Subject: [PATCH] Runtime support for functor delays. (Stephan Boettcher) --- vvp/Makefile.in | 4 +- vvp/delay.cc | 253 ++++++++++++++++++++++++++++++++++++++++++++++++ vvp/delay.h | 120 +++++++++++++++++++++++ vvp/functor.cc | 6 +- vvp/functor.h | 56 ++++++----- 5 files changed, 413 insertions(+), 26 deletions(-) create mode 100644 vvp/delay.cc create mode 100644 vvp/delay.h diff --git a/vvp/Makefile.in b/vvp/Makefile.in index e16298df8..05be187c4 100644 --- a/vvp/Makefile.in +++ b/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) diff --git a/vvp/delay.cc b/vvp/delay.cc new file mode 100644 index 000000000..82cd44bcd --- /dev/null +++ b/vvp/delay.cc @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2001 Stephan Boettcher + * + * 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 +#include + +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(del); break; + case 6: delete static_cast(del); break; + case 12: delete static_cast(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; idel[i] = oth->del[i]; + else switch (so) { + case 1: + for (unsigned i=0; idel[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; idel[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) +** +*/ diff --git a/vvp/delay.h b/vvp/delay.h new file mode 100644 index 000000000..edeba7112 --- /dev/null +++ b/vvp/delay.h @@ -0,0 +1,120 @@ +#ifndef __delay_H /* -*- c++ -*- */ +#define __delay_H +/* + * Copyright (c) 2001 Stephan Boettcher + * + * 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 diff --git a/vvp/functor.cc b/vvp/functor.cc index 4d199bc6c..5f869e08b 100644 --- a/vvp/functor.cc +++ b/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) * diff --git a/vvp/functor.h b/vvp/functor.h index 718f96247..2bc4797f2 100644 --- a/vvp/functor.h +++ b/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. *