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:
Stephen Williams 2008-06-03 21:17:57 -07:00
commit 95850ac112
22 changed files with 708 additions and 585 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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.
*
*/

View File

@ -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);

View File

@ -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);
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
}

131
vpi/sys_priv.c Normal file
View File

@ -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;
}

View File

@ -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

View File

@ -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
};

View File

@ -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.
*
*/

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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

268
vpi/vams_simparam.c Normal file
View File

@ -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);
}

View File

@ -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;
}

View File

@ -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

View File

@ -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,

View File

@ -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);
}

View File

@ -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) {

View File

@ -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)