Handle correctly

This commit is contained in:
wsxarcher 2026-03-23 00:48:44 +01:00
parent fd2dfd6982
commit b28fde7e57
73 changed files with 2150 additions and 34 deletions

View File

@ -2926,6 +2926,20 @@ std::string VerilatedContext::dumpfileCheck() const VL_MT_SAFE_EXCLUDES(m_timeDu
}
return out;
}
void VerilatedContext::dumpvarsAdd(int level,
const std::string& hier) VL_MT_SAFE_EXCLUDES(m_timeDumpMutex) {
const VerilatedLockGuard lock{m_timeDumpMutex};
if (level == 0 && hier.empty()) {
m_dumpvars.clear();
} else {
m_dumpvars.emplace_back(level, hier);
}
}
std::vector<VerilatedTraceDumpvarsEntry>
VerilatedContext::dumpvars() const VL_MT_SAFE_EXCLUDES(m_timeDumpMutex) {
const VerilatedLockGuard lock{m_timeDumpMutex};
return m_dumpvars;
}
void VerilatedContext::errorCount(int val) VL_MT_SAFE {
const VerilatedLockGuard lock{m_mutex};
m_s.m_errorCount = val;

View File

@ -110,6 +110,15 @@ class VerilatedVcd;
class VerilatedVcdC;
class VerilatedVcdSc;
struct VerilatedTraceDumpvarsEntry final {
int m_level;
std::string m_hier;
VerilatedTraceDumpvarsEntry(int level, const std::string& hier)
: m_level{level}
, m_hier{hier} {}
};
//=========================================================================
// Basic types
@ -404,6 +413,8 @@ protected:
mutable VerilatedMutex m_timeDumpMutex; // Protect misc slow strings
std::string m_timeFormatSuffix VL_GUARDED_BY(m_timeDumpMutex); // $timeformat printf format
std::string m_dumpfile VL_GUARDED_BY(m_timeDumpMutex); // $dumpfile setting
std::vector<VerilatedTraceDumpvarsEntry>
m_dumpvars VL_GUARDED_BY(m_timeDumpMutex); // $dumpvars settings
struct NonSerialized final { // Non-serialized information
// These are reloaded from on command-line settings, so do not need to persist
@ -656,6 +667,11 @@ public:
void dumpfile(const std::string& flag) VL_MT_SAFE_EXCLUDES(m_timeDumpMutex);
std::string dumpfileCheck() const VL_MT_SAFE_EXCLUDES(m_timeDumpMutex);
// Internal: $dumpvars
void dumpvarsAdd(int level, const std::string& hier) VL_MT_SAFE_EXCLUDES(m_timeDumpMutex);
std::vector<VerilatedTraceDumpvarsEntry> dumpvars() const
VL_MT_SAFE_EXCLUDES(m_timeDumpMutex);
// Internal: --prof-exec related settings
uint64_t profExecStart() const VL_MT_SAFE { return m_ns.m_profExecStart; }
void profExecStart(uint64_t flag) VL_MT_SAFE;

View File

@ -220,8 +220,9 @@ void VerilatedFst::declare(uint32_t code, const char* name, int dtypenum,
const int bits = ((msb > lsb) ? (msb - lsb) : (lsb - msb)) + 1;
const std::string hierarchicalName = m_prefixStack.back().first + name;
const auto dumpvarsPath = Super::dumpvarsPath(m_prefixStack, name);
const bool enabled = Super::declCode(code, hierarchicalName, bits);
const bool enabled = Super::declCode(code, dumpvarsPath, bits);
if (!enabled) return;
assert(hierarchicalName.rfind(' ') != std::string::npos);

View File

@ -539,8 +539,9 @@ void VerilatedSaif::declare(const uint32_t code, uint32_t fidx, const char* name
const int bits = ((msb > lsb) ? (msb - lsb) : (lsb - msb)) + 1;
const std::string hierarchicalName = m_prefixStack.back().first + name;
const auto dumpvarsPath = Super::dumpvarsPath(m_prefixStack, name);
if (!Super::declCode(code, hierarchicalName, bits)) return;
if (!Super::declCode(code, dumpvarsPath, bits)) return;
std::string variableName = lastWord(hierarchicalName);
m_currentScope->addActivityVar(code, variableName);

View File

@ -313,7 +313,7 @@ private:
uint32_t m_maxBits = 0; // Number of bits in the widest signal
void* m_initUserp = nullptr; // The callback userp of the instance currently being initialized
// TODO: Should keep this as a Trie, that is how it's accessed all the time.
std::vector<std::pair<int, std::string>> m_dumpvars; // dumpvar() entries
std::vector<VerilatedTraceDumpvarsEntry> m_dumpvars; // dumpvar() entries
double m_timeRes = 1e-9; // Time resolution (ns/ms etc)
double m_timeUnit = 1e-0; // Time units (ns/ms etc)
uint64_t m_timeLastDump = 0; // Last time we did a dump
@ -371,6 +371,59 @@ private:
VL_UNCOPYABLE(VerilatedTrace);
protected:
struct DumpvarsPath final {
std::string m_name;
std::vector<size_t> m_scopeEndps;
static bool countsAsScopeLevel(VerilatedTracePrefixType type) {
return type == VerilatedTracePrefixType::SCOPE_MODULE
|| type == VerilatedTracePrefixType::SCOPE_INTERFACE
|| type == VerilatedTracePrefixType::ROOTIO_WRAPPER;
}
static char separator(VerilatedTracePrefixType type) {
return (type == VerilatedTracePrefixType::ARRAY_PACKED
|| type == VerilatedTracePrefixType::ARRAY_UNPACKED)
? '\0'
: '.';
}
static std::string trimPrefix(const std::string& prefix) {
if (!prefix.empty() && prefix.back() == ' ') {
return prefix.substr(0, prefix.size() - 1);
}
return prefix;
}
void append(const std::string& piece, VerilatedTracePrefixType type,
bool countLevel = true) {
if (piece.empty()) return;
const char sep = separator(type);
if (sep && !m_name.empty()) m_name += sep;
m_name += piece;
if (countLevel && countsAsScopeLevel(type)) m_scopeEndps.push_back(m_name.size());
}
bool matchesPrefix(const std::string& prefix) const {
if (prefix.empty()) return true;
if (m_name.compare(0, prefix.size(), prefix) != 0) return false;
return prefix.size() >= m_name.size() || m_name[prefix.size()] == '.';
}
int scopeLevelsBelow(size_t prefixLen) const {
int levels = 0;
for (const size_t endp : m_scopeEndps) {
if (endp > prefixLen) ++levels;
}
return levels;
}
bool matches(const VerilatedTraceDumpvarsEntry& entry) const {
if (!matchesPrefix(entry.m_hier)) return false;
return entry.m_level <= 0 || scopeLevelsBelow(entry.m_hier.size()) < entry.m_level;
}
};
//=========================================================================
// Internals available to format-specific implementations
@ -390,7 +443,7 @@ protected:
void traceInit() VL_MT_UNSAFE;
// Declare new signal and return true if enabled
bool declCode(uint32_t code, const std::string& declName, uint32_t bits);
bool declCode(uint32_t code, const DumpvarsPath& path, uint32_t bits);
void closeBase();
void flushBase();
@ -405,6 +458,23 @@ protected:
return str.substr(idx + 1);
}
static DumpvarsPath dumpvarsPath(
const std::vector<std::pair<std::string, VerilatedTracePrefixType>>& prefixStack,
const char* namep) {
DumpvarsPath out;
std::string prev;
for (size_t i = 1; i < prefixStack.size(); ++i) {
const std::string curr = DumpvarsPath::trimPrefix(prefixStack[i].first);
if (curr.size() < prev.size()) continue;
std::string piece = curr.substr(prev.size());
if (!piece.empty() && piece.front() == ' ') piece.erase(0, 1);
out.append(piece, prefixStack[i].second);
prev = curr;
}
out.append(namep ? namep : "", prefixStack.back().second, false);
return out;
}
//=========================================================================
// Virtual functions to be provided by the format-specific implementation

View File

@ -369,7 +369,8 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::traceInit() VL_MT_UNSAFE {
}
template <>
bool VerilatedTrace<VL_SUB_T, VL_BUF_T>::declCode(uint32_t code, const std::string& declName,
bool VerilatedTrace<VL_SUB_T, VL_BUF_T>::declCode(uint32_t code,
const DumpvarsPath& path,
uint32_t bits) {
if (VL_UNCOVERABLE(!code)) {
VL_FATAL_MT(__FILE__, __LINE__, "", "Internal: internal trace problem, code 0 is illegal");
@ -377,21 +378,8 @@ bool VerilatedTrace<VL_SUB_T, VL_BUF_T>::declCode(uint32_t code, const std::stri
// To keep it simple, this is O(enables * signals), but we expect few enables
bool enabled = false;
if (m_dumpvars.empty()) enabled = true;
for (const auto& item : m_dumpvars) {
const int dumpvarsLevel = item.first;
const char* dvp = item.second.c_str();
const char* np = declName.c_str();
while (*dvp && *dvp == *np) {
++dvp;
++np;
}
if (*dvp) continue; // Didn't match dumpvar item
if (*np && *np != ' ') continue; // e.g. "t" isn't a match for "top"
int levels = 0;
while (*np) {
if (*np++ == ' ') ++levels;
}
if (levels > dumpvarsLevel) continue; // Too deep
for (const auto& entry : m_dumpvars) {
if (!path.matches(entry)) continue;
// We only need to set first code word if it's a multicode signal
// as that's all we'll check for later
if (m_sigs_enabledVec.size() <= code) m_sigs_enabledVec.resize((code + 1024) * 2);
@ -434,15 +422,10 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::set_time_resolution(const std::string&
}
template <>
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::dumpvars(int level, const std::string& hier) VL_MT_SAFE {
if (level == 0) {
if (level == 0 && hier.empty()) {
m_dumpvars.clear(); // empty = everything on
} else {
// Convert Verilog . separators to trace space separators
std::string hierSpaced = hier;
for (auto& i : hierSpaced) {
if (i == '.') i = ' ';
}
m_dumpvars.emplace_back(level, hierSpaced);
m_dumpvars.emplace_back(level, hier);
}
}

View File

@ -383,8 +383,9 @@ void VerilatedVcd::declare(uint32_t code, const char* name, const char* wirep, b
const int bits = ((msb > lsb) ? (msb - lsb) : (lsb - msb)) + 1;
const std::string hierarchicalName = m_prefixStack.back().first + name;
const auto dumpvarsPath = Super::dumpvarsPath(m_prefixStack, name);
const bool enabled = Super::declCode(code, hierarchicalName, bits);
const bool enabled = Super::declCode(code, dumpvarsPath, bits);
if (m_suffixes.size() <= nextCode() * VL_TRACE_SUFFIX_ENTRY_SIZE) {
m_suffixes.resize(nextCode() * VL_TRACE_SUFFIX_ENTRY_SIZE * 2, 0);

View File

@ -636,6 +636,8 @@ class AstDumpCtl final : public AstNodeStmt {
// $dumpon etc
// Parents: expr
// @astgen op1 := exprp : Optional[AstNodeExpr] // Expression based on type of statement
// @astgen op2 := scopeNamep : Optional[AstScopeName] // Scope of the $dumpvars call site
// @astgen op3 := targetsp : List[AstNode] // Optional scope/signal targets for $dumpvars
const VDumpCtlType m_ctlType; // Type of operation
public:
AstDumpCtl(FileLine* fl, VDumpCtlType ctlType, AstNodeExpr* exprp = nullptr)
@ -649,8 +651,9 @@ public:
bool isOutputter() override { return true; }
bool isPredictOptimizable() const override { return false; }
bool isPure() override { return false; }
virtual bool cleanOut() const { return true; }
bool sameNode(const AstNode* /*samep*/) const override { return true; }
bool sameNode(const AstNode* samep) const override {
return ctlType() == VN_DBG_AS(samep, DumpCtl)->ctlType();
}
VDumpCtlType ctlType() const { return m_ctlType; }
};
class AstEventControl final : public AstNodeStmt {

View File

@ -377,6 +377,12 @@ class BeginVisitor final : public VNVisitor {
// If there's a %m in the display text, we add a special node that will contain the name()
// Similar code in V3Inline
if (nodep->user1SetOnce()) return; // Don't double-add text's
// $dumpvars scope names resolve relative to the enclosing module,
// not the block, so don't add block scope components for them.
if (VN_IS(nodep->backp(), DumpCtl)) {
iterateChildren(nodep);
return;
}
// DPI svGetScope doesn't include function name, but %m does
const std::string scname = nodep->forFormat() ? m_displayScope : m_namedScope;
// To keep correct visual order, must add before exising

View File

@ -895,6 +895,62 @@ public:
if (nodep->addNewline()) text += "\n";
displayNode(nodep, nodep->fmtp(), text, nodep->fmtp()->exprsp(), false);
}
static bool dumpvarsHasScopePrefix(const string& target, const string& scope) {
return target == scope
|| (target.length() > scope.length() && target.compare(0, scope.length(), scope) == 0
&& target[scope.length()] == '.');
}
static string dumpvarsHierPath(const string& scope, const string& target) {
if (target.empty()) return scope;
if (scope.empty() || dumpvarsHasScopePrefix(target, scope)) return target;
return scope + "." + target;
}
// Emit C++ code that registers a $dumpvars filter at runtime.
// Builds the full hierarchy path from vlSymsp->name() and the given suffix,
// then calls dumpvarsAdd with the specified level expression.
void emitDumpVarsAdd(const AstDumpCtl* nodep, const string& hierPath,
const string& levelExpr) {
putns(nodep, "{ std::string __vlDvHier{vlSymsp->name()};\n");
if (!hierPath.empty()) {
puts("if (!__vlDvHier.empty()) __vlDvHier += '.';\n");
puts("__vlDvHier += \"");
puts(V3OutFormatter::quoteNameControls(hierPath));
puts("\";\n");
}
puts("vlSymsp->_vm_contextp__->dumpvarsAdd(");
puts(levelExpr);
puts(", __vlDvHier); }\n");
}
// Emit $dumpvars filter logic when scope info is available.
void emitDumpVarsWithScope(AstDumpCtl* nodep) {
UASSERT_OBJ(nodep->scopeNamep(), nodep, "$dumpvars missing AstScopeName");
const string scope = nodep->scopeNamep()->scopePrettySymName();
// Resolve the level expression (constant or runtime)
const AstConst* const levelp = VN_CAST(nodep->exprp(), Const);
string levelExpr;
if (levelp) {
levelExpr = cvtToStr(levelp->toUInt());
} else {
putns(nodep, "{ const int __vlDvLevel = ");
iterateConst(nodep->exprp());
puts(";\n");
levelExpr = "__vlDvLevel";
}
// Emit one dumpvarsAdd call per target, or one for the scope itself
if (nodep->targetsp()) {
for (AstNode* tp = nodep->targetsp(); tp; tp = tp->nextp()) {
const string target = VN_AS(tp, Text)->text();
emitDumpVarsAdd(nodep, dumpvarsHierPath(scope, target), levelExpr);
}
} else {
emitDumpVarsAdd(nodep, scope, levelExpr);
}
if (!levelp) puts("}\n");
putns(nodep, "vlSymsp->_traceDumpClose();\n");
putns(nodep, "vlSymsp->_traceDumpOpen();\n");
}
void visit(AstDumpCtl* nodep) override {
switch (nodep->ctlType()) {
case VDumpCtlType::FILE:
@ -903,9 +959,8 @@ public:
puts(");\n");
break;
case VDumpCtlType::VARS:
// We ignore number of levels to dump in exprp()
if (v3Global.opt.trace()) {
putns(nodep, "vlSymsp->_traceDumpOpen();\n");
emitDumpVarsWithScope(nodep);
} else {
putns(nodep, "VL_PRINTF_MT(\"-Info: ");
puts(V3OutFormatter::quoteNameControls(protect(nodep->fileline()->filename())));

View File

@ -1215,6 +1215,10 @@ void EmitCSyms::emitSymImp(const AstNetlist* netlistp) {
puts("const VerilatedLockGuard lock{__Vm_dumperMutex};\n");
puts("if (VL_UNLIKELY(!__Vm_dumperp)) {\n");
puts("__Vm_dumperp = new " + v3Global.opt.traceClassLang() + "();\n");
puts("const auto dvars = _vm_contextp__->dumpvars();\n");
puts("for (const auto& dv : dvars) {\n");
puts("__Vm_dumperp->dumpvars(dv.m_level, dv.m_hier);\n");
puts("}\n");
puts("__Vm_modelp->trace(__Vm_dumperp, 0, 0);\n");
puts("const std::string dumpfile = _vm_contextp__->dumpfileCheck();\n");
puts("__Vm_dumperp->open(dumpfile.c_str());\n");

View File

@ -80,6 +80,27 @@
VL_DEFINE_DEBUG_FUNCTIONS;
static string dumpvarsTargetText(const AstNode* nodep) {
if (!nodep) return "";
if (const AstText* const textp = VN_CAST(nodep, Text)) return textp->text();
if (const AstCellRef* const refp = VN_CAST(nodep, CellRef)) return refp->name();
if (const AstCellArrayRef* const refp = VN_CAST(nodep, CellArrayRef)) return refp->name();
if (const AstParseRef* const refp = VN_CAST(nodep, ParseRef)) return refp->prettyName();
if (const AstVarRef* const refp = VN_CAST(nodep, VarRef)) return refp->name();
if (const AstVarXRef* const refp = VN_CAST(nodep, VarXRef)) {
if (refp->dotted().empty()) return refp->name();
return refp->dotted() + "." + refp->name();
}
if (const AstDot* const dotp = VN_CAST(nodep, Dot)) {
const string lhs = dumpvarsTargetText(dotp->lhsp());
const string rhs = dumpvarsTargetText(dotp->rhsp());
if (lhs.empty()) return rhs;
if (rhs.empty()) return lhs;
return lhs + "." + rhs;
}
return nodep->prettyName();
}
static string extractDottedPath(AstNode* nodep, bool& hasPartSelect) {
if (AstParseRef* const refp = VN_CAST(nodep, ParseRef)) {
return refp->name();
@ -6029,6 +6050,37 @@ class LinkDotResolveVisitor final : public VNVisitor {
UINFO(5, indent() << "visit " << nodep);
iterateChildren(nodep);
}
void visit(AstDumpCtl* nodep) override {
LINKDOT_VISIT_START();
UINFO(5, indent() << "visit " << nodep);
if (nodep->exprp()) iterateAndNextNull(nodep->exprp());
AstNode* targetsp = nodep->targetsp();
if (!targetsp) return;
// Resolve each target from its parse-tree form (AstParseRef/AstDot)
// into a plain text name, validating it against the symbol table.
VNRelinker relinker;
targetsp->unlinkFrBackWithNext(&relinker);
AstNode* newTargetsp = nullptr;
for (AstNode* targetp = targetsp; targetp;) {
AstNode* const nextp = targetp->nextp();
if (nextp) nextp->unlinkFrBackWithNext();
const string target = dumpvarsTargetText(targetp);
if (!target.empty() && m_curSymp) {
string baddot;
VSymEnt* matchSymp = nullptr;
if (!m_statep->findDotted(nodep->fileline(), m_curSymp, target,
baddot, matchSymp, true)) {
UINFO(5, "$dumpvars target '" << target
<< "' not found in hierarchy" << endl);
}
}
VL_DO_DANGLING(pushDeletep(targetp), targetp);
newTargetsp
= AstNode::addNextNull(newTargetsp, new AstText{nodep->fileline(), target});
targetp = nextp;
}
relinker.relink(newTargetsp);
}
void visit(AstCellArrayRef* nodep) override {
LINKDOT_VISIT_START();
UINFO(5, indent() << "visit " << nodep);

View File

@ -461,6 +461,14 @@ class LinkResolveVisitor final : public VNVisitor {
}
}
void visit(AstDumpCtl* nodep) override {
if (nodep->ctlType() == VDumpCtlType::VARS && !nodep->scopeNamep()) {
// Attach AstScopeName so V3Scope/V3Inline build the call-site scope path
nodep->scopeNamep(new AstScopeName{nodep->fileline(), false});
}
iterateChildren(nodep);
}
void visit(AstUdpTable* nodep) override {
UINFO(5, "UDPTABLE " << nodep);
if (!v3Global.opt.bboxUnsup()) {

View File

@ -96,6 +96,13 @@ AstArg* V3ParseGrammar::argWrapList(AstNodeExpr* nodep) {
return outp;
}
AstDumpCtl* V3ParseGrammar::createDumpVarsScoped(FileLine* fl, AstNodeExpr* levelp,
AstNode* exprListp) {
AstDumpCtl* const resultp = new AstDumpCtl{fl, VDumpCtlType::VARS, levelp};
resultp->addTargetsp(exprListp);
return resultp;
}
AstAssignW* V3ParseGrammar::createSupplyExpr(FileLine* fileline, const string& name, int value) {
AstAssignW* assignp = new AstAssignW{fileline, new AstParseRef{fileline, name},
value ? new AstConst{fileline, AstConst::All1{}}

View File

@ -67,6 +67,8 @@ public:
// METHODS
AstArg* argWrapList(AstNodeExpr* nodep) VL_MT_DISABLED;
AstDumpCtl* createDumpVarsScoped(FileLine* fl, AstNodeExpr* levelp,
AstNode* exprListp) VL_MT_DISABLED;
bool allTracingOn(const FileLine* fl) const {
return v3Global.opt.trace() && m_tracingParse && fl->tracingOn();
}

View File

@ -1598,6 +1598,29 @@ class TaskVisitor final : public VNVisitor {
beginp = createInlinedFTask(nodep, namePrefix, outvscp);
++m_statInlines;
}
// When a function call has inlinedDots (from V3Inline's cell hierarchy),
// propagate that info to:
// 1. Any AstDumpCtl/AstScopeName in the inlined body (direct $dumpvars)
// 2. Any nested AstNodeFTaskRef in the inlined body (indirect $dumpvars)
if (!nodep->inlinedDots().empty()) {
const string& callerDots = nodep->inlinedDots();
string dots = callerDots;
string::size_type pos;
while ((pos = dots.find('.')) != string::npos) dots.replace(pos, 1, "__DOT__");
const string scopePath = "__DOT__"s + m_scopep->name() + "__DOT__" + dots;
beginp->foreachAndNext([&](AstDumpCtl* dcp) {
if (AstScopeName* const snp = dcp->scopeNamep()) {
snp->scopeAttr(scopePath);
snp->scopeEntr(scopePath);
}
});
// Propagate inlinedDots to nested task references
beginp->foreachAndNext([&](AstNodeFTaskRef* refp) {
if (refp->inlinedDots().empty()) {
refp->inlinedDots(callerDots);
}
});
}
if (VN_IS(nodep, New)) { // New not legal as while() condition
insertBeforeStmt(nodep, beginp);

View File

@ -6202,7 +6202,14 @@ class WidthVisitor final : public VNVisitor {
}
void visit(AstDumpCtl* nodep) override {
assertAtStatement(nodep);
if (nodep->exprp()) iterateCheckString(nodep, "LHS", nodep->exprp(), BOTH);
if (nodep->exprp()) {
if (nodep->ctlType() == VDumpCtlType::VARS) {
// $dumpvars level argument is an integer
userIterateAndNext(nodep->exprp(), WidthVP{SELF, BOTH}.p());
} else {
iterateCheckString(nodep, "LHS", nodep->exprp(), BOTH);
}
}
}
void visit(AstFOpen* nodep) override {
// Although a system function in IEEE, here a statement which sets the file pointer (MCD)

View File

@ -4223,7 +4223,7 @@ system_t_stmt_call<nodeStmtp>: // IEEE: part of system_tf_call (as task returni
| yD_DUMPVARS parenE { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::VARS,
new AstConst{$<fl>1, 0}}; }
| yD_DUMPVARS '(' expr ')' { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::VARS, $3}; }
| yD_DUMPVARS '(' expr ',' exprList ')' { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::VARS, $3}; DEL($5); }
| yD_DUMPVARS '(' expr ',' exprList ')' { $$ = GRAMMARP->createDumpVarsScoped($<fl>1, $3, $5); }
| yD_DUMPALL parenE { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::ALL}; }
| yD_DUMPALL '(' expr ')' { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::ALL}; DEL($3); }
| yD_DUMPFLUSH parenE { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::FLUSH}; }

View File

@ -0,0 +1,28 @@
$version Generated by VerilatedVcd $end
$timescale 1ps $end
$scope module $rootio $end
$upscope $end
$scope module t $end
$var wire 1 % clk $end
$var wire 32 " cyc [31:0] $end
$scope module sub_a $end
$var wire 32 & ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 # value [31:0] $end
$upscope $end
$scope module sub_b $end
$var wire 32 ' ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 $ value [31:0] $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
b00000000000000000000000000000000 "
b00000000000000000000000000001010 #
b00000000000000000000000000010100 $
0%
b00000000000000000000000000001010 &
b00000000000000000000000000010100 '

View File

@ -0,0 +1,20 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# 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-FileCopyrightText: 2026 by Marco Bartoli.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.compile(verilator_flags2=['--binary --trace-vcd'])
test.execute()
test.vcd_identical(test.trace_filename, test.golden_filename)
test.passes()

View File

@ -0,0 +1,38 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 by Marco Bartoli.
// SPDX-License-Identifier: CC0-1.0
`define STRINGIFY(x) `"x`"
module t(
input clk
);
int cyc;
sub #(10) sub_a(.*);
sub #(20) sub_b(.*);
always @(posedge clk) begin
cyc <= cyc + 1;
if (cyc == 5) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
initial begin
$dumpfile(`STRINGIFY(`TEST_DUMPFILE));
$dumpvars(0);
end
endmodule
module sub #(
parameter int ADD
)(
input int cyc
);
int value;
always_comb value = cyc + ADD;
endmodule

View File

@ -0,0 +1,29 @@
$version Generated by VerilatedVcd $end
$timescale 1ps $end
$scope module $rootio $end
$upscope $end
$scope module t $end
$scope module sub_a $end
$var wire 32 ( ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 # value [31:0] $end
$scope module deep_i $end
$var wire 32 ) ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 $ inner [31:0] $end
$upscope $end
$upscope $end
$scope module sub_b $end
$scope module deep_i $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
b00000000000000000000000000000000 "
b00000000000000000000000000001010 #
b00000000000000000000000000001011 $
b00000000000000000000000000001010 (
b00000000000000000000000000001011 )

View File

@ -0,0 +1,20 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# 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-FileCopyrightText: 2026 by Marco Bartoli.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.compile(verilator_flags2=['--binary --trace-vcd'])
test.execute()
test.vcd_identical(test.trace_filename, test.golden_filename)
test.passes()

View File

@ -0,0 +1,50 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 by Marco Bartoli.
// SPDX-License-Identifier: CC0-1.0
`define STRINGIFY(x) `"x`"
module t(
input clk
);
int cyc;
sub #(10) sub_a(.*);
sub #(20) sub_b(.*);
always @(posedge clk) begin
cyc <= cyc + 1;
if (cyc == 5) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
initial begin
$dumpfile(`STRINGIFY(`TEST_DUMPFILE));
// Test $dumpvars with absolute hierarchical scope path
$dumpvars(0, t.sub_a);
end
endmodule
module sub #(
parameter int ADD
)(
input int cyc
);
int value;
always_comb value = cyc + ADD;
deep #(ADD + 1) deep_i(.*);
endmodule
module deep #(
parameter int ADD
)(
input int cyc
);
int inner;
always_comb inner = cyc + ADD;
endmodule

View File

@ -0,0 +1,21 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# 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-FileCopyrightText: 2026 by Marco Bartoli.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.compile(verilator_flags2=['--binary --timing --trace-vcd'])
test.execute()
test.vcd_identical(test.obj_dir + '/simx0.vcd', test.t_dir + '/t_trace_dumpvars_add_module_0.out')
test.vcd_identical(test.obj_dir + '/simx1.vcd', test.t_dir + '/t_trace_dumpvars_add_module_1.out')
test.passes()

View File

@ -0,0 +1,58 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 by Marco Bartoli.
// SPDX-License-Identifier: CC0-1.0
`define STRINGIFY(x) `"x`"
module t(
);
logic clk;
int cyc;
sub #(10) sub_a(.*);
sub #(20) sub_b(.*);
initial begin
clk = 0;
forever #1 clk = !clk;
end
always @(posedge clk) begin
cyc <= cyc + 1;
if (cyc == 1) begin
$dumpfile({`STRINGIFY(`TEST_OBJ_DIR), "/simx1.vcd"});
$dumpvars(0, sub_b);
end
if (cyc == 5) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
initial begin
$dumpfile({`STRINGIFY(`TEST_OBJ_DIR), "/simx0.vcd"});
$dumpvars(1, sub_a);
end
endmodule
module sub #(
parameter int ADD
)(
input int cyc
);
int value;
always_comb value = cyc + ADD;
deep #(ADD + 1) deep_i(.*);
endmodule
module deep #(
parameter int ADD
)(
input int cyc
);
int inner;
always_comb inner = cyc + ADD;
endmodule

View File

@ -0,0 +1,26 @@
$version Generated by VerilatedVcd $end
$timescale 1ps $end
$scope module t $end
$scope module sub_a $end
$var wire 32 ( ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 # value [31:0] $end
$scope module deep_i $end
$upscope $end
$upscope $end
$scope module sub_b $end
$scope module deep_i $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
b00000000000000000000000000000000 "
b00000000000000000000000000001010 #
b00000000000000000000000000001010 (
#1
b00000000000000000000000000000001 "
b00000000000000000000000000001011 #
#2

View File

@ -0,0 +1,53 @@
$version Generated by VerilatedVcd $end
$timescale 1ps $end
$scope module t $end
$scope module sub_a $end
$var wire 32 ( ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 # value [31:0] $end
$scope module deep_i $end
$upscope $end
$upscope $end
$scope module sub_b $end
$var wire 32 * ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 % value [31:0] $end
$scope module deep_i $end
$var wire 32 + ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 & inner [31:0] $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#3
b00000000000000000000000000000010 "
b00000000000000000000000000001100 #
b00000000000000000000000000010110 %
b00000000000000000000000000010111 &
b00000000000000000000000000001010 (
b00000000000000000000000000010100 *
b00000000000000000000000000010101 +
#5
b00000000000000000000000000000011 "
b00000000000000000000000000001101 #
b00000000000000000000000000010111 %
b00000000000000000000000000011000 &
#7
b00000000000000000000000000000100 "
b00000000000000000000000000001110 #
b00000000000000000000000000011000 %
b00000000000000000000000000011001 &
#9
b00000000000000000000000000000101 "
b00000000000000000000000000001111 #
b00000000000000000000000000011001 %
b00000000000000000000000000011010 &
#11
b00000000000000000000000000000110 "
b00000000000000000000000000010000 #
b00000000000000000000000000011010 %
b00000000000000000000000000011011 &

View File

@ -0,0 +1,29 @@
$version Generated by VerilatedVcd $end
$timescale 1ps $end
$scope module $rootio $end
$upscope $end
$scope module t $end
$scope module sub_a $end
$var wire 32 ( ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 # value [31:0] $end
$scope module deep_i $end
$upscope $end
$upscope $end
$scope module sub_b $end
$var wire 32 * ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 % value [31:0] $end
$scope module deep_i $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
b00000000000000000000000000000000 "
b00000000000000000000000000001010 #
b00000000000000000000000000010100 %
b00000000000000000000000000001010 (
b00000000000000000000000000010100 *

View File

@ -0,0 +1,20 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# 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-FileCopyrightText: 2026 by Marco Bartoli.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.compile(verilator_flags2=['--binary --trace-vcd'])
test.execute()
test.vcd_identical(test.trace_filename, test.golden_filename)
test.passes()

View File

@ -0,0 +1,61 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 by Marco Bartoli.
// SPDX-License-Identifier: CC0-1.0
`define STRINGIFY(x) `"x`"
function int get_trace_level;
return 1;
endfunction
function void varsdump;
$dumpvars(get_trace_level());
endfunction
function void setup_trace;
$dumpfile(`STRINGIFY(`TEST_DUMPFILE));
varsdump();
endfunction
module t(
input clk
);
int cyc;
sub #(10) sub_a(.*);
sub #(20) sub_b(.*);
always @(posedge clk) begin
cyc <= cyc + 1;
if (cyc == 5) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
module sub #(
parameter int ADD
)(
input int cyc
);
int value;
always_comb value = cyc + ADD;
initial begin
setup_trace;
end
deep #(ADD + 1) deep_i(.*);
endmodule
module deep #(
parameter int ADD
)(
input int cyc
);
int inner;
always_comb inner = cyc + ADD;
endmodule

View File

@ -0,0 +1,24 @@
$version Generated by VerilatedVcd $end
$timescale 1ps $end
$scope module $rootio $end
$upscope $end
$scope module t $end
$scope module sub_a $end
$scope module deep_i $end
$var wire 32 ) ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 $ inner [31:0] $end
$upscope $end
$upscope $end
$scope module sub_b $end
$scope module deep_i $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
b00000000000000000000000000000000 "
b00000000000000000000000000001011 $
b00000000000000000000000000001011 )

View File

@ -0,0 +1,20 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# 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-FileCopyrightText: 2026 by Marco Bartoli.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.compile(verilator_flags2=['--binary --trace-vcd'])
test.execute()
test.vcd_identical(test.trace_filename, test.golden_filename)
test.passes()

View File

@ -0,0 +1,50 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 by Marco Bartoli.
// SPDX-License-Identifier: CC0-1.0
`define STRINGIFY(x) `"x`"
module t(
input clk
);
int cyc;
sub #(10) sub_a(.*);
sub #(20) sub_b(.*);
always @(posedge clk) begin
cyc <= cyc + 1;
if (cyc == 5) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
initial begin
$dumpfile(`STRINGIFY(`TEST_DUMPFILE));
// Test $dumpvars with hierarchical scope: level 1 limits to direct signals of sub_a.deep_i
$dumpvars(1, sub_a.deep_i);
end
endmodule
module sub #(
parameter int ADD
)(
input int cyc
);
int value;
always_comb value = cyc + ADD;
deep #(ADD + 1) deep_i(.*);
endmodule
module deep #(
parameter int ADD
)(
input int cyc
);
int inner;
always_comb inner = cyc + ADD;
endmodule

View File

@ -0,0 +1,22 @@
$version Generated by VerilatedVcd $end
$timescale 1ps $end
$scope module $rootio $end
$upscope $end
$scope module t $end
$var wire 1 ' clk $end
$var wire 32 " cyc [31:0] $end
$scope module sub_a $end
$scope module deep_i $end
$upscope $end
$upscope $end
$scope module sub_b $end
$scope module deep_i $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
b00000000000000000000000000000000 "
0'

View File

@ -0,0 +1,20 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# 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-FileCopyrightText: 2026 by Marco Bartoli.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.compile(verilator_flags2=['--binary --trace-vcd'])
test.execute()
test.vcd_identical(test.trace_filename, test.golden_filename)
test.passes()

View File

@ -0,0 +1,50 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 by Marco Bartoli.
// SPDX-License-Identifier: CC0-1.0
`define STRINGIFY(x) `"x`"
module t(
input clk
);
int cyc;
sub #(10) sub_a(.*);
sub #(20) sub_b(.*);
always @(posedge clk) begin
cyc <= cyc + 1;
if (cyc == 5) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
initial begin
$dumpfile(`STRINGIFY(`TEST_DUMPFILE));
// Test $dumpvars with level argument (level 1 = top-level signals only)
$dumpvars(1);
end
endmodule
module sub #(
parameter int ADD
)(
input int cyc
);
int value;
always_comb value = cyc + ADD;
deep #(ADD + 1) deep_i(.*);
endmodule
module deep #(
parameter int ADD
)(
input int cyc
);
int inner;
always_comb inner = cyc + ADD;
endmodule

View File

@ -0,0 +1,24 @@
$version Generated by VerilatedVcd $end
$timescale 1ps $end
$scope module $rootio $end
$upscope $end
$scope module t $end
$scope module sub_a $end
$var wire 32 ( ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 # value [31:0] $end
$scope module deep_i $end
$upscope $end
$upscope $end
$scope module sub_b $end
$scope module deep_i $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
b00000000000000000000000000000000 "
b00000000000000000000000000001010 #
b00000000000000000000000000001010 (

View File

@ -0,0 +1,20 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# 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-FileCopyrightText: 2026 by Marco Bartoli.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.compile(verilator_flags2=['--binary --trace-vcd'])
test.execute()
test.vcd_identical(test.trace_filename, test.golden_filename)
test.passes()

View File

@ -0,0 +1,50 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 by Marco Bartoli.
// SPDX-License-Identifier: CC0-1.0
`define STRINGIFY(x) `"x`"
module t(
input clk
);
int cyc;
sub #(10) sub_a(.*);
sub #(20) sub_b(.*);
always @(posedge clk) begin
cyc <= cyc + 1;
if (cyc == 5) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
initial begin
$dumpfile(`STRINGIFY(`TEST_DUMPFILE));
// Test $dumpvars with level AND scope: level 1 limits to sub_a direct signals only
$dumpvars(1, sub_a);
end
endmodule
module sub #(
parameter int ADD
)(
input int cyc
);
int value;
always_comb value = cyc + ADD;
deep #(ADD + 1) deep_i(.*);
endmodule
module deep #(
parameter int ADD
)(
input int cyc
);
int inner;
always_comb inner = cyc + ADD;
endmodule

View File

@ -0,0 +1,15 @@
$version Generated by VerilatedVcd $end
$timescale 1ps $end
$scope module $rootio $end
$upscope $end
$scope module t $end
$scope module sub_a $end
$scope module deep_i $end
$upscope $end
$upscope $end
$scope module sub_b $end
$scope module deep_i $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end

View File

@ -0,0 +1,21 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# 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-FileCopyrightText: 2026 by Marco Bartoli.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.compile(verilator_flags2=['--binary --trace-vcd'])
test.execute()
test.file_grep(test.trace_filename, r'^\$enddefinitions \$end')
test.file_grep_not(test.trace_filename, r'^\s*\$var\s')
test.passes()

View File

@ -0,0 +1,50 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 by Marco Bartoli.
// SPDX-License-Identifier: CC0-1.0
`define STRINGIFY(x) `"x`"
module t(
input clk
);
int cyc;
sub #(10) sub_a(.*);
sub #(20) sub_b(.*);
always @(posedge clk) begin
cyc <= cyc + 1;
if (cyc == 5) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
initial begin
$dumpfile(`STRINGIFY(`TEST_DUMPFILE));
// Test $dumpvars with a non-existent module scope argument
$dumpvars(0, missing_module);
end
endmodule
module sub #(
parameter int ADD
)(
input int cyc
);
int value;
always_comb value = cyc + ADD;
deep #(ADD + 1) deep_i(.*);
endmodule
module deep #(
parameter int ADD
)(
input int cyc
);
int inner;
always_comb inner = cyc + ADD;
endmodule

View File

@ -0,0 +1,27 @@
$version Generated by VerilatedVcd $end
$timescale 1ps $end
$scope module $rootio $end
$upscope $end
$scope module t $end
$var wire 1 ' clk $end
$var wire 32 " cyc [31:0] $end
$scope module sub_a $end
$scope module deep_i $end
$var wire 32 ) ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 $ inner [31:0] $end
$upscope $end
$upscope $end
$scope module sub_b $end
$scope module deep_i $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
b00000000000000000000000000000000 "
b00000000000000000000000000001011 $
0'
b00000000000000000000000000001011 )

