Allow VPI modules to be loaded by multiple clients under Windows.

The old scheme of linking the VPI modules with the vvp exports meant they
did not work when loaded by the compiler. Instead, let each client create
a jump table for the VPI routines and pass that to each VPI module as it
is loaded.
This commit is contained in:
Martin Whitaker 2019-10-22 16:00:13 +01:00
parent e63135b412
commit a59b183bd1
14 changed files with 257 additions and 108 deletions

View File

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

View File

@ -3,8 +3,8 @@
* This may change in the future once I have thought about it more. */
#define IVERILOG_VPI_CC "@IVLCC@"
#define IVERILOG_VPI_CXX "@IVLCXX@"
#define IVERILOG_VPI_CFLAGS " @IVLCFLAGS@"
#define IVERILOG_VPI_CXXFLAGS " @IVLCXXFLAGS@"
#define IVERILOG_VPI_CFLAGS " @IVLCFLAGS@ -DIVL_VPI_MODULE"
#define IVERILOG_VPI_CXXFLAGS " @IVLCXXFLAGS@ -DIVL_VPI_MODULE"
#define IVERILOG_VPI_LDFLAGS "@SHARED@"
#define IVERILOG_VPI_LDLIBS "-lveriuser@SUFFIX@ -lvpi@SUFFIX@"
#define IVERILOG_SUFFIX "@SUFFIX@"

View File

@ -21,8 +21,8 @@
# These are the variables used for compiling files
CC="@IVCC@"
CXX=@IVCXX@
CFLAGS="@PIC@ @IVCFLAGS@ -I@INCLUDEDIR@"
CXXFLAGS="@PIC@ @IVCXXFLAGS@ -I@INCLUDEDIR@"
CFLAGS="@PIC@ @IVCFLAGS@ -I@INCLUDEDIR@ -DIVL_VPI_MODULE"
CXXFLAGS="@PIC@ @IVCXXFLAGS@ -I@INCLUDEDIR@ -DIVL_VPI_MODULE"
SUFFIX=@SUFFIX@

View File

@ -47,7 +47,7 @@ LDRELOCFLAGS = @LDRELOCFLAGS@
LDTARGETFLAGS = @LDTARGETFLAGS@
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ -DICARUS_VPI_CONST=const @PICFLAG@
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ -DICARUS_VPI_CONST=const -DIVL_VPI_MODULE @PICFLAG@
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
A = a_close.o a_compare_handles.o a_configure.o a_fetch_argc.o \

View File

@ -45,7 +45,7 @@ else
INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/..
endif
CPPFLAGS = $(INCLUDE_PATH) @file64_support@ @CPPFLAGS@ @DEFS@ -DICARUS_VPI_CONST=const @PICFLAG@
CPPFLAGS = $(INCLUDE_PATH) @file64_support@ @CPPFLAGS@ @DEFS@ -DICARUS_VPI_CONST=const -DIVL_VPI_MODULE @PICFLAG@
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@
LDFLAGS = @LDFLAGS@
@ -83,12 +83,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 +122,12 @@ dep:
$(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
mv $*.d dep
libvpi.a: libvpi.c
$(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 +136,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 +162,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: $M libvpi.a
$(CC) @shared@ -o $@ $M -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: $V libvpi.a
$(CC) @shared@ -o $@ $V -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,6 +186,7 @@ stamp-vpi_config-h: $(srcdir)/vpi_config.h.in ../config.status
vpi_config.h: stamp-vpi_config-h
install: all installdirs \
$(libdir)/libvpi$(suffix).a \
$(vpidir)/system.vpi \
$(vpidir)/va_math.vpi \
$(vpidir)/v2005_math.vpi \
@ -188,6 +195,9 @@ install: all installdirs \
$(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"
@ -213,6 +223,7 @@ 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)/va_math.vpi"
rm -f "$(DESTDIR)$(vpidir)/v2005_math.vpi"

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003 Stephen Williams (steve@icarus.com)
* 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
@ -17,10 +17,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/*
* Things that should be statically linked by VPI modules go here.
*/
#include "vpi_user.h"
void __libvpi_c_dummy_function(void)
vpip_routines_s*vpip = 0;
DLLEXPORT void vpip_set_callback(vpip_routines_s*routines)
{
vpip = routines;
}

View File

@ -184,6 +184,51 @@ vpiHandle vpi_register_systf(const struct t_vpi_systf_data*ss)
return 0;
}
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_printf = vpi_mcd_printf,
.mcd_vprintf = vpi_mcd_vprintf,
.flush = vpi_flush,
.printf = vpi_printf,
.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,
.control = vpi_control,
.sim_control = vpi_sim_control,
.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 void (*vpip_set_callback_t)(vpip_routines_s*);
typedef void (*vlog_startup_routines_t)(void);
bool load_vpi_module(const char*path)
@ -195,6 +240,14 @@ bool load_vpi_module(const char*path)
return false;
}
vpip_set_callback_t set_callback = (vpip_set_callback_t)ivl_dlsym(dll, "vpip_set_callback");
if (set_callback == 0) {
cerr << "warning: '" << path << "' has no vpip_set_callback()" << endl;
ivl_dlclose(dll);
return true;
}
set_callback(&vpi_routines);
#ifdef __MINGW32__
void*table = ivl_dlsym(dll, "vlog_startup_routines");
#else

View File

