From a638d1eed0f04486fc8857b03e1fc84a9726ea2f Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 28 Oct 2018 12:43:40 -0700 Subject: [PATCH 1/2] Check for too many paths specified and fix path priority so paths specified on command line supersede built-in paths --- vvp/main.cc | 96 ++++++++++++++++++++++++++++------------------ vvp/vpi_modules.cc | 19 +-------- vvp/vpi_priv.h | 2 +- 3 files changed, 62 insertions(+), 55 deletions(-) diff --git a/vvp/main.cc b/vvp/main.cc index e095a0d5d..acde2cb88 100644 --- a/vvp/main.cc +++ b/vvp/main.cc @@ -262,43 +262,6 @@ int main(int argc, char*argv[]) extern bool stop_is_finish; extern int stop_is_finish_exit_code; -#ifdef __MINGW32__ - /* Calculate the module path from the path to the command. - This is necessary because of the installation process on - Windows. Mostly, it is those darn drive letters, but oh - well. We know the command path is formed like this: - - D:\iverilog\bin\iverilog.exe - - The IVL_ROOT in a Windows installation is the path: - - D:\iverilog\lib\ivl$(suffix) - - so we chop the file name and the last directory by - turning the last two \ characters to null. Then we append - the lib\ivl$(suffix) to finish. */ - char *s; - char basepath[4096], tmp[4096]; - GetModuleFileName(NULL, tmp, sizeof tmp); - /* Convert to a short name to remove any embedded spaces. */ - GetShortPathName(tmp, basepath, sizeof basepath); - s = strrchr(basepath, '\\'); - if (s) *s = 0; - else { - fprintf(stderr, "%s: Missing first \\ in exe path!\n", argv[0]); - exit(1); - } - s = strrchr(basepath, '\\'); - if (s) *s = 0; - else { - fprintf(stderr, "%s: Missing second \\ in exe path!\n", argv[0]); - exit(1); - } - strcat(s, "\\lib\\ivl" IVL_SUFFIX); - vpip_module_path[0] = strdup(basepath); -#endif - - if( ::getenv("VVP_WAIT_FOR_DEBUGGER") != 0 ) { fprintf( stderr, "Waiting for debugger...\n"); bool debugger_release = false; @@ -343,6 +306,10 @@ int main(int argc, char*argv[]) vpip_module_path_cnt = 0; vpip_module_path[0] = 0; } else { + if (vpip_module_path_cnt >= VPIP_MODULE_PATH_MAX) { + fprintf(stderr, "Too many paths specified\n"); + return -1; + } vpip_module_path[vpip_module_path_cnt++] = optarg; } break; @@ -369,6 +336,61 @@ int main(int argc, char*argv[]) flag_errors += 1; } +#ifdef __MINGW32__ + /* Calculate the module path from the path to the command. + This is necessary because of the installation process on + Windows. Mostly, it is those darn drive letters, but oh + well. We know the command path is formed like this: + + D:\iverilog\bin\iverilog.exe + + The IVL_ROOT in a Windows installation is the path: + + D:\iverilog\lib\ivl$(suffix) + + so we chop the file name and the last directory by + turning the last two \ characters to null. Then we append + the lib\ivl$(suffix) to finish. */ + char *s; + char basepath[4096], tmp[4096]; + GetModuleFileName(NULL, tmp, sizeof tmp); + /* Convert to a short name to remove any embedded spaces. */ + GetShortPathName(tmp, basepath, sizeof basepath); + s = strrchr(basepath, '\\'); + if (s) *s = 0; + else { + fprintf(stderr, "%s: Missing first \\ in exe path!\n", argv[0]); + exit(1); + } + s = strrchr(basepath, '\\'); + if (s) *s = 0; + else { + fprintf(stderr, "%s: Missing second \\ in exe path!\n", argv[0]); + exit(1); + } + strcat(s, "\\lib\\ivl" IVL_SUFFIX); + if (vpip_module_path_cnt >= VPIP_MODULE_PATH_MAX) { + fprintf(stderr, "Too many paths specified\n"); + return -1; + } + vpip_module_path[vpip_module_path_cnt++] = strdup(basepath); +#else +#ifdef MODULE_DIR1 + if (vpip_module_path_cnt >= VPIP_MODULE_PATH_MAX) { + fprintf(stderr, "Too many paths specified\n"); + return -1; + } + vpip_module_path[vpip_module_path_cnt++] = MODULE_DIR1; +#endif +#endif +#ifdef MODULE_DIR2 + if (vpip_module_path_cnt >= VPIP_MODULE_PATH_MAX) { + fprintf(stderr, "Too many paths specified\n"); + return -1; + } + vpip_module_path[vpip_module_path_cnt++] = MODULE_DIR2; +#endif + if (flag_errors) return flag_errors; diff --git a/vvp/vpi_modules.cc b/vvp/vpi_modules.cc index 6a9a515b1..6a8012473 100644 --- a/vvp/vpi_modules.cc +++ b/vvp/vpi_modules.cc @@ -33,24 +33,9 @@ static unsigned dll_list_cnt = 0; typedef void (*vlog_startup_routines_t)(void); -const char* vpip_module_path[64] = { -#ifdef MODULE_DIR1 - MODULE_DIR1, -#endif -#ifdef MODULE_DIR2 - MODULE_DIR2, -#endif - 0 -}; +const char* vpip_module_path[VPIP_MODULE_PATH_MAX] = {0}; -unsigned vpip_module_path_cnt = 0 -#ifdef MODULE_DIR1 - + 1 -#endif -#ifdef MODULE_DIR2 - + 1 -#endif -; +unsigned vpip_module_path_cnt = 0; void load_module_delete(void) { diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index 9fa811e3f..51b1bf4b3 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -874,7 +874,7 @@ vpiHandle vpip_make_vthr_APV(char*label, unsigned index, unsigned bit, unsigned extern void vpip_load_module(const char*name); # define VPIP_MODULE_PATH_MAX 64 -extern const char* vpip_module_path[64]; +extern const char* vpip_module_path[VPIP_MODULE_PATH_MAX]; extern unsigned vpip_module_path_cnt; /* From a1ad6d4b51a5e505ce938c4a3a58a202b4f94831 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 28 Oct 2018 12:44:09 -0700 Subject: [PATCH 2/2] Support IVERILOG_VPI_MODULE_PATH environment variable --- vvp/main.cc | 22 ++++++++++++++++++++++ vvp/vvp.man.in | 7 +++++++ 2 files changed, 29 insertions(+) diff --git a/vvp/main.cc b/vvp/main.cc index acde2cb88..b0a5bb633 100644 --- a/vvp/main.cc +++ b/vvp/main.cc @@ -336,6 +336,28 @@ int main(int argc, char*argv[]) flag_errors += 1; } + if (char *var = ::getenv("IVERILOG_VPI_MODULE_PATH")) { + char *ptr = var; + char *end = var+strlen(var); + int len = 0; + while (ptr <= end) { + if (*ptr == 0 || *ptr == ':' || *ptr == ';') { + if (len > 0) { + if (vpip_module_path_cnt >= VPIP_MODULE_PATH_MAX) { + fprintf(stderr, "Too many paths specified\n"); + return -1; + } + vpip_module_path[vpip_module_path_cnt++] = strndup(var, len); + } + len = 0; + var = ptr+1; + } else { + len++; + } + ptr++; + } + } + #ifdef __MINGW32__ /* Calculate the module path from the path to the command. This is necessary because of the installation process on diff --git a/vvp/vvp.man.in b/vvp/vvp.man.in index d08b937d0..add5faf4e 100644 --- a/vvp/vvp.man.in +++ b/vvp/vvp.man.in @@ -166,6 +166,13 @@ select lxt format, which is far more compact, though limited to GTKWave or compatible viewers. It can also be used to suppress VCD output, a time-saver for regression tests. +.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 \-M, but +before the default search path. Multiple paths can be separated with +colons or semicolons. + .SH INTERACTIVE MODE .PP The simulation engine supports an interactive mode. The user may