View File

@ -0,0 +1,20 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# 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-FileCopyrightText: 2026 by Marco Bartoli.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.compile(verilator_flags2=['--binary --trace-vcd'])
test.execute()
test.vcd_identical(test.trace_filename, test.golden_filename)
test.passes()

View File

@ -0,0 +1,50 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 by Marco Bartoli.
// SPDX-License-Identifier: CC0-1.0
`define STRINGIFY(x) `"x`"
module t(
input clk
);
int cyc;
sub #(10) sub_a(.*);
sub #(20) sub_b(.*);
always @(posedge clk) begin
cyc <= cyc + 1;
if (cyc == 5) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
initial begin
$dumpfile(`STRINGIFY(`TEST_DUMPFILE));
// Test multiple scopes with non-constant level expression
$dumpvars(0+1, t, t.sub_a.deep_i);
end
endmodule
module sub #(
parameter int ADD
)(
input int cyc
);
int value;
always_comb value = cyc + ADD;
deep #(ADD + 1) deep_i(.*);
endmodule
module deep #(
parameter int ADD
)(
input int cyc
);
int inner;
always_comb inner = cyc + ADD;
endmodule

View File

@ -0,0 +1,31 @@
$version Generated by VerilatedVcd $end
$timescale 1ps $end
$scope module $rootio $end
$upscope $end
$scope module t $end
$scope module dumpblock $end
$upscope $end
$scope module sub_a $end
$var wire 32 ) ADD [31:0] $end
$var wire 32 # cyc [31:0] $end
$var wire 32 $ value [31:0] $end
$scope module deep_i $end
$var wire 32 * ADD [31:0] $end
$var wire 32 # cyc [31:0] $end
$var wire 32 % inner [31:0] $end
$upscope $end
$upscope $end
$scope module sub_b $end
$scope module deep_i $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
b00000000000000000000000000000000 #
b00000000000000000000000000001010 $
b00000000000000000000000000001011 %
b00000000000000000000000000001010 )
b00000000000000000000000000001011 *

