From 47a4f7fb9b2d54b124059830496ee098f78c826e Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Tue, 16 Dec 2025 11:08:19 +0000 Subject: [PATCH] Improve reusability of --dump-inputs output (#6812) --- docs/guide/extensions.rst | 9 + docs/internals.rst | 14 +- src/V3OptionParser.cpp | 21 +- src/V3OptionParser.h | 10 +- src/V3Options.cpp | 332 ++++++++++++------- src/V3Options.h | 5 +- src/V3ParseImp.cpp | 23 +- src/V3PreProc.cpp | 12 +- src/VlcMain.cpp | 2 +- test_regress/t/t_clk_first_bad.out | 2 +- test_regress/t/t_dpi_display_bad.out | 6 +- test_regress/t/t_dump_inputs_rerun.py | 98 ++++++ test_regress/t/t_flag_future_bad.out | 6 +- test_regress/t/t_hier_block1_bad.out | 4 +- test_regress/t/t_hier_block_threads_bad.out | 2 +- test_regress/t/t_lint_badvltpragma_bad.out | 2 +- test_regress/t/t_lint_restore_prag_bad.out | 2 +- test_regress/t/t_metacmt_fargs.py | 20 ++ test_regress/t/t_metacmt_fargs.v | 25 ++ test_regress/t/t_metacmt_fargs_bad.out | 2 + test_regress/t/t_metacmt_fargs_bad.py | 18 + test_regress/t/t_metacmt_fargs_bad.v | 11 + test_regress/t/t_metacmt_onoff.out | 8 +- test_regress/t/t_parse_sync_bad.out | 2 +- test_regress/t/t_pp_underline_bad.out | 2 +- test_regress/t/t_preproc.out | 12 +- test_regress/t/t_preproc_comments.out | 350 ++++++++++---------- test_regress/t/t_preproc_defines.out | 12 +- test_regress/t/t_sarif.sarif.out | 2 +- test_regress/t/t_split_var_1_bad.out | 30 +- test_regress/t/t_var_rsvd_bad.out | 2 +- 31 files changed, 685 insertions(+), 361 deletions(-) create mode 100755 test_regress/t/t_dump_inputs_rerun.py create mode 100755 test_regress/t/t_metacmt_fargs.py create mode 100644 test_regress/t/t_metacmt_fargs.v create mode 100644 test_regress/t/t_metacmt_fargs_bad.out create mode 100755 test_regress/t/t_metacmt_fargs_bad.py create mode 100644 test_regress/t/t_metacmt_fargs_bad.v diff --git a/docs/guide/extensions.rst b/docs/guide/extensions.rst index 1065c7dc5..9a9da3be4 100644 --- a/docs/guide/extensions.rst +++ b/docs/guide/extensions.rst @@ -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 */ + + 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 diff --git a/docs/internals.rst b/docs/internals.rst index 63f8456a7..5b050170d 100644 --- a/docs/internals.rst +++ b/docs/internals.rst @@ -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 __inputs.vpp __inputs.vpp + +The first `-f __inputs.vpp` reads the command line arguments from +the file. The second `__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 diff --git a/src/V3OptionParser.cpp b/src/V3OptionParser.cpp index d19c27cc3..cd0dcd0a5 100644 --- a/src/V3OptionParser.cpp +++ b/src/V3OptionParser.cpp @@ -39,14 +39,23 @@ struct V3OptionParser::Impl final { // Base class of actual action classes template 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 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 { diff --git a/src/V3OptionParser.h b/src/V3OptionParser.h index ec2c1f895..c9ad20f66 100644 --- a/src/V3OptionParser.h +++ b/src/V3OptionParser.h @@ -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 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 diff --git a/src/V3Options.cpp b/src/V3Options.cpp index c3970959b..d186ac3b7 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -68,7 +68,8 @@ public: // STATE std::list m_lineArgs; // List of command line argument encountered - std::list m_allArgs; // List of every argument encountered + // List of arguments encounterd, and a bool in needed for rerunning --dump-inputs + std::list, bool>> m_allArgs; std::list m_incDirUsers; // Include directories (ordered) std::set m_incDirUserSet; // Include directories (for removing duplicates) std::list 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, 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, bool>& pair = m_impp->m_allArgs.back(); + pair.second = isForRerun; + pair.first.emplace_back(arg); +} + +const std::list, 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 __inputs.vpp __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."); diff --git a/src/V3Options.h b/src/V3Options.h index 304079ecd..76780e1f8 100644 --- a/src/V3Options.h +++ b/src/V3Options.h @@ -23,6 +23,7 @@ #include "V3Error.h" #include "V3LangCode.h" +#include #include #include #include @@ -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, bool>>& allArgs() const; // Return options for child hierarchical blocks when forTop==false, otherwise returns args for // the top module. string allArgsStringForHierBlock(bool forTop) const; diff --git a/src/V3ParseImp.cpp b/src/V3ParseImp.cpp index bec4d50d4..cba0ed5a1 100644 --- a/src/V3ParseImp.cpp +++ b/src/V3ParseImp.cpp @@ -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); diff --git a/src/V3PreProc.cpp b/src/V3PreProc.cpp index d4982561d..c57135d19 100644 --- a/src/V3PreProc.cpp +++ b/src/V3PreProc.cpp @@ -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(" "); } } diff --git a/src/VlcMain.cpp b/src/VlcMain.cpp index 56916b5b7..2fe68a73c 100644 --- a/src/VlcMain.cpp +++ b/src/VlcMain.cpp @@ -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])); diff --git a/test_regress/t/t_clk_first_bad.out b/test_regress/t/t_clk_first_bad.out index 6ed468978..0f3358053 100644 --- a/test_regress/t/t_clk_first_bad.out +++ b/test_regress/t/t_clk_first_bad.out @@ -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. diff --git a/test_regress/t/t_dpi_display_bad.out b/test_regress/t/t_dpi_display_bad.out index be959988b..778f34166 100644 --- a/test_regress/t/t_dpi_display_bad.out +++ b/test_regress/t/t_dpi_display_bad.out @@ -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 diff --git a/test_regress/t/t_dump_inputs_rerun.py b/test_regress/t/t_dump_inputs_rerun.py new file mode 100755 index 000000000..16fd3a5d2 --- /dev/null +++ b/test_regress/t/t_dump_inputs_rerun.py @@ -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: ") + # 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() diff --git a/test_regress/t/t_flag_future_bad.out b/test_regress/t/t_flag_future_bad.out index d89fcbc03..b085b428e 100644 --- a/test_regress/t/t_flag_future_bad.out +++ b/test_regress/t/t_flag_future_bad.out @@ -1,12 +1,12 @@ %Error: t/t_flag_future.v:8:7: Unknown verilator lint message code: 'FUTURE1', in '/*verilator lint_off FUTURE1*/' - 8 | /*verilator lint_off FUTURE1*/ + 8 | /*verilator lint_off FUTURE1*/ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. %Error-BADVLTPRAGMA: t/t_flag_future.v:11:7: Unknown verilator comment: '/*verilator FUTURE2*/' - 11 | /*verilator FUTURE2*/ + 11 | /*verilator FUTURE2*/ | ^~~~~~~~~~~~~~~~~~~~~ ... For error description see https://verilator.org/warn/BADVLTPRAGMA?v=latest %Error-BADVLTPRAGMA: t/t_flag_future.v:12:7: Unknown verilator comment: '/*verilator FUTURE2 blah blah*/' - 12 | /*verilator FUTURE2 blah blah*/ + 12 | /*verilator FUTURE2 blah blah*/ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_hier_block1_bad.out b/test_regress/t/t_hier_block1_bad.out index be6024fb2..df2b64a25 100644 --- a/test_regress/t/t_hier_block1_bad.out +++ b/test_regress/t/t_hier_block1_bad.out @@ -7,11 +7,11 @@ ... Use "/* verilator lint_off HIERBLOCK */" and lint_on around source to disable this message. %Error: t/t_hier_block1_bad.v:45:32: Modport cannot be used at the hierarchical block boundary : ... note: In instance 't.i_sub1' - 45 | module sub1 (byte_ifs.receiver in, byte_ifs.sender out); /*verilator hier_block*/ + 45 | module sub1 (byte_ifs.receiver in, byte_ifs.sender out); /*verilator hier_block*/ | ^~ ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. %Error: t/t_hier_block1_bad.v:45:52: Modport cannot be used at the hierarchical block boundary : ... note: In instance 't.i_sub1' - 45 | module sub1 (byte_ifs.receiver in, byte_ifs.sender out); /*verilator hier_block*/ + 45 | module sub1 (byte_ifs.receiver in, byte_ifs.sender out); /*verilator hier_block*/ | ^~~ %Error: Exiting due to diff --git a/test_regress/t/t_hier_block_threads_bad.out b/test_regress/t/t_hier_block_threads_bad.out index c82c09c9b..7d31c58b0 100644 --- a/test_regress/t/t_hier_block_threads_bad.out +++ b/test_regress/t/t_hier_block_threads_bad.out @@ -1,6 +1,6 @@ %Error: t/t_hier_block_threads_bad.v:23:8: Hierarchical blocks cannot be scheduled on more threads than in thread pool, threads = 4 hierarchical block threads = 8 : ... note: In instance 't.genblk1[1].hierCore' - 23 | module Core(input clk); /*verilator hier_block*/ + 23 | module Core(input clk); /*verilator hier_block*/ | ^~~~ ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. %Error-UNSUPPORTED: t/t_hier_block_threads_bad.vlt:9:1: Specifying workers for nested hierarchical blocks diff --git a/test_regress/t/t_lint_badvltpragma_bad.out b/test_regress/t/t_lint_badvltpragma_bad.out index b99627491..2535f453b 100644 --- a/test_regress/t/t_lint_badvltpragma_bad.out +++ b/test_regress/t/t_lint_badvltpragma_bad.out @@ -1,5 +1,5 @@ %Error-BADVLTPRAGMA: t/t_lint_badvltpragma_bad.v:7:3: Unknown verilator comment: '/*verilator lintt_off WIDTH <--- Warning (lint_off misspelled)*/' - 7 | /*verilator lintt_off WIDTH <--- Warning (lint_off misspelled)*/ + 7 | /*verilator lintt_off WIDTH <--- Warning (lint_off misspelled)*/ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ... For error description see https://verilator.org/warn/BADVLTPRAGMA?v=latest %Error: Exiting due to diff --git a/test_regress/t/t_lint_restore_prag_bad.out b/test_regress/t/t_lint_restore_prag_bad.out index 4b1d62de7..54fdb1bb5 100644 --- a/test_regress/t/t_lint_restore_prag_bad.out +++ b/test_regress/t/t_lint_restore_prag_bad.out @@ -1,5 +1,5 @@ %Error: t/t_lint_restore_prag_bad.v:10:4: /*verilator lint_restore*/ without matching save - 10 | /*verilator lint_restore*/ + 10 | /*verilator lint_restore*/ | ^~~~~~~~~~~~~~~~~~~~~~~~~~ ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. %Error: Exiting due to diff --git a/test_regress/t/t_metacmt_fargs.py b/test_regress/t/t_metacmt_fargs.py new file mode 100755 index 000000000..06454285a --- /dev/null +++ b/test_regress/t/t_metacmt_fargs.py @@ -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() diff --git a/test_regress/t/t_metacmt_fargs.v b/test_regress/t/t_metacmt_fargs.v new file mode 100644 index 000000000..2264fc67b --- /dev/null +++ b/test_regress/t/t_metacmt_fargs.v @@ -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 diff --git a/test_regress/t/t_metacmt_fargs_bad.out b/test_regress/t/t_metacmt_fargs_bad.out new file mode 100644 index 000000000..c7754b043 --- /dev/null +++ b/test_regress/t/t_metacmt_fargs_bad.out @@ -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. diff --git a/test_regress/t/t_metacmt_fargs_bad.py b/test_regress/t/t_metacmt_fargs_bad.py new file mode 100755 index 000000000..54eb6c48d --- /dev/null +++ b/test_regress/t/t_metacmt_fargs_bad.py @@ -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() diff --git a/test_regress/t/t_metacmt_fargs_bad.v b/test_regress/t/t_metacmt_fargs_bad.v new file mode 100644 index 000000000..93649c65e --- /dev/null +++ b/test_regress/t/t_metacmt_fargs_bad.v @@ -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 diff --git a/test_regress/t/t_metacmt_onoff.out b/test_regress/t/t_metacmt_onoff.out index 1c8f60b7c..1d5f8006b 100644 --- a/test_regress/t/t_metacmt_onoff.out +++ b/test_regress/t/t_metacmt_onoff.out @@ -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 diff --git a/test_regress/t/t_parse_sync_bad.out b/test_regress/t/t_parse_sync_bad.out index ad7479297..d3d33ca66 100644 --- a/test_regress/t/t_parse_sync_bad.out +++ b/test_regress/t/t_parse_sync_bad.out @@ -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 diff --git a/test_regress/t/t_pp_underline_bad.out b/test_regress/t/t_pp_underline_bad.out index c6cf038e0..663d52e91 100644 --- a/test_regress/t/t_pp_underline_bad.out +++ b/test_regress/t/t_pp_underline_bad.out @@ -6,7 +6,7 @@ 10 | case (1'b1) // synopsys_full_case | ^~~~~~~~~~~~~~~~~~~~~ %Error-BADVLTPRAGMA: t/t_pp_underline_bad.v:8:4: Unknown verilator comment: '/*verilator _no_inline_module*/' - 8 | /*verilator _no_inline_module*/ + 8 | /*verilator _no_inline_module*/ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ... For error description see https://verilator.org/warn/BADVLTPRAGMA?v=latest %Error: Exiting due to diff --git a/test_regress/t/t_preproc.out b/test_regress/t/t_preproc.out index 65614fbd2..785b37dd3 100644 --- a/test_regress/t/t_preproc.out +++ b/test_regress/t/t_preproc.out @@ -63,10 +63,10 @@ At file "t/t_preproc_inc2.vh" line 5 `line 15 "t/t_preproc.v" 0 -/*verilator pass_thru comment*/ +/*verilator pass_thru comment*/ `line 17 "t/t_preproc.v" 0 -/*verilator pass_thru_comment2*/ +/*verilator pass_thru_comment2*/ `line 19 "t/t_preproc.v" 0 @@ -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 diff --git a/test_regress/t/t_preproc_comments.out b/test_regress/t/t_preproc_comments.out index fe2c0e2c2..9054c0fec 100644 --- a/test_regress/t/t_preproc_comments.out +++ b/test_regress/t/t_preproc_comments.out @@ -1,39 +1,39 @@ `line 1 "t/t_preproc.v" 1 -// DESCRIPTION: Verilator: Verilog Test module -// This file ONLY is placed under the Creative Commons Public Domain, for -// any use, without warranty, 2000-2011 by Wilson Snyder. -// SPDX-License-Identifier: CC0-1.0 +// DESCRIPTION: Verilator: Verilog Test module +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2000-2011 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 `line 6 "t/t_preproc.v" 0 -// This file intentionally includes some tabs +// This file intentionally includes some tabs `line 8 "t/t_preproc.v" 0 -//=========================================================================== -// Includes +//=========================================================================== +// Includes `line 10 "t/t_preproc.v" 0 `line 1 "t/t_preproc_inc2.vh" 1 -// DESCRIPTION: Verilog::Preproc: Example source code +// DESCRIPTION: Verilog::Preproc: Example source code `line 2 "t/t_preproc_inc2.vh" 0 -// This file ONLY is placed under the Creative Commons Public Domain, for -// any use, without warranty, 2000-2007 by Wilson Snyder. -// SPDX-License-Identifier: CC0-1.0 +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2000-2007 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 At file "t/t_preproc_inc2.vh" line 5 `line 7 "t/t_preproc_inc2.vh" 0 `line 1 "t/t_preproc_inc3.vh" 1 -// DESCRIPTION: Verilog::Preproc: Example source code +// DESCRIPTION: Verilog::Preproc: Example source code `line 2 "t/t_preproc_inc3.vh" 0 -// This file ONLY is placed under the Creative Commons Public Domain, for -// any use, without warranty, 2000-2007 by Wilson Snyder. -// SPDX-License-Identifier: CC0-1.0 +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2000-2007 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 `line 6 "t/t_preproc_inc3.vh" 0 - // FOO + // FOO At file "t/t_preproc_inc3.vh" line 10 `line 12 "inc3_a_filename_from_line_directive_with_LINE" 0 At file "inc3_a_filename_from_line_directive_with_LINE" line 12 @@ -43,7 +43,7 @@ At file "t/t_preproc_inc2.vh" line 5 `line 103 "inc3_a_filename_from_line_directive" 0 - // guard + // guard `line 106 "inc3_a_filename_from_line_directive" 0 @@ -59,23 +59,23 @@ At file "t/t_preproc_inc2.vh" line 5 `line 12 "t/t_preproc.v" 0 -//=========================================================================== -// Comments +//=========================================================================== +// Comments `line 15 "t/t_preproc.v" 0 -/* verilator pass_thru comment */ +/* verilator pass_thru comment */ `line 17 "t/t_preproc.v" 0 -// verilator pass_thru_comment2 +// verilator pass_thru_comment2 `line 19 "t/t_preproc.v" 0 -//=========================================================================== -// Defines +//=========================================================================== +// Defines `line 22 "t/t_preproc.v" 0 -// DEF_A0 set by command line +// DEF_A0 set by command line wire [3:0] q = { 1'b1 , 1'b0 , @@ -89,8 +89,8 @@ text. `line 34 "t/t_preproc.v" 0 -foo /*this */ bar /* this too */ -foobar2 // but not +foo /*this */ bar /* this too */ +foobar2 // but not `line 39 "t/t_preproc.v" 0 @@ -104,7 +104,7 @@ foobar2 // but not `line 48 "t/t_preproc.v" 0 -/*******COMMENT*****/ +/*******COMMENT*****/ first part `line 49 "t/t_preproc.v" 0 second part @@ -120,7 +120,7 @@ first part Line_Preproc_Check 51 `line 53 "t/t_preproc.v" 0 -//=========================================================================== +//=========================================================================== `line 55 "t/t_preproc.v" 0 @@ -148,7 +148,7 @@ firstline comma","line LLZZ firstline comma","line `line 74 "t/t_preproc.v" 0 -x y LLZZ "a" y // IEEE 1800-2023 clarified that "a" not to substitute +x y LLZZ "a" y // IEEE 1800-2023 clarified that "a" not to substitute `line 77 "t/t_preproc.v" 0 @@ -177,12 +177,12 @@ arg suffix_after_space $c("Zap(\"","bug2","\");");; `line 94 "t/t_preproc.v" 0 -/* Define inside comment: `DEEPER and `WITHTICK */ -// More commentary: `zap(bug1); `zap("bug2"); +/* Define inside comment: `DEEPER and `WITHTICK */ +// More commentary: `zap(bug1); `zap("bug2"); `line 97 "t/t_preproc.v" 0 -//====================================================================== -// display passthru +//====================================================================== +// display passthru `line 100 "t/t_preproc.v" 0 @@ -192,7 +192,7 @@ arg suffix_after_space initial begin - //$display(`msg( \`, \`)); // Illegal + //$display(`msg( \`, \`)); // Illegal $display("pre thrupre thrumid thrupost post: \"right side\""); $display("left side: \"right side\""); $display("left side: \"right side\""); @@ -200,26 +200,26 @@ arg suffix_after_space $display("na: \"right_side\""); $display("prep ( midp1 left_side midp2 ( outp ) ): \"right_side\""); $display("na: \"nana\""); - $display("left_side right_side // Doesn't expand: \"left_side right_side // Doesn't expand\""); // Results vary between simulators - $display(": \"\""); // Empty + $display("left_side right_side // Doesn't expand: \"left_side right_side // Doesn't expand\""); // Results vary between simulators + $display(": \"\""); // Empty $display("left side: \"right side\""); $display("left side: \"right side\""); $display("standalone"); `line 121 "t/t_preproc.v" 0 - // Unspecified when the stringification has multiple lines + // Unspecified when the stringification has multiple lines $display("twoline: \"first second\""); - //$display(`msg(left side, \ right side \ )); // Not sure \{space} is legal. + //$display(`msg(left side, \ right side \ )); // Not sure \{space} is legal. $write("*-* All Finished *-*\n"); $finish; end endmodule `line 131 "t/t_preproc.v" 0 -//====================================================================== -// rt.cpan.org bug34429 +//====================================================================== +// rt.cpan.org bug34429 `line 134 "t/t_preproc.v" 0 @@ -235,7 +235,7 @@ wire tmp_d1 = d1; `line 140 "t/t_preproc.v" 0 wire tmp_o1 = tmp_d1 + 1; `line 140 "t/t_preproc.v" 0 -assign o1 = tmp_o1 ; // expansion is OK +assign o1 = tmp_o1 ; // expansion is OK endmodule module add2 ( input wire d2, output wire o2); @@ -244,7 +244,7 @@ wire tmp_d2 = d2; `line 143 "t/t_preproc.v" 0 wire tmp_o2 = tmp_d2 + 1; `line 143 "t/t_preproc.v" 0 -assign o2 = tmp_o2 ; // expansion is bad +assign o2 = tmp_o2 ; // expansion is bad endmodule `line 146 "t/t_preproc.v" 0 @@ -255,7 +255,7 @@ endmodule `line 152 "t/t_preproc.v" 0 -// parameterized macro with arguments that are macros +// parameterized macro with arguments that are macros @@ -269,11 +269,11 @@ endmodule `line 157 "t/t_preproc.v" 0 psl cover { ~m5k.f .ctl._ctl_mvldx_m1.d[i] & m5k.f .ctl._ctl_mvldx_m1.q[i] & !m5k.f .ctl._ctl_mvldx_m1.cond & ((m5k.f .ctl.alive & m5k.f .ctl.alive_m1))} report "fondNoFall: m5kc_fcl._ctl_mvldx_m1"; `line 157 "t/t_preproc.v" 0 - end endgenerate // ignorecmt + end endgenerate // ignorecmt `line 159 "t/t_preproc.v" 0 -//====================================================================== -// Quotes are legal in protected blocks. Grr. +//====================================================================== +// Quotes are legal in protected blocks. Grr. module prot(); `protected I!#r#e6<_Q{{E2+]I3<[3s)1@D|'E''i!O?]jD>Jo_![Cl) @@ -281,11 +281,11 @@ module prot(); `line 165 "t/t_preproc.v" 0 `endprotected endmodule -//" +//" `line 169 "t/t_preproc.v" 0 -//====================================================================== -// Check IEEE 1800-2017 `pragma protect encrypted modules +//====================================================================== +// Check IEEE 1800-2017 `pragma protect encrypted modules module t_lint_pragma_protected; `line 173 "t/t_preproc.v" 0 @@ -337,7 +337,7 @@ ZCBXb3JrIGFzIG== `pragma protect end_protected `line 216 "t/t_preproc.v" 0 -// encoding envelope +// encoding envelope `pragma protect `pragma protect end @@ -345,8 +345,8 @@ ZCBXb3JrIGFzIG== endmodule `line 222 "t/t_preproc.v" 0 -//====================================================================== -// macro call with define that has comma +//====================================================================== +// macro call with define that has comma @@ -361,17 +361,17 @@ begin addr <= ({regs[6], regs[7]} + 1); rd <= 1; end begin addr <= ({regs[6], regs[7]}); wdata <= (rdata); wr <= 1; end more `line 236 "t/t_preproc.v" 0 -//====================================================================== -// include of parameterized file +//====================================================================== +// include of parameterized file `line 239 "t/t_preproc.v" 0 `line 1 "t/t_preproc_inc4.vh" 1 -// DESCRIPTION: Verilog::Preproc: Example source code +// DESCRIPTION: Verilog::Preproc: Example source code `line 2 "t/t_preproc_inc4.vh" 0 -// This file ONLY is placed under the Creative Commons Public Domain, for -// any use, without warranty, 2000-2011 by Wilson Snyder. -// SPDX-License-Identifier: CC0-1.0 +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2000-2011 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 `line 6 "t/t_preproc_inc4.vh" 0 @@ -392,8 +392,8 @@ begin addr <= ({regs[6], regs[7]}); wdata <= (rdata); wr <= 1; end more `line 249 "t/t_preproc.v" 0 -//====================================================================== -// macro call with , in {} +//====================================================================== +// macro call with , in {} `line 252 "t/t_preproc.v" 0 @@ -403,8 +403,8 @@ $blah(this.logfile,vec[1,2,3]); $blah(this.logfile,{blah.name(), " is not foo"}); `line 258 "t/t_preproc.v" 0 -//====================================================================== -// pragma/default net type +//====================================================================== +// pragma/default net type `line 261 "t/t_preproc.v" 0 `pragma foo = 1 @@ -412,8 +412,8 @@ $blah(this.logfile,{blah.name(), " is not foo"}); `default_nettype uwire `line 265 "t/t_preproc.v" 0 -//====================================================================== -// Ifdef +//====================================================================== +// Ifdef `line 268 "t/t_preproc.v" 0 @@ -424,11 +424,11 @@ $blah(this.logfile,{blah.name(), " is not foo"}); Line_Preproc_Check 272 `line 274 "t/t_preproc.v" 0 -//====================================================================== -// bug84 +//====================================================================== +// 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,25 +436,25 @@ 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 -//====================================================================== -// defines split arguments +//====================================================================== +// defines split arguments `line 290 "t/t_preproc.v" 0 -beginend // 2001 spec doesn't require two tokens, so "beginend" ok -beginend // 2001 spec doesn't require two tokens, so "beginend" ok -"beginend" // No space "beginend" +beginend // 2001 spec doesn't require two tokens, so "beginend" ok +beginend // 2001 spec doesn't require two tokens, so "beginend" ok +"beginend" // No space "beginend" `line 298 "t/t_preproc.v" 0 -//====================================================================== -// bug106 +//====================================================================== +// bug106 `\esc`def @@ -463,8 +463,8 @@ beginend // 2001 spec doesn't require two tokens, so "beginend" ok Not a \`define `line 306 "t/t_preproc.v" 0 -//====================================================================== -// misparsed comma in submacro +//====================================================================== +// misparsed comma in submacro @@ -472,14 +472,14 @@ Not a \`define x,y)--bee submacro has comma paren `line 314 "t/t_preproc.v" 0 -//====================================================================== -// bug191 +//====================================================================== +// bug191 $display("bits %d %d", $bits(foo), 10); `line 319 "t/t_preproc.v" 0 -//====================================================================== -// 1800-2009 +//====================================================================== +// 1800-2009 @@ -488,8 +488,8 @@ $display("bits %d %d", $bits(foo), 10); `line 327 "t/t_preproc.v" 0 -//====================================================================== -// bug202 +//====================================================================== +// bug202 @@ -528,11 +528,11 @@ $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 \ - line2*/ + line2*/ @@ -544,13 +544,13 @@ $display("bits %d %d", $bits(foo), 10); `line 352 "t/t_preproc.v" 0 /* multi - line 3*/ + line 3*/ `line 352 "t/t_preproc.v" 0 def i `line 354 "t/t_preproc.v" 0 -//====================================================================== +//====================================================================== `line 356 "t/t_preproc.v" 0 @@ -566,21 +566,21 @@ $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 - also3 // CMT NOT (nodef) + also3 // CMT NOT (nodef) HAS a NEW @@ -588,7 +588,7 @@ HAS a NEW LINE `line 375 "t/t_preproc.v" 0 -//====================================================================== +//====================================================================== `line 377 "t/t_preproc.v" 0 @@ -619,7 +619,7 @@ EXP: do if (start("verilog/inc1.v", 25)) begin message({"Blah-", "clx_scen", " `line 399 "t/t_preproc.v" 0 do `line 399 "t/t_preproc.v" 0 - /* synopsys translate_off */ + /* synopsys translate_off */ `line 399 "t/t_preproc.v" 0 `line 399 "t/t_preproc.v" 0 @@ -635,12 +635,12 @@ EXP: do if (start("verilog/inc1.v", 25)) begin message({"Blah-", "clx_scen", " `line 399 "t/t_preproc.v" 0 end `line 399 "t/t_preproc.v" 0 - /* synopsys translate_on */ + /* synopsys translate_on */ `line 399 "t/t_preproc.v" 0 while(0); `line 401 "t/t_preproc.v" 0 -//====================================================================== +//====================================================================== `line 403 "t/t_preproc.v" 0 @@ -655,19 +655,19 @@ EXP: do if (start("verilog/inc1.v", 25)) begin message({"Blah-", "clx_scen", " `line 408 "t/t_preproc.v" 0 -//`ifndef def_fooed_2 `error "No def_fooed_2" `endif +//`ifndef def_fooed_2 `error "No def_fooed_2" `endif EXP: This is fooed This is fooed EXP: This is fooed_2 This is fooed_2 `line 415 "t/t_preproc.v" 0 -//====================================================================== +//====================================================================== np np -//====================================================================== -// It's unclear if the spec allows this; is text_macro_idenitfier before or after substitution? +//====================================================================== +// It's unclear if the spec allows this; is text_macro_idenitfier before or after substitution? @@ -678,8 +678,8 @@ np `line 429 "t/t_preproc.v" 0 -//====================================================================== -// Metaprogramming +//====================================================================== +// Metaprogramming @@ -694,18 +694,18 @@ np `line 441 "t/t_preproc.v" 0 hello3hello3hello3 hello4hello4hello4hello4 -//====================================================================== -// Include from stringification +//====================================================================== +// Include from stringification `line 447 "t/t_preproc.v" 0 `line 1 "t/t_preproc_inc4.vh" 1 -// DESCRIPTION: Verilog::Preproc: Example source code +// DESCRIPTION: Verilog::Preproc: Example source code `line 2 "t/t_preproc_inc4.vh" 0 -// This file ONLY is placed under the Creative Commons Public Domain, for -// any use, without warranty, 2000-2011 by Wilson Snyder. -// SPDX-License-Identifier: CC0-1.0 +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2000-2011 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 `line 6 "t/t_preproc_inc4.vh" 0 @@ -715,9 +715,9 @@ hello4hello4hello4hello4 `line 448 "t/t_preproc.v" 0 -//====================================================================== -// Defines doing defines -// Note the newline on the end - required to form the end of a define +//====================================================================== +// Defines doing defines +// Note the newline on the end - required to form the end of a define @@ -729,8 +729,8 @@ hello4hello4hello4hello4 Line_Preproc_Check 460 -//====================================================================== -// Quoted multiline - track line numbers, and ensure \\n gets propagated +//====================================================================== +// Quoted multiline - track line numbers, and ensure \\n gets propagated @@ -741,14 +741,14 @@ Line_Preproc_Check 466 BAR " `line 469 "t/t_preproc.v" 0 Line_Preproc_Check 469 -//====================================================================== -// bug283 +//====================================================================== +// bug283 `line 473 "t/t_preproc.v" 0 -// EXP: abc +// EXP: abc abc @@ -767,14 +767,14 @@ sonet_frame EXP: sonet_frame sonet_frame -// This result varies between simulators +// This result varies between simulators EXP: sonet_frame sonet_frame `line 499 "t/t_preproc.v" 0 -// The existance of non-existance of a base define can make a difference +// The existance of non-existance of a base define can make a difference EXP: module zzz ; endmodule @@ -788,95 +788,95 @@ module a_b ; endmodule module a_b ; endmodule `line 511 "t/t_preproc.v" 0 -//====================================================================== -// bug311 -integer/*NEED_SPACE*/ foo; -//====================================================================== -// bug441 +//====================================================================== +// bug311 +integer/*NEED_SPACE*/foo; +//====================================================================== +// bug441 module t; - //----- - // case provided - // note this does NOT escape as suggested in the mail + //----- + // case provided + // note this does NOT escape as suggested in the mail initial begin : \`LEX_CAT(a[0],_assignment) `line 523 "t/t_preproc.v" 0 $write("GOT%%m='%m' EXP='%s'\n", "t.\\`LEX_CAT(a[0],_assignment) "); end - //----- - // SHOULD(simulator-dependant): Backslash doesn't prevent arguments from - // substituting and the \ staying in the expansion - // Note space after name is important so when substitute it has ending whitespace + //----- + // SHOULD(simulator-dependant): Backslash doesn't prevent arguments from + // substituting and the \ staying in the expansion + // Note space after name is important so when substitute it has ending whitespace initial begin : \a[0]_assignment_a[1] `line 530 "t/t_preproc.v" 0 $write("GOT%%m='%m' EXP='%s'\n", "t.\\a[0]_assignment_a[1] "); end - //----- + //----- - // RULE: Ignoring backslash does NOT allow an additional expansion level - // (Because ESC gets expanded then the \ has it's normal escape meaning) + // RULE: Ignoring backslash does NOT allow an additional expansion level + // (Because ESC gets expanded then the \ has it's normal escape meaning) initial begin : \`CAT(pp,suffix) $write("GOT%%m='%m' EXP='%s'\n", "t.\\`CAT(pp,suffix) "); end - //----- + //----- - // Similar to above; \ does not allow expansion after substitution + // Similar to above; \ does not allow expansion after substitution initial begin : \`CAT(ff,bb) `line 544 "t/t_preproc.v" 0 $write("GOT%%m='%m' EXP='%s'\n", "t.\\`CAT(ff,bb) "); end - //----- + //----- - // MUST: Unknown macro with backslash escape stays as escaped symbol name + // MUST: Unknown macro with backslash escape stays as escaped symbol name initial begin : \`zzz `line 550 "t/t_preproc.v" 0 $write("GOT%%m='%m' EXP='%s'\n", "t.\\`zzz "); end - //----- + //----- - // SHOULD(simulator-dependant): Known macro with backslash escape expands + // SHOULD(simulator-dependant): Known macro with backslash escape expands initial begin : \`FOO `line 557 "t/t_preproc.v" 0 $write("GOT%%m='%m' OTHER_EXP='%s'\n OUR_EXP='%s'", "t.bar ","t.\\`FOO "); end - // SHOULD(simulator-dependant): Prefix breaks the above + // SHOULD(simulator-dependant): Prefix breaks the above initial begin : \xx`FOO `line 559 "t/t_preproc.v" 0 $write("GOT%%m='%m' EXP='%s'\n", "t.\\xx`FOO "); end - //----- - // MUST: Unknown macro not under call with backslash escape doesn't expand + //----- + // MUST: Unknown macro not under call with backslash escape doesn't expand initial begin : \`UNKNOWN $write("GOT%%m='%m' EXP='%s'\n", "t.\\`UNKNOWN "); end - //----- - // MUST: Unknown macro not under call doesn't expand + //----- + // MUST: Unknown macro not under call doesn't expand initial begin : \`DEF_NO_EXPAND $write("GOT%%m='%m' EXP='%s'\n", "t.\\`DEF_NO_EXPAND "); end - //----- - // bug441 derivative - // Clarified in IEEE 1800-2023: Quotes prevent arguments from expanding + //----- + // bug441 derivative + // Clarified in IEEE 1800-2023: Quotes prevent arguments from expanding initial $write("GOT='%s' EXP='%s'\n", "foo name baz", "foo bar baz"); - //----- - // RULE: Because there are quotes after substituting STR, the `A does NOT expand + //----- + // RULE: Because there are quotes after substituting STR, the `A does NOT expand initial $write("GOT='%s' EXP='%s'\n", "foo name baz", "foo `A(bar) baz"); - //---- - // bug845 + //---- + // bug845 initial $write("Slashed=`%s'\n", "1//2.3"); - //---- - // bug915 + //---- + // bug915 initial @@ -885,8 +885,8 @@ module t; endmodule `line 593 "t/t_preproc.v" 0 -//====================================================================== -//bug1225 +//====================================================================== +//bug1225 `line 596 "t/t_preproc.v" 0 @@ -933,7 +933,7 @@ XYS_FAMILY = XYS_foo `line 634 "t/t_preproc.v" 0 -//==== +//==== `line 636 "t/t_preproc.v" 0 @@ -972,16 +972,16 @@ XYS_FAMILY = XYS_foo `line 667 "t/t_preproc.v" 0 - // NEVER + // NEVER `line 669 "t/t_preproc.v" 0 -//bug1227 +//bug1227 (.mySig (myInterface.pa5), `line 673 "t/t_preproc.v" 0 -//====================================================================== -// Stringify bug +//====================================================================== +// Stringify bug `line 676 "t/t_preproc.v" 0 @@ -1012,13 +1012,13 @@ module pcc2_cfg; endmodule `line 693 "t/t_preproc.v" 0 -//====================================================================== -// Verilog-Perl bug1668 +//====================================================================== +// Verilog-Perl bug1668 "`NOT_DEFINED_STR" `line 698 "t/t_preproc.v" 0 -//====================================================================== +//====================================================================== """First line with "quoted"\nSecond line\ Third line""" @@ -1032,13 +1032,13 @@ Second line""" """QQQ defval""" `line 710 "t/t_preproc.v" 0 -// string concat bug +// string concat bug "string argument" `line 714 "t/t_preproc.v" 0 -//====================================================================== -// See issue #5094 - IEEE 1800-2023 clarified proper behavior +//====================================================================== +// See issue #5094 - IEEE 1800-2023 clarified proper behavior `line 717 "t/t_preproc.v" 0 @@ -1047,9 +1047,9 @@ bar "foo foo foo" bar bar """foo foo foo""" bar `line 722 "t/t_preproc.v" 0 -//====================================================================== -// IEEE mandated predefines - // undefineall should have no effect on these +//====================================================================== +// IEEE mandated predefines + // undefineall should have no effect on these predef 0 0 predef 1 1 predef 2 2 @@ -1065,13 +1065,13 @@ predef -1 -1 predef 0 0 predef 1 1 predef 2 2 -//====================================================================== -// After `undefineall above, for testing --dump-defines +//====================================================================== +// After `undefineall above, for testing --dump-defines `line 744 "t/t_preproc.v" 0 -//====================================================================== -// Stringify in nested macro +//====================================================================== +// Stringify in nested macro @@ -1084,8 +1084,8 @@ string boo = "testx,ytest x x,y"; string boo = "testtest x,y xquux(test)"; `line 757 "t/t_preproc.v" 0 -//====================================================================== -// Define with --preproc-defines needs to keep backslashes +//====================================================================== +// Define with --preproc-defines needs to keep backslashes `line 760 "t/t_preproc.v" 0 diff --git a/test_regress/t/t_preproc_defines.out b/test_regress/t/t_preproc_defines.out index 52914a989..d57c0c08f 100644 --- a/test_regress/t/t_preproc_defines.out +++ b/test_regress/t/t_preproc_defines.out @@ -73,10 +73,10 @@ At file "t/t_preproc_inc2.vh" line 5 `line 15 "t/t_preproc.v" 0 -/*verilator pass_thru comment*/ +/*verilator pass_thru comment*/ `line 17 "t/t_preproc.v" 0 -/*verilator pass_thru_comment2*/ +/*verilator pass_thru_comment2*/ `line 19 "t/t_preproc.v" 0 @@ -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 diff --git a/test_regress/t/t_sarif.sarif.out b/test_regress/t/t_sarif.sarif.out index 61eb1a6ea..6d5fae4b2 100644 --- a/test_regress/t/t_sarif.sarif.out +++ b/test_regress/t/t_sarif.sarif.out @@ -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 } ], diff --git a/test_regress/t/t_split_var_1_bad.out b/test_regress/t/t_split_var_1_bad.out index 2ff9868da..071aefe15 100644 --- a/test_regress/t/t_split_var_1_bad.out +++ b/test_regress/t/t_split_var_1_bad.out @@ -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]; diff --git a/test_regress/t/t_var_rsvd_bad.out b/test_regress/t/t_var_rsvd_bad.out index 93b831450..269c38632 100644 --- a/test_regress/t/t_var_rsvd_bad.out +++ b/test_regress/t/t_var_rsvd_bad.out @@ -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