Fix root global, arrays, no inline, escaped, fail on missing
This commit is contained in:
parent
b28fde7e57
commit
ad50b31077
|
|
@ -2929,11 +2929,8 @@ std::string VerilatedContext::dumpfileCheck() const VL_MT_SAFE_EXCLUDES(m_timeDu
|
|||
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);
|
||||
}
|
||||
if (level == 0 && hier.empty()) m_dumpvars.clear();
|
||||
m_dumpvars.emplace_back(level, hier);
|
||||
}
|
||||
std::vector<VerilatedTraceDumpvarsEntry>
|
||||
VerilatedContext::dumpvars() const VL_MT_SAFE_EXCLUDES(m_timeDumpMutex) {
|
||||
|
|
|
|||
|
|
@ -110,8 +110,11 @@ class VerilatedVcd;
|
|||
class VerilatedVcdC;
|
||||
class VerilatedVcdSc;
|
||||
|
||||
// Internal: One $dumpvars call.
|
||||
struct VerilatedTraceDumpvarsEntry final {
|
||||
/// Maximum hierarchy depth to dump modules.
|
||||
int m_level;
|
||||
/// Hierarchy root to dump.
|
||||
std::string m_hier;
|
||||
|
||||
VerilatedTraceDumpvarsEntry(int level, const std::string& hier)
|
||||
|
|
|
|||
|
|
@ -300,6 +300,9 @@ public:
|
|||
void dumpvars(int level, const std::string& hier) VL_MT_SAFE {
|
||||
m_sptrace.dumpvars(level, hier);
|
||||
}
|
||||
void dumpvars(const std::vector<VerilatedTraceDumpvarsEntry>& entries) VL_MT_SAFE {
|
||||
m_sptrace.dumpvars(entries);
|
||||
}
|
||||
|
||||
// Internal class access
|
||||
VerilatedFst* spTrace() { return &m_sptrace; }
|
||||
|
|
|
|||
|
|
@ -318,6 +318,9 @@ public:
|
|||
void dumpvars(int level, const std::string& hier) VL_MT_SAFE {
|
||||
m_sptrace.dumpvars(level, hier);
|
||||
}
|
||||
void dumpvars(const std::vector<VerilatedTraceDumpvarsEntry>& entries) VL_MT_SAFE {
|
||||
m_sptrace.dumpvars(entries);
|
||||
}
|
||||
|
||||
// Internal class access
|
||||
VerilatedSaif* spTrace() { return &m_sptrace; }
|
||||
|
|
|
|||
|
|
@ -509,6 +509,11 @@ public:
|
|||
// Set variables to dump, using $dumpvars format
|
||||
// If level = 0, dump everything and hier is then ignored
|
||||
void dumpvars(int level, const std::string& hier) VL_MT_SAFE;
|
||||
void dumpvars(const std::vector<VerilatedTraceDumpvarsEntry>& entries) VL_MT_SAFE {
|
||||
for (const VerilatedTraceDumpvarsEntry& entry : entries) {
|
||||
dumpvars(entry.m_level, entry.m_hier);
|
||||
}
|
||||
}
|
||||
|
||||
// Call
|
||||
void dump(uint64_t timeui) VL_MT_SAFE_EXCLUDES(m_mutex);
|
||||
|
|
|
|||
|
|
@ -422,11 +422,8 @@ 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 && hier.empty()) {
|
||||
m_dumpvars.clear(); // empty = everything on
|
||||
} else {
|
||||
m_dumpvars.emplace_back(level, hier);
|
||||
}
|
||||
if (level == 0 && hier.empty()) m_dumpvars.clear();
|
||||
m_dumpvars.emplace_back(level, hier);
|
||||
}
|
||||
|
||||
template <>
|
||||
|
|
|
|||
|
|
@ -351,6 +351,9 @@ public:
|
|||
void dumpvars(int level, const std::string& hier) VL_MT_SAFE {
|
||||
m_sptrace.dumpvars(level, hier);
|
||||
}
|
||||
void dumpvars(const std::vector<VerilatedTraceDumpvarsEntry>& entries) VL_MT_SAFE {
|
||||
m_sptrace.dumpvars(entries);
|
||||
}
|
||||
|
||||
// Internal class access
|
||||
VerilatedVcd* spTrace() { return &m_sptrace; }
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ set(HEADERS
|
|||
V3DfgPeepholePatterns.h
|
||||
V3DfgVertices.h
|
||||
V3DiagSarif.h
|
||||
V3Dumpvars.h
|
||||
V3DupFinder.h
|
||||
V3EmitC.h
|
||||
V3EmitCBase.h
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Dumpvars helpers
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// 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: 2003-2026 Wilson Snyder
|
||||
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
#ifndef VERILATOR_V3DUMPVARS_H_
|
||||
#define VERILATOR_V3DUMPVARS_H_
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
|
||||
// Tagged $dumpvars target string. During compile-time resolution in V3LinkDot
|
||||
// each target is tagged with a prefix that tells EmitC how to emit the
|
||||
// corresponding runtime code. The three tag types are:
|
||||
// Resolved – fully resolved to a compile-time hierarchy path
|
||||
// RuntimeRoot – first component must match the C++ wrapper root name at runtime
|
||||
// Missing – proven invalid at compile time; emit VL_FATAL_MT at runtime
|
||||
struct DumpvarsTag final {
|
||||
const char* const prefix;
|
||||
const size_t prefixLen;
|
||||
template <size_t N>
|
||||
constexpr DumpvarsTag(const char (&s)[N])
|
||||
: prefix{s}
|
||||
, prefixLen{N - 1} {}
|
||||
bool matches(const string& target) const { return target.compare(0, prefixLen, prefix) == 0; }
|
||||
string make(const string& target) const { return string{prefix, prefixLen} + target; }
|
||||
string strip(const string& target) const {
|
||||
return matches(target) ? target.substr(prefixLen) : target;
|
||||
}
|
||||
};
|
||||
|
||||
constexpr DumpvarsTag kDumpvarsResolved{"@dumpvars:"};
|
||||
constexpr DumpvarsTag kDumpvarsRuntimeRoot{"@dumpvars_root:"};
|
||||
constexpr DumpvarsTag kDumpvarsMissing{"@dumpvars_missing:"};
|
||||
|
||||
#endif // Guard
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
#include "verilatedos.h"
|
||||
|
||||
#include "V3EmitCConstInit.h"
|
||||
#include "V3Dumpvars.h"
|
||||
#include "V3Global.h"
|
||||
#include "V3MemberMap.h"
|
||||
|
||||
|
|
@ -903,8 +904,9 @@ public:
|
|||
|
||||
static string dumpvarsHierPath(const string& scope, const string& target) {
|
||||
if (target.empty()) return scope;
|
||||
if (kDumpvarsResolved.matches(target)) return kDumpvarsResolved.strip(target);
|
||||
if (scope.empty() || dumpvarsHasScopePrefix(target, scope)) return target;
|
||||
return scope + "." + target;
|
||||
return VString::dot(scope, ".", target);
|
||||
}
|
||||
|
||||
// Emit C++ code that registers a $dumpvars filter at runtime.
|
||||
|
|
@ -923,6 +925,41 @@ public:
|
|||
puts(levelExpr);
|
||||
puts(", __vlDvHier); }\n");
|
||||
}
|
||||
void emitDumpVarsAddRuntimeRoot(const AstDumpCtl* nodep, const string& target,
|
||||
const string& levelExpr) {
|
||||
const string::size_type dotPos = target.find('.');
|
||||
const string rootName = dotPos == string::npos ? target : target.substr(0, dotPos);
|
||||
const string suffix = dotPos == string::npos ? "" : target.substr(dotPos + 1);
|
||||
putns(nodep, "{ const std::string __vlDvRoot{vlSymsp->name()};\n");
|
||||
puts("if (__vlDvRoot != \"");
|
||||
puts(V3OutFormatter::quoteNameControls(rootName));
|
||||
puts("\") VL_FATAL_MT(\"");
|
||||
puts(V3OutFormatter::quoteNameControls(protect(nodep->fileline()->filename())));
|
||||
puts("\", ");
|
||||
puts(cvtToStr(nodep->fileline()->lineno()));
|
||||
puts(", \"\", \"$dumpvars target not found: ");
|
||||
puts(V3OutFormatter::quoteNameControls(target));
|
||||
puts("\");\n");
|
||||
puts("std::string __vlDvHier{__vlDvRoot};\n");
|
||||
if (!suffix.empty()) {
|
||||
puts("__vlDvHier += '.';\n");
|
||||
puts("__vlDvHier += \"");
|
||||
puts(V3OutFormatter::quoteNameControls(suffix));
|
||||
puts("\";\n");
|
||||
}
|
||||
puts("vlSymsp->_vm_contextp__->dumpvarsAdd(");
|
||||
puts(levelExpr);
|
||||
puts(", __vlDvHier); }\n");
|
||||
}
|
||||
void emitDumpVarsTargetMissing(const AstDumpCtl* nodep, const string& target) {
|
||||
putns(nodep, "VL_FATAL_MT(\"");
|
||||
puts(V3OutFormatter::quoteNameControls(protect(nodep->fileline()->filename())));
|
||||
puts("\", ");
|
||||
puts(cvtToStr(nodep->fileline()->lineno()));
|
||||
puts(", \"\", \"$dumpvars target not found: ");
|
||||
puts(V3OutFormatter::quoteNameControls(target));
|
||||
puts("\");\n");
|
||||
}
|
||||
// Emit $dumpvars filter logic when scope info is available.
|
||||
void emitDumpVarsWithScope(AstDumpCtl* nodep) {
|
||||
UASSERT_OBJ(nodep->scopeNamep(), nodep, "$dumpvars missing AstScopeName");
|
||||
|
|
@ -938,14 +975,29 @@ public:
|
|||
puts(";\n");
|
||||
levelExpr = "__vlDvLevel";
|
||||
}
|
||||
// Emit one dumpvarsAdd call per target, or one for the scope itself
|
||||
// Emit one dumpvarsAdd call per target, or one for the scope itself.
|
||||
// The no-target $dumpvars(0) form is design-global and should not be
|
||||
// narrowed to the lexical scope where it appears.
|
||||
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);
|
||||
if (kDumpvarsMissing.matches(target)) {
|
||||
emitDumpVarsTargetMissing(nodep, kDumpvarsMissing.strip(target));
|
||||
} else if (kDumpvarsRuntimeRoot.matches(target)) {
|
||||
emitDumpVarsAddRuntimeRoot(nodep, kDumpvarsRuntimeRoot.strip(target),
|
||||
levelExpr);
|
||||
} else {
|
||||
emitDumpVarsAdd(nodep, dumpvarsHierPath(scope, target), levelExpr);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
emitDumpVarsAdd(nodep, scope, levelExpr);
|
||||
if (levelp && levelp->toUInt() == 0 && scope.find('.') == string::npos) {
|
||||
putns(nodep, "vlSymsp->_vm_contextp__->dumpvarsAdd(");
|
||||
puts(levelExpr);
|
||||
puts(", \"\"s);\n");
|
||||
} else {
|
||||
emitDumpVarsAdd(nodep, scope, levelExpr);
|
||||
}
|
||||
}
|
||||
if (!levelp) puts("}\n");
|
||||
putns(nodep, "vlSymsp->_traceDumpClose();\n");
|
||||
|
|
|
|||
|
|
@ -1215,11 +1215,8 @@ 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("__Vm_dumperp->dumpvars(_vm_contextp__->dumpvars());\n");
|
||||
puts("_vm_contextp__->trace(__Vm_dumperp, 0, 0);\n");
|
||||
puts("const std::string dumpfile = _vm_contextp__->dumpfileCheck();\n");
|
||||
puts("__Vm_dumperp->open(dumpfile.c_str());\n");
|
||||
puts("__Vm_dumping = true;\n");
|
||||
|
|
|
|||
|
|
@ -84,19 +84,29 @@ 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 AstSelBit* const selp = VN_CAST(nodep, SelBit)) {
|
||||
const string from = dumpvarsTargetText(selp->fromp());
|
||||
const string bit = dumpvarsTargetText(selp->bitp());
|
||||
if (from.empty()) return "";
|
||||
return from + "[" + bit + "]";
|
||||
}
|
||||
if (const AstCellArrayRef* const refp = VN_CAST(nodep, CellArrayRef)) {
|
||||
string out = refp->name();
|
||||
for (const AstNodeExpr* selp = refp->selp(); selp; selp = VN_CAST(selp->nextp(), NodeExpr)) {
|
||||
out += "[" + dumpvarsTargetText(selp) + "]";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
if (const AstConst* const constp = VN_CAST(nodep, Const)) return cvtToStr(constp->toSInt());
|
||||
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();
|
||||
return VString::dot(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 VString::dot(lhs, ".", rhs);
|
||||
}
|
||||
return nodep->prettyName();
|
||||
}
|
||||
|
|
@ -3163,6 +3173,127 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
|||
}
|
||||
} m_ds; // State to preserve across recursions
|
||||
|
||||
static string dumpvarsSymPathPiece(const AstNode* nodep) {
|
||||
if (!nodep) return "";
|
||||
if (const AstNodeModule* const modp = VN_CAST(nodep, NodeModule)) return modp->origName();
|
||||
if (const AstCell* const cellp = VN_CAST(nodep, Cell)) return cellp->origName();
|
||||
if (const AstCellInline* const inlinep = VN_CAST(nodep, CellInline)) return inlinep->name();
|
||||
if (const AstVarScope* const vscp = VN_CAST(nodep, VarScope)) return vscp->varp()->name();
|
||||
return nodep->name();
|
||||
}
|
||||
|
||||
static bool dumpvarsMatchesLocalModule(const VSymEnt* symp, const string& ident) {
|
||||
if (!symp) return false;
|
||||
if (const AstCell* const cellp = VN_CAST(symp->nodep(), Cell)) {
|
||||
return cellp->modp() && cellp->modp()->origName() == ident;
|
||||
}
|
||||
if (const AstCellInline* const inlinep = VN_CAST(symp->nodep(), CellInline)) {
|
||||
return inlinep->origModName() == ident;
|
||||
}
|
||||
if (const AstNodeModule* const modp = VN_CAST(symp->nodep(), NodeModule)) {
|
||||
return modp->origName() == ident;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static string dumpvarsResolvedPath(VSymEnt* symp) {
|
||||
std::vector<string> pieces;
|
||||
for (VSymEnt* walkp = symp; walkp && walkp->parentp(); walkp = walkp->parentp()) {
|
||||
const string piece = dumpvarsSymPathPiece(walkp->nodep());
|
||||
if (!piece.empty()) pieces.push_back(piece);
|
||||
}
|
||||
std::reverse(pieces.begin(), pieces.end());
|
||||
string path;
|
||||
for (const string& piece : pieces) {
|
||||
if (!path.empty()) path += '.';
|
||||
path += piece;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
static bool dumpvarsHasBareTarget(AstNode* targetsp, const string& name) {
|
||||
for (AstNode* tp = targetsp; tp; tp = tp->nextp()) {
|
||||
if (dumpvarsTargetText(tp) == name) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
VSymEnt* findDumpvarsLocal(FileLine* refLocationp, const string& dotname, string& baddot,
|
||||
VSymEnt*& okSymp) {
|
||||
if (!m_curSymp) return nullptr;
|
||||
string leftname = dotname;
|
||||
string::size_type pos;
|
||||
string ident;
|
||||
if ((pos = leftname.find('.')) != string::npos) {
|
||||
ident = leftname.substr(0, pos);
|
||||
leftname = leftname.substr(pos + 1);
|
||||
} else {
|
||||
ident = leftname;
|
||||
leftname = "";
|
||||
}
|
||||
|
||||
baddot = ident;
|
||||
okSymp = m_curSymp;
|
||||
string altIdent;
|
||||
if (m_statep->forPrearray()) {
|
||||
if ((pos = ident.rfind("__BRA__")) != string::npos) altIdent = ident.substr(0, pos);
|
||||
}
|
||||
|
||||
VSymEnt* symp = nullptr;
|
||||
if (dumpvarsMatchesLocalModule(m_curSymp, ident)) {
|
||||
symp = m_curSymp;
|
||||
} else {
|
||||
symp = m_curSymp->findIdFallback(ident);
|
||||
if (!symp && !altIdent.empty()) symp = m_curSymp->findIdFallback(altIdent);
|
||||
}
|
||||
if (!symp) return nullptr;
|
||||
if (leftname.empty()) {
|
||||
okSymp = symp;
|
||||
return symp;
|
||||
}
|
||||
return m_statep->findDotted(refLocationp, symp, leftname, baddot, okSymp, false);
|
||||
}
|
||||
|
||||
// Resolve a single $dumpvars target string against the symbol table.
|
||||
// Returns a tagged string that tells EmitC how to generate the runtime code.
|
||||
string resolveDumpvarsTarget(FileLine* fl, const string& target, AstNode* targetsp) {
|
||||
if (target.empty() || !m_curSymp) return target;
|
||||
|
||||
string baddot;
|
||||
VSymEnt* matchSymp = nullptr;
|
||||
|
||||
// Step 1: Try local scope lookup.
|
||||
if (findDumpvarsLocal(fl, target, baddot, matchSymp)) return target;
|
||||
|
||||
// Step 2: Try global lookup from $root.
|
||||
if (VSymEnt* const rootSymp = m_statep->findDotted(
|
||||
fl, m_statep->rootEntp(), target, baddot, matchSymp, true)) {
|
||||
const string resolved = dumpvarsResolvedPath(rootSymp);
|
||||
if (!resolved.empty()) return kDumpvarsResolved.make(resolved);
|
||||
}
|
||||
|
||||
// Step 3: Single-component name — defer to runtime root matching.
|
||||
const string::size_type dotPos = target.find('.');
|
||||
const string firstComp = (dotPos != string::npos) ? target.substr(0, dotPos) : target;
|
||||
|
||||
if (dotPos == string::npos) return kDumpvarsRuntimeRoot.make(target);
|
||||
|
||||
// Step 4: Multi-component "X.y.z" where X might be the runtime root.
|
||||
const string remaining = target.substr(dotPos + 1);
|
||||
if (dumpvarsHasBareTarget(targetsp, firstComp)) {
|
||||
string runtimeBaddot;
|
||||
VSymEnt* runtimeMatchSymp = nullptr;
|
||||
if (m_statep->findDotted(fl, m_statep->rootEntp(), remaining, runtimeBaddot,
|
||||
runtimeMatchSymp, true)) {
|
||||
return kDumpvarsRuntimeRoot.make(target);
|
||||
}
|
||||
return kDumpvarsMissing.make(target);
|
||||
}
|
||||
|
||||
UINFO(5, "$dumpvars target '" << target << "' not found in hierarchy" << endl);
|
||||
return target;
|
||||
}
|
||||
|
||||
// METHODS - Variables
|
||||
AstVar* createImplicitVar(VSymEnt* /*lookupSymp*/, AstParseRef* nodep, AstNodeModule* modp,
|
||||
VSymEnt* moduleSymp, bool noWarn) {
|
||||
|
|
@ -6064,19 +6195,17 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
|||
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);
|
||||
}
|
||||
// Skip if already resolved to text.
|
||||
if (VN_IS(targetp, Text)) {
|
||||
newTargetsp = AstNode::addNextNull(newTargetsp, targetp);
|
||||
targetp = nextp;
|
||||
continue;
|
||||
}
|
||||
const string target = dumpvarsTargetText(targetp);
|
||||
const string linkedTarget = resolveDumpvarsTarget(nodep->fileline(), target, targetsp);
|
||||
VL_DO_DANGLING(pushDeletep(targetp), targetp);
|
||||
newTargetsp
|
||||
= AstNode::addNextNull(newTargetsp, new AstText{nodep->fileline(), target});
|
||||
= AstNode::addNextNull(newTargetsp, new AstText{nodep->fileline(), linkedTarget});
|
||||
targetp = nextp;
|
||||
}
|
||||
relinker.relink(newTargetsp);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "verilatedos.h"
|
||||
|
||||
#include "V3Ast.h"
|
||||
#include "V3Dumpvars.h"
|
||||
#include "V3Error.h"
|
||||
|
||||
//============================================================================
|
||||
|
|
|
|||
|
|
@ -96,13 +96,6 @@ 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{}}
|
||||
|
|
|
|||
|
|
@ -67,8 +67,6 @@ 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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1598,28 +1598,33 @@ 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:
|
||||
// Propagate the caller scope into the cloned task body so scope-sensitive
|
||||
// operations such as $dumpvars reflect the call site even when the task
|
||||
// was defined at $unit. When V3Inline added extra hierarchy, include it.
|
||||
// This applies 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;
|
||||
string scopePath = "__DOT__"s + m_scopep->name();
|
||||
if (!callerDots.empty()) {
|
||||
string dots = callerDots;
|
||||
string::size_type pos;
|
||||
while ((pos = dots.find('.')) != string::npos) dots.replace(pos, 1, "__DOT__");
|
||||
scopePath += "__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 (!callerDots.empty()) {
|
||||
// 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
|
||||
|
|
|
|||
|
|
@ -4215,15 +4215,17 @@ system_t_stmt_call<nodeStmtp>: // IEEE: part of system_tf_call (as task returni
|
|||
//
|
||||
| yD_DUMPPORTS '(' idDottedSel ',' expr ')' { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::FILE, $5}; DEL($3);
|
||||
$$->addNext(new AstDumpCtl{$<fl>1, VDumpCtlType::VARS,
|
||||
new AstConst{$<fl>1, 1}}); }
|
||||
new AstConst{$<fl>1, 0}}); }
|
||||
| yD_DUMPPORTS '(' ',' expr ')' { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::FILE, $4};
|
||||
$$->addNext(new AstDumpCtl{$<fl>1, VDumpCtlType::VARS,
|
||||
new AstConst{$<fl>1, 1}}); }
|
||||
new AstConst{$<fl>1, 0}}); }
|
||||
| yD_DUMPFILE '(' expr ')' { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::FILE, $3}; }
|
||||
| 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 ')' { $$ = GRAMMARP->createDumpVarsScoped($<fl>1, $3, $5); }
|
||||
| yD_DUMPVARS '(' expr ',' exprList ')' { AstDumpCtl* const dumpctlp = new AstDumpCtl{$<fl>1, VDumpCtlType::VARS, $3};
|
||||
dumpctlp->addTargetsp($5);
|
||||
$$ = dumpctlp; }
|
||||
| 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}; }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
$version Generated by VerilatedVcd $end
|
||||
$timescale 1ps $end
|
||||
$scope module $rootio $end
|
||||
$var wire 1 % clk $end
|
||||
$upscope $end
|
||||
$scope module t $end
|
||||
$var wire 1 % clk $end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
$version Generated by VerilatedVcd $end
|
||||
$timescale 1ps $end
|
||||
$scope module $rootio $end
|
||||
$upscope $end
|
||||
$scope module t $end
|
||||
$var wire 32 ( top [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
|
||||
$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 "
|
||||
b00000000000000000000000000001011 $
|
||||
b00000000000000000000000000010101 &
|
||||
b00000000000000000000000000000000 (
|
||||
b00000000000000000000000000001011 *
|
||||
b00000000000000000000000000010101 ,
|
||||
|
|
@ -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()
|
||||
|
|
@ -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
|
||||
);
|
||||
int cyc;
|
||||
int top;
|
||||
|
||||
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 sub_a.deep_i only, then let deep_i issue $dumpvars(0)
|
||||
// to confirm the no-target override still expands tracing globally.
|
||||
$dumpvars(1, t.sub_a.deep_i);
|
||||
$dumpvars(0, top);
|
||||
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;
|
||||
|
||||
initial begin
|
||||
$dumpvars(0);
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//
|
||||
// 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
|
||||
|
||||
#include <verilated.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include VM_PREFIX_INCLUDE
|
||||
|
||||
unsigned long long main_time = 0;
|
||||
double sc_time_stamp() { return (double)main_time; }
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
Verilated::debug(0);
|
||||
Verilated::traceEverOn(true);
|
||||
Verilated::commandArgs(argc, argv);
|
||||
|
||||
// Name the top module "cpptop" instead of default "TOP"
|
||||
std::unique_ptr<VM_PREFIX> top{new VM_PREFIX{"cpptop"}};
|
||||
top->clk = 0;
|
||||
|
||||
while (!Verilated::gotFinish()) {
|
||||
top->eval();
|
||||
++main_time;
|
||||
top->clk = !top->clk;
|
||||
}
|
||||
top->final();
|
||||
top.reset();
|
||||
printf("*-* All Finished *-*\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
$version Generated by VerilatedVcd $end
|
||||
$timescale 1ps $end
|
||||
$scope module cpptop $end
|
||||
$var wire 1 % clk $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
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
|
||||
|
||||
#0
|
||||
b00000000000000000000000000000000 "
|
||||
b00000000000000000000000000001010 #
|
||||
b00000000000000000000000000010100 $
|
||||
0%
|
||||
b00000000000000000000000000001010 &
|
||||
b00000000000000000000000000010100 '
|
||||
#1
|
||||
b00000000000000000000000000000001 "
|
||||
b00000000000000000000000000001011 #
|
||||
b00000000000000000000000000010101 $
|
||||
1%
|
||||
#2
|
||||
0%
|
||||
#3
|
||||
b00000000000000000000000000000010 "
|
||||
b00000000000000000000000000001100 #
|
||||
b00000000000000000000000000010110 $
|
||||
1%
|
||||
#4
|
||||
0%
|
||||
#5
|
||||
b00000000000000000000000000000011 "
|
||||
b00000000000000000000000000001101 #
|
||||
b00000000000000000000000000010111 $
|
||||
1%
|
||||
#6
|
||||
0%
|
||||
#7
|
||||
b00000000000000000000000000000100 "
|
||||
b00000000000000000000000000001110 #
|
||||
b00000000000000000000000000011000 $
|
||||
1%
|
||||
#8
|
||||
0%
|
||||
#9
|
||||
b00000000000000000000000000000101 "
|
||||
b00000000000000000000000000001111 #
|
||||
b00000000000000000000000000011001 $
|
||||
1%
|
||||
#10
|
||||
0%
|
||||
#11
|
||||
b00000000000000000000000000000110 "
|
||||
b00000000000000000000000000010000 #
|
||||
b00000000000000000000000000011010 $
|
||||
1%
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
#!/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(
|
||||
make_main=False,
|
||||
verilator_flags2=[
|
||||
'--cc',
|
||||
'--exe',
|
||||
'--trace-vcd',
|
||||
't/t_trace_dumpvars_cpptop.cpp',
|
||||
])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.vcd_identical(test.trace_filename, test.golden_filename)
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
// 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));
|
||||
// cpptop is defined in the C++ testbench as the root of the trace hierarchy, so $dumpvars(0, cpptop) should dump everything.
|
||||
$dumpvars(0, cpptop);
|
||||
end
|
||||
endmodule
|
||||
|
||||
module sub #(
|
||||
parameter int ADD
|
||||
)(
|
||||
input int cyc
|
||||
);
|
||||
int value;
|
||||
always_comb value = cyc + ADD;
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//
|
||||
// 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
|
||||
|
||||
#include <verilated.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include VM_PREFIX_INCLUDE
|
||||
|
||||
unsigned long long main_time = 0;
|
||||
double sc_time_stamp() { return (double)main_time; }
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
Verilated::debug(0);
|
||||
Verilated::traceEverOn(true);
|
||||
Verilated::commandArgs(argc, argv);
|
||||
|
||||
// Name the top module "cpptop" instead of default "TOP"
|
||||
std::unique_ptr<VM_PREFIX> top{new VM_PREFIX{"cpptop"}};
|
||||
top->clk = 0;
|
||||
|
||||
while (!Verilated::gotFinish()) {
|
||||
top->eval();
|
||||
++main_time;
|
||||
top->clk = !top->clk;
|
||||
}
|
||||
top->final();
|
||||
top.reset();
|
||||
printf("*-* All Finished *-*\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
%Error: t/t_trace_dumpvars_cpptop2.v:27: $dumpvars target not found: cpptop.notfound
|
||||
Aborting...
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#!/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(
|
||||
make_main=False,
|
||||
verilator_flags2=[
|
||||
'--cc',
|
||||
'--exe',
|
||||
'--trace-vcd',
|
||||
't/t_trace_dumpvars_cpptop.cpp',
|
||||
])
|
||||
|
||||
test.execute(fails=True, expect_filename=test.golden_filename)
|
||||
|
||||
test.passes()
|
||||
|
|
@ -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, cpptop, cpptop.notfound);
|
||||
end
|
||||
endmodule
|
||||
|
||||
module sub #(
|
||||
parameter int ADD
|
||||
)(
|
||||
input int cyc
|
||||
);
|
||||
int value;
|
||||
always_comb value = cyc + ADD;
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
$version Generated by VerilatedVcd $end
|
||||
$timescale 1ps $end
|
||||
$scope module $rootio $end
|
||||
$upscope $end
|
||||
$scope module t $end
|
||||
$scope module arr[0] $end
|
||||
$scope module deep $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module arr[1] $end
|
||||
$scope module deep $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 "
|
||||
b00000000000000000000000000001011 $
|
||||
b00000000000000000000000000001011 '
|
||||
|
|
@ -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()
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
// 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) arr[2](.*);
|
||||
|
||||
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 an arrayed hierarchical scope path.
|
||||
$dumpvars(1, t.arr[1].deep);
|
||||
end
|
||||
endmodule
|
||||
|
||||
module sub #(
|
||||
parameter int ADD
|
||||
)(
|
||||
input int cyc
|
||||
);
|
||||
int value;
|
||||
always_comb value = cyc + ADD;
|
||||
|
||||
deep #(ADD + 1) deep(.*);
|
||||
endmodule
|
||||
|
||||
module deep #(
|
||||
parameter int ADD
|
||||
)(
|
||||
input int cyc
|
||||
);
|
||||
int inner;
|
||||
always_comb inner = cyc + ADD;
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
$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 * t [31:0] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module sub_b $end
|
||||
$scope module deep_i $end
|
||||
$var wire 32 - t [31:0] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
|
||||
|
||||
#0
|
||||
b00000000000000000000000000000000 "
|
||||
0'
|
||||
b00000000000000000000000000000000 *
|
||||
b00000000000000000000000000000000 -
|
||||
|
|
@ -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()
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
// 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
|
||||
endmodule
|
||||
|
||||
module sub #(
|
||||
parameter int ADD
|
||||
)(
|
||||
input int cyc
|
||||
);
|
||||
int value;
|
||||
always_comb value = cyc + ADD;
|
||||
|
||||
deep #(ADD + 1) deep_i(.*);
|
||||
|
||||
initial begin
|
||||
$dumpfile(`STRINGIFY(`TEST_DUMPFILE));
|
||||
// Test $dumpvars with hierarchical scope: level 1 limits to direct signals of t outside the scope
|
||||
$dumpvars(1, t);
|
||||
end
|
||||
endmodule
|
||||
|
||||
module deep #(
|
||||
parameter int ADD
|
||||
)(
|
||||
input int cyc
|
||||
);
|
||||
int inner;
|
||||
int t;
|
||||
always_comb inner = cyc + ADD;
|
||||
|
||||
initial begin
|
||||
$dumpfile(`STRINGIFY(`TEST_DUMPFILE));
|
||||
$dumpvars(1, t);
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
$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 * t [31:0] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module sub_b $end
|
||||
$scope module deep_i $end
|
||||
$var wire 32 - t [31:0] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
|
||||
|
||||
#0
|
||||
b00000000000000000000000000000000 "
|
||||
0'
|
||||
b00000000000000000000000000000000 *
|
||||
b00000000000000000000000000000000 -
|
||||
|
|
@ -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 --fno-inline'])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.vcd_identical(test.trace_filename, test.golden_filename)
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
// 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
|
||||
endmodule
|
||||
|
||||
module sub #(
|
||||
parameter int ADD
|
||||
)(
|
||||
input int cyc
|
||||
);
|
||||
int value;
|
||||
always_comb value = cyc + ADD;
|
||||
|
||||
function void dump_from_func;
|
||||
$dumpvars(1, t);
|
||||
endfunction
|
||||
|
||||
task setup_trace;
|
||||
$dumpfile(`STRINGIFY(`TEST_DUMPFILE));
|
||||
dump_from_func();
|
||||
endtask
|
||||
|
||||
deep #(ADD + 1) deep_i(.*);
|
||||
|
||||
initial begin
|
||||
setup_trace();
|
||||
end
|
||||
endmodule
|
||||
|
||||
module deep #(
|
||||
parameter int ADD
|
||||
)(
|
||||
input int cyc
|
||||
);
|
||||
int inner;
|
||||
int t;
|
||||
always_comb inner = cyc + ADD;
|
||||
|
||||
function void dump_from_func;
|
||||
$dumpvars(1, t);
|
||||
endfunction
|
||||
|
||||
task setup_trace;
|
||||
$dumpfile(`STRINGIFY(`TEST_DUMPFILE));
|
||||
dump_from_func();
|
||||
endtask
|
||||
|
||||
initial begin
|
||||
setup_trace();
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
$version Generated by VerilatedVcd $end
|
||||
$timescale 1ps $end
|
||||
$scope module $rootio $end
|
||||
$upscope $end
|
||||
$scope module t $end
|
||||
$scope module mystruct $end
|
||||
$scope module deep $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 #
|
||||
b00000000000000000000000000001011 $
|
||||
b00000000000000000000000000001011 '
|
||||
|
|
@ -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()
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
// 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`"
|
||||
|
||||
typedef struct packed {
|
||||
logic [31:0] add;
|
||||
logic [31:0] cyc;
|
||||
logic [31:0] inner;
|
||||
} deep_t;
|
||||
|
||||
typedef struct packed {
|
||||
deep_t deep;
|
||||
logic [31:0] value;
|
||||
} top_t;
|
||||
|
||||
module t(
|
||||
input clk
|
||||
);
|
||||
int cyc;
|
||||
top_t mystruct;
|
||||
|
||||
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 traced struct sub-scope.
|
||||
$dumpvars(1, t.mystruct.deep);
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
mystruct.value = cyc + 32'd10;
|
||||
mystruct.deep.add = 32'd11;
|
||||
mystruct.deep.cyc = cyc;
|
||||
mystruct.deep.inner = cyc + mystruct.deep.add;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -1,15 +1,2 @@
|
|||
$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
|
||||
%Error: t/t_trace_dumpvars_missing_scope.v:28: $dumpvars target not found: missing_module
|
||||
Aborting...
|
||||
|
|
|
|||
|
|
@ -13,9 +13,6 @@ 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.execute(fails=True, expect_filename=test.golden_filename)
|
||||
|
||||
test.passes()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
$version Generated by VerilatedVcd $end
|
||||
$timescale 1ps $end
|
||||
$scope module $rootio $end
|
||||
$var wire 1 ' clk $end
|
||||
$upscope $end
|
||||
$scope module t $end
|
||||
$var wire 1 ' clk $end
|
||||
|
|
|
|||
|
|
@ -3,22 +3,16 @@ $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 rect $end
|
||||
$scope module origin $end
|
||||
$var wire 8 # x [7:0] $end
|
||||
$upscope $end
|
||||
$scope module size $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module pt $end
|
||||
$var wire 8 ( y [7:0] $end
|
||||
$upscope $end
|
||||
$scope module sub_a $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
|
|
@ -26,11 +20,5 @@ $enddefinitions $end
|
|||
|
||||
|
||||
#0
|
||||
b00000000000000000000000000000000 "
|
||||
b00000000 #
|
||||
b00000000 $
|
||||
b00000000 %
|
||||
b00000000 &
|
||||
b00000000 '
|
||||
b00000000 (
|
||||
0*
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ module t(
|
|||
input clk
|
||||
);
|
||||
typedef struct packed {
|
||||
logic [7:0] x;
|
||||
logic [7:0] \x ;
|
||||
logic [7:0] y;
|
||||
} point_t;
|
||||
|
||||
|
|
@ -21,17 +21,17 @@ module t(
|
|||
|
||||
int cyc;
|
||||
rect_t rect;
|
||||
point_t pt;
|
||||
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;
|
||||
\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.\x <= 8'd100;
|
||||
rect.size.y <= 8'd200;
|
||||
if (cyc == 5) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
|
|
@ -41,9 +41,9 @@ module t(
|
|||
|
||||
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);
|
||||
// Target a single escaped struct member in $dumpvars.
|
||||
$dumpvars(1, rect.origin.\x );
|
||||
$dumpvars(1, \pt .\y );
|
||||
end
|
||||
endmodule
|
||||
|
||||
|
|
|
|||
|
|
@ -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 *
|
||||
|
|
@ -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 --fno-inline'])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.vcd_identical(test.trace_filename, test.golden_filename)
|
||||
|
||||
test.passes()
|
||||
|
|
@ -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
|
||||
|
|
@ -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 *
|
||||
|
|
@ -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 --fno-inline'])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.vcd_identical(test.trace_filename, test.golden_filename)
|
||||
|
||||
test.passes()
|
||||
|
|
@ -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
|
||||
|
|
@ -26,7 +26,7 @@ module t;
|
|||
|
||||
initial begin
|
||||
$dumpfile(`STRINGIFY(`TEST_DUMPFILE));
|
||||
$dumpvars(0, top);
|
||||
$dumpvars(0);
|
||||
for (i = 0; i < 10; i++) begin
|
||||
@(posedge clk);
|
||||
|
||||
|
|
|
|||
|
|
@ -26,9 +26,9 @@ module t (
|
|||
|
||||
`ifdef TEST_DUMP
|
||||
$dumpfile(filename);
|
||||
$dumpvars(0); // Intentionally no ", top" for parsing coverage with just (expr)
|
||||
$dumpvars(1, top); // Intentionally checking parsing coverage
|
||||
$dumpvars(1, top, top); // Intentionally checking parsing coverage
|
||||
$dumpvars(0); // Intentionally no ", topa" for parsing coverage with just (expr)
|
||||
$dumpvars(1, topa); // Intentionally checking parsing coverage
|
||||
$dumpvars(1, topa, topa); // Intentionally checking parsing coverage
|
||||
$dumplimit(10 * 1024 * 1024);
|
||||
`elsif TEST_DUMPPORTS
|
||||
$dumpports(top, filename);
|
||||
|
|
|
|||
Loading…
Reference in New Issue