View File

@ -0,0 +1,20 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# 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-FileCopyrightText: 2026 by Marco Bartoli.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.compile(verilator_flags2=['--binary --trace-vcd'])
test.execute(all_run_flags=['+LEVEL=0'])
test.vcd_identical(test.trace_filename, test.golden_filename)
test.passes()

View File

@ -0,0 +1,52 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 by Marco Bartoli.
// SPDX-License-Identifier: CC0-1.0
`define STRINGIFY(x) `"x`"
module t(
input clk
);
int cyc;
sub #(10) sub_a(.*);
sub #(20) sub_b(.*);
always @(posedge clk) begin
cyc <= cyc + 1;
if (cyc == 5) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
initial begin: dumpblock
int level;
if (!$value$plusargs("LEVEL=%d", level)) level = 0;
$dumpfile(`STRINGIFY(`TEST_DUMPFILE));
// Test $dumpvars with non-constant level expression and scope argument
$dumpvars(level, t.sub_a);
end
endmodule
module sub #(
parameter int ADD
)(
input int cyc
);
int value;
always_comb value = cyc + ADD;
deep #(ADD + 1) deep_i(.*);
endmodule
module deep #(
parameter int ADD
)(
input int cyc
);
int inner;
always_comb inner = cyc + ADD;
endmodule

