Merge branch 'sft-rework'
This commit is contained in:
commit
a621fa48a6
|
|
@ -117,7 +117,7 @@ O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \
|
|||
net_udp.o pad_to_width.o parse.o parse_misc.o pform.o pform_analog.o \
|
||||
pform_disciplines.o pform_dump.o pform_package.o pform_pclass.o \
|
||||
pform_class_type.o pform_string_type.o pform_struct_type.o pform_types.o \
|
||||
symbol_search.o sync.o sys_funcs.o verinum.o verireal.o target.o \
|
||||
symbol_search.o sync.o sys_funcs.o verinum.o verireal.o vpi_modules.o target.o \
|
||||
Attrib.o HName.o Module.o PClass.o PDelays.o PEvent.o PExpr.o PFunction.o \
|
||||
PGate.o PGenerate.o PModport.o PNamedItem.o PPackage.o PScope.o PSpec.o \
|
||||
PTask.o PUdp.o PWire.o Statement.o AStatement.o $M $(FF) $(TT)
|
||||
|
|
@ -138,7 +138,7 @@ endif
|
|||
check: all
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
test -r check.conf || cp $(srcdir)/check.conf .
|
||||
driver/iverilog -B. -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl
|
||||
driver/iverilog -B. -BMvpi -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl
|
||||
ifeq (@WIN32@,yes)
|
||||
ifeq (@install_suffix@,)
|
||||
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
|
||||
|
|
|
|||
|
|
@ -71,12 +71,12 @@ dep:
|
|||
$(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $<
|
||||
mv $*.d dep
|
||||
|
||||
SYSTEM_VPI_LDFLAGS = -L../vvp -lvpi
|
||||
SYSTEM_VPI_LDFLAGS = -L../vpi -lvpi
|
||||
ifeq (@MINGW32@,yes)
|
||||
SYSTEM_VPI_LDFLAGS += @EXTRALIBS@
|
||||
endif
|
||||
|
||||
cadpli.vpl: $O ../vvp/libvpi.a ../libveriuser/libveriuser.o
|
||||
cadpli.vpl: $O ../vpi/libvpi.a ../libveriuser/libveriuser.o
|
||||
$(CC) @shared@ $(LDFLAGS) -o $@ $O ../libveriuser/libveriuser.o $(SYSTEM_VPI_LDFLAGS)
|
||||
|
||||
install: all installdirs $(vpidir)/cadpli.vpl
|
||||
|
|
|
|||
|
|
@ -290,9 +290,16 @@ struct sfunc_return_type {
|
|||
bool override_flag;
|
||||
};
|
||||
|
||||
extern void add_sys_func(const struct sfunc_return_type&ret_type);
|
||||
extern const struct sfunc_return_type* lookup_sys_func(const char*name);
|
||||
extern int load_sys_func_table(const char*path);
|
||||
extern void cleanup_sys_func_table();
|
||||
/*
|
||||
* This temporarily loads a VPI module, to determine the return values
|
||||
* of system functions provided by that module, and adds the return values
|
||||
* to the system function table.
|
||||
*/
|
||||
extern bool load_vpi_module(const char*path);
|
||||
|
||||
/*
|
||||
* In system Verilog it is allowed with a warning to call a function
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
.TH iverilog 1 "Oct 5th, 2019" "" "Version %M.%n%E"
|
||||
.TH iverilog 1 "Oct 23rd, 2019" "" "Version %M.%n%E"
|
||||
.SH NAME
|
||||
iverilog - Icarus Verilog compiler
|
||||
|
||||
|
|
@ -7,8 +7,9 @@ iverilog - Icarus Verilog compiler
|
|||
[\-EiSuVv] [\-Bpath] [\-ccmdfile|\-fcmdfile] [\-Dmacro[=defn]]
|
||||
[\-Pparameter=value] [\-pflag=value] [\-dname]
|
||||
[\-g1995\:|\-g2001\:|\-g2005\:|\-g2005-sv\:|\-g2009\:|\-g2012\:|\-g<feature>]
|
||||
[\-Iincludedir] [\-mmodule] [\-M[mode=]file] [\-Nfile] [\-ooutputfilename]
|
||||
[\-stopmodule] [\-ttype] [\-Tmin/typ/max] [\-Wclass] [\-ypath] [\-lfile]
|
||||
[\-Iincludedir] [\-Lmoduledir] [\-mmodule] [\-M[mode=]file] [\-Nfile]
|
||||
[\-ooutputfilename] [\-stopmodule] [\-ttype] [\-Tmin/typ/max] [\-Wclass]
|
||||
[\-ypath] [\-lfile]
|
||||
sourcefile
|
||||
|
||||
.SH DESCRIPTION
|
||||
|
|
@ -164,6 +165,12 @@ over that instantiation. It will also stop the compiler returning an
|
|||
error if there are no top level modules. This allows the compiler to be
|
||||
used to check incomplete designs for errors.
|
||||
.TP 8
|
||||
.B -L\fIpath\fP
|
||||
This flag adds a directory to the path list used to locate VPI
|
||||
modules. The default path includes only the install directory for the
|
||||
system.vpi module, but this flag can add other directories. Multiple
|
||||
paths are allowed, and the paths will be searched in order.
|
||||
.TP 8
|
||||
.B -l\fIfile\fP
|
||||
Add the specified file to the list of source files to be compiled,
|
||||
but mark it as a library file. All modules contained within that
|
||||
|
|
@ -191,12 +198,12 @@ prefixed by "I " and other files are prefixed by "M ".
|
|||
Add this module to the list of VPI modules to be loaded by the
|
||||
simulation. Many modules can be specified, and all will be loaded, in
|
||||
the order specified. The system module is implicit and always included
|
||||
(and loaded last). If a System Function Table file (<module>.sft)
|
||||
exists for the module it will be loaded automatically.
|
||||
(and loaded last).
|
||||
|
||||
If the specified name includes at least one directory character, it is
|
||||
assumed to be prefixed by the path to the module, otherwise the module
|
||||
is assumed to be located in the \fIiverilog\fP base directory.
|
||||
is searched for in the paths specified by preceding \fB-L\fP options,
|
||||
and if not found there, in the \fIiverilog\fP base directory.
|
||||
.TP 8
|
||||
.B -N\fIpath\fP
|
||||
This is used for debugging the compiler proper. Dump the final netlist
|
||||
|
|
@ -406,13 +413,23 @@ sensitivity list. Although this behaviour is prescribed by the IEEE
|
|||
standard, it is not what might be expected and can have performance
|
||||
implications if the array is large.
|
||||
|
||||
.SH "SYSTEM FUNCTION TABLE FILES"
|
||||
If the source file name as a \fB.sft\fP suffix, then it is taken to be
|
||||
a system function table file. A System function table file is used to
|
||||
describe to the compiler the return types for system functions. This
|
||||
.SH "VPI MODULES"
|
||||
If the source file name has a \fB.vpi\fP or \fB.vpl\fP suffix, then it
|
||||
is taken to be a VPI module. VPI modules supplied by the user are scanned
|
||||
to determine the return types of any system functions they provide. This
|
||||
is necessary because the compiler needs this information to elaborate
|
||||
expressions that contain these system functions, but cannot run the
|
||||
sizetf functions since it has no run-time.
|
||||
expressions that contain these system functions. The module path/name is
|
||||
passed on to the target to allow the VPI module to be automatically loaded
|
||||
at the start of simulation.
|
||||
|
||||
VPI modules may also be supplied using the \fB-L\fP and \fB-m\fP options.
|
||||
|
||||
.SH "SYSTEM FUNCTION TABLE FILES [deprecated]"
|
||||
If the source file name has a \fB.sft\fP suffix, then it is taken to be a
|
||||
system function table file. A system function table file is the old method
|
||||
used to describe to the compiler the return types for system functions.
|
||||
Users are encouraged to switch to the new method of simply supplying the
|
||||
VPI module.
|
||||
|
||||
The format of the table is ASCII, one function per line. Empty lines
|
||||
are ignored, and lines that start with the '\fI#\fP' character are
|
||||
|
|
@ -566,6 +583,24 @@ This is always defined when compiling with Icarus Verilog.
|
|||
.B __VAMS_ENABLE__ = 1
|
||||
This is defined if Verilog\-AMS is enabled.
|
||||
|
||||
.SH ENVIRONMENT
|
||||
.PP
|
||||
\fIiverilog\fP also accepts some environment variables that control
|
||||
its behavior. These can be used to make semi-permanent changes.
|
||||
|
||||
.TP 8
|
||||
.B IVERILOG_ICONFIG=\fIfile-name\fP
|
||||
This sets the name used for the temporary file that passes parameters
|
||||
to the compiler proper, and prevents that file being deleted after the
|
||||
compiler has exited.
|
||||
|
||||
.TP 8
|
||||
.B IVERILOG_VPI_MODULE_PATH=\fI/some/path:/some/other/path\fP
|
||||
This adds additional components to the VPI module search path. Paths
|
||||
specified in this way are searched after paths specified with \fB-L\fP,
|
||||
but before the default search path. Multiple paths can be separated with
|
||||
colons (semicolons if using Windows).
|
||||
|
||||
.SH EXAMPLES
|
||||
These examples assume that you have a Verilog source file called hello.v in
|
||||
the current directory
|
||||
|
|
|
|||
186
driver/main.c
186
driver/main.c
|
|
@ -40,7 +40,7 @@ const char NOTICE[] =
|
|||
const char HELP[] =
|
||||
"Usage: iverilog [-EiSuvV] [-B base] [-c cmdfile|-f cmdfile]\n"
|
||||
" [-g1995|-g2001|-g2005|-g2005-sv|-g2009|-g2012] [-g<feature>]\n"
|
||||
" [-D macro[=defn]] [-I includedir]\n"
|
||||
" [-D macro[=defn]] [-I includedir] [-L moduledir]\n"
|
||||
" [-M [mode=]depfile] [-m module]\n"
|
||||
" [-N file] [-o filename] [-p flag=value]\n"
|
||||
" [-s topmodule] [-t target] [-T min|typ|max]\n"
|
||||
|
|
@ -99,13 +99,16 @@ extern const char*optarg;
|
|||
|
||||
#ifdef __MINGW32__
|
||||
const char sep = '\\';
|
||||
const char path_sep = ';';
|
||||
#else
|
||||
const char sep = '/';
|
||||
const char path_sep = ':';
|
||||
#endif
|
||||
|
||||
extern void cfreset(FILE*fd, const char*path);
|
||||
|
||||
const char*base = 0;
|
||||
const char*vpi_dir = 0;
|
||||
const char*ivlpp_dir = 0;
|
||||
const char*vhdlpp_dir= 0;
|
||||
const char*vhdlpp_work = 0;
|
||||
|
|
@ -169,6 +172,12 @@ char*compiled_defines_path = 0;
|
|||
|
||||
static char iconfig_common_path[4096] = "";
|
||||
|
||||
static const char**vpi_path_list = 0;
|
||||
static unsigned vpi_path_list_size = 0;
|
||||
|
||||
static const char**env_vpi_path_list = 0;
|
||||
static unsigned env_vpi_path_list_size = 0;
|
||||
|
||||
int synth_flag = 0;
|
||||
int verbose_flag = 0;
|
||||
|
||||
|
|
@ -673,14 +682,19 @@ void process_timescale(const char*ts_string)
|
|||
/*
|
||||
* This function is called while processing a file name in a command
|
||||
* file, or a file name on the command line. Look to see if there is a
|
||||
* .sft suffix, and if so pass that as a sys_func file. Otherwise, it
|
||||
* is a Verilog source file to be written into the file list.
|
||||
* .sft or .vpi suffix, and if so pass that as a sys_func or module
|
||||
* file. Otherwise, it is a Verilog source file to be written into the
|
||||
* file list.
|
||||
*/
|
||||
void process_file_name(const char*name, int lib_flag)
|
||||
{
|
||||
if (strlen(name) > 4 && strcasecmp(".sft", name+strlen(name)-4) == 0) {
|
||||
fprintf(stderr, "SFT files are deprecated. Please pass the VPI module instead.\n");
|
||||
fprintf(iconfig_file,"sys_func:%s\n", name);
|
||||
|
||||
} else if (strlen(name) > 4 && strcasecmp(".vpi", name+strlen(name)-4) == 0) {
|
||||
fprintf(iconfig_file,"module:%s\n", name);
|
||||
|
||||
} else {
|
||||
fprintf(source_file, "%s\n", name);
|
||||
source_count += 1;
|
||||
|
|
@ -856,25 +870,124 @@ static int process_depfile(const char*name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If it exists add the SFT file for the given module.
|
||||
*/
|
||||
static void add_sft_file(const char *module)
|
||||
static void add_env_vpi_module_path(const char*path)
|
||||
{
|
||||
char *file;
|
||||
env_vpi_path_list_size += 1;
|
||||
env_vpi_path_list = (const char**)realloc(env_vpi_path_list,
|
||||
env_vpi_path_list_size*sizeof(char*));
|
||||
env_vpi_path_list[env_vpi_path_list_size-1] = path;
|
||||
}
|
||||
|
||||
file = (char *) malloc(strlen(base)+1+strlen(module)+4+1);
|
||||
// If the module name has at least one directory character
|
||||
// in it, assume it includes the path, otherwise look in
|
||||
// the base directory.
|
||||
if (strchr(module, sep))
|
||||
sprintf(file, "%s.sft", module);
|
||||
else
|
||||
sprintf(file, "%s%c%s.sft", base, sep, module);
|
||||
static void get_env_vpi_module_paths(void)
|
||||
{
|
||||
char *var = getenv("IVERILOG_VPI_MODULE_PATH");
|
||||
char *ptr, *end;
|
||||
|
||||
if (access(file, R_OK) == 0)
|
||||
fprintf(iconfig_file, "sys_func:%s\n", file);
|
||||
free(file);
|
||||
if (!var)
|
||||
return;
|
||||
|
||||
var = strdup(var);
|
||||
#ifdef __MINGW32__
|
||||
convert_to_MS_path(var);
|
||||
#endif
|
||||
ptr = var;
|
||||
end = var+strlen(var);
|
||||
int len = 0;
|
||||
while (ptr <= end) {
|
||||
if (*ptr == 0 || *ptr == path_sep) {
|
||||
*ptr = 0;
|
||||
if (len > 0) {
|
||||
add_env_vpi_module_path(var);
|
||||
}
|
||||
len = 0;
|
||||
var = ptr+1;
|
||||
} else {
|
||||
len++;
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
static void add_vpi_module_path(const char*path)
|
||||
{
|
||||
#ifdef __MINGW32__
|
||||
char*tmp_path = strdup(path);
|
||||
convert_to_MS_path(tmp_path);
|
||||
path = tmp_path;
|
||||
#endif
|
||||
vpi_path_list_size += 1;
|
||||
vpi_path_list = (const char**)realloc(vpi_path_list,
|
||||
vpi_path_list_size*sizeof(char*));
|
||||
vpi_path_list[vpi_path_list_size-1] = path;
|
||||
}
|
||||
|
||||
static int probe_for_vpi_module(const char*base_path, const char*name,
|
||||
char*path, unsigned path_size)
|
||||
{
|
||||
snprintf(path, path_size, "%s%c%s.vpi", base_path, sep, name);
|
||||
if (access(path, R_OK) == 0)
|
||||
return 1;
|
||||
|
||||
snprintf(path, path_size, "%s%c%s.vpl", base_path, sep, name);
|
||||
if (access(path, R_OK) == 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If it exists add the VPI file for the given module.
|
||||
*/
|
||||
static void add_vpi_file(const char *name)
|
||||
{
|
||||
const char*base_dir = vpi_dir ? vpi_dir : base;
|
||||
|
||||
char path[4096];
|
||||
|
||||
#ifdef __MINGW32__
|
||||
char*tmp_name = strdup(name);
|
||||
convert_to_MS_path(tmp_name);
|
||||
name = tmp_name;
|
||||
#endif
|
||||
|
||||
int found = 0;
|
||||
if (strchr(name, sep)) {
|
||||
/* If the name has at least one directory character in it
|
||||
then assume it is a complete name, maybe including any
|
||||
possible .vpi or .vpl suffix. */
|
||||
found = access(name, R_OK) == 0;
|
||||
if (!found) {
|
||||
snprintf(path, sizeof(path), "%s.vpi", name);
|
||||
found = access(path, R_OK) == 0;
|
||||
if (!found) {
|
||||
snprintf(path, sizeof(path), "%s.vpl", name);
|
||||
found = access(path, R_OK) == 0;
|
||||
}
|
||||
} else {
|
||||
strncpy(path, name, sizeof(path) - 1);
|
||||
}
|
||||
} else {
|
||||
for (unsigned idx = 0; !found && (idx < vpi_path_list_size); idx += 1) {
|
||||
found = probe_for_vpi_module(vpi_path_list[idx], name,
|
||||
path, sizeof(path));
|
||||
}
|
||||
for (unsigned idx = 0; !found && (idx < env_vpi_path_list_size); idx += 1) {
|
||||
found = probe_for_vpi_module(env_vpi_path_list[idx], name,
|
||||
path, sizeof(path));
|
||||
}
|
||||
if (!found) {
|
||||
found = probe_for_vpi_module(base_dir, name,
|
||||
path, sizeof(path));
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
fprintf(iconfig_file, "module:%s\n", path);
|
||||
} else {
|
||||
fprintf(stderr, "Unable to find VPI module '%s'\n", name);
|
||||
}
|
||||
#ifdef __MINGW32__
|
||||
free(tmp_name);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void find_ivl_root_failed(const char *reason)
|
||||
|
|
@ -979,6 +1092,8 @@ int main(int argc, char **argv)
|
|||
find_ivl_root();
|
||||
base = ivl_root;
|
||||
|
||||
get_env_vpi_module_paths();
|
||||
|
||||
/* Create a temporary file for communicating input parameters
|
||||
to the preprocessor. */
|
||||
source_path = strdup(my_tempfile("ivrlg", &source_file));
|
||||
|
|
@ -1039,7 +1154,7 @@ int main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
while ((opt = getopt(argc, argv, "B:c:D:d:Ef:g:hl:I:iM:m:N:o:P:p:Ss:T:t:uvVW:y:Y:")) != EOF) {
|
||||
while ((opt = getopt(argc, argv, "B:c:D:d:Ef:g:hl:I:iL:M:m:N:o:P:p:Ss:T:t:uvVW:y:Y:")) != EOF) {
|
||||
|
||||
switch (opt) {
|
||||
case 'B':
|
||||
|
|
@ -1048,6 +1163,9 @@ int main(int argc, char **argv)
|
|||
character of the path indicates which path the
|
||||
user is specifying. */
|
||||
switch (optarg[0]) {
|
||||
case 'M': /* Path for the VPI modules */
|
||||
vpi_dir = optarg+1;
|
||||
break;
|
||||
case 'P': /* Path for the ivlpp preprocessor */
|
||||
ivlpp_dir = optarg+1;
|
||||
break;
|
||||
|
|
@ -1098,6 +1216,10 @@ int main(int argc, char **argv)
|
|||
ignore_missing_modules = 1;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
add_vpi_module_path(optarg);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
process_file_name(optarg, 1);
|
||||
break;
|
||||
|
|
@ -1108,8 +1230,7 @@ int main(int argc, char **argv)
|
|||
break;
|
||||
|
||||
case 'm':
|
||||
fprintf(iconfig_file, "module:%s\n", optarg);
|
||||
add_sft_file(optarg);
|
||||
add_vpi_file(optarg);
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
|
|
@ -1180,6 +1301,8 @@ int main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
if (vpi_dir == 0)
|
||||
vpi_dir = base;
|
||||
if (ivlpp_dir == 0)
|
||||
ivlpp_dir = base;
|
||||
if (vhdlpp_dir == 0)
|
||||
|
|
@ -1198,12 +1321,10 @@ int main(int argc, char **argv)
|
|||
/* Write values to the iconfig file. */
|
||||
fprintf(iconfig_file, "basedir:%s\n", base);
|
||||
|
||||
/* Tell the core where to find the system.sft. This file
|
||||
describes the system functions so that elaboration knows
|
||||
how to handle them. */
|
||||
fprintf(iconfig_file, "sys_func:%s%csystem.sft\n", base, sep);
|
||||
fprintf(iconfig_file, "sys_func:%s%cvhdl_sys.sft\n", base, sep);
|
||||
fprintf(iconfig_file, "sys_func:%s%cvhdl_textio.sft\n", base, sep);
|
||||
/* Tell the core where to find the system VPI modules. */
|
||||
fprintf(iconfig_file, "module:%s%csystem.vpi\n", vpi_dir, sep);
|
||||
fprintf(iconfig_file, "module:%s%cvhdl_sys.vpi\n", vpi_dir, sep);
|
||||
fprintf(iconfig_file, "module:%s%cvhdl_textio.vpi\n", vpi_dir, sep);
|
||||
|
||||
/* If verilog-2005/09/12 is enabled or icarus-misc or verilog-ams,
|
||||
* then include the v2005_math library. */
|
||||
|
|
@ -1212,23 +1333,20 @@ int main(int argc, char **argv)
|
|||
strcmp(generation, "2012") == 0 ||
|
||||
strcmp(gen_icarus, "icarus-misc") == 0 ||
|
||||
strcmp(gen_verilog_ams, "verilog-ams") == 0) {
|
||||
fprintf(iconfig_file, "sys_func:%s%cv2005_math.sft\n", base, sep);
|
||||
fprintf(iconfig_file, "module:v2005_math\n");
|
||||
fprintf(iconfig_file, "module:%s%cv2005_math.vpi\n", vpi_dir, sep);
|
||||
}
|
||||
/* If verilog-ams or icarus_misc is enabled, then include the
|
||||
* va_math module as well. */
|
||||
if (strcmp(gen_verilog_ams,"verilog-ams") == 0 ||
|
||||
strcmp(gen_icarus, "icarus-misc") == 0) {
|
||||
fprintf(iconfig_file, "sys_func:%s%cva_math.sft\n", base, sep);
|
||||
fprintf(iconfig_file, "module:va_math\n");
|
||||
fprintf(iconfig_file, "module:%s%cva_math.vpi\n", vpi_dir, sep);
|
||||
}
|
||||
/* If verilog-2009 (SystemVerilog) is enabled, then include the
|
||||
v2009 module. */
|
||||
if (strcmp(generation, "2005-sv") == 0 ||
|
||||
strcmp(generation, "2009") == 0 ||
|
||||
strcmp(generation, "2012") == 0) {
|
||||
fprintf(iconfig_file, "sys_func:%s%cv2009.sft\n", base, sep);
|
||||
fprintf(iconfig_file, "module:v2009\n");
|
||||
fprintf(iconfig_file, "module:%s%cv2009.vpi\n", vpi_dir, sep);
|
||||
}
|
||||
|
||||
if (mtm != 0) fprintf(iconfig_file, "-T:%s\n", mtm);
|
||||
|
|
|
|||
6
main.cc
6
main.cc
|
|
@ -136,6 +136,7 @@ void add_vpi_module(const char*name)
|
|||
vpi_module_list = tmp;
|
||||
}
|
||||
flags["VPI_MODULE_LIST"] = vpi_module_list;
|
||||
load_vpi_module(name);
|
||||
}
|
||||
|
||||
map<perm_string,unsigned> missing_modules;
|
||||
|
|
@ -900,11 +901,6 @@ int main(int argc, char*argv[])
|
|||
}
|
||||
library_suff.push_back(strdup(".v"));
|
||||
|
||||
// Start the module list with the base system module.
|
||||
add_vpi_module("system");
|
||||
add_vpi_module("vhdl_sys");
|
||||
add_vpi_module("vhdl_textio");
|
||||
|
||||
flags["-o"] = strdup("a.out");
|
||||
min_typ_max_flag = TYP;
|
||||
min_typ_max_warn = 10;
|
||||
|
|
|
|||
41
sys_funcs.cc
41
sys_funcs.cc
|
|
@ -29,16 +29,8 @@
|
|||
* via the lookup_sys_func function.
|
||||
*/
|
||||
|
||||
static const struct sfunc_return_type sfunc_table[] = {
|
||||
{ "$realtime", IVL_VT_REAL, 1, false, false },
|
||||
{ "$bitstoreal", IVL_VT_REAL, 1, false, false },
|
||||
{ "$itor", IVL_VT_REAL, 1, false, false },
|
||||
{ "$realtobits", IVL_VT_LOGIC, 64, false, false },
|
||||
{ "$time", IVL_VT_LOGIC, 64, false, false },
|
||||
{ "$stime", IVL_VT_LOGIC, 32, false, false },
|
||||
{ "$simtime", IVL_VT_LOGIC, 64, false, false },
|
||||
{ 0, IVL_VT_LOGIC, 32, false, false }
|
||||
};
|
||||
static const struct sfunc_return_type default_return_type =
|
||||
{ 0, IVL_VT_LOGIC, 32, false, false };
|
||||
|
||||
struct sfunc_return_type_cell : sfunc_return_type {
|
||||
struct sfunc_return_type_cell*next;
|
||||
|
|
@ -89,19 +81,26 @@ const struct sfunc_return_type* lookup_sys_func(const char*name)
|
|||
if (def)
|
||||
return def;
|
||||
|
||||
/* Next, look in the core table. */
|
||||
unsigned idx = 0;
|
||||
while (sfunc_table[idx].name) {
|
||||
/* No luck finding, so return the default description. */
|
||||
return &default_return_type;
|
||||
}
|
||||
|
||||
if (strcmp(sfunc_table[idx].name, name) == 0)
|
||||
return sfunc_table + idx;
|
||||
|
||||
idx += 1;
|
||||
void add_sys_func(const struct sfunc_return_type&ret_type)
|
||||
{
|
||||
struct sfunc_return_type*def = find_in_sys_func_list(ret_type.name);
|
||||
if (def) {
|
||||
/* Keep the original definition, but flag that it
|
||||
overrides a later definition. */
|
||||
def->override_flag = true;
|
||||
return;
|
||||
}
|
||||
|
||||
/* No luck finding, so return the trailer, which gives a
|
||||
default description. */
|
||||
return sfunc_table + idx;
|
||||
struct sfunc_return_type_cell*cell = new struct sfunc_return_type_cell;
|
||||
cell->name = lex_strings.add(ret_type.name);
|
||||
cell->type = ret_type.type;
|
||||
cell->wid = ret_type.wid;
|
||||
cell->signed_flag = ret_type.signed_flag;
|
||||
cell->override_flag = ret_type.override_flag;
|
||||
append_to_list(cell);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef VERIUSER_H
|
||||
#define VERIUSER_H
|
||||
/*
|
||||
* Copyright (c) 2002-2018 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2002-2019 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
|
||||
|
|
@ -152,6 +152,9 @@ typedef struct t_tfcell
|
|||
*/
|
||||
extern s_tfcell veriusertfs[];
|
||||
extern void veriusertfs_register_table(p_tfcell vtable);
|
||||
#if defined(__MINGW32__) || defined (__CYGWIN32__)
|
||||
extern __declspec(dllexport) void (*vlog_startup_routines[])(void);
|
||||
#endif
|
||||
|
||||
#define usertask 1
|
||||
#define userfunction 2
|
||||
|
|
|
|||
24
vpi.txt
24
vpi.txt
|
|
@ -4,13 +4,16 @@ HOW IT WORKS
|
|||
The VPI interface for Icarus Verilog works by creating from a
|
||||
collection of PLI applications a single vpi module. The vpi module
|
||||
includes compiled code for the applications linked together (with any
|
||||
other libraries that the applications need) into a module with a
|
||||
single exported symbol, the vlog_startup_routines array.
|
||||
other libraries that the applications need) into a module with two
|
||||
exported symbols, the vpip_set_callback function and the
|
||||
vlog_startup_routines array.
|
||||
|
||||
The product that wishes to invoke the module (normally at run time)
|
||||
loads the module, locates the vlog_startup_routines table, and calls
|
||||
all the startup routines contained in that table. It is possible for a
|
||||
product to link with many modules. In that case, all the modules are
|
||||
The product that wishes to invoke the module (normally at run time) loads
|
||||
the module, locates and calls the vpip_set_callback function to pass the
|
||||
the module a jump table that allows the module to access the VPI routines
|
||||
implemented by the product, then locates the vlog_startup_routines table
|
||||
and calls all the startup routines contained in that table. It is possible
|
||||
for a product to link with many modules. In that case, all the modules are
|
||||
linked in and startup routines are called in order.
|
||||
|
||||
The product that uses vpi modules uses the environment variable
|
||||
|
|
@ -19,9 +22,11 @@ module search path. When a module is specified by name (using whatever
|
|||
means the product supports) the module search path is scanned until
|
||||
the module is located.
|
||||
|
||||
The special module name "system.vpi" is part of the core Icarus
|
||||
Verilog distribution and includes implementations of the standard
|
||||
system tasks/functions.
|
||||
The special module names "system.vpi", "v2005_math.vpi", "v2009.vpi",
|
||||
and "va_math.vpi" are part of the core Icarus Verilog distribution and
|
||||
include implementations of the standard system tasks/functions. The
|
||||
additional special module names "vhdl_sys.vpi" and "vhdl_textio.vpi"
|
||||
include implementations of private functions used to support VHDL.
|
||||
|
||||
COMPILING A VPI MODULE
|
||||
|
||||
|
|
@ -40,4 +45,3 @@ This tracing is pretty verbose, so you don't want to run like this
|
|||
normally. Also, the format of the tracing messages will change
|
||||
according to my needs (and whim) so don't expect to be able to parse
|
||||
it in software.
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ vpidir = $(libdir)/ivl$(suffix)
|
|||
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
AR = @AR@
|
||||
RANLIB = @RANLIB@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
|
@ -69,10 +71,10 @@ O += sys_fst.o fstapi.o fastlz.o lz4.o
|
|||
endif
|
||||
|
||||
# Object files for v2005_math.vpi
|
||||
M = sys_clog2.o v2005_math.o
|
||||
V2005 = sys_clog2.o v2005_math.o
|
||||
|
||||
# Object files for va_math.vpi
|
||||
V = va_math.o
|
||||
VA_MATH = va_math.o
|
||||
|
||||
V2009 = v2009_table.o v2009_array.o v2009_bitvec.o v2009_enum.o v2009_string.o \
|
||||
sys_priv.o
|
||||
|
|
@ -83,12 +85,12 @@ VHDL_TEXTIO = vhdl_textio.o sys_priv.o
|
|||
|
||||
VPI_DEBUG = vpi_debug.o
|
||||
|
||||
all: dep system.vpi va_math.vpi v2005_math.vpi v2009.vpi vhdl_sys.vpi vhdl_textio.vpi vpi_debug.vpi $(ALL32)
|
||||
all: dep libvpi.a system.vpi va_math.vpi v2005_math.vpi v2009.vpi vhdl_sys.vpi vhdl_textio.vpi vpi_debug.vpi $(ALL32)
|
||||
|
||||
check: all
|
||||
|
||||
clean:
|
||||
rm -rf *.o sys_readmem_lex.c dep system.vpi
|
||||
rm -rf *.o sys_readmem_lex.c dep libvpi.a system.vpi
|
||||
rm -f sdf_lexor.c sdf_parse.c sdf_parse.output sdf_parse.h
|
||||
rm -f table_mod_parse.c table_mod_parse.h table_mod_parse.output
|
||||
rm -f table_mod_lexor.c
|
||||
|
|
@ -122,6 +124,12 @@ dep:
|
|||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
|
||||
mv $*.d dep
|
||||
|
||||
libvpi.a: libvpi.c ../vpi_user.h
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c $<
|
||||
rm -f libvpi.a
|
||||
$(AR) cqv libvpi.a libvpi.o
|
||||
$(RANLIB) libvpi.a
|
||||
|
||||
LIBS = @LIBS@
|
||||
SYSTEM_VPI_LDFLAGS = $(LIBS)
|
||||
VA_MATH_LDFLAGS =
|
||||
|
|
@ -130,8 +138,8 @@ ifeq (@MINGW32@,yes)
|
|||
VA_MATH_LDFLAGS += @EXTRALIBS@
|
||||
endif
|
||||
|
||||
system.vpi: $O $(OPP) ../vvp/libvpi.a
|
||||
$(CXX) @shared@ -o $@ $O $(OPP) -L../vvp $(LDFLAGS) -lvpi $(SYSTEM_VPI_LDFLAGS)
|
||||
system.vpi: $O $(OPP) libvpi.a
|
||||
$(CXX) @shared@ -o $@ $O $(OPP) -L. $(LDFLAGS) -lvpi $(SYSTEM_VPI_LDFLAGS)
|
||||
|
||||
sys_readmem_lex.c: $(srcdir)/sys_readmem_lex.lex
|
||||
$(LEX) -t $< > $@
|
||||
|
|
@ -156,23 +164,23 @@ table_mod_parse.c: $(srcdir)/table_mod_parse.y
|
|||
$(YACC) --verbose -t -p tblmod -d -o $@ $<
|
||||
table_mod_parse.h: table_mod_parse.c
|
||||
|
||||
v2005_math.vpi: $M ../vvp/libvpi.a
|
||||
$(CC) @shared@ -o $@ $M -L../vvp $(LDFLAGS) -lvpi $(VA_MATH_VPI_LDFLAGS)
|
||||
v2005_math.vpi: $(V2005) libvpi.a
|
||||
$(CC) @shared@ -o $@ $(V2005) -L. $(LDFLAGS) -lvpi $(VA_MATH_VPI_LDFLAGS)
|
||||
|
||||
v2009.vpi: $(V2009) ../vvp/libvpi.a
|
||||
$(CC) @shared@ -o $@ $(V2009) -L../vvp $(LDFLAGS) -lvpi $(SYSTEM_VPI_LDFLAGS)
|
||||
v2009.vpi: $(V2009) libvpi.a
|
||||
$(CC) @shared@ -o $@ $(V2009) -L. $(LDFLAGS) -lvpi $(SYSTEM_VPI_LDFLAGS)
|
||||
|
||||
va_math.vpi: $V ../vvp/libvpi.a
|
||||
$(CC) @shared@ -o $@ $V -L../vvp $(LDFLAGS) -lvpi $(VA_MATH_VPI_LDFLAGS)
|
||||
va_math.vpi: $(VA_MATH) libvpi.a
|
||||
$(CC) @shared@ -o $@ $(VA_MATH) -L. $(LDFLAGS) -lvpi $(VA_MATH_VPI_LDFLAGS)
|
||||
|
||||
vhdl_sys.vpi: $(VHDL_SYS) ../vvp/libvpi.a
|
||||
$(CC) @shared@ -o $@ $(VHDL_SYS) -L../vvp $(LDFLAGS) -lvpi $(SYSTEM_VPI_LDFLAGS)
|
||||
vhdl_sys.vpi: $(VHDL_SYS) libvpi.a
|
||||
$(CC) @shared@ -o $@ $(VHDL_SYS) -L. $(LDFLAGS) -lvpi $(SYSTEM_VPI_LDFLAGS)
|
||||
|
||||
vhdl_textio.vpi: $(VHDL_TEXTIO) ../vvp/libvpi.a
|
||||
$(CC) @shared@ -o $@ $(VHDL_TEXTIO) -L../vvp $(LDFLAGS) -lvpi $(SYSTEM_VPI_LDFLAGS)
|
||||
vhdl_textio.vpi: $(VHDL_TEXTIO) libvpi.a
|
||||
$(CC) @shared@ -o $@ $(VHDL_TEXTIO) -L. $(LDFLAGS) -lvpi $(SYSTEM_VPI_LDFLAGS)
|
||||
|
||||
vpi_debug.vpi: $(VPI_DEBUG) ../vvp/libvpi.a
|
||||
$(CC) @shared@ -o $@ $(VPI_DEBUG) -L../vvp $(LDFLAGS) -lvpi $(SYSTEM_VPI_LDFLAGS)
|
||||
vpi_debug.vpi: $(VPI_DEBUG) libvpi.a
|
||||
$(CC) @shared@ -o $@ $(VPI_DEBUG) -L. $(LDFLAGS) -lvpi $(SYSTEM_VPI_LDFLAGS)
|
||||
|
||||
stamp-vpi_config-h: $(srcdir)/vpi_config.h.in ../config.status
|
||||
@rm -f $@
|
||||
|
|
@ -180,50 +188,36 @@ stamp-vpi_config-h: $(srcdir)/vpi_config.h.in ../config.status
|
|||
vpi_config.h: stamp-vpi_config-h
|
||||
|
||||
install: all installdirs \
|
||||
$(vpidir)/system.vpi $(vpidir)/system.sft \
|
||||
$(vpidir)/va_math.vpi $(vpidir)/va_math.sft \
|
||||
$(vpidir)/v2005_math.vpi $(vpidir)/v2005_math.sft \
|
||||
$(vpidir)/v2009.vpi $(vpidir)/v2009.sft \
|
||||
$(vpidir)/vhdl_sys.vpi $(vpidir)/vhdl_sys.sft \
|
||||
$(vpidir)/vhdl_textio.vpi $(vpidir)/vhdl_textio.sft \
|
||||
$(libdir)/libvpi$(suffix).a \
|
||||
$(vpidir)/system.vpi \
|
||||
$(vpidir)/va_math.vpi \
|
||||
$(vpidir)/v2005_math.vpi \
|
||||
$(vpidir)/v2009.vpi \
|
||||
$(vpidir)/vhdl_sys.vpi \
|
||||
$(vpidir)/vhdl_textio.vpi \
|
||||
$(vpidir)/vpi_debug.vpi
|
||||
|
||||
$(libdir)/libvpi$(suffix).a : ./libvpi.a
|
||||
$(INSTALL_DATA) libvpi.a "$(DESTDIR)$(libdir)/libvpi$(suffix).a"
|
||||
|
||||
$(vpidir)/system.vpi: ./system.vpi
|
||||
$(INSTALL_PROGRAM) ./system.vpi "$(DESTDIR)$(vpidir)/system.vpi"
|
||||
|
||||
$(vpidir)/system.sft: system.sft
|
||||
$(INSTALL_DATA) $< "$(DESTDIR)$@"
|
||||
|
||||
$(vpidir)/va_math.vpi: ./va_math.vpi
|
||||
$(INSTALL_PROGRAM) ./va_math.vpi "$(DESTDIR)$(vpidir)/va_math.vpi"
|
||||
|
||||
$(vpidir)/va_math.sft: va_math.sft
|
||||
$(INSTALL_DATA) $< "$(DESTDIR)$@"
|
||||
|
||||
$(vpidir)/v2005_math.vpi: ./v2005_math.vpi
|
||||
$(INSTALL_PROGRAM) ./v2005_math.vpi "$(DESTDIR)$(vpidir)/v2005_math.vpi"
|
||||
|
||||
$(vpidir)/v2005_math.sft: v2005_math.sft
|
||||
$(INSTALL_DATA) $< "$(DESTDIR)$@"
|
||||
|
||||
$(vpidir)/v2009.vpi: ./v2009.vpi
|
||||
$(INSTALL_PROGRAM) ./v2009.vpi "$(DESTDIR)$(vpidir)/v2009.vpi"
|
||||
|
||||
$(vpidir)/v2009.sft: v2009.sft
|
||||
$(INSTALL_DATA) $< "$(DESTDIR)$@"
|
||||
|
||||
$(vpidir)/vhdl_sys.vpi: ./vhdl_sys.vpi
|
||||
$(INSTALL_PROGRAM) ./vhdl_sys.vpi "$(DESTDIR)$(vpidir)/vhdl_sys.vpi"
|
||||
|
||||
$(vpidir)/vhdl_sys.sft: vhdl_sys.sft
|
||||
$(INSTALL_DATA) $< "$(DESTDIR)$@"
|
||||
|
||||
$(vpidir)/vhdl_textio.vpi: ./vhdl_textio.vpi
|
||||
$(INSTALL_PROGRAM) ./vhdl_textio.vpi "$(DESTDIR)$(vpidir)/vhdl_textio.vpi"
|
||||
|
||||
$(vpidir)/vhdl_textio.sft: vhdl_textio.sft
|
||||
$(INSTALL_DATA) $< "$(DESTDIR)$@"
|
||||
|
||||
$(vpidir)/vpi_debug.vpi: ./vpi_debug.vpi
|
||||
$(INSTALL_PROGRAM) ./vpi_debug.vpi "$(DESTDIR)$(vpidir)/vpi_debug.vpi"
|
||||
|
||||
|
|
@ -231,21 +225,20 @@ installdirs: $(srcdir)/../mkinstalldirs
|
|||
$(srcdir)/../mkinstalldirs "$(DESTDIR)$(libdir)" "$(DESTDIR)$(vpidir)"
|
||||
|
||||
uninstall:
|
||||
rm -f "$(DESTDIR)$(libdir)/libvpi$(suffix).a"
|
||||
rm -f "$(DESTDIR)$(vpidir)/system.vpi"
|
||||
rm -f "$(DESTDIR)$(vpidir)/system.sft"
|
||||
rm -f "$(DESTDIR)$(vpidir)/va_math.vpi"
|
||||
rm -f "$(DESTDIR)$(vpidir)/va_math.sft"
|
||||
rm -f "$(DESTDIR)$(vpidir)/v2005_math.vpi"
|
||||
rm -f "$(DESTDIR)$(vpidir)/v2005_math.sft"
|
||||
rm -f "$(DESTDIR)$(vpidir)/v2009.vpi"
|
||||
rm -f "$(DESTDIR)$(vpidir)/v2009.sft"
|
||||
rm -f "$(DESTDIR)$(vpidir)/vhdl_sys.vpi"
|
||||
rm -f "$(DESTDIR)$(vpidir)/vhdl_sys.sft"
|
||||
rm -f "$(DESTDIR)$(vpidir)/vhdl_textio.vpi"
|
||||
rm -f "$(DESTDIR)$(vpidir)/vhdl_textio.sft"
|
||||
rm -f "$(DESTDIR)$(vpidir)/vpi_debug.vpi"
|
||||
|
||||
-include $(patsubst %.o, dep/%.d, $O)
|
||||
-include $(patsubst %.o, dep/%.d, $(OPP))
|
||||
-include $(patsubst %.o, dep/%.d, $M)
|
||||
-include $(patsubst %.o, dep/%.d, $V)
|
||||
-include $(patsubst %.o, dep/%.d, $(V2005))
|
||||
-include $(patsubst %.o, dep/%.d, $(VA_MATH))
|
||||
-include $(patsubst %.o, dep/%.d, $(V2009))
|
||||
-include $(patsubst %.o, dep/%.d, $(VHDL_SYS))
|
||||
-include $(patsubst %.o, dep/%.d, $(VHDL_TEXTIO))
|
||||
-include $(patsubst %.o, dep/%.d, $(VPI_DEBUG))
|
||||
|
|
|
|||
|
|
@ -0,0 +1,303 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Martin Whitaker (icarus@martin-whitaker.me.uk)
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#if defined(__MINGW32__) || defined (__CYGWIN32__)
|
||||
|
||||
#include "vpi_user.h"
|
||||
#include <assert.h>
|
||||
|
||||
static vpip_routines_s*vpip_routines = 0;
|
||||
|
||||
// callback related
|
||||
|
||||
vpiHandle vpi_register_cb(p_cb_data data)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->register_cb(data);
|
||||
}
|
||||
PLI_INT32 vpi_remove_cb(vpiHandle ref)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->remove_cb(ref);
|
||||
}
|
||||
|
||||
vpiHandle vpi_register_systf(const struct t_vpi_systf_data*ss)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->register_systf(ss);
|
||||
}
|
||||
void vpi_get_systf_info(vpiHandle obj, p_vpi_systf_data data)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
vpip_routines->get_systf_info(obj, data);
|
||||
}
|
||||
|
||||
// for obtaining handles
|
||||
|
||||
vpiHandle vpi_handle_by_name(const char*name, vpiHandle scope)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->handle_by_name(name, scope);
|
||||
}
|
||||
vpiHandle vpi_handle_by_index(vpiHandle ref, PLI_INT32 idx)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->handle_by_index(ref, idx);
|
||||
}
|
||||
|
||||
// for traversing relationships
|
||||
|
||||
vpiHandle vpi_handle(PLI_INT32 type, vpiHandle ref)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->handle(type, ref);
|
||||
}
|
||||
vpiHandle vpi_iterate(PLI_INT32 type, vpiHandle ref)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->iterate(type, ref);
|
||||
}
|
||||
vpiHandle vpi_scan(vpiHandle iter)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->scan(iter);
|
||||
}
|
||||
|
||||
// for processing properties
|
||||
|
||||
PLI_INT32 vpi_get(int property, vpiHandle ref)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->get(property, ref);
|
||||
}
|
||||
char*vpi_get_str(PLI_INT32 property, vpiHandle ref)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->get_str(property, ref);
|
||||
}
|
||||
|
||||
// delay processing
|
||||
|
||||
void vpi_get_delays(vpiHandle expr, p_vpi_delay delays)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
vpip_routines->get_delays(expr, delays);
|
||||
}
|
||||
void vpi_put_delays(vpiHandle expr, p_vpi_delay delays)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
vpip_routines->put_delays(expr, delays);
|
||||
}
|
||||
|
||||
// value processing
|
||||
|
||||
void vpi_get_value(vpiHandle expr, p_vpi_value value)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
vpip_routines->get_value(expr, value);
|
||||
}
|
||||
vpiHandle vpi_put_value(vpiHandle obj, p_vpi_value value, p_vpi_time when, PLI_INT32 flags)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->put_value(obj, value, when, flags);
|
||||
}
|
||||
|
||||
// time processing
|
||||
|
||||
void vpi_get_time(vpiHandle obj, s_vpi_time*t)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
vpip_routines->get_time(obj, t);
|
||||
}
|
||||
|
||||
// data processing
|
||||
|
||||
void*vpi_get_userdata(vpiHandle obj)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->get_userdata(obj);
|
||||
}
|
||||
PLI_INT32 vpi_put_userdata(vpiHandle obj, void*data)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->put_userdata(obj, data);
|
||||
}
|
||||
|
||||
// I/O routines
|
||||
|
||||
PLI_UINT32 vpi_mcd_open(char*name)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->mcd_open(name);
|
||||
}
|
||||
PLI_UINT32 vpi_mcd_close(PLI_UINT32 mcd)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->mcd_close(mcd);
|
||||
}
|
||||
PLI_INT32 vpi_mcd_flush(PLI_UINT32 mcd)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->mcd_flush(mcd);
|
||||
}
|
||||
char*vpi_mcd_name(PLI_UINT32 mcd)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->mcd_name(mcd);
|
||||
}
|
||||
PLI_INT32 vpi_mcd_printf(PLI_UINT32 mcd, const char*fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
assert(vpip_routines);
|
||||
PLI_INT32 rv = vpip_routines->mcd_vprintf(mcd, fmt, ap);
|
||||
va_end(ap);
|
||||
return rv;
|
||||
}
|
||||
PLI_INT32 vpi_mcd_vprintf(PLI_UINT32 mcd, const char*fmt, va_list ap)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->mcd_vprintf(mcd, fmt, ap);
|
||||
}
|
||||
|
||||
PLI_INT32 vpi_flush(void)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->flush();
|
||||
}
|
||||
PLI_INT32 vpi_printf(const char*fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
assert(vpip_routines);
|
||||
PLI_INT32 rv = vpip_routines->vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
return rv;
|
||||
}
|
||||
PLI_INT32 vpi_vprintf(const char*fmt, va_list ap)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->vprintf(fmt, ap);
|
||||
}
|
||||
|
||||
// utility routines
|
||||
|
||||
PLI_INT32 vpi_chk_error(p_vpi_error_info info)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->chk_error(info);
|
||||
}
|
||||
PLI_INT32 vpi_compare_objects(vpiHandle obj1, vpiHandle obj2)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->compare_objects(obj1, obj2);
|
||||
}
|
||||
PLI_INT32 vpi_free_object(vpiHandle ref)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->free_object(ref);
|
||||
}
|
||||
PLI_INT32 vpi_get_vlog_info(p_vpi_vlog_info info)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->get_vlog_info(info);
|
||||
|
||||
}
|
||||
|
||||
// control routines
|
||||
|
||||
void vpi_control(PLI_INT32 operation, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, operation);
|
||||
assert(vpip_routines);
|
||||
vpip_routines->vcontrol(operation, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
void vpi_sim_control(PLI_INT32 operation, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, operation);
|
||||
assert(vpip_routines);
|
||||
vpip_routines->vcontrol(operation, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
// proposed standard extensions
|
||||
|
||||
PLI_INT32 vpi_fopen(const char*name, const char*mode)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->fopen(name, mode);
|
||||
}
|
||||
FILE*vpi_get_file(PLI_INT32 fd)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->get_file(fd);
|
||||
}
|
||||
|
||||
// Icarus extensions
|
||||
|
||||
s_vpi_vecval vpip_calc_clog2(vpiHandle arg)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
return vpip_routines->calc_clog2(arg);
|
||||
}
|
||||
void vpip_count_drivers(vpiHandle ref, unsigned idx, unsigned counts[4])
|
||||
{
|
||||
assert(vpip_routines);
|
||||
vpip_routines->count_drivers(ref, idx, counts);
|
||||
}
|
||||
void vpip_format_strength(char*str, s_vpi_value*value, unsigned bit)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
vpip_routines->format_strength(str, value, bit);
|
||||
}
|
||||
void vpip_make_systf_system_defined(vpiHandle ref)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
vpip_routines->make_systf_system_defined(ref);
|
||||
}
|
||||
void vpip_mcd_rawwrite(PLI_UINT32 mcd, const char*buf, size_t count)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
vpip_routines->mcd_rawwrite(mcd, buf, count);
|
||||
}
|
||||
void vpip_set_return_value(int value)
|
||||
{
|
||||
assert(vpip_routines);
|
||||
vpip_routines->set_return_value(value);
|
||||
}
|
||||
|
||||
DLLEXPORT PLI_UINT32 vpip_set_callback(vpip_routines_s*routines, PLI_UINT32 version)
|
||||
{
|
||||
if (version != vpip_routines_version)
|
||||
return 0;
|
||||
|
||||
vpip_routines = routines;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void __libvpi_c_dummy_function(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -90,11 +90,6 @@ static void error_message(vpiHandle callh, const char* msg)
|
|||
vpi_control(vpiFinish, 1);
|
||||
}
|
||||
|
||||
static PLI_INT32 sizetf_32 (ICARUS_VPI_CONST PLI_BYTE8*name)
|
||||
{
|
||||
(void)name; /* Parameter is not used. */
|
||||
return 32;
|
||||
}
|
||||
static PLI_INT32 sizetf_64 (ICARUS_VPI_CONST PLI_BYTE8*name)
|
||||
{
|
||||
(void)name; /* Parameter is not used. */
|
||||
|
|
@ -252,39 +247,43 @@ void sys_convert_register(void)
|
|||
s_vpi_systf_data tf_data;
|
||||
vpiHandle res;
|
||||
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.user_data = "$bitstoreal";
|
||||
tf_data.tfname = tf_data.user_data;
|
||||
tf_data.sizetf = sizetf_64;
|
||||
tf_data.compiletf = sys_convert_compiletf;
|
||||
tf_data.calltf = sys_bitstoreal_calltf;
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.sysfunctype = vpiRealFunc;
|
||||
tf_data.user_data = "$bitstoreal";
|
||||
tf_data.tfname = tf_data.user_data;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.compiletf = sys_convert_compiletf;
|
||||
tf_data.calltf = sys_bitstoreal_calltf;
|
||||
res = vpi_register_systf(&tf_data);
|
||||
vpip_make_systf_system_defined(res);
|
||||
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.user_data = "$itor";
|
||||
tf_data.tfname = tf_data.user_data;
|
||||
tf_data.sizetf = sizetf_64;
|
||||
tf_data.compiletf = sys_convert_compiletf;
|
||||
tf_data.calltf = sys_itor_calltf;
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.sysfunctype = vpiRealFunc;
|
||||
tf_data.user_data = "$itor";
|
||||
tf_data.tfname = tf_data.user_data;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.compiletf = sys_convert_compiletf;
|
||||
tf_data.calltf = sys_itor_calltf;
|
||||
res = vpi_register_systf(&tf_data);
|
||||
vpip_make_systf_system_defined(res);
|
||||
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.user_data = "$realtobits";
|
||||
tf_data.tfname = tf_data.user_data;
|
||||
tf_data.sizetf = sizetf_64;
|
||||
tf_data.compiletf = sys_convert_compiletf;
|
||||
tf_data.calltf = sys_realtobits_calltf;
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.sysfunctype = vpiSizedFunc;
|
||||
tf_data.user_data = "$realtobits";
|
||||
tf_data.tfname = tf_data.user_data;
|
||||
tf_data.sizetf = sizetf_64;
|
||||
tf_data.compiletf = sys_convert_compiletf;
|
||||
tf_data.calltf = sys_realtobits_calltf;
|
||||
res = vpi_register_systf(&tf_data);
|
||||
vpip_make_systf_system_defined(res);
|
||||
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.user_data = "$rtoi";
|
||||
tf_data.tfname = tf_data.user_data;
|
||||
tf_data.sizetf = sizetf_32;
|
||||
tf_data.compiletf = sys_convert_compiletf;
|
||||
tf_data.calltf = sys_rtoi_calltf;
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.sysfunctype = vpiIntFunc;
|
||||
tf_data.user_data = "$rtoi";
|
||||
tf_data.tfname = tf_data.user_data;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.compiletf = sys_convert_compiletf;
|
||||
tf_data.calltf = sys_rtoi_calltf;
|
||||
res = vpi_register_systf(&tf_data);
|
||||
vpip_make_systf_system_defined(res);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,6 +78,12 @@ static void check_var_arg(vpiHandle arg, vpiHandle callh, const char *name,
|
|||
vpi_control(vpiFinish, 1);
|
||||
}
|
||||
|
||||
static PLI_INT32 sys_countdrivers_sizetf(ICARUS_VPI_CONST PLI_BYTE8*name)
|
||||
{
|
||||
(void)name; /* Parameter is not used. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the given $countdrivers() call has valid arguments.
|
||||
*/
|
||||
|
|
@ -204,12 +210,13 @@ void sys_countdrivers_register(void)
|
|||
s_vpi_systf_data tf_data;
|
||||
vpiHandle res;
|
||||
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.tfname = "$countdrivers";
|
||||
tf_data.calltf = sys_countdrivers_calltf;
|
||||
tf_data.compiletf = sys_countdrivers_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.user_data = "$countdrivers";
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.sysfunctype = vpiSizedFunc;
|
||||
tf_data.tfname = "$countdrivers";
|
||||
tf_data.calltf = sys_countdrivers_calltf;
|
||||
tf_data.compiletf = sys_countdrivers_compiletf;
|
||||
tf_data.sizetf = sys_countdrivers_sizetf;
|
||||
tf_data.user_data = "$countdrivers";
|
||||
res = vpi_register_systf(&tf_data);
|
||||
vpip_make_systf_system_defined(res);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
#
|
||||
# This is the system function descriptor table for the
|
||||
# builtin (system) functions.
|
||||
#
|
||||
|
||||
$random vpiSysFuncInt
|
||||
$rtoi vpiSysFuncInt
|
||||
$urandom vpiSysFuncSized 32 unsigned
|
||||
$urandom_range vpiSysFuncSized 32 unsigned
|
||||
$dist_uniform vpiSysFuncInt
|
||||
$dist_normal vpiSysFuncInt
|
||||
$dist_exponential vpiSysFuncInt
|
||||
$dist_poisson vpiSysFuncInt
|
||||
$dist_chi_square vpiSysFuncInt
|
||||
$dist_t vpiSysFuncInt
|
||||
$dist_erlang vpiSysFuncInt
|
||||
$clog2 vpiSysFuncInt
|
||||
$q_full vpiSysFuncInt
|
||||
|
||||
$abstime vpiSysFuncReal
|
||||
$simparam vpiSysFuncReal
|
||||
$simparam$str vpiSysFuncSized 1024 unsigned
|
||||
$table_model vpiSysFuncReal
|
||||
|
||||
$ivl_string_method$len vpiSysFuncInt
|
||||
$ivl_string_method$to_vec vpiSysFuncVoid
|
||||
|
||||
$sformatf vpiSysFuncString
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
#
|
||||
# This is the system function descriptor table for the
|
||||
# Verilog-2005 math functions.
|
||||
#
|
||||
|
||||
# Single argument functions.
|
||||
$sqrt vpiSysFuncReal
|
||||
$ln vpiSysFuncReal
|
||||
$log10 vpiSysFuncReal
|
||||
$exp vpiSysFuncReal
|
||||
$ceil vpiSysFuncReal
|
||||
$floor vpiSysFuncReal
|
||||
$sin vpiSysFuncReal
|
||||
$cos vpiSysFuncReal
|
||||
$tan vpiSysFuncReal
|
||||
$asin vpiSysFuncReal
|
||||
$acos vpiSysFuncReal
|
||||
$atan vpiSysFuncReal
|
||||
$sinh vpiSysFuncReal
|
||||
$cosh vpiSysFuncReal
|
||||
$tanh vpiSysFuncReal
|
||||
$asinh vpiSysFuncReal
|
||||
$acosh vpiSysFuncReal
|
||||
$atanh vpiSysFuncReal
|
||||
# Double argument functions.
|
||||
$pow vpiSysFuncReal
|
||||
$atan2 vpiSysFuncReal
|
||||
$hypot vpiSysFuncReal
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
#
|
||||
# This is the system function descriptor table for the
|
||||
# builtin (SystemVerilog) functions.
|
||||
#
|
||||
|
||||
$dimensions vpiSysFuncInt
|
||||
$unpacked_dimensions vpiSysFuncInt
|
||||
$left vpiSysFuncInt
|
||||
$right vpiSysFuncInt
|
||||
$low vpiSysFuncInt
|
||||
$high vpiSysFuncInt
|
||||
$increment vpiSysFuncInt
|
||||
$size vpiSysFuncInt
|
||||
|
||||
$countbits vpiSysFuncInt
|
||||
$countones vpiSysFuncInt
|
||||
$onehot vpiSysFuncSized 1 unsigned
|
||||
$onehot0 vpiSysFuncSized 1 unsigned
|
||||
$isunknown vpiSysFuncSized 1 unsigned
|
||||
|
||||
$ivl_array_method$to_vec vpiSysFuncVoid
|
||||
$ivl_array_method$from_vec vpiSysFuncVoid
|
||||
|
|
@ -505,6 +505,7 @@ void v2009_enum_register(void)
|
|||
vpiHandle res;
|
||||
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.sysfunctype = vpiOtherFunc;
|
||||
tf_data.calltf = ivl_enum_method_name_calltf;
|
||||
tf_data.compiletf = ivl_enum_method_name_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
|
|
@ -515,6 +516,7 @@ void v2009_enum_register(void)
|
|||
vpip_make_systf_system_defined(res);
|
||||
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.sysfunctype = vpiOtherFunc;
|
||||
tf_data.calltf = ivl_enum_method_next_prev_calltf;
|
||||
tf_data.compiletf = ivl_enum_method_next_prev_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
|
|
@ -525,6 +527,7 @@ void v2009_enum_register(void)
|
|||
vpip_make_systf_system_defined(res);
|
||||
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.sysfunctype = vpiOtherFunc;
|
||||
tf_data.calltf = ivl_enum_method_next_prev_calltf;
|
||||
tf_data.compiletf = ivl_enum_method_next_prev_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2018 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2010-2019 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
|
||||
|
|
@ -17,6 +17,8 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "vpi_user.h"
|
||||
|
||||
extern void v2009_array_register(void);
|
||||
extern void v2009_bitvec_register(void);
|
||||
extern void v2009_enum_register(void);
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
#
|
||||
# This is the system function descriptor table for the
|
||||
# Verilog-A math functions.
|
||||
#
|
||||
|
||||
# Single argument functions.
|
||||
$abs vpiSysFuncReal
|
||||
# Double argument functions.
|
||||
$min vpiSysFuncReal
|
||||
$max vpiSysFuncReal
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
$ivlh_attribute_event vpiSysFuncSized 1 unsigned
|
||||
$ivlh_rising_edge vpiSysFuncSized 1 unsigned
|
||||
$ivlh_falling_edge vpiSysFuncSized 1 unsigned
|
||||
|
||||
$ivlh_shift_left vpiSysFuncSized 32 unsigned
|
||||
$ivlh_shift_right vpiSysFuncSized 32 unsigned
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
$ivlh_file_open vpiSysFuncVoid
|
||||
|
||||
$ivlh_readline vpiSysFuncVoid
|
||||
$ivlh_writeline vpiSysFuncVoid
|
||||
|
||||
$ivlh_read vpiSysFuncVoid
|
||||
$ivlh_write vpiSysFuncVoid
|
||||
$ivlh_hread vpiSysFuncVoid
|
||||
$ivlh_hwrite vpiSysFuncVoid
|
||||
|
|
@ -0,0 +1,273 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Martin Whitaker (icarus@martin-whitaker.me.uk)
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "compiler.h"
|
||||
#include "vpi_user.h"
|
||||
#include "sv_vpi_user.h"
|
||||
#include "vvp/ivl_dlfcn.h"
|
||||
|
||||
/* The only VPI routines that can be legally called when the functions in
|
||||
the vlog_startup_routines[] array are executed are vpi_register_systf()
|
||||
and vpi_register_cb(), so we can simply provide stubs for the rest. We
|
||||
aren't going to execute any callbacks, so we can just provide a stub for
|
||||
vpi_register_cb() too.
|
||||
|
||||
Note that the Icarus system module illegally calls vpi_get_vlog_info()
|
||||
during startup, so take care to fill in the data structure for that.
|
||||
*/
|
||||
|
||||
// callback related
|
||||
|
||||
vpiHandle vpi_register_cb(p_cb_data) { return 0; }
|
||||
PLI_INT32 vpi_remove_cb(vpiHandle) { return 0; }
|
||||
|
||||
void vpi_get_systf_info(vpiHandle, p_vpi_systf_data) { }
|
||||
|
||||
// for obtaining handles
|
||||
|
||||
vpiHandle vpi_handle_by_name(const char*, vpiHandle) { return 0; }
|
||||
vpiHandle vpi_handle_by_index(vpiHandle, PLI_INT32) { return 0; }
|
||||
|
||||
// for traversing relationships
|
||||
|
||||
vpiHandle vpi_handle(PLI_INT32, vpiHandle) { return 0; }
|
||||
vpiHandle vpi_iterate(PLI_INT32, vpiHandle) { return 0; }
|
||||
vpiHandle vpi_scan(vpiHandle) { return 0; }
|
||||
|
||||
// for processing properties
|
||||
|
||||
PLI_INT32 vpi_get(int, vpiHandle) { return 0; }
|
||||
char* vpi_get_str(PLI_INT32, vpiHandle) { return 0; }
|
||||
|
||||
// delay processing
|
||||
|
||||
void vpi_get_delays(vpiHandle, p_vpi_delay) { }
|
||||
void vpi_put_delays(vpiHandle, p_vpi_delay) { }
|
||||
|
||||
// value processing
|
||||
|
||||
void vpi_get_value(vpiHandle, p_vpi_value) { }
|
||||
vpiHandle vpi_put_value(vpiHandle, p_vpi_value, p_vpi_time, PLI_INT32) { return 0; }
|
||||
|
||||
// time processing
|
||||
|
||||
void vpi_get_time(vpiHandle, s_vpi_time*) { }
|
||||
|
||||
// data processing
|
||||
|
||||
void* vpi_get_userdata(vpiHandle) { return 0; }
|
||||
PLI_INT32 vpi_put_userdata(vpiHandle, void*) { return 0; }
|
||||
|
||||
// I/O routines
|
||||
|
||||
PLI_UINT32 vpi_mcd_open(char *) { return 0; }
|
||||
PLI_UINT32 vpi_mcd_close(PLI_UINT32) { return 0; }
|
||||
PLI_INT32 vpi_mcd_flush(PLI_UINT32) { return 0; }
|
||||
char* vpi_mcd_name(PLI_UINT32) { return 0; }
|
||||
PLI_INT32 vpi_mcd_printf(PLI_UINT32, const char*, ...) { return 0; }
|
||||
PLI_INT32 vpi_mcd_vprintf(PLI_UINT32, const char*, va_list) { return 0; }
|
||||
|
||||
PLI_INT32 vpi_flush(void) { return 0; }
|
||||
PLI_INT32 vpi_printf(const char*, ...) { return 0; }
|
||||
PLI_INT32 vpi_vprintf(const char*, va_list) { return 0; }
|
||||
|
||||
// utility routines
|
||||
|
||||
PLI_INT32 vpi_chk_error(p_vpi_error_info) { return 0; }
|
||||
PLI_INT32 vpi_compare_objects(vpiHandle, vpiHandle) { return 0; }
|
||||
PLI_INT32 vpi_free_object(vpiHandle) { return 0; }
|
||||
PLI_INT32 vpi_get_vlog_info(p_vpi_vlog_info info)
|
||||
{
|
||||
info->argc = 0;
|
||||
info->argv = 0;
|
||||
info->product = 0;
|
||||
info->version = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// control routines
|
||||
|
||||
void vpi_control(PLI_INT32, ...) { }
|
||||
void vpi_sim_control(PLI_INT32, ...) { }
|
||||
|
||||
// proposed standard extensions
|
||||
|
||||
PLI_INT32 vpi_fopen(const char*, const char*) { return 0; }
|
||||
FILE* vpi_get_file(PLI_INT32) { return 0; }
|
||||
|
||||
// Icarus extensions
|
||||
|
||||
s_vpi_vecval vpip_calc_clog2(vpiHandle)
|
||||
{
|
||||
s_vpi_vecval val = { 0, 0 };
|
||||
return val;
|
||||
}
|
||||
void vpip_count_drivers(vpiHandle, unsigned, unsigned [4]) { }
|
||||
void vpip_format_strength(char*, s_vpi_value*, unsigned) { }
|
||||
void vpip_make_systf_system_defined(vpiHandle) { }
|
||||
void vpip_mcd_rawwrite(PLI_UINT32, const char*, size_t) { }
|
||||
void vpip_set_return_value(int) { }
|
||||
void vpi_vcontrol(PLI_INT32, va_list) { }
|
||||
|
||||
|
||||
/* When a module registers a system function, extract and save the return
|
||||
type for use during elaboration. */
|
||||
vpiHandle vpi_register_systf(const struct t_vpi_systf_data*ss)
|
||||
{
|
||||
if (ss->type != vpiSysFunc)
|
||||
return 0;
|
||||
|
||||
struct sfunc_return_type ret_type;
|
||||
ret_type.name = ss->tfname;
|
||||
switch (ss->sysfunctype) {
|
||||
case vpiIntFunc:
|
||||
ret_type.type = IVL_VT_LOGIC;
|
||||
ret_type.wid = 32;
|
||||
ret_type.signed_flag = true;
|
||||
break;
|
||||
case vpiRealFunc:
|
||||
ret_type.type = IVL_VT_REAL;
|
||||
ret_type.wid = 1;
|
||||
ret_type.signed_flag = true;
|
||||
break;
|
||||
case vpiTimeFunc:
|
||||
ret_type.type = IVL_VT_LOGIC;
|
||||
ret_type.wid = 64;
|
||||
ret_type.signed_flag = false;
|
||||
break;
|
||||
case vpiSizedFunc:
|
||||
ret_type.type = IVL_VT_LOGIC;
|
||||
ret_type.wid = ss->sizetf ? ss->sizetf(ss->user_data) : 32;
|
||||
ret_type.signed_flag = false;
|
||||
break;
|
||||
case vpiSizedSignedFunc:
|
||||
ret_type.type = IVL_VT_LOGIC;
|
||||
ret_type.wid = ss->sizetf ? ss->sizetf(ss->user_data) : 32;
|
||||
ret_type.signed_flag = true;
|
||||
break;
|
||||
case vpiStringFunc:
|
||||
ret_type.type = IVL_VT_STRING;
|
||||
ret_type.wid = 0;
|
||||
ret_type.signed_flag = false;
|
||||
break;
|
||||
case vpiOtherFunc:
|
||||
ret_type.type = IVL_VT_NO_TYPE;
|
||||
ret_type.wid = 0;
|
||||
ret_type.signed_flag = false;
|
||||
break;
|
||||
default:
|
||||
cerr << "warning: " << ss->tfname << " has an unknown return type. "
|
||||
"Assuming 32 bit unsigned." << endl;
|
||||
ret_type.type = IVL_VT_LOGIC;
|
||||
ret_type.wid = 32;
|
||||
ret_type.signed_flag = false;
|
||||
break;
|
||||
}
|
||||
ret_type.override_flag = false;
|
||||
add_sys_func(ret_type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(__MINGW32__) || defined (__CYGWIN32__)
|
||||
vpip_routines_s vpi_routines = {
|
||||
.register_cb = vpi_register_cb,
|
||||
.remove_cb = vpi_remove_cb,
|
||||
.register_systf = vpi_register_systf,
|
||||
.get_systf_info = vpi_get_systf_info,
|
||||
.handle_by_name = vpi_handle_by_name,
|
||||
.handle_by_index = vpi_handle_by_index,
|
||||
.handle = vpi_handle,
|
||||
.iterate = vpi_iterate,
|
||||
.scan = vpi_scan,
|
||||
.get = vpi_get,
|
||||
.get_str = vpi_get_str,
|
||||
.get_delays = vpi_get_delays,
|
||||
.put_delays = vpi_put_delays,
|
||||
.get_value = vpi_get_value,
|
||||
.put_value = vpi_put_value,
|
||||
.get_time = vpi_get_time,
|
||||
.get_userdata = vpi_get_userdata,
|
||||
.put_userdata = vpi_put_userdata,
|
||||
.mcd_open = vpi_mcd_open,
|
||||
.mcd_close = vpi_mcd_close,
|
||||
.mcd_flush = vpi_mcd_flush,
|
||||
.mcd_name = vpi_mcd_name,
|
||||
.mcd_vprintf = vpi_mcd_vprintf,
|
||||
.flush = vpi_flush,
|
||||
.vprintf = vpi_vprintf,
|
||||
.chk_error = vpi_chk_error,
|
||||
.compare_objects = vpi_compare_objects,
|
||||
.free_object = vpi_free_object,
|
||||
.get_vlog_info = vpi_get_vlog_info,
|
||||
.vcontrol = vpi_vcontrol,
|
||||
.fopen = vpi_fopen,
|
||||
.get_file = vpi_get_file,
|
||||
.calc_clog2 = vpip_calc_clog2,
|
||||
.count_drivers = vpip_count_drivers,
|
||||
.format_strength = vpip_format_strength,
|
||||
.make_systf_system_defined = vpip_make_systf_system_defined,
|
||||
.mcd_rawwrite = vpip_mcd_rawwrite,
|
||||
.set_return_value = vpip_set_return_value,
|
||||
};
|
||||
|
||||
typedef PLI_UINT32 (*vpip_set_callback_t)(vpip_routines_s*, PLI_UINT32);
|
||||
#endif
|
||||
typedef void (*vlog_startup_routines_t)(void);
|
||||
|
||||
bool load_vpi_module(const char*path)
|
||||
{
|
||||
ivl_dll_t dll = ivl_dlopen(path, false);
|
||||
if (dll == 0) {
|
||||
cerr << "error: Failed to open '" << path << "' because:" << endl;
|
||||
cerr << " : " << dlerror() << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(__MINGW32__) || defined (__CYGWIN32__)
|
||||
void*function = ivl_dlsym(dll, "vpip_set_callback");
|
||||
if (function == 0) {
|
||||
cerr << "warning: '" << path << "' has no vpip_set_callback()" << endl;
|
||||
ivl_dlclose(dll);
|
||||
return true;
|
||||
}
|
||||
vpip_set_callback_t set_callback = (vpip_set_callback_t)function;
|
||||
if (!set_callback(&vpi_routines, vpip_routines_version)) {
|
||||
cerr << "error: Failed to link '" << path << "'. "
|
||||
"Try rebuilding it with iverilog-vpi." << endl;
|
||||
ivl_dlclose(dll);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void*table = ivl_dlsym(dll, LU "vlog_startup_routines" TU);
|
||||
if (table == 0) {
|
||||
cerr << "warning: '" << path << "' has no vlog_startup_routines" << endl;
|
||||
ivl_dlclose(dll);
|
||||
return true;
|
||||
}
|
||||
|
||||
vlog_startup_routines_t*routines = (vlog_startup_routines_t*)table;
|
||||
for (unsigned idx = 0; routines[idx]; idx += 1) {
|
||||
(routines[idx])();
|
||||
}
|
||||
|
||||
ivl_dlclose(dll);
|
||||
return true;
|
||||
}
|
||||
59
vpi_user.h
59
vpi_user.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef VPI_USER_H
|
||||
#define VPI_USER_H
|
||||
/*
|
||||
* Copyright (c) 1999-2018 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2019 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
|
||||
|
|
@ -675,6 +675,63 @@ extern void vpip_count_drivers(vpiHandle ref, unsigned idx,
|
|||
# define _vpi_at_APV 6
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW32__) || defined (__CYGWIN32__)
|
||||
/*
|
||||
* In Linux, when loaded, a shared library can automatically bind to functions
|
||||
* provided by its client. In Windows, a DLL can only do this statically at
|
||||
* link time, and is then tied to a specific client. So to enable VPI modules
|
||||
* to be used by both the compiler and the simulator, we construct a jump table
|
||||
* for the VPI routines that we can pass down to the VPI modules.
|
||||
*/
|
||||
|
||||
// Increment the version number any time vpip_routines_s is changed.
|
||||
static const PLI_UINT32 vpip_routines_version = 1;
|
||||
|
||||
typedef struct {
|
||||
vpiHandle (*register_cb)(p_cb_data);
|
||||
PLI_INT32 (*remove_cb)(vpiHandle);
|
||||
vpiHandle (*register_systf)(const struct t_vpi_systf_data*ss);
|
||||
void (*get_systf_info)(vpiHandle, p_vpi_systf_data);
|
||||
vpiHandle (*handle_by_name)(const char*, vpiHandle);
|
||||
vpiHandle (*handle_by_index)(vpiHandle, PLI_INT32);
|
||||
vpiHandle (*handle)(PLI_INT32, vpiHandle);
|
||||
vpiHandle (*iterate)(PLI_INT32, vpiHandle);
|
||||
vpiHandle (*scan)(vpiHandle);
|
||||
PLI_INT32 (*get)(int, vpiHandle);
|
||||
char* (*get_str)(PLI_INT32, vpiHandle);
|
||||
void (*get_delays)(vpiHandle, p_vpi_delay);
|
||||
void (*put_delays)(vpiHandle, p_vpi_delay);
|
||||
void (*get_value)(vpiHandle, p_vpi_value);
|
||||
vpiHandle (*put_value)(vpiHandle, p_vpi_value, p_vpi_time, PLI_INT32);
|
||||
void (*get_time)(vpiHandle, s_vpi_time*);
|
||||
void* (*get_userdata)(vpiHandle);
|
||||
PLI_INT32 (*put_userdata)(vpiHandle, void*);
|
||||
PLI_UINT32 (*mcd_open)(char *);
|
||||
PLI_UINT32 (*mcd_close)(PLI_UINT32);
|
||||
PLI_INT32 (*mcd_flush)(PLI_UINT32);
|
||||
char* (*mcd_name)(PLI_UINT32);
|
||||
PLI_INT32 (*mcd_vprintf)(PLI_UINT32, const char*, va_list);
|
||||
PLI_INT32 (*flush)(void);
|
||||
PLI_INT32 (*vprintf)(const char*, va_list);
|
||||
PLI_INT32 (*chk_error)(p_vpi_error_info);
|
||||
PLI_INT32 (*compare_objects)(vpiHandle, vpiHandle);
|
||||
PLI_INT32 (*free_object)(vpiHandle);
|
||||
PLI_INT32 (*get_vlog_info)(p_vpi_vlog_info info) ;
|
||||
void (*vcontrol)(PLI_INT32, va_list);
|
||||
PLI_INT32 (*fopen)(const char*, const char*);
|
||||
FILE* (*get_file)(PLI_INT32);
|
||||
s_vpi_vecval(*calc_clog2)(vpiHandle);
|
||||
void (*count_drivers)(vpiHandle, unsigned, unsigned [4]);
|
||||
void (*format_strength)(char*, s_vpi_value*, unsigned);
|
||||
void (*make_systf_system_defined)(vpiHandle);
|
||||
void (*mcd_rawwrite)(PLI_UINT32, const char*, size_t);
|
||||
void (*set_return_value)(int);
|
||||
} vpip_routines_s;
|
||||
|
||||
extern DLLEXPORT PLI_UINT32 vpip_set_callback(vpip_routines_s*routines, PLI_UINT32 version);
|
||||
|
||||
#endif // defined(__MINGW32__) || defined (__CYGWIN32__)
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif /* VPI_USER_H */
|
||||
|
|
|
|||
|
|
@ -38,9 +38,6 @@ HOSTCFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
|
|||
BUILDCC = @CC_FOR_BUILD@
|
||||
BUILDEXT = @BUILD_EXEEXT@
|
||||
CXX = @CXX@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
AR = @AR@
|
||||
RANLIB = @RANLIB@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
|
|
@ -82,7 +79,7 @@ O = main.o parse.o parse_misc.o lexor.o arith.o array_common.o array.o bufif.o c
|
|||
vvp_object.o vvp_cobject.o vvp_darray.o event.o logic.o delay.o \
|
||||
words.o island_tran.o $(VPI)
|
||||
|
||||
all: dep vvp@EXEEXT@ libvpi.a vvp.man
|
||||
all: dep vvp@EXEEXT@ vvp.man
|
||||
|
||||
check: all
|
||||
ifeq (@WIN32@,yes)
|
||||
|
|
@ -101,13 +98,13 @@ endif
|
|||
|
||||
clean:
|
||||
rm -f *.o *~ parse.cc parse.h lexor.cc tables.cc
|
||||
rm -rf dep vvp@EXEEXT@ libvpi.a parse.output vvp.man vvp.ps vvp.pdf vvp.exp
|
||||
rm -rf dep vvp@EXEEXT@ parse.output vvp.man vvp.ps vvp.pdf vvp.exp
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile config.log
|
||||
rm -f stamp-config-h config.h
|
||||
|
||||
cppcheck: $(O:.o=.cc) libvpi.c draw_tt.c
|
||||
cppcheck: $(O:.o=.cc) draw_tt.c
|
||||
cppcheck --enable=all --std=posix --std=c99 --std=c++03 -f \
|
||||
--suppressions-list=$(srcdir)/cppcheck.sup \
|
||||
-UMODULE_DIR1 -UMODULE_DIR2 -UYY_USER_INIT \
|
||||
|
|
@ -121,30 +118,8 @@ Makefile: $(srcdir)/Makefile.in
|
|||
dep:
|
||||
mkdir dep
|
||||
|
||||
ifeq (@WIN32@,yes)
|
||||
# Under Windows (mingw) I need to make the vvp.exe in two steps.
|
||||
# The first step makes an vvp.exe that dlltool can use to make an
|
||||
# export and import library, and the last link makes a, vvp.exe
|
||||
# that really exports the things that the import library imports.
|
||||
#
|
||||
# To get this to work correctly we must use the suffixed version of the
|
||||
# executable to build the library.
|
||||
vvp@EXEEXT@ libvpi.a: $O $(srcdir)/vvp.def
|
||||
$(CXX) -o vvp$(suffix)@EXEEXT@ $(LDFLAGS) $O $(dllib) $(LIBS)
|
||||
$(DLLTOOL) --dllname vvp$(suffix)@EXEEXT@ --def $(srcdir)/vvp.def \
|
||||
--output-lib libvpi.a --output-exp vvp.exp
|
||||
rm -f vvp$(suffix)@EXEEXT@
|
||||
$(CXX) $(LDFLAGS) -o vvp@EXEEXT@ vvp.exp $(LDFLAGS) $O $(dllib) $(LIBS)
|
||||
else
|
||||
libvpi.a: libvpi.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c $<
|
||||
rm -f libvpi.a
|
||||
$(AR) cqv libvpi.a libvpi.o
|
||||
$(RANLIB) libvpi.a
|
||||
|
||||
vvp@EXEEXT@: $O
|
||||
$(CXX) $(LDFLAGS) -o vvp@EXEEXT@ $O $(LIBS) $(dllib)
|
||||
endif
|
||||
|
||||
%.o: %.cc config.h
|
||||
$(CXX) $(CPPFLAGS) -DIVL_SUFFIX='"$(suffix)"' $(MDIR1) $(MDIR2) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
|
||||
|
|
@ -207,14 +182,11 @@ stamp-config-h: $(srcdir)/config.h.in ../config.status
|
|||
cd ..; ./config.status --header=vvp/config.h
|
||||
config.h: stamp-config-h
|
||||
|
||||
install: all installdirs $(bindir)/vvp$(suffix)@EXEEXT@ $(libdir)/libvpi$(suffix).a $(INSTALL_DOC)
|
||||
install: all installdirs $(bindir)/vvp$(suffix)@EXEEXT@ $(INSTALL_DOC)
|
||||
|
||||
$(bindir)/vvp$(suffix)@EXEEXT@: ./vvp@EXEEXT@
|
||||
$(INSTALL_PROGRAM) ./vvp@EXEEXT@ "$(DESTDIR)$(bindir)/vvp$(suffix)@EXEEXT@"
|
||||
|
||||
$(libdir)/libvpi$(suffix).a : ./libvpi.a
|
||||
$(INSTALL_DATA) libvpi.a "$(DESTDIR)$(libdir)/libvpi$(suffix).a"
|
||||
|
||||
$(mandir)/man1/vvp$(suffix).1: vvp.man
|
||||
$(INSTALL_DATA) vvp.man "$(DESTDIR)$(mandir)/man1/vvp$(suffix).1"
|
||||
|
||||
|
|
@ -227,7 +199,6 @@ installdirs: $(srcdir)/../mkinstalldirs
|
|||
|
||||
uninstall: $(UNINSTALL32)
|
||||
rm -f "$(DESTDIR)$(bindir)/vvp$(suffix)@EXEEXT@"
|
||||
rm -f "$(DESTDIR)$(libdir)/libvpi$(suffix).a"
|
||||
rm -f "$(DESTDIR)$(mandir)/man1/vvp$(suffix).1" "$(DESTDIR)$(prefix)/vvp$(suffix).pdf"
|
||||
|
||||
-include $(patsubst %.o, dep/%.d, $O)
|
||||
|
|
|
|||
|
|
@ -2,10 +2,6 @@
|
|||
// pool is defined there.
|
||||
uninitVar:vvp_net.cc:167
|
||||
|
||||
// These functions are not used by Icarus
|
||||
// __libvpi_c_dummy_function()
|
||||
unusedFunction:libvpi.c:24
|
||||
|
||||
// These functions are not used by Icarus
|
||||
// vpi_chk_error()
|
||||
unusedFunction:vpi_priv.cc:193
|
||||
|
|
|
|||
26
vvp/libvpi.c
26
vvp/libvpi.c
|
|
@ -1,26 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Things that should be statically linked by VPI modules go here.
|
||||
*/
|
||||
|
||||
void __libvpi_c_dummy_function(void)
|
||||
{
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2018 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2019 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
|
||||
|
|
@ -30,6 +30,9 @@
|
|||
static ivl_dll_t*dll_list = 0;
|
||||
static unsigned dll_list_cnt = 0;
|
||||
|
||||
#if defined(__MINGW32__) || defined (__CYGWIN32__)
|
||||
typedef PLI_UINT32 (*vpip_set_callback_t)(vpip_routines_s*, PLI_UINT32);
|
||||
#endif
|
||||
typedef void (*vlog_startup_routines_t)(void);
|
||||
|
||||
# define VPIP_MODULE_PATH_MAX 64
|
||||
|
|
@ -215,13 +218,22 @@ void vpip_load_module(const char*name)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __MINGW32__
|
||||
/* For this check MinGW does not want the leading underscore! */
|
||||
void*table = ivl_dlsym(dll, "vlog_startup_routines");
|
||||
#else
|
||||
void*table = ivl_dlsym(dll, LU "vlog_startup_routines" TU);
|
||||
#if defined(__MINGW32__) || defined (__CYGWIN32__)
|
||||
void*function = ivl_dlsym(dll, "vpip_set_callback");
|
||||
if (function == 0) {
|
||||
fprintf(stderr, "%s: no vpip_set_callback()\n", name);
|
||||
ivl_dlclose(dll);
|
||||
return;
|
||||
}
|
||||
vpip_set_callback_t set_callback = (vpip_set_callback_t)function;
|
||||
if (!set_callback(&vpi_routines, vpip_routines_version)) {
|
||||
fprintf(stderr, "Failed to link VPI module %s. Try rebuilding it with iverilog-vpi.\n", name);
|
||||
ivl_dlclose(dll);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
void*table = ivl_dlsym(dll, LU "vlog_startup_routines" TU);
|
||||
if (table == 0) {
|
||||
fprintf(stderr, "%s: no vlog_startup_routines\n", name);
|
||||
ivl_dlclose(dll);
|
||||
|
|
|
|||
|
|
@ -1634,3 +1634,46 @@ extern "C" void vpip_count_drivers(vpiHandle ref, unsigned idx,
|
|||
assert(rfp);
|
||||
rfp->node->count_drivers(idx, counts);
|
||||
}
|
||||
|
||||
#if defined(__MINGW32__) || defined (__CYGWIN32__)
|
||||
vpip_routines_s vpi_routines = {
|
||||
.register_cb = vpi_register_cb,
|
||||
.remove_cb = vpi_remove_cb,
|
||||
.register_systf = vpi_register_systf,
|
||||
.get_systf_info = vpi_get_systf_info,
|
||||
.handle_by_name = vpi_handle_by_name,
|
||||
.handle_by_index = vpi_handle_by_index,
|
||||
.handle = vpi_handle,
|
||||
.iterate = vpi_iterate,
|
||||
.scan = vpi_scan,
|
||||
.get = vpi_get,
|
||||
.get_str = vpi_get_str,
|
||||
.get_delays = vpi_get_delays,
|
||||
.put_delays = vpi_put_delays,
|
||||
.get_value = vpi_get_value,
|
||||
.put_value = vpi_put_value,
|
||||
.get_time = vpi_get_time,
|
||||
.get_userdata = vpi_get_userdata,
|
||||
.put_userdata = vpi_put_userdata,
|
||||
.mcd_open = vpi_mcd_open,
|
||||
.mcd_close = vpi_mcd_close,
|
||||
.mcd_flush = vpi_mcd_flush,
|
||||
.mcd_name = vpi_mcd_name,
|
||||
.mcd_vprintf = vpi_mcd_vprintf,
|
||||
.flush = vpi_flush,
|
||||
.vprintf = vpi_vprintf,
|
||||
.chk_error = vpi_chk_error,
|
||||
.compare_objects = vpi_compare_objects,
|
||||
.free_object = vpi_free_object,
|
||||
.get_vlog_info = vpi_get_vlog_info,
|
||||
.vcontrol = vpi_sim_vcontrol,
|
||||
.fopen = vpi_fopen,
|
||||
.get_file = vpi_get_file,
|
||||
.calc_clog2 = vpip_calc_clog2,
|
||||
.count_drivers = vpip_count_drivers,
|
||||
.format_strength = vpip_format_strength,
|
||||
.make_systf_system_defined = vpip_make_systf_system_defined,
|
||||
.mcd_rawwrite = vpip_mcd_rawwrite,
|
||||
.set_return_value = vpip_set_return_value,
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -48,6 +48,10 @@ typedef struct __vpiArray* vvp_array_t;
|
|||
* header file elsewhere.
|
||||
*/
|
||||
|
||||
#if defined(__MINGW32__) || defined (__CYGWIN32__)
|
||||
extern vpip_routines_s vpi_routines;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Routines/definitions used to build the file/line number tracing object.
|
||||
*/
|
||||
|
|
|
|||
45
vvp/vvp.def
45
vvp/vvp.def
|
|
@ -1,45 +0,0 @@
|
|||
EXPORTS
|
||||
|
||||
vpi_chk_error
|
||||
vpi_compare_objects
|
||||
vpi_control
|
||||
vpi_flush
|
||||
vpi_fopen
|
||||
vpi_free_object
|
||||
vpi_get
|
||||
vpi_get_delays
|
||||
vpi_get_file
|
||||
vpi_get_str
|
||||
vpi_get_systf_info
|
||||
vpi_get_time
|
||||
vpi_get_userdata
|
||||
vpi_get_value
|
||||
vpi_get_vlog_info
|
||||
vpi_handle
|
||||
vpi_handle_by_index
|
||||
vpi_handle_by_name
|
||||
vpi_iterate
|
||||
vpi_mcd_close
|
||||
vpi_mcd_flush
|
||||
vpi_mcd_name
|
||||
vpi_mcd_open
|
||||
vpi_mcd_printf
|
||||
vpi_mcd_vprintf
|
||||
vpi_printf
|
||||
vpi_put_delays
|
||||
vpi_put_userdata
|
||||
vpi_put_value
|
||||
vpi_register_cb
|
||||
vpi_register_systf
|
||||
vpi_remove_cb
|
||||
vpi_scan
|
||||
vpi_sim_control
|
||||
vpi_sim_vcontrol
|
||||
vpi_vprintf
|
||||
|
||||
vpip_calc_clog2
|
||||
vpip_count_drivers
|
||||
vpip_format_strength
|
||||
vpip_make_systf_system_defined
|
||||
vpip_mcd_rawwrite
|
||||
vpip_set_return_value
|
||||
Loading…
Reference in New Issue