@ -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,111 @@ extern void vpip_count_drivers(vpiHandle ref, unsigned idx,
# define _vpi_at_APV 6
#endif
/*
* In Linux, a shared library can bind by name to functions provided by its
* client when it is loaded. 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.
*/
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_printf)(PLI_UINT32, const char*, ...);
PLI_INT32 (*mcd_vprintf)(PLI_UINT32, const char*, va_list);
PLI_INT32 (*flush)(void);
PLI_INT32 (*printf)(const char*, ...);
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 (*control)(PLI_INT32, ...);
void (*sim_control)(PLI_INT32, ...);
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 void vpip_set_callback(vpip_routines_s*routines);
/*
* IVL_VPI_MODULE should be defined when compiling a VPI module to route
* all VPI routine calls through the jump table.
*/
#ifdef IVL_VPI_MODULE
extern vpip_routines_s*vpip;
#define vpi_register_cb(...) vpip->register_cb(__VA_ARGS__)
#define vpi_remove_cb(...) vpip->remove_cb(__VA_ARGS__)
#define vpi_register_systf(...) vpip->register_systf(__VA_ARGS__)
#define vpi_get_systf_info(...) vpip->get_systf_info(__VA_ARGS__)
#define vpi_handle_by_name(...) vpip->handle_by_name(__VA_ARGS__)
#define vpi_handle_by_index(...) vpip->handle_by_index(__VA_ARGS__)
#define vpi_handle(...) vpip->handle(__VA_ARGS__)
#define vpi_iterate(...) vpip->iterate(__VA_ARGS__)
#define vpi_scan(...) vpip->scan(__VA_ARGS__)
#define vpi_get(...) vpip->get(__VA_ARGS__)
#define vpi_get_str(...) vpip->get_str(__VA_ARGS__)
#define vpi_get_delays(...) vpip->get_delays(__VA_ARGS__)
#define vpi_put_delays(...) vpip->put_delays(__VA_ARGS__)
#define vpi_get_value(...) vpip->get_value(__VA_ARGS__)
#define vpi_put_value(...) vpip->put_value(__VA_ARGS__)
#define vpi_get_time(...) vpip->get_time(__VA_ARGS__)
#define vpi_get_userdata(...) vpip->get_userdata(__VA_ARGS__)
#define vpi_put_userdata(...) vpip->put_userdata(__VA_ARGS__)
#define vpi_mcd_open(...) vpip->mcd_open(__VA_ARGS__)
#define vpi_mcd_close(...) vpip->mcd_close(__VA_ARGS__)
#define vpi_mcd_flush(...) vpip->mcd_flush(__VA_ARGS__)
#define vpi_mcd_name(...) vpip->mcd_name(__VA_ARGS__)
#define vpi_mcd_printf(...) vpip->mcd_printf(__VA_ARGS__)
#define vpi_mcd_vprintf(...) vpip->mcd_vprintf(__VA_ARGS__)
#define vpi_flush(...) vpip->flush(__VA_ARGS__)
#define vpi_printf(...) vpip->printf(__VA_ARGS__)
#define vpi_vprintf(...) vpip->vprintf(__VA_ARGS__)
#define vpi_chk_error(...) vpip->chk_error(__VA_ARGS__)
#define vpi_compare_objects(...) vpip->compare_objects(__VA_ARGS__)
#define vpi_free_object(...) vpip->free_object(__VA_ARGS__)
#define vpi_get_vlog_info(...) vpip->get_vlog_info(__VA_ARGS__)
#define vpi_control(...) vpip->control(__VA_ARGS__)
#define vpi_sim_control(...) vpip->sim_control(__VA_ARGS__)
#define vpi_fopen(...) vpip->fopen(__VA_ARGS__)
#define vpi_get_file(...) vpip->get_file(__VA_ARGS__)
#define vpip_calc_clog2(...) vpip->calc_clog2(__VA_ARGS__)
#define vpip_count_drivers(...) vpip->count_drivers(__VA_ARGS__)
#define vpip_format_strength(...) vpip->format_strength(__VA_ARGS__)
#define vpip_make_systf_system_defined(...) vpip->make_systf_system_defined(__VA_ARGS__)
#define vpip_mcd_rawwrite(...) vpip->mcd_rawwrite(__VA_ARGS__)
#define vpip_set_return_value(...) vpip->set_return_value(__VA_ARGS__)
#endif // IVL_VPI_MODULE
EXTERN_C_END
#endif /* VPI_USER_H */

View File

@ -82,7 +82,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 +101,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 +121,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 +185,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 +202,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)

View File

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

View File

@ -30,6 +30,7 @@
static ivl_dll_t*dll_list = 0;
static unsigned dll_list_cnt = 0;
typedef void (*vpip_set_callback_t)(vpip_routines_s*);
typedef void (*vlog_startup_routines_t)(void);
# define VPIP_MODULE_PATH_MAX 64
@ -215,6 +216,13 @@ void vpip_load_module(const char*name)
return;
}
vpip_set_callback_t set_callback = (vpip_set_callback_t)ivl_dlsym(dll, "vpip_set_callback");
if (set_callback == 0) {
fprintf(stderr, "%s: no vpip_set_callback\n", name);
ivl_dlclose(dll);
return;
}
set_callback(&vpi_routines);
#ifdef __MINGW32__
/* For this check MinGW does not want the leading underscore! */

View File

@ -1634,3 +1634,47 @@ extern "C" void vpip_count_drivers(vpiHandle ref, unsigned idx,
assert(rfp);
rfp->node->count_drivers(idx, counts);
}
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_printf = vpi_mcd_printf,
.mcd_vprintf = vpi_mcd_vprintf,
.flush = vpi_flush,
.printf = vpi_printf,
.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,
.control = vpi_control,
.sim_control = vpi_sim_control,
.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,
};

View File

@ -48,6 +48,8 @@ typedef struct __vpiArray* vvp_array_t;
* header file elsewhere.
*/
extern vpip_routines_s vpi_routines;
/*
* Routines/definitions used to build the file/line number tracing object.
*/

View File

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