View File

@ -0,0 +1,42 @@
$version Generated by VerilatedVcd $end
$timescale 1ps $end
$scope module $rootio $end
$upscope $end
$scope module t $end
$var wire 1 ' clk $end
$var wire 32 " cyc [31:0] $end
$scope module sub_a $end
$var wire 32 ( ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 # value [31:0] $end
$scope module deep_i $end
$var wire 32 ) ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 $ inner [31:0] $end
$upscope $end
$upscope $end
$scope module sub_b $end
$var wire 32 * ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 % value [31:0] $end
$scope module deep_i $end
$var wire 32 + ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 & inner [31:0] $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
b00000000000000000000000000000000 "
b00000000000000000000000000001010 #
b00000000000000000000000000001011 $
b00000000000000000000000000010100 %
b00000000000000000000000000010101 &
0'
b00000000000000000000000000001010 (
b00000000000000000000000000001011 )
b00000000000000000000000000010100 *
b00000000000000000000000000010101 +

View File

@ -0,0 +1,20 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# 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-FileCopyrightText: 2026 by Marco Bartoli.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.compile(verilator_flags2=['--binary --trace-vcd'])
test.execute()
test.vcd_identical(test.trace_filename, test.golden_filename)
test.passes()

View File

@ -0,0 +1,51 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 by Marco Bartoli.
// SPDX-License-Identifier: CC0-1.0
`define STRINGIFY(x) `"x`"
module t(
input clk
);
int cyc;
sub #(10) sub_a(.*);
sub #(20) sub_b(.*);
always @(posedge clk) begin
cyc <= cyc + 1;
if (cyc == 5) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
initial begin
$dumpfile(`STRINGIFY(`TEST_DUMPFILE));
// First restrict to deep_i only, then override with $dumpvars(0) to dump all
$dumpvars(1, t.sub_a.deep_i);
$dumpvars(0);
end
endmodule
module sub #(
parameter int ADD
)(
input int cyc
);
int value;
always_comb value = cyc + ADD;
deep #(ADD + 1) deep_i(.*);
endmodule
module deep #(
parameter int ADD
)(
input int cyc
);
int inner;
always_comb inner = cyc + ADD;
endmodule

