From 62c9f39297ca16fc73919708275e11bed42b3043 Mon Sep 17 00:00:00 2001 From: steve Date: Thu, 26 Apr 2001 03:10:55 +0000 Subject: [PATCH] Redo and simplify UDP behavior. --- vvp/README.txt | 22 +++++++++---- vvp/compile.cc | 43 +++++++++++++++++--------- vvp/pointers.h | 13 +++++++- vvp/udp.cc | 65 ++++++++++++++++++--------------------- vvp/udp.h | 83 +++----------------------------------------------- 5 files changed, 89 insertions(+), 137 deletions(-) diff --git a/vvp/README.txt b/vvp/README.txt index 13783a08f..1967bb767 100644 --- a/vvp/README.txt +++ b/vvp/README.txt @@ -1,7 +1,7 @@ /* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * - * $Id: README.txt,v 1.17 2001/04/25 04:35:05 steve Exp $ + * $Id: README.txt,v 1.18 2001/04/26 03:10:55 steve Exp $ */ VVP SIMULATION ENGINE @@ -125,13 +125,23 @@ the output becomes 1'bx. The output state can be specified as "0", "1", or "x". Sequential UDPs may also have "-": no change. -An input or current output state can be "1", "0", "x", or "?" (don't -care). For Sequential UDPs, at most one input state specification may -be replaced by an edge specification. Valid edges are: +An input or current output state can be + + "1": 1 + "0": 0 + "x": x + "b": 1, 0 + "h": 1, x + "l": 0, x + "?": 1, 0, x + +For Sequential UDPs, at most one input state specification may be +replaced by an edge specification. Valid edges are: "*": (??) "_": (?0) "+": (?1) "%": (?x) - "r": (01) "R": (x1) "f": (10) "F": (x0) - "p": (0?) "n": (1?) "P": (0x) "N": (1x) + "p": (0?) "r": (01) "P": (0x) + "n": (1?) "f": (10) "N": (1x) + "B": (x?) "F": (x0) "R": (x1) A combinatorial UDP is defined like this: diff --git a/vvp/compile.cc b/vvp/compile.cc index db4efbaf1..e9603c944 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -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.40 2001/04/24 03:48:53 steve Exp $" +#ident "$Id: compile.cc,v 1.41 2001/04/26 03:10:55 steve Exp $" #endif # include "compile.h" @@ -319,7 +319,7 @@ void compile_udp_functor(char*label, char*type, struct vvp_udp_s *u = udp_find(type); assert (argc == u->nin); - int nfun = argc<=4 ? 1 : (argc-2) / 3 + 1; + int nfun = (argc+3)/4; vvp_ipoint_t fdx = functor_allocate(nfun); functor_t obj = functor_index(fdx); @@ -330,6 +330,26 @@ void compile_udp_functor(char*label, char*type, sym_set_value(sym_functors, label, val); } + for (unsigned idx = 0; idx < argc; idx += 4) + { + vvp_ipoint_t ifdx = ipoint_input_index(fdx, idx); + functor_t iobj = functor_index(ifdx); + + iobj->ival = 0xaa; + iobj->old_ival = obj->ival; + iobj->oval = u->init; + iobj->mode = 3; + if (idx) + { + iobj->out = fdx; + iobj->udp = 0; + } + else + { + iobj->udp = u; + } + } + /* Run through the arguments looking for the functors that are connected to my input ports. For each source functor that I find, connect the output of that functor to the indexed @@ -338,15 +358,11 @@ void compile_udp_functor(char*label, char*type, If the source functor is not declared yet, then don't do the link yet. Save the reference to be resolved later. */ - - udp_init_links(fdx, u); - - udp_idx_t ux(fdx, u); + for (unsigned idx = 0; idx < argc; idx += 1) { - vvp_ipoint_t ifdx = ux.ipoint(); - functor_t iobj = ux.functor(); - ux.next(); + vvp_ipoint_t ifdx = ipoint_input_index(fdx, idx); + functor_t iobj = functor_index(ifdx); symbol_value_t val = sym_get_value(sym_functors, argv[idx].text); vvp_ipoint_t tmp = val.num; @@ -366,12 +382,6 @@ void compile_udp_functor(char*label, char*type, } } - obj->ival = 0xaa; - obj->old_ival = obj->ival; - obj->oval = u->init; - obj->mode = 3; - obj->udp = u; - free(argv); free(label); } @@ -944,6 +954,9 @@ void compile_dump(FILE*fd) /* * $Log: compile.cc,v $ + * Revision 1.41 2001/04/26 03:10:55 steve + * Redo and simplify UDP behavior. + * * Revision 1.40 2001/04/24 03:48:53 steve * Fix underflow when UDP has 1 input. * diff --git a/vvp/pointers.h b/vvp/pointers.h index e76a6f331..8c2c00aae 100644 --- a/vvp/pointers.h +++ b/vvp/pointers.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: pointers.h,v 1.3 2001/03/26 04:00:39 steve Exp $" +#ident "$Id: pointers.h,v 1.4 2001/04/26 03:10:55 steve Exp $" #endif /* @@ -66,6 +66,14 @@ inline vvp_ipoint_t ipoint_index(vvp_ipoint_t base, unsigned idx) return base + (idx<<2); } +/* + * Return the ipoint of an input into a multi-functor input vector. + */ +inline vvp_ipoint_t ipoint_input_index(vvp_ipoint_t base, unsigned idx) +{ + return (base & ~3) + idx; +} + /* * This function returns the port index of a functor given a complete * vvp_ipoint_t pointer. @@ -94,6 +102,9 @@ typedef struct vthread_s*vthread_t; /* * $Log: pointers.h,v $ + * Revision 1.4 2001/04/26 03:10:55 steve + * Redo and simplify UDP behavior. + * * Revision 1.3 2001/03/26 04:00:39 steve * Add the .event statement and the %wait instruction. * diff --git a/vvp/udp.cc b/vvp/udp.cc index b34c0af0d..8d41feef7 100644 --- a/vvp/udp.cc +++ b/vvp/udp.cc @@ -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.1 2001/04/24 02:23:59 steve Exp $" +#ident "$Id: udp.cc,v 1.2 2001/04/26 03:10:55 steve Exp $" #endif #include "udp.h" @@ -56,27 +56,6 @@ struct vvp_udp_s *udp_find(char *label) return (struct vvp_udp_s *)v.ptr; } -void udp_init_links(vvp_ipoint_t fdx, struct vvp_udp_s *u) -{ - udp_idx_t ux(fdx, u); - do - { - vvp_ipoint_t pa = ux.parent(); - if (pa) - { - functor_t fu = ux.functor(); - functor_t fp = functor_index(pa); - fp->port[ipoint_port(pa)] = 0x0; - fu->out = pa; - fu->udp = 0x0; - fu->mode = 3; - - fu->ival = 0xaa; - fu->old_ival = fu->ival; - } - } while (ux.next_node()); -} - unsigned char udp_propagate(vvp_ipoint_t uix) { functor_t fu = functor_index(uix); @@ -84,8 +63,6 @@ unsigned char udp_propagate(vvp_ipoint_t uix) assert(u); assert(u->table); - udp_idx_t ux(uix, u); - unsigned char ret = 2; for (char **rptr = u->table; *rptr ; rptr++) @@ -94,24 +71,34 @@ unsigned char udp_propagate(vvp_ipoint_t uix) if (u->sequ) { - if (row[0]=='?' || row[0]==(fu->oval&3)["01xx"]) + char old_out = (fu->oval&3)["01xx"]; + if ( row[0]=='?' + || row[0]==old_out + || (row[0]=='b' && old_out!='x') + || (row[0]=='l' && old_out!='1') + || (row[0]=='h' && old_out!='0') ) row++; else continue; } - ux.reset(); + int i; - do + for (i=0; i < u->nin; i++, row++) { assert (*row); - int port = ipoint_port(ux.ipoint()); - functor_t pfun = ux.functor(); + int idx = ipoint_input_index(uix, i); + int port = ipoint_port(idx); + functor_t pfun = functor_index(idx); char new_bit = ((pfun->ival >> (2*port))&3)["01xx"]; - if (*row != new_bit && *row != '?') + if ( *row != new_bit + && *row != '?' + && (*row != 'b' || new_bit == 'x') + && (*row != 'l' || new_bit == '1') + && (*row != 'h' || new_bit == '0') ) { char old_bit = ((pfun->old_ival >> (2*port))&3)["01xx"]; if (new_bit == old_bit) @@ -133,6 +120,10 @@ unsigned char udp_propagate(vvp_ipoint_t uix) if (new_bit == 'x') continue; break; + case 'B': + if (old_bit == 'x') + continue; + break; case 'r': if (old_bit=='0' && new_bit=='1') continue; @@ -168,9 +159,9 @@ unsigned char udp_propagate(vvp_ipoint_t uix) } break; } - } while (row++, ux.next()); + } - if (ux.done()) + if (i == u->nin) { assert(*row); if (*row == '-') @@ -192,18 +183,20 @@ unsigned char udp_propagate(vvp_ipoint_t uix) } } - ux.reset(); - do + for (int i=0; i < u->nin; i+=4) { - functor_t fu = ux.functor(); + functor_t fu = functor_index(ipoint_input_index(uix, i)); fu->old_ival = fu->ival; - } while (ux.next_node()); + } return ret; } /* * $Log: udp.cc,v $ + * Revision 1.2 2001/04/26 03:10:55 steve + * Redo and simplify UDP behavior. + * * Revision 1.1 2001/04/24 02:23:59 steve * Support for UDP devices in VVP (Stephen Boettcher) * diff --git a/vvp/udp.h b/vvp/udp.h index 97d910b2a..891102650 100644 --- a/vvp/udp.h +++ b/vvp/udp.h @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: udp.h,v 1.2 2001/04/24 03:48:53 steve Exp $" +#ident "$Id: udp.h,v 1.3 2001/04/26 03:10:55 steve Exp $" #endif #include "pointers.h" @@ -36,90 +36,15 @@ struct vvp_udp_s char **table; }; -void udp_init_links(vvp_ipoint_t fdx, struct vvp_udp_s *u); struct vvp_udp_s *udp_create(char *label); struct vvp_udp_s *udp_find(char *label); unsigned char udp_propagate(vvp_ipoint_t); -// The iterator through the input port list/tree/whatever - -class udp_idx_t -{ -public: - udp_idx_t(vvp_ipoint_t, struct vvp_udp_s *); - vvp_ipoint_t ipoint(); - functor_t functor(); - bool next(); - vvp_ipoint_t next_node(); - bool done(); - vvp_ipoint_t parent(); - void reset(); -private: - vvp_ipoint_t root; - unsigned nin; - unsigned cur_i; -}; - -inline void udp_idx_t::reset() -{ - cur_i = 0; -} - -inline udp_idx_t::udp_idx_t(vvp_ipoint_t idx, struct vvp_udp_s *u) - : root(idx), nin(u->nin) -{ - reset(); -} - -inline bool udp_idx_t::done() -{ - return cur_i >= nin; -} - -inline bool udp_idx_t::next() -{ - cur_i++; - return !done(); -} - -inline vvp_ipoint_t udp_idx_t::ipoint() -{ - // The last node in the chain can hold 4 inputs. - int idx = (cur_i==nin-1 && cur_i ? cur_i-1 : cur_i) / 3; - int port = cur_i - 3*idx; - return ipoint_make(ipoint_index(root, idx), port); -} - -inline functor_t udp_idx_t::functor() -{ - return functor_index(ipoint()); -} - -// junp to the next node, and return the ipoint. - -inline vvp_ipoint_t udp_idx_t::next_node() -{ - // We omit the last-node case, since is is a don't care here. - int idx = cur_i / 3 + 1; - cur_i = idx*3+1; - return cur_i < nin - ? ipoint_make(ipoint_index(root, idx),0) - : 0; -} - -inline vvp_ipoint_t udp_idx_t::parent() -{ - if (nin<=4) - return 0x0; - - int idx = (cur_i==nin-1 ? cur_i-1 : cur_i) / 3; - if (!idx) - return 0x0; - return ipoint_make(ipoint_index(root, idx-1), 3); -} - /* * $Log: udp.h,v $ + * Revision 1.3 2001/04/26 03:10:55 steve + * Redo and simplify UDP behavior. + * * Revision 1.2 2001/04/24 03:48:53 steve * Fix underflow when UDP has 1 input. *