Add --get-supported to determine what features are in Verilator (#3688).

This commit is contained in:
Wilson Snyder 2022-10-20 21:42:30 -04:00
parent ca8ef7ce73
commit 7e1b92fa75
11 changed files with 97 additions and 58 deletions

View File

@ -35,6 +35,7 @@ Verilator 5.001 devel
* Support tristate select/extend (#3604). [Ryszard Rozak, Antmicro Ltd>
* Support linting for top module interfaces (#3635). [Kanad Kanhere]
* Add --dump-tree-dot to enable dumping Ast Tree .dot files (#3636). [Marcel Chang]
* Add --get-supported to determine what features are in Verilator.
* Add error on real edge event control.
* Fix LSB error on --hierarchical submodules (#3539). [danbone]
* Fix $display of fixed-width numbers (#3565). [Iztok Jeras]

View File

@ -335,6 +335,7 @@ detailed descriptions of these arguments.
--gdbbt Run Verilator under GDB for backtrace
--generate-key Create random key for --protect-key
--getenv <var> Get environment variable with defaults
--get-supported <feature> Get if feature is supported
--help Display this help
--hierarchical Enable hierarchical Verilation
-I<dir> Directory to search for includes

View File

@ -648,6 +648,15 @@ Summary:
a newline and exit immediately. This can be useful in makefiles. See
also :vlopt:`-V`, and the various :file:`*.mk` files.
.. option:: --get-supported <feature>
If the given feature is supported, print "1" and exit
immediately. Otherwise, print a newline and exit immediately. This can
be useful in makefiles. See also :vlopt:`-V`, and the various
:file:`*.mk` files.
Feature may be one of the following: COROUTINES, SYSTEMC.
.. option:: --help
Displays this message and program version and exits.

View File

@ -39,30 +39,12 @@ ifneq ($(CMAKE_GT_3_8),true)
TARGET := oldcmake
else
# Test existence of SYSTEMC_INCLUDE and SYSTEMC_LIBDIR environment variabless
ifneq (,$(SYSTEMC_INCLUDE))
ifneq (,${SYSTEMC_LIBDIR})
SYSTEMC_SET := true
endif
endif
# Test existence of SYSTEMC_ROOT environment variable
ifneq (SYSTEMC_SET, true)
ifneq (,${SYSTEMC_ROOT})
SYSTEMC_SET := true
endif
endif
# Test existence of SYSTEMC environment variable
ifneq (SYSTEMC_SET, true)
ifneq (,${SYSTEMC})
SYSTEMC_SET := true
endif
endif
# Check if SC exists via a verilator call (empty if not)
SYSTEMC_EXISTS := $(shell $(VERILATOR) --get-supported SYSTEMC)
# Test whether SystemC is installed with CMake support
# This will print a CMake error about processing arguments that can (currently) be ignored.
ifneq (SYSTEMC_SET, true)
ifneq (,$(SYSTEMC_EXISTS))
FINDSC := $(shell mkdir -p build && cd build && cmake --find-package -DNAME=SystemCLanguage -DCMAKE_USE_PTHREADS_INIT=ON -DCOMPILER_ID=GNU -DLANGUAGE=CXX -DMODE=EXIST -DThreads_FOUND=ON)
ifneq (,$(findstring SystemCLanguage found,$(FINDSC)))
SYSTEMC_SET := true

View File

@ -39,30 +39,12 @@ ifneq ($(CMAKE_GT_3_8),true)
TARGET := oldcmake
else
# Test existence of SYSTEMC_INCLUDE and SYSTEMC_LIBDIR environment variabless
ifneq (,$(SYSTEMC_INCLUDE))
ifneq (,${SYSTEMC_LIBDIR})
SYSTEMC_SET := true
endif
endif
# Test existence of SYSTEMC_ROOT environment variable
ifneq (SYSTEMC_SET, true)
ifneq (,${SYSTEMC_ROOT})
SYSTEMC_SET := true
endif
endif
# Test existence of SYSTEMC environment variable
ifneq (SYSTEMC_SET, true)
ifneq (,${SYSTEMC})
SYSTEMC_SET := true
endif
endif
# Check if SC exists via a verilator call (empty if not)
SYSTEMC_EXISTS := $(shell $(VERILATOR) --get-supported SYSTEMC)
# Test whether SystemC is installed with CMake support
# This will print a CMake error about processing arguments that can (currently) be ignored.
ifneq (SYSTEMC_SET, true)
ifneq (,$(SYSTEMC_EXISTS))
FINDSC := $(shell mkdir -p build && cd build && cmake --find-package -DNAME=SystemCLanguage -DCMAKE_USE_PTHREADS_INIT=ON -DCOMPILER_ID=GNU -DLANGUAGE=CXX -DMODE=EXIST -DThreads_FOUND=ON)
ifneq (,$(findstring SystemCLanguage found,$(FINDSC)))
SYSTEMC_SET := true

View File

@ -33,7 +33,7 @@ VERILATOR = $(VERILATOR_ROOT)/bin/verilator
endif
# Check if SC exists via a verilator call (empty if not)
SYSTEMC_EXISTS := $(shell $(VERILATOR) --getenv SYSTEMC_INCLUDE)
SYSTEMC_EXISTS := $(shell $(VERILATOR) --get-supported SYSTEMC)
ifneq ($(SYSTEMC_EXISTS),)
default: run

View File

@ -55,7 +55,7 @@ VERILATOR_FLAGS += --coverage
VERILATOR_INPUT = -f input.vc top.v sc_main.cpp
# Check if SC exists via a verilator call (empty if not)
SYSTEMC_EXISTS := $(shell $(VERILATOR) --getenv SYSTEMC_INCLUDE)
SYSTEMC_EXISTS := $(shell $(VERILATOR) --get-supported SYSTEMC)
######################################################################

View File

@ -604,6 +604,7 @@ V3LangCode V3Options::fileLanguage(const string& filename) {
// Environment
string V3Options::getenvBuiltins(const string& var) {
// If update below, also update V3Options::showVersion()
if (var == "MAKE") {
return getenvMAKE();
} else if (var == "PERL") {
@ -711,6 +712,17 @@ string V3Options::getenvVERILATOR_ROOT() {
return var;
}
string V3Options::getSupported(const string& var) {
// If update below, also update V3Options::showVersion()
if (var == "COROUTINES" && coroutineSupport()) {
return "1";
} else if (var == "SYSTEMC" && systemCFound()) {
return "1";
} else {
return "";
}
}
bool V3Options::systemCSystemWide() {
#ifdef HAVE_SYSTEMC
return true;
@ -1179,6 +1191,10 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
cout << V3Options::getenvBuiltins(valp) << endl;
std::exit(0);
});
DECL_OPTION("-get-supported", CbVal, [](const char* valp) {
cout << V3Options::getSupported(valp) << endl;
std::exit(0);
});
DECL_OPTION("-hierarchical", OnOff, &m_hierarchical);
DECL_OPTION("-hierarchical-block", CbVal, [this](const char* valp) {
@ -1800,6 +1816,7 @@ void V3Options::showVersion(bool verbose) {
cout << " VERILATOR_ROOT = " << DEFENV_VERILATOR_ROOT << endl;
cout << " SystemC system-wide = " << cvtToStr(systemCSystemWide()) << endl;
// If update below, also update V3Options::getenvBuiltins()
cout << endl;
cout << "Environment:\n";
cout << " MAKE = " << V3Os::getenvStr("MAKE", "") << endl;
@ -1812,10 +1829,11 @@ void V3Options::showVersion(bool verbose) {
cout << " VERILATOR_BIN = " << V3Os::getenvStr("VERILATOR_BIN", "") << endl;
cout << " VERILATOR_ROOT = " << V3Os::getenvStr("VERILATOR_ROOT", "") << endl;
// If update below, also update V3Options::getSupported()
cout << endl;
cout << "Features (based on environment or compiled-in support):\n";
cout << " SystemC found = " << cvtToStr(systemCFound()) << endl;
cout << " Coroutine support = " << cvtToStr(coroutineSupport()) << endl;
cout << "Supported features (compiled-in or forced by environment):\n";
cout << " COROUTINES = " << getSupported("COROUTINES") << endl;
cout << " SYSTEMC = " << getSupported("SYSTEMC") << endl;
}
//======================================================================

View File

@ -666,6 +666,7 @@ public:
static string getenvSYSTEMC_INCLUDE();
static string getenvSYSTEMC_LIBDIR();
static string getenvVERILATOR_ROOT();
static string getSupported(const string& var);
static bool systemCSystemWide();
static bool systemCFound(); // SystemC installed, or environment points to it
static bool coroutineSupport(); // Compiler supports coroutines

View File

@ -1476,13 +1476,13 @@ sub sc {
sub have_sc {
my $self = (ref $_[0] ? shift : $Self);
return 1 if (defined $ENV{SYSTEMC} || defined $ENV{SYSTEMC_INCLUDE} || $ENV{CFG_HAVE_SYSTEMC});
return 1 if $self->verilator_version =~ /systemc found *= *1/i;
return 1 if $self->verilator_get_supported('SYSTEMC');
return 0;
}
sub have_coroutines {
my $self = (ref $_[0] ? shift : $Self);
return 1 if $self->verilator_version =~ /coroutine support *= *1/i;
return 1 if $self->verilator_get_supported('COROUTINES');
return 0;
}
@ -2162,17 +2162,20 @@ sub _read_inputs_vhdl {
#######################################################################
# Verilator utilities
our $_Verilator_Version;
sub verilator_version {
# Returns verbose version, line 1 contains actual version
if (!defined $_Verilator_Version) {
my @args = ("perl", "$ENV{VERILATOR_ROOT}/bin/verilator", "-V");
our %_Verilator_Supported;
sub verilator_get_supported {
my $self = (ref $_[0] ? shift : $Self);
my $feature = shift;
# Returns if given feature is supported
if (!defined $_Verilator_Supported{$feature}) {
my @args = ("perl", "$ENV{VERILATOR_ROOT}/bin/verilator", "-get-supported", $feature);
my $args = join(' ', @args);
$_Verilator_Version = `$args`;
$_Verilator_Version or die "can't fork: $! " . join(' ', @args);
chomp $_Verilator_Version;
my $out = `$args`;
$out or die "couldn't run: $! " . join(' ', @args);
chomp $out;
$_Verilator_Supported{$feature} = ($out =~ /1/ ? 1 : 0);
}
return $_Verilator_Version if defined $_Verilator_Version;
return $_Verilator_Supported{$feature};
}
#######################################################################

View File

@ -0,0 +1,42 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2008 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
scenarios(vlt => 1);
if ($Self->have_coroutines) {
run(
cmd => ["../bin/verilator --get-supported COROUTINES"],
expect => '1
',
logfile => "$Self->{obj_dir}/vlt_coroutines.log",
verilator_run => 1,
);
}
if ($Self->have_sc) {
run(
cmd => ["../bin/verilator --get-supported SYSTEMC"],
expect => '1
',
logfile => "$Self->{obj_dir}/vlt_systemc.log",
verilator_run => 1,
);
}
run(
cmd => ["../bin/verilator --get-supported DOES_NOT_EXIST"],
expect => '',
logfile => "$Self->{obj_dir}/vlt_does_not_exist.log",
verilator_run => 1,
);
ok(1);
1;