View File

@ -0,0 +1,29 @@
$version Generated by VerilatedVcd $end
$timescale 1ps $end
$scope module $rootio $end
$upscope $end
$scope module t $end
$scope module sub_a $end
$var wire 32 ( ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 # value [31:0] $end
$scope module deep_i $end
$var wire 32 ) ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 $ inner [31:0] $end
$upscope $end
$upscope $end
$scope module sub_b $end
$scope module deep_i $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
b00000000000000000000000000000000 "
b00000000000000000000000000001010 #
b00000000000000000000000000001011 $
b00000000000000000000000000001010 (
b00000000000000000000000000001011 )

View File

@ -0,0 +1,20 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# 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-FileCopyrightText: 2026 by Marco Bartoli.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.compile(verilator_flags2=['--binary --trace-vcd'])
test.execute()
test.vcd_identical(test.trace_filename, test.golden_filename)
test.passes()

View File

@ -0,0 +1,50 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 by Marco Bartoli.
// SPDX-License-Identifier: CC0-1.0
`define STRINGIFY(x) `"x`"
module t(
input clk
);
int cyc;
sub #(10) sub_a(.*);
sub #(20) sub_b(.*);
always @(posedge clk) begin
cyc <= cyc + 1;
if (cyc == 5) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
initial begin
$dumpfile(`STRINGIFY(`TEST_DUMPFILE));
// Test $dumpvars with module scope argument
$dumpvars(0, sub_a);
end
endmodule
module sub #(
parameter int ADD
)(
input int cyc
);
int value;
always_comb value = cyc + ADD;
deep #(ADD + 1) deep_i(.*);
endmodule
module deep #(
parameter int ADD
)(
input int cyc
);
int inner;
always_comb inner = cyc + ADD;
endmodule

