introduce vpi access to modpath objects
Add/rework VPI access to modpaths. This allows VPI code access to paths described in specify blocks. In the process, the VPI structure has been reworked to conform to the IEEE1364 standard. Signed-off-by: Stephen Williams <steve@icarus.com>
This commit is contained in:
commit
5352a0cc40
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
1
ivl.def
1
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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
1
t-dll.cc
1
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();
|
||||
|
|
|
|||
1
t-dll.h
1
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;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* 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 <string.h>
|
||||
# include <stdlib.h>
|
||||
# include <assert.h>
|
||||
|
||||
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
|
||||
* 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 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);
|
||||
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, ")");
|
||||
|
||||
ivl_signal_t src_sig = find_path_source_port(path);
|
||||
fprintf(vvp_out, " v%p_0", src_sig);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -680,66 +680,6 @@ static char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr)
|
|||
return strdup("C<z>");
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -1120,25 +1120,31 @@ 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);
|
||||
__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;
|
||||
|
||||
|
|
@ -1185,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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -175,16 +175,21 @@ extern void compile_dff(char*label,
|
|||
struct symb_s arg_a);
|
||||
|
||||
class __vpiModPath;
|
||||
extern __vpiModPath* compile_modpath(char*label, struct symb_s src);
|
||||
extern void compile_modpath_src(__vpiModPath*dst,
|
||||
char edge,
|
||||
struct symb_s input,
|
||||
struct numbv_s d);
|
||||
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,
|
||||
struct numbv_s d,
|
||||
struct symb_s condit_input);
|
||||
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 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);
|
||||
|
|
|
|||
415
vvp/delay.cc
415
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) {
|
||||
|
|
@ -497,42 +499,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 +522,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 +561,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
|
||||
|
|
@ -595,18 +569,21 @@ 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));
|
||||
|
||||
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<vvp_fun_modpath_src*>(src->node->fun);
|
||||
assert(src) ;
|
||||
|
||||
vvp_fun_modpath_src *fun = dynamic_cast<vvp_fun_modpath_src*>(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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -619,44 +596,49 @@ 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<vvp_fun_modpath_src*>(src->node->fun);
|
||||
assert( fun );
|
||||
for ( i = 0 ; i < delays->no_of_delays ; i++)
|
||||
delays->da[ i ].real = fun->delay[i];
|
||||
struct __vpiModPathSrc*src = vpip_modpath_src_from_handle( ref) ;
|
||||
assert(src);
|
||||
|
||||
vvp_fun_modpath_src *fun = dynamic_cast<vvp_fun_modpath_src*>(src->net->fun);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
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 (..) ;
|
||||
|
||||
|
||||
* 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_src = {
|
||||
vpiModPathIn,
|
||||
static const struct __vpirt vpip_modpath_src_rt = {
|
||||
vpiModPath,
|
||||
modpath_src_get,
|
||||
modpath_src_get_str,
|
||||
0, /* vpi_get_str */
|
||||
modpath_src_get_value,
|
||||
modpath_src_put_value,
|
||||
modpath_src_get_handle,
|
||||
|
|
@ -667,180 +649,61 @@ static const struct __vpirt vpip_modpath_src = {
|
|||
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)
|
||||
{
|
||||
assert( (ref->vpi_type->type_code==vpiModPath) );
|
||||
struct __vpiModPath *rfp = (struct __vpiModPath *)ref ;
|
||||
|
||||
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 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 ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
This Struct will be used by the make_vpi_modpath ( )
|
||||
to initializa the vpiModPath vpiHandle type, and assign
|
||||
method routines
|
||||
*/
|
||||
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_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
|
||||
* 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 ( );
|
||||
|
||||
obj->name = (char *)calloc(strlen(name) + 1 , sizeof ( char )) ;
|
||||
strcpy ( obj->name, name ) ;
|
||||
initialize_path_term(obj->path_term_out);
|
||||
obj->input_net = net ;
|
||||
|
||||
obj->input = (char *)calloc(strlen(input) + 1 , sizeof ( char )) ;
|
||||
strcpy ( obj->input,input ) ;
|
||||
return obj;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -849,12 +712,12 @@ vpiHandle vpip_make_modpath ( char *name, char *input, vvp_net_t *net )
|
|||
to a struct __vpiModPath { }
|
||||
*/
|
||||
|
||||
struct __vpiModPath* vpip_modpath_from_handle(vpiHandle ref)
|
||||
struct __vpiModPathTerm* vpip_modpath_term_from_handle(vpiHandle ref)
|
||||
{
|
||||
if (ref->vpi_type->type_code != vpiModPath)
|
||||
if (ref->vpi_type->type_code != vpiPathTerm)
|
||||
return 0;
|
||||
|
||||
return (struct __vpiModPath *) ref;
|
||||
return (struct __vpiModPathTerm*) ref;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -865,7 +728,7 @@ struct __vpiModPath* vpip_modpath_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;
|
||||
|
|
@ -882,13 +745,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 ;
|
||||
}
|
||||
|
|
|
|||
53
vvp/delay.h
53
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
|
||||
|
|
|
|||
46
vvp/parse.y
46
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. */
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
@ -218,38 +215,23 @@ 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] ;
|
||||
/*
|
||||
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 ;
|
||||
|
||||
/*
|
||||
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;
|
||||
} ;
|
||||
|
||||
|
||||
|
|
@ -262,33 +244,15 @@ struct __vpiModPathSrc {
|
|||
*/
|
||||
|
||||
struct __vpiModPath {
|
||||
struct __vpiHandle base ;
|
||||
struct __vpiScope *scope ;
|
||||
|
||||
class vvp_fun_modpath*modpath;
|
||||
|
||||
/*
|
||||
* The name, input must be removed
|
||||
* in future um ModPathSrc have no
|
||||
* name.
|
||||
*/
|
||||
char *name ;
|
||||
char *input ;
|
||||
struct __vpiModPathTerm path_term_out;
|
||||
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);
|
||||
|
||||
|
||||
|
|
@ -297,13 +261,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,
|
||||
|
|
@ -315,15 +277,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
|
||||
|
|
|
|||
Loading…
Reference in New Issue