diff --git a/driver/main.c b/driver/main.c index 95d02e91b..cacd81f22 100644 --- a/driver/main.c +++ b/driver/main.c @@ -1374,6 +1374,13 @@ int main(int argc, char **argv) } } + if (version_flag) { + printf("Icarus Verilog version " VERSION " (" VERSION_TAG ")\n\n"); + printf("%s\n\n", COPYRIGHT); + puts(NOTICE); + return 0; + } + if (strcmp(gen_verilog_ams,"verilog-ams") == 0) fprintf(defines_file, "D:__VAMS_ENABLE__=1\n"); if (synth_flag) @@ -1390,12 +1397,6 @@ int main(int argc, char **argv) if (tconfig_dir == 0) tconfig_dir = base; - if (version_flag || verbose_flag) { - printf("Icarus Verilog version " VERSION " (" VERSION_TAG ")\n\n"); - printf("%s\n\n", COPYRIGHT); - puts(NOTICE); - } - /* Make a common conf file path to reflect the target. */ snprintf(iconfig_common_path, sizeof iconfig_common_path, "%s%c%s%s.conf", tconfig_dir, sep, targ, synth_flag? "-s" : ""); @@ -1403,10 +1404,20 @@ 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 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); + char module_prefix[1024]; + const char *module_suffix; + if (strcmp(vpi_dir, base) != 0) { + snprintf(module_prefix, sizeof(module_prefix), "module:%s%c", vpi_dir, sep); + module_suffix = ".vpi"; + } else { + snprintf(module_prefix, sizeof(module_prefix), "module:"); + module_suffix = ""; + } + + /* Tell the core where to find the built-in VPI modules. */ + fprintf(iconfig_file, "%ssystem%s\n", module_prefix, module_suffix); + fprintf(iconfig_file, "%svhdl_sys%s\n", module_prefix, module_suffix); + fprintf(iconfig_file, "%svhdl_textio%s\n", module_prefix, module_suffix); /* If verilog-2005/09/12/17/23 is enabled or icarus-misc or verilog-ams, * then include the v2005_math library. */ @@ -1417,13 +1428,13 @@ int main(int argc, char **argv) strcmp(generation, "2023") == 0 || strcmp(gen_icarus, "icarus-misc") == 0 || strcmp(gen_verilog_ams, "verilog-ams") == 0) { - fprintf(iconfig_file, "module:%s%cv2005_math.vpi\n", vpi_dir, sep); + fprintf(iconfig_file, "%sv2005_math%s\n", module_prefix, module_suffix); } /* 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, "module:%s%cva_math.vpi\n", vpi_dir, sep); + fprintf(iconfig_file, "%sva_math%s\n", module_prefix, module_suffix); } /* If verilog-2009 (SystemVerilog) is enabled, then include the v2009 module. */ @@ -1432,7 +1443,7 @@ int main(int argc, char **argv) strcmp(generation, "2012") == 0 || strcmp(generation, "2017") == 0 || strcmp(generation, "2023") == 0) { - fprintf(iconfig_file, "module:%s%cv2009.vpi\n", vpi_dir, sep); + fprintf(iconfig_file, "%sv2009%s\n", module_prefix, module_suffix); } if (mtm != 0) fprintf(iconfig_file, "-T:%s\n", mtm); @@ -1547,8 +1558,14 @@ int main(int argc, char **argv) /* Write the preprocessor command needed to preprocess a single file. This may be used to preprocess library files. */ - fprintf(iconfig_file, "ivlpp:%s%civlpp %s -L -F\"%s\" -P\"%s\"\n", - ivlpp_dir, sep, + char ivlpp_prefix[1024]; + if (strcmp(ivlpp_dir, base) != 0) + snprintf(ivlpp_prefix, sizeof(ivlpp_prefix), "%s%c", ivlpp_dir, sep); + else + *ivlpp_prefix = '\0'; + + fprintf(iconfig_file, "ivlpp:%sivlpp %s -L -F\"%s\" -P\"%s\"\n", + ivlpp_prefix, strchr(warning_flags, 'r') ? "-Wredef-all" : strchr(warning_flags, 'R') ? "-Wredef-chg" : "", defines_path, compiled_defines_path diff --git a/ivlpp/main.c b/ivlpp/main.c index fb50b9516..b7910abd4 100644 --- a/ivlpp/main.c +++ b/ivlpp/main.c @@ -59,6 +59,8 @@ char *dep_path = NULL; char dep_mode = 'a'; /* verbose flag */ int verbose_flag = 0; +/* version flag */ +int version_flag = 0; /* Path to vhdlpp */ char *vhdlpp_path = 0; /* vhdlpp work directory */ @@ -350,19 +352,12 @@ int main(int argc, char*argv[]) break; case 'v': - fprintf(stderr, "Icarus Verilog Preprocessor version " - VERSION " (" VERSION_TAG ")\n\n"); - fprintf(stderr, "%s\n\n", COPYRIGHT); - fputs(NOTICE, stderr); verbose_flag = 1; break; case 'V': - fprintf(stdout, "Icarus Verilog Preprocessor version " - VERSION " (" VERSION_TAG ")\n\n"); - fprintf(stdout, "%s\n\n", COPYRIGHT); - fputs(NOTICE, stdout); - return 0; + version_flag = 1; + break; default: flag_errors += 1; @@ -387,6 +382,14 @@ int main(int argc, char*argv[]) return flag_errors; } + if (version_flag) { + fprintf(stdout, "Icarus Verilog Preprocessor version " + VERSION " (" VERSION_TAG ")\n\n"); + fprintf(stdout, "%s\n\n", COPYRIGHT); + fputs(NOTICE, stdout); + return 0; + } + /* Collect the file names on the command line in the source file list, then if there is a file list, read more file names from there. */ diff --git a/ivtest/Makefile.in b/ivtest/Makefile.in index a68469b04..4b2fa2b5d 100644 --- a/ivtest/Makefile.in +++ b/ivtest/Makefile.in @@ -40,9 +40,9 @@ check-installed: check-installed-vpi: @echo "Running vpi_reg.pl" ifeq (@LIBVERIUSER@,yes) - cd $(abs_srcdir); perl vpi_reg.pl --with-pli1 $(opts) + cd $(abs_srcdir); perl vpi_reg.pl --with-pli1 $(opts) --verbose else - cd $(abs_srcdir); perl vpi_reg.pl $(opts) + cd $(abs_srcdir); perl vpi_reg.pl $(opts) --verbose endif check-installed-vvp: diff --git a/ivtest/perl-lib/Environment.pm b/ivtest/perl-lib/Environment.pm index a348e91cc..ab8bc2c83 100644 --- a/ivtest/perl-lib/Environment.pm +++ b/ivtest/perl-lib/Environment.pm @@ -91,14 +91,15 @@ sub get_regress_fn { # sub get_ivl_version { my $sfx = shift(@_); - if (`iverilog$sfx -V` =~ /^Icarus Verilog version (\d+)\.(\d+)/) { + my $cmd = "iverilog$sfx -V"; + if (`$cmd` =~ /^Icarus Verilog version (\d+)\.(\d+)/) { if ($1 == 0) { return $1.".".$2; } else { return $1; } } else { - die "Failed to get version from iverilog$sfx -V output"; + die "Failed to get version from '$cmd' output"; } } @@ -107,7 +108,7 @@ sub get_ivl_version { # is redirected to a log file. # sub run_program { - my ($cmd, $log_mode, $log_file) = @_; + my ($cmd, $log_mode, $log_file, $verbose) = @_; my $ret; if ($log_mode) { @@ -121,6 +122,9 @@ sub run_program { } else { $ret = system($cmd); } + if ($verbose) { + print "running: '$cmd' -> $ret\n"; + } $ret; } diff --git a/ivtest/vpi_reg.pl b/ivtest/vpi_reg.pl index 71418cd79..6cb49753b 100755 --- a/ivtest/vpi_reg.pl +++ b/ivtest/vpi_reg.pl @@ -13,9 +13,11 @@ use Getopt::Long; $sfx = ""; # Default suffix. $with_pli1 = 0; # Default PLI 1 support (keep this off). $with_valg = 0; # Default valgrind usage (keep this off). +$verbose = 0; # Verbose mode if (!GetOptions("suffix=s" => \$sfx, "with-pli1" => \$with_pli1, "with-valgrind" => \$with_valg, + "verbose" => \$verbose, "help" => \&usage)) { die "Error: Invalid argument(s).\n"; } @@ -28,6 +30,8 @@ sub usage { "default \"off\".\n" . " --with-valgrind # Run the test suite with valgrind, " . "default \"off\".\n" . + " --verbose # Be verbose when running commands, " . + "default \"off\".\n" . " # The regression file, " . "default \"./vpi_regress.list\".\n\n"; exit; @@ -157,6 +161,15 @@ sub read_regression_list { close (REGRESS_LIST); } +sub print_log { + my ($filename) = @_; + open(my $fh, '<', $filename) or die $!; + my $content = do { local $/; <$fh> }; + close($fh); + open(my $fh, '<', $filename) or die "Datei '$filename' konnte nicht geƶffnet werden: $!"; + print "content of '$filename': $content"; +} + # # execute_regression sequentially compiles and executes each test in # the regression. It then checks that the output matched the gold file. @@ -198,16 +211,19 @@ sub execute_regression { $cmd = "iverilog-vpi$sfx --name=$tname $cargs{$tname} " . "vpi/$ccode{$tname}"; - if (run_program($cmd, '>', "vpi_log/$tname.log")) { + if (run_program($cmd, '>', "vpi_log/$tname.log", $verbose)) { print "==> Failed - running iverilog-vpi.\n"; + print_log("vpi_log/$tname.log"); $failed++; next; } + $vflag = $verbose ? " -v" : ""; $cmd = $with_valg ? "valgrind --trace-children=yes " : ""; - $cmd .= "iverilog$sfx $args{$tname} -L . -m $tname -o vsim vpi/$tname.v"; - if (run_program($cmd, '>>', "vpi_log/$tname.log")) { + $cmd .= "iverilog$sfx $vflag $args{$tname} -L . -m $tname -o vsim vpi/$tname.v"; + if (run_program($cmd, '>>', "vpi_log/$tname.log", $verbose)) { print "==> Failed - running iverilog.\n"; + print_log("vpi_log/$tname.log"); $failed++; next; } @@ -215,14 +231,16 @@ sub execute_regression { $cmd = $with_valg ? "valgrind --leak-check=full " . "--show-reachable=yes " : ""; $cmd .= "vvp$sfx vsim"; - if (run_program($cmd, '>>', "vpi_log/$tname.log")) { + if (run_program($cmd, '>>', "vpi_log/$tname.log", $verbose)) { print "==> Failed - running vvp.\n"; + print_log("vpi_log/$tname.log"); $failed++; next; } if (diff("vpi_gold/$goldfile{$tname}", "vpi_log/$tname.log")) { print "==> Failed - output does not match gold file.\n"; + print_log("vpi_log/$tname.log"); $failed++; next; } @@ -237,7 +255,7 @@ sub execute_regression { if ($tname ne "" and $ccode{$tname} ne "") { my $doto = $ccode{$tname}; $doto =~ s/\.(c|cc|cpp)$/.o/; - run_program("rm -f $doto $tname.vpi vsim") and + run_program("rm -f $doto $tname.vpi vsim", '', '', $verbose) and die "Error: failed to remove temporary files.\n"; } } diff --git a/main.cc b/main.cc index 917e006e9..9ac47b4d6 100644 --- a/main.cc +++ b/main.cc @@ -131,18 +131,35 @@ map flags; char*vpi_module_list = 0; void add_vpi_module(const char*name) { + const char*module_name = strrchr(name, '/'); +#ifdef __MINGW32__ + const char*module_name2 = strrchr(name, '\\'); + if (!module_name || (module_name2 && module_name2 > module_name)) + module_name = module_name2; +#endif + module_name = module_name ? module_name + 1 : name; + + char*module_base = strdup(module_name); + size_t module_len = strlen(module_base); + if (module_len > 4 && strcmp(module_base + module_len - 4, ".vpi") == 0) { + module_base[module_len - 4] = 0; + } else if (module_len > 4 && strcmp(module_base + module_len - 4, ".vpl") == 0) { + module_base[module_len - 4] = 0; + } + if (vpi_module_list == 0) { - vpi_module_list = strdup(name); + vpi_module_list = strdup(module_base); } else { char*tmp = static_cast(realloc(vpi_module_list, strlen(vpi_module_list) - + strlen(name) + + strlen(module_base) + 2)); strcat(tmp, ","); - strcat(tmp, name); + strcat(tmp, module_base); vpi_module_list = tmp; } + free(module_base); flags["VPI_MODULE_LIST"] = vpi_module_list; load_vpi_module(name); } diff --git a/vpi_modules.cc b/vpi_modules.cc index 17a42c69f..92c852c81 100644 --- a/vpi_modules.cc +++ b/vpi_modules.cc @@ -23,6 +23,8 @@ #include "sv_vpi_user.h" #include "ivl_dlfcn.h" +#include + using namespace std; /* The only VPI routines that can be legally called when the functions in @@ -241,11 +243,27 @@ 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; + ivl_dll_t dll = NULL;; + if (strchr(path, '/') != NULL || strchr(path, '\\') != NULL) { + dll = ivl_dlopen(path, false); + if (dll == 0) { + cerr << "error: Failed to open +++'" << path << "' because:" << endl; + cerr << " : " << dlerror() << endl; + return false; + } + } else { + const char *suffix = ".vpi"; + size_t len = strlen(basedir) + 1 + strlen(path) + strlen(suffix) + 1; + char*tmp = new char[len]; + snprintf(tmp, len, "%s/%s%s", basedir, path, suffix); + dll = ivl_dlopen(tmp, false); + if (dll == 0) { + cerr << "error: Failed to open ---'" << tmp << "' because:" << endl; + cerr << " : " << dlerror() << endl; + delete[] tmp; + return false; + } + delete[] tmp; } #if defined(__MINGW32__) || defined (__CYGWIN__)