Add -CFLAGS, -LDFLAGS, <file>.a, <file>.o, and <file>.so options.

This commit is contained in:
Wilson Snyder 2010-01-28 19:33:02 -05:00
parent a51e95d052
commit c49e0ac5c8
11 changed files with 260 additions and 46 deletions

View File

@ -43,6 +43,8 @@ indicates the contributor was also the author of the fix; Thanks!
*** Add experimental config files to filter warnings outside of the source. *** Add experimental config files to filter warnings outside of the source.
*** Add -CFLAGS, -LDFLAGS, <file>.a, <file>.o, and <file>.so options.
*** Speed compiles by avoiding including the STL iostream header. *** Speed compiles by avoiding including the STL iostream header.
Application programs may need to include it themselves to avoid errors. Application programs may need to include it themselves to avoid errors.

View File

@ -156,9 +156,9 @@ Verilator - Convert Verilog code to C++/SystemC
verilator --help verilator --help
verilator --version verilator --version
verilator --cc [options] [top_level.v] [opt_c_files.cpp/c/cc] verilator --cc [options] [top_level.v] [opt_c_files.cpp/c/cc/a/o/so]
verilator --sc [options] [top_level.v] [opt_c_files.cpp/c/cc] verilator --sc [options] [top_level.v] [opt_c_files.cpp/c/cc/a/o/so]
verilator --sp [options] [top_level.v] [opt_c_files.cpp/c/cc] verilator --sp [options] [top_level.v] [opt_c_files.cpp/c/cc/a/o/so]
verilator --lint-only ... verilator --lint-only ...
=head1 DESCRIPTION =head1 DESCRIPTION
@ -197,6 +197,7 @@ descriptions in the next sections for more information.
--bbox-sys Blackbox unknown $system calls --bbox-sys Blackbox unknown $system calls
--bbox-unsup Blackbox unsupported language features --bbox-unsup Blackbox unsupported language features
--bin <filename> Override Verilator binary --bin <filename> Override Verilator binary
-CFLAGS <flags> C++ Compiler flags for makefile
--cc Create C++ output --cc Create C++ output
--cdc Clock domain crossing analysis --cdc Clock domain crossing analysis
--compiler <compiler-name> Tune for specified C++ compiler --compiler <compiler-name> Tune for specified C++ compiler
@ -218,6 +219,8 @@ descriptions in the next sections for more information.
-I<dir> Directory to search for includes -I<dir> Directory to search for includes
--inhibit-sim Create function to turn off sim --inhibit-sim Create function to turn off sim
--inline-mult <value> Tune module inlining --inline-mult <value> Tune module inlining
-LDFLAGS <flags> Linker pre-object flags for makefile
-LDLIBS <flags> Linker library flags for makefile
--language <lang> Language standard to parse --language <lang> Language standard to parse
--lint-only Lint, but do not make output --lint-only Lint, but do not make output
--MMD Create .d dependency files --MMD Create .d dependency files
@ -277,7 +280,15 @@ Specifies optional C++ files to be linked in with the Verilog code. If any
C++ files are specified in this way, Verilator will include a make rule C++ files are specified in this way, Verilator will include a make rule
that generates a I<module> executable. Without any C++ files, Verilator that generates a I<module> executable. Without any C++ files, Verilator
will stop at the I<module>__ALL.a library, and presume you'll continue will stop at the I<module>__ALL.a library, and presume you'll continue
linking with make rules you write yourself. linking with make rules you write yourself. See also the -CFLAGS option.
=item {file.a/.o/.so}
Specifies optional object or library files to be linked in with the Verilog
code, as a shorthand for -LDFLAGS "<file>". If any files are specified in
this way, Verilator will include a make rule that uses these files when
linking the I<module> executable. This generally is only useful when used
with the --exe option.
=item --assert =item --assert
@ -313,6 +324,12 @@ dependency (.d) file is created, this filename will become a source
dependency, such that a change in this binary will have make rebuild the dependency, such that a change in this binary will have make rebuild the
output files. output files.
=item -CFLAGS I<flags>
Add specified C compiler flags to the generated makefiles. When make is
run on the generated makefile these will be passed to the C++ compiler
(gcc/g++/msvc++).
=item --cc =item --cc
Specifies C++ without SystemC output mode; see also --sc and --sp. Specifies C++ without SystemC output mode; see also --sc and --sp.
@ -476,6 +493,16 @@ values, or a value <= 1 will inline everything, will lead to longer compile
times, but potentially faster runtimes. This setting is ignored for very times, but potentially faster runtimes. This setting is ignored for very
small modules; they will always be inlined, if allowed. small modules; they will always be inlined, if allowed.
=item -LDFLAGS I<flags>
Add specified C linker flags to the generated makefiles. When make is run
on the generated makefile these will be passed to the C++ linker (ld)
*after* the primary file being linked. This flag is called -LDFLAGS as
that's the traditional name in simulators; it's would have been better
called LDLIBS as that's the Makefile variable it controls. (In Make,
LDFLAGS is before the first object, LDLIBS after. -L libraries need to be
in the Make variable LDLIBS, not LDFLAGS.)
=item --language I<value> =item --language I<value>
Select the language to be used when first processing each Verilog file. Select the language to be used when first processing each Verilog file.

