From 0d9ed65e8c4588294bfb6122141ebc2e4701a2f2 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Wed, 31 Oct 2007 21:39:29 -0700 Subject: [PATCH 1/6] Give delay paths scope. Delay paths need a scope. This helps the code generators bind the modpaths to the correct scope. This patch doesn't actually make use of the information, it just makes it available to code generators. Signed-off-by: Stephen Williams --- design_dump.cc | 2 +- ivl.def | 1 + ivl_target.h | 5 +++++ t-dll-api.cc | 7 +++++++ t-dll.cc | 1 + t-dll.h | 1 + tgt-stub/stub.c | 3 ++- 7 files changed, 18 insertions(+), 2 deletions(-) diff --git a/design_dump.cc b/design_dump.cc index 34551f4d2..016cc5b6d 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -128,7 +128,7 @@ void NetDelaySrc::dump(ostream&o, unsigned ind) const << "/" << transition_delays_[IVL_PE_x0] << "," << transition_delays_[IVL_PE_xz] << "," << transition_delays_[IVL_PE_zx] - << "): " << endl; + << ") scope=" << scope_path(scope()) << endl; dump_node_pins(o, ind+4); } diff --git a/ivl.def b/ivl.def index 65a0e7cbf..ba7b44444 100644 --- a/ivl.def +++ b/ivl.def @@ -111,6 +111,7 @@ ivl_parameter_expr ivl_path_condit ivl_path_delay +ivl_path_scope ivl_path_source ivl_path_source_negedge ivl_path_source_posedge diff --git a/ivl_target.h b/ivl_target.h index 7b06582ae..5d75dd150 100644 --- a/ivl_target.h +++ b/ivl_target.h @@ -385,6 +385,10 @@ typedef const struct ivl_attribute_s*ivl_attribute_t; * block in the verilog source file. The destination signal references * the path object, which in turn points to the source for the path. * + * ivl_path_scope + * This returns the scope of the delay path. This scope corresponds + * to the scope of the specify-block that led to this path. + * * ivl_path_source * This returns the nexus that is the source end of the delay * path. Transitions on the source are the start of the delay time @@ -398,6 +402,7 @@ typedef const struct ivl_attribute_s*ivl_attribute_t; * ivl_path_source_negedge * These functions return true if the source is edge sensitive. */ +extern ivl_scope_t ivl_path_scope(ivl_delaypath_t obj); extern ivl_nexus_t ivl_path_source(ivl_delaypath_t obj); extern uint64_t ivl_path_delay(ivl_delaypath_t obj, ivl_path_edge_t pt); extern ivl_nexus_t ivl_path_condit(ivl_delaypath_t obj); diff --git a/t-dll-api.cc b/t-dll-api.cc index 0d74ef637..191e130e8 100644 --- a/t-dll-api.cc +++ b/t-dll-api.cc @@ -1264,6 +1264,13 @@ extern uint64_t ivl_path_delay(ivl_delaypath_t obj, ivl_path_edge_t edg) return obj->delay[edg]; } +extern ivl_scope_t ivl_path_scope(ivl_delaypath_t obj) +{ + assert(obj); + assert(obj->scope); + return obj->scope; +} + extern ivl_nexus_t ivl_path_source(ivl_delaypath_t net) { return net->src; diff --git a/t-dll.cc b/t-dll.cc index b8d068669..b44e4e5f3 100644 --- a/t-dll.cc +++ b/t-dll.cc @@ -2242,6 +2242,7 @@ bool dll_target::signal_paths(const NetNet*net) << "." << endl; } assert(nex->t_cookie()); + obj->path[ptr].scope = lookup_scope_(src->scope()); obj->path[ptr].src = nex->t_cookie(); obj->path[ptr].condit = path_condit; obj->path[ptr].posedge = src->is_posedge(); diff --git a/t-dll.h b/t-dll.h index b1e0a1949..faea12b63 100644 --- a/t-dll.h +++ b/t-dll.h @@ -175,6 +175,7 @@ struct dll_target : public target_t, public expr_scan_t { */ struct ivl_delaypath_s { + ivl_scope_t scope; ivl_nexus_t src; ivl_nexus_t condit; bool posedge; diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index 468b7dd05..fd1bd3b42 100644 --- a/tgt-stub/stub.c +++ b/tgt-stub/stub.c @@ -1141,7 +1141,7 @@ static void show_signal(ivl_signal_t net) fprintf(out, " %" PRIu64 ",%" PRIu64 ",%" PRIu64 " %" PRIu64 ",%" PRIu64 ",%" PRIu64 " %" PRIu64 ",%" PRIu64 ",%" PRIu64 - " %" PRIu64 ",%" PRIu64 ",%" PRIu64 "\n", + " %" PRIu64 ",%" PRIu64 ",%" PRIu64, ivl_path_delay(path, IVL_PE_01), ivl_path_delay(path, IVL_PE_10), ivl_path_delay(path, IVL_PE_0z), @@ -1154,6 +1154,7 @@ static void show_signal(ivl_signal_t net) ivl_path_delay(path, IVL_PE_x0), ivl_path_delay(path, IVL_PE_xz), ivl_path_delay(path, IVL_PE_zx)); + fprintf(out, " scope=%s\n", ivl_scope_name(ivl_path_scope(path))); } for (idx = 0 ; idx < ivl_signal_attr_cnt(net) ; idx += 1) { From 5c69e243acbb99abe52c23fbb077c8cddf6e54c7 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Wed, 31 Oct 2007 21:45:34 -0700 Subject: [PATCH 2/6] Put modpaths in correct scope. Modpaths need to be in the proper scope in order to be available to vpi functions. The code generator manages that by writing the modpath records with scope switch functions. Batch the modpath records at the end of the structural stuff so that the scope switching doesn't cause trouble. Also seperate the modpath code into its own source file. Signed-off-by: Stephen Williams --- tgt-vvp/Makefile.in | 2 +- tgt-vvp/modpath.c | 123 +++++++++++++++++++++++++++++++++++++++ tgt-vvp/vvp.c | 4 ++ tgt-vvp/vvp_priv.h | 138 +++++--------------------------------------- tgt-vvp/vvp_scope.c | 64 +------------------- 5 files changed, 144 insertions(+), 187 deletions(-) create mode 100644 tgt-vvp/modpath.c diff --git a/tgt-vvp/Makefile.in b/tgt-vvp/Makefile.in index 399e033a2..c9b6b5098 100644 --- a/tgt-vvp/Makefile.in +++ b/tgt-vvp/Makefile.in @@ -52,7 +52,7 @@ dep: mv $*.d dep O = vvp.o draw_mux.o draw_ufunc.o draw_vpi.o eval_bool.o eval_expr.o \ -eval_real.o vector.o \ +eval_real.o modpath.o vector.o \ vvp_process.o vvp_scope.o ifeq (@WIN32@,yes) diff --git a/tgt-vvp/modpath.c b/tgt-vvp/modpath.c new file mode 100644 index 000000000..ba9f80819 --- /dev/null +++ b/tgt-vvp/modpath.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2007 Stephen Williams (steve@icarus.com) + * + * 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 + */ + +# include "vvp_priv.h" +# include +# include +# include + +/* +* Draw a .modpath record. The label is the label to use for this +* record. The driver is the label of the net that feeds into the +* modpath device. (Note that there is only 1 driver.) The path_sig is +* the signal that is the output of this modpath. From that signal we +* can find all the modpath source nodes to generate the complete +* modpath record. +*/ +static void draw_modpath_record(const char*label, const char*driver, + ivl_signal_t path_sig) +{ + unsigned idx; + typedef const char*ccharp; + ccharp*src_drivers; + ccharp*con_drivers; + + src_drivers = calloc(ivl_signal_npath(path_sig), sizeof(ccharp)); + con_drivers = calloc(ivl_signal_npath(path_sig), sizeof(ccharp)); + for (idx = 0 ; idx < ivl_signal_npath(path_sig) ; idx += 1) { + ivl_delaypath_t path = ivl_signal_path(path_sig, idx); + ivl_nexus_t src = ivl_path_source(path); + ivl_nexus_t con = ivl_path_condit(path); + + src_drivers[idx] = draw_net_input(src); + + if (con) con_drivers[idx] = draw_net_input(con); + else con_drivers[idx] = 0; + } + + fprintf(vvp_out, " .scope S_%p;\n", ivl_path_scope(ivl_signal_path(path_sig,0))); + fprintf(vvp_out, "%s .modpath %s", label, driver); + + for (idx = 0 ; idx < ivl_signal_npath(path_sig); idx += 1) { + ivl_delaypath_t path = ivl_signal_path(path_sig, idx); + int ppos = ivl_path_source_posedge(path); + int pneg = ivl_path_source_negedge(path); + const char*edge = ppos? " +" : pneg ? " -" : ""; + fprintf(vvp_out, ",\n %s%s", src_drivers[idx], edge); + fprintf(vvp_out, + " (%"PRIu64",%"PRIu64",%"PRIu64 + ", %"PRIu64",%"PRIu64",%"PRIu64 + ", %"PRIu64",%"PRIu64",%"PRIu64 + ", %"PRIu64",%"PRIu64",%"PRIu64, + ivl_path_delay(path, IVL_PE_01), + ivl_path_delay(path, IVL_PE_10), + ivl_path_delay(path, IVL_PE_0z), + ivl_path_delay(path, IVL_PE_z1), + ivl_path_delay(path, IVL_PE_1z), + ivl_path_delay(path, IVL_PE_z0), + ivl_path_delay(path, IVL_PE_0x), + ivl_path_delay(path, IVL_PE_x1), + ivl_path_delay(path, IVL_PE_1x), + ivl_path_delay(path, IVL_PE_x0), + ivl_path_delay(path, IVL_PE_xz), + ivl_path_delay(path, IVL_PE_zx)); + + if (con_drivers[idx]) { + fprintf(vvp_out, " ? %s", con_drivers[idx]); + } + + fprintf(vvp_out, ")"); + } + + fprintf(vvp_out, ";\n"); + + free(src_drivers); + free(con_drivers); +} + +struct modpath_item { + ivl_signal_t path_sig; + char*drive_label; + struct modpath_item*next; +}; + +static struct modpath_item*modpath_list = 0; + +void draw_modpath(ivl_signal_t path_sig, char*drive_label) +{ + struct modpath_item*cur = calloc(1, sizeof(struct modpath_item)); + cur->path_sig = path_sig; + cur->drive_label = drive_label; + cur->next = modpath_list; + modpath_list = cur; +} + +void cleanup_modpath(void) +{ + while (modpath_list) { + struct modpath_item*cur = modpath_list; + modpath_list = cur->next; + + char modpath_label[64]; + snprintf(modpath_label, sizeof modpath_label, "V_%p/m", cur->path_sig); + draw_modpath_record(modpath_label, cur->drive_label, cur->path_sig); + free(cur->drive_label); + free(cur); + } +} diff --git a/tgt-vvp/vvp.c b/tgt-vvp/vvp.c index ef714e2fb..597e171bd 100644 --- a/tgt-vvp/vvp.c +++ b/tgt-vvp/vvp.c @@ -95,10 +95,14 @@ int target_design(ivl_design_t des) draw_module_declarations(des); + /* This causes all structural records to be drawn. */ ivl_design_roots(des, &roots, &nroots); for (i = 0; i < nroots; i++) draw_scope(roots[i], 0); + /* Finish up any modpaths that are not yet emitted. */ + cleanup_modpath(); + rc = ivl_design_process(des, draw_process, 0); fclose(vvp_out); diff --git a/tgt-vvp/vvp_priv.h b/tgt-vvp/vvp_priv.h index 69cf61e4e..02a94b9cb 100644 --- a/tgt-vvp/vvp_priv.h +++ b/tgt-vvp/vvp_priv.h @@ -18,9 +18,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#ifdef HAVE_CVS_IDENT -#ident "$Id: vvp_priv.h,v 1.43 2007/02/26 19:49:50 steve Exp $" -#endif # include "vvp_config.h" # include "ivl_target.h" @@ -69,6 +66,20 @@ extern void draw_lpm_mux(ivl_lpm_t net); extern struct vector_info draw_ufunc_expr(ivl_expr_t exp, unsigned wid); extern int draw_ufunc_real(ivl_expr_t exp); +/* + * modpath.c symbols. + * + * draw_modpath arranges for a .modpath record to be written out. + * + * cleanup_modpath() cleans up any pending .modpath records that may + * have been scheduled by draw_modpath() but not yet writte. + * + * Note: draw_modpath drive_label must be malloc'ed by the + * caller. This function will free the string sometime in the future. + */ +extern void draw_modpath(ivl_signal_t path_sig, char*drive_label); +extern void cleanup_modpath(void); + /* * This function draws the execution of a vpi_call statement, along * with the tricky handling of arguments. If this is called with a @@ -242,125 +253,4 @@ extern void clr_word(int idx); extern unsigned local_count; extern unsigned thread_count; -/* - * $Log: vvp_priv.h,v $ - * Revision 1.43 2007/02/26 19:49:50 steve - * Spelling fixes (larry doolittle) - * - * Revision 1.42 2007/01/17 04:39:18 steve - * Remove dead code related to memories. - * - * Revision 1.41 2007/01/16 05:44:16 steve - * Major rework of array handling. Memories are replaced with the - * more general concept of arrays. The NetMemory and NetEMemory - * classes are removed from the ivl core program, and the IVL_LPM_RAM - * lpm type is removed from the ivl_target API. - * - * Revision 1.40 2006/02/02 02:43:59 steve - * Allow part selects of memory words in l-values. - * - * Revision 1.39 2005/10/12 17:26:17 steve - * MUX nodes get inputs from nets, not from net inputs, - * Detect and draw alias nodes to reduce net size and - * handle force confusion. - * - * Revision 1.38 2005/10/11 18:30:50 steve - * Remove obsolete vvp_memory_label function. - * - * Revision 1.37 2005/10/10 04:16:13 steve - * Remove dead dram_input_from_net and lpm_inputs_a_b - * - * Revision 1.36 2005/09/17 01:01:00 steve - * More robust use of precalculated expressions, and - * Separate lookaside for written variables that can - * also be reused. - * - * Revision 1.35 2005/09/15 02:50:13 steve - * Preserve precalculated expressions when possible. - * - * Revision 1.34 2005/09/14 02:53:15 steve - * Support bool expressions and compares handle them optimally. - * - * Revision 1.33 2005/09/01 04:11:37 steve - * Generate code to handle real valued muxes. - * - * Revision 1.32 2005/08/06 17:58:16 steve - * Implement bi-directional part selects. - * - * Revision 1.31 2005/07/13 04:52:31 steve - * Handle functions with real values. - * - * Revision 1.30 2005/07/11 16:56:51 steve - * Remove NetVariable and ivl_variable_t structures. - * - * Revision 1.29 2004/12/11 02:31:28 steve - * Rework of internals to carry vectors through nexus instead - * of single bits. Make the ivl, tgt-vvp and vvp initial changes - * down this path. - * - * Revision 1.28 2004/01/20 21:00:47 steve - * Isolate configure from containing config.h - * - * Revision 1.27 2003/06/17 19:17:42 steve - * Remove short int restrictions from vvp opcodes. - * - * Revision 1.26 2003/06/05 04:18:50 steve - * Better width testing for thread vector allocation. - * - * Revision 1.25 2003/03/15 04:45:18 steve - * Allow real-valued vpi functions to have arguments. - * - * Revision 1.24 2003/02/28 20:21:13 steve - * Merge vpi_call and vpi_func draw functions. - * - * Revision 1.23 2003/01/26 21:16:00 steve - * Rework expression parsing and elaboration to - * accommodate real/realtime values and expressions. - * - * Revision 1.22 2002/09/27 16:33:34 steve - * Add thread expression lookaside map. - * - * Revision 1.21 2002/09/24 04:20:32 steve - * Allow results in register bits 47 in certain cases. - * - * Revision 1.20 2002/09/13 03:12:50 steve - * Optimize ==1 when in context where x vs z doesnt matter. - * - * Revision 1.19 2002/08/27 05:39:57 steve - * Fix l-value indexing of memories and vectors so that - * an unknown (x) index causes so cell to be addresses. - * - * Fix tangling of label identifiers in the fork-join - * code generator. - * - * Revision 1.18 2002/08/12 01:35:04 steve - * conditional ident string using autoconfig. - * - * Revision 1.17 2002/08/04 18:28:15 steve - * Do not use hierarchical names of memories to - * generate vvp labels. -tdll target does not - * used hierarchical name string to look up the - * memory objects in the design. - * - * Revision 1.16 2002/08/03 22:30:48 steve - * Eliminate use of ivl_signal_name for signal labels. - * - * Revision 1.15 2002/07/08 04:04:07 steve - * Generate code for wide muxes. - * - * Revision 1.14 2002/06/02 18:57:17 steve - * Generate %cmpi/u where appropriate. - * - * Revision 1.13 2002/04/22 02:41:30 steve - * Reduce the while loop expression if needed. - * - * Revision 1.12 2001/11/01 04:26:57 steve - * Generate code for deassign and cassign. - * - * Revision 1.11 2001/06/18 03:10:34 steve - * 1. Logic with more than 4 inputs - * 2. Id and name mangling - * 3. A memory leak in draw_net_in_scope() - * (Stephan Boettcher) - */ #endif diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index 026c70816..45cbed5ae 100644 --- a/tgt-vvp/vvp_scope.c +++ b/tgt-vvp/vvp_scope.c @@ -680,66 +680,6 @@ static char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr) return strdup("C"); } -static void draw_modpath(const char*label, const char*driver, - ivl_signal_t path_sig) -{ - unsigned idx; - typedef const char*ccharp; - ccharp*src_drivers; - ccharp*con_drivers; - - src_drivers = calloc(ivl_signal_npath(path_sig), sizeof(ccharp)); - con_drivers = calloc(ivl_signal_npath(path_sig), sizeof(ccharp)); - for (idx = 0 ; idx < ivl_signal_npath(path_sig) ; idx += 1) { - ivl_delaypath_t path = ivl_signal_path(path_sig, idx); - ivl_nexus_t src = ivl_path_source(path); - ivl_nexus_t con = ivl_path_condit(path); - - src_drivers[idx] = draw_net_input(src); - - if (con) con_drivers[idx] = draw_net_input(con); - else con_drivers[idx] = 0; - } - - fprintf(vvp_out, "%s .modpath %s", label, driver); - - for (idx = 0 ; idx < ivl_signal_npath(path_sig); idx += 1) { - ivl_delaypath_t path = ivl_signal_path(path_sig, idx); - int ppos = ivl_path_source_posedge(path); - int pneg = ivl_path_source_negedge(path); - const char*edge = ppos? " +" : pneg ? " -" : ""; - fprintf(vvp_out, ",\n %s%s", src_drivers[idx], edge); - fprintf(vvp_out, - " (%"PRIu64",%"PRIu64",%"PRIu64 - ", %"PRIu64",%"PRIu64",%"PRIu64 - ", %"PRIu64",%"PRIu64",%"PRIu64 - ", %"PRIu64",%"PRIu64",%"PRIu64, - ivl_path_delay(path, IVL_PE_01), - ivl_path_delay(path, IVL_PE_10), - ivl_path_delay(path, IVL_PE_0z), - ivl_path_delay(path, IVL_PE_z1), - ivl_path_delay(path, IVL_PE_1z), - ivl_path_delay(path, IVL_PE_z0), - ivl_path_delay(path, IVL_PE_0x), - ivl_path_delay(path, IVL_PE_x1), - ivl_path_delay(path, IVL_PE_1x), - ivl_path_delay(path, IVL_PE_x0), - ivl_path_delay(path, IVL_PE_xz), - ivl_path_delay(path, IVL_PE_zx)); - - if (con_drivers[idx]) { - fprintf(vvp_out, " ? %s", con_drivers[idx]); - } - - fprintf(vvp_out, ")"); - } - - fprintf(vvp_out, ";\n"); - - free(src_drivers); - free(con_drivers); -} - static int nexus_drive_is_strength_aware(ivl_nexus_ptr_t nptr) { if (ivl_nexus_ptr_drive0(nptr) != IVL_DR_STRONG) @@ -908,9 +848,9 @@ static char* draw_net_input_x(ivl_nexus_t nex, char modpath_label[64]; snprintf(modpath_label, sizeof modpath_label, "V_%p/m", path_sig); - draw_modpath(modpath_label, nex_str, path_sig); nex_private = strdup(modpath_label); - free(nex_str); + draw_modpath(path_sig, nex_str); + } else { nex_private = draw_net_input_drive(nex, drivers[0]); } From 68cf5baba510c76e269b98e219d4d329d7583bf1 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Fri, 2 Nov 2007 19:59:08 -0700 Subject: [PATCH 3/6] Out path term for modpaths Add vvp support for modpath path term outputs. This also introduces the concept of path terms and moves towards the path term in general for getting at the endpoits of a modpath. --- vpi_user.h | 2 ++ vvp/compile.cc | 9 ++++-- vvp/compile.h | 4 ++- vvp/delay.cc | 80 ++++++++++++++++++++++++++++++++++++++------------ vvp/parse.y | 20 ++++++------- vvp/vpi_priv.h | 8 +++++ 6 files changed, 90 insertions(+), 33 deletions(-) diff --git a/vpi_user.h b/vpi_user.h index d255f56d4..c7662f853 100644 --- a/vpi_user.h +++ b/vpi_user.h @@ -282,6 +282,7 @@ typedef struct t_vpi_delay { #define vpiNamedFork 35 #define vpiNet 36 #define vpiParameter 41 +#define vpiPathTerm 43 #define vpiRealVar 47 #define vpiReg 48 #define vpiSysFuncCall 56 @@ -331,6 +332,7 @@ typedef struct t_vpi_delay { # define vpiSysFuncTime vpiTimeFunc # define vpiSysFuncSized vpiSizedFunc #define vpiSigned 65 +#define vpiExpr 102 /* IVL private properties */ #define _vpiNexusId 0x1000000 diff --git a/vvp/compile.cc b/vvp/compile.cc index 46765f823..ed3ec4a4d 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -1120,19 +1120,22 @@ void compile_extend_signed(char*label, long wid, struct symb_s arg) input_connect(ptr, 0, arg.text); } -struct __vpiModPath* compile_modpath(char*label, struct symb_s src) +struct __vpiModPath* compile_modpath(char*label, struct symb_s drv, + struct symb_s dest) { vvp_net_t*net = new vvp_net_t; vvp_fun_modpath*obj = new vvp_fun_modpath(net); net->fun = obj; - input_connect(net, 0, src.text); + input_connect(net, 0, drv.text); define_functor_symbol(label, net); - vpiHandle tmp = vpip_make_modpath(label, src.text, net); + vpiHandle tmp = vpip_make_modpath(label, drv.text, net); __vpiModPath*modpath = vpip_modpath_from_handle(tmp); + compile_vpi_lookup(&modpath->path_term_out.expr, dest.text); + modpath->modpath = obj; return modpath; } diff --git a/vvp/compile.h b/vvp/compile.h index 05edb50c4..05b51aff8 100644 --- a/vvp/compile.h +++ b/vvp/compile.h @@ -175,7 +175,9 @@ extern void compile_dff(char*label, struct symb_s arg_a); class __vpiModPath; -extern __vpiModPath* compile_modpath(char*label, struct symb_s src); +extern __vpiModPath* compile_modpath(char*label, + struct symb_s drv, + struct symb_s dest); extern void compile_modpath_src(__vpiModPath*dst, char edge, struct symb_s input, diff --git a/vvp/delay.cc b/vvp/delay.cc index 8642e1208..d89893338 100644 --- a/vvp/delay.cc +++ b/vvp/delay.cc @@ -756,24 +756,24 @@ static vpiHandle modpath_put_value(vpiHandle ref, s_vpi_value *vp ) static vpiHandle modpath_get_handle(int code, vpiHandle ref) { - assert( (ref->vpi_type->type_code==vpiModPath) ); - struct __vpiModPath *rfp = (struct __vpiModPath *)ref ; + struct __vpiModPath *rfp = vpip_modpath_from_handle(ref); + assert(rfp); - switch (code) - { - case vpiScope: - return &rfp->scope->base ; - - case vpiModule: - { - struct __vpiScope*scope = rfp->scope; - while (scope && scope->base.vpi_type->type_code != vpiModule) - scope = scope->scope; - - assert(scope); - return &scope->base; - } - } + switch (code) { + case vpiScope: + return vpi_handle(rfp->scope); + + case vpiModule: + { struct __vpiScope*scope = rfp->scope; + while (scope && scope->base.vpi_type->type_code != vpiModule) + scope = scope->scope; + assert(scope); + return vpi_handle(scope); + } + + case vpiModPathOut: + return vpi_handle(&rfp->path_term_out); + } return 0; } @@ -798,6 +798,18 @@ static int modpath_free_object( vpiHandle ref ) return 1 ; } +static vpiHandle pathterm_get_handle(int code, vpiHandle ref) +{ + struct __vpiModPathTerm*obj = vpip_modpath_term_from_handle(ref); + assert(obj); + + switch (code) { + case vpiExpr: + return obj->expr; + default: + return 0; + } +} /* @@ -819,6 +831,26 @@ static const struct __vpirt vpip_modpath_rt = { 0 // modpath_put_delays }; +static const struct __vpirt vpip_modpath_term_rt = { + vpiPathTerm, + 0, // vpi_get + 0, // vpi_get_str + 0, // vpi_get_value, + 0, // vpi_put_value, + pathterm_get_handle, + 0, // vpi_iterate, + 0, // vpi_index, + 0, // vpi_free_object, + 0, // vpi_get_delays, + 0 // vpi_put_delays +}; + +static void initialize_path_term(struct __vpiModPathTerm&obj) +{ + obj.base.vpi_type = &vpip_modpath_term_rt; + obj.expr = 0; +} + /* * This function will Construct a vpiModPath Object. * give a respective "net", and will point to his @@ -829,8 +861,10 @@ vpiHandle vpip_make_modpath ( char *name, char *input, vvp_net_t *net ) { struct __vpiModPath *obj = (struct __vpiModPath *) calloc (1, sizeof ( struct __vpiModPath ) ) ; - obj->base.vpi_type = &vpip_modpath_rt ; - obj->scope = vpip_peek_current_scope ( ); + obj->base.vpi_type = &vpip_modpath_rt ; + obj->scope = vpip_peek_current_scope ( ); + + initialize_path_term(obj->path_term_out); obj->name = (char *)calloc(strlen(name) + 1 , sizeof ( char )) ; strcpy ( obj->name, name ) ; @@ -858,6 +892,14 @@ struct __vpiModPath* vpip_modpath_from_handle(vpiHandle ref) return (struct __vpiModPath *) ref; } +struct __vpiModPathTerm* vpip_modpath_term_from_handle(vpiHandle ref) +{ + if (ref->vpi_type->type_code != vpiPathTerm) + return 0; + + return (struct __vpiModPathTerm*) ref; +} + /* this Routine will safetly convert a modpathsrc vpiHandle to a struct __vpiModPathSrc { }, This is equivalent ao diff --git a/vvp/parse.y b/vvp/parse.y index 47257808a..022ebc8ae 100644 --- a/vvp/parse.y +++ b/vvp/parse.y @@ -320,17 +320,17 @@ statement node takes two form, one with an array of constants and a single input, and another with an array of inputs. */ - | T_LABEL K_DELAY delay symbol ';' - { compile_delay($1, $3, $4); } - | T_LABEL K_DELAY symbols ';' - { struct symbv_s obj = $3; - compile_delay($1, obj.cnt, obj.vect); - } + | T_LABEL K_DELAY delay symbol ';' + { compile_delay($1, $3, $4); } + | T_LABEL K_DELAY symbols ';' + { struct symbv_s obj = $3; + compile_delay($1, obj.cnt, obj.vect); + } - | T_LABEL K_MODPATH symbol ',' - { modpath_dst = compile_modpath($1, $3); } - modpath_src_list ';' - { modpath_dst = 0; } + | T_LABEL K_MODPATH symbol symbol ',' + { modpath_dst = compile_modpath($1, $3, $4); } + modpath_src_list ';' + { modpath_dst = 0; } /* DFF nodes have an output and take exactly 4 inputs. */ diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index 4ff520eaa..1dcb7f8e1 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -253,6 +253,11 @@ struct __vpiModPathSrc { } ; +struct __vpiModPathTerm { + struct __vpiHandle base; + vpiHandle expr; +}; + /* * * The vpiMoaPath vpiHandle will define @@ -267,6 +272,8 @@ struct __vpiModPath { class vvp_fun_modpath*modpath; + struct __vpiModPathTerm path_term_out; + /* * The name, input must be removed * in future um ModPathSrc have no @@ -289,6 +296,7 @@ struct __vpiModPath { }; extern struct __vpiModPath* vpip_modpath_from_handle(vpiHandle ref); +extern struct __vpiModPathTerm* vpip_modpath_term_from_handle(vpiHandle ref); extern struct __vpiModPathSrc* vpip_modpath_src_from_handle(vpiHandle ref); From 5bcbd09ed927fd749863becc2db7083cfe5bb53f Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Mon, 5 Nov 2007 19:58:20 -0800 Subject: [PATCH 4/6] Make the modpath source define the VPI modpath object. The modpath source node defines the modpath object, and carries the nodes for the source expression. The modpath outputs are references by pointers to the vpiModPath that is not in itself a vpi object any more. This makes the VPI view of a module path look like the source-destinaiton pair that is the IEEE1364 description of the modpath. --- vvp/compile.cc | 42 +++--- vvp/compile.h | 7 +- vvp/delay.cc | 351 ++++++++++--------------------------------------- vvp/parse.y | 26 ++-- vvp/vpi_priv.h | 79 +++-------- 5 files changed, 136 insertions(+), 369 deletions(-) diff --git a/vvp/compile.cc b/vvp/compile.cc index ed3ec4a4d..71ba609e0 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -1131,17 +1131,20 @@ struct __vpiModPath* compile_modpath(char*label, struct symb_s drv, define_functor_symbol(label, net); - vpiHandle tmp = vpip_make_modpath(label, drv.text, net); - __vpiModPath*modpath = vpip_modpath_from_handle(tmp); + __vpiModPath*modpath = vpip_make_modpath(net); compile_vpi_lookup(&modpath->path_term_out.expr, dest.text); + free(label); + modpath->modpath = obj; return modpath; } -static vvp_net_t*make_modpath_src(struct __vpiModPath*path, char edge, - struct symb_s src, struct numbv_s vals) +static struct __vpiModPathSrc*make_modpath_src(struct __vpiModPath*path, + char edge, + struct symb_s src, + struct numbv_s vals) { vvp_fun_modpath*dst = path->modpath; @@ -1188,29 +1191,36 @@ static vvp_net_t*make_modpath_src(struct __vpiModPath*path, char edge, Compiling the delays values into actual modpath vpiHandle */ //vpip_add_mopdath_delay ( vpiobj, src.text, use_delay ) ; - vpiHandle srcobj = vpip_make_modpath_src ( src.text, use_delay, net ) ; - vpip_add_modpath_src (vpi_handle(path), srcobj); + struct __vpiModPathSrc* srcobj = vpip_make_modpath_src (path, use_delay, net) ; + vpip_attach_to_current_scope(vpi_handle(srcobj)); net->fun = obj; input_connect(net, 0, src.text); dst->add_modpath_src(obj); - return net; -} - -void compile_modpath_src(struct __vpiModPath*dst, char edge, - struct symb_s src, struct numbv_s vals) -{ - make_modpath_src(dst, edge, src, vals); + return srcobj; } void compile_modpath_src(struct __vpiModPath*dst, char edge, struct symb_s src, struct numbv_s vals, - struct symb_s condit_src) + struct symb_s condit_src, + struct symb_s path_term_in) { - vvp_net_t*net = make_modpath_src(dst, edge, src, vals); - input_connect(net, 1, condit_src.text); + struct __vpiModPathSrc*obj = make_modpath_src(dst, edge, src, vals); + input_connect(obj->net, 1, condit_src.text); + compile_vpi_lookup(&obj->path_term_in.expr, path_term_in.text); +} + +void compile_modpath_src(struct __vpiModPath*dst, char edge, + struct symb_s src, + struct numbv_s vals, + int condit_src, + struct symb_s path_term_in) +{ + assert(condit_src == 0); + struct __vpiModPathSrc*obj = make_modpath_src(dst, edge, src, vals); + compile_vpi_lookup(&obj->path_term_in.expr, path_term_in.text); } /* diff --git a/vvp/compile.h b/vvp/compile.h index 05b51aff8..1ead83ae1 100644 --- a/vvp/compile.h +++ b/vvp/compile.h @@ -181,12 +181,15 @@ extern __vpiModPath* compile_modpath(char*label, extern void compile_modpath_src(__vpiModPath*dst, char edge, struct symb_s input, - struct numbv_s d); + struct numbv_s d, + int condit_input, /* match with '0' */ + struct symb_s path_term_input); extern void compile_modpath_src(__vpiModPath*dst, char edge, struct symb_s input, struct numbv_s d, - struct symb_s condit_input); + struct symb_s condit_input, + struct symb_s path_term_input); extern void compile_reduce_and(char*label, struct symb_s arg); extern void compile_reduce_or(char*label, struct symb_s arg); diff --git a/vvp/delay.cc b/vvp/delay.cc index d89893338..43df5db21 100644 --- a/vvp/delay.cc +++ b/vvp/delay.cc @@ -497,42 +497,11 @@ bool vvp_fun_modpath_edge::test_vec4(const vvp_vector4_t&bit) */ static int modpath_src_get(int code, vpiHandle ref) { - assert((ref->vpi_type->type_code == vpiModPath)); + struct __vpiModPathSrc*obj = vpip_modpath_src_from_handle(ref); + assert(obj); return 0 ; } -/* - * This routine will return an modpathIn input port - * name for an modpath vpiHandle object - * - */ -static char* modpath_src_get_str(int code, vpiHandle ref) -{ - assert((ref->vpi_type->type_code == vpiModPathIn)); - struct __vpiModPathSrc *refp = (struct __vpiModPathSrc *)ref; - char *bn = strdup(vpi_get_str(vpiFullName, &refp->scope->base)); - - char *nm = (char *)refp->name ; - - char *rbuf = need_result_buf(strlen(bn) + strlen(nm) + 2, RBUF_STR); - - switch (code) - { - case vpiFullName: - sprintf(rbuf, "%s.%s", bn, nm); - free(bn); - return rbuf; - - case vpiName: - strcpy(rbuf, nm); - free(bn); - return rbuf; - } - - free(bn); - return 0; -} - static void modpath_src_get_value(vpiHandle ref, p_vpi_value vp) { assert((ref->vpi_type->type_code == vpiModPathIn)); @@ -551,24 +520,28 @@ static vpiHandle modpath_src_put_value(vpiHandle ref, s_vpi_value *vp ) static vpiHandle modpath_src_get_handle(int code, vpiHandle ref) { - assert( (ref->vpi_type->type_code==vpiModPathIn ) ); - struct __vpiModPathSrc *rfp = (struct __vpiModPathSrc *)ref ; - - switch (code) - { + struct __vpiModPathSrc*rfp = vpip_modpath_src_from_handle(ref); + assert(rfp); + + switch (code) { + case vpiScope: - return &rfp->scope->base ; - - case vpiModule: - { - struct __vpiScope*scope = rfp->scope; - while (scope && scope->base.vpi_type->type_code != vpiModule) - scope = scope->scope; - - assert(scope); - return &scope->base; - } - } + return vpi_handle(rfp->dest->scope); + + case vpiModule: + { struct __vpiScope*scope = rfp->dest->scope; + while (scope && scope->base.vpi_type->type_code != vpiModule) + scope = scope->scope; + assert(scope); + return vpi_handle(scope); + } + + case vpiModPathIn: + return vpi_handle(&rfp->path_term_in); + + case vpiModPathOut: + return vpi_handle(&rfp->dest->path_term_out); + } return 0; } @@ -586,7 +559,6 @@ static int modpath_src_free_object( vpiHandle ref ) return 1 ; } - /* * This Routine will put specific demension of delay[] values * into a vpiHandle. In this case, he will put an @@ -596,17 +568,15 @@ static int modpath_src_free_object( vpiHandle ref ) static void modpath_src_put_delays ( vpiHandle ref, p_vpi_delay delays ) { int i ; - assert((ref->vpi_type->type_code == vpiModPathIn)); - struct __vpiModPathSrc * src = vpip_modpath_src_from_handle( ref) ; - assert ( src ) ; - vvp_fun_modpath_src *fun = dynamic_cast(src->node->fun); + assert(src) ; + + vvp_fun_modpath_src *fun = dynamic_cast(src->net->fun); assert( fun ); - for ( i = 0 ; i < delays->no_of_delays ; i++) - { - fun->delay[i] = delays->da[ i ].real ; - } + for ( i = 0 ; i < delays->no_of_delays ; i++) { + fun->delay[i] = delays->da[ i ].real ; + } } /* @@ -620,183 +590,15 @@ static void modpath_src_put_delays ( vpiHandle ref, p_vpi_delay delays ) static void modpath_src_get_delays ( vpiHandle ref, p_vpi_delay delays ) { int i ; - assert(( ref->vpi_type->type_code == vpiModPathIn )); - struct __vpiModPathSrc * src = vpip_modpath_src_from_handle( ref) ; - assert ( src ) ; - vvp_fun_modpath_src *fun = dynamic_cast(src->node->fun); + assert(src); + + vvp_fun_modpath_src *fun = dynamic_cast(src->net->fun); assert( fun ); for ( i = 0 ; i < delays->no_of_delays ; i++) - delays->da[ i ].real = fun->delay[i]; + delays->da[ i ].real = fun->delay[i]; } -/* - This Struct will be used by the make_vpi_modpath_src ( ) - to initializa the vpiModPathIn vpiHandle type, and assign - method routines - - vpiModPathIn vpiHandle interanl operations : - - we have - - vpi_get == modpath_src_get (..) ; - vpi_get_str == modpath_src_get_str (..) ; - vpi_get_value == modpath_src_get_value (..) ; - vpi_put_value == modpath_src_put_value (..) ; - vpi_get_handle == modpath_src_get_handle (..) ; - vpi_iterate == modpath_src_iterate (..) ; - vpi_index == modpath_src_index ( .. ) ; - vpi_free_object == modpath_src_free_object ( .. ) ; - vpi_get_delay == modpath_src_get_delay (..) ; - vpi_put_delay == modpath_src_put_delay (..) ; - - -*/ - -static const struct __vpirt vpip_modpath_src = { - vpiModPathIn, - modpath_src_get, - modpath_src_get_str, - modpath_src_get_value, - modpath_src_put_value, - modpath_src_get_handle, - 0, /* modpath_src_iterate,*/ - modpath_src_index, - modpath_src_free_object, - modpath_src_get_delays, - modpath_src_put_delays -}; - -/* - * This function will Constructs a vpiModPathIn - * ( struct __vpiModPathSrc ) Object. will give - * a delays[12] values, and point to the specified functor - * - */ - -vpiHandle vpip_make_modpath_src ( char *name, vvp_time64_t use_delay[12] , vvp_net_t *net ) -{ - struct __vpiModPathSrc *obj = (struct __vpiModPathSrc *) calloc (1, sizeof ( struct __vpiModPathSrc ) ) ; - obj->base.vpi_type = &vpip_modpath_src; - obj->scope = vpip_peek_current_scope ( ); - obj->name = (char *)calloc(strlen(name) + 1 , sizeof ( char )) ; - strcpy ( obj->name, name ) ; - obj->node = net ; - vpip_attach_to_current_scope (&obj->base) ; - return &obj->base ; -} - - -/* - vpiModPath vpiHandle interanl operations : - - we have - - vpi_get == modpath_get (..) ; - vpi_get_str == modpath_get_str (..) ; - vpi_get_value == modpath_get_value (..) ; - vpi_put_value == modpath_put_value (..) ; - vpi_get_handle == modpath_get_handle (..) ; - vpi_iterate == modpath_iterate (..) ; - vpi_index == modpath_index ( .. ) ; - vpi_free_object == modpath_free_object ( .. ) ; - vpi_get_delay == modpath_get_delay (..) ; - vpi_put_delay == modpath_put_delay (..) ; - -*/ - -static int modpath_get(int code, vpiHandle ref) -{ - assert((ref->vpi_type->type_code == vpiModPath)); - - return 0 ; -} - -static char* modpath_get_str(int code, vpiHandle ref) -{ - assert((ref->vpi_type->type_code == vpiModPath)); - - struct __vpiModPath *refp = (struct __vpiModPath *)ref; - char *bn = strdup(vpi_get_str(vpiFullName, &refp->scope->base)); - char *nm = (char *)refp->name ; - char *rbuf = need_result_buf(strlen(bn) + strlen(nm) + 2, RBUF_STR); - - switch (code) - { - case vpiFullName: - sprintf(rbuf, "%s.%s", bn, nm); - free(bn); - return rbuf; - - case vpiName: - strcpy(rbuf, nm); - free(bn); - return rbuf; - } - - free(bn); - return 0; -} - -static void modpath_get_value(vpiHandle ref, p_vpi_value vp) -{ - assert((ref->vpi_type->type_code == vpiModPath)); - // struct __vpiModPath* modpath = vpip_modpath_from_handle( ref) ; - // assert ( modpath ) ; - return ; -} - -static vpiHandle modpath_put_value(vpiHandle ref, s_vpi_value *vp ) -{ - assert((ref->vpi_type->type_code == vpiModPath)); - // struct __vpiModPath* modpath = vpip_modpath_from_handle( ref) ; - // assert ( modpath ) ; - return 0 ; -} - -static vpiHandle modpath_get_handle(int code, vpiHandle ref) -{ - struct __vpiModPath *rfp = vpip_modpath_from_handle(ref); - assert(rfp); - - switch (code) { - case vpiScope: - return vpi_handle(rfp->scope); - - case vpiModule: - { struct __vpiScope*scope = rfp->scope; - while (scope && scope->base.vpi_type->type_code != vpiModule) - scope = scope->scope; - assert(scope); - return vpi_handle(scope); - } - - case vpiModPathOut: - return vpi_handle(&rfp->path_term_out); - } - return 0; -} - - -static vpiHandle modpath_iterate (int code , vpiHandle ref ) -{ - assert( (ref->vpi_type->type_code == vpiModPath) ); - return 0 ; -} - -static vpiHandle modpath_index ( vpiHandle ref, int code ) -{ - assert( (ref->vpi_type->type_code == vpiModPath) ); - return 0 ; -} - - -static int modpath_free_object( vpiHandle ref ) -{ - assert( (ref->vpi_type->type_code == vpiModPath) ); - free ( ref ) ; - return 1 ; -} static vpiHandle pathterm_get_handle(int code, vpiHandle ref) { @@ -811,24 +613,23 @@ static vpiHandle pathterm_get_handle(int code, vpiHandle ref) } } - /* - This Struct will be used by the make_vpi_modpath ( ) - to initializa the vpiModPath vpiHandle type, and assign - method routines +* The __vpiModPathSrc class is what the VPI client sees as a +* vpiModPath object. The __vpiModPath structure contains items that +* are common to a bunch of modpaths, including the destination term. */ -static const struct __vpirt vpip_modpath_rt = { - vpiModPath, - modpath_get, - modpath_get_str, - modpath_get_value, - modpath_put_value, - modpath_get_handle, - modpath_iterate, - modpath_index, - modpath_free_object, - 0, // modpath_get_delays, - 0 // modpath_put_delays +static const struct __vpirt vpip_modpath_src_rt = { + vpiModPath, + modpath_src_get, + 0, /* vpi_get_str */ + modpath_src_get_value, + modpath_src_put_value, + modpath_src_get_handle, + 0, /* modpath_src_iterate,*/ + modpath_src_index, + modpath_src_free_object, + modpath_src_get_delays, + modpath_src_put_delays }; static const struct __vpirt vpip_modpath_term_rt = { @@ -857,25 +658,35 @@ static void initialize_path_term(struct __vpiModPathTerm&obj) * respective functor */ -vpiHandle vpip_make_modpath ( char *name, char *input, vvp_net_t *net ) +struct __vpiModPath* vpip_make_modpath(vvp_net_t *net) { - - struct __vpiModPath *obj = (struct __vpiModPath *) calloc (1, sizeof ( struct __vpiModPath ) ) ; - obj->base.vpi_type = &vpip_modpath_rt ; - obj->scope = vpip_peek_current_scope ( ); + struct __vpiModPath*obj = (struct __vpiModPath *)calloc(1, sizeof ( struct __vpiModPath ) ); + obj->scope = vpip_peek_current_scope ( ); initialize_path_term(obj->path_term_out); + obj->input_net = net ; - obj->name = (char *)calloc(strlen(name) + 1 , sizeof ( char )) ; - strcpy ( obj->name, name ) ; + return obj; +} - obj->input = (char *)calloc(strlen(input) + 1 , sizeof ( char )) ; - strcpy ( obj->input,input ) ; - fprintf(stderr, "XXXX: Add vpiModpath...\n"); - obj->input_net = net ; - vpip_attach_to_current_scope (&obj->base) ; - return &obj->base ; +/* + * This function will Constructs a vpiModPathIn + * ( struct __vpiModPathSrc ) Object. will give + * a delays[12] values, and point to the specified functor + * + */ + +struct __vpiModPathSrc* vpip_make_modpath_src (struct __vpiModPath*path, vvp_time64_t use_delay[12] , vvp_net_t *net ) +{ + struct __vpiModPathSrc *obj = (struct __vpiModPathSrc *) calloc (1, sizeof ( struct __vpiModPathSrc ) ) ; + + obj->base.vpi_type = &vpip_modpath_src_rt; + obj->dest = path; + obj->net = net; + initialize_path_term(obj->path_term_in); + + return obj; } @@ -884,14 +695,6 @@ vpiHandle vpip_make_modpath ( char *name, char *input, vvp_net_t *net ) to a struct __vpiModPath { } */ -struct __vpiModPath* vpip_modpath_from_handle(vpiHandle ref) -{ - if (ref->vpi_type->type_code != vpiModPath) - return 0; - - return (struct __vpiModPath *) ref; -} - struct __vpiModPathTerm* vpip_modpath_term_from_handle(vpiHandle ref) { if (ref->vpi_type->type_code != vpiPathTerm) @@ -908,7 +711,7 @@ struct __vpiModPathTerm* vpip_modpath_term_from_handle(vpiHandle ref) struct __vpiModPathSrc* vpip_modpath_src_from_handle(vpiHandle ref) { - if (ref->vpi_type->type_code != vpiModPathIn) + if (ref->vpi_type->type_code != vpiModPath) return 0; return (struct __vpiModPathSrc *) ref; @@ -925,13 +728,3 @@ void vpip_add_mopdath_edge ( vpiHandle vpiobj, char *label, } - - - -void vpip_add_modpath_src ( vpiHandle modpath, vpiHandle src ) -{ - assert( (src->vpi_type->type_code == vpiModPathIn )); - assert( (modpath->vpi_type->type_code == vpiModPath )); - - return ; -} diff --git a/vvp/parse.y b/vvp/parse.y index 022ebc8ae..1579b4fc6 100644 --- a/vvp/parse.y +++ b/vvp/parse.y @@ -775,19 +775,19 @@ modpath_src_list ; modpath_src - : symbol '(' numbers ')' - { compile_modpath_src(modpath_dst, 0, $1, $3); } - | symbol '(' numbers '?' symbol ')' - { compile_modpath_src(modpath_dst, 0, $1, $3, $5); } - | symbol '+' '(' numbers ')' - { compile_modpath_src(modpath_dst, '+', $1, $4); } - | symbol '+' '(' numbers '?' symbol ')' - { compile_modpath_src(modpath_dst, '+', $1, $4, $6); } - | symbol '-' '(' numbers ')' - { compile_modpath_src(modpath_dst, '-', $1, $4); } - | symbol '-' '(' numbers '?' symbol ')' - { compile_modpath_src(modpath_dst, '-', $1, $4, $6); } - ; + : symbol '(' numbers ')' symbol + { compile_modpath_src(modpath_dst, 0, $1, $3, 0, $5); } + | symbol '(' numbers '?' symbol ')' symbol + { compile_modpath_src(modpath_dst, 0, $1, $3, $5, $7); } + | symbol '+' '(' numbers ')' symbol + { compile_modpath_src(modpath_dst, '+', $1, $4, 0, $6); } + | symbol '+' '(' numbers '?' symbol ')' symbol + { compile_modpath_src(modpath_dst, '+', $1, $4, $6, $8); } + | symbol '-' '(' numbers ')' symbol + { compile_modpath_src(modpath_dst, '-', $1, $4, 0, $6); } + | symbol '-' '(' numbers '?' symbol ')' symbol + { compile_modpath_src(modpath_dst, '-', $1, $4, $6, $8); } + ; udp_table : T_STRING diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index 1dcb7f8e1..81c964395 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -218,18 +218,19 @@ extern vpiHandle vpip_make_net(const char*name, int msb, int lsb, extern __vpiSignal* vpip_signal_from_handle(vpiHandle obj); +struct __vpiModPathTerm { + struct __vpiHandle base; + vpiHandle expr; +}; + struct __vpiModPathSrc { - struct __vpiHandle base ; - struct __vpiScope *scope ; - int type ; - char *label ; /* - Must Be removed in Future - because the ModPathSrc have - no label - */ - char *name ; - struct __vpiModPathSrc *next ; - + struct __vpiHandle base; + struct __vpiModPath *dest; + int type; + + /* This is the input expression for this modpath. */ + struct __vpiModPathTerm path_term_in; + /* Just Temporary */ vvp_time64_t use_delay [12] ; /* @@ -243,21 +244,13 @@ struct __vpiModPathSrc { */ p_vpi_delay delays ; - /* - The Posedge, Negedge are already defined - in the "delays->p_vpi_time(da)->high/low" - - bool posedge, negedge ; - */ - vvp_net_t *node; + /* This is the input net for the modpath. signals on this net + are used to determine the modpath. They are *not* propagated + anywhere. */ + vvp_net_t *net; } ; -struct __vpiModPathTerm { - struct __vpiHandle base; - vpiHandle expr; -}; - /* * * The vpiMoaPath vpiHandle will define @@ -267,35 +260,14 @@ struct __vpiModPathTerm { */ struct __vpiModPath { - struct __vpiHandle base ; struct __vpiScope *scope ; class vvp_fun_modpath*modpath; struct __vpiModPathTerm path_term_out; - - /* - * The name, input must be removed - * in future um ModPathSrc have no - * name. - */ - char *name ; - char *input ; vvp_net_t *input_net ; - struct __vpiModPathSrc *src_list ; - /* - * Keep an array of internal modpath_src - * vpiHandle - */ - struct __vpiHandle **src ; - /* - * Registering the number of modpath_src - * number - */ - unsigned int src_no ; }; -extern struct __vpiModPath* vpip_modpath_from_handle(vpiHandle ref); extern struct __vpiModPathTerm* vpip_modpath_term_from_handle(vpiHandle ref); extern struct __vpiModPathSrc* vpip_modpath_src_from_handle(vpiHandle ref); @@ -305,13 +277,11 @@ extern struct __vpiModPathSrc* vpip_modpath_src_from_handle(vpiHandle ref); * for vpiModPath && vpiModPathIn objects */ -extern vpiHandle vpip_make_modpath_src ( char *name, - vvp_time64_t use_delay[12] , - vvp_net_t *net ) ; +extern struct __vpiModPathSrc* vpip_make_modpath_src (struct __vpiModPath*path_dest, + vvp_time64_t use_delay[12] , + vvp_net_t *net ) ; -extern vpiHandle vpip_make_modpath ( char *name, - char *input, - vvp_net_t *net ) ; +extern struct __vpiModPath* vpip_make_modpath(vvp_net_t *net) ; extern void vpip_add_mopdath_delay ( vpiHandle vpiobj, char *label, @@ -323,15 +293,6 @@ extern void vpip_add_mopdath_edge ( vpiHandle vpiobj, bool posedge , bool negedge ) ; -extern void vpip_add_modpath_src ( vpiHandle modpath, - vpiHandle src ) ; - -extern __vpiModPath* vpip_modpath_from_handle ( vpiHandle obj); - -extern __vpiModPathSrc* vpip_modpath_src_from_handle( vpiHandle obj); - - - /* * These methods support the vpi creation of events. The name string From 2fac019d9dd1d0965a532d764c9ccb0ab2588040 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Mon, 5 Nov 2007 19:59:27 -0800 Subject: [PATCH 5/6] modpath nodes need vpi expression handles Generate the code that attaches the VPI handle of the source and destination to the modpath object. --- tgt-vvp/modpath.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/tgt-vvp/modpath.c b/tgt-vvp/modpath.c index ba9f80819..cfb79fa29 100644 --- a/tgt-vvp/modpath.c +++ b/tgt-vvp/modpath.c @@ -22,6 +22,26 @@ # include # include +static ivl_signal_t find_path_source_port(ivl_delaypath_t path) +{ + int idx; + ivl_nexus_t nex = ivl_path_source(path); + + for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { + ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx); + ivl_signal_t sig = ivl_nexus_ptr_sig(ptr); + if (sig == 0) + continue; + if (ivl_signal_port(sig) == IVL_SIP_NONE) + continue; + + /* XXXX Should check that the scope is right. */ + return sig; + } + + return 0; +} + /* * Draw a .modpath record. The label is the label to use for this * record. The driver is the label of the net that feeds into the @@ -52,7 +72,7 @@ static void draw_modpath_record(const char*label, const char*driver, } fprintf(vvp_out, " .scope S_%p;\n", ivl_path_scope(ivl_signal_path(path_sig,0))); - fprintf(vvp_out, "%s .modpath %s", label, driver); + fprintf(vvp_out, "%s .modpath %s v%p_0", label, driver, path_sig); for (idx = 0 ; idx < ivl_signal_npath(path_sig); idx += 1) { ivl_delaypath_t path = ivl_signal_path(path_sig, idx); @@ -83,6 +103,9 @@ static void draw_modpath_record(const char*label, const char*driver, } fprintf(vvp_out, ")"); + + ivl_signal_t src_sig = find_path_source_port(path); + fprintf(vvp_out, " v%p_0", src_sig); } fprintf(vvp_out, ";\n"); From 859d8b3502ece9474b5dfedd68f8941690f1ef0b Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Tue, 6 Nov 2007 20:26:03 -0800 Subject: [PATCH 6/6] Rework vpi_get_delay of modpaths Cleanup klunky implementation of vpi_get/put_delays for modpath objects. Remove some useless members. Signed-off-by: Stephen Williams --- vvp/delay.cc | 57 ++++++++++++++++++++++++++++++++------------------ vvp/delay.h | 53 +++------------------------------------------- vvp/vpi_priv.h | 18 +--------------- 3 files changed, 41 insertions(+), 87 deletions(-) diff --git a/vvp/delay.cc b/vvp/delay.cc index 43df5db21..71912d4b7 100644 --- a/vvp/delay.cc +++ b/vvp/delay.cc @@ -425,17 +425,7 @@ void vvp_fun_modpath::run_run() vvp_fun_modpath_src::vvp_fun_modpath_src(vvp_time64_t del[12]) { for (unsigned idx = 0 ; idx < 12 ; idx += 1) - { - delay_[idx] = del[idx]; - /* - Added By Yang. - - Make the delay[12] value to be Public - make the get_delays(), put_delays() to - be possible - */ - delay [idx] = del[idx]; - } + delay_[idx] = del[idx]; next_ = 0; wake_time_ = 0; @@ -446,6 +436,18 @@ vvp_fun_modpath_src::~vvp_fun_modpath_src() { } +void vvp_fun_modpath_src::get_delay12(vvp_time64_t val[12]) const +{ + for (unsigned idx = 0 ; idx < 12 ; idx += 1) + val[idx] = delay_[idx]; +} + +void vvp_fun_modpath_src::put_delay12(const vvp_time64_t val[12]) +{ + for (unsigned idx = 0 ; idx < 12 ; idx += 1) + delay_[idx] = val[idx]; +} + void vvp_fun_modpath_src::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit) { if (port.port() == 0) { @@ -567,16 +569,21 @@ static int modpath_src_free_object( vpiHandle ref ) */ static void modpath_src_put_delays ( vpiHandle ref, p_vpi_delay delays ) { - int i ; + vvp_time64_t tmp[12]; + int idx; struct __vpiModPathSrc * src = vpip_modpath_src_from_handle( ref) ; assert(src) ; vvp_fun_modpath_src *fun = dynamic_cast(src->net->fun); assert( fun ); - - for ( i = 0 ; i < delays->no_of_delays ; i++) { - fun->delay[i] = delays->da[ i ].real ; + assert(delays->no_of_delays == 12); + assert(delays->time_type == vpiSimTime); + + for (idx = 0 ; idx < delays->no_of_delays ; idx += 1) { + tmp[idx] = vpip_timestruct_to_time(delays->da+idx); } + + fun->put_delay12(tmp); } /* @@ -589,14 +596,24 @@ static void modpath_src_put_delays ( vpiHandle ref, p_vpi_delay delays ) static void modpath_src_get_delays ( vpiHandle ref, p_vpi_delay delays ) { - int i ; - struct __vpiModPathSrc * src = vpip_modpath_src_from_handle( ref) ; + struct __vpiModPathSrc*src = vpip_modpath_src_from_handle( ref) ; assert(src); vvp_fun_modpath_src *fun = dynamic_cast(src->net->fun); - assert( fun ); - for ( i = 0 ; i < delays->no_of_delays ; i++) - delays->da[ i ].real = fun->delay[i]; + assert(fun); + switch (delays->no_of_delays) { + case 12: + { int idx; + vvp_time64_t tmp[12]; + fun->get_delay12(tmp); + for (idx = 0; idx < 12; idx += 1) { + vpip_time_to_timestruct(delays->da+idx, tmp[idx]); + } + } + break; + default: + assert(0); + } } diff --git a/vvp/delay.h b/vvp/delay.h index d599160f9..d6c4d3655 100644 --- a/vvp/delay.h +++ b/vvp/delay.h @@ -18,9 +18,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#ifdef HAVE_CVS_IDENT -#ident "$Id: delay.h,v 1.15 2007/03/02 06:13:22 steve Exp $" -#endif /* */ @@ -186,15 +183,9 @@ class vvp_fun_modpath_src : public vvp_net_fun_t { public: void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit); virtual bool test_vec4(const vvp_vector4_t&bit); - - /* - Added By Yang. - - Make the Delay Value be Public too - make the get_delays(), put_delays() be possible - */ - vvp_time64_t delay[12]; - + + void get_delay12(vvp_time64_t out[12]) const; + void put_delay12(const vvp_time64_t in[12]); private: // FIXME: Needs to be a 12-value array @@ -223,42 +214,4 @@ class vvp_fun_modpath_edge : public vvp_fun_modpath_src { bool negedge_; }; -/* - * $Log: delay.h,v $ - * Revision 1.15 2007/03/02 06:13:22 steve - * Add support for edge sensitive spec paths. - * - * Revision 1.14 2007/03/01 06:19:39 steve - * Add support for conditional specify delay paths. - * - * Revision 1.13 2007/01/26 05:15:41 steve - * More literal implementation of inertial delay model. - * - * Revision 1.12 2006/09/29 03:57:01 steve - * Modpath delay chooses correct delay for edge. - * - * Revision 1.11 2006/09/23 04:57:20 steve - * Basic support for specify timing. - * - * Revision 1.10 2006/01/02 05:32:07 steve - * Require explicit delay node from source. - * - * Revision 1.9 2005/07/06 04:29:25 steve - * Implement real valued signals and arith nodes. - * - * Revision 1.8 2005/06/22 00:04:49 steve - * Reduce vvp_vector4 copies by using const references. - * - * Revision 1.7 2005/06/02 16:02:11 steve - * Add support for notif0/1 gates. - * Make delay nodes support inertial delay. - * Add the %force/link instruction. - * - * Revision 1.6 2005/05/14 19:43:23 steve - * Move functor delays to vvp_delay_fun object. - * - * Revision 1.5 2005/04/03 05:45:51 steve - * Rework the vvp_delay_t class. - * - */ #endif // __delay_H diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index 81c964395..57784190a 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -1,7 +1,7 @@ #ifndef __vpi_priv_H #define __vpi_priv_H /* - * Copyright (c) 2001-2003 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2007 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -18,9 +18,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#ifdef HAVE_CVS_IDENT -#ident "$Id: vpi_priv.h,v 1.74 2007/04/12 04:25:59 steve Exp $" -#endif # include "vpi_user.h" # include "pointers.h" @@ -230,19 +227,6 @@ struct __vpiModPathSrc { /* This is the input expression for this modpath. */ struct __vpiModPathTerm path_term_in; - - /* Just Temporary */ - vvp_time64_t use_delay [12] ; - /* - Conform the IEEE1364, we use the - standard delay value structure - (p_vpi_time) to represent delay values - of each modpath_src delay - - the "p_vpi_time" is defined in the - "vpi_user.h" - */ - p_vpi_delay delays ; /* This is the input net for the modpath. signals on this net are used to determine the modpath. They are *not* propagated