This commit is contained in:
Ralf Habacker 2026-05-22 13:20:13 +02:00 committed by GitHub
commit 1294beb96e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 119 additions and 42 deletions

View File

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

View File

@ -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. */

View File

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

View File

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

View File

@ -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" .
" <regression file> # 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";
}
}

23
main.cc
View File

@ -131,18 +131,35 @@ map<string,const char*> 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<char*>(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);
}

View File

@ -23,6 +23,8 @@
#include "sv_vpi_user.h"
#include "ivl_dlfcn.h"
#include <string.h>
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__)