diff --git a/ivl.def b/ivl.def index c23176ff8..823eab3cc 100644 --- a/ivl.def +++ b/ivl.def @@ -72,9 +72,11 @@ ivl_memory_root ivl_memory_size ivl_memory_width +ivl_nexus_get_private ivl_nexus_name ivl_nexus_ptrs ivl_nexus_ptr +ivl_nexus_set_private ivl_nexus_ptr_con ivl_nexus_ptr_drive0 diff --git a/ivl_target.h b/ivl_target.h index d72669ca5..cfd1df16a 100644 --- a/ivl_target.h +++ b/ivl_target.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: ivl_target.h,v 1.75 2001/07/27 04:51:44 steve Exp $" +#ident "$Id: ivl_target.h,v 1.76 2001/08/10 00:40:45 steve Exp $" #endif #ifdef __cplusplus @@ -604,6 +604,14 @@ extern ivl_nexus_t ivl_lval_pin(ivl_lval_t net, unsigned idx); * ivl_nexus_ptr * Return a nexus pointer given the nexus and an index. * + * ivl_nexus_set_private + * ivl_nexus_get_private + * The target module often needs to associate data with a nexus for + * later use when the nexus is encountered associated with a + * device. These methods allow the code generator to store to or + * retrieve from a nexus a void* of private data. This pointer is + * guaranteed to be 0 before the target module is invoked. + * * Once an ivl_nexus_ptr_t is selected by the ivl_nexus_ptr method, * the properties of the pointer can be accessed by the following * methods: @@ -651,6 +659,10 @@ extern const char* ivl_nexus_name(ivl_nexus_t net); extern unsigned ivl_nexus_ptrs(ivl_nexus_t net); extern ivl_nexus_ptr_t ivl_nexus_ptr(ivl_nexus_t net, unsigned idx); +extern void ivl_nexus_set_private(ivl_nexus_t net, void*data); +extern void* ivl_nexus_get_private(ivl_nexus_t net); + + extern ivl_drive_t ivl_nexus_ptr_drive0(ivl_nexus_ptr_t net); extern ivl_drive_t ivl_nexus_ptr_drive1(ivl_nexus_ptr_t net); extern unsigned ivl_nexus_ptr_pin(ivl_nexus_ptr_t net); @@ -659,7 +671,6 @@ extern ivl_net_logic_t ivl_nexus_ptr_log(ivl_nexus_ptr_t net); extern ivl_lpm_t ivl_nexus_ptr_lpm(ivl_nexus_ptr_t net); extern ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net); - /* SCOPE * Scopes of various sort have these properties. Use these methods to * access them. Scopes come to exist in the elaborated design @@ -896,6 +907,9 @@ _END_DECL /* * $Log: ivl_target.h,v $ + * Revision 1.76 2001/08/10 00:40:45 steve + * tgt-vvp generates code that skips nets as inputs. + * * Revision 1.75 2001/07/27 04:51:44 steve * Handle part select expressions as variants of * NetESignal/IVL_EX_SIGNAL objects, instead of diff --git a/t-dll-api.cc b/t-dll-api.cc index 53145bc04..ab5aec69c 100644 --- a/t-dll-api.cc +++ b/t-dll-api.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-api.cc,v 1.61 2001/07/28 01:17:40 steve Exp $" +#ident "$Id: t-dll-api.cc,v 1.62 2001/08/10 00:40:45 steve Exp $" #endif # include "config.h" @@ -757,6 +757,18 @@ extern "C" const char* ivl_nexus_name(ivl_nexus_t net) return net->name_; } +extern "C" void* ivl_nexus_get_private(ivl_nexus_t net) +{ + assert(net); + return net->private_data; +} + +extern "C" void ivl_nexus_set_private(ivl_nexus_t net, void*data) +{ + assert(net); + net->private_data = data; +} + extern "C" unsigned ivl_nexus_ptrs(ivl_nexus_t net) { assert(net); @@ -1297,6 +1309,9 @@ extern "C" ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net) /* * $Log: t-dll-api.cc,v $ + * Revision 1.62 2001/08/10 00:40:45 steve + * tgt-vvp generates code that skips nets as inputs. + * * Revision 1.61 2001/07/28 01:17:40 steve * Support getting the signal from IVL_EX_SIGNAL expressions. * diff --git a/t-dll.cc b/t-dll.cc index 70a77ec64..4e256c8ea 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.56 2001/07/25 03:10:50 steve Exp $" +#ident "$Id: t-dll.cc,v 1.57 2001/08/10 00:40:45 steve Exp $" #endif # include "config.h" @@ -180,6 +180,7 @@ ivl_memory_t dll_target::lookup_memory_(const NetMemory*cur) static ivl_nexus_t nexus_sig_make(ivl_signal_t net, unsigned pin) { ivl_nexus_t tmp = new struct ivl_nexus_s; + tmp->private_data = 0; tmp->nptr_ = 1; tmp->ptrs_ = (struct ivl_nexus_ptr_s*) malloc(sizeof(struct ivl_nexus_ptr_s)); @@ -1484,6 +1485,9 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj }; /* * $Log: t-dll.cc,v $ + * Revision 1.57 2001/08/10 00:40:45 steve + * tgt-vvp generates code that skips nets as inputs. + * * Revision 1.56 2001/07/25 03:10:50 steve * Create a config.h.in file to hold all the config * junk, and support gcc 3.0. (Stephan Boettcher) diff --git a/t-dll.h b/t-dll.h index 062427d4e..ea8d3a4c6 100644 --- a/t-dll.h +++ b/t-dll.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: t-dll.h,v 1.58 2001/07/27 04:51:44 steve Exp $" +#ident "$Id: t-dll.h,v 1.59 2001/08/10 00:40:45 steve Exp $" #endif # include "target.h" @@ -391,6 +391,7 @@ struct ivl_nexus_s { unsigned nptr_; struct ivl_nexus_ptr_s*ptrs_; char*name_; + void*private_data; }; @@ -561,6 +562,9 @@ struct ivl_statement_s { /* * $Log: t-dll.h,v $ + * Revision 1.59 2001/08/10 00:40:45 steve + * tgt-vvp generates code that skips nets as inputs. + * * Revision 1.58 2001/07/27 04:51:44 steve * Handle part select expressions as variants of * NetESignal/IVL_EX_SIGNAL objects, instead of diff --git a/tgt-vvp/README.txt b/tgt-vvp/README.txt index 0d0988ca1..4242b1b09 100644 --- a/tgt-vvp/README.txt +++ b/tgt-vvp/README.txt @@ -16,3 +16,18 @@ full hierarchical name of the signal. Logic devices (and, or, buf, bufz, etc.) are named L_. In this case the symbol is attached to a functor that is the output of the logic device. + + +GENERAL FUNCTOR WEB STRUCTURE + +The net of gates, signals and resolvers is formed from the input +design. The basic structure is wrapped around the nexus, which is +represented by the ivl_nexus_t. + +Each nexus represents a resolved value. The input of the nexus is fed +by a single driver. If the nexus in the design has multiple drivers, +the drivers are first fed into a resolver (or a tree of resolvers) to +form a single output that is the nexus. + +The nexus, then, feeds its output to the inputs of other gates, or to +the .net objects in the design. \ No newline at end of file diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index 78c7d18f3..ccb7f2860 100644 --- a/tgt-vvp/vvp_scope.c +++ b/tgt-vvp/vvp_scope.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vvp_scope.c,v 1.44 2001/08/03 17:06:10 steve Exp $" +#ident "$Id: vvp_scope.c,v 1.45 2001/08/10 00:40:45 steve Exp $" #endif # include "vvp_priv.h" @@ -253,15 +253,33 @@ static const char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr) return "C"; } +/* + * This function draws the input to a net. What that means is that it + * returns a static string that can be used to represent a resolved + * driver to a nexus. If there are multiple drivers to the nexus, then + * it writes out the resolver declarations needed to perform strength + * resolution. + * + * The string that this returns must be copied out before this + * function is called again. Otherwise, the string memory will be + * overwritten. + */ static const char* draw_net_input(ivl_nexus_t nex) { - static char result[512]; + char result[512]; unsigned idx; int level; unsigned ndrivers = 0; static ivl_nexus_ptr_t *drivers = 0x0; static unsigned adrivers = 0; + /* If this nexus already has a label, then its input is + already figured out. Just return the existing label. */ + const char*nex_private = (const char*)ivl_nexus_get_private(nex); + if (nex_private) + return nex_private; + + for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { ivl_nexus_ptr_t nptr = ivl_nexus_ptr(nex, idx); @@ -283,13 +301,19 @@ static const char* draw_net_input(ivl_nexus_t nex) /* If the nexus has no drivers, then send a constant HiZ into the net. */ - if (ndrivers == 0) - return "C"; + if (ndrivers == 0) { + nex_private = "C"; + ivl_nexus_set_private(nex, nex_private); + return nex_private; + } /* If the nexus has exactly one driver, then simply draw it. */ - if (ndrivers == 1) - return draw_net_input_drive(nex, drivers[0]); + if (ndrivers == 1) { + nex_private = strdup(draw_net_input_drive(nex, drivers[0])); + ivl_nexus_set_private(nex, nex_private); + return nex_private; + } level = 0; while (ndrivers) { @@ -327,18 +351,21 @@ static const char* draw_net_input(ivl_nexus_t nex) } sprintf(result, "RS_%s", vvp_mangle_id(ivl_nexus_name(nex))); - return result; + nex_private = strdup(result); + ivl_nexus_set_private(nex, nex_private); + return nex_private; } /* - * This function looks at the nexus in search for the net to attach + * This function looks at the nexus in search of the net to attach * functor inputs to. Sort the signals in the nexus by name, and * choose the lexically earliest one. */ -void draw_input_from_net(ivl_nexus_t nex) +static void draw_input_from_net(ivl_nexus_t nex) { +#if 0 unsigned idx; ivl_signal_t sig = 0; unsigned sig_pin = 0; @@ -367,6 +394,13 @@ void draw_input_from_net(ivl_nexus_t nex) assert(sig); fprintf(vvp_out, "V_%s[%u]", vvp_mangle_id(ivl_signal_name(sig)), sig_pin); +#else + const char*nex_private = (const char*)ivl_nexus_get_private(nex); + if (nex_private == 0) + nex_private = draw_net_input(nex); + assert(nex_private); + fprintf(vvp_out, "%s", nex_private); +#endif } /* @@ -376,6 +410,7 @@ void draw_input_from_net(ivl_nexus_t nex) */ static void draw_reg_in_scope(ivl_signal_t sig) { + unsigned idx; int msb = ivl_signal_pins(sig) - 1; int lsb = 0; @@ -384,46 +419,14 @@ static void draw_reg_in_scope(ivl_signal_t sig) fprintf(vvp_out, "V_%s .var%s \"%s\", %d, %d;\n", vvp_mangle_id(ivl_signal_name(sig)), signed_flag, vvp_mangle_name(ivl_signal_basename(sig)), msb, lsb); -} -/* - * This function takes a nexus and a signal, and finds the next signal - * (lexically) that is connected to at the same nexus. Return the - * ivl_nexus_ptr_t object to represent that junction. - */ -static ivl_nexus_ptr_t find_net_just_after(ivl_nexus_t nex, - ivl_signal_t sig) -{ - ivl_nexus_ptr_t res = 0; - ivl_signal_t res_sig = 0; - unsigned idx; - - for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { - ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx); - ivl_signal_t tmp = ivl_nexus_ptr_sig(ptr); - - if (tmp == 0) - continue; - - if (strcmp(ivl_signal_name(tmp),ivl_signal_name(sig)) <= 0) - continue; - - if (res == 0) { - res = ptr; - res_sig = tmp; - continue; - } - - if (strcmp(ivl_signal_name(tmp),ivl_signal_name(res_sig)) < 0) { - res = ptr; - res_sig = tmp; - } + /* Attach input information to the nexus. */ + for (idx = 0 ; idx < ivl_signal_pins(sig) ; idx += 1) { + ivl_nexus_t nex = ivl_signal_pin(sig, idx); + draw_net_input(nex); } - - return res; } - /* * This function draws a net. This is a bit more complicated as we * have to find an appropriate functor to connect to the input. @@ -441,19 +444,9 @@ static void draw_net_in_scope(ivl_signal_t sig) /* Connect all the pins of the signal to something. */ for (idx = 0 ; idx < ivl_signal_pins(sig) ; idx += 1) { - ivl_nexus_ptr_t ptr; ivl_nexus_t nex = ivl_signal_pin(sig, idx); - ptr = find_net_just_after(nex, sig); - if (ptr) { - char tmp[512]; - sprintf(tmp, "V_%s[%u]", - vvp_mangle_id(ivl_signal_name(ivl_nexus_ptr_sig(ptr))), - ivl_nexus_ptr_pin(ptr)); - args[idx] = strdup(tmp); - } else { - args[idx] = strdup(draw_net_input(nex)); - } + args[idx] = draw_net_input(nex); } fprintf(vvp_out, "V_%s .net%s \"%s\", %d, %d", @@ -461,7 +454,6 @@ static void draw_net_in_scope(ivl_signal_t sig) vvp_mangle_name(ivl_signal_basename(sig)), msb, lsb); for (idx = 0 ; idx < ivl_signal_pins(sig) ; idx += 1) { fprintf(vvp_out, ", %s", args[idx]); - free(args[idx]); } fprintf(vvp_out, ";\n"); @@ -1136,6 +1128,9 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent) /* * $Log: vvp_scope.c,v $ + * Revision 1.45 2001/08/10 00:40:45 steve + * tgt-vvp generates code that skips nets as inputs. + * * Revision 1.44 2001/08/03 17:06:10 steve * More detailed messages about unsupported things. * @@ -1182,103 +1177,5 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent) * Generate vvp code for GT and GE comparisons. * * Revision 1.31 2001/06/07 04:20:10 steve - * Account for carry out on add devices. - * - * Revision 1.30 2001/06/07 03:09:37 steve - * support subtraction in tgt-vvp. - * - * Revision 1.29 2001/06/07 02:12:43 steve - * Support structural addition. - * - * Revision 1.28 2001/05/12 16:34:47 steve - * Fixup the resolver syntax. - * - * Revision 1.27 2001/05/12 03:31:01 steve - * Generate resolvers for multiple drivers. - * - * Revision 1.26 2001/05/08 23:59:33 steve - * Add ivl and vvp.tgt support for memories in - * expressions and l-values. (Stephan Boettcher) - * - * Revision 1.25 2001/05/06 00:01:02 steve - * Generate code that causes the value of a net to be passed - * passed through all nets of a nexus. - * - * Revision 1.24 2001/05/03 04:55:46 steve - * Generate code for the fully general event or. - * - * Revision 1.23 2001/05/02 04:05:16 steve - * Remove the init parameter of functors, and instead use - * the special C symbols to initialize inputs. This is - * clearer and more regular. - * - * Revision 1.22 2001/04/30 00:00:27 steve - * detect multiple drivers on nexa. - * - * Revision 1.21 2001/04/29 23:16:31 steve - * Add bufif and pull devices. - * - * Revision 1.20 2001/04/26 05:12:02 steve - * Implement simple MUXZ for ?: operators. - * - * Revision 1.19 2001/04/24 02:59:52 steve - * Fix generation of udp/comb definitions. - * - * 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. - * - * Revision 1.16 2001/04/15 16:37:48 steve - * add XOR support. - * - * Revision 1.15 2001/04/14 05:11:49 steve - * Use event/or for wide anyedge statements. - * - * Revision 1.14 2001/04/06 02:28:03 steve - * Generate vvp code for functions with ports. - * - * Revision 1.13 2001/04/05 01:38:24 steve - * Generate signed .net and .var statements. - * - * Revision 1.12 2001/04/02 02:28:13 steve - * Generate code for task calls. - * - * Revision 1.11 2001/04/01 21:34:48 steve - * Recognize the BUF device. - * - * Revision 1.10 2001/04/01 01:48:21 steve - * Redesign event information to support arbitrary edge combining. - * - * Revision 1.9 2001/03/31 19:29:23 steve - * Fix compilation warnings. - * - * Revision 1.8 2001/03/29 03:47:13 steve - * events can take up to 4 inputs. - * - * Revision 1.7 2001/03/28 06:07:40 steve - * Add the ivl_event_t to ivl_target, and use that to generate - * .event statements in vvp way ahead of the thread that uses it. - * - * Revision 1.6 2001/03/27 06:27:41 steve - * Generate code for simple @ statements. - * - * Revision 1.5 2001/03/25 19:36:12 steve - * Draw AND NOR and NOT gates. - * - * Revision 1.4 2001/03/25 05:59:47 steve - * Recursive make check target. - * - * Revision 1.3 2001/03/25 03:53:40 steve - * Include signal bit index in functor input. - * - * Revision 1.2 2001/03/25 03:25:43 steve - * Generate .net statements, and nexus inputs. - * - * Revision 1.1 2001/03/21 01:49:43 steve - * Scan the scopes of a design, and draw behavioral - * blocking assignments of constants to vectors. - * */