View File

@ -0,0 +1,36 @@
$version Generated by VerilatedVcd $end
$timescale 1ps $end
$scope module $rootio $end
$upscope $end
$scope module t $end
$var wire 1 * clk $end
$var wire 32 " cyc [31:0] $end
$scope module rect $end
$scope module origin $end
$var wire 8 # x [7:0] $end
$var wire 8 $ y [7:0] $end
$upscope $end
$scope module size $end
$var wire 8 % x [7:0] $end
$var wire 8 & y [7:0] $end
$upscope $end
$upscope $end
$scope module pt $end
$var wire 8 ' x [7:0] $end
$var wire 8 ( y [7:0] $end
$upscope $end
$scope module sub_a $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
b00000000000000000000000000000000 "
b00000000 #
b00000000 $
b00000000 %
b00000000 &
b00000000 '
b00000000 (
0*

View File

@ -0,0 +1,20 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# 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-FileCopyrightText: 2026 by Marco Bartoli.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.compile(verilator_flags2=['--binary --trace-vcd --trace-structs'])
test.execute()
test.vcd_identical(test.trace_filename, test.golden_filename)
test.passes()

View File

@ -0,0 +1,57 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 by Marco Bartoli.
// SPDX-License-Identifier: CC0-1.0
`define STRINGIFY(x) `"x`"
module t(
input clk
);
typedef struct packed {
logic [7:0] x;
logic [7:0] y;
} point_t;
typedef struct packed {
point_t origin;
point_t size;
} rect_t;
int cyc;
rect_t rect;
point_t pt;
sub #(10) sub_a(.*);
always @(posedge clk) begin
cyc <= cyc + 1;
pt.x <= pt.x + 1;
pt.y <= pt.y + 2;
rect.origin.x <= rect.origin.x + 1;
rect.origin.y <= rect.origin.y + 2;
rect.size.x <= 8'd100;
rect.size.y <= 8'd200;
if (cyc == 5) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
initial begin
$dumpfile(`STRINGIFY(`TEST_DUMPFILE));
// Level 1 counts only module nesting, so nested struct members under t
// are dumped, but sub_a's signals are still excluded.
$dumpvars(1);
end
endmodule
module sub #(
parameter int ADD
)(
input int cyc
);
int value;
always_comb value = cyc + ADD;
endmodule

