Internals: Some prep from branch towards multitrace (#5813 prep)
This commit is contained in:
parent
8c7c6c594a
commit
a7e6efb4c0
|
|
@ -664,7 +664,8 @@ class EmitCTrace final : EmitCFunc {
|
|||
"IPTION: Verilator output: Tracing implementation internals\n");
|
||||
|
||||
// Includes
|
||||
puts("#include \"" + v3Global.opt.traceSourceLang() + ".h\"\n");
|
||||
for (const string& base : v3Global.opt.traceSourceLangs())
|
||||
puts("#include \"" + base + ".h\"\n");
|
||||
puts("#include \"" + EmitCUtil::symClassName() + ".h\"\n");
|
||||
puts("\n");
|
||||
}
|
||||
|
|
@ -693,7 +694,8 @@ class EmitCTrace final : EmitCFunc {
|
|||
"IPTION: Verilator output: Tracing declarations\n");
|
||||
|
||||
// Includes
|
||||
typesFp()->puts("#include \"" + v3Global.opt.traceSourceLang() + ".h\"\n");
|
||||
for (const string& base : v3Global.opt.traceSourceLangs())
|
||||
typesFp()->puts("#include \"" + base + ".h\"\n");
|
||||
typesFp()->puts("\n");
|
||||
|
||||
typesFp()->puts("\nvoid " + EmitCUtil::prefixNameProtect(m_modp) + "__"
|
||||
|
|
@ -860,7 +862,7 @@ class EmitCTrace final : EmitCFunc {
|
|||
|
||||
int emitTraceDeclDType(AstNodeDType* nodep) {
|
||||
// Return enum number or -1 for none
|
||||
if (v3Global.opt.traceFormat().fst()) {
|
||||
if (v3Global.opt.traceEnabledFst()) {
|
||||
// Skip over refs-to-refs, but stop before final ref so can get data type name
|
||||
// Alternatively back in V3Width we could push enum names from upper typedefs
|
||||
if (AstEnumDType* const enump = VN_CAST(nodep->skipRefToEnump(), EnumDType)) {
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ class EmitCModel final : public EmitCFunc {
|
|||
puts("\n");
|
||||
puts("class " + EmitCUtil::symClassName() + ";\n");
|
||||
puts("class " + EmitCUtil::prefixNameProtect(modp) + ";\n"); // For rootp pointer only
|
||||
if (v3Global.opt.trace()) puts("class " + v3Global.opt.traceClassLang() + ";\n");
|
||||
for (const string& base : v3Global.opt.traceClassLangs()) puts("class " + base + ";\n");
|
||||
emitModCUse(modp, VUseType::INT_FWD_CLASS); // Note: This is needed for cell forwarding
|
||||
|
||||
puts("\n");
|
||||
|
|
@ -637,9 +637,8 @@ class EmitCModel final : public EmitCFunc {
|
|||
|
||||
puts("\n");
|
||||
puts("#include \"" + EmitCUtil::pchClassName() + ".h\"\n");
|
||||
if (v3Global.opt.trace()) {
|
||||
puts("#include \"" + v3Global.opt.traceSourceLang() + ".h\"\n");
|
||||
}
|
||||
for (const string& base : v3Global.opt.traceSourceLangs())
|
||||
puts("#include \"" + base + ".h\"\n");
|
||||
|
||||
emitConstructorImplementation(modp);
|
||||
emitDestructorImplementation();
|
||||
|
|
|
|||
|
|
@ -416,7 +416,8 @@ void EmitCSyms::emitSymHdr() {
|
|||
ofp()->putsIntTopInclude();
|
||||
puts("#include \"verilated.h\"\n");
|
||||
if (v3Global.needTraceDumper()) {
|
||||
puts("#include \"" + v3Global.opt.traceSourceLang() + ".h\"\n");
|
||||
for (const string& base : v3Global.opt.traceSourceLangs())
|
||||
puts("#include \"" + base + ".h\"\n");
|
||||
}
|
||||
if (v3Global.opt.usesProfiler()) puts("#include \"verilated_profiler.h\"\n");
|
||||
|
||||
|
|
@ -747,7 +748,7 @@ void EmitCSyms::emitSymImp() {
|
|||
puts("if (VL_UNLIKELY(!__Vm_dumperp)) {\n");
|
||||
puts("__Vm_dumperp = new " + v3Global.opt.traceClassLang() + "();\n");
|
||||
puts("__Vm_modelp->trace(__Vm_dumperp, 0, 0);\n");
|
||||
puts("std::string dumpfile = _vm_contextp__->dumpfileCheck();\n");
|
||||
puts("const std::string dumpfile = _vm_contextp__->dumpfileCheck();\n");
|
||||
puts("__Vm_dumperp->open(dumpfile.c_str());\n");
|
||||
puts("__Vm_dumping = true;\n");
|
||||
puts("}\n");
|
||||
|
|
|
|||
|
|
@ -226,7 +226,8 @@ std::vector<std::string> V3Global::verilatedCppFiles() {
|
|||
if (v3Global.opt.vpi()) result.emplace_back("verilated_vpi.cpp");
|
||||
if (v3Global.opt.savable()) result.emplace_back("verilated_save.cpp");
|
||||
if (v3Global.opt.coverage()) result.emplace_back("verilated_cov.cpp");
|
||||
if (v3Global.opt.trace()) result.emplace_back(v3Global.opt.traceSourceBase() + "_c.cpp");
|
||||
for (const string& base : v3Global.opt.traceSourceBases())
|
||||
result.emplace_back(base + "_c.cpp");
|
||||
if (v3Global.usesProbDist()) result.emplace_back("verilated_probdist.cpp");
|
||||
if (v3Global.usesTiming()) result.emplace_back("verilated_timing.cpp");
|
||||
if (v3Global.useRandomizeMethods()) result.emplace_back("verilated_random.cpp");
|
||||
|
|
|
|||
|
|
@ -477,6 +477,41 @@ void V3Options::decorations(FileLine* fl, const string& arg) { // --decorations
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> V3Options::traceClassBases() const VL_MT_SAFE {
|
||||
std::vector<std::string> result;
|
||||
if (traceEnabledFst()) result.emplace_back("VerilatedFst");
|
||||
if (traceEnabledSaif()) result.emplace_back("VerilatedSaif");
|
||||
if (traceEnabledVcd()) result.emplace_back("VerilatedVcd");
|
||||
return result;
|
||||
}
|
||||
std::vector<std::string> V3Options::traceClassLangs() const VL_MT_SAFE {
|
||||
std::vector<std::string> result;
|
||||
for (auto& cbase : traceClassBases()) result.emplace_back(cbase + (systemC() ? "Sc" : "C"));
|
||||
return result;
|
||||
}
|
||||
std::vector<std::string> V3Options::traceSourceBases() const VL_MT_SAFE {
|
||||
std::vector<std::string> result;
|
||||
if (traceEnabledFst()) result.emplace_back("verilated_fst");
|
||||
if (traceEnabledSaif()) result.emplace_back("verilated_saif");
|
||||
if (traceEnabledVcd()) result.emplace_back("verilated_vcd");
|
||||
return result;
|
||||
}
|
||||
std::vector<std::string> V3Options::traceSourceLangs() const VL_MT_SAFE {
|
||||
std::vector<std::string> result = traceSourceBases();
|
||||
for (std::string& str : result) str += systemC() ? "_sc"s : "_c"s;
|
||||
return result;
|
||||
}
|
||||
std::string V3Options::traceClassBase() const VL_MT_SAFE {
|
||||
// Deprecated - Needs to be fixed to support multiple trace, issue #5813
|
||||
UASSERT(!traceClassBases().empty(), "Call traceClassBase only when trace() enabled");
|
||||
return traceClassBases().front();
|
||||
}
|
||||
std::string V3Options::traceClassLang() const VL_MT_SAFE {
|
||||
// Deprecated - Needs to be fixed to support multiple trace, issue #5813
|
||||
UASSERT(!traceClassBases().empty(), "Call traceClassLang only when trace() enabled");
|
||||
return traceClassLangs().front();
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
// File searching
|
||||
|
||||
|
|
@ -903,6 +938,14 @@ void V3Options::notify() VL_MT_DISABLED {
|
|||
m_main = false;
|
||||
}
|
||||
|
||||
if (trace() && !traceEnabledFst() && !traceEnabledSaif() && !traceEnabledVcd()) {
|
||||
m_traceEnabledVcd = true; // No format, with --trace means wanted --trace-vcd
|
||||
}
|
||||
if (traceEnabledFst() || traceEnabledSaif() || traceEnabledVcd()) m_trace = true;
|
||||
const int ntraces = traceEnabledFst() + traceEnabledSaif() + traceEnabledVcd();
|
||||
if (ntraces > 1) // Issue #5813
|
||||
cmdfl->v3error("Only one of --trace-fst, --trace-saif or --trace--vcd may be used");
|
||||
|
||||
if (protectIds()) {
|
||||
if (allPublic()) {
|
||||
// We always call protect() on names, we don't check if public or not
|
||||
|
|
@ -940,7 +983,7 @@ void V3Options::notify() VL_MT_DISABLED {
|
|||
|
||||
if (trace()) {
|
||||
// With --trace-vcd, --trace-threads is ignored
|
||||
if (traceFormat().vcd()) m_traceThreads = 1;
|
||||
if (traceEnabledVcd()) m_traceThreads = 1;
|
||||
}
|
||||
|
||||
UASSERT(!(useTraceParallel() && useTraceOffload()),
|
||||
|
|
@ -1671,20 +1714,15 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
|
|||
DECL_OPTION("-top", Set, &m_topModule);
|
||||
DECL_OPTION("-top-module", Set, &m_topModule);
|
||||
DECL_OPTION("-trace", OnOff, &m_trace);
|
||||
DECL_OPTION("-trace-saif", CbCall, [this]() {
|
||||
m_trace = true;
|
||||
m_traceFormat = TraceFormat::SAIF;
|
||||
});
|
||||
DECL_OPTION("-trace-saif", CbCall, [this]() { m_traceEnabledSaif = true; });
|
||||
DECL_OPTION("-trace-coverage", OnOff, &m_traceCoverage);
|
||||
DECL_OPTION("-trace-depth", Set, &m_traceDepth);
|
||||
DECL_OPTION("-trace-fst", CbCall, [this]() {
|
||||
m_trace = true;
|
||||
m_traceFormat = TraceFormat::FST;
|
||||
m_traceEnabledFst = true;
|
||||
addLdLibs("-lz");
|
||||
});
|
||||
DECL_OPTION("-trace-fst-thread", CbCall, [this, fl]() {
|
||||
m_trace = true;
|
||||
m_traceFormat = TraceFormat::FST;
|
||||
m_traceEnabledFst = true;
|
||||
addLdLibs("-lz");
|
||||
fl->v3warn(DEPRECATED, "Option --trace-fst-thread is deprecated. "
|
||||
"Use --trace-fst with --trace-threads > 0.");
|
||||
|
|
@ -1701,10 +1739,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
|
|||
});
|
||||
DECL_OPTION("-no-trace-top", Set, &m_noTraceTop);
|
||||
DECL_OPTION("-trace-underscore", OnOff, &m_traceUnderscore);
|
||||
DECL_OPTION("-trace-vcd", CbCall, [this]() {
|
||||
m_trace = true;
|
||||
m_traceFormat = TraceFormat::VCD;
|
||||
});
|
||||
DECL_OPTION("-trace-vcd", CbCall, [this]() { m_traceEnabledVcd = true; });
|
||||
|
||||
DECL_OPTION("-U", CbPartialMatch, &V3PreShell::undef);
|
||||
DECL_OPTION("-underline-zero", OnOff, &m_underlineZero); // Deprecated
|
||||
|
|
@ -2127,8 +2162,6 @@ void V3Options::showVersion(bool verbose) {
|
|||
V3Options::V3Options() {
|
||||
m_impp = new V3OptionsImp;
|
||||
|
||||
m_traceFormat = TraceFormat::VCD;
|
||||
|
||||
m_makeDir = "obj_dir";
|
||||
m_unusedRegexp = "*unused*";
|
||||
m_xAssign = "fast";
|
||||
|
|
|
|||
|
|
@ -159,35 +159,6 @@ inline std::ostream& operator<<(std::ostream& os, const VTimescale& rhs) {
|
|||
|
||||
// ######################################################################
|
||||
|
||||
class TraceFormat final {
|
||||
public:
|
||||
enum en : uint8_t { VCD = 0, FST, SAIF } m_e;
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
constexpr TraceFormat(en _e = VCD)
|
||||
: m_e{_e} {}
|
||||
explicit TraceFormat(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
constexpr operator en() const { return m_e; }
|
||||
bool fst() const { return m_e == FST; }
|
||||
bool saif() const { return m_e == SAIF; }
|
||||
bool vcd() const { return m_e == VCD; }
|
||||
string classBase() const VL_MT_SAFE {
|
||||
static const char* const names[] = {"VerilatedVcd", "VerilatedFst", "VerilatedSaif"};
|
||||
return names[m_e];
|
||||
}
|
||||
string sourceName() const VL_MT_SAFE {
|
||||
static const char* const names[] = {"verilated_vcd", "verilated_fst", "verilated_saif"};
|
||||
return names[m_e];
|
||||
}
|
||||
};
|
||||
constexpr bool operator==(const TraceFormat& lhs, const TraceFormat& rhs) {
|
||||
return lhs.m_e == rhs.m_e;
|
||||
}
|
||||
constexpr bool operator==(const TraceFormat& lhs, TraceFormat::en rhs) { return lhs.m_e == rhs; }
|
||||
constexpr bool operator==(TraceFormat::en lhs, const TraceFormat& rhs) { return lhs == rhs.m_e; }
|
||||
|
||||
// ######################################################################
|
||||
|
||||
// Information given by --hierarchical-block option
|
||||
class V3HierarchicalBlockOption final {
|
||||
public:
|
||||
|
|
@ -321,6 +292,9 @@ private:
|
|||
VOptionBool m_timing; // main switch: --timing
|
||||
bool m_trace = false; // main switch: --trace
|
||||
bool m_traceCoverage = false; // main switch: --trace-coverage
|
||||
bool m_traceEnabledFst = false; // main switch: --trace-fst
|
||||
bool m_traceEnabledSaif = false; // main switch: --trace-saif
|
||||
bool m_traceEnabledVcd = false; // main switch: --trace-vcd
|
||||
bool m_traceParams = true; // main switch: --trace-params
|
||||
bool m_traceStructs = false; // main switch: --trace-structs
|
||||
bool m_noTraceTop = false; // main switch: --no-trace-top
|
||||
|
|
@ -366,7 +340,6 @@ private:
|
|||
VTimescale m_timeOverridePrec; // main switch: --timescale-override
|
||||
VTimescale m_timeOverrideUnit; // main switch: --timescale-override
|
||||
int m_traceDepth = 0; // main switch: --trace-depth
|
||||
TraceFormat m_traceFormat; // main switch: --trace or --trace-fst
|
||||
int m_traceMaxArray = 32; // main switch: --trace-max-array
|
||||
int m_traceMaxWidth = 256; // main switch: --trace-max-width
|
||||
int m_traceThreads = 0; // main switch: --trace-threads
|
||||
|
|
@ -565,6 +538,9 @@ public:
|
|||
VOptionBool timing() const { return m_timing; }
|
||||
bool trace() const { return m_trace; }
|
||||
bool traceCoverage() const { return m_traceCoverage; }
|
||||
bool traceEnabledFst() const { return m_traceEnabledFst; }
|
||||
bool traceEnabledSaif() const { return m_traceEnabledSaif; }
|
||||
bool traceEnabledVcd() const { return m_traceEnabledVcd; }
|
||||
bool traceParams() const { return m_traceParams; }
|
||||
bool traceStructs() const { return m_traceStructs; }
|
||||
bool traceUnderscore() const { return m_traceUnderscore; }
|
||||
|
|
@ -638,18 +614,14 @@ public:
|
|||
VTimescale timeComputePrec(const VTimescale& flag) const;
|
||||
VTimescale timeComputeUnit(const VTimescale& flag) const;
|
||||
int traceDepth() const { return m_traceDepth; }
|
||||
TraceFormat traceFormat() const { return m_traceFormat; }
|
||||
bool traceEnabledFst() const { return trace() && traceFormat().fst(); }
|
||||
bool traceEnabledSaif() const { return trace() && traceFormat().saif(); }
|
||||
bool traceEnabledVcd() const { return trace() && traceFormat().vcd(); }
|
||||
int traceMaxArray() const { return m_traceMaxArray; }
|
||||
int traceMaxWidth() const { return m_traceMaxWidth; }
|
||||
int traceThreads() const { return m_traceThreads; }
|
||||
bool useTraceOffload() const { return trace() && traceFormat().fst() && traceThreads() > 1; }
|
||||
bool useTraceOffload() const { return trace() && traceEnabledFst() && traceThreads() > 1; }
|
||||
bool useTraceParallel() const {
|
||||
return trace() && traceFormat().vcd() && (threads() > 1 || hierChild() > 1);
|
||||
return trace() && traceEnabledVcd() && (threads() > 1 || hierChild() > 1);
|
||||
}
|
||||
bool useFstWriterThread() const { return traceThreads() && traceFormat().fst(); }
|
||||
bool useFstWriterThread() const { return traceThreads() && traceEnabledFst(); }
|
||||
unsigned vmTraceThreads() const {
|
||||
return useTraceParallel() ? threads() : useTraceOffload() ? 1 : 0;
|
||||
}
|
||||
|
|
@ -762,12 +734,12 @@ public:
|
|||
bool fTaskifyAll() const { return m_fTaskifyAll; }
|
||||
bool fVarSplit() const { return m_fVarSplit; }
|
||||
|
||||
string traceClassBase() const VL_MT_SAFE { return m_traceFormat.classBase(); }
|
||||
string traceClassLang() const { return m_traceFormat.classBase() + (systemC() ? "Sc" : "C"); }
|
||||
string traceSourceBase() const { return m_traceFormat.sourceName(); }
|
||||
string traceSourceLang() const VL_MT_SAFE {
|
||||
return m_traceFormat.sourceName() + (systemC() ? "_sc" : "_c");
|
||||
}
|
||||
std::string traceClassBase() const VL_MT_SAFE; // Deprecated
|
||||
std::string traceClassLang() const VL_MT_SAFE; // Deprecated
|
||||
std::vector<std::string> traceClassBases() const VL_MT_SAFE;
|
||||
std::vector<std::string> traceClassLangs() const VL_MT_SAFE;
|
||||
std::vector<std::string> traceSourceBases() const VL_MT_SAFE;
|
||||
std::vector<std::string> traceSourceLangs() const VL_MT_SAFE;
|
||||
|
||||
bool hierarchical() const { return m_hierarchical; }
|
||||
int hierChild() const VL_MT_SAFE { return m_hierChild; }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
%Error: Only one of --trace-fst, --trace-saif or --trace--vcd may be used
|
||||
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||
%Error: Exiting due to
|
||||
|
|
@ -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.lint(verilator_flags=['--trace-fst --trace-vcd'],
|
||||
fails=True,
|
||||
expect_filename=test.golden_filename)
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
// 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
|
||||
|
||||
module t;
|
||||
initial $finish;
|
||||
endmodule
|
||||
Loading…
Reference in New Issue