Merge branch 'master' into verilog-ams
Conflicts: tgt-vvp/vvp_scope.c Note that the draw_net_input.c takes in a lot of the codes that used to be in vvp_scope.c, so some changes may have been lost.
This commit is contained in:
commit
95850ac112
16
Makefile.in
16
Makefile.in
|
|
@ -186,17 +186,14 @@ iverilog-vpi.pdf: iverilog-vpi.ps
|
|||
# version.h file in the source tree (included in snapshots and releases), and
|
||||
# finally use nothing.
|
||||
.PHONY: version.h
|
||||
version.h:
|
||||
# "true" and "false" in the next few lines are Unix shell command names
|
||||
ifeq ($(GIT),none)
|
||||
@if test -r $(srcdir)/$@; then \
|
||||
echo "Using $(srcdir)/$@ for VERSION_TAG"; \
|
||||
diff $(srcdir)/$@ $@ > /dev/null 2>&1 || cp $(srcdir)/$@ $@; \
|
||||
else \
|
||||
echo "Using empty VERSION_TAG"; \
|
||||
echo '#define VERSION_TAG ""' > $@; \
|
||||
fi
|
||||
GIT_PRESENT = false
|
||||
else
|
||||
@if test -d $(srcdir)/.git; then \
|
||||
GIT_PRESENT = true
|
||||
endif
|
||||
version.h:
|
||||
@if $(GIT_PRESENT) && test -d $(srcdir)/.git; then \
|
||||
echo "Using git-describe for VERSION_TAG"; \
|
||||
tmp=`$(GIT) --git-dir $(srcdir)/.git describe \
|
||||
| sed -e 's;\(.*\);#define VERSION_TAG "\1";'`; \
|
||||
|
|
@ -208,7 +205,6 @@ else
|
|||
echo "Using empty VERSION_TAG"; \
|
||||
echo '#define VERSION_TAG ""' > $@; \
|
||||
fi
|
||||
endif
|
||||
|
||||
ifeq (@MINGW32@,yes)
|
||||
ifeq ($(MAN),none)
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ O = sys_table.o sys_convert.o sys_deposit.o sys_display.o sys_fileio.o \
|
|||
sys_finish.o sys_icarus.o sys_plusargs.o sys_random.o sys_random_mti.o \
|
||||
sys_readmem.o sys_readmem_lex.o sys_scanf.o sys_sdf.o \
|
||||
sys_time.o sys_vcd.o sys_vcdoff.o vcd_priv.o \
|
||||
mt19937int.o priv.o sdf_lexor.o sdf_parse.o stringheap.o
|
||||
mt19937int.o sys_priv.o sdf_lexor.o sdf_parse.o stringheap.o \
|
||||
vams_simparam.o
|
||||
|
||||
ifeq (@HAVE_LIBZ@,yes)
|
||||
ifeq (@HAVE_LIBBZ2@,yes)
|
||||
|
|
|
|||
44
vpi/priv.c
44
vpi/priv.c
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2003 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
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: priv.c,v 1.2 2003/10/06 21:26:27 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "sys_priv.h"
|
||||
|
||||
PLI_UINT64 timerec_to_time64(const struct t_vpi_time*time)
|
||||
{
|
||||
PLI_UINT64 tmp;
|
||||
|
||||
tmp = time->high;
|
||||
tmp <<= 32;
|
||||
tmp |= (PLI_UINT64) time->low;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: priv.c,v $
|
||||
* Revision 1.2 2003/10/06 21:26:27 steve
|
||||
* Include sys_priv.h instead of priv.h
|
||||
*
|
||||
* Revision 1.1 2003/10/02 21:16:11 steve
|
||||
* Include timerec_to_time64 implementation.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -60,16 +60,6 @@ struct strobe_cb_info {
|
|||
unsigned mcd;
|
||||
};
|
||||
|
||||
int is_constant(vpiHandle obj)
|
||||
{
|
||||
if (vpi_get(vpiType, obj) == vpiConstant)
|
||||
return vpiConstant;
|
||||
if (vpi_get(vpiType, obj) == vpiParameter)
|
||||
return vpiParameter;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The number of decimal digits needed to represent a
|
||||
// nr_bits binary number is floor(nr_bits*log_10(2))+1,
|
||||
// where log_10(2) = 0.30102999566398.... and I approximate
|
||||
|
|
@ -665,7 +655,7 @@ static int format_str_char(vpiHandle scope, unsigned int mcd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (is_constant(argv[idx])
|
||||
if (is_constant_obj(argv[idx])
|
||||
&& (vpi_get(vpiConstType, argv[idx]) == vpiRealConst)) {
|
||||
|
||||
value.format = vpiRealVal;
|
||||
|
|
@ -1119,11 +1109,16 @@ static PLI_INT32 sys_monitor_calltf(PLI_BYTE8*name)
|
|||
for (idx = 0 ; idx < monitor_info.nitems ; idx += 1) {
|
||||
|
||||
switch (vpi_get(vpiType, monitor_info.items[idx])) {
|
||||
case vpiMemoryWord:
|
||||
/*
|
||||
* We only support constant selections. Make this
|
||||
* better when we add a real compiletf routine.
|
||||
*/
|
||||
assert(vpi_get(vpiConstantSelect, monitor_info.items[idx]));
|
||||
case vpiNet:
|
||||
case vpiReg:
|
||||
case vpiIntegerVar:
|
||||
case vpiRealVar:
|
||||
case vpiMemoryWord:
|
||||
/* Monitoring reg and net values involves setting
|
||||
a callback for value changes. Pass the storage
|
||||
pointer for the callback itself as user_data so
|
||||
|
|
@ -2187,12 +2182,7 @@ static PLI_INT32 sys_printtimescale_calltf(PLI_BYTE8*xx)
|
|||
vpiHandle argv = vpi_iterate(vpiArgument, sys);
|
||||
vpiHandle scope;
|
||||
if (!argv) {
|
||||
vpiHandle parent = vpi_handle(vpiScope, sys);
|
||||
scope = NULL; /* fallback value if parent is NULL */
|
||||
while (parent) {
|
||||
scope = parent;
|
||||
parent = vpi_handle(vpiScope, scope);
|
||||
}
|
||||
scope = sys_func_module(sys);
|
||||
} else {
|
||||
scope = vpi_scan(argv);
|
||||
vpi_free_object(argv);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2003-2008 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
|
||||
|
|
@ -16,9 +16,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: sys_fileio.c,v 1.10 2007/03/14 04:05:51 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vpi_user.h"
|
||||
# include "sys_priv.h"
|
||||
|
|
@ -60,7 +57,7 @@ static PLI_INT32 sys_fopen_compiletf(PLI_BYTE8*name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (! is_constant(item)) {
|
||||
if (! is_constant_obj(item)) {
|
||||
vpi_printf("ERROR: %s mode argument must be a constant\n", name);
|
||||
vpi_control(vpiFinish, 1);
|
||||
}
|
||||
|
|
@ -918,4 +915,3 @@ void sys_fileio_register()
|
|||
vpi_register_systf(&tf_data);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,38 +16,9 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "vpi_config.h"
|
||||
#include <assert.h>
|
||||
#include <vpi_user.h>
|
||||
|
||||
|
||||
/*
|
||||
* Routine to return the width in bits of a CPU word (long).
|
||||
*/
|
||||
static PLI_INT32 vvp_cpu_wordsize_calltf(PLI_BYTE8* ud)
|
||||
{
|
||||
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||
assert(callh != 0);
|
||||
s_vpi_value val;
|
||||
(void) ud; /* Not used! */
|
||||
|
||||
/* Calculate the result */
|
||||
val.format = vpiIntVal;
|
||||
val.value.integer = 8*sizeof(long);
|
||||
|
||||
/* Return the result */
|
||||
vpi_put_value(callh, &val, 0, vpiNoDelay);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PLI_INT32 size_32(PLI_BYTE8* ud)
|
||||
{
|
||||
(void) ud; /* Not used! */
|
||||
|
||||
return 32;
|
||||
}
|
||||
|
||||
#include "sys_priv.h"
|
||||
|
||||
/*
|
||||
* Routine to finish the simulation and return a value to the
|
||||
|
|
@ -56,8 +27,8 @@ static PLI_INT32 size_32(PLI_BYTE8* ud)
|
|||
static PLI_INT32 finish_and_return_compiletf(PLI_BYTE8* ud)
|
||||
{
|
||||
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||
assert(callh);
|
||||
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
||||
vpiHandle arg;
|
||||
(void) ud; /* Not used! */
|
||||
|
||||
/* We must have at least one argument. */
|
||||
|
|
@ -70,42 +41,19 @@ static PLI_INT32 finish_and_return_compiletf(PLI_BYTE8* ud)
|
|||
}
|
||||
|
||||
/* This must be a numeric argument. */
|
||||
arg = vpi_scan(argv);
|
||||
switch(vpi_get(vpiType, arg)) {
|
||||
case vpiConstant:
|
||||
case vpiParameter:
|
||||
/* String constants are invalid numeric values. */
|
||||
if (vpi_get(vpiConstType, arg) == vpiStringConst) {
|
||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("The argument to $finish_and_return must be numeric.\n");
|
||||
vpi_control(vpiFinish, 1);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case vpiIntegerVar:
|
||||
case vpiMemoryWord:
|
||||
case vpiNet:
|
||||
case vpiRealVar:
|
||||
case vpiReg:
|
||||
case vpiTimeVar:
|
||||
break;
|
||||
|
||||
default:
|
||||
if (! is_numeric_obj(vpi_scan(argv))) {
|
||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("The argument to $finish_and_return must be numeric.\n");
|
||||
vpi_control(vpiFinish, 1);
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* We can only have one argument. */
|
||||
if (vpi_scan(argv) != 0) {
|
||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("$finish_and_return takes a single argument.\n");
|
||||
vpi_printf("$finish_and_return takes only a single argument.\n");
|
||||
vpi_control(vpiFinish, 1);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -142,15 +90,6 @@ void sys_special_register(void)
|
|||
{
|
||||
s_vpi_systf_data tf_data;
|
||||
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.sysfunctype = vpiIntFunc;
|
||||
tf_data.calltf = vvp_cpu_wordsize_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = size_32;
|
||||
tf_data.tfname = "$vvp_cpu_wordsize";
|
||||
tf_data.user_data = 0;
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.calltf = finish_and_return_calltf;
|
||||
tf_data.compiletf = finish_and_return_compiletf;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2002-2008 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
|
||||
|
|
@ -16,9 +16,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: sys_lxt.c,v 1.28 2007/03/14 04:05:51 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "sys_priv.h"
|
||||
# include "lxt_write.h"
|
||||
|
|
@ -324,9 +321,9 @@ inline static int install_dumpvars_callback(void)
|
|||
return 0;
|
||||
|
||||
if (dumpvars_status == 2) {
|
||||
vpi_mcd_printf(1, "LXT warning:" " $dumpvars ignored, previously"
|
||||
" called at simtime %" PLI_UINT64_FMT "\n",
|
||||
dumpvars_time);
|
||||
vpi_printf("LXT warning: $dumpvars ignored, previously"
|
||||
" called at simtime %" PLI_UINT64_FMT "\n",
|
||||
dumpvars_time);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -431,22 +428,23 @@ static void *close_dumpfile(void)
|
|||
return (dump_file = NULL);
|
||||
}
|
||||
|
||||
static void open_dumpfile(void)
|
||||
static void open_dumpfile(vpiHandle callh)
|
||||
{
|
||||
if (dump_path == 0) dump_path = strdup("dump.lxt");
|
||||
|
||||
dump_file = lt_init(dump_path);
|
||||
|
||||
if (dump_file == 0) {
|
||||
vpi_mcd_printf(1, "LXT Error: Unable to open %s for output.\n",
|
||||
dump_path);
|
||||
vpi_printf("LXT Error: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("Unable to open %s for output.\n", dump_path);
|
||||
vpi_control(vpiFinish, 1);
|
||||
return;
|
||||
} else {
|
||||
int prec = vpi_get(vpiTimePrecision, 0);
|
||||
|
||||
vpi_mcd_printf(1, "LXT info: dumpfile %s opened for output.\n",
|
||||
dump_path);
|
||||
vpi_printf("LXT info: dumpfile %s opened for output.\n",
|
||||
dump_path);
|
||||
|
||||
assert(prec >= -15);
|
||||
lt_set_timescale(dump_file, prec);
|
||||
|
|
@ -468,9 +466,9 @@ static PLI_INT32 sys_dumpfile_calltf(PLI_BYTE8*name)
|
|||
|
||||
/* $dumpfile must be called before $dumpvars starts! */
|
||||
if (dumpvars_status != 0) {
|
||||
vpi_mcd_printf(1, "LXT warning: %s called after $dumpvars started"
|
||||
",\n using existing file (%s).\n",
|
||||
name, dump_path);
|
||||
vpi_printf("LXT warning: %s called after $dumpvars started,\n"
|
||||
" using existing file (%s).\n",
|
||||
name, dump_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -480,8 +478,8 @@ static PLI_INT32 sys_dumpfile_calltf(PLI_BYTE8*name)
|
|||
path = strdup(value.value.str);
|
||||
|
||||
if (dump_path) {
|
||||
vpi_mcd_printf(1, "LXT warning: Overriding dump file %s with"
|
||||
" %s\n", dump_path, path);
|
||||
vpi_printf("LXT warning: Overriding dump file %s with %s\n",
|
||||
dump_path, path);
|
||||
free(dump_path);
|
||||
}
|
||||
dump_path = path;
|
||||
|
|
@ -542,16 +540,9 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
|
|||
|
||||
switch (vpi_get(vpiType, item)) {
|
||||
|
||||
case vpiMemory:
|
||||
/* don't know how to watch memories. */
|
||||
break;
|
||||
|
||||
case vpiNamedEvent:
|
||||
/* There is nothing in named events to dump. */
|
||||
break;
|
||||
|
||||
case vpiNet: type = "wire"; if(0){
|
||||
case vpiIntegerVar:
|
||||
case vpiMemoryWord:
|
||||
case vpiTimeVar:
|
||||
case vpiReg: type = "reg"; }
|
||||
|
||||
|
|
@ -644,18 +635,16 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
|
|||
vpi_get_str(vpiFullName, item);
|
||||
|
||||
#if 0
|
||||
vpi_mcd_printf(1,
|
||||
"LXT info:"
|
||||
" scanning scope %s, %u levels\n",
|
||||
fullname, depth);
|
||||
vpi_printf("LXT info: scanning scope %s, %u levels\n",
|
||||
fullname, depth);
|
||||
#endif
|
||||
nskip = 0 != vcd_names_search(&lxt_tab, fullname);
|
||||
|
||||
if (!nskip)
|
||||
vcd_names_add(&lxt_tab, fullname);
|
||||
else
|
||||
vpi_mcd_printf(1, "LXT warning: ignoring signals in"
|
||||
" previously scanned scope %s\n", fullname);
|
||||
vpi_printf("LXT warning: ignoring signals in "
|
||||
"previously scanned scope %s\n", fullname);
|
||||
|
||||
name = vpi_get_str(vpiName, item);
|
||||
|
||||
|
|
@ -674,8 +663,8 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
|
|||
break;
|
||||
|
||||
default:
|
||||
vpi_mcd_printf(1, "LXT warning: $dumpvars: Unsupported parameter"
|
||||
" type (%d)\n", vpi_get(vpiType, item));
|
||||
vpi_printf("LXT warning: $dumpvars: Unsupported parameter "
|
||||
"type (%s)\n", vpi_get_str(vpiType, item));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -684,7 +673,6 @@ static int draw_scope(vpiHandle item)
|
|||
{
|
||||
int depth;
|
||||
const char *name;
|
||||
// char *type; // Not needed, see below.
|
||||
|
||||
vpiHandle scope = vpi_handle(vpiScope, item);
|
||||
if (!scope)
|
||||
|
|
@ -693,20 +681,6 @@ static int draw_scope(vpiHandle item)
|
|||
depth = 1 + draw_scope(scope);
|
||||
name = vpi_get_str(vpiName, scope);
|
||||
|
||||
#if 0 /* The type information is not needed by the LXT dumper. */
|
||||
switch (vpi_get(vpiType, scope)) {
|
||||
case vpiNamedBegin: type = "begin"; break;
|
||||
case vpiTask: type = "task"; break;
|
||||
case vpiFunction: type = "function"; break;
|
||||
case vpiNamedFork: type = "fork"; break;
|
||||
case vpiModule: type = "module"; break;
|
||||
default:
|
||||
vpi_mcd_printf(1, "LXT Error: $dumpvars: Unsupported scope "
|
||||
"type (%d)\n", vpi_get(vpiType, item));
|
||||
assert(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
push_scope(name);
|
||||
|
||||
return depth;
|
||||
|
|
@ -721,7 +695,7 @@ static PLI_INT32 sys_dumpvars_calltf(PLI_BYTE8*name)
|
|||
unsigned depth = 0;
|
||||
|
||||
if (dump_file == 0) {
|
||||
open_dumpfile();
|
||||
open_dumpfile(callh);
|
||||
if (dump_file == 0) return 0;
|
||||
}
|
||||
|
||||
|
|
@ -784,7 +758,7 @@ void sys_lxt_register()
|
|||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$dumpall";
|
||||
tf_data.calltf = sys_dumpall_calltf;
|
||||
tf_data.compiletf = sys_dumpall_compiletf;
|
||||
tf_data.compiletf = sys_no_arg_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$dumpall";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
|
@ -800,7 +774,7 @@ void sys_lxt_register()
|
|||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$dumpflush";
|
||||
tf_data.calltf = sys_dumpflush_calltf;
|
||||
tf_data.compiletf = sys_dumpflush_compiletf;
|
||||
tf_data.compiletf = sys_no_arg_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$dumpflush";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
|
@ -816,7 +790,7 @@ void sys_lxt_register()
|
|||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$dumpoff";
|
||||
tf_data.calltf = sys_dumpoff_calltf;
|
||||
tf_data.compiletf = sys_dumpoff_compiletf;
|
||||
tf_data.compiletf = sys_no_arg_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$dumpoff";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
|
@ -824,7 +798,7 @@ void sys_lxt_register()
|
|||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$dumpon";
|
||||
tf_data.calltf = sys_dumpon_calltf;
|
||||
tf_data.compiletf = sys_dumpon_compiletf;
|
||||
tf_data.compiletf = sys_no_arg_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$dumpon";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
|
@ -837,4 +811,3 @@ void sys_lxt_register()
|
|||
tf_data.user_data = "$dumpvars";
|
||||
vpi_register_systf(&tf_data);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003-2004 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2003-2008 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
|
||||
|
|
@ -16,9 +16,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: sys_lxt2.c,v 1.10 2007/03/14 04:05:51 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "sys_priv.h"
|
||||
# include "lxt2_write.h"
|
||||
|
|
@ -322,9 +319,9 @@ inline static int install_dumpvars_callback(void)
|
|||
if (dumpvars_status == 1) return 0;
|
||||
|
||||
if (dumpvars_status == 2) {
|
||||
vpi_mcd_printf(1, "LXT2 warning: $dumpvars ignored, previously"
|
||||
" called at simtime %" PLI_UINT64_FMT "\n",
|
||||
dumpvars_time);
|
||||
vpi_printf("LXT2 warning: $dumpvars ignored, previously"
|
||||
" called at simtime %" PLI_UINT64_FMT "\n",
|
||||
dumpvars_time);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -429,22 +426,23 @@ static void *close_dumpfile(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void open_dumpfile(void)
|
||||
static void open_dumpfile(vpiHandle callh)
|
||||
{
|
||||
if (dump_path == 0) dump_path = strdup("dump.lx2");
|
||||
|
||||
dump_file = lxt2_wr_init(dump_path);
|
||||
|
||||
if (dump_file == 0) {
|
||||
vpi_mcd_printf(1, "LXT2 Error: Unable to open %s for output.\n",
|
||||
dump_path);
|
||||
vpi_printf("LXT2 Error: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("Unable to open %s for output.\n", dump_path);
|
||||
vpi_control(vpiFinish, 1);
|
||||
return;
|
||||
} else {
|
||||
int prec = vpi_get(vpiTimePrecision, 0);
|
||||
|
||||
vpi_mcd_printf(1, "LXT2 info: dumpfile %s opened for output.\n",
|
||||
dump_path);
|
||||
vpi_printf("LXT2 info: dumpfile %s opened for output.\n",
|
||||
dump_path);
|
||||
|
||||
assert(prec >= -15);
|
||||
lxt2_wr_set_timescale(dump_file, prec);
|
||||
|
|
@ -468,9 +466,9 @@ static PLI_INT32 sys_dumpfile_calltf(PLI_BYTE8*name)
|
|||
|
||||
/* $dumpfile must be called before $dumpvars starts! */
|
||||
if (dumpvars_status != 0) {
|
||||
vpi_mcd_printf(1, "LXT2 warning: %s called after $dumpvars started"
|
||||
",\n using existing file (%s).\n",
|
||||
name, dump_path);
|
||||
vpi_printf("LXT2 warning: %s called after $dumpvars started,\n"
|
||||
" using existing file (%s).\n",
|
||||
name, dump_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -480,8 +478,8 @@ static PLI_INT32 sys_dumpfile_calltf(PLI_BYTE8*name)
|
|||
path = strdup(value.value.str);
|
||||
|
||||
if (dump_path) {
|
||||
vpi_mcd_printf(1, "LXT2 warning: Overriding dump file %s with"
|
||||
" %s.\n", dump_path, path);
|
||||
vpi_printf("LXT2 warning: Overriding dump file %s with %s.\n",
|
||||
dump_path, path);
|
||||
free(dump_path);
|
||||
}
|
||||
dump_path = path;
|
||||
|
|
@ -548,16 +546,9 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
|
|||
|
||||
switch (vpi_get(vpiType, item)) {
|
||||
|
||||
case vpiMemory:
|
||||
/* don't know how to watch memories. */
|
||||
break;
|
||||
|
||||
case vpiNamedEvent:
|
||||
/* There is nothing in named events to dump. */
|
||||
break;
|
||||
|
||||
case vpiNet: type = "wire"; if(0){
|
||||
case vpiIntegerVar:
|
||||
case vpiMemoryWord:
|
||||
case vpiTimeVar:
|
||||
case vpiReg: type = "reg"; }
|
||||
|
||||
|
|
@ -657,18 +648,16 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
|
|||
vpi_get_str(vpiFullName, item);
|
||||
|
||||
#if 0
|
||||
vpi_mcd_printf(1,
|
||||
"LXT2 info:"
|
||||
" scanning scope %s, %u levels\n",
|
||||
fullname, depth);
|
||||
vpi_printf("LXT2 info: scanning scope %s, %u levels\n",
|
||||
fullname, depth);
|
||||
#endif
|
||||
nskip = 0 != vcd_names_search(&lxt_tab, fullname);
|
||||
|
||||
if (!nskip)
|
||||
vcd_names_add(&lxt_tab, fullname);
|
||||
else
|
||||
vpi_mcd_printf(1, "LXT2 warning: ignoring signals in"
|
||||
" previously scanned scope %s\n", fullname);
|
||||
vpi_printf("LXT2 warning: ignoring signals in "
|
||||
"previously scanned scope %s\n", fullname);
|
||||
|
||||
name = vpi_get_str(vpiName, item);
|
||||
|
||||
|
|
@ -687,8 +676,8 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
|
|||
break;
|
||||
|
||||
default:
|
||||
vpi_mcd_printf(1, "LXT2 warning: $dumpvars: Unsupported parameter"
|
||||
" type (%d)\n", vpi_get(vpiType, item));
|
||||
vpi_printf("LXT2 warning: $dumpvars: Unsupported parameter "
|
||||
"type (%s)\n", vpi_get_str(vpiType, item));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -697,7 +686,6 @@ static int draw_scope(vpiHandle item)
|
|||
{
|
||||
int depth;
|
||||
const char *name;
|
||||
// char *type; // Not needed, see below.
|
||||
|
||||
vpiHandle scope = vpi_handle(vpiScope, item);
|
||||
if (!scope) return 0;
|
||||
|
|
@ -705,20 +693,6 @@ static int draw_scope(vpiHandle item)
|
|||
depth = 1 + draw_scope(scope);
|
||||
name = vpi_get_str(vpiName, scope);
|
||||
|
||||
#if 0 /* The type information is not needed by the LXT2 dumper. */
|
||||
switch (vpi_get(vpiType, item)) {
|
||||
case vpiNamedBegin: type = "begin"; break;
|
||||
case vpiTask: type = "task"; break;
|
||||
case vpiFunction: type = "function"; break;
|
||||
case vpiNamedFork: type = "fork"; break;
|
||||
case vpiModule: type = "module"; break;
|
||||
default:
|
||||
vpi_mcd_printf(1, "LXT2 Error: $dumpvars: Unsupported scope "
|
||||
"type (%d)\n", vpi_get(vpiType, item));
|
||||
assert(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
push_scope(name);
|
||||
|
||||
return depth;
|
||||
|
|
@ -733,7 +707,7 @@ static PLI_INT32 sys_dumpvars_calltf(PLI_BYTE8*name)
|
|||
unsigned depth = 0;
|
||||
|
||||
if (dump_file == 0) {
|
||||
open_dumpfile();
|
||||
open_dumpfile(callh);
|
||||
if (dump_file == 0) return 0;
|
||||
}
|
||||
|
||||
|
|
@ -799,7 +773,7 @@ void sys_lxt2_register()
|
|||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$dumpall";
|
||||
tf_data.calltf = sys_dumpall_calltf;
|
||||
tf_data.compiletf = sys_dumpall_compiletf;
|
||||
tf_data.compiletf = sys_no_arg_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$dumpall";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
|
@ -815,7 +789,7 @@ void sys_lxt2_register()
|
|||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$dumpflush";
|
||||
tf_data.calltf = sys_dumpflush_calltf;
|
||||
tf_data.compiletf = sys_dumpflush_compiletf;
|
||||
tf_data.compiletf = sys_no_arg_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$dumpflush";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
|
@ -831,7 +805,7 @@ void sys_lxt2_register()
|
|||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$dumpoff";
|
||||
tf_data.calltf = sys_dumpoff_calltf;
|
||||
tf_data.compiletf = sys_dumpoff_compiletf;
|
||||
tf_data.compiletf = sys_no_arg_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$dumpoff";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
|
@ -839,7 +813,7 @@ void sys_lxt2_register()
|
|||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$dumpon";
|
||||
tf_data.calltf = sys_dumpon_calltf;
|
||||
tf_data.compiletf = sys_dumpon_compiletf;
|
||||
tf_data.compiletf = sys_no_arg_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$dumpon";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
|
@ -852,4 +826,3 @@ void sys_lxt2_register()
|
|||
tf_data.user_data = "$dumpvars";
|
||||
vpi_register_systf(&tf_data);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright (c) 2003-2008 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 <assert.h>
|
||||
#include "sys_priv.h"
|
||||
|
||||
PLI_UINT64 timerec_to_time64(const struct t_vpi_time*time)
|
||||
{
|
||||
PLI_UINT64 tmp;
|
||||
|
||||
tmp = time->high;
|
||||
tmp <<= 32;
|
||||
tmp |= (PLI_UINT64) time->low;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine returns 1 if the argument is a constant value,
|
||||
* otherwise it returns 0.
|
||||
*/
|
||||
unsigned is_constant_obj(vpiHandle obj)
|
||||
{
|
||||
assert(obj);
|
||||
unsigned rtn = 0;
|
||||
|
||||
switch(vpi_get(vpiType, obj)) {
|
||||
case vpiConstant:
|
||||
case vpiParameter:
|
||||
rtn = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return rtn;
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine returns 1 if the argument supports has a numeric value,
|
||||
* otherwise it returns 0.
|
||||
*/
|
||||
unsigned is_numeric_obj(vpiHandle obj)
|
||||
{
|
||||
assert(obj);
|
||||
unsigned rtn = 0;
|
||||
|
||||
switch(vpi_get(vpiType, obj)) {
|
||||
case vpiConstant:
|
||||
case vpiParameter:
|
||||
/* These cannot be a string constant. */
|
||||
if (vpi_get(vpiConstType, obj) != vpiStringConst) rtn = 1;
|
||||
break;
|
||||
|
||||
/* These can have a valid numeric value. */
|
||||
case vpiIntegerVar:
|
||||
case vpiMemoryWord:
|
||||
case vpiNet:
|
||||
case vpiPartSelect:
|
||||
case vpiRealVar:
|
||||
case vpiReg:
|
||||
case vpiTimeVar:
|
||||
rtn = 1;;
|
||||
break;
|
||||
}
|
||||
|
||||
return rtn;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This routine returns 1 if the argument supports a valid string value,
|
||||
* otherwise it returns 0.
|
||||
*/
|
||||
unsigned is_string_obj(vpiHandle obj)
|
||||
{
|
||||
assert(obj);
|
||||
unsigned rtn = 0;
|
||||
|
||||
switch(vpi_get(vpiType, obj)) {
|
||||
case vpiConstant:
|
||||
case vpiParameter: {
|
||||
/* These must be a string or binary constant. */
|
||||
PLI_INT32 ctype = vpi_get(vpiConstType, obj);
|
||||
if (ctype == vpiStringConst || ctype == vpiBinaryConst) rtn = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* These can have a valid string value. */
|
||||
case vpiIntegerVar:
|
||||
case vpiMemoryWord:
|
||||
case vpiNet:
|
||||
case vpiPartSelect:
|
||||
case vpiReg:
|
||||
case vpiTimeVar:
|
||||
rtn = 1;;
|
||||
break;
|
||||
}
|
||||
|
||||
return rtn;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find the enclosing module.
|
||||
*/
|
||||
vpiHandle sys_func_module(vpiHandle obj)
|
||||
{
|
||||
assert(obj);
|
||||
|
||||
while (vpi_get(vpiType, obj) != vpiModule) {
|
||||
obj = vpi_handle(vpiScope, obj);
|
||||
assert(obj);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __vpi_sys_priv_H
|
||||
#define __vpi_sys_priv_H
|
||||
/*
|
||||
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2002-2008 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,12 +18,9 @@
|
|||
* 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: sys_priv.h,v 1.8 2007/03/14 04:05:51 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vpi_config.h"
|
||||
# include "vpi_user.h"
|
||||
#include "vpi_config.h"
|
||||
#include "vpi_user.h"
|
||||
|
||||
/*
|
||||
* Context structure for PRNG in mt19937int.c
|
||||
|
|
@ -36,9 +33,6 @@ struct context_s {
|
|||
extern void sgenrand(struct context_s *context, unsigned long seed);
|
||||
extern unsigned long genrand(struct context_s *context);
|
||||
|
||||
|
||||
extern int is_constant(vpiHandle obj);
|
||||
|
||||
extern PLI_UINT64 timerec_to_time64(const struct t_vpi_time*time);
|
||||
|
||||
struct timeformat_info_s {
|
||||
|
|
@ -50,4 +44,10 @@ struct timeformat_info_s {
|
|||
|
||||
extern struct timeformat_info_s timeformat_info;
|
||||
|
||||
extern unsigned is_constant_obj(vpiHandle obj);
|
||||
extern unsigned is_numeric_obj(vpiHandle obj);
|
||||
extern unsigned is_string_obj(vpiHandle obj);
|
||||
|
||||
extern vpiHandle sys_func_module(vpiHandle obj);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ extern void sys_time_register();
|
|||
extern void sys_vcd_register();
|
||||
extern void sys_vcdoff_register();
|
||||
extern void sys_special_register();
|
||||
extern void vams_simparam_register();
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
#ifdef HAVE_LIBBZ2
|
||||
|
|
@ -180,5 +181,6 @@ void (*vlog_startup_routines[])() = {
|
|||
sys_lxt_or_vcd_register,
|
||||
sys_sdf_register,
|
||||
sys_special_register,
|
||||
vams_simparam_register,
|
||||
0
|
||||
};
|
||||
|
|
|
|||
139
vpi/sys_time.c
139
vpi/sys_time.c
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2008 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
|
||||
|
|
@ -16,36 +16,14 @@
|
|||
* 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: sys_time.c,v 1.12 2007/03/14 04:05:51 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vpi_config.h"
|
||||
#include "vpi_config.h"
|
||||
|
||||
# include "vpi_user.h"
|
||||
# include <string.h>
|
||||
# include <math.h>
|
||||
# include <assert.h>
|
||||
|
||||
static vpiHandle module_of_function(vpiHandle obj)
|
||||
{
|
||||
while (vpi_get(vpiType, obj) != vpiModule) {
|
||||
obj = vpi_handle(vpiScope, obj);
|
||||
assert(obj);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
static PLI_INT32 sys_time_sizetf(PLI_BYTE8*x)
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
|
||||
static PLI_INT32 sys_stime_sizetf(PLI_BYTE8*x)
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
#include "vpi_user.h"
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <sys_priv.h>
|
||||
|
||||
static PLI_INT32 sys_time_calltf(PLI_BYTE8*name)
|
||||
{
|
||||
|
|
@ -60,7 +38,7 @@ static PLI_INT32 sys_time_calltf(PLI_BYTE8*name)
|
|||
call_handle = vpi_handle(vpiSysTfCall, 0);
|
||||
assert(call_handle);
|
||||
|
||||
mod = module_of_function(call_handle);
|
||||
mod = sys_func_module(call_handle);
|
||||
|
||||
now.type = vpiSimTime;
|
||||
vpi_get_time(0, &now);
|
||||
|
|
@ -113,7 +91,7 @@ static PLI_INT32 sys_realtime_calltf(PLI_BYTE8*name)
|
|||
call_handle = vpi_handle(vpiSysTfCall, 0);
|
||||
assert(call_handle);
|
||||
|
||||
mod = module_of_function(call_handle);
|
||||
mod = sys_func_module(call_handle);
|
||||
|
||||
now.type = vpiSimTime;
|
||||
vpi_get_time(0, &now);
|
||||
|
|
@ -134,82 +112,39 @@ void sys_time_register()
|
|||
{
|
||||
s_vpi_systf_data tf_data;
|
||||
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.tfname = "$time";
|
||||
tf_data.calltf = sys_time_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = sys_time_sizetf;
|
||||
tf_data.user_data = "$time";
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.tfname = "$time";
|
||||
tf_data.sysfunctype = vpiTimeFunc;
|
||||
tf_data.calltf = sys_time_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$time";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.tfname = "$realtime";
|
||||
tf_data.calltf = sys_realtime_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$realtime";
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.tfname = "$realtime";
|
||||
tf_data.sysfunctype = vpiRealFunc;
|
||||
tf_data.calltf = sys_realtime_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$realtime";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.tfname = "$stime";
|
||||
tf_data.calltf = sys_time_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = sys_stime_sizetf;
|
||||
tf_data.user_data = "$stime";
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.tfname = "$stime";
|
||||
tf_data.sysfunctype = vpiIntFunc;
|
||||
tf_data.calltf = sys_time_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$stime";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.tfname = "$simtime";
|
||||
tf_data.calltf = sys_time_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = sys_time_sizetf;
|
||||
tf_data.user_data = "$simtime";
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.tfname = "$simtime";
|
||||
tf_data.sysfunctype = vpiTimeFunc;
|
||||
tf_data.calltf = sys_time_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$simtime";
|
||||
vpi_register_systf(&tf_data);
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: sys_time.c,v $
|
||||
* Revision 1.12 2007/03/14 04:05:51 steve
|
||||
* VPI tasks take PLI_BYTE* by the standard.
|
||||
*
|
||||
* Revision 1.11 2006/10/30 22:45:37 steve
|
||||
* Updates for Cygwin portability (pr1585922)
|
||||
*
|
||||
* Revision 1.10 2004/01/21 01:22:53 steve
|
||||
* Give the vip directory its own configure and vpi_config.h
|
||||
*
|
||||
* Revision 1.9 2003/06/18 00:54:28 steve
|
||||
* Account for all 64 bits in results of $time.
|
||||
*
|
||||
* Revision 1.8 2003/02/07 02:44:25 steve
|
||||
* Properly round inter time values from $time.
|
||||
*
|
||||
* Revision 1.7 2003/01/28 04:41:55 steve
|
||||
* Use more precise pow function to scale time by units.
|
||||
*
|
||||
* Revision 1.6 2003/01/27 00:14:37 steve
|
||||
* Support in various contexts the $realtime
|
||||
* system task.
|
||||
*
|
||||
* Revision 1.5 2002/12/21 00:55:58 steve
|
||||
* The $time system task returns the integer time
|
||||
* scaled to the local units. Change the internal
|
||||
* implementation of vpiSystemTime the $time functions
|
||||
* to properly account for this. Also add $simtime
|
||||
* to get the simulation time.
|
||||
*
|
||||
* Revision 1.4 2002/08/12 01:35:05 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.3 2002/01/11 05:20:59 steve
|
||||
* Add the stime system function.
|
||||
*
|
||||
* Revision 1.2 2001/07/25 03:10:50 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.1 2000/11/01 03:19:36 steve
|
||||
* Add the general $time system function.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2003 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2008 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
|
||||
|
|
@ -16,9 +16,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: sys_vcd.c,v 1.58 2007/03/14 04:05:51 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "sys_priv.h"
|
||||
|
||||
|
|
@ -269,9 +266,9 @@ inline static int install_dumpvars_callback(void)
|
|||
if (dumpvars_status == 1) return 0;
|
||||
|
||||
if (dumpvars_status == 2) {
|
||||
vpi_mcd_printf(1, "VCD warning: $dumpvars ignored, previously"
|
||||
" called at simtime %" PLI_UINT64_FMT "\n",
|
||||
dumpvars_time);
|
||||
vpi_printf("VCD warning: $dumpvars ignored, previously"
|
||||
" called at simtime %" PLI_UINT64_FMT "\n",
|
||||
dumpvars_time);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -374,15 +371,16 @@ static PLI_INT32 sys_dumpall_calltf(PLI_BYTE8*name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void open_dumpfile(void)
|
||||
static void open_dumpfile(vpiHandle callh)
|
||||
{
|
||||
if (dump_path == 0) dump_path = strdup("dump.vcd");
|
||||
|
||||
dump_file = fopen(dump_path, "w");
|
||||
|
||||
if (dump_file == 0) {
|
||||
vpi_mcd_printf(1, "VCD Error: Unable to open %s for output.\n",
|
||||
dump_path);
|
||||
vpi_printf("VCD Error: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("Unable to open %s for output.\n", dump_path);
|
||||
vpi_control(vpiFinish, 1);
|
||||
return;
|
||||
} else {
|
||||
|
|
@ -391,8 +389,7 @@ static void open_dumpfile(void)
|
|||
unsigned udx = 0;
|
||||
time_t walltime;
|
||||
|
||||
vpi_mcd_printf(1, "VCD info: dumpfile %s opened for output.\n",
|
||||
dump_path);
|
||||
vpi_printf("VCD info: dumpfile %s opened for output.\n", dump_path);
|
||||
|
||||
time(&walltime);
|
||||
|
||||
|
|
@ -428,9 +425,9 @@ static PLI_INT32 sys_dumpfile_calltf(PLI_BYTE8*name)
|
|||
|
||||
/* $dumpfile must be called before $dumpvars starts! */
|
||||
if (dumpvars_status != 0) {
|
||||
vpi_mcd_printf(1, "VCD warning: %s called after $dumpvars started"
|
||||
",\n using existing file (%s).\n",
|
||||
name, dump_path);
|
||||
vpi_printf("VCD warning: %s called after $dumpvars started,\n"
|
||||
" using existing file (%s).\n",
|
||||
name, dump_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -440,8 +437,8 @@ static PLI_INT32 sys_dumpfile_calltf(PLI_BYTE8*name)
|
|||
path = strdup(value.value.str);
|
||||
|
||||
if (dump_path) {
|
||||
vpi_mcd_printf(1, "VCD warning: Overriding dump file %s with"
|
||||
" %s\n", dump_path, path);
|
||||
vpi_printf("VCD warning: Overriding dump file %s with %s\n",
|
||||
dump_path, path);
|
||||
free(dump_path);
|
||||
}
|
||||
dump_path = path;
|
||||
|
|
@ -502,16 +499,9 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
|
|||
|
||||
switch (vpi_get(vpiType, item)) {
|
||||
|
||||
case vpiMemory:
|
||||
/* don't know how to watch memories. */
|
||||
break;
|
||||
|
||||
case vpiNamedEvent:
|
||||
/* There is nothing in named events to dump. */
|
||||
break;
|
||||
|
||||
case vpiNet: type = "wire"; if(0){
|
||||
case vpiIntegerVar:
|
||||
case vpiMemoryWord:
|
||||
case vpiTimeVar:
|
||||
case vpiReg: type = "reg"; }
|
||||
|
||||
|
|
@ -635,18 +625,16 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
|
|||
vpi_get_str(vpiFullName, item);
|
||||
|
||||
#if 0
|
||||
vpi_mcd_printf(1,
|
||||
"VCD info:"
|
||||
" scanning scope %s, %u levels\n",
|
||||
fullname, depth);
|
||||
vpi_printf("VCD info: scanning scope %s, %u levels\n",
|
||||
fullname, depth);
|
||||
#endif
|
||||
nskip = 0 != vcd_names_search(&vcd_tab, fullname);
|
||||
|
||||
if (!nskip)
|
||||
vcd_names_add(&vcd_tab, fullname);
|
||||
else
|
||||
vpi_mcd_printf(1, "VCD warning: ignoring signals in"
|
||||
" previously scanned scope %s\n", fullname);
|
||||
vpi_printf("VCD warning: ignoring signals in "
|
||||
"previously scanned scope %s\n", fullname);
|
||||
|
||||
name = vpi_get_str(vpiName, item);
|
||||
|
||||
|
|
@ -665,12 +653,12 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
|
|||
break;
|
||||
|
||||
default:
|
||||
vpi_mcd_printf(1, "VCD warning: $dumpvars: Unsupported parameter "
|
||||
"type (%d)\n", vpi_get(vpiType, item));
|
||||
vpi_printf("VCD warning: $dumpvars: Unsupported parameter "
|
||||
"type (%s)\n", vpi_get_str(vpiType, item));
|
||||
}
|
||||
}
|
||||
|
||||
static int draw_scope(vpiHandle item)
|
||||
static int draw_scope(vpiHandle item, vpiHandle callh)
|
||||
{
|
||||
int depth;
|
||||
const char *name;
|
||||
|
|
@ -679,7 +667,7 @@ static int draw_scope(vpiHandle item)
|
|||
vpiHandle scope = vpi_handle(vpiScope, item);
|
||||
if (!scope) return 0;
|
||||
|
||||
depth = 1 + draw_scope(scope);
|
||||
depth = 1 + draw_scope(scope, callh);
|
||||
name = vpi_get_str(vpiName, scope);
|
||||
|
||||
switch (vpi_get(vpiType, scope)) {
|
||||
|
|
@ -689,8 +677,9 @@ static int draw_scope(vpiHandle item)
|
|||
case vpiNamedFork: type = "fork"; break;
|
||||
case vpiModule: type = "module"; break;
|
||||
default:
|
||||
vpi_mcd_printf(1, "VCD Error: $dumpvars: Unsupported scope "
|
||||
"type (%d)\n", vpi_get(vpiType, item));
|
||||
vpi_printf("VCD Error: %s line %d: $dumpvars: Unsupported scope "
|
||||
"type (%d)\n", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh), vpi_get(vpiType, item));
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
|
@ -708,7 +697,7 @@ static PLI_INT32 sys_dumpvars_calltf(PLI_BYTE8*name)
|
|||
unsigned depth = 0;
|
||||
|
||||
if (dump_file == 0) {
|
||||
open_dumpfile();
|
||||
open_dumpfile(callh);
|
||||
if (dump_file == 0) return 0;
|
||||
}
|
||||
|
||||
|
|
@ -739,23 +728,23 @@ static PLI_INT32 sys_dumpvars_calltf(PLI_BYTE8*name)
|
|||
* been included. */
|
||||
switch (vpi_get(vpiType, item)) {
|
||||
case vpiIntegerVar:
|
||||
/* What about MemoryWord? */
|
||||
case vpiMemoryWord:
|
||||
case vpiNet:
|
||||
case vpiRealVar:
|
||||
case vpiReg:
|
||||
case vpiTimeVar:
|
||||
scname = vpi_get_str(vpiFullName, vpi_handle(vpiScope, item));
|
||||
if (vcd_names_search(&vcd_tab, scname)) {
|
||||
vpi_mcd_printf(1, "VCD warning: skipping signal %s, "
|
||||
"it was previously included.\n",
|
||||
vpi_get_str(vpiFullName, item));
|
||||
vpi_printf("VCD warning: skipping signal %s, "
|
||||
"it was previously included.\n",
|
||||
vpi_get_str(vpiFullName, item));
|
||||
continue;
|
||||
} else {
|
||||
add_var = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int dep = draw_scope(item);
|
||||
int dep = draw_scope(item, callh);
|
||||
|
||||
scan_item(depth, item, 0);
|
||||
|
||||
|
|
@ -782,7 +771,7 @@ void sys_vcd_register()
|
|||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$dumpall";
|
||||
tf_data.calltf = sys_dumpall_calltf;
|
||||
tf_data.compiletf = sys_dumpall_compiletf;
|
||||
tf_data.compiletf = sys_no_arg_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$dumpall";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
|
@ -798,7 +787,7 @@ void sys_vcd_register()
|
|||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$dumpflush";
|
||||
tf_data.calltf = sys_dumpflush_calltf;
|
||||
tf_data.compiletf = sys_dumpflush_compiletf;
|
||||
tf_data.compiletf = sys_no_arg_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$dumpflush";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
|
@ -814,7 +803,7 @@ void sys_vcd_register()
|
|||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$dumpoff";
|
||||
tf_data.calltf = sys_dumpoff_calltf;
|
||||
tf_data.compiletf = sys_dumpoff_compiletf;
|
||||
tf_data.compiletf = sys_no_arg_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$dumpoff";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
|
@ -822,7 +811,7 @@ void sys_vcd_register()
|
|||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$dumpon";
|
||||
tf_data.calltf = sys_dumpon_calltf;
|
||||
tf_data.compiletf = sys_dumpon_compiletf;
|
||||
tf_data.compiletf = sys_no_arg_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$dumpon";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
|
@ -835,4 +824,3 @@ void sys_vcd_register()
|
|||
tf_data.user_data = "$dumpvars";
|
||||
vpi_register_systf(&tf_data);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2003-2008 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
|
||||
|
|
@ -16,9 +16,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: sys_vcdoff.c,v 1.5 2007/03/14 04:05:52 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "sys_priv.h"
|
||||
|
||||
|
|
@ -40,7 +37,7 @@
|
|||
|
||||
static int dump_flag = 0;
|
||||
|
||||
static PLI_INT32 sys_dump_calltf(PLI_BYTE8*name)
|
||||
static PLI_INT32 sys_dummy_calltf(PLI_BYTE8*name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -48,7 +45,7 @@ static PLI_INT32 sys_dump_calltf(PLI_BYTE8*name)
|
|||
static PLI_INT32 sys_dumpvars_calltf(PLI_BYTE8*name)
|
||||
{
|
||||
if (dump_flag == 0) {
|
||||
vpi_mcd_printf(1, "VCD info: dumping is suppressed.\n");
|
||||
vpi_printf("VCD info: dumping is suppressed.\n");
|
||||
dump_flag = 1;
|
||||
}
|
||||
|
||||
|
|
@ -63,15 +60,15 @@ void sys_vcdoff_register()
|
|||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$dumpall";
|
||||
tf_data.calltf = sys_dump_calltf;
|
||||
tf_data.compiletf = sys_dumpall_compiletf;
|
||||
tf_data.calltf = sys_dummy_calltf;
|
||||
tf_data.compiletf = sys_no_arg_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$dumpall";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$dumpfile";
|
||||
tf_data.calltf = sys_dump_calltf;
|
||||
tf_data.calltf = sys_dummy_calltf;
|
||||
tf_data.compiletf = sys_dumpfile_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$dumpfile";
|
||||
|
|
@ -79,15 +76,15 @@ void sys_vcdoff_register()
|
|||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$dumpflush";
|
||||
tf_data.calltf = sys_dump_calltf;
|
||||
tf_data.compiletf = sys_dumpflush_compiletf;
|
||||
tf_data.calltf = sys_dummy_calltf;
|
||||
tf_data.compiletf = sys_no_arg_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$dumpflush";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$dumplimit";
|
||||
tf_data.calltf = sys_dump_calltf;
|
||||
tf_data.calltf = sys_dummy_calltf;
|
||||
tf_data.compiletf = sys_dumplimit_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$dumplimit";
|
||||
|
|
@ -95,16 +92,16 @@ void sys_vcdoff_register()
|
|||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$dumpoff";
|
||||
tf_data.calltf = sys_dump_calltf;
|
||||
tf_data.compiletf = sys_dumpoff_compiletf;
|
||||
tf_data.calltf = sys_dummy_calltf;
|
||||
tf_data.compiletf = sys_no_arg_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$dumpoff";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$dumpon";
|
||||
tf_data.calltf = sys_dump_calltf;
|
||||
tf_data.compiletf = sys_dumpon_compiletf;
|
||||
tf_data.calltf = sys_dummy_calltf;
|
||||
tf_data.compiletf = sys_no_arg_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$dumpon";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
|
@ -117,4 +114,3 @@ void sys_vcdoff_register()
|
|||
tf_data.user_data = "$dumpvars";
|
||||
vpi_register_systf(&tf_data);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,4 +14,6 @@ $dist_poisson vpiSysFuncInt
|
|||
$dist_chi_square vpiSysFuncInt
|
||||
$dist_t vpiSysFuncInt
|
||||
$dist_erlang vpiSysFuncInt
|
||||
$vvp_cpu_wordsize vpiSysFuncInt
|
||||
|
||||
$simparam vpiSysFuncReal
|
||||
$simparam$str vpiSysFuncSized 1024 unsigned
|
||||
|
|
|
|||
|
|
@ -0,0 +1,268 @@
|
|||
/*
|
||||
* Copyright (C) 2008 Cary R. (cygcary@yahoo.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <vpi_user.h>
|
||||
#include "sys_priv.h"
|
||||
|
||||
/* Once we have real string objects replace this with a dynamic string. */
|
||||
#define MAX_STRING_RESULT 1024
|
||||
|
||||
|
||||
/*
|
||||
* Check that the routines are called with the correct arguments.
|
||||
*/
|
||||
static PLI_INT32 simparam_compiletf(PLI_BYTE8* ud)
|
||||
{
|
||||
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||
assert(callh != 0);
|
||||
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
||||
vpiHandle arg;
|
||||
|
||||
/* We must have at least one argument. */
|
||||
if (argv == 0) {
|
||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("$simparam%s requires an argument.\n", ud);
|
||||
vpi_control(vpiFinish, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The first argument must be a string. */
|
||||
arg = vpi_scan(argv);
|
||||
if (! is_string_obj(arg)) {
|
||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("The first argument to $simparam%s must be a string.\n", ud);
|
||||
vpi_control(vpiFinish, 1);
|
||||
}
|
||||
|
||||
/* The second argument (default value) is optional. */
|
||||
arg = vpi_scan(argv);
|
||||
if (arg == 0) return 0;
|
||||
|
||||
/* For the string version the default must also be a string. */
|
||||
if (strcmp(ud, "$str") == 0) {
|
||||
if (! is_string_obj(arg)) {
|
||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("When provided, the second argument to $simparam%s"
|
||||
"must be a string.\n", ud);
|
||||
vpi_control(vpiFinish, 1);
|
||||
}
|
||||
/* For the rest the default must be numeric. */
|
||||
} else {
|
||||
if (! is_numeric_obj(arg)) {
|
||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("When provided, the second argument to $simparam%s"
|
||||
"must be numeric.\n", ud);
|
||||
vpi_control(vpiFinish, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* We can only have two argument. */
|
||||
if (vpi_scan(argv) != 0) {
|
||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("$simparam%s takes at most two arguments.\n", ud);
|
||||
vpi_control(vpiFinish, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PLI_INT32 simparam_calltf(PLI_BYTE8* ud)
|
||||
{
|
||||
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
||||
vpiHandle arg;
|
||||
s_vpi_value val;
|
||||
char *param;
|
||||
unsigned have_def_val = 0;
|
||||
double retval, defval = 0.0;
|
||||
|
||||
/* Get the parameter we are looking for. */
|
||||
arg = vpi_scan(argv);
|
||||
val.format = vpiStringVal;
|
||||
vpi_get_value(arg, &val);
|
||||
param = strdup(val.value.str);
|
||||
|
||||
/* See if there is a default value. */
|
||||
arg = vpi_scan(argv);
|
||||
if (arg != 0) {
|
||||
vpi_free_object(argv);
|
||||
have_def_val = 1;
|
||||
val.format = vpiRealVal;
|
||||
vpi_get_value(arg, &val);
|
||||
defval = val.value.real;
|
||||
}
|
||||
|
||||
/* Now check the various things we can return. */
|
||||
if (strcmp(param, "gdev") == 0) {
|
||||
retval = 0.0; /* Nothing for now. */
|
||||
} else if (strcmp(param, "gmin") == 0) {
|
||||
retval = 0.0; /* Nothing for now. */
|
||||
} else if (strcmp(param, "imax") == 0) {
|
||||
retval = 0.0; /* Nothing for now. */
|
||||
} else if (strcmp(param, "imelt") == 0) {
|
||||
retval = 0.0; /* Nothing for now. */
|
||||
} else if (strcmp(param, "iteration") == 0) {
|
||||
retval = 0.0; /* Nothing for now. */
|
||||
} else if (strcmp(param, "scale") == 0) {
|
||||
retval = 0.0; /* Nothing for now. */
|
||||
} else if (strcmp(param, "shrink") == 0) {
|
||||
retval = 0.0; /* Nothing for now. */
|
||||
} else if (strcmp(param, "simulatorSubversion") == 0) {
|
||||
retval = 0.0;
|
||||
} else if (strcmp(param, "simulatorVersion") == 0) {
|
||||
retval = 0.9;
|
||||
} else if (strcmp(param, "sourceScaleFactor") == 0) {
|
||||
retval = 0.0; /* Nothing for now. */
|
||||
} else if (strcmp(param, "tnom") == 0) {
|
||||
retval = 0.0; /* Nothing for now. */
|
||||
} else if (strcmp(param, "timeUnit") == 0) {
|
||||
retval = pow(10, vpi_get(vpiTimeUnit, sys_func_module(callh)));
|
||||
} else if (strcmp(param, "timePrecision") == 0) {
|
||||
retval = pow(10, vpi_get(vpiTimePrecision, sys_func_module(callh)));
|
||||
} else if (strcmp(param, "CPUWordSize") == 0) {
|
||||
retval = 8.0*sizeof(long);
|
||||
} else {
|
||||
if (! have_def_val) {
|
||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("unknown parameter name \"%s\".\n", param);
|
||||
}
|
||||
retval = defval;
|
||||
}
|
||||
|
||||
free(param);
|
||||
|
||||
/* Return the value to the system. */
|
||||
val.format = vpiRealVal;
|
||||
val.value.real = retval;
|
||||
vpi_put_value(callh, &val, 0, vpiNoDelay);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PLI_INT32 simparam_str_calltf(PLI_BYTE8* ud)
|
||||
{
|
||||
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
||||
vpiHandle arg;
|
||||
s_vpi_value val;
|
||||
char *param;
|
||||
char *retval, *defval = NULL;
|
||||
|
||||
/* Get the parameter we are looking for. */
|
||||
arg = vpi_scan(argv);
|
||||
val.format = vpiStringVal;
|
||||
vpi_get_value(arg, &val);
|
||||
param = strdup(val.value.str);
|
||||
|
||||
/* See if there is a default value. */
|
||||
arg = vpi_scan(argv);
|
||||
if (arg != 0) {
|
||||
vpi_free_object(argv);
|
||||
val.format = vpiStringVal;
|
||||
vpi_get_value(arg, &val);
|
||||
defval = strdup(val.value.str);
|
||||
}
|
||||
|
||||
/* Now check the various things we can return. */
|
||||
/* For now we limit the result to 1024 characters. */
|
||||
if (strcmp(param, "analysis_name") == 0) {
|
||||
retval = strdup("N/A"); /* Nothing for now. */
|
||||
} else if (strcmp(param, "analysis_type") == 0) {
|
||||
retval = strdup("N/A"); /* Nothing for now. */
|
||||
} else if (strcmp(param, "cwd") == 0) {
|
||||
char path [MAX_STRING_RESULT];
|
||||
char *ptr = getcwd(path, MAX_STRING_RESULT);
|
||||
if (ptr == NULL) {
|
||||
ptr = strcpy(path, "<error getting the cwd, "
|
||||
"is it too long?>");
|
||||
}
|
||||
retval = strdup(path);
|
||||
} else if (strcmp(param, "module") == 0) {
|
||||
retval = strdup(vpi_get_str(vpiDefName, sys_func_module(callh)));
|
||||
} else if (strcmp(param, "instance") == 0) {
|
||||
retval = strdup(vpi_get_str(vpiFullName, sys_func_module(callh)));
|
||||
} else if (strcmp(param, "path") == 0) {
|
||||
retval = strdup(vpi_get_str(vpiFullName,
|
||||
vpi_handle(vpiScope,callh)));
|
||||
} else {
|
||||
if (defval == 0) {
|
||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("unknown parameter name \"%s\".\n", param);
|
||||
defval = strdup("<error>");
|
||||
}
|
||||
retval = defval;
|
||||
}
|
||||
|
||||
free(param);
|
||||
|
||||
/* Return the value to the system. */
|
||||
val.format = vpiStringVal;
|
||||
val.value.str = retval;
|
||||
vpi_put_value(callh, &val, 0, vpiNoDelay);
|
||||
free(retval);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PLI_INT32 simparam_str_sizetf(PLI_BYTE8* ud)
|
||||
{
|
||||
(void) ud; //* Not used! */
|
||||
|
||||
return MAX_STRING_RESULT; // 128 characters max!
|
||||
}
|
||||
|
||||
/*
|
||||
* Register the function with Verilog.
|
||||
*/
|
||||
void vams_simparam_register(void)
|
||||
{
|
||||
s_vpi_systf_data tf_data;
|
||||
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.sysfunctype = vpiRealFunc;
|
||||
tf_data.calltf = simparam_calltf;
|
||||
tf_data.compiletf = simparam_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.tfname = "$simparam";
|
||||
tf_data.user_data = "";
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.sysfunctype = vpiSizedFunc; /* What should this be? */
|
||||
tf_data.calltf = simparam_str_calltf;
|
||||
tf_data.compiletf = simparam_compiletf;
|
||||
tf_data.sizetf = simparam_str_sizetf; /* Only 128 characters! */
|
||||
tf_data.tfname = "$simparam$str";
|
||||
tf_data.user_data = "$str";
|
||||
vpi_register_systf(&tf_data);
|
||||
}
|
||||
201
vpi/vcd_priv.c
201
vpi/vcd_priv.c
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2003-2008 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
|
||||
|
|
@ -16,21 +16,19 @@
|
|||
* 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: vcd_priv.c,v 1.6 2004/10/04 01:10:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vpi_config.h"
|
||||
# include "vcd_priv.h"
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <assert.h>
|
||||
#include "vpi_config.h"
|
||||
#include "vcd_priv.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
# include <ctype.h>
|
||||
# include "stringheap.h"
|
||||
#include <ctype.h>
|
||||
#include "stringheap.h"
|
||||
#include <sys_priv.h>
|
||||
|
||||
int is_escaped_id(const char *name)
|
||||
{
|
||||
|
|
@ -188,86 +186,21 @@ void set_nexus_ident(int nex, const char *id)
|
|||
vcd_ids[ihash(nex)] = bucket;
|
||||
}
|
||||
|
||||
/* This is used by the compiletf routines to check if an argument
|
||||
* is numeric. */
|
||||
static void check_numeric_arg(vpiHandle arg, char *msg, PLI_BYTE8 *name)
|
||||
{
|
||||
assert(arg);
|
||||
|
||||
switch (vpi_get(vpiType, arg)) {
|
||||
case vpiConstant:
|
||||
case vpiParameter:
|
||||
/* String constants are invalid numeric values. */
|
||||
if (vpi_get(vpiConstType, arg) == vpiStringConst) {
|
||||
vpi_mcd_printf(1, msg, name);
|
||||
vpi_control(vpiFinish, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
/* These have valid numeric values. */
|
||||
case vpiIntegerVar:
|
||||
case vpiMemoryWord:
|
||||
case vpiNet:
|
||||
case vpiRealVar:
|
||||
case vpiReg:
|
||||
case vpiTimeVar:
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Anything else is not a numeric value. */
|
||||
vpi_mcd_printf(1, msg, name);
|
||||
vpi_control(vpiFinish, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* This is used by the compiletf routines to check if an argument
|
||||
* is a string value. */
|
||||
static void check_string_arg(vpiHandle arg, char *msg, PLI_BYTE8 *name)
|
||||
{
|
||||
assert(arg);
|
||||
PLI_INT32 ctype = 0;
|
||||
|
||||
switch (vpi_get(vpiType, arg)) {
|
||||
case vpiConstant:
|
||||
case vpiParameter:
|
||||
/* These must be a string or binary constant. */
|
||||
ctype = vpi_get(vpiConstType, arg);
|
||||
if (ctype != vpiStringConst && ctype != vpiBinaryConst) {
|
||||
vpi_mcd_printf(1, msg, name);
|
||||
vpi_control(vpiFinish, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
/* These have valid string values. */
|
||||
case vpiIntegerVar:
|
||||
case vpiMemoryWord:
|
||||
case vpiNet:
|
||||
case vpiReg:
|
||||
case vpiTimeVar:
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Anything else is not a string. */
|
||||
vpi_mcd_printf(1, msg, name);
|
||||
vpi_control(vpiFinish, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Since the compiletf routines are all the same they are located here,
|
||||
* so we only need a single copy.
|
||||
*/
|
||||
|
||||
/* $dumpall does not take an argument. */
|
||||
PLI_INT32 sys_dumpall_compiletf(PLI_BYTE8 *name)
|
||||
/* $dumpall, $dumpflush, $dumpoff and $dumpon do not take an argument. */
|
||||
PLI_INT32 sys_no_arg_compiletf(PLI_BYTE8 *name)
|
||||
{
|
||||
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
||||
|
||||
if (argv != 0) {
|
||||
vpi_mcd_printf(1, "ERROR: %s does not take an argument.\n", name);
|
||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("%s does not take an argument.\n", name);
|
||||
vpi_control(vpiFinish, 1);
|
||||
}
|
||||
|
||||
|
|
@ -282,31 +215,24 @@ PLI_INT32 sys_dumpfile_compiletf(PLI_BYTE8 *name)
|
|||
|
||||
/* Check that there is an argument and that it is a string. */
|
||||
if (argv == 0) {
|
||||
vpi_mcd_printf(1, "ERROR: %s requires an argument.\n", name);
|
||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("%s requires an argument.\n", name);
|
||||
vpi_control(vpiFinish, 1);
|
||||
return 0;
|
||||
}
|
||||
check_string_arg(vpi_scan(argv), "ERROR: %s's argument must be a"
|
||||
" string.\n", name);
|
||||
if (! is_string_obj(vpi_scan(argv))) {
|
||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("%s's argument must be a string.\n", name);
|
||||
vpi_control(vpiFinish, 1);
|
||||
}
|
||||
|
||||
/* Check that there is only a single argument. */
|
||||
if (vpi_scan(argv) != 0) {
|
||||
vpi_mcd_printf(1, "ERROR: %s takes a single argument.\n", name);
|
||||
vpi_control(vpiFinish, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* $dumpflush does not take an argument. */
|
||||
PLI_INT32 sys_dumpflush_compiletf(PLI_BYTE8 *name)
|
||||
{
|
||||
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
||||
|
||||
if (argv != 0) {
|
||||
vpi_mcd_printf(1, "ERROR: %s does not take an argument.\n", name);
|
||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("%s takes a single argument.\n", name);
|
||||
vpi_control(vpiFinish, 1);
|
||||
}
|
||||
|
||||
|
|
@ -321,45 +247,25 @@ PLI_INT32 sys_dumplimit_compiletf(PLI_BYTE8 *name)
|
|||
|
||||
/* Check that there is an argument and that it is numeric. */
|
||||
if (argv == 0) {
|
||||
vpi_mcd_printf(1, "ERROR: %s requires an argument.\n", name);
|
||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("%s requires an argument.\n", name);
|
||||
vpi_control(vpiFinish, 1);
|
||||
return 0;
|
||||
}
|
||||
check_numeric_arg(vpi_scan(argv), "ERROR: %s's argument must be"
|
||||
" numeric.\n", name);
|
||||
|
||||
if (! is_numeric_obj(vpi_scan(argv))) {
|
||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("%s's argument must be numeric.\n", name);
|
||||
vpi_control(vpiFinish, 1);
|
||||
}
|
||||
|
||||
/* Check that there is only a single argument. */
|
||||
if (vpi_scan(argv) != 0) {
|
||||
vpi_mcd_printf(1, "ERROR: %s takes a single argument.\n", name);
|
||||
vpi_control(vpiFinish, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* $dumpoff does not take an argument. */
|
||||
PLI_INT32 sys_dumpoff_compiletf(PLI_BYTE8 *name)
|
||||
{
|
||||
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
||||
|
||||
if (argv != 0) {
|
||||
vpi_mcd_printf(1, "ERROR: %s does not take an argument.\n", name);
|
||||
vpi_control(vpiFinish, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* $dumpon does not take an argument. */
|
||||
PLI_INT32 sys_dumpon_compiletf(PLI_BYTE8 *name)
|
||||
{
|
||||
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
||||
|
||||
if (argv != 0) {
|
||||
vpi_mcd_printf(1, "ERROR: %s does not take an argument.\n", name);
|
||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("%s takes a single argument.\n", name);
|
||||
vpi_control(vpiFinish, 1);
|
||||
}
|
||||
|
||||
|
|
@ -374,16 +280,27 @@ PLI_INT32 sys_dumpvars_compiletf(PLI_BYTE8 *name)
|
|||
vpiHandle arg;
|
||||
|
||||
/* No arguments is OK, dump everything. */
|
||||
if (argv == 0)
|
||||
return 0;
|
||||
if (argv == 0) return 0;
|
||||
|
||||
/* The first argument is the numeric level. */
|
||||
check_numeric_arg(vpi_scan(argv), "ERROR: %s's first argument must be"
|
||||
" numeric.\n", name);
|
||||
if (! is_numeric_obj(vpi_scan(argv))) {
|
||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("%s's argument must be numeric.\n", name);
|
||||
vpi_control(vpiFinish, 1);
|
||||
}
|
||||
|
||||
/* The rest of the arguments are either a module or a variable. */
|
||||
while ((arg=vpi_scan(argv)) != NULL) {
|
||||
switch(vpi_get(vpiType, arg)) {
|
||||
case vpiMemoryWord:
|
||||
if (vpi_get(vpiConstantSelect, arg) == 0) {
|
||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("%s cannot dump a non-constant select %s.\n", name,
|
||||
vpi_get_str(vpiType, arg));
|
||||
vpi_control(vpiFinish, 1);
|
||||
}
|
||||
/* The module types. */
|
||||
case vpiModule:
|
||||
case vpiTask:
|
||||
|
|
@ -393,18 +310,18 @@ PLI_INT32 sys_dumpvars_compiletf(PLI_BYTE8 *name)
|
|||
/* The variable types. */
|
||||
case vpiNet:
|
||||
case vpiReg:
|
||||
case vpiMemoryWord:
|
||||
case vpiIntegerVar:
|
||||
case vpiTimeVar:
|
||||
case vpiRealVar:
|
||||
break;
|
||||
default:
|
||||
vpi_mcd_printf(1, "ERROR: %s cannot dump a %s.\n",
|
||||
name, vpi_get_str(vpiType, arg));
|
||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("%s cannot dump a %s.\n", name,
|
||||
vpi_get_str(vpiType, arg));
|
||||
vpi_control(vpiFinish, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __vcd_priv_H
|
||||
#define __vcd_priv_H
|
||||
/*
|
||||
* Copyright (c) 2003 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2003-2008 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: vcd_priv.h,v 1.2 2003/02/13 18:13:28 steve Exp $"
|
||||
#endif
|
||||
|
||||
#include "vpi_user.h"
|
||||
|
||||
|
|
@ -47,12 +44,9 @@ extern const char*find_nexus_ident(int nex);
|
|||
extern void set_nexus_ident(int nex, const char *id);
|
||||
|
||||
/* The compiletf routines are common for the VCD, LXT and LXT2 dumpers. */
|
||||
extern PLI_INT32 sys_dumpall_compiletf(PLI_BYTE8 *name);
|
||||
extern PLI_INT32 sys_no_arg_compiletf(PLI_BYTE8 *name);
|
||||
extern PLI_INT32 sys_dumpfile_compiletf(PLI_BYTE8 *name);
|
||||
extern PLI_INT32 sys_dumpflush_compiletf(PLI_BYTE8 *name);
|
||||
extern PLI_INT32 sys_dumplimit_compiletf(PLI_BYTE8 *name);
|
||||
extern PLI_INT32 sys_dumpoff_compiletf(PLI_BYTE8 *name);
|
||||
extern PLI_INT32 sys_dumpon_compiletf(PLI_BYTE8 *name);
|
||||
extern PLI_INT32 sys_dumpvars_compiletf(PLI_BYTE8 *name);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
42
vvp/array.cc
42
vvp/array.cc
|
|
@ -125,8 +125,10 @@ static void vpi_array_var_word_get_value(vpiHandle, p_vpi_value);
|
|||
static vpiHandle vpi_array_var_word_put_value(vpiHandle, p_vpi_value, int);
|
||||
|
||||
static int vpi_array_vthr_A_get(int code, vpiHandle);
|
||||
static char*vpi_array_vthr_A_get_str(int code, vpiHandle);
|
||||
static void vpi_array_vthr_A_get_value(vpiHandle, p_vpi_value);
|
||||
static vpiHandle vpi_array_vthr_A_put_value(vpiHandle, p_vpi_value, int);
|
||||
static vpiHandle vpi_array_vthr_A_get_handle(int code, vpiHandle ref);
|
||||
|
||||
static const struct __vpirt vpip_arraymem_rt = {
|
||||
vpiMemory,
|
||||
|
|
@ -181,10 +183,10 @@ static const struct __vpirt vpip_array_var_word_rt = {
|
|||
static const struct __vpirt vpip_array_vthr_A_rt = {
|
||||
vpiMemoryWord,
|
||||
&vpi_array_vthr_A_get,
|
||||
0,
|
||||
&vpi_array_vthr_A_get_str,
|
||||
&vpi_array_vthr_A_get_value,
|
||||
&vpi_array_vthr_A_put_value,
|
||||
0,
|
||||
&vpi_array_vthr_A_get_handle,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
|
|
@ -456,10 +458,31 @@ static int vpi_array_vthr_A_get(int code, vpiHandle ref)
|
|||
assert(parent->vals);
|
||||
return parent->vals_width;
|
||||
|
||||
// For now &A<> is only a constant select. This will need
|
||||
// to be changed when it supports variable selection.
|
||||
case vpiConstantSelect:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static char*vpi_array_vthr_A_get_str(int code, vpiHandle ref)
|
||||
{
|
||||
struct __vpiArrayVthrA*obj = array_vthr_a_from_handle(ref);
|
||||
assert(obj);
|
||||
struct __vpiArray*parent = obj->array;
|
||||
|
||||
if (code == vpiFile) { // Not implemented for now!
|
||||
return simple_set_rbuf_str(file_names[0]);
|
||||
}
|
||||
|
||||
char index [64];
|
||||
snprintf(index, 63, "%d", (int)obj->address + parent->first_addr.value);
|
||||
return generic_get_str(code, &parent->scope->base, parent->name, index);
|
||||
}
|
||||
|
||||
static void vpi_array_vthr_A_get_value(vpiHandle ref, p_vpi_value value)
|
||||
{
|
||||
struct __vpiArrayVthrA*obj = array_vthr_a_from_handle(ref);
|
||||
|
|
@ -491,6 +514,21 @@ static vpiHandle vpi_array_vthr_A_put_value(vpiHandle ref, p_vpi_value vp, int)
|
|||
return ref;
|
||||
}
|
||||
|
||||
static vpiHandle vpi_array_vthr_A_get_handle(int code, vpiHandle ref)
|
||||
{
|
||||
struct __vpiArrayVthrA*obj = array_vthr_a_from_handle(ref);
|
||||
assert(obj);
|
||||
struct __vpiArray*parent = obj->array;
|
||||
|
||||
switch (code) {
|
||||
|
||||
case vpiScope:
|
||||
return &parent->scope->base;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void array_set_word(vvp_array_t arr,
|
||||
unsigned address,
|
||||
|
|
|
|||
|
|
@ -190,26 +190,32 @@ static const char* vpi_type_values(PLI_INT32 code)
|
|||
switch (code) {
|
||||
case vpiConstant:
|
||||
return "vpiConstant";
|
||||
case vpiFunction:
|
||||
return "vpiFunction";
|
||||
case vpiIntegerVar:
|
||||
return "vpiIntegerVar";
|
||||
case vpiIterator:
|
||||
return "vpiIterator";
|
||||
case vpiFunction:
|
||||
return "vpiFunction";
|
||||
case vpiMemory:
|
||||
return "vpiMemory";
|
||||
case vpiMemoryWord:
|
||||
return "vpiMemoryWord";
|
||||
case vpiModule:
|
||||
return "vpiModule";
|
||||
case vpiNet:
|
||||
return "vpiNet";
|
||||
case vpiParameter:
|
||||
return "vpiParameter";
|
||||
case vpiPartSelect:
|
||||
return "vpiPartSelect";
|
||||
case vpiRealVar:
|
||||
return "vpiRealVar";
|
||||
case vpiReg:
|
||||
return "vpiReg";
|
||||
case vpiTask:
|
||||
return "vpiTask";
|
||||
case vpiTimeVar:
|
||||
return "vpiTimeVar";
|
||||
default:
|
||||
sprintf(buf, "%d", code);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -198,7 +198,6 @@ static vpiHandle sysfunc_put_value(vpiHandle ref, p_vpi_value vp, int)
|
|||
}
|
||||
break;
|
||||
|
||||
|
||||
case vpiScalarVal:
|
||||
switch (vp->value.scalar) {
|
||||
case vpi0:
|
||||
|
|
@ -219,6 +218,29 @@ static vpiHandle sysfunc_put_value(vpiHandle ref, p_vpi_value vp, int)
|
|||
}
|
||||
break;
|
||||
|
||||
case vpiStringVal: {
|
||||
unsigned len = strlen(vp->value.str) - 1;
|
||||
assert(len*8 <= (unsigned)rfp->vwid);
|
||||
for (unsigned wdx = 0 ; wdx < (unsigned)rfp->vwid ; wdx += 8) {
|
||||
unsigned word = wdx / 8;
|
||||
char bits;
|
||||
if (word <= len) {
|
||||
bits = vp->value.str[len-word];
|
||||
} else {
|
||||
bits = 0;
|
||||
}
|
||||
for (unsigned idx = 0 ; (wdx+idx) < (unsigned)rfp->vwid &&
|
||||
idx < 8; idx += 1) {
|
||||
vvp_bit4_t bit4 = BIT4_0;
|
||||
if (bits & 1) bit4 = BIT4_1;
|
||||
vthread_put_bit(vpip_current_vthread,
|
||||
rfp->vbit+wdx+idx, bit4);
|
||||
bits >>= 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case vpiVectorVal:
|
||||
|
||||
for (unsigned wdx = 0 ; wdx < (unsigned)rfp->vwid ; wdx += 32) {
|
||||
|
|
|
|||
|
|
@ -1648,7 +1648,7 @@ static unsigned long* divide_bits(unsigned long*ap, unsigned long*bp, unsigned w
|
|||
// carry&1. If it is 0, then it is *negative*.) In that
|
||||
// case, we know that cur_res was too large by 1. Correct by
|
||||
// adding 1b back in and reducing cur_res.
|
||||
if (carry&1 == 0) {
|
||||
if ((carry&1) == 0) {
|
||||
cur_res -= 1;
|
||||
carry = 0;
|
||||
for (unsigned idx = cur_ptr ; idx < words ; idx += 1)
|
||||
|
|
|
|||
Loading…
Reference in New Issue