View File

@ -0,0 +1,29 @@
$version Generated by VerilatedVcd $end
$timescale 1ps $end
$scope module $rootio $end
$upscope $end
$scope module t $end
$scope module sub_a $end
$var wire 32 ( ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 # value [31:0] $end
$scope module deep_i $end
$upscope $end
$upscope $end
$scope module sub_b $end
$var wire 32 * ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 % value [31:0] $end
$scope module deep_i $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
b00000000000000000000000000000000 "
b00000000000000000000000000001010 #
b00000000000000000000000000010100 %
b00000000000000000000000000001010 (
b00000000000000000000000000010100 *

View File

@ -0,0 +1,20 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# 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-FileCopyrightText: 2026 by Marco Bartoli.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.compile(verilator_flags2=['--binary --trace-vcd'])
test.execute()
test.vcd_identical(test.trace_filename, test.golden_filename)
test.passes()

View File

@ -0,0 +1,54 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 by Marco Bartoli.
// SPDX-License-Identifier: CC0-1.0
`define STRINGIFY(x) `"x`"
module t(
input clk
);
int cyc;
sub #(10) sub_a(.*);
sub #(20) sub_b(.*);
always @(posedge clk) begin
cyc <= cyc + 1;
if (cyc == 5) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
initial begin
$dumpfile(`STRINGIFY(`TEST_DUMPFILE));
end
endmodule
module sub #(
parameter int ADD
)(
input int cyc
);
int value;
always_comb value = cyc + ADD;
deep #(ADD + 1) deep_i(.*);
// $dumpvars called from sub module scope with level 1
// Should dump only this sub module's direct signals, not deep_i's
initial begin
$dumpvars(1);
end
endmodule
module deep #(
parameter int ADD
)(
input int cyc
);
int inner;
always_comb inner = cyc + ADD;
endmodule