View File

@ -151,8 +151,23 @@ public:
of.puts("# Module prefix (from --prefix)\n"); of.puts("# Module prefix (from --prefix)\n");
of.puts(string("VM_MODPREFIX = ")+v3Global.opt.modPrefix()+"\n"); of.puts(string("VM_MODPREFIX = ")+v3Global.opt.modPrefix()+"\n");
V3StringSet dirs; of.puts("# User CFLAGS (from -CFLAGS on Verilator command line)\n");
of.puts("VM_USER_CFLAGS = \\\n");
for (V3StringSet::const_iterator it = v3Global.opt.cFlags().begin();
it != v3Global.opt.cFlags().end(); ++it) {
of.puts("\t"+*it+" \\\n");
}
of.puts("\n");
of.puts("# User LDLIBS (from -LDFLAGS on Verilator command line)\n");
of.puts("VM_USER_LDLIBS = \\\n");
for (V3StringSet::const_iterator it = v3Global.opt.ldLibs().begin();
it != v3Global.opt.ldLibs().end(); ++it) {
of.puts("\t"+*it+" \\\n");
}
of.puts("\n");
V3StringSet dirs;
of.puts("# User .cpp files (from .cpp's on Verilator command line)\n"); of.puts("# User .cpp files (from .cpp's on Verilator command line)\n");
of.puts("VM_USER_CLASSES = \\\n"); of.puts("VM_USER_CLASSES = \\\n");
for (V3StringSet::const_iterator it = v3Global.opt.cppFiles().begin(); for (V3StringSet::const_iterator it = v3Global.opt.cppFiles().begin();

View File

@ -97,6 +97,16 @@ void V3Options::addCppFile(const string& filename) {
m_cppFiles.insert(filename); m_cppFiles.insert(filename);
} }
} }
void V3Options::addCFlags(const string& filename) {
if (m_cFlags.find(filename) == m_cFlags.end()) {
m_cFlags.insert(filename);
}
}
void V3Options::addLdLibs(const string& filename) {
if (m_ldLibs.find(filename) == m_ldLibs.end()) {
m_ldLibs.insert(filename);
}
}
void V3Options::addFuture(const string& flag) { void V3Options::addFuture(const string& flag) {
if (m_futures.find(flag) == m_futures.end()) { if (m_futures.find(flag) == m_futures.end()) {
m_futures.insert(flag); m_futures.insert(flag);
@ -538,6 +548,11 @@ bool V3Options::onoff(const char* sw, const char* arg, bool& flag) {
return false; return false;
} }
bool V3Options::suffixed(const char* sw, const char* arg) {
if (strlen(arg) > strlen(sw)) return false;
return (0==strcmp(sw+strlen(sw)-strlen(arg), arg));
}
void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) { void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
// Parse parameters // Parse parameters
// Note argc and argv DO NOT INCLUDE the filename in [0]!!! // Note argc and argv DO NOT INCLUDE the filename in [0]!!!
@ -717,12 +732,20 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
} }
} }
// Parameterized switches // Parameterized switches
else if ( !strcmp (sw, "-CFLAGS") && (i+1)<argc ) {
shift;
addCFlags(argv[i]);
}
else if ( !strncmp (sw, "-D", 2)) { else if ( !strncmp (sw, "-D", 2)) {
addDefine (string (sw+strlen("-D"))); addDefine (string (sw+strlen("-D")));
} }
else if ( !strncmp (sw, "-I", 2)) { else if ( !strncmp (sw, "-I", 2)) {
addIncDir (string (sw+strlen("-I"))); addIncDir (string (sw+strlen("-I")));
} }
else if ( !strcmp (sw, "-LDFLAGS") && (i+1)<argc ) {
shift;
addLdLibs(argv[i]);
}
else if ( !strcmp (sw, "-Mdir") && (i+1)<argc ) { else if ( !strcmp (sw, "-Mdir") && (i+1)<argc ) {
shift; m_makeDir = argv[i]; shift; m_makeDir = argv[i];
addIncDir (string (m_makeDir)); // Need to find generated files there too addIncDir (string (m_makeDir)); // Need to find generated files there too
@ -829,12 +852,18 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
else { else {
// Filename // Filename
string filename = filenameSubstitute(argv[i]); string filename = filenameSubstitute(argv[i]);
if (filename.find(".cpp") != string::npos if (suffixed(filename.c_str(), ".cpp")
|| filename.find(".cxx") != string::npos || suffixed(filename.c_str(), ".cxx")
|| filename.find(".cc") != string::npos || suffixed(filename.c_str(), ".cc")
|| filename.find(".sp") != string::npos) { || suffixed(filename.c_str(), ".sp")) {
V3Options::addCppFile(filename); V3Options::addCppFile(filename);
} else { }
else if (suffixed(filename.c_str(), ".a")
|| suffixed(filename.c_str(), ".o")
|| suffixed(filename.c_str(), ".so")) {
V3Options::addLdLibs(filename);
}
else {
V3Options::addVFile(filename); V3Options::addVFile(filename);
} }
shift; shift;

View File

@ -86,6 +86,8 @@ class V3Options {
V3OptionsImp* m_impp; // Slow hidden options V3OptionsImp* m_impp; // Slow hidden options
V3StringSet m_cppFiles; // argument: C++ files to link against V3StringSet m_cppFiles; // argument: C++ files to link against
V3StringSet m_cFlags; // argument: user CFLAGS
V3StringSet m_ldLibs; // argument: user LDFLAGS
V3StringSet m_futures; // argument: -Wfuture- list V3StringSet m_futures; // argument: -Wfuture- list
V3StringSet m_libraryFiles; // argument: Verilog -v files V3StringSet m_libraryFiles; // argument: Verilog -v files
V3StringList m_vFiles; // argument: Verilog files to read V3StringList m_vFiles; // argument: Verilog files to read
@ -176,6 +178,7 @@ class V3Options {
void showVersion(bool verbose); void showVersion(bool verbose);
void coverage(bool flag) { m_coverageLine = m_coverageToggle = m_coverageUser = flag; } void coverage(bool flag) { m_coverageLine = m_coverageToggle = m_coverageUser = flag; }
bool onoff(const char* sw, const char* arg, bool& flag); bool onoff(const char* sw, const char* arg, bool& flag);
bool suffixed(const char* sw, const char* arg);
static bool wildmatchi(const char* s, const char* p); static bool wildmatchi(const char* s, const char* p);
static string getenvStr(const string& envvar, const string& defaultValue); static string getenvStr(const string& envvar, const string& defaultValue);
@ -192,6 +195,8 @@ class V3Options {
// METHODS // METHODS
void addCppFile(const string& filename); void addCppFile(const string& filename);
void addCFlags(const string& filename);
void addLdLibs(const string& filename);
void addLibraryFile(const string& filename); void addLibraryFile(const string& filename);
void addVFile(const string& filename); void addVFile(const string& filename);
@ -254,6 +259,8 @@ class V3Options {
string xAssign() const { return m_xAssign; } string xAssign() const { return m_xAssign; }
const V3StringSet& cppFiles() const { return m_cppFiles; } const V3StringSet& cppFiles() const { return m_cppFiles; }
const V3StringSet& cFlags() const { return m_cFlags; }
const V3StringSet& ldLibs() const { return m_ldLibs; }
const V3StringSet& libraryFiles() const { return m_libraryFiles; } const V3StringSet& libraryFiles() const { return m_libraryFiles; }
const V3StringList& vFiles() const { return m_vFiles; } const V3StringList& vFiles() const { return m_vFiles; }
const V3LangCode& language() const { return m_language; } const V3LangCode& language() const { return m_language; }

View File

@ -247,6 +247,7 @@ sub new {
make_main => 1, # Make __main.cpp make_main => 1, # Make __main.cpp
sim_time => 1100, sim_time => 1100,
benchmark => $opt_benchmark, benchmark => $opt_benchmark,
run_env => '',
# All compilers # All compilers
v_flags => [split(/\s+/,(" -f input.vc " v_flags => [split(/\s+/,(" -f input.vc "
.($opt_verbose ? " +define+TEST_VERBOSE=1":"") .($opt_verbose ? " +define+TEST_VERBOSE=1":"")
@ -502,10 +503,14 @@ sub execute {
return 1 if $self->errors; return 1 if $self->errors;
my %param = (%{$self}, @_); # Default arguments are from $self my %param = (%{$self}, @_); # Default arguments are from $self
$self->oprint("Run\n"); $self->oprint("Run\n");
my $run_env = $param{run_env};
$run_env .= ' ' if $run_env;
if ($param{iv}) { if ($param{iv}) {
$self->_run(logfile=>"$self->{obj_dir}/iv_sim.log", $self->_run(logfile=>"$self->{obj_dir}/iv_sim.log",
fails=>$param{fails}, fails=>$param{fails},
cmd=>["$self->{obj_dir}/simiv", cmd=>[$run_env."$self->{obj_dir}/simiv",
@{$param{ivrun_flags}}, @{$param{ivrun_flags}},
@{$param{all_run_flags}}, @{$param{all_run_flags}},
]); ]);
@ -513,7 +518,7 @@ sub execute {
if ($param{nc}) { if ($param{nc}) {
$self->_run(logfile=>"$self->{obj_dir}/nc_sim.log", $self->_run(logfile=>"$self->{obj_dir}/nc_sim.log",
fails=>$param{fails}, fails=>$param{fails},
cmd=>[($ENV{VERILATOR_NCVERILOG}||"ncverilog"), cmd=>[$run_env.($ENV{VERILATOR_NCVERILOG}||"ncverilog"),
@{$param{ncrun_flags}}, @{$param{ncrun_flags}},
@{$param{all_run_flags}}, @{$param{all_run_flags}},
]); ]);
@ -522,7 +527,7 @@ sub execute {
#my $fh = IO::File->new(">simv.key") or die "%Error: $! simv.key,"; #my $fh = IO::File->new(">simv.key") or die "%Error: $! simv.key,";
#$fh->print("quit\n"); $fh->close; #$fh->print("quit\n"); $fh->close;
$self->_run(logfile=>"$self->{obj_dir}/vcs_sim.log", $self->_run(logfile=>"$self->{obj_dir}/vcs_sim.log",
cmd=>["./simv", cmd=>[$run_env."./simv",
@{$param{all_run_flags}}, @{$param{all_run_flags}},
], ],
%param, %param,
@ -533,7 +538,8 @@ sub execute {
#&& (!$param{needs_v4} || -r "$ENV{VERILATOR_ROOT}/src/V3Gate.cpp") #&& (!$param{needs_v4} || -r "$ENV{VERILATOR_ROOT}/src/V3Gate.cpp")
) { ) {
$self->_run(logfile=>"$self->{obj_dir}/vlt_sim.log", $self->_run(logfile=>"$self->{obj_dir}/vlt_sim.log",
cmd=>[(($opt_gdbsim ? "gdbrun ":"") cmd=>[($run_env
.($opt_gdbsim ? "gdbrun ":"")
."$self->{obj_dir}/$param{VM_PREFIX}"), ."$self->{obj_dir}/$param{VM_PREFIX}"),
@{$param{all_run_flags}}, @{$param{all_run_flags}},
], ],
@ -666,44 +672,46 @@ sub _run {
return if $self->errors; return if $self->errors;
# Read the log file a couple of times to allow for NFS delays # Read the log file a couple of times to allow for NFS delays
for (my $try=7; $try>=0; $try--) { if ($param{check_finished} || $param{expect}) {
sleep 1 if ($try!=7); for (my $try=7; $try>=0; $try--) {
my $moretry = $try!=0; sleep 1 if ($try!=7);
my $moretry = $try!=0;
my $fh = IO::File->new("<$param{logfile}"); my $fh = IO::File->new("<$param{logfile}");
next if !$fh && $moretry; next if !$fh && $moretry;
local $/; undef $/; local $/; undef $/;
my $wholefile = <$fh>; my $wholefile = <$fh>;
$fh->close(); $fh->close();
# Strip debugging comments # Strip debugging comments
$wholefile =~ s/^- [^\n]+\n//mig; $wholefile =~ s/^- [^\n]+\n//mig;
$wholefile =~ s/^- [a-z.0-9]+:\d+:[^\n]+\n//mig; $wholefile =~ s/^- [a-z.0-9]+:\d+:[^\n]+\n//mig;
$wholefile =~ s/^dot [^\n]+\n//mig; $wholefile =~ s/^dot [^\n]+\n//mig;
# Finished? # Finished?
if ($param{check_finished} && $wholefile !~ /\*\-\* All Finished \*\-\*/) { if ($param{check_finished} && $wholefile !~ /\*\-\* All Finished \*\-\*/) {
next if $moretry;
$self->error("Missing All Finished\n");
}
if ($param{expect}) {
# Compare
my $quoted = quotemeta ($param{expect});
my $bad = ($wholefile !~ /$param{expect}/ms
&& $wholefile !~ /$quoted/ms);
if ($bad) {
#print "**BAD $self->{name} $param{logfile} MT $moretry $try\n";
next if $moretry; next if $moretry;
$self->error("Mismatch in output from $param{cmd}[0]\n"); $self->error("Missing All Finished\n");
print "GOT:\n";
print $wholefile;
print "ENDGOT\n";
print "EXPECT:\n";
print $param{expect};
print "ENDEXPECT\n";
} }
if ($param{expect}) {
# Compare
my $quoted = quotemeta ($param{expect});
my $bad = ($wholefile !~ /$param{expect}/ms
&& $wholefile !~ /$quoted/ms);
if ($bad) {
#print "**BAD $self->{name} $param{logfile} MT $moretry $try\n";
next if $moretry;
$self->error("Mismatch in output from $param{cmd}[0]\n");
print "GOT:\n";
print $wholefile;
print "ENDGOT\n";
print "EXPECT:\n";
print $param{expect};
print "ENDEXPECT\n";
}
}
last;
} }
last;
} }
} }

View File

@ -0,0 +1,34 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 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.
$Self->_run (cmd=>["cd $Self->{obj_dir}"
." && g++ -c ../../t/t_flag_ldflags_a.cpp"
." && ar r t_flag_ldflags_a.a t_flag_ldflags_a.o"
." && ranlib t_flag_ldflags_a.a "],
check_finished=>0);
$Self->_run (cmd=>["cd $Self->{obj_dir}"
." && g++ -fPIC -c ../../t/t_flag_ldflags_so.cpp"
." && ld -shared -o t_flag_ldflags_so.so -lc t_flag_ldflags_so.o"],
check_finished=>0);
compile (
# Pass multiple -D's so we check quoting works properly
v_flags2 => ["-CFLAGS '-DCFLAGS_FROM_CMDLINE -DCFLAGS2_FROM_CMDLINE' ",
"t/t_flag_ldflags_c.cpp",
"t_flag_ldflags_a.a",
"t_flag_ldflags_so.so",],
);
execute (
check_finished=>1,
run_env => "LD_LIBRARY_PATH=$Self->{obj_dir}",
);
ok(1);
1;

View File

@ -0,0 +1,20 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// Copyright 2010 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.
import "DPI-C" pure function void dpii_a_library();
import "DPI-C" pure function void dpii_c_library();
import "DPI-C" pure function void dpii_so_library();
module t ();
initial begin
dpii_a_library(); // From .a file
dpii_c_library(); // From .cpp file
dpii_so_library(); // From .so file
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -0,0 +1,18 @@
// -*- C++ -*-
//*************************************************************************
//
// Copyright 2010-2010 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.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
extern "C" {
void dpii_a_library() {}
};

View File

@ -0,0 +1,36 @@
// -*- C++ -*-
//*************************************************************************
//
// Copyright 2010-2010 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.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
#include <cstdio>
#include <svdpi.h>
//======================================================================
#if defined(VERILATOR)
# include "Vt_flag_ldflags__Dpi.h"
#else
# error "Unknown simulator for DPI test"
#endif
//======================================================================
#ifndef CFLAGS_FROM_CMDLINE
# error "CFLAGS_FROM_CMDLINE not set - not passed down?"
#endif
#ifndef CFLAGS2_FROM_CMDLINE
# error "CFLAGS2_FROM_CMDLINE not set - not passed down?"
#endif
void dpii_c_library() {}

View File

@ -0,0 +1,18 @@
// -*- C++ -*-
//*************************************************************************
//
// Copyright 2010-2010 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.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
extern "C" {
void dpii_so_library() {}
};