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:
parent
e63135b412
commit
a59b183bd1
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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@"
|
||||
|
|
|
|||
|
|
@ -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@
|
||||
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
107
vpi_user.h
107
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,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 */
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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! */
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
|||
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