View File

@ -0,0 +1,39 @@
$version Generated by VerilatedVcd $end
$timescale 1ps $end
$scope module $rootio $end
$upscope $end
$scope module t $end
$scope module sub_a $end
$var wire 32 ( ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 # value [31:0] $end
$scope module deep_i $end
$var wire 32 ) ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 $ inner [31:0] $end
$upscope $end
$upscope $end
$scope module sub_b $end
$var wire 32 * ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 % value [31:0] $end
$scope module deep_i $end
$var wire 32 + ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 & inner [31:0] $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
b00000000000000000000000000000000 "
b00000000000000000000000000001010 #
b00000000000000000000000000001011 $
b00000000000000000000000000010100 %
b00000000000000000000000000010101 &
b00000000000000000000000000001010 (
b00000000000000000000000000001011 )
b00000000000000000000000000010100 *
b00000000000000000000000000010101 +

View File

@ -0,0 +1,20 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# 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-FileCopyrightText: 2026 by Marco Bartoli.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.compile(verilator_flags2=['--binary --trace-vcd'])
test.execute()
test.vcd_identical(test.trace_filename, test.golden_filename)
test.passes()

View File

@ -0,0 +1,54 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 by Marco Bartoli.
// SPDX-License-Identifier: CC0-1.0
`define STRINGIFY(x) `"x`"
module t(
input clk
);
int cyc;
sub #(10) sub_a(.*);
sub #(20) sub_b(.*);
always @(posedge clk) begin
cyc <= cyc + 1;
if (cyc == 5) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
initial begin
$dumpfile(`STRINGIFY(`TEST_DUMPFILE));
end
endmodule
module sub #(
parameter int ADD
)(
input int cyc
);
int value;
always_comb value = cyc + ADD;
deep #(ADD + 1) deep_i(.*);
// $dumpvars called from sub module scope with level 0
// Should dump all signals in this sub module and below (including deep_i)
initial begin
$dumpvars(0);
end
endmodule
module deep #(
parameter int ADD
)(
input int cyc
);
int inner;
always_comb inner = cyc + ADD;
endmodule

View File

@ -0,0 +1,29 @@
$version Generated by VerilatedVcd $end
$timescale 1ps $end
$scope module $rootio $end
$upscope $end
$scope module t $end
$scope module sub_a $end
$var wire 32 ( ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 # value [31:0] $end
$scope module deep_i $end
$upscope $end
$upscope $end
$scope module sub_b $end
$var wire 32 * ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 % value [31:0] $end
$scope module deep_i $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
b00000000000000000000000000000000 "
b00000000000000000000000000001010 #
b00000000000000000000000000010100 %
b00000000000000000000000000001010 (
b00000000000000000000000000010100 *

View File

@ -0,0 +1,20 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# 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-FileCopyrightText: 2026 by Marco Bartoli.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.compile(verilator_flags2=['--binary --trace-vcd'])
test.execute()
test.vcd_identical(test.trace_filename, test.golden_filename)
test.passes()

View File

@ -0,0 +1,61 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 by Marco Bartoli.
// SPDX-License-Identifier: CC0-1.0
`define STRINGIFY(x) `"x`"
function int get_trace_level;
return 1;
endfunction
function void varsdump;
$dumpvars(get_trace_level());
endfunction
task setup_trace;
$dumpfile(`STRINGIFY(`TEST_DUMPFILE));
varsdump();
endtask
module t(
input clk
);
int cyc;
sub #(10) sub_a(.*);
sub #(20) sub_b(.*);
always @(posedge clk) begin
cyc <= cyc + 1;
if (cyc == 5) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
module sub #(
parameter int ADD
)(
input int cyc
);
int value;
always_comb value = cyc + ADD;
initial begin
setup_trace;
end
deep #(ADD + 1) deep_i(.*);
endmodule
module deep #(
parameter int ADD
)(
input int cyc
);
int inner;
always_comb inner = cyc + ADD;
endmodule

View File

@ -0,0 +1,29 @@
$version Generated by VerilatedVcd $end
$timescale 1ps $end
$scope module $rootio $end
$upscope $end
$scope module t $end
$scope module sub_a $end
$var wire 32 ( ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 # value [31:0] $end
$scope module deep_i $end
$upscope $end
$upscope $end
$scope module sub_b $end
$var wire 32 * ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 % value [31:0] $end
$scope module deep_i $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
b00000000000000000000000000000000 "
b00000000000000000000000000001010 #
b00000000000000000000000000010100 %
b00000000000000000000000000001010 (
b00000000000000000000000000010100 *

View File

@ -0,0 +1,20 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# 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-FileCopyrightText: 2026 by Marco Bartoli.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.compile(verilator_flags2=['--binary --trace-vcd'])
test.execute()
test.vcd_identical(test.trace_filename, test.golden_filename)
test.passes()

View File

@ -0,0 +1,65 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 by Marco Bartoli.
// SPDX-License-Identifier: CC0-1.0
`define STRINGIFY(x) `"x`"
function int get_trace_level;
return 1;
endfunction
function void varsdump;
$dumpvars(get_trace_level());
endfunction
task setup_trace;
$dumpfile(`STRINGIFY(`TEST_DUMPFILE));
varsdump();
endtask
task setup_trace_nested;
setup_trace();
endtask
module t(
input clk
);
int cyc;
sub #(10) sub_a(.*);
sub #(20) sub_b(.*);
always @(posedge clk) begin
cyc <= cyc + 1;
if (cyc == 5) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
module sub #(
parameter int ADD
)(
input int cyc
);
int value;
always_comb value = cyc + ADD;
initial begin
setup_trace_nested;
end
deep #(ADD + 1) deep_i(.*);
endmodule
module deep #(
parameter int ADD
)(
input int cyc
);
int inner;
always_comb inner = cyc + ADD;
endmodule

View File

@ -0,0 +1,18 @@
$version Generated by VerilatedVcd $end
$timescale 1ps $end
$scope module $rootio $end
$upscope $end
$scope module t $end
$var wire 32 " cyc [31:0] $end
$var wire 32 # counter [31:0] $end
$scope module sub_a $end
$upscope $end
$scope module sub_b $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
b00000000000000000000000000000000 "
b00000000000000000000000000000000 #

View File

@ -0,0 +1,20 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# 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-FileCopyrightText: 2026 by Marco Bartoli.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt')
test.compile(verilator_flags2=['--binary --trace-vcd'])
test.execute()
test.vcd_identical(test.trace_filename, test.golden_filename)
test.passes()

View File

@ -0,0 +1,41 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 by Marco Bartoli.
// SPDX-License-Identifier: CC0-1.0
`define STRINGIFY(x) `"x`"
module t(
input clk
);
int cyc;
int counter;
sub #(10) sub_a(.*);
sub #(20) sub_b(.*);
always @(posedge clk) begin
cyc <= cyc + 1;
counter <= counter + 2;
if (cyc == 5) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
initial begin
$dumpfile(`STRINGIFY(`TEST_DUMPFILE));
// Test $dumpvars with specific wire names
$dumpvars(0, cyc, counter);
end
endmodule
module sub #(
parameter int ADD
)(
input int cyc
);
int value;
always_comb value = cyc + ADD;
endmodule