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 -CFLAGS, -LDFLAGS, <file>.a, <file>.o, and <file>.so options.
*** Speed compiles by avoiding including the STL iostream header.
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 --version
verilator --cc [options] [top_level.v] [opt_c_files.cpp/c/cc]
verilator --sc [options] [top_level.v] [opt_c_files.cpp/c/cc]
verilator --sp [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/a/o/so]
verilator --sp [options] [top_level.v] [opt_c_files.cpp/c/cc/a/o/so]
verilator --lint-only ...
=head1 DESCRIPTION
@ -197,6 +197,7 @@ descriptions in the next sections for more information.
--bbox-sys Blackbox unknown $system calls
--bbox-unsup Blackbox unsupported language features
--bin <filename> Override Verilator binary
-CFLAGS <flags> C++ Compiler flags for makefile
--cc Create C++ output
--cdc Clock domain crossing analysis
--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
--inhibit-sim Create function to turn off sim
--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
--lint-only Lint, but do not make output
--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
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
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
@ -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
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
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
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>
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(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("VM_USER_CLASSES = \\\n");
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);
}
}
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) {
if (m_futures.find(flag) == m_futures.end()) {
m_futures.insert(flag);
@ -538,6 +548,11 @@ bool V3Options::onoff(const char* sw, const char* arg, bool& flag) {
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) {
// Parse parameters
// 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
else if ( !strcmp (sw, "-CFLAGS") && (i+1)<argc ) {
shift;
addCFlags(argv[i]);
}
else if ( !strncmp (sw, "-D", 2)) {
addDefine (string (sw+strlen("-D")));
}
else if ( !strncmp (sw, "-I", 2)) {
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 ) {
shift; m_makeDir = argv[i];
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 {
// Filename
string filename = filenameSubstitute(argv[i]);
if (filename.find(".cpp") != string::npos
|| filename.find(".cxx") != string::npos
|| filename.find(".cc") != string::npos
|| filename.find(".sp") != string::npos) {
if (suffixed(filename.c_str(), ".cpp")
|| suffixed(filename.c_str(), ".cxx")
|| suffixed(filename.c_str(), ".cc")
|| suffixed(filename.c_str(), ".sp")) {
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);
}
shift;

View File

@ -86,6 +86,8 @@ class V3Options {
V3OptionsImp* m_impp; // Slow hidden options
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_libraryFiles; // argument: Verilog -v files
V3StringList m_vFiles; // argument: Verilog files to read
@ -176,6 +178,7 @@ class V3Options {
void showVersion(bool verbose);
void coverage(bool flag) { m_coverageLine = m_coverageToggle = m_coverageUser = 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 string getenvStr(const string& envvar, const string& defaultValue);
@ -192,6 +195,8 @@ class V3Options {
// METHODS
void addCppFile(const string& filename);
void addCFlags(const string& filename);
void addLdLibs(const string& filename);
void addLibraryFile(const string& filename);
void addVFile(const string& filename);
@ -254,6 +259,8 @@ class V3Options {
string xAssign() const { return m_xAssign; }
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 V3StringList& vFiles() const { return m_vFiles; }
const V3LangCode& language() const { return m_language; }

View File

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