Improve reusability of --dump-inputs output (#6812)
This commit is contained in:
parent
25f72e4305
commit
47a4f7fb9b
|
|
@ -285,6 +285,15 @@ or "`ifdef`"'s may break other tools.
|
|||
(if appropriate :vlopt:`--coverage` flags are passed) after being
|
||||
disabled earlier with :option:`/*verilator&32;coverage_off*/`.
|
||||
|
||||
.. option:: /*verilator&32;fargs <arguments>*/
|
||||
|
||||
For Verilator developers only. When a source file containing :option:`fargs`
|
||||
metacomments is passed to Verilator on the command line via the :option:`-f`
|
||||
or :option:`-F` option, the provided arguments will be added as if specified
|
||||
on the command line. The source file is not preprocessed before parsing for
|
||||
arguments, and all :option:`fargs` comment will take effect, even if placed
|
||||
undef an inactive :option:`\`ifdef`.
|
||||
|
||||
.. option:: /*verilator&32;forceable*/
|
||||
|
||||
Specifies that the signal (net or variable) should be made forceable from
|
||||
|
|
|
|||
|
|
@ -1769,10 +1769,20 @@ placed into the obj_dir, .vpp, .tree and .dot files.
|
|||
Verilator creates a *{mod_prefix}*\ __inputs.vpp file containing all the
|
||||
files that were read, filtered by preprocessing. This file can be fed back
|
||||
into Verilator, replacing on the command line all of the previous input
|
||||
files, to enable simplification of test cases.
|
||||
files, to enable simplification of test cases. This file also contains most
|
||||
command line arguments Verilator was invoked as `// verilator fargs``
|
||||
metacomments, with and can be parsed by ``-f`. So to reproduce the run that
|
||||
created the file, run:
|
||||
|
||||
::
|
||||
verilator -f <prefix>__inputs.vpp <prefix>__inputs.vpp
|
||||
|
||||
The first `-f <prefix>__inputs.vpp` reads the command line arguments from
|
||||
the file. The second `<prefix>__inputsl.vpp` adds the file as a normal
|
||||
source file.
|
||||
|
||||
Verilator also creates .vpp files for each individual file passed on the
|
||||
command line.
|
||||
command line. These do not contain the command line argument metacomments.
|
||||
|
||||
|
||||
.dot Output
|
||||
|
|
|
|||
|
|
@ -39,14 +39,23 @@ struct V3OptionParser::Impl final {
|
|||
// Base class of actual action classes
|
||||
template <en N_Mode, bool N_Allow_Partial_Match = false>
|
||||
class ActionBase VL_NOT_FINAL : public ActionIfs {
|
||||
bool m_notForRerun = false; // This option is not needed for rerun with --dump-inputs
|
||||
bool m_undocumented = false; // This option is not documented
|
||||
public:
|
||||
bool isValueNeeded() const override final { return N_Mode == en::VALUE; }
|
||||
bool isFOnOffAllowed() const override final { return N_Mode == en::FONOFF; }
|
||||
bool isNotForRerun() const override final { return m_notForRerun; }
|
||||
bool isOnOffAllowed() const override final { return N_Mode == en::ONOFF; }
|
||||
bool isPartialMatchAllowed() const override final { return N_Allow_Partial_Match; }
|
||||
bool isUndocumented() const override { return m_undocumented; }
|
||||
void undocumented() override { m_undocumented = true; }
|
||||
ActionIfs& undocumented() override {
|
||||
m_undocumented = true;
|
||||
return *this;
|
||||
}
|
||||
ActionIfs& notForRerun() override {
|
||||
m_notForRerun = true;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
// Actual action classes
|
||||
|
|
@ -195,20 +204,20 @@ bool V3OptionParser::hasPrefixNo(const char* strp) {
|
|||
return VString::startsWith(strp, "-no");
|
||||
}
|
||||
|
||||
int V3OptionParser::parse(int idx, int argc, char* argv[]) {
|
||||
std::pair<int, bool> V3OptionParser::parse(int idx, int argc, char* argv[]) {
|
||||
UASSERT(m_pimpl->m_isFinalized, "finalize() must be called before parse()");
|
||||
const char* optp = argv[idx];
|
||||
if (optp[0] == '-' && optp[1] == '-') ++optp;
|
||||
ActionIfs* const actp = find(optp);
|
||||
if (!actp) return 0;
|
||||
if (!actp) return {0, false};
|
||||
if (!actp->isValueNeeded()) {
|
||||
actp->exec(optp, nullptr);
|
||||
return 1;
|
||||
return {1, !actp->isNotForRerun()};
|
||||
} else if (idx + 1 < argc) {
|
||||
actp->exec(optp, argv[idx + 1]);
|
||||
return 2;
|
||||
return {2, !actp->isNotForRerun()};
|
||||
}
|
||||
return 0;
|
||||
return {0, false};
|
||||
}
|
||||
|
||||
string V3OptionParser::getSuggestion(const char* str) const {
|
||||
|
|
|
|||
|
|
@ -74,8 +74,9 @@ private:
|
|||
|
||||
public:
|
||||
// METHODS
|
||||
// Returns how many args are consumed. 0 means not match
|
||||
int parse(int idx, int argc, char* argv[]) VL_MT_DISABLED;
|
||||
// Returns how many args are consumed. 0 means not match.
|
||||
// Also bool, true iff option is needed for rerun with --dump-inputs
|
||||
std::pair<int, bool> parse(int idx, int argc, char* argv[]) VL_MT_DISABLED;
|
||||
// Find the most similar option
|
||||
string getSuggestion(const char* str) const VL_MT_DISABLED;
|
||||
void addSuggestionCandidate(const string& s) VL_MT_DISABLED;
|
||||
|
|
@ -93,13 +94,16 @@ public:
|
|||
virtual ~ActionIfs() = default;
|
||||
virtual bool isValueNeeded() const = 0; // Need val of "-opt val"
|
||||
virtual bool isFOnOffAllowed() const = 0; // true if "-fno-opt" is allowed
|
||||
virtual bool isNotForRerun() const = 0; // Will not be dumped with --dump-inputs
|
||||
virtual bool isOnOffAllowed() const = 0; // true if "-no-opt" is allowed
|
||||
virtual bool isPartialMatchAllowed() const = 0; // true if "-Wno-" matches "-Wno-fatal"
|
||||
virtual bool isUndocumented() const = 0; // Will not be suggested in typo
|
||||
// Set a value or run callback
|
||||
virtual void exec(const char* optp, const char* valp) = 0;
|
||||
// Mark this option undocumented. (Exclude this option from suggestion list).
|
||||
virtual void undocumented() = 0;
|
||||
virtual ActionIfs& undocumented() = 0;
|
||||
// Mark this as not needed for rerunning with preprocessed sources
|
||||
virtual ActionIfs& notForRerun() = 0;
|
||||
};
|
||||
|
||||
// A helper class to register options
|
||||
|
|
|
|||
|
|
@ -68,7 +68,8 @@ public:
|
|||
|
||||
// STATE
|
||||
std::list<string> m_lineArgs; // List of command line argument encountered
|
||||
std::list<string> m_allArgs; // List of every argument encountered
|
||||
// List of arguments encounterd, and a bool in needed for rerunning --dump-inputs
|
||||
std::list<std::pair<std::list<std::string>, bool>> m_allArgs;
|
||||
std::list<string> m_incDirUsers; // Include directories (ordered)
|
||||
std::set<string> m_incDirUserSet; // Include directories (for removing duplicates)
|
||||
std::list<string> m_incDirFallbacks; // Include directories (ordered)
|
||||
|
|
@ -398,13 +399,31 @@ void V3Options::addForceInc(const string& filename) { m_forceIncs.push_back(file
|
|||
|
||||
void V3Options::addLineArg(const string& arg) { m_impp->m_lineArgs.push_back(arg); }
|
||||
|
||||
void V3Options::addArg(const string& arg) { m_impp->m_allArgs.push_back(arg); }
|
||||
void V3Options::addArg(char** argv, size_t count, bool isForRerun) {
|
||||
m_impp->m_allArgs.emplace_back();
|
||||
std::pair<std::list<std::string>, bool>& pair = m_impp->m_allArgs.back();
|
||||
pair.second = isForRerun;
|
||||
for (size_t n = 0; n < count; ++n) pair.first.emplace_back(argv[n]);
|
||||
}
|
||||
|
||||
void V3Options::addArg(const std::string& arg, bool isForRerun) {
|
||||
m_impp->m_allArgs.emplace_back();
|
||||
std::pair<std::list<std::string>, bool>& pair = m_impp->m_allArgs.back();
|
||||
pair.second = isForRerun;
|
||||
pair.first.emplace_back(arg);
|
||||
}
|
||||
|
||||
const std::list<std::pair<std::list<std::string>, bool>>& V3Options::allArgs() const {
|
||||
return m_impp->m_allArgs;
|
||||
}
|
||||
|
||||
string V3Options::allArgsString() const VL_MT_SAFE {
|
||||
string result;
|
||||
for (const string& i : m_impp->m_allArgs) {
|
||||
if (result != "") result += " ";
|
||||
result += i;
|
||||
for (const auto& pair : m_impp->m_allArgs) {
|
||||
for (const string& arg : pair.first) {
|
||||
if (!result.empty()) result += " ";
|
||||
result += arg;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -1165,9 +1184,6 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
|
|||
// Parse parameters
|
||||
// Note argc and argv DO NOT INCLUDE the filename in [0]!!!
|
||||
// May be called recursively when there are -f files.
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
addArg(argv[i]); // -f's really should be inserted in the middle, but this is for debug
|
||||
}
|
||||
|
||||
V3OptionParser parser;
|
||||
const V3OptionParser::AppendHelper DECL_OPTION{parser};
|
||||
|
|
@ -1209,8 +1225,9 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
|
|||
// (If DECL_OPTION is a macro, then lambda would be collapsed into a single line).
|
||||
|
||||
// Plus options
|
||||
DECL_OPTION("+define+", CbPartialMatch,
|
||||
[this](const char* optp) VL_MT_DISABLED { addDefine(optp, true); });
|
||||
DECL_OPTION("+define+", CbPartialMatch, [this](const char* optp) VL_MT_DISABLED {
|
||||
addDefine(optp, true);
|
||||
}).notForRerun();
|
||||
DECL_OPTION("+incdir+", CbPartialMatch, [this, &optdir](const char* optp) {
|
||||
string dirs = optp;
|
||||
string::size_type pos;
|
||||
|
|
@ -1219,7 +1236,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
|
|||
dirs = dirs.substr(pos + 1);
|
||||
}
|
||||
addIncDirUser(parseFileArg(optdir, dirs));
|
||||
});
|
||||
}).notForRerun();
|
||||
DECL_OPTION("+libext+", CbPartialMatch, [this](const char* optp) {
|
||||
string exts = optp;
|
||||
string::size_type pos;
|
||||
|
|
@ -1228,31 +1245,42 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
|
|||
exts = exts.substr(pos + 1);
|
||||
}
|
||||
addLibExtV(exts);
|
||||
});
|
||||
DECL_OPTION("+librescan", CbCall, []() {}); // NOP
|
||||
DECL_OPTION("+notimingchecks", CbCall, []() {}); // NOP
|
||||
DECL_OPTION("+systemverilogext+", CbPartialMatch,
|
||||
[this](const char* optp) { addLangExt(optp, V3LangCode::L1800_2017); });
|
||||
DECL_OPTION("+verilog1995ext+", CbPartialMatch,
|
||||
[this](const char* optp) { addLangExt(optp, V3LangCode::L1364_1995); });
|
||||
DECL_OPTION("+verilog2001ext+", CbPartialMatch,
|
||||
[this](const char* optp) { addLangExt(optp, V3LangCode::L1364_2001); });
|
||||
DECL_OPTION("+1364-1995ext+", CbPartialMatch,
|
||||
[this](const char* optp) { addLangExt(optp, V3LangCode::L1364_1995); });
|
||||
DECL_OPTION("+1364-2001ext+", CbPartialMatch,
|
||||
[this](const char* optp) { addLangExt(optp, V3LangCode::L1364_2001); });
|
||||
DECL_OPTION("+1364-2005ext+", CbPartialMatch,
|
||||
[this](const char* optp) { addLangExt(optp, V3LangCode::L1364_2005); });
|
||||
DECL_OPTION("+1800-2005ext+", CbPartialMatch,
|
||||
[this](const char* optp) { addLangExt(optp, V3LangCode::L1800_2005); });
|
||||
DECL_OPTION("+1800-2009ext+", CbPartialMatch,
|
||||
[this](const char* optp) { addLangExt(optp, V3LangCode::L1800_2009); });
|
||||
DECL_OPTION("+1800-2012ext+", CbPartialMatch,
|
||||
[this](const char* optp) { addLangExt(optp, V3LangCode::L1800_2012); });
|
||||
DECL_OPTION("+1800-2017ext+", CbPartialMatch,
|
||||
[this](const char* optp) { addLangExt(optp, V3LangCode::L1800_2017); });
|
||||
DECL_OPTION("+1800-2023ext+", CbPartialMatch,
|
||||
[this](const char* optp) { addLangExt(optp, V3LangCode::L1800_2023); });
|
||||
}).notForRerun();
|
||||
DECL_OPTION("+librescan", CbCall, []() {}).notForRerun(); // NOP
|
||||
DECL_OPTION("+notimingchecks", CbCall, []() {}).notForRerun(); // NOP
|
||||
DECL_OPTION("+systemverilogext+", CbPartialMatch, [this](const char* optp) {
|
||||
addLangExt(optp, V3LangCode::L1800_2017);
|
||||
}).notForRerun();
|
||||
DECL_OPTION("+verilog1995ext+", CbPartialMatch, [this](const char* optp) {
|
||||
addLangExt(optp, V3LangCode::L1364_1995);
|
||||
}).notForRerun();
|
||||
DECL_OPTION("+verilog2001ext+", CbPartialMatch, [this](const char* optp) {
|
||||
addLangExt(optp, V3LangCode::L1364_2001);
|
||||
}).notForRerun();
|
||||
DECL_OPTION("+1364-1995ext+", CbPartialMatch, [this](const char* optp) {
|
||||
addLangExt(optp, V3LangCode::L1364_1995);
|
||||
}).notForRerun();
|
||||
DECL_OPTION("+1364-2001ext+", CbPartialMatch, [this](const char* optp) {
|
||||
addLangExt(optp, V3LangCode::L1364_2001);
|
||||
}).notForRerun();
|
||||
DECL_OPTION("+1364-2005ext+", CbPartialMatch, [this](const char* optp) {
|
||||
addLangExt(optp, V3LangCode::L1364_2005);
|
||||
}).notForRerun();
|
||||
DECL_OPTION("+1800-2005ext+", CbPartialMatch, [this](const char* optp) {
|
||||
addLangExt(optp, V3LangCode::L1800_2005);
|
||||
}).notForRerun();
|
||||
DECL_OPTION("+1800-2009ext+", CbPartialMatch, [this](const char* optp) {
|
||||
addLangExt(optp, V3LangCode::L1800_2009);
|
||||
}).notForRerun();
|
||||
DECL_OPTION("+1800-2012ext+", CbPartialMatch, [this](const char* optp) {
|
||||
addLangExt(optp, V3LangCode::L1800_2012);
|
||||
}).notForRerun();
|
||||
DECL_OPTION("+1800-2017ext+", CbPartialMatch, [this](const char* optp) {
|
||||
addLangExt(optp, V3LangCode::L1800_2017);
|
||||
}).notForRerun();
|
||||
DECL_OPTION("+1800-2023ext+", CbPartialMatch, [this](const char* optp) {
|
||||
addLangExt(optp, V3LangCode::L1800_2023);
|
||||
}).notForRerun();
|
||||
|
||||
// Minus options
|
||||
DECL_OPTION("-aslr", CbOnOff, [](bool) {}); // Processed only in bin/verilator shell
|
||||
|
|
@ -1333,10 +1361,11 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
|
|||
DECL_OPTION("-coverage-underscore", OnOff, &m_coverageUnderscore);
|
||||
DECL_OPTION("-coverage-user", OnOff, &m_coverageUser);
|
||||
|
||||
DECL_OPTION("-D", CbPartialMatch,
|
||||
[this](const char* valp) VL_MT_DISABLED { addDefine(valp, false); });
|
||||
DECL_OPTION("-debug", CbCall, [this]() { setDebugMode(3); });
|
||||
DECL_OPTION("-debugi", CbVal, [this](int v) { setDebugMode(v); });
|
||||
DECL_OPTION("-D", CbPartialMatch, [this](const char* valp) VL_MT_DISABLED {
|
||||
addDefine(valp, false);
|
||||
}).notForRerun();
|
||||
DECL_OPTION("-debug", CbCall, [this]() { setDebugMode(3); }).notForRerun();
|
||||
DECL_OPTION("-debugi", CbVal, [this](int v) { setDebugMode(v); }).notForRerun();
|
||||
DECL_OPTION("-debugi-", CbPartialMatchVal, [this](const char* optp, const char* valp) {
|
||||
m_debugLevel[optp] = std::atoi(valp);
|
||||
});
|
||||
|
|
@ -1370,11 +1399,15 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
|
|||
m_diagnosticsSarif = true;
|
||||
});
|
||||
DECL_OPTION("-dpi-hdr-only", OnOff, &m_dpiHdrOnly);
|
||||
DECL_OPTION("-dump-", CbPartialMatch, [this](const char* optp) { m_dumpLevel[optp] = 3; });
|
||||
DECL_OPTION("-no-dump-", CbPartialMatch, [this](const char* optp) { m_dumpLevel[optp] = 0; });
|
||||
DECL_OPTION("-dump-", CbPartialMatch, [this](const char* optp) {
|
||||
m_dumpLevel[optp] = 3;
|
||||
}).notForRerun();
|
||||
DECL_OPTION("-no-dump-", CbPartialMatch, [this](const char* optp) {
|
||||
m_dumpLevel[optp] = 0;
|
||||
}).notForRerun();
|
||||
DECL_OPTION("-dumpi-", CbPartialMatchVal, [this](const char* optp, const char* valp) {
|
||||
m_dumpLevel[optp] = std::atoi(valp);
|
||||
});
|
||||
}).notForRerun();
|
||||
|
||||
DECL_OPTION("-E", CbOnOff, [this](bool flag) {
|
||||
if (flag) {
|
||||
|
|
@ -1391,12 +1424,12 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
|
|||
|
||||
DECL_OPTION("-F", CbVal, [this, fl, &optdir](const char* valp) VL_MT_DISABLED {
|
||||
parseOptsFile(fl, parseFileArg(optdir, valp), true);
|
||||
});
|
||||
}).notForRerun();
|
||||
DECL_OPTION("-FI", CbVal,
|
||||
[this, &optdir](const char* valp) { addForceInc(parseFileArg(optdir, valp)); });
|
||||
DECL_OPTION("-f", CbVal, [this, fl, &optdir](const char* valp) VL_MT_DISABLED {
|
||||
parseOptsFile(fl, parseFileArg(optdir, valp), false);
|
||||
});
|
||||
}).notForRerun();
|
||||
DECL_OPTION("-flatten", OnOff, &m_flatten);
|
||||
DECL_OPTION("-future0", CbVal, [this](const char* valp) { addFuture0(valp); });
|
||||
DECL_OPTION("-future1", CbVal, [this](const char* valp) { addFuture1(valp); });
|
||||
|
|
@ -1485,8 +1518,9 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
|
|||
DECL_OPTION("-hierarchical-params-file", CbVal,
|
||||
[this](const char* optp) { m_hierParamsFile.push_back({optp, work()}); });
|
||||
|
||||
DECL_OPTION("-I", CbPartialMatch,
|
||||
[this, &optdir](const char* optp) { addIncDirUser(parseFileArg(optdir, optp)); });
|
||||
DECL_OPTION("-I", CbPartialMatch, [this, &optdir](const char* optp) {
|
||||
addIncDirUser(parseFileArg(optdir, optp));
|
||||
}).notForRerun();
|
||||
DECL_OPTION("-if-depth", Set, &m_ifDepth);
|
||||
DECL_OPTION("-ignc", OnOff, &m_ignc).undocumented();
|
||||
DECL_OPTION("-inline-mult", Set, &m_inlineMult);
|
||||
|
|
@ -1523,8 +1557,8 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
|
|||
fl->v3error("Unknown language specified: " << valp << spell.bestCandidateMsg(valp));
|
||||
}
|
||||
};
|
||||
DECL_OPTION("-default-language", CbVal, setLang);
|
||||
DECL_OPTION("-language", CbVal, setLang);
|
||||
DECL_OPTION("-default-language", CbVal, setLang).notForRerun();
|
||||
DECL_OPTION("-language", CbVal, setLang).notForRerun();
|
||||
DECL_OPTION("-lib-create", CbVal, [this, fl](const char* valp) {
|
||||
validateIdentifier(fl, valp, "--lib-create");
|
||||
m_libCreate = valp;
|
||||
|
|
@ -1538,7 +1572,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
|
|||
DECL_OPTION("-Mdir", CbVal, [this](const char* valp) {
|
||||
m_makeDir = valp;
|
||||
addIncDirFallback(m_makeDir); // Need to find generated files there too
|
||||
});
|
||||
}).notForRerun();
|
||||
DECL_OPTION("-main", OnOff, &m_main);
|
||||
DECL_OPTION("-main-top-name", Set, &m_mainTopName);
|
||||
DECL_OPTION("-make", CbVal, [this, fl](const char* valp) {
|
||||
|
|
@ -1943,56 +1977,77 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
|
|||
|
||||
DECL_OPTION("-y", CbVal, [this, &optdir](const char* valp) {
|
||||
addIncDirUser(parseFileArg(optdir, string{valp}));
|
||||
});
|
||||
}).notForRerun();
|
||||
|
||||
parser.finalize();
|
||||
|
||||
const std::string cwd = V3Os::filenameRealPath(".");
|
||||
|
||||
for (int i = 0; i < argc;) {
|
||||
UINFO(9, " Option: " << argv[i]);
|
||||
if (!std::strcmp(argv[i], "-j")
|
||||
|| !std::strcmp(argv[i], "--j")) { // Allow gnu -- switches
|
||||
++i;
|
||||
int val = 0;
|
||||
if (i < argc && std::isdigit(argv[i][0])) {
|
||||
val = std::atoi(argv[i]); // Can't be negative due to isdigit above
|
||||
if (val == 0) val = VlOs::getProcessDefaultParallelism();
|
||||
++i;
|
||||
}
|
||||
if (m_buildJobs == -1) m_buildJobs = val;
|
||||
if (m_verilateJobs == -1) m_verilateJobs = val;
|
||||
if (m_outputGroups == -1) m_outputGroups = val;
|
||||
} else if (argv[i][0] == '-' || argv[i][0] == '+') {
|
||||
const char* argvNoDashp = (argv[i][1] == '-') ? (argv[i] + 2) : (argv[i] + 1);
|
||||
if (const int consumed = parser.parse(i, argc, argv)) {
|
||||
i += consumed;
|
||||
} else if (isFuture0(argvNoDashp)) {
|
||||
++i;
|
||||
} else if (isFuture1(argvNoDashp)) {
|
||||
i += 2;
|
||||
|
||||
// Option
|
||||
if (argv[i][0] == '-' || argv[i][0] == '+') {
|
||||
const std::string argName = argv[i] + (argv[i][0] == argv[i][1] ? 2 : 1);
|
||||
int consumed = 0;
|
||||
bool isForRerun = true;
|
||||
|
||||
// Special case for -j which has an optional argument
|
||||
if (argv[i][0] == '-' && argName == "j") {
|
||||
consumed = 1;
|
||||
int val = 0;
|
||||
if (i + 1 < argc && std::isdigit(argv[i + 1][0])) {
|
||||
val = std::atoi(argv[i + 1]); // Can't be negative due to isdigit above
|
||||
if (val == 0) val = VlOs::getProcessDefaultParallelism();
|
||||
consumed = 2;
|
||||
}
|
||||
if (m_buildJobs == -1) m_buildJobs = val;
|
||||
if (m_verilateJobs == -1) m_verilateJobs = val;
|
||||
if (m_outputGroups == -1) m_outputGroups = val;
|
||||
} else {
|
||||
fl->v3fatal("Invalid option: " << argv[i] << parser.getSuggestion(argv[i]));
|
||||
++i; // LCOV_EXCL_LINE
|
||||
const auto pair = parser.parse(i, argc, argv);
|
||||
consumed = pair.first;
|
||||
isForRerun = pair.second;
|
||||
if (consumed) {
|
||||
// Already processed
|
||||
} else if (isFuture0(argName)) {
|
||||
consumed = 1;
|
||||
} else if (isFuture1(argName)) {
|
||||
consumed = 2;
|
||||
} else {
|
||||
fl->v3fatal("Invalid option: " << argv[i] << parser.getSuggestion(argv[i]));
|
||||
consumed = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Filename
|
||||
const string filename = parseFileArg(optdir, argv[i]);
|
||||
if (suffixed(filename, ".cpp") //
|
||||
|| suffixed(filename, ".cxx") //
|
||||
|| suffixed(filename, ".cc") //
|
||||
|| suffixed(filename, ".c") //
|
||||
|| suffixed(filename, ".sp")) {
|
||||
V3Options::addCppFile(filename);
|
||||
} else if (suffixed(filename, ".a") //
|
||||
|| suffixed(filename, ".o") //
|
||||
|| suffixed(filename, ".so")) {
|
||||
V3Options::addLdLibs(filename);
|
||||
} else if (suffixed(filename, ".vlt")) {
|
||||
V3Options::addVltFile(filename, work());
|
||||
} else {
|
||||
V3Options::addVFile(filename, work());
|
||||
}
|
||||
++i;
|
||||
UASSERT(consumed, "Failed to consume argument: " << argv[i]);
|
||||
// Record all arguments except for -f and -F (their contents will be recorded instead)
|
||||
if (argName != "f" && argName != "F") addArg(argv + i, consumed, isForRerun);
|
||||
i += consumed;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Filename
|
||||
const std::string filename = parseFileArg(optdir, argv[i]);
|
||||
bool isForRerun = true;
|
||||
if (suffixed(filename, ".cpp") //
|
||||
|| suffixed(filename, ".cxx") //
|
||||
|| suffixed(filename, ".cc") //
|
||||
|| suffixed(filename, ".c") //
|
||||
|| suffixed(filename, ".sp")) {
|
||||
V3Options::addCppFile(filename);
|
||||
} else if (suffixed(filename, ".a") //
|
||||
|| suffixed(filename, ".o") //
|
||||
|| suffixed(filename, ".so")) {
|
||||
V3Options::addLdLibs(filename);
|
||||
} else if (suffixed(filename, ".vlt")) {
|
||||
V3Options::addVltFile(filename, work());
|
||||
isForRerun = false;
|
||||
} else {
|
||||
V3Options::addVFile(filename, work());
|
||||
isForRerun = false;
|
||||
}
|
||||
addArg(filename, isForRerun);
|
||||
++i;
|
||||
}
|
||||
|
||||
if (m_debugOptions) {
|
||||
|
|
@ -2013,38 +2068,73 @@ void V3Options::parseOptsFile(FileLine* fl, const string& filename, bool rel) VL
|
|||
return;
|
||||
}
|
||||
|
||||
string whole_file;
|
||||
bool inCmt = false;
|
||||
while (!ifp->eof()) {
|
||||
const string line = V3Os::getline(*ifp);
|
||||
// Strip simple comments
|
||||
string oline;
|
||||
// cppcheck-suppress StlMissingComparison
|
||||
char lastch = ' ';
|
||||
bool space_begin = true; // At beginning or leading spaces only
|
||||
for (string::const_iterator pos = line.begin(); pos != line.end(); lastch = *pos++) {
|
||||
if (inCmt) {
|
||||
if (*pos == '*' && *(pos + 1) == '/') {
|
||||
inCmt = false;
|
||||
++pos;
|
||||
// If we find any '// verilator fargs' line in the file, we will only use these,
|
||||
// otherwise we will use the file contents. This enables rerunning the output
|
||||
// produced by --dump-inptus with:
|
||||
// verilator -f <prefix>__inputs.vpp <prefix>__inputs.vpp
|
||||
bool has_fargs = false;
|
||||
std::string whole_file;
|
||||
|
||||
// Parses a '// verilator fargs' or '/* verilator fargs */' comment
|
||||
const auto parse_fargs_cmt = [&](const char* p) -> void {
|
||||
const bool blockCmt = p[1] == '*';
|
||||
p += 2;
|
||||
while (std::isspace(*p)) ++p;
|
||||
if (VString::startsWith(p, "verilator")) {
|
||||
p += std::strlen("verilator");
|
||||
if (std::isspace(*p)) {
|
||||
while (std::isspace(*p)) ++p;
|
||||
if (VString::startsWith(p, "fargs")) {
|
||||
p += std::strlen("fargs");
|
||||
if (std::isspace(*p)) {
|
||||
while (std::isspace(*p)) ++p;
|
||||
if (!has_fargs) {
|
||||
has_fargs = true;
|
||||
whole_file.clear();
|
||||
}
|
||||
whole_file += p;
|
||||
if (blockCmt) {
|
||||
const std::string::size_type pos = whole_file.find("*/");
|
||||
if (pos == std::string::npos) {
|
||||
fl->v3fatal("/* verilator fargs */ must be on single line");
|
||||
}
|
||||
whole_file.resize(pos);
|
||||
}
|
||||
whole_file += ' ';
|
||||
}
|
||||
}
|
||||
} else if (*pos == '/' && *(pos + 1) == '/'
|
||||
&& (pos == line.begin()
|
||||
|| std::isspace(lastch))) { // But allow /file//path
|
||||
break; // Ignore to EOL
|
||||
} else if (*pos == '#' && space_begin) { // Only # at [spaced] begin of line
|
||||
break; // Ignore to EOL
|
||||
} else if (*pos == '/' && *(pos + 1) == '*') {
|
||||
inCmt = true;
|
||||
space_begin = false;
|
||||
// cppcheck-suppress StlMissingComparison
|
||||
++pos;
|
||||
} else {
|
||||
if (!std::isspace(*pos)) space_begin = false;
|
||||
oline += *pos;
|
||||
}
|
||||
}
|
||||
whole_file += oline + " ";
|
||||
};
|
||||
|
||||
bool inCmt = false;
|
||||
while (!ifp->eof()) {
|
||||
const std::string line = V3Os::getline(*ifp);
|
||||
// Strip simple comments
|
||||
char lastch = ' '; // 'std::isspace(lastch)' is true at the start of the line
|
||||
bool space_begin = true; // At beginning or leading spaces only
|
||||
for (const char* p = line.c_str(); *p; lastch = *p++) {
|
||||
if (inCmt) {
|
||||
if (p[0] == '*' && p[1] == '/') {
|
||||
inCmt = false;
|
||||
++p;
|
||||
}
|
||||
} else if (p[0] == '/' && p[1] == '/' && std::isspace(lastch)) { // Allow /file//path
|
||||
parse_fargs_cmt(p);
|
||||
break; // Ignore to EOL
|
||||
} else if (p[0] == '#' && space_begin) { // Only # at [spaced] begin of line
|
||||
break; // Ignore to EOL
|
||||
} else if (p[0] == '/' && p[1] == '*') {
|
||||
parse_fargs_cmt(p);
|
||||
inCmt = true;
|
||||
space_begin = false;
|
||||
++p;
|
||||
} else {
|
||||
if (!std::isspace(*p)) space_begin = false;
|
||||
if (!has_fargs) whole_file += *p;
|
||||
}
|
||||
}
|
||||
if (!has_fargs) whole_file += " ";
|
||||
}
|
||||
whole_file += "\n"; // So string match below is simplified
|
||||
if (inCmt) fl->v3error("Unterminated /* comment inside -f file.");
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "V3Error.h"
|
||||
#include "V3LangCode.h"
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
|
@ -427,8 +428,9 @@ private:
|
|||
|
||||
private:
|
||||
// METHODS
|
||||
void addArg(char** argv, size_t count, bool isForRerun);
|
||||
void addArg(const std::string& arg, bool isForRerun);
|
||||
void addLineArg(const string& arg);
|
||||
void addArg(const string& arg);
|
||||
void addDefine(const string& defline, bool allowPlus) VL_MT_DISABLED;
|
||||
void addFuture(const string& flag);
|
||||
void addFuture0(const string& flag);
|
||||
|
|
@ -758,6 +760,7 @@ public:
|
|||
static string version() VL_PURE;
|
||||
static string argString(int argc, char** argv); ///< Return list of arguments as simple string
|
||||
string allArgsString() const VL_MT_SAFE; ///< Return all passed arguments as simple string
|
||||
const std::list<std::pair<std::list<std::string>, bool>>& allArgs() const;
|
||||
// Return options for child hierarchical blocks when forTop==false, otherwise returns args for
|
||||
// the top module.
|
||||
string allArgsStringForHierBlock(bool forTop) const;
|
||||
|
|
|
|||
|
|
@ -373,8 +373,29 @@ void V3ParseImp::dumpInputsFile() {
|
|||
*ofp << "// Blank lines and `line directives have been removed\n";
|
||||
*ofp << "//\n";
|
||||
V3Stats::infoHeader(*ofp, "// ");
|
||||
*ofp << '\n';
|
||||
for (const auto& pair : v3Global.opt.allArgs()) {
|
||||
if (!pair.second) continue;
|
||||
*ofp << "// verilator fargs";
|
||||
for (const std::string& arg : pair.first) {
|
||||
// Apply some quoting, pretty basic, update as needed ...
|
||||
std::string quoted;
|
||||
bool quoteIt = false;
|
||||
for (const char c : arg) {
|
||||
if (c == '"' || c == '\\') {
|
||||
quoteIt = true;
|
||||
quoted += '\\';
|
||||
} else if (std::isspace(c)) {
|
||||
quoteIt = true;
|
||||
}
|
||||
quoted += c;
|
||||
}
|
||||
*ofp << " " << (quoteIt ? '"' + quoted + '"' : arg);
|
||||
}
|
||||
*ofp << "\n";
|
||||
}
|
||||
*ofp << "\n";
|
||||
}
|
||||
*ofp << "\n";
|
||||
preprocDumps(*ofp, true);
|
||||
ofp->close();
|
||||
VL_DO_DANGLING(delete ofp, ofp);
|
||||
|
|
|
|||
|
|
@ -528,7 +528,11 @@ void V3PreProcImp::comment(const string& text) {
|
|||
//}
|
||||
// else ignore the comment we don't recognize
|
||||
} // else no assertions
|
||||
} else if (vlcomment && !(v3Global.opt.publicOff() && VString::startsWith(cmd, "public"))) {
|
||||
} else if (vlcomment
|
||||
// Drop 'public' if disabled on the command line
|
||||
&& !(v3Global.opt.publicOff() && VString::startsWith(cmd, "public"))
|
||||
// Drop 'fargs', they are handled separately during option parsing
|
||||
&& !VString::startsWith(cmd, "fargs")) {
|
||||
if (VString::startsWith(cmd, "public_flat_rw")) {
|
||||
// "/*verilator public_flat_rw @(foo) */" -> "/*verilator public_flat_rw*/ @(foo)"
|
||||
string::size_type endOfCmd = std::strlen("public_flat_rw");
|
||||
|
|
@ -1062,12 +1066,12 @@ int V3PreProcImp::getStateToken() {
|
|||
string rtn;
|
||||
rtn.assign(yyourtext(), yyourleng());
|
||||
comment(rtn);
|
||||
// Need to ensure "foo/**/bar" becomes two tokens
|
||||
insertUnreadback(" ");
|
||||
// Need to ensure "foo/**/bar" becomes two tokens, not one 'foobar'
|
||||
if (m_lineCmt.empty()) insertUnreadback(" ");
|
||||
} else if (m_lexp->m_keepComments) {
|
||||
return tok;
|
||||
} else {
|
||||
// Need to ensure "foo/**/bar" becomes two tokens
|
||||
// Need to ensure "foo/**/bar" becomes two tokens, not one 'foobar'
|
||||
insertUnreadback(" ");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ void VlcOptions::parseOptsList(int argc, char** argv) {
|
|||
for (int i = 0; i < argc;) {
|
||||
UINFO(9, " Option: " << argv[i]);
|
||||
if (argv[i][0] == '-') {
|
||||
if (const int consumed = parser.parse(i, argc, argv)) {
|
||||
if (const int consumed = parser.parse(i, argc, argv).first) {
|
||||
i += consumed;
|
||||
} else {
|
||||
v3fatal("Invalid option: " << argv[i] << parser.getSuggestion(argv[i]));
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
%Warning-DEPRECATED: t/t_clk_first_deprecated.v:12:14: sc_clock is ignored
|
||||
12 | input clk /*verilator sc_clock*/ ;
|
||||
12 | input clk /*verilator sc_clock*/;
|
||||
| ^~~~~~~~~~~~~~~~~~~~~~
|
||||
... For warning description see https://verilator.org/warn/DEPRECATED?v=latest
|
||||
... Use "/* verilator lint_off DEPRECATED */" and lint_on around source to disable this message.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
%Error: t/t_dpi_display_bad.v:17:69: /*verilator sformat*/ can only be applied to last argument of a function
|
||||
17 | (input string formatted /*verilator sformat*/ , input string other_bad );
|
||||
| ^~~~~~~~~
|
||||
%Error: t/t_dpi_display_bad.v:17:68: /*verilator sformat*/ can only be applied to last argument of a function
|
||||
17 | (input string formatted /*verilator sformat*/, input string other_bad );
|
||||
| ^~~~~~~~~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -0,0 +1,98 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2025 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
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('vlt')
|
||||
|
||||
|
||||
def fixup(path):
|
||||
lines = []
|
||||
removeBeginKeywords = True
|
||||
with open(path, "r", encoding="utf-8") as rfd:
|
||||
for line in rfd:
|
||||
# Remove "all arguments" line, which can differ
|
||||
if line.startswith("// Arguments:"):
|
||||
lines.append("// Arguments: <REDACTED>")
|
||||
# Remove first `begin_keywords, which will be re-inserted on reruns
|
||||
elif removeBeginKeywords and line.startswith("`begin_keywords"):
|
||||
removeBeginKeywords = False
|
||||
lines.append("// " + line)
|
||||
else:
|
||||
lines.append(line)
|
||||
with open(path, "w", encoding="utf-8") as wfd:
|
||||
for line in lines:
|
||||
wfd.write(line)
|
||||
|
||||
|
||||
obj_dir_1 = test.obj_dir + "/obj_dir_1"
|
||||
test.mkdir_ok(obj_dir_1)
|
||||
dump_1 = obj_dir_1 + "/Vprefix__inputs.vpp"
|
||||
test.run(
|
||||
logfile=obj_dir_1 + "/vlt_compile.log",
|
||||
cmd=[
|
||||
"perl",
|
||||
os.environ["VERILATOR_ROOT"] + "/bin/verilator",
|
||||
"-cc",
|
||||
"-Mdir",
|
||||
obj_dir_1,
|
||||
"--prefix",
|
||||
"Vprefix",
|
||||
"--top-module",
|
||||
"lpm_divide",
|
||||
"--no-timing",
|
||||
"-CFLAGS",
|
||||
"'-O3 --foo'", # Argument with whitespace
|
||||
"-CFLAGS",
|
||||
"'-DDQUOTE=\"'", # Argument with quote
|
||||
"--dump-inputs",
|
||||
"t/t_altera_lpm.v",
|
||||
"t/t_math_cond_huge.v"
|
||||
])
|
||||
fixup(dump_1)
|
||||
|
||||
obj_dir_2 = test.obj_dir + "/obj_dir_2"
|
||||
test.mkdir_ok(obj_dir_2)
|
||||
dump_2 = obj_dir_2 + "/Vprefix__inputs.vpp"
|
||||
test.run(
|
||||
logfile=obj_dir_2 + "/vlt_compile.log",
|
||||
cmd=[
|
||||
"perl",
|
||||
os.environ["VERILATOR_ROOT"] + "/bin/verilator",
|
||||
"-Mdir",
|
||||
obj_dir_2,
|
||||
"-f",
|
||||
dump_1,
|
||||
dump_1,
|
||||
"--debug", # --debug also dumps the same way
|
||||
"--debugi",
|
||||
"1"
|
||||
])
|
||||
fixup(dump_2)
|
||||
|
||||
obj_dir_3 = test.obj_dir + "/obj_dir_3"
|
||||
test.mkdir_ok(obj_dir_3)
|
||||
dump_3 = obj_dir_3 + "/Vprefix__inputs.vpp"
|
||||
test.run(logfile=obj_dir_3 + "/vlt_compile.log",
|
||||
cmd=[
|
||||
"perl",
|
||||
os.environ["VERILATOR_ROOT"] + "/bin/verilator",
|
||||
"-Mdir",
|
||||
obj_dir_3,
|
||||
"-f",
|
||||
dump_2,
|
||||
dump_2,
|
||||
"--dump-inputs",
|
||||
])
|
||||
fixup(dump_3)
|
||||
|
||||
test.files_identical(dump_1, dump_2)
|
||||
test.files_identical(dump_1, dump_3)
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2025 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
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('vlt')
|
||||
|
||||
test.compile(verilator_flags2=["-f", test.top_filename], make_main=False)
|
||||
|
||||
test.file_grep(test.stats, r'Tracing, Traced signals\s+(\d+)', 2)
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2025 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// verilator fargs --binary -Wno-WIDTHEXPAND
|
||||
/* verilator fargs -Wno-WIDTHTRUNC *//* verilator fargs --trace-vcd --stats */
|
||||
|
||||
module top;
|
||||
|
||||
bit clk = 0;
|
||||
always #5 clk = ~clk;
|
||||
reg [3:0] cyc = 0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 10'd1; // Intentional width warning
|
||||
$display("%8t %1d", $time, cyc);
|
||||
if (cyc == 3'd7) begin // Intentional width warning
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
%Error: /* verilator fargs */ must be on single line
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2025 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
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('vlt')
|
||||
|
||||
test.compile(verilator_flags2=["-f", test.top_filename],
|
||||
fails=True,
|
||||
expect_filename=test.golden_filename)
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2025 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
/* verilator fargs --cc
|
||||
*/
|
||||
|
||||
module t;
|
||||
endmodule
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
%Warning-ASCRANGE: t/t_metacmt_onoff.v:8:8: Ascending bit range vector: left < right of bit range: [0:1]
|
||||
: ... note: In instance 't'
|
||||
8 | reg [0:1] show1; /*verilator lint_off ASCRANGE*/ reg [0:2] ign2; /*verilator lint_on ASCRANGE*/ reg [0:3] show3;
|
||||
8 | reg [0:1] show1; /*verilator lint_off ASCRANGE*/ reg [0:2] ign2; /*verilator lint_on ASCRANGE*/ reg [0:3] show3;
|
||||
| ^
|
||||
... For warning description see https://verilator.org/warn/ASCRANGE?v=latest
|
||||
... Use "/* verilator lint_off ASCRANGE */" and lint_on around source to disable this message.
|
||||
%Warning-ASCRANGE: t/t_metacmt_onoff.v:8:107: Ascending bit range vector: left < right of bit range: [0:3]
|
||||
%Warning-ASCRANGE: t/t_metacmt_onoff.v:8:105: Ascending bit range vector: left < right of bit range: [0:3]
|
||||
: ... note: In instance 't'
|
||||
8 | reg [0:1] show1; /*verilator lint_off ASCRANGE*/ reg [0:2] ign2; /*verilator lint_on ASCRANGE*/ reg [0:3] show3;
|
||||
| ^
|
||||
8 | reg [0:1] show1; /*verilator lint_off ASCRANGE*/ reg [0:2] ign2; /*verilator lint_on ASCRANGE*/ reg [0:3] show3;
|
||||
| ^
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
| ^~~~~~~
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: t/t_parse_sync_bad.v:25:14: syntax error, unexpected /*verilator clocker*/, expecting ',' or ';'
|
||||
25 | logic clk /*verilator clocker*/ ;
|
||||
25 | logic clk /*verilator clocker*/;
|
||||
| ^~~~~~~~~~~~~~~~~~~~~
|
||||
%Error: t/t_parse_sync_bad.v:29:1: syntax error, unexpected endmodule
|
||||
29 | endmodule
|
||||
|
|
|
|||
|
|
@ -561,17 +561,17 @@ $display("bits %d %d", $bits(foo), 10);
|
|||
|
||||
|
||||
`line 366 "t/t_preproc.v" 0
|
||||
1 /*verilator NOT IN DEFINE*/ (nodef)
|
||||
2 /*verilator PART OF DEFINE*/ (hasdef)
|
||||
1 /*verilator NOT IN DEFINE*/ (nodef)
|
||||
2 /*verilator PART OF DEFINE*/ (hasdef)
|
||||
3
|
||||
`line 368 "t/t_preproc.v" 0
|
||||
/*verilator NOT PART
|
||||
OF DEFINE*/ (nodef)
|
||||
OF DEFINE*/ (nodef)
|
||||
`line 369 "t/t_preproc.v" 0
|
||||
4
|
||||
`line 369 "t/t_preproc.v" 0
|
||||
/*verilator PART
|
||||
OF DEFINE*/ (nodef)
|
||||
OF DEFINE*/ (nodef)
|
||||
`line 370 "t/t_preproc.v" 0
|
||||
5 also in
|
||||
`line 370 "t/t_preproc.v" 0
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ text.
|
|||
`line 34 "t/t_preproc.v" 0
|
||||
|
||||
|
||||
foo /*this */ bar /* this too */
|
||||
foo /*this */ bar /* this too */
|
||||
foobar2 // but not
|
||||
|
||||
`line 39 "t/t_preproc.v" 0
|
||||
|
|
@ -428,7 +428,7 @@ Line_Preproc_Check 272
|
|||
// bug84
|
||||
|
||||
`line 277 "t/t_preproc.v" 0
|
||||
// Hello, comments MIGHT not be legal /*more,,)cmts*/ // But newlines ARE legal... who speced THAT?
|
||||
// Hello, comments MIGHT not be legal/*more,,)cmts*/// But newlines ARE legal... who speced THAT?
|
||||
|
||||
|
||||
(p,q)
|
||||
|
|
@ -436,7 +436,7 @@ Line_Preproc_Check 272
|
|||
|
||||
|
||||
`line 284 "t/t_preproc.v" 0
|
||||
(//Here x,y //Too)
|
||||
(//Here x,y //Too)
|
||||
Line_Preproc_Check 285
|
||||
|
||||
`line 287 "t/t_preproc.v" 0
|
||||
|
|
@ -528,7 +528,7 @@ $display("bits %d %d", $bits(foo), 10);
|
|||
`line 343 "t/t_preproc.v" 0
|
||||
|
||||
/* multi \
|
||||
line1*/ \
|
||||
line1*/ \
|
||||
`line 345 "t/t_preproc.v" 0
|
||||
|
||||
/*multi \
|
||||
|
|
@ -567,16 +567,16 @@ $display("bits %d %d", $bits(foo), 10);
|
|||
|
||||
`line 366 "t/t_preproc.v" 0
|
||||
1 // verilator NOT IN DEFINE (nodef)
|
||||
2 /* verilator PART OF DEFINE */ (hasdef)
|
||||
2 /* verilator PART OF DEFINE */ (hasdef)
|
||||
3
|
||||
`line 368 "t/t_preproc.v" 0
|
||||
/* verilator NOT PART
|
||||
OF DEFINE */ (nodef)
|
||||
OF DEFINE */ (nodef)
|
||||
`line 369 "t/t_preproc.v" 0
|
||||
4
|
||||
`line 369 "t/t_preproc.v" 0
|
||||
/* verilator PART
|
||||
OF DEFINE */ (nodef)
|
||||
OF DEFINE */ (nodef)
|
||||
`line 370 "t/t_preproc.v" 0
|
||||
5 also in
|
||||
`line 370 "t/t_preproc.v" 0
|
||||
|
|
@ -790,7 +790,7 @@ module a_b ; endmodule
|
|||
`line 511 "t/t_preproc.v" 0
|
||||
//======================================================================
|
||||
// bug311
|
||||
integer/*NEED_SPACE*/ foo;
|
||||
integer/*NEED_SPACE*/foo;
|
||||
//======================================================================
|
||||
// bug441
|
||||
module t;
|
||||
|
|
|
|||
|
|
@ -724,17 +724,17 @@ $display("bits %d %d", $bits(foo), 10);
|
|||
`line 366 "t/t_preproc.v" 0
|
||||
|
||||
`line 366 "t/t_preproc.v" 0
|
||||
1 /*verilator NOT IN DEFINE*/ (nodef)
|
||||
2 /*verilator PART OF DEFINE*/ (hasdef)
|
||||
1 /*verilator NOT IN DEFINE*/ (nodef)
|
||||
2 /*verilator PART OF DEFINE*/ (hasdef)
|
||||
3
|
||||
`line 368 "t/t_preproc.v" 0
|
||||
/*verilator NOT PART
|
||||
OF DEFINE*/ (nodef)
|
||||
OF DEFINE*/ (nodef)
|
||||
`line 369 "t/t_preproc.v" 0
|
||||
4
|
||||
`line 369 "t/t_preproc.v" 0
|
||||
/*verilator PART
|
||||
OF DEFINE*/ (nodef)
|
||||
OF DEFINE*/ (nodef)
|
||||
`line 370 "t/t_preproc.v" 0
|
||||
5 also in
|
||||
`line 370 "t/t_preproc.v" 0
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
},
|
||||
"invocations": [
|
||||
{
|
||||
"commandLine": "--prefix Vt_sarif --lint-only -Mdir obj_vlt/t_sarif --debug-check --x-assign unique -Wno-fatal --diagnostics-sarif --no-skip-identical -f input.vc +define+TEST_OBJ_DIR=obj_vlt/t_sarif +define+TEST_DUMPFILE=obj_vlt/t_sarif/simx.vcd t/t_sarif.v +librescan +notimingchecks +libext+.v -y t +incdir+t",
|
||||
"commandLine": "--prefix Vt_sarif --lint-only -Mdir obj_vlt/t_sarif --debug-check --x-assign unique -Wno-fatal --diagnostics-sarif --no-skip-identical +librescan +notimingchecks +libext+.v -y t +incdir+t +define+TEST_OBJ_DIR=obj_vlt/t_sarif +define+TEST_DUMPFILE=obj_vlt/t_sarif/simx.vcd t/t_sarif.v",
|
||||
"executionSuccessful": true
|
||||
}
|
||||
],
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:7:13: 'should_show_warning_global0' has split_var metacomment, but will not be split because it is not declared in a module.
|
||||
7 | logic [7:0] should_show_warning_global0 /*verilator split_var*/ ;
|
||||
7 | logic [7:0] should_show_warning_global0 /*verilator split_var*/;
|
||||
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
... For warning description see https://verilator.org/warn/SPLITVAR?v=latest
|
||||
... Use "/* verilator lint_off SPLITVAR */" and lint_on around source to disable this message.
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:8:13: 'should_show_warning_global1' has split_var metacomment, but will not be split because it is not declared in a module.
|
||||
8 | logic [7:0] should_show_warning_global1 [1:0] /*verilator split_var*/ ;
|
||||
8 | logic [7:0] should_show_warning_global1 [1:0] /*verilator split_var*/;
|
||||
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:11:16: 'should_show_warning_ifs0' has split_var metacomment, but will not be split because it is not declared in a module.
|
||||
11 | logic [7:0] should_show_warning_ifs0 /*verilator split_var*/ ;
|
||||
11 | logic [7:0] should_show_warning_ifs0 /*verilator split_var*/;
|
||||
| ^~~~~~~~~~~~~~~~~~~~~~~~
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:12:16: 'should_show_warning_ifs1' has split_var metacomment, but will not be split because it is not declared in a module.
|
||||
12 | logic [7:0] should_show_warning_ifs1 [1:0] /*verilator split_var*/ ;
|
||||
12 | logic [7:0] should_show_warning_ifs1 [1:0] /*verilator split_var*/;
|
||||
| ^~~~~~~~~~~~~~~~~~~~~~~~
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:40:14: 'cannot_split1' has split_var metacomment but will not be split because it is accessed from another module via a dot.
|
||||
40 | i_sub0.cannot_split1[0] = 0;
|
||||
|
|
@ -42,40 +42,40 @@
|
|||
| ^~
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:17:9: 'should_show_warning0' has split_var metacomment but will not be split because it is not an aggregate type of bit nor logic.
|
||||
: ... note: In instance 't'
|
||||
17 | real should_show_warning0 /*verilator split_var*/ ;
|
||||
17 | real should_show_warning0 /*verilator split_var*/;
|
||||
| ^~~~~~~~~~~~~~~~~~~~
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:18:11: 'should_show_warning1' has split_var metacomment but will not be split because it is not an aggregate type of bit nor logic.
|
||||
: ... note: In instance 't'
|
||||
18 | string should_show_warning1 /*verilator split_var*/ ;
|
||||
18 | string should_show_warning1 /*verilator split_var*/;
|
||||
| ^~~~~~~~~~~~~~~~~~~~
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:19:11: 'should_show_warning2' has split_var metacomment but will not be split because its bitwidth is 1.
|
||||
: ... note: In instance 't'
|
||||
19 | wire should_show_warning2 /*verilator split_var*/ ;
|
||||
19 | wire should_show_warning2 /*verilator split_var*/;
|
||||
| ^~~~~~~~~~~~~~~~~~~~
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:23:16: 'public_signal' has split_var metacomment but will not be split because it is public.
|
||||
: ... note: In instance 't'
|
||||
23 | logic [1:0] public_signal /*verilator public*/ /*verilator split_var*/ ;
|
||||
23 | logic [1:0] public_signal /*verilator public*/ /*verilator split_var*/;
|
||||
| ^~~~~~~~~~~~~
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:31:44: 'inout_port' has split_var metacomment but will not be split because it is an inout port.
|
||||
: ... note: In instance 't'
|
||||
31 | function int bad_func(inout logic [3:0] inout_port /*verilator split_var*/ ,
|
||||
31 | function int bad_func(inout logic [3:0] inout_port /*verilator split_var*/,
|
||||
| ^~~~~~~~~~
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:32:42: 'ref_port' has split_var metacomment but will not be split because it is a ref argument.
|
||||
: ... note: In instance 't'
|
||||
32 | ref logic [7:0] ref_port /*verilator split_var*/ );
|
||||
32 | ref logic [7:0] ref_port /*verilator split_var*/);
|
||||
| ^~~~~~~~
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:37:19: 'loop_idx' has split_var metacomment but will not be split because it is used as a loop variable.
|
||||
: ... note: In instance 't'
|
||||
37 | logic [7:0] loop_idx /*verilator split_var*/ ;
|
||||
37 | logic [7:0] loop_idx /*verilator split_var*/;
|
||||
| ^~~~~~~~
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:62:11: 'cannot_split_genvar' has split_var metacomment but will not be split because it is not an aggregate type of bit nor logic.
|
||||
: ... note: In instance 't.i_sub1'
|
||||
62 | genvar cannot_split_genvar /*verilator split_var*/ ;
|
||||
62 | genvar cannot_split_genvar /*verilator split_var*/;
|
||||
| ^~~~~~~~~~~~~~~~~~~
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:65:72: 'cannot_split' has split_var metacomment but will not be split because its bit range cannot be determined statically.
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:65:71: 'cannot_split' has split_var metacomment but will not be split because its bit range cannot be determined statically.
|
||||
: ... note: In instance 't.i_sub1'
|
||||
65 | static logic [8:0] rd_tmp /*verilator split_var*/ = cannot_split[addr];
|
||||
| ^
|
||||
65 | static logic [8:0] rd_tmp /*verilator split_var*/ = cannot_split[addr];
|
||||
| ^
|
||||
%Warning-SPLITVAR: t/t_split_var_1_bad.v:66:23: 'rd_tmp' has split_var metacomment but will not be split because its bit range cannot be determined statically.
|
||||
: ... note: In instance 't.i_sub1'
|
||||
66 | rd_data = rd_tmp[{3'b0, addr[0]}+:8];
|
||||
|
|
|
|||
|
|
@ -5,6 +5,6 @@
|
|||
... Use "/* verilator lint_off SYMRSVDWORD */" and lint_on around source to disable this message.
|
||||
%Warning-SYMRSVDWORD: t/t_var_rsvd_port.v:15:9: Symbol matches C++ keyword: 'switch'
|
||||
: ... note: In instance 't'
|
||||
15 | reg switch /*verilator public*/ ;
|
||||
15 | reg switch /*verilator public*/;
|
||||
| ^~~~~~
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
Loading…
Reference in New Issue