diff --git a/elaborate.cc b/elaborate.cc index 22742c0f3..4ef26dd24 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: elaborate.cc,v 1.210 2001/04/22 23:09:46 steve Exp $" +#ident "$Id: elaborate.cc,v 1.211 2001/04/24 02:23:58 steve Exp $" #endif /* @@ -612,8 +612,9 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, const string&path) const void PGModule::elaborate_udp_(Design*des, PUdp*udp, const string&path) const { + NetScope*scope = des->find_scope(path); const string my_name = path+"."+get_name(); - NetUDP*net = new NetUDP(my_name, udp->ports.count(), udp); + NetUDP*net = new NetUDP(scope, my_name, udp->ports.count(), udp); net->set_attributes(udp->attributes); /* Run through the pins, making netlists for the pin @@ -2300,6 +2301,9 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.211 2001/04/24 02:23:58 steve + * Support for UDP devices in VVP (Stephen Boettcher) + * * Revision 1.210 2001/04/22 23:09:46 steve * More UDP consolidation from Stephan Boettcher. * diff --git a/net_udp.cc b/net_udp.cc index 2d2a63e3e..2fde00e78 100644 --- a/net_udp.cc +++ b/net_udp.cc @@ -18,13 +18,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: net_udp.cc,v 1.4 2001/04/22 23:09:46 steve Exp $" +#ident "$Id: net_udp.cc,v 1.5 2001/04/24 02:23:58 steve Exp $" #endif # include "netlist.h" -NetUDP::NetUDP(const string&n, unsigned pins, PUdp *u) - : NetNode(n, pins), udp(u) +NetUDP::NetUDP(NetScope*s, const string&n, unsigned pins, PUdp *u) + : NetNode(s, n, pins), udp(u) { pin(0).set_dir(Link::OUTPUT); pin(0).set_name("O", 0); @@ -89,6 +89,9 @@ char NetUDP::get_initial() const /* * $Log: net_udp.cc,v $ + * Revision 1.5 2001/04/24 02:23:58 steve + * Support for UDP devices in VVP (Stephen Boettcher) + * * Revision 1.4 2001/04/22 23:09:46 steve * More UDP consolidation from Stephan Boettcher. * diff --git a/netlist.h b/netlist.h index 89f6d5bb4..b32767870 100644 --- a/netlist.h +++ b/netlist.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: netlist.h,v 1.203 2001/04/22 23:09:46 steve Exp $" +#ident "$Id: netlist.h,v 1.204 2001/04/24 02:23:58 steve Exp $" #endif /* @@ -1067,7 +1067,7 @@ class NetLogic : public NetNode { class NetUDP : public NetNode { public: - explicit NetUDP(const string&n, unsigned pins, PUdp*u); + explicit NetUDP(NetScope*s, const string&n, unsigned pins, PUdp*u); virtual bool emit_node(struct target_t*) const; virtual void dump_node(ostream&, unsigned ind) const; @@ -2802,6 +2802,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.204 2001/04/24 02:23:58 steve + * Support for UDP devices in VVP (Stephen Boettcher) + * * Revision 1.203 2001/04/22 23:09:46 steve * More UDP consolidation from Stephan Boettcher. * diff --git a/t-dll.cc b/t-dll.cc index cd9f7d93d..0f4637490 100644 --- a/t-dll.cc +++ b/t-dll.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: t-dll.cc,v 1.34 2001/04/22 23:09:46 steve Exp $" +#ident "$Id: t-dll.cc,v 1.35 2001/04/24 02:23:58 steve Exp $" #endif # include "compiler.h" @@ -416,11 +416,15 @@ void dll_target::udp(const NetUDP*net) obj->type_ = IVL_LO_UDP; static map udps; + ivl_udp_t u; - ivl_udp_t u = udps[net->udp_name()]; - if (!u) + if (udps.find(net->udp_name()) != udps.end()) { - u = new ivl_udp_s; + u = udps[net->udp_name()]; + } + else + { + u = new struct ivl_udp_s; u->nrows = net->rows(); u->table = (char**)malloc((u->nrows+1)*sizeof(char*)); assert(u->table); @@ -439,6 +443,7 @@ void dll_target::udp(const NetUDP*net) string tt = inp+out; u->table[i++] = strdup(tt.c_str()); } while (net->next(inp, out)); + assert(i==u->nrows); udps[net->udp_name()] = u; } @@ -806,6 +811,9 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj }; /* * $Log: t-dll.cc,v $ + * Revision 1.35 2001/04/24 02:23:58 steve + * Support for UDP devices in VVP (Stephen Boettcher) + * * Revision 1.34 2001/04/22 23:09:46 steve * More UDP consolidation from Stephan Boettcher. * diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index 7956b2f1b..8da1469d0 100644 --- a/tgt-vvp/vvp_scope.c +++ b/tgt-vvp/vvp_scope.c @@ -17,11 +17,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vvp_scope.c,v 1.17 2001/04/21 02:04:01 steve Exp $" +#ident "$Id: vvp_scope.c,v 1.18 2001/04/24 02:23:58 steve Exp $" #endif # include "vvp_priv.h" # include +# include /* * The draw_scope function draws the major functional items within a @@ -107,20 +108,91 @@ static void draw_net_in_scope(ivl_signal_t sig) fprintf(vvp_out, ";\n"); } +static void draw_udp_def(ivl_udp_t udp) +{ + unsigned init; + int i; + + switch (ivl_udp_init(udp)) + { + case '0': + init = 0; + break; + case '1': + init = 1; + break; + default: + init = 2; + break; + } + + fprintf(vvp_out, + "UDP_%s .udp/%s \"%s\", %d, %d", + ivl_udp_name(udp), + ivl_udp_sequ(udp) ? "sequ" : "comp", + ivl_udp_name(udp), + ivl_udp_nin(udp), + init ); + + for (i=0; i= nudps) + { + udps = (ivl_udp_t*)realloc(udps, (nudps+1)*sizeof(ivl_udp_t)); + assert(udps); + udps[nudps++] = udp; + draw_udp_def(udp); + } + + fprintf(vvp_out, "L_%s .udp UDP_%s", + ivl_logic_name(lptr), ivl_udp_name(udp)); + + for (pdx = 1 ; pdx < ivl_logic_pins(lptr) ; pdx += 1) + { + ivl_nexus_t nex = ivl_logic_pin(lptr, pdx); + fprintf(vvp_out, ", "); + draw_nexus_input(nex); + } + + fprintf(vvp_out, ";\n"); +} + static void draw_logic_in_scope(ivl_net_logic_t lptr) { unsigned pdx; const char*ltype = "?"; unsigned init_val = 0; - /* Skip BUFZ objects. Things that have a bufz as input - will use the input to bufz instead. */ - if (ivl_logic_type(lptr) == IVL_LO_BUFZ) - return; - switch (ivl_logic_type(lptr)) { + case IVL_LO_UDP: + draw_udp_in_scope(lptr); + return; + + case IVL_LO_BUFZ: + /* Skip BUFZ objects. Things that have a bufz as input + will use the input to bufz instead. */ + return; + case IVL_LO_AND: ltype = "AND"; init_val = 0x55; @@ -314,6 +386,9 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent) /* * $Log: vvp_scope.c,v $ + * Revision 1.18 2001/04/24 02:23:58 steve + * Support for UDP devices in VVP (Stephen Boettcher) + * * Revision 1.17 2001/04/21 02:04:01 steve * Add NAND and XNOR functors. * diff --git a/vvp/Makefile.in b/vvp/Makefile.in index ea68676a2..243340d9d 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.13 2001/04/01 21:31:46 steve Exp $" +#ident "$Id: Makefile.in,v 1.14 2001/04/24 02:23:59 steve Exp $" # # SHELL = /bin/sh @@ -61,7 +61,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 O = main.o parse.o parse_misc.o lexor.o compile.o functor.o symbols.o \ -codes.o vthread.o schedule.o tables.o $V +codes.o vthread.o schedule.o tables.o udp.o $V vvp: $O $(CXX) $(rdynamic) $(CXXFLAGS) $(LDFLAGS) -o vvp $O $(dllib) diff --git a/vvp/compile.cc b/vvp/compile.cc index c3e3a69c1..2f2679747 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -17,11 +17,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: compile.cc,v 1.38 2001/04/23 00:37:58 steve Exp $" +#ident "$Id: compile.cc,v 1.39 2001/04/24 02:23:59 steve Exp $" #endif # include "compile.h" # include "functor.h" +# include "udp.h" # include "symbols.h" # include "codes.h" # include "schedule.h" @@ -285,6 +286,97 @@ void compile_functor(char*label, char*type, unsigned init, free(type); } +void compile_udp_def(int sequ, char *label, char *name, + unsigned nin, unsigned init, char **table) +{ + struct vvp_udp_s *u = udp_create(label); + u->name = name; + u->sequ = sequ; + u->nin = nin; + u->init = init; + u->table = table; +} + +char **compile_udp_table(char **table, char *row) +{ + if (table) + assert(strlen(*table)==strlen(row)); + + char **tt; + for (tt = table; tt && *tt; tt++); + int n = (tt-table) + 2; + + table = (char**)realloc(table, n*sizeof(char*)); + table[n-2] = row; + table[n-1] = 0x0; + + return table; +} + +void compile_udp_functor(char*label, char*type, + unsigned argc, struct symb_s*argv) +{ + struct vvp_udp_s *u = udp_find(type); + assert (argc == u->nin); + + int nfun = (argc-2) / 3 + 1; + + vvp_ipoint_t fdx = functor_allocate(nfun); + functor_t obj = functor_index(fdx); + + { + symbol_value_t val; + val.num = fdx; + sym_set_value(sym_functors, label, val); + } + + /* 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 + input by inserting myself (complete with the port number in + the vvp_ipoint_t) into the list that the source heads. + + 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(); + + symbol_value_t val = sym_get_value(sym_functors, argv[idx].text); + vvp_ipoint_t tmp = val.num; + + if (tmp) + { + tmp = ipoint_index(tmp, argv[idx].idx); + functor_t fport = functor_index(tmp); + iobj->port[ipoint_port(ifdx)] = fport->out; + fport->out = ifdx; + + free(argv[idx].text); + } + else + { + postpone_functor_input(ifdx, argv[idx].text, argv[idx].idx); + } + } + + obj->ival = 0xaa; + obj->old_ival = obj->ival; + obj->oval = u->init; + obj->mode = 3; + obj->udp = u; + + free(argv); + free(label); +} + + void compile_event(char*label, char*type, unsigned argc, struct symb_s*argv) { @@ -852,6 +944,9 @@ void compile_dump(FILE*fd) /* * $Log: compile.cc,v $ + * Revision 1.39 2001/04/24 02:23:59 steve + * Support for UDP devices in VVP (Stephen Boettcher) + * * Revision 1.38 2001/04/23 00:37:58 steve * Support unconnected .net objects. * diff --git a/vvp/compile.h b/vvp/compile.h index a3aeb4590..ce29ac3ac 100644 --- a/vvp/compile.h +++ b/vvp/compile.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: compile.h,v 1.16 2001/04/18 04:21:23 steve Exp $" +#ident "$Id: compile.h,v 1.17 2001/04/24 02:23:59 steve Exp $" #endif # include @@ -65,6 +65,19 @@ extern void compile_functor(char*label, char*type, unsigned init, extern void compile_vpi_symbol(const char*label, vpiHandle obj); extern vpiHandle compile_vpi_lookup(const char*label); +/* + * The first function creates a UDP, the second function adds table + entries, and the third one instantiates a UDP functor. + */ + +extern void compile_udp_def(int sequ, char*label, char *name, + unsigned nin, unsigned init, char **table); + +extern void compile_udp_functor(char*label, char*type, + unsigned argc, struct symb_s*argv); + +extern char **compile_udp_table(char **table, char *row); + /* * The compile_event function takes the parts of the event statement * and makes the various objects needed to simulate it. This includes @@ -142,6 +155,9 @@ extern void compile_dump(FILE*fd); /* * $Log: compile.h,v $ + * Revision 1.17 2001/04/24 02:23:59 steve + * Support for UDP devices in VVP (Stephen Boettcher) + * * Revision 1.16 2001/04/18 04:21:23 steve * Put threads into scopes. * diff --git a/vvp/functor.cc b/vvp/functor.cc index 4e93af267..a54ef64a8 100644 --- a/vvp/functor.cc +++ b/vvp/functor.cc @@ -17,10 +17,11 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: functor.cc,v 1.12 2001/04/18 04:21:23 steve Exp $" +#ident "$Id: functor.cc,v 1.13 2001/04/24 02:23:59 steve Exp $" #endif # include "functor.h" +# include "udp.h" # include "schedule.h" # include "vthread.h" # include @@ -213,6 +214,27 @@ static void functor_set_mode2(functor_t fp) schedule_assign(fp->out, 0, 0); } +/* + * A mode-3 functor is a UDP. + */ +static void functor_set_mode3(vvp_ipoint_t ptr, functor_t fp) +{ + /* If we are down the tree, just propagate */ + if (!fp->udp) + { + functor_propagate(ptr); + return; + } + + unsigned char out = udp_propagate(ptr); + + if (out != fp->oval) + { + fp->oval = out; + functor_propagate(ptr); + } +} + /* * Set the addressed bit of the functor, and recalculate the * output. If the output changes any, then generate the necessary @@ -223,7 +245,7 @@ void functor_set(vvp_ipoint_t ptr, unsigned bit, bool push) functor_t fp = functor_index(ptr); unsigned pp = ipoint_port(ptr); assert(fp); - assert(fp->table); + // assert(fp->table); /* Change the bits of the input. */ static const unsigned char mask_table[4] = { 0xfc, 0xf3, 0xcf, 0x3f }; @@ -240,6 +262,9 @@ void functor_set(vvp_ipoint_t ptr, unsigned bit, bool push) case 2: functor_set_mode2(fp); break; + case 3: + functor_set_mode3(ptr, fp); + break; } } @@ -306,6 +331,9 @@ const unsigned char ft_var[16] = { /* * $Log: functor.cc,v $ + * Revision 1.13 2001/04/24 02:23:59 steve + * Support for UDP devices in VVP (Stephen Boettcher) + * * Revision 1.12 2001/04/18 04:21:23 steve * Put threads into scopes. * diff --git a/vvp/functor.h b/vvp/functor.h index 6bf6b0a31..a863db2db 100644 --- a/vvp/functor.h +++ b/vvp/functor.h @@ -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.13 2001/04/21 02:04:01 steve Exp $" +#ident "$Id: functor.h,v 1.14 2001/04/24 02:23:59 steve Exp $" #endif # include "pointers.h" @@ -82,6 +82,7 @@ struct functor_s { union { vvp_truth_t table; vvp_event_t event; + struct vvp_udp_s *udp; // mode 3 }; /* This is the output for the device. */ @@ -92,7 +93,11 @@ struct functor_s { unsigned char ival; unsigned char oval; /* functor mode: 0 == table ; 1 == event ; 2 == named event */ + /* 3 == udp */ unsigned char mode; + union { + unsigned char old_ival; // mode 3 + }; }; typedef struct functor_s *functor_t; @@ -179,6 +184,9 @@ extern const unsigned char ft_var[]; /* * $Log: functor.h,v $ + * Revision 1.14 2001/04/24 02:23:59 steve + * Support for UDP devices in VVP (Stephen Boettcher) + * * Revision 1.13 2001/04/21 02:04:01 steve * Add NAND and XNOR functors. * diff --git a/vvp/lexor.lex b/vvp/lexor.lex index dcab38fd3..4091118a5 100644 --- a/vvp/lexor.lex +++ b/vvp/lexor.lex @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: lexor.lex,v 1.13 2001/04/18 04:21:23 steve Exp $" +#ident "$Id: lexor.lex,v 1.14 2001/04/24 02:23:59 steve Exp $" #endif # include "parse_misc.h" @@ -74,6 +74,9 @@ ".thread" { return K_THREAD; } ".var" { return K_VAR; } ".var/s" { return K_VAR_S; } +".udp" { return K_UDP; } +".udp/c"(omb)? { return K_UDP_C; } +".udp/s"(equ)? { return K_UDP_S; } /* instructions start with a % character. The compiler decides what @@ -127,6 +130,9 @@ int yywrap() /* * $Log: lexor.lex,v $ + * Revision 1.14 2001/04/24 02:23:59 steve + * Support for UDP devices in VVP (Stephen Boettcher) + * * Revision 1.13 2001/04/18 04:21:23 steve * Put threads into scopes. * diff --git a/vvp/parse.y b/vvp/parse.y index 87942720a..fceed9d36 100644 --- a/vvp/parse.y +++ b/vvp/parse.y @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: parse.y,v 1.21 2001/04/23 00:37:58 steve Exp $" +#ident "$Id: parse.y,v 1.22 2001/04/24 02:23:59 steve Exp $" #endif # include "parse_misc.h" @@ -37,6 +37,7 @@ extern FILE*yyin; %union { char*text; + char **table; long numb; comp_operands_t opa; @@ -52,6 +53,7 @@ extern FILE*yyin; %token K_EVENT K_EVENT_OR K_FUNCTOR K_NET K_NET_S K_SCOPE K_THREAD +%token K_UDP K_UDP_C K_UDP_S %token K_VAR K_VAR_S K_vpi_call K_disable K_fork %token K_vpi_module @@ -66,6 +68,7 @@ extern FILE*yyin; %type symbols symbols_net %type label_opt %type operand operands operands_opt +%type udp_table %type argument_opt argument_list %type argument @@ -110,6 +113,21 @@ statement | T_LABEL K_FUNCTOR T_SYMBOL',' T_NUMBER ';' { compile_functor($1, $3, $5, 0, 0); } + + /* UDP statements define or instantiate UDPs. Definitions take a + label (UDP type id) a name (string), the number of inputs, and + for sequentioal UDPs the initial value. */ + + | T_LABEL K_UDP_S T_STRING ',' T_NUMBER ',' T_NUMBER ',' udp_table ';' + { compile_udp_def(1, $1, $3, $5, $7, $9); } + + | T_LABEL K_UDP_C T_STRING ',' T_NUMBER ',' udp_table ';' + { compile_udp_def(0, $1, $3, $5, 0, $7); } + + | T_LABEL K_UDP T_SYMBOL ',' symbols ';' + { compile_udp_functor($1, $3, $5.cnt, $5.vect); } + + /* Event statements take a label, a type (the first T_SYMBOL) and a list of inputs. If the type is instead a string, then we have a named event instead. */ @@ -341,6 +359,13 @@ symbol_opt $$.idx = 0; } +udp_table + : T_STRING + { $$ = compile_udp_table(0x0, $1); } + | udp_table ',' T_STRING + { $$ = compile_udp_table($1, $3); } + ; + %% int compile_design(const char*path) @@ -360,6 +385,9 @@ int compile_design(const char*path) /* * $Log: parse.y,v $ + * Revision 1.22 2001/04/24 02:23:59 steve + * Support for UDP devices in VVP (Stephen Boettcher) + * * Revision 1.21 2001/04/23 00:37:58 steve * Support unconnected .net objects. * diff --git a/vvp/udp.cc b/vvp/udp.cc new file mode 100644 index 000000000..b34c0af0d --- /dev/null +++ b/vvp/udp.cc @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2000 Stephen Williams (steve@icarus.com) + * 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: udp.cc,v 1.1 2001/04/24 02:23:59 steve Exp $" +#endif + +#include "udp.h" +#include "symbols.h" +#include +#include + +static symbol_table_t udp_table; + +struct vvp_udp_s *udp_create(char *label) +{ + if (!udp_table) + udp_table = new_symbol_table(); + + assert(!udp_find(label)); + + struct vvp_udp_s *u = new struct vvp_udp_s; + + symbol_value_t v; + v.ptr = u; + sym_set_value(udp_table, label, v); + + u->name = 0x0; + u->sequ = 0; + u->nin = 0; + u->init = 3; + u->table = 0x0; + + return u; +} + +struct vvp_udp_s *udp_find(char *label) +{ + symbol_value_t v = sym_get_value(udp_table, 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); + struct vvp_udp_s *u = fu->udp; + assert(u); + assert(u->table); + + udp_idx_t ux(uix, u); + + unsigned char ret = 2; + + for (char **rptr = u->table; *rptr ; rptr++) + { + char *row = *rptr; + + if (u->sequ) + { + if (row[0]=='?' || row[0]==(fu->oval&3)["01xx"]) + row++; + else + continue; + } + + ux.reset(); + + do + { + assert (*row); + + int port = ipoint_port(ux.ipoint()); + functor_t pfun = ux.functor(); + + char new_bit = ((pfun->ival >> (2*port))&3)["01xx"]; + + if (*row != new_bit && *row != '?') + { + char old_bit = ((pfun->old_ival >> (2*port))&3)["01xx"]; + if (new_bit == old_bit) + break; + + switch (*row) + { + case '*': + continue; + case '_': + if (new_bit == '0') + continue; + break; + case '+': + if (new_bit == '1') + continue; + break; + case '%': + if (new_bit == 'x') + continue; + break; + case 'r': + if (old_bit=='0' && new_bit=='1') + continue; + break; + case 'R': + if (old_bit=='x' && new_bit=='1') + continue; + break; + case 'f': + if (old_bit=='1' && new_bit=='0') + continue; + break; + case 'F': + if (old_bit=='x' && new_bit=='0') + continue; + break; + case 'p': + if (old_bit=='0') + continue; + break; + case 'n': + if (old_bit=='1') + continue; + break; + case 'P': + if (old_bit=='0' && new_bit=='x') + continue; + break; + case 'N': + if (old_bit=='1' && new_bit=='x') + continue; + break; + } + break; + } + } while (row++, ux.next()); + + if (ux.done()) + { + assert(*row); + if (*row == '-') + ret = fu->oval; + else + switch (*row) + { + case '0': + ret = 0; + break; + case '1': + ret = 1; + break; + default: + ret = 2; + break; + } + break; + } + } + + ux.reset(); + do + { + functor_t fu = ux.functor(); + fu->old_ival = fu->ival; + } while (ux.next_node()); + + return ret; +} + +/* + * $Log: udp.cc,v $ + * 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 new file mode 100644 index 000000000..373cfd2d8 --- /dev/null +++ b/vvp/udp.h @@ -0,0 +1,124 @@ +#ifndef __udp_H +#define __udp_H +/* + * Copyright (c) 2001 Stephen Williams (steve@icarus.com) + * 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: udp.h,v 1.1 2001/04/24 02:23:59 steve Exp $" +#endif + +#include "pointers.h" +#include "functor.h" +#include "udp.h" + +struct vvp_udp_s +{ + char *name; + unsigned short sequ; + unsigned short nin; + unsigned char init; + 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() +{ + 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.1 2001/04/24 02:23:59 steve + * Support for UDP devices in VVP (Stephen Boettcher) + * + */ +#endif