diff --git a/src/V3EmitCMake.cpp b/src/V3EmitCMake.cpp index 8139cd418..d244469d1 100644 --- a/src/V3EmitCMake.cpp +++ b/src/V3EmitCMake.cpp @@ -229,6 +229,8 @@ class CMakeEmitter { *of << deslash(" ${CMAKE_CURRENT_BINARY_DIR}/" + (*child)->hierWrapper(true)); } *of << " "; + const string vFile = hblockp->vFileIfNecessary(); + if (!vFile.empty()) *of << vFile << " "; const V3StringList& vFiles = v3Global.opt.vFiles(); for (const string& i : vFiles) *of << V3Os::filenameRealPath(i); *of << " VERILATOR_ARGS "; diff --git a/src/V3HierBlock.cpp b/src/V3HierBlock.cpp index 59adf8211..ae1bb1f86 100644 --- a/src/V3HierBlock.cpp +++ b/src/V3HierBlock.cpp @@ -80,6 +80,7 @@ #include "V3Error.h" #include "V3File.h" #include "V3HierBlock.h" +#include "V3Os.h" #include "V3String.h" #include "V3Stats.h" @@ -88,13 +89,18 @@ static string V3HierCommandArgsFileName(const string& prefix, bool forCMake) { + (forCMake ? "_hierCMakeArgs.f" : "_hierMkArgs.f"); } -static void V3HierWriteCommonInputs(std::ostream* of, bool forCMake) { +static void V3HierWriteCommonInputs(const V3HierBlock* hblockp, std::ostream* of, bool forCMake) { + string topModuleFile; + if (hblockp) topModuleFile = hblockp->vFileIfNecessary(); if (!forCMake) { + if (!topModuleFile.empty()) *of << topModuleFile << "\n"; const V3StringList& vFiles = v3Global.opt.vFiles(); for (const string& i : vFiles) *of << i << "\n"; } const V3StringSet& libraryFiles = v3Global.opt.libraryFiles(); - for (const string& i : libraryFiles) *of << "-v " << i << "\n"; + for (const string& i : libraryFiles) { + if (V3Os::filenameRealPath(i) != topModuleFile) *of << "-v " << i << "\n"; + } } //###################################################################### @@ -194,6 +200,15 @@ string V3HierBlock::hierGenerated(bool withDir) const { return hierWrapper(withDir) + ' ' + hierMk(withDir); } +string V3HierBlock::vFileIfNecessary() const { + const string filename = V3Os::filenameRealPath(m_modp->fileline()->filename()); + for (const string v : v3Global.opt.vFiles()) { + // Already listed in vFiles, so no need to add the file. + if (filename == V3Os::filenameRealPath(v)) return ""; + } + return filename; +} + void V3HierBlock::writeCommandArgsFile(bool forCMake) const { std::unique_ptr of(V3File::new_ofstream(commandArgsFileName(forCMake))); *of << "--cc\n"; @@ -205,7 +220,7 @@ void V3HierBlock::writeCommandArgsFile(bool forCMake) const { } } *of << "-Mdir " << v3Global.opt.makeDir() << "/" << hierPrefix() << " \n"; - V3HierWriteCommonInputs(of.get(), forCMake); + V3HierWriteCommonInputs(this, of.get(), forCMake); const V3StringList& commandOpts = commandArgs(false); for (const string& opt : commandOpts) *of << opt << "\n"; *of << hierBlockArgs().front() << "\n"; @@ -394,7 +409,7 @@ void V3HierBlockPlan::writeCommandArgsFiles(bool forCMake) const { *of << it->second->hierWrapper(true) << "\n"; } } - V3HierWriteCommonInputs(of.get(), forCMake); + V3HierWriteCommonInputs(nullptr, of.get(), forCMake); if (!forCMake) { const V3StringSet& cppFiles = v3Global.opt.cppFiles(); for (const string& i : cppFiles) *of << i << "\n"; diff --git a/src/V3HierBlock.h b/src/V3HierBlock.h index 6bc0ce285..8a04dd3fb 100644 --- a/src/V3HierBlock.h +++ b/src/V3HierBlock.h @@ -85,6 +85,8 @@ public: string hierMk(bool withDir) const; string hierLib(bool withDir) const; string hierGenerated(bool withDir) const; + // Returns the original HDL file if it is not included in v3Global.opt.vFiles(). + string vFileIfNecessary() const; // Write command line argumuents to .f file for this hierarchical block void writeCommandArgsFile(bool forCMake) const; string commandArgsFileName(bool forCMake) const; diff --git a/test_regress/t/t_hier_block_libmod.pl b/test_regress/t/t_hier_block_libmod.pl new file mode 100755 index 000000000..6fcdd000e --- /dev/null +++ b/test_regress/t/t_hier_block_libmod.pl @@ -0,0 +1,23 @@ +#!/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. + +scenarios(vlt_all => 1); + +compile( + verilator_flags2 => ['--hierarchical', + '-y', $Self->{t_dir} . '/t_flag_relinc_dir/chip', + '+incdir+'. $Self->{t_dir} . '/t_flag_relinc_dir/include'], + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_hier_block_libmod.v b/test_regress/t/t_hier_block_libmod.v new file mode 100644 index 000000000..deaeb9fe2 --- /dev/null +++ b/test_regress/t/t_hier_block_libmod.v @@ -0,0 +1,14 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2020 by Yutetsu TAKATSUKASA + +module t; + t_flag_relinc_sub i_t_flag_relinc_sub(); +endmodule + +`ifdef VERILATOR +`verilator_config +hier_block -module "t_flag_relinc_sub" +`verilog +`endif