Fix scope tree in traces in hierarchical mode (#7042)
This commit is contained in:
parent
b84466ec10
commit
3dd2b762e7
|
|
@ -2571,3 +2571,9 @@ The grammar of control commands is as follows:
|
|||
scope which the rule is to match, where 0 means all levels below, 1 the
|
||||
exact level as the provided scope, and 2 means an additional level of
|
||||
children below the provided scope, etc.
|
||||
|
||||
.. option:: verilator_lib -module "<modulename>"
|
||||
|
||||
Internal use only. Marks the specified module as being a stub for a library
|
||||
created by :option:`--lib-creat` (including when created with
|
||||
:option:`--hierarchical`). Required for special internal processing.
|
||||
|
|
|
|||
|
|
@ -134,7 +134,8 @@ void VerilatedFst::declDTypeEnum(int dtypenum, const char* name, uint32_t elemen
|
|||
const char** itemValuesp) {
|
||||
const fstEnumHandle enumNum
|
||||
= fstWriterCreateEnumTable(m_fst, name, elements, minValbits, itemNamesp, itemValuesp);
|
||||
m_local2fstdtype[dtypenum] = enumNum;
|
||||
const bool newEntry = m_local2fstdtype[initUserp()].emplace(dtypenum, enumNum).second;
|
||||
assert(newEntry);
|
||||
}
|
||||
|
||||
// TODO: should return std::optional<fstScopeType>, but I can't have C++17
|
||||
|
|
@ -205,7 +206,9 @@ void VerilatedFst::declare(uint32_t code, const char* name, int dtypenum,
|
|||
if (bussed) name_ss << " [" << msb << ":" << lsb << "]";
|
||||
const std::string name_str = name_ss.str();
|
||||
|
||||
if (dtypenum > 0) fstWriterEmitEnumTableRef(m_fst, m_local2fstdtype[dtypenum]);
|
||||
if (dtypenum > 0) {
|
||||
fstWriterEmitEnumTableRef(m_fst, m_local2fstdtype.at(initUserp()).at(dtypenum));
|
||||
}
|
||||
|
||||
fstVarDir varDir = FST_VD_IMPLICIT;
|
||||
switch (direction) {
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ private:
|
|||
|
||||
fstWriterContext* m_fst = nullptr;
|
||||
std::map<uint32_t, vlFstHandle> m_code2symbol;
|
||||
std::map<int, vlFstEnumHandle> m_local2fstdtype;
|
||||
std::map<void*, std::map<int, vlFstEnumHandle>> m_local2fstdtype;
|
||||
vlFstHandle* m_symbolp = nullptr; // same as m_code2symbol, but as an array
|
||||
char* m_strbufp = nullptr; // String buffer long enough to hold maxBits() chars
|
||||
uint64_t m_timeui = 0; // Time to emit, 0 = not needed
|
||||
|
|
|
|||
|
|
@ -233,22 +233,41 @@ private:
|
|||
};
|
||||
const uint32_t m_fidx; // The index of the tracing function
|
||||
void* const m_userp; // The user pointer to pass to the callback (the symbol table)
|
||||
CallbackRecord(initCb_t cb, void* userp)
|
||||
const bool m_isLibInstance; // Whether the callback is for a --lib-create instance
|
||||
const std::string m_name; // The name of the instance callback is for
|
||||
const uint32_t m_nTraceCodes; // The number of trace codes used by callback
|
||||
CallbackRecord(initCb_t cb, void* userp, bool isLibInstance, const std::string& name,
|
||||
uint32_t nTraceCodes)
|
||||
: m_initCb{cb}
|
||||
, m_fidx{0}
|
||||
, m_userp{userp} {}
|
||||
, m_userp{userp}
|
||||
, m_isLibInstance{isLibInstance}
|
||||
, m_name{name}
|
||||
, m_nTraceCodes{nTraceCodes} {}
|
||||
CallbackRecord(dumpCb_t cb, uint32_t fidx, void* userp)
|
||||
: m_dumpCb{cb}
|
||||
, m_fidx{fidx}
|
||||
, m_userp{userp} {}
|
||||
, m_userp{userp}
|
||||
, m_isLibInstance{false} // Don't care
|
||||
, m_name{} // Don't care
|
||||
, m_nTraceCodes{0} // Don't care
|
||||
{}
|
||||
CallbackRecord(dumpOffloadCb_t cb, uint32_t fidx, void* userp)
|
||||
: m_dumpOffloadCb{cb}
|
||||
, m_fidx{fidx}
|
||||
, m_userp{userp} {}
|
||||
, m_userp{userp}
|
||||
, m_isLibInstance{false} // Don't care
|
||||
, m_name{} // Don't care
|
||||
, m_nTraceCodes{0} // Don't care
|
||||
{}
|
||||
CallbackRecord(cleanupCb_t cb, void* userp)
|
||||
: m_cleanupCb{cb}
|
||||
, m_fidx{0}
|
||||
, m_userp{userp} {}
|
||||
, m_userp{userp}
|
||||
, m_isLibInstance{false} // Don't care
|
||||
, m_name{} // Don't care
|
||||
, m_nTraceCodes{0} // Don't care
|
||||
{}
|
||||
};
|
||||
|
||||
bool m_offload = false; // Use the offload thread
|
||||
|
|
@ -292,6 +311,7 @@ private:
|
|||
uint32_t m_nextCode = 0; // Next code number to assign
|
||||
uint32_t m_numSignals = 0; // Number of distinct signals
|
||||
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
|
||||
double m_timeRes = 1e-9; // Time resolution (ns/ms etc)
|
||||
|
|
@ -359,6 +379,7 @@ protected:
|
|||
uint32_t nextCode() const { return m_nextCode; }
|
||||
uint32_t numSignals() const { return m_numSignals; }
|
||||
uint32_t maxBits() const { return m_maxBits; }
|
||||
void* initUserp() const { return m_initUserp; }
|
||||
void constDump(bool value) { m_constDump = value; }
|
||||
void fullDump(bool value) { m_fullDump = value; }
|
||||
|
||||
|
|
@ -429,7 +450,8 @@ public:
|
|||
// Non-hot path internal interface to Verilator generated code
|
||||
|
||||
void addModel(VerilatedModel*) VL_MT_SAFE_EXCLUDES(m_mutex);
|
||||
void addInitCb(initCb_t cb, void* userp) VL_MT_SAFE;
|
||||
void addInitCb(initCb_t cb, void* userp, const std::string& name, bool isLibInstance,
|
||||
uint32_t nTraceCodes) VL_MT_SAFE;
|
||||
void addConstCb(dumpCb_t cb, uint32_t fidx, void* userp) VL_MT_SAFE;
|
||||
void addConstCb(dumpOffloadCb_t cb, uint32_t fidx, void* userp) VL_MT_SAFE;
|
||||
void addFullCb(dumpCb_t cb, uint32_t fidx, void* userp) VL_MT_SAFE;
|
||||
|
|
@ -437,6 +459,7 @@ public:
|
|||
void addChgCb(dumpCb_t cb, uint32_t fidx, void* userp) VL_MT_SAFE;
|
||||
void addChgCb(dumpOffloadCb_t cb, uint32_t fidx, void* userp) VL_MT_SAFE;
|
||||
void addCleanupCb(cleanupCb_t cb, void* userp) VL_MT_SAFE;
|
||||
void initLib(const std::string& name) VL_MT_UNSAFE;
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
|
|
|
|||
|
|
@ -312,10 +312,17 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::traceInit() VL_MT_UNSAFE {
|
|||
m_maxBits = 0;
|
||||
m_sigs_enabledVec.clear();
|
||||
|
||||
// Call all initialize callbacks, which will:
|
||||
// Call all initialize callbacks for root (non-library) instances, which will:
|
||||
// - Call decl* for each signal (these eventually call ::declCode)
|
||||
// - Call the initialize callbacks of library instances underneath
|
||||
// - Store the base code
|
||||
for (const CallbackRecord& cbr : m_initCbs) cbr.m_initCb(cbr.m_userp, self(), nextCode());
|
||||
for (const CallbackRecord& cbr : m_initCbs) {
|
||||
if (cbr.m_isLibInstance) continue; // Will be called from parent callback
|
||||
const uint32_t baseCode = nextCode();
|
||||
m_nextCode += cbr.m_nTraceCodes;
|
||||
m_initUserp = cbr.m_userp;
|
||||
cbr.m_initCb(cbr.m_userp, self(), baseCode);
|
||||
}
|
||||
|
||||
if (expectedCodes && nextCode() != expectedCodes) {
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "",
|
||||
|
|
@ -393,8 +400,6 @@ bool VerilatedTrace<VL_SUB_T, VL_BUF_T>::declCode(uint32_t code, const std::stri
|
|||
break;
|
||||
}
|
||||
|
||||
int codesNeeded = VL_WORDS_I(bits);
|
||||
m_nextCode = std::max(m_nextCode, code + codesNeeded);
|
||||
++m_numSignals;
|
||||
m_maxBits = std::max(m_maxBits, bits);
|
||||
return enabled;
|
||||
|
|
@ -680,8 +685,10 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addCallbackRecord(std::vector<CallbackR
|
|||
}
|
||||
|
||||
template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addInitCb(initCb_t cb, void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_initCbs, CallbackRecord{cb, userp});
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addInitCb(initCb_t cb, void* userp,
|
||||
const std::string& name, bool isLibInstance,
|
||||
uint32_t nTraceCodes) VL_MT_SAFE {
|
||||
addCallbackRecord(m_initCbs, CallbackRecord{cb, userp, isLibInstance, name, nTraceCodes});
|
||||
}
|
||||
template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addConstCb(dumpCb_t cb, uint32_t fidx,
|
||||
|
|
@ -718,6 +725,20 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addCleanupCb(cleanupCb_t cb, void* user
|
|||
addCallbackRecord(m_cleanupCbs, CallbackRecord{cb, userp});
|
||||
}
|
||||
|
||||
template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::initLib(const std::string& name) VL_MT_SAFE {
|
||||
// Note it's possible the instance doesn't exist if the lib was compiled without tracing
|
||||
void* const prevInitUserp = m_initUserp;
|
||||
for (const CallbackRecord& cbr : m_initCbs) {
|
||||
if (cbr.m_name != name) continue;
|
||||
const uint32_t baseCode = nextCode();
|
||||
m_nextCode += cbr.m_nTraceCodes;
|
||||
m_initUserp = cbr.m_userp;
|
||||
cbr.m_initCb(cbr.m_userp, self(), baseCode);
|
||||
m_initUserp = prevInitUserp;
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// Primitives converting binary values to strings...
|
||||
|
||||
|
|
|
|||
|
|
@ -1471,6 +1471,7 @@ public:
|
|||
UNROLL_FULL,
|
||||
FULL_CASE,
|
||||
PARALLEL_CASE,
|
||||
VERILATOR_LIB,
|
||||
_ENUM_SIZE
|
||||
};
|
||||
enum en m_e;
|
||||
|
|
@ -1489,6 +1490,7 @@ public:
|
|||
"UNROLL_FULL", //
|
||||
"FULL_CASE", //
|
||||
"PARALLEL_CASE", //
|
||||
"VERILATOR_LIB", //
|
||||
"_ENUM_SIZE" //
|
||||
};
|
||||
return names[m_e];
|
||||
|
|
|
|||
|
|
@ -285,6 +285,7 @@ class AstNodeModule VL_NOT_FINAL : public AstNode {
|
|||
bool m_internal : 1; // Internally created
|
||||
bool m_recursive : 1; // Recursive module
|
||||
bool m_recursiveClone : 1; // If recursive, what module it clones, otherwise nullptr
|
||||
bool m_verilatorLib : 1; // Module is a stub for a Verilator produced --lib-create
|
||||
protected:
|
||||
AstNodeModule(VNType t, FileLine* fl, const string& name, const string& libname)
|
||||
: AstNode{t, fl}
|
||||
|
|
@ -301,7 +302,8 @@ protected:
|
|||
, m_hierParams{false}
|
||||
, m_internal{false}
|
||||
, m_recursive{false}
|
||||
, m_recursiveClone{false} {}
|
||||
, m_recursiveClone{false}
|
||||
, m_verilatorLib{false} {}
|
||||
|
||||
public:
|
||||
ASTGEN_MEMBERS_AstNodeModule;
|
||||
|
|
@ -343,6 +345,8 @@ public:
|
|||
void recursive(bool flag) { m_recursive = flag; }
|
||||
void recursiveClone(bool flag) { m_recursiveClone = flag; }
|
||||
bool recursiveClone() const { return m_recursiveClone; }
|
||||
void verilatorLib(bool flag) { m_verilatorLib = flag; }
|
||||
bool verilatorLib() const { return m_verilatorLib; }
|
||||
VLifetime lifetime() const { return m_lifetime; }
|
||||
void lifetime(const VLifetime& flag) { m_lifetime = flag; }
|
||||
VTimescale timeunit() const { return m_timeunit; }
|
||||
|
|
@ -1251,6 +1255,7 @@ class AstNetlist final : public AstNode {
|
|||
VTimescale m_timeunit; // Global time unit
|
||||
VTimescale m_timeprecision; // Global time precision
|
||||
bool m_timescaleSpecified = false; // Input HDL specified timescale
|
||||
uint32_t m_nTraceCodes = 0; // Number of trace codes used by design
|
||||
public:
|
||||
AstNetlist();
|
||||
ASTGEN_MEMBERS_AstNetlist;
|
||||
|
|
@ -1292,6 +1297,8 @@ public:
|
|||
void timeprecisionMerge(FileLine*, const VTimescale& value);
|
||||
void timescaleSpecified(bool specified) { m_timescaleSpecified = specified; }
|
||||
bool timescaleSpecified() const { return m_timescaleSpecified; }
|
||||
uint32_t nTraceCodes() const { return m_nTraceCodes; }
|
||||
void nTraceCodes(uint32_t value) { m_nTraceCodes = value; }
|
||||
AstVarScope* stlFirstIterationp();
|
||||
void clearStlFirstIterationp() { m_stlFirstIterationp = nullptr; }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2567,6 +2567,7 @@ void AstNodeModule::dump(std::ostream& str) const {
|
|||
} else if (recursive()) {
|
||||
str << " [RECURSIVE]";
|
||||
}
|
||||
if (verilatorLib()) str << " [VERILATOR-LIB]";
|
||||
str << " [" << timeunit() << "]";
|
||||
if (libname() != "work") str << " libname=" << libname();
|
||||
}
|
||||
|
|
@ -2579,6 +2580,7 @@ void AstNodeModule::dumpJson(std::ostream& str) const {
|
|||
dumpJsonBoolFuncIf(str, dead);
|
||||
dumpJsonBoolFuncIf(str, recursiveClone);
|
||||
dumpJsonBoolFuncIf(str, recursive);
|
||||
dumpJsonBoolFuncIf(str, verilatorLib);
|
||||
dumpJsonStr(str, "timeunit", timeunit().ascii());
|
||||
if (libname() != "work") dumpJsonStr(str, "libname=", libname());
|
||||
dumpJsonGen(str);
|
||||
|
|
|
|||
|
|
@ -292,9 +292,12 @@ class DeadVisitor final : public VNVisitor {
|
|||
void visit(AstVar* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
checkAll(nodep);
|
||||
if (nodep->isSigPublic() && m_modp && VN_IS(m_modp, Package)) m_modp->user1Inc();
|
||||
if (m_selloopvarsp) nodep->user1Inc();
|
||||
if (mightElimVar(nodep)) m_varsp.push_back(nodep);
|
||||
if (mightElimVar(nodep)) {
|
||||
m_varsp.push_back(nodep);
|
||||
} else {
|
||||
if (m_modp && VN_IS(m_modp, Package)) m_modp->user1Inc();
|
||||
}
|
||||
}
|
||||
void visit(AstNodeAssign* nodep) override {
|
||||
// See if simple assignments to variables may be eliminated because
|
||||
|
|
|
|||
|
|
@ -549,10 +549,14 @@ class EmitCModel final : public EmitCFunc {
|
|||
"0.\");\n");
|
||||
puts("}\n");
|
||||
puts("vlSymsp->__Vm_baseCode = code;\n");
|
||||
puts("tracep->pushPrefix(vlSymsp->name(), VerilatedTracePrefixType::SCOPE_MODULE);\n");
|
||||
if (v3Global.opt.libCreate().empty()) {
|
||||
puts("tracep->pushPrefix(vlSymsp->name(), VerilatedTracePrefixType::SCOPE_MODULE);\n");
|
||||
}
|
||||
puts(topModNameProtected + "__" + protect("trace_decl_types") + "(tracep);\n");
|
||||
puts(topModNameProtected + "__" + protect("trace_init_top") + "(vlSelf, tracep);\n");
|
||||
puts("tracep->popPrefix();\n");
|
||||
if (v3Global.opt.libCreate().empty()) { //
|
||||
puts("tracep->popPrefix();\n");
|
||||
}
|
||||
puts("}\n");
|
||||
|
||||
// Forward declaration
|
||||
|
|
@ -583,8 +587,13 @@ class EmitCModel final : public EmitCFunc {
|
|||
+ " and --trace-vcd with VerilatedVcd object\");\n");
|
||||
puts(/**/ "}\n");
|
||||
puts(/**/ "stfp->spTrace()->addModel(this);\n");
|
||||
puts(/**/ "stfp->spTrace()->addInitCb(&" + protect("trace_init")
|
||||
+ ", &(vlSymsp->TOP));\n");
|
||||
puts(/**/ "stfp->spTrace()->addInitCb("s //
|
||||
+ "&" + protect("trace_init") //
|
||||
+ ", &(vlSymsp->TOP)" //
|
||||
+ ", name()" //
|
||||
+ ", " + (v3Global.opt.libCreate().empty() ? "false" : "true") //
|
||||
+ ", " + std::to_string(v3Global.rootp()->nTraceCodes()) //
|
||||
+ ");\n");
|
||||
puts(/**/ topModNameProtected + "__" + protect("trace_register")
|
||||
+ "(&(vlSymsp->TOP), stfp->spTrace());\n");
|
||||
puts("}\n");
|
||||
|
|
|
|||
|
|
@ -122,6 +122,12 @@ class InlineMarkVisitor final : public VNVisitor {
|
|||
if (m_modp->modPublic() && (m_modp->isTop() || !v3Global.opt.flatten())) {
|
||||
cantInline("modPublic", false);
|
||||
}
|
||||
// If the instance is a --lib-create library stub instance, and need tracing,
|
||||
// then don't inline as we need to know its a lib stub for sepecial handling
|
||||
// in V3TraceDecl. See #7001.
|
||||
if (m_modp->verilatorLib() && v3Global.opt.trace()) {
|
||||
cantInline("verilatorLib with --trace", false);
|
||||
}
|
||||
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -307,6 +307,11 @@ class LinkResolveVisitor final : public VNVisitor {
|
|||
m_modp->modPublic(true); // Need to get to the task...
|
||||
nodep->unlinkFrBack();
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (nodep->pragType() == VPragmaType::VERILATOR_LIB) {
|
||||
UASSERT_OBJ(m_modp, nodep, "VERILATOR_LIB not under a module");
|
||||
m_modp->verilatorLib(true);
|
||||
nodep->unlinkFrBack();
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else {
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,6 +102,8 @@ class ProtectVisitor final : public VNVisitor {
|
|||
txtp->add("\n`ifdef VERILATOR\n");
|
||||
txtp->add("`verilator_config\n");
|
||||
|
||||
txtp->add("verilator_lib -module \"" + m_libName + "\"\n");
|
||||
|
||||
txtp->add("profile_data -hier-dpi \"" + m_libName + "_protectlib_combo_update\" -cost 64'd"
|
||||
+ std::to_string(v3Global.currentHierBlockCost()) + "\n");
|
||||
txtp->add("profile_data -hier-dpi \"" + m_libName + "_protectlib_seq_update\" -cost 64'd"
|
||||
|
|
|
|||
|
|
@ -847,6 +847,9 @@ class TraceVisitor final : public VNVisitor {
|
|||
|
||||
// Create the trace functions and insert them into the tree
|
||||
createTraceFunctions();
|
||||
|
||||
// Save number of trace codes used
|
||||
nodep->nTraceCodes(m_code);
|
||||
}
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
if (nodep->isTop()) m_topModp = nodep;
|
||||
|
|
|
|||
|
|
@ -94,8 +94,6 @@ public:
|
|||
// TraceDecl state, as a visitor of each AstNode
|
||||
|
||||
class TraceDeclVisitor final : public VNVisitor {
|
||||
// NODE STATE
|
||||
|
||||
// STATE
|
||||
AstTopScope* const m_topScopep; // The singleton AstTopScope
|
||||
const AstScope* m_currScopep = nullptr; // Current scope being visited
|
||||
|
|
@ -130,7 +128,7 @@ class TraceDeclVisitor final : public VNVisitor {
|
|||
std::string m_path; // Path to enclosing module in original hierarchy
|
||||
std::string m_name; // Name of signal/subscope
|
||||
|
||||
void init(const std::string& name, AstNode* nodep) {
|
||||
void init(const std::string& name, AstNode* nodep, bool inTopScope) {
|
||||
// Compute path in hierarchy and item name
|
||||
const std::string& vcdName = AstNode::vcdName(name);
|
||||
AstVar* const varp = VN_CAST(nodep, Var);
|
||||
|
|
@ -149,16 +147,33 @@ class TraceDeclVisitor final : public VNVisitor {
|
|||
m_path = vcdName.substr(0, pathLen);
|
||||
m_name = vcdName.substr(pathLen);
|
||||
}
|
||||
|
||||
// When creating a --lib-create library, drop the name of the top module (l2 name).
|
||||
// This will be replaced by the instance name in the model that uses the library.
|
||||
// This would be a bit murky when there are other top level entities ($unit,
|
||||
// packages, which have an instance in all libs - a problem on its own). If
|
||||
// --top-module was explicitly specified, then we will drop the prefix only for the
|
||||
// actual top level module, and wrap the rest in '$libroot'. This way at least we get a
|
||||
// usable dump of everything, with library instances showing in a right place, without
|
||||
// pollution from other top level entities.
|
||||
if (inTopScope && !v3Global.opt.libCreate().empty()) {
|
||||
const size_t start = m_path.find(' ');
|
||||
// Must have a prefix in the top scope with lib, as top wrapper signals not traced
|
||||
UASSERT_OBJ(start != std::string::npos, nodep, "No prefix with --lib-create");
|
||||
const std::string prefix = m_path.substr(0, start);
|
||||
m_path = m_path.substr(start + 1);
|
||||
if (v3Global.opt.topModule() != prefix) m_path = "$libroot " + m_path;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
explicit TraceEntry(AstVarScope* vscp)
|
||||
explicit TraceEntry(const AstScope* scopep, AstVarScope* vscp)
|
||||
: m_vscp{vscp} {
|
||||
init(vscp->varp()->name(), vscp->varp());
|
||||
init(vscp->varp()->name(), vscp->varp(), scopep->isTop());
|
||||
}
|
||||
explicit TraceEntry(AstCell* cellp)
|
||||
explicit TraceEntry(const AstScope* scopep, AstCell* cellp)
|
||||
: m_cellp{cellp} {
|
||||
init(cellp->name(), cellp);
|
||||
init(cellp->name(), cellp, scopep->isTop());
|
||||
}
|
||||
int operatorCompare(const TraceEntry& b) const {
|
||||
if (const int cmp = path().compare(b.path())) return cmp < 0;
|
||||
|
|
@ -296,6 +311,21 @@ class TraceDeclVisitor final : public VNVisitor {
|
|||
VL_DO_DANGLING(placeholderp->deleteTree(), placeholderp);
|
||||
}
|
||||
|
||||
void fixupLibStub(const std::string& path, AstNodeStmt* placeholderp) {
|
||||
FileLine* const flp = placeholderp->fileline();
|
||||
|
||||
// Call the initialization function for the library instance
|
||||
AstCStmt* const initp = new AstCStmt{flp};
|
||||
initp->add("tracep->initLib(vlSymsp->name() + ");
|
||||
initp->add(new AstConst{flp, AstConst::String{}, "." + AstNode::prettyName(path)});
|
||||
initp->add(");\n");
|
||||
|
||||
placeholderp->addNextHere(initp);
|
||||
// Delete the placeholder
|
||||
VL_DO_DANGLING(placeholderp->unlinkFrBack()->deleteTree(), placeholderp);
|
||||
return;
|
||||
}
|
||||
|
||||
void fixupPlaceholders() {
|
||||
// Fix up cell initialization placehodlers
|
||||
UINFO(9, "fixupPlaceholders()");
|
||||
|
|
@ -304,7 +334,11 @@ class TraceDeclVisitor final : public VNVisitor {
|
|||
const AstCell* const cellp = std::get<1>(item);
|
||||
AstNodeStmt* const placeholderp = std::get<2>(item);
|
||||
const std::string path = parentp->name() + "__DOT__" + cellp->name();
|
||||
fixupPlaceholder(path, placeholderp);
|
||||
if (cellp->modp()->verilatorLib()) {
|
||||
fixupLibStub(path, placeholderp);
|
||||
} else {
|
||||
fixupPlaceholder(path, placeholderp);
|
||||
}
|
||||
}
|
||||
|
||||
// Fix up interface reference initialization placeholders
|
||||
|
|
@ -364,6 +398,9 @@ class TraceDeclVisitor final : public VNVisitor {
|
|||
UASSERT_OBJ(!m_traValuep, nodep, "Should not nest");
|
||||
UASSERT_OBJ(m_traName.empty(), nodep, "Should not nest");
|
||||
|
||||
// If this is a stub for a --lib-create library, skip.
|
||||
if (nodep->modp()->verilatorLib()) return;
|
||||
|
||||
VL_RESTORER(m_currScopep);
|
||||
m_currScopep = nodep;
|
||||
|
||||
|
|
@ -372,7 +409,7 @@ class TraceDeclVisitor final : public VNVisitor {
|
|||
|
||||
// Gather cells under this scope
|
||||
for (AstNode* stmtp = nodep->modp()->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
if (AstCell* const cellp = VN_CAST(stmtp, Cell)) m_entries.emplace_back(cellp);
|
||||
if (AstCell* const cellp = VN_CAST(stmtp, Cell)) m_entries.emplace_back(nodep, cellp);
|
||||
}
|
||||
|
||||
if (!m_entries.empty()) {
|
||||
|
|
@ -483,8 +520,16 @@ class TraceDeclVisitor final : public VNVisitor {
|
|||
if (nodep->varp()->isClassMember()) return;
|
||||
if (nodep->varp()->isFuncLocal()) return;
|
||||
|
||||
// When creating a --lib-create library ...
|
||||
if (!v3Global.opt.libCreate().empty()) {
|
||||
// Ignore the wrapper created primary IO ports
|
||||
if (nodep->varp()->isPrimaryIO()) return;
|
||||
// Ignore parameters in packages. These will be traced at the top level.
|
||||
if (nodep->varp()->isParam() && VN_IS(nodep->scopep()->modp(), Package)) return;
|
||||
}
|
||||
|
||||
// Add to traced signal list
|
||||
m_entries.emplace_back(nodep);
|
||||
m_entries.emplace_back(m_currScopep, nodep);
|
||||
}
|
||||
|
||||
// VISITORS - Data types when tracing
|
||||
|
|
|
|||
|
|
@ -161,6 +161,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
|
|||
"timing_on" { FL; return yVLT_TIMING_ON; }
|
||||
"tracing_off" { FL; return yVLT_TRACING_OFF; }
|
||||
"tracing_on" { FL; return yVLT_TRACING_ON; }
|
||||
"verilator_lib" { FL; return yVLT_VERILATOR_LIB; }
|
||||
|
||||
-?"-block" { FL; return yVLT_D_BLOCK; }
|
||||
-?"-contents" { FL; return yVLT_D_CONTENTS; }
|
||||
|
|
|
|||
|
|
@ -271,6 +271,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"})
|
|||
%token<fl> yVLT_TIMING_ON "timing_on"
|
||||
%token<fl> yVLT_TRACING_OFF "tracing_off"
|
||||
%token<fl> yVLT_TRACING_ON "tracing_on"
|
||||
%token<fl> yVLT_VERILATOR_LIB "verilator_lib"
|
||||
|
||||
%token<fl> yVLT_D_BLOCK "--block"
|
||||
%token<fl> yVLT_D_CONTENTS "--contents"
|
||||
|
|
@ -8199,6 +8200,8 @@ vltItem:
|
|||
{ V3Control::addProfileData($<fl>1, *$2, $3->toUQuad()); }
|
||||
| yVLT_PROFILE_DATA vltDModel vltDMtask vltDCost
|
||||
{ V3Control::addProfileData($<fl>1, *$2, *$3, $4->toUQuad()); }
|
||||
| yVLT_VERILATOR_LIB vltDModule
|
||||
{ V3Control::addModulePragma(*$2, VPragmaType::VERILATOR_LIB); }
|
||||
;
|
||||
|
||||
vltOffFront<errcodeen>:
|
||||
|
|
|
|||
|
|
@ -2492,7 +2492,7 @@ class VlTest:
|
|||
print("%Warning: HARNESS_UPDATE_GOLDEN set: cp " + fn1 + " " + fn2, file=sys.stderr)
|
||||
shutil.copy(fn1, fn2)
|
||||
|
||||
def vcd_identical(self, fn1: str, fn2: str) -> None:
|
||||
def vcd_identical(self, fn1: str, fn2: str, ignore_attr: bool = False) -> None:
|
||||
"""Test if two VCD files have logically-identical contents"""
|
||||
# vcddiff to check transitions, if installed
|
||||
cmd = "vcddiff --help"
|
||||
|
|
@ -2511,6 +2511,9 @@ class VlTest:
|
|||
# Also provides backup if vcddiff not installed
|
||||
h1 = self._vcd_read(fn1)
|
||||
h2 = self._vcd_read(fn2)
|
||||
if ignore_attr:
|
||||
h1 = {k: v for k, v in h1.items() if "$attr" not in v}
|
||||
h2 = {k: v for k, v in h2.items() if "$attr" not in v}
|
||||
a = json.dumps(h1, sort_keys=True, indent=1)
|
||||
b = json.dumps(h2, sort_keys=True, indent=1)
|
||||
if a != b:
|
||||
|
|
@ -2530,11 +2533,17 @@ class VlTest:
|
|||
out = VtOs.run_capture(cmd, check=False)
|
||||
print(out)
|
||||
|
||||
def fst_identical(self, fn1: str, fn2: str) -> None:
|
||||
def fst_identical(self, fn1: str, fn2: str, ignore_attr: bool = False) -> None:
|
||||
"""Test if two FST files have logically-identical contents"""
|
||||
tmp = fn1 + ".vcd"
|
||||
self.fst2vcd(fn1, tmp)
|
||||
self.vcd_identical(tmp, fn2)
|
||||
if fn1.endswith(".fst"):
|
||||
tmp = fn1 + ".vcd"
|
||||
self.fst2vcd(fn1, tmp)
|
||||
fn1 = tmp
|
||||
if fn2.endswith(".fst"):
|
||||
tmp = fn2 + ".vcd"
|
||||
self.fst2vcd(fn2, tmp)
|
||||
fn2 = tmp
|
||||
self.vcd_identical(fn1, fn2, ignore_attr)
|
||||
|
||||
def saif_identical(self, fn1: str, fn2: str) -> None:
|
||||
"""Test if two SAIF files have logically-identical contents"""
|
||||
|
|
|
|||
|
|
@ -14,6 +14,17 @@
|
|||
`timescale 1ns/1ps
|
||||
`endif
|
||||
|
||||
package stateless_pkg;
|
||||
localparam int ONE = 1;
|
||||
endpackage
|
||||
|
||||
`ifdef STATEFUL_PKG
|
||||
// This is in the $unit package, and will have a copy in every library, which
|
||||
// is functionally incorrect, but testing it here to make sure it's at least
|
||||
// traced properly.
|
||||
logic global_flag = 1'b0;
|
||||
`endif
|
||||
|
||||
interface byte_ifs(input clk);
|
||||
logic [7:0] data;
|
||||
modport sender(input clk, output data);
|
||||
|
|
@ -27,6 +38,13 @@ typedef enum logic [1:0] {
|
|||
enum_val_3 = 2'd3
|
||||
} enum_t;
|
||||
|
||||
typedef enum logic [1:0] {
|
||||
alt_enum_0 = 2'd0,
|
||||
alt_enum_1 = 2'd1,
|
||||
alt_enum_2 = 2'd2,
|
||||
alt_enum_3 = 2'd3
|
||||
} alt_enum_t;
|
||||
|
||||
`ifdef AS_PROT_LIB
|
||||
module secret (
|
||||
clk
|
||||
|
|
@ -87,6 +105,9 @@ module t #(
|
|||
end
|
||||
end
|
||||
count <= count + 1;
|
||||
`ifdef STATEFUL_PKG
|
||||
global_flag <= ~global_flag;
|
||||
`endif
|
||||
end
|
||||
|
||||
`ifdef CPP_MACRO
|
||||
|
|
@ -126,21 +147,33 @@ module sub0(
|
|||
input wire clk,
|
||||
input wire [7:0] in,
|
||||
output wire [7:0] out); `HIER_BLOCK
|
||||
`ifdef NO_INLINE
|
||||
/* verilator no_inline_module */
|
||||
`endif
|
||||
|
||||
logic [7:0] ff;
|
||||
|
||||
always_ff @(posedge clk) ff <= in;
|
||||
assign out = ff;
|
||||
|
||||
`ifdef STATEFUL_PKG
|
||||
always_ff @(posedge clk) if (ff[0]) global_flag <= ff[1];
|
||||
`endif
|
||||
endmodule
|
||||
|
||||
module sub1(
|
||||
input wire clk,
|
||||
input wire [11:4] in, // Uses higher LSB to cover bug3539
|
||||
output wire [7:0] out); `HIER_BLOCK
|
||||
`ifdef NO_INLINE
|
||||
/* verilator no_inline_module */
|
||||
`endif
|
||||
|
||||
logic [7:0] ff;
|
||||
enum_t enum_v;
|
||||
|
||||
always_ff @(posedge clk) ff <= in + 1;
|
||||
always_ff @(posedge clk) ff <= in + 8'(stateless_pkg::ONE);
|
||||
always_ff @(posedge clk) enum_v <= enum_v.next();
|
||||
assign out = ff;
|
||||
endmodule
|
||||
|
||||
|
|
@ -150,6 +183,7 @@ module sub2(
|
|||
output wire [7:0] out); `HIER_BLOCK
|
||||
|
||||
logic [7:0] ff;
|
||||
alt_enum_t alt_enum_v;
|
||||
|
||||
// dpi_import_func returns (dpi_eport_func(v) -1)
|
||||
import "DPI-C" context function int dpi_import_func(int v);
|
||||
|
|
@ -160,6 +194,7 @@ module sub2(
|
|||
endfunction
|
||||
|
||||
always_ff @(posedge clk) ff <= 8'(dpi_import_func({24'b0, in})) + 8'd2;
|
||||
always_ff @(posedge clk) alt_enum_v <= alt_enum_v.next();
|
||||
|
||||
byte_ifs in_ifs(.clk(clk));
|
||||
byte_ifs out_ifs(.clk(clk));
|
||||
|
|
@ -202,6 +237,9 @@ module sub3 #(
|
|||
input wire clk,
|
||||
input wire [7:0] in,
|
||||
output wire [7:0] out); `HIER_BLOCK
|
||||
`ifdef NO_INLINE
|
||||
/* verilator no_inline_module */
|
||||
`endif
|
||||
|
||||
initial $display("P0:%d UNUSED:%d %s %d", P0, UNUSED, STR, ENUM);
|
||||
|
||||
|
|
@ -233,6 +271,9 @@ module sub4 #(
|
|||
input wire clk,
|
||||
input wire [7:0] in,
|
||||
output wire[7:0] out); `HIER_BLOCK
|
||||
`ifdef NO_INLINE
|
||||
/* verilator no_inline_module */
|
||||
`endif
|
||||
|
||||
initial begin
|
||||
if (P1 == 2) begin
|
||||
|
|
@ -296,6 +337,9 @@ module sub4 #(
|
|||
endmodule
|
||||
|
||||
module sub5 (input wire clk, input wire [127:0] in[2][3], output logic [7:0] out[2][3]); `HIER_BLOCK
|
||||
`ifdef NO_INLINE
|
||||
/* verilator no_inline_module */
|
||||
`endif
|
||||
|
||||
int count = 0;
|
||||
always @(posedge clk) begin
|
||||
|
|
@ -349,6 +393,9 @@ module sub5 (input wire clk, input wire [127:0] in[2][3], output logic [7:0] out
|
|||
endmodule
|
||||
|
||||
module sub6 #(parameter P0 = 1, parameter P1 = 2) (output wire [7:0] out[2]); `HIER_BLOCK
|
||||
`ifdef NO_INLINE
|
||||
/* verilator no_inline_module */
|
||||
`endif
|
||||
assign out[0] = 8'(P0);
|
||||
assign out[1] = 8'(P1);
|
||||
endmodule
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -4,31 +4,56 @@
|
|||
# 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: 2024 Wilson Snyder
|
||||
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.priority(30)
|
||||
noinline = "noinl" in test.name
|
||||
if not noinline:
|
||||
test.priority(30)
|
||||
test.scenarios('vlt_all')
|
||||
test.top_filename = "t/t_hier_block.v"
|
||||
|
||||
# CI environment offers 2 VCPUs, 2 thread setting causes the following warning.
|
||||
# %Warning-UNOPTTHREADS: Thread scheduler is unable to provide requested parallelism; consider asking for fewer threads.
|
||||
# So use 6 threads here though it's not optimal in performance, but ok.
|
||||
verilator_common_flags = [
|
||||
't/t_hier_block.cpp',
|
||||
'--Wno-TIMESCALEMOD',
|
||||
'--trace-fst',
|
||||
'--trace-underscore', # Should not trace handle
|
||||
"--trace-max-width",
|
||||
"0",
|
||||
"--trace-max-array",
|
||||
"0",
|
||||
"--trace-structs",
|
||||
]
|
||||
|
||||
test.compile(
|
||||
v_flags2=['t/t_hier_block.cpp'],
|
||||
verilator_flags2=[
|
||||
'--hierarchical',
|
||||
'--Wno-TIMESCALEMOD',
|
||||
'--trace-fst',
|
||||
'--no-trace-underscore', # To avoid handle mismatches
|
||||
],
|
||||
threads=(6 if test.vltmt else 1))
|
||||
verilator_hier_flags = verilator_common_flags + ['--hierarchical']
|
||||
if noinline:
|
||||
verilator_hier_flags.extend(["+define+NO_INLINE"])
|
||||
|
||||
test.execute()
|
||||
# Compile hierarchically
|
||||
test.vm_prefix = "Vhier"
|
||||
test.main_filename = test.obj_dir + "/Vhier__main.cpp"
|
||||
test.compile(verilator_flags2=verilator_hier_flags)
|
||||
|
||||
test.fst_identical(test.trace_filename, test.golden_filename)
|
||||
# Compile non hierarchically
|
||||
test.vm_prefix = "Vnonh"
|
||||
test.main_filename = test.obj_dir + "/Vnonh__main.cpp"
|
||||
test.compile(verilator_flags2=verilator_common_flags)
|
||||
|
||||
trace_hier = test.trace_filename.replace("simx", "hier")
|
||||
trace_nonh = test.trace_filename.replace("simx", "nonh")
|
||||
|
||||
# Run the hierarchical model
|
||||
test.execute(executable=test.obj_dir + "/Vhier")
|
||||
test.run(cmd=["mv", test.trace_filename, trace_hier])
|
||||
# Run the non hierarchical model
|
||||
test.execute(executable=test.obj_dir + "/Vnonh")
|
||||
test.run(cmd=["mv", test.trace_filename, trace_nonh])
|
||||
|
||||
# The two models must match - ignore enum type attributes which can differ
|
||||
test.fst_identical(trace_hier, trace_nonh, ignore_attr=True)
|
||||
# The hierarchical must match the reference
|
||||
test.fst_identical(trace_hier, test.golden_filename.replace("_noinl", ""))
|
||||
|
||||
test.passes()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
#!/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 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
import runpy
|
||||
|
||||
test.priority(30)
|
||||
test.scenarios('vlt_all')
|
||||
|
||||
runpy.run_path("t/t_hier_block_trace_fst.py", globals())
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -4,32 +4,57 @@
|
|||
# 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: 2025 Wilson Snyder
|
||||
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.priority(30)
|
||||
noinline = "noinl" in test.name
|
||||
if not noinline:
|
||||
test.priority(30)
|
||||
test.scenarios('vlt_all')
|
||||
test.top_filename = "t/t_hier_block.v"
|
||||
test.golden_filename = "t/t_hier_block_trace_saif.out"
|
||||
|
||||
# CI environment offers 2 VCPUs, 2 thread setting causes the following warning.
|
||||
# %Warning-UNOPTTHREADS: Thread scheduler is unable to provide requested parallelism; consider asking for fewer threads.
|
||||
# So use 6 threads here though it's not optimal in performance, but ok.
|
||||
verilator_common_flags = [
|
||||
't/t_hier_block.cpp',
|
||||
'--Wno-TIMESCALEMOD',
|
||||
'--trace-saif',
|
||||
'--trace-underscore', # Should not trace handle
|
||||
"--trace-max-width",
|
||||
"0",
|
||||
"--trace-max-array",
|
||||
"0",
|
||||
"--trace-structs",
|
||||
]
|
||||
|
||||
test.compile(
|
||||
v_flags2=['t/t_hier_block.cpp'],
|
||||
verilator_flags2=[
|
||||
'--hierarchical',
|
||||
'--Wno-TIMESCALEMOD',
|
||||
'--trace-saif',
|
||||
'--no-trace-underscore', # To avoid handle mismatches
|
||||
],
|
||||
threads=(6 if test.vltmt else 1))
|
||||
verilator_hier_flags = verilator_common_flags + ['--hierarchical']
|
||||
if noinline:
|
||||
verilator_hier_flags.extend(["+define+NO_INLINE"])
|
||||
|
||||
test.execute()
|
||||
# Compile hierarchically
|
||||
test.vm_prefix = "Vhier"
|
||||
test.main_filename = test.obj_dir + "/Vhier__main.cpp"
|
||||
test.compile(verilator_flags2=verilator_hier_flags)
|
||||
|
||||
test.saif_identical(test.trace_filename, test.golden_filename)
|
||||
# Compile non hierarchically
|
||||
test.vm_prefix = "Vnonh"
|
||||
test.main_filename = test.obj_dir + "/Vnonh__main.cpp"
|
||||
test.compile(verilator_flags2=verilator_common_flags)
|
||||
|
||||
trace_hier = test.trace_filename.replace("simx", "hier")
|
||||
trace_nonh = test.trace_filename.replace("simx", "nonh")
|
||||
|
||||
# Run the hierarchical model
|
||||
test.execute(executable=test.obj_dir + "/Vhier")
|
||||
test.run(cmd=["mv", test.trace_filename, trace_hier])
|
||||
# Run the non hierarchical model
|
||||
test.execute(executable=test.obj_dir + "/Vnonh")
|
||||
test.run(cmd=["mv", test.trace_filename, trace_nonh])
|
||||
|
||||
# The two models must match
|
||||
test.saif_identical(trace_hier, trace_nonh)
|
||||
# The hierarchical must match the reference
|
||||
test.saif_identical(trace_hier, test.golden_filename.replace("_noinl", ""))
|
||||
|
||||
test.passes()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
#!/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 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
import runpy
|
||||
|
||||
test.priority(30)
|
||||
test.scenarios('vlt_all')
|
||||
|
||||
runpy.run_path("t/t_hier_block_trace_saif.py", globals())
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -4,31 +4,70 @@
|
|||
# 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: 2024 Wilson Snyder
|
||||
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.priority(30)
|
||||
import re
|
||||
|
||||
noinline = "noinl" in test.name
|
||||
if not noinline:
|
||||
test.priority(30)
|
||||
test.scenarios('vlt_all')
|
||||
test.top_filename = "t/t_hier_block.v"
|
||||
|
||||
# CI environment offers 2 VCPUs, 2 thread setting causes the following warning.
|
||||
# %Warning-UNOPTTHREADS: Thread scheduler is unable to provide requested parallelism; consider asking for fewer threads.
|
||||
# So use 6 threads here though it's not optimal in performance, but ok.
|
||||
verilator_common_flags = [
|
||||
't/t_hier_block.cpp',
|
||||
'--Wno-TIMESCALEMOD',
|
||||
'--trace-vcd',
|
||||
'--trace-underscore', # Should not trace handle
|
||||
"--trace-max-width",
|
||||
"0",
|
||||
"--trace-max-array",
|
||||
"0",
|
||||
"--trace-structs",
|
||||
]
|
||||
|
||||
test.compile(
|
||||
v_flags2=['t/t_hier_block.cpp'],
|
||||
verilator_flags2=[
|
||||
'--hierarchical',
|
||||
'--Wno-TIMESCALEMOD',
|
||||
'--trace-vcd',
|
||||
'--no-trace-underscore', # To avoid handle mismatches
|
||||
],
|
||||
threads=(6 if test.vltmt else 1))
|
||||
verilator_hier_flags = verilator_common_flags + ['--hierarchical']
|
||||
if noinline:
|
||||
verilator_hier_flags.extend(["+define+NO_INLINE"])
|
||||
|
||||
test.execute()
|
||||
# Compile hierarchically
|
||||
test.vm_prefix = "Vhier"
|
||||
test.main_filename = test.obj_dir + "/Vhier__main.cpp"
|
||||
test.compile(verilator_flags2=verilator_hier_flags)
|
||||
|
||||
test.vcd_identical(test.trace_filename, test.golden_filename)
|
||||
# Compile non hierarchically
|
||||
test.vm_prefix = "Vnonh"
|
||||
test.main_filename = test.obj_dir + "/Vnonh__main.cpp"
|
||||
test.compile(verilator_flags2=verilator_common_flags)
|
||||
|
||||
trace_hier = test.trace_filename.replace("simx", "hier")
|
||||
trace_nonh = test.trace_filename.replace("simx", "nonh")
|
||||
|
||||
# Run the hierarchical model
|
||||
test.execute(executable=test.obj_dir + "/Vhier")
|
||||
test.run(cmd=["mv", test.trace_filename, trace_hier])
|
||||
# Run the non hierarchical model
|
||||
test.execute(executable=test.obj_dir + "/Vnonh")
|
||||
test.run(cmd=["mv", test.trace_filename, trace_nonh])
|
||||
|
||||
# Scope structure must match exactly
|
||||
with open(trace_nonh, 'r', encoding='utf8') as fnonh, open(trace_hier, 'r',
|
||||
encoding='utf8') as fhier:
|
||||
for la, lb in zip(fnonh, fhier):
|
||||
la = re.sub(r'^(\s*\$var\s+\S+\s+\S+\s+)\S+(.*)$', r'\1CODE\2', la)
|
||||
lb = re.sub(r'^(\s*\$var\s+\S+\s+\S+\s+)\S+(.*)$', r'\1CODE\2', lb)
|
||||
if la != lb:
|
||||
test.error_keep_going("VCD header mismatch: '{}' !~ '{}'".format(
|
||||
la.strip(), lb.strip()))
|
||||
if "enddefinitions" in la:
|
||||
break
|
||||
|
||||
# The two models must match
|
||||
test.vcd_identical(trace_hier, trace_nonh)
|
||||
# The hierarchical must match the reference
|
||||
test.vcd_identical(trace_hier, test.golden_filename.replace("_noinl", ""))
|
||||
|
||||
test.passes()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
#!/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 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
import runpy
|
||||
|
||||
test.priority(30)
|
||||
test.scenarios('vlt_all')
|
||||
|
||||
runpy.run_path("t/t_hier_block_trace_vcd.py", globals())
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,26 @@
|
|||
#!/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 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.priority(30)
|
||||
test.scenarios('vlt_all')
|
||||
test.top_filename = "t/t_hier_block.v"
|
||||
|
||||
test.compile(verilator_flags2=[
|
||||
't/t_hier_block.cpp', '--Wno-TIMESCALEMOD', '--trace-vcd', '--trace-underscore',
|
||||
"--trace-max-width", "0", "--trace-max-array", "0", "--trace-structs", "--hierarchical",
|
||||
"+define+STATEFUL_PKG"
|
||||
])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.vcd_identical(test.trace_filename, test.golden_filename)
|
||||
|
||||
test.passes()
|
||||
|
|
@ -1,268 +1,124 @@
|
|||
$version Generated by VerilatedVcd $end
|
||||
$timescale 1ps $end
|
||||
$scope module top $end
|
||||
$var wire 1 # clk $end
|
||||
$var wire 1 $ reset_l $end
|
||||
$var wire 1 " clk $end
|
||||
$var wire 1 # reset_l $end
|
||||
$scope module t $end
|
||||
$var wire 1 # clk $end
|
||||
$var wire 1 $ reset_l $end
|
||||
$var wire 1 " clk $end
|
||||
$var wire 1 # reset_l $end
|
||||
$scope module u0_sub_top $end
|
||||
$var wire 1 # clk $end
|
||||
$var wire 1 $ reset_l $end
|
||||
$var wire 1 $ clk $end
|
||||
$var wire 1 % reset_l $end
|
||||
$scope module u0 $end
|
||||
$var wire 1 & clk $end
|
||||
$var wire 1 ' reset_l $end
|
||||
$upscope $end
|
||||
$scope module u1 $end
|
||||
$var wire 1 ( clk $end
|
||||
$var wire 1 ) reset_l $end
|
||||
$upscope $end
|
||||
$scope module u2 $end
|
||||
$var wire 1 * clk $end
|
||||
$var wire 1 + reset_l $end
|
||||
$upscope $end
|
||||
$scope module u3 $end
|
||||
$var wire 1 , clk $end
|
||||
$var wire 1 - reset_l $end
|
||||
$upscope $end
|
||||
$scope module u4 $end
|
||||
$var wire 1 . clk $end
|
||||
$var wire 1 / reset_l $end
|
||||
$upscope $end
|
||||
$scope module u5 $end
|
||||
$var wire 1 0 clk $end
|
||||
$var wire 1 1 reset_l $end
|
||||
$upscope $end
|
||||
$scope module u6 $end
|
||||
$var wire 1 2 clk $end
|
||||
$var wire 1 3 reset_l $end
|
||||
$upscope $end
|
||||
$scope module u7 $end
|
||||
$var wire 1 4 clk $end
|
||||
$var wire 1 5 reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module u1_sub_top $end
|
||||
$var wire 1 # clk $end
|
||||
$var wire 1 $ reset_l $end
|
||||
$var wire 1 6 clk $end
|
||||
$var wire 1 7 reset_l $end
|
||||
$scope module u0 $end
|
||||
$var wire 1 8 clk $end
|
||||
$var wire 1 9 reset_l $end
|
||||
$upscope $end
|
||||
$scope module u1 $end
|
||||
$var wire 1 : clk $end
|
||||
$var wire 1 ; reset_l $end
|
||||
$upscope $end
|
||||
$scope module u2 $end
|
||||
$var wire 1 < clk $end
|
||||
$var wire 1 = reset_l $end
|
||||
$upscope $end
|
||||
$scope module u3 $end
|
||||
$var wire 1 > clk $end
|
||||
$var wire 1 ? reset_l $end
|
||||
$upscope $end
|
||||
$scope module u4 $end
|
||||
$var wire 1 @ clk $end
|
||||
$var wire 1 A reset_l $end
|
||||
$upscope $end
|
||||
$scope module u5 $end
|
||||
$var wire 1 B clk $end
|
||||
$var wire 1 C reset_l $end
|
||||
$upscope $end
|
||||
$scope module u6 $end
|
||||
$var wire 1 D clk $end
|
||||
$var wire 1 E reset_l $end
|
||||
$upscope $end
|
||||
$scope module u7 $end
|
||||
$var wire 1 F clk $end
|
||||
$var wire 1 G reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u0_sub_top $end
|
||||
$var wire 1 & clk $end
|
||||
$var wire 1 ' reset_l $end
|
||||
$scope module sub_top $end
|
||||
$var wire 1 & clk $end
|
||||
$var wire 1 ' reset_l $end
|
||||
$scope module u0 $end
|
||||
$var wire 1 & clk $end
|
||||
$var wire 1 ' reset_l $end
|
||||
$upscope $end
|
||||
$scope module u1 $end
|
||||
$var wire 1 & clk $end
|
||||
$var wire 1 ' reset_l $end
|
||||
$upscope $end
|
||||
$scope module u2 $end
|
||||
$var wire 1 & clk $end
|
||||
$var wire 1 ' reset_l $end
|
||||
$upscope $end
|
||||
$scope module u3 $end
|
||||
$var wire 1 & clk $end
|
||||
$var wire 1 ' reset_l $end
|
||||
$upscope $end
|
||||
$scope module u4 $end
|
||||
$var wire 1 & clk $end
|
||||
$var wire 1 ' reset_l $end
|
||||
$upscope $end
|
||||
$scope module u5 $end
|
||||
$var wire 1 & clk $end
|
||||
$var wire 1 ' reset_l $end
|
||||
$upscope $end
|
||||
$scope module u6 $end
|
||||
$var wire 1 & clk $end
|
||||
$var wire 1 ' reset_l $end
|
||||
$upscope $end
|
||||
$scope module u7 $end
|
||||
$var wire 1 & clk $end
|
||||
$var wire 1 ' reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u1_sub_top $end
|
||||
$var wire 1 ) clk $end
|
||||
$var wire 1 * reset_l $end
|
||||
$scope module sub_top $end
|
||||
$var wire 1 ) clk $end
|
||||
$var wire 1 * reset_l $end
|
||||
$scope module u0 $end
|
||||
$var wire 1 ) clk $end
|
||||
$var wire 1 * reset_l $end
|
||||
$upscope $end
|
||||
$scope module u1 $end
|
||||
$var wire 1 ) clk $end
|
||||
$var wire 1 * reset_l $end
|
||||
$upscope $end
|
||||
$scope module u2 $end
|
||||
$var wire 1 ) clk $end
|
||||
$var wire 1 * reset_l $end
|
||||
$upscope $end
|
||||
$scope module u3 $end
|
||||
$var wire 1 ) clk $end
|
||||
$var wire 1 * reset_l $end
|
||||
$upscope $end
|
||||
$scope module u4 $end
|
||||
$var wire 1 ) clk $end
|
||||
$var wire 1 * reset_l $end
|
||||
$upscope $end
|
||||
$scope module u5 $end
|
||||
$var wire 1 ) clk $end
|
||||
$var wire 1 * reset_l $end
|
||||
$upscope $end
|
||||
$scope module u6 $end
|
||||
$var wire 1 ) clk $end
|
||||
$var wire 1 * reset_l $end
|
||||
$upscope $end
|
||||
$scope module u7 $end
|
||||
$var wire 1 ) clk $end
|
||||
$var wire 1 * reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u0_sub_top.sub_top.u0 $end
|
||||
$var wire 1 , clk $end
|
||||
$var wire 1 - reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 , clk $end
|
||||
$var wire 1 - reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u0_sub_top.sub_top.u1 $end
|
||||
$var wire 1 / clk $end
|
||||
$var wire 1 0 reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 / clk $end
|
||||
$var wire 1 0 reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u0_sub_top.sub_top.u2 $end
|
||||
$var wire 1 2 clk $end
|
||||
$var wire 1 3 reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 2 clk $end
|
||||
$var wire 1 3 reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u0_sub_top.sub_top.u3 $end
|
||||
$var wire 1 5 clk $end
|
||||
$var wire 1 6 reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 5 clk $end
|
||||
$var wire 1 6 reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u0_sub_top.sub_top.u4 $end
|
||||
$var wire 1 8 clk $end
|
||||
$var wire 1 9 reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 8 clk $end
|
||||
$var wire 1 9 reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u0_sub_top.sub_top.u5 $end
|
||||
$var wire 1 ; clk $end
|
||||
$var wire 1 < reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 ; clk $end
|
||||
$var wire 1 < reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u0_sub_top.sub_top.u6 $end
|
||||
$var wire 1 > clk $end
|
||||
$var wire 1 ? reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 > clk $end
|
||||
$var wire 1 ? reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u0_sub_top.sub_top.u7 $end
|
||||
$var wire 1 A clk $end
|
||||
$var wire 1 B reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 A clk $end
|
||||
$var wire 1 B reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u1_sub_top.sub_top.u0 $end
|
||||
$var wire 1 D clk $end
|
||||
$var wire 1 E reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 D clk $end
|
||||
$var wire 1 E reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u1_sub_top.sub_top.u1 $end
|
||||
$var wire 1 G clk $end
|
||||
$var wire 1 H reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 G clk $end
|
||||
$var wire 1 H reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u1_sub_top.sub_top.u2 $end
|
||||
$var wire 1 J clk $end
|
||||
$var wire 1 K reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 J clk $end
|
||||
$var wire 1 K reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u1_sub_top.sub_top.u3 $end
|
||||
$var wire 1 M clk $end
|
||||
$var wire 1 N reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 M clk $end
|
||||
$var wire 1 N reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u1_sub_top.sub_top.u4 $end
|
||||
$var wire 1 P clk $end
|
||||
$var wire 1 Q reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 P clk $end
|
||||
$var wire 1 Q reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u1_sub_top.sub_top.u5 $end
|
||||
$var wire 1 S clk $end
|
||||
$var wire 1 T reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 S clk $end
|
||||
$var wire 1 T reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u1_sub_top.sub_top.u6 $end
|
||||
$var wire 1 V clk $end
|
||||
$var wire 1 W reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 V clk $end
|
||||
$var wire 1 W reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u1_sub_top.sub_top.u7 $end
|
||||
$var wire 1 Y clk $end
|
||||
$var wire 1 Z reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 Y clk $end
|
||||
$var wire 1 Z reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
|
||||
|
||||
#0
|
||||
0"
|
||||
0#
|
||||
0$
|
||||
0%
|
||||
06
|
||||
07
|
||||
0&
|
||||
0'
|
||||
0(
|
||||
0)
|
||||
0*
|
||||
0+
|
||||
0,
|
||||
0-
|
||||
0.
|
||||
0/
|
||||
00
|
||||
01
|
||||
02
|
||||
03
|
||||
04
|
||||
05
|
||||
06
|
||||
08
|
||||
09
|
||||
0:
|
||||
0;
|
||||
0<
|
||||
0=
|
||||
0>
|
||||
0?
|
||||
0@
|
||||
0A
|
||||
0B
|
||||
0C
|
||||
0D
|
||||
0E
|
||||
0F
|
||||
0G
|
||||
0H
|
||||
0J
|
||||
0K
|
||||
0M
|
||||
0N
|
||||
0P
|
||||
0Q
|
||||
0S
|
||||
0T
|
||||
0V
|
||||
0W
|
||||
0Y
|
||||
0Z
|
||||
|
|
|
|||
|
|
@ -1,268 +1,124 @@
|
|||
$version Generated by VerilatedVcd $end
|
||||
$timescale 1ps $end
|
||||
$scope module top $end
|
||||
$var wire 1 # clk $end
|
||||
$var wire 1 $ reset_l $end
|
||||
$var wire 1 " clk $end
|
||||
$var wire 1 # reset_l $end
|
||||
$scope module t $end
|
||||
$var wire 1 # clk $end
|
||||
$var wire 1 $ reset_l $end
|
||||
$var wire 1 " clk $end
|
||||
$var wire 1 # reset_l $end
|
||||
$scope module u0_sub_top $end
|
||||
$var wire 1 # clk $end
|
||||
$var wire 1 $ reset_l $end
|
||||
$var wire 1 $ clk $end
|
||||
$var wire 1 % reset_l $end
|
||||
$scope module u0 $end
|
||||
$var wire 1 & clk $end
|
||||
$var wire 1 ' reset_l $end
|
||||
$upscope $end
|
||||
$scope module u1 $end
|
||||
$var wire 1 ( clk $end
|
||||
$var wire 1 ) reset_l $end
|
||||
$upscope $end
|
||||
$scope module u2 $end
|
||||
$var wire 1 * clk $end
|
||||
$var wire 1 + reset_l $end
|
||||
$upscope $end
|
||||
$scope module u3 $end
|
||||
$var wire 1 , clk $end
|
||||
$var wire 1 - reset_l $end
|
||||
$upscope $end
|
||||
$scope module u4 $end
|
||||
$var wire 1 . clk $end
|
||||
$var wire 1 / reset_l $end
|
||||
$upscope $end
|
||||
$scope module u5 $end
|
||||
$var wire 1 0 clk $end
|
||||
$var wire 1 1 reset_l $end
|
||||
$upscope $end
|
||||
$scope module u6 $end
|
||||
$var wire 1 2 clk $end
|
||||
$var wire 1 3 reset_l $end
|
||||
$upscope $end
|
||||
$scope module u7 $end
|
||||
$var wire 1 4 clk $end
|
||||
$var wire 1 5 reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module u1_sub_top $end
|
||||
$var wire 1 # clk $end
|
||||
$var wire 1 $ reset_l $end
|
||||
$var wire 1 6 clk $end
|
||||
$var wire 1 7 reset_l $end
|
||||
$scope module u0 $end
|
||||
$var wire 1 8 clk $end
|
||||
$var wire 1 9 reset_l $end
|
||||
$upscope $end
|
||||
$scope module u1 $end
|
||||
$var wire 1 : clk $end
|
||||
$var wire 1 ; reset_l $end
|
||||
$upscope $end
|
||||
$scope module u2 $end
|
||||
$var wire 1 < clk $end
|
||||
$var wire 1 = reset_l $end
|
||||
$upscope $end
|
||||
$scope module u3 $end
|
||||
$var wire 1 > clk $end
|
||||
$var wire 1 ? reset_l $end
|
||||
$upscope $end
|
||||
$scope module u4 $end
|
||||
$var wire 1 @ clk $end
|
||||
$var wire 1 A reset_l $end
|
||||
$upscope $end
|
||||
$scope module u5 $end
|
||||
$var wire 1 B clk $end
|
||||
$var wire 1 C reset_l $end
|
||||
$upscope $end
|
||||
$scope module u6 $end
|
||||
$var wire 1 D clk $end
|
||||
$var wire 1 E reset_l $end
|
||||
$upscope $end
|
||||
$scope module u7 $end
|
||||
$var wire 1 F clk $end
|
||||
$var wire 1 G reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u0_sub_top $end
|
||||
$var wire 1 & clk $end
|
||||
$var wire 1 ' reset_l $end
|
||||
$scope module sub_top $end
|
||||
$var wire 1 & clk $end
|
||||
$var wire 1 ' reset_l $end
|
||||
$scope module u0 $end
|
||||
$var wire 1 & clk $end
|
||||
$var wire 1 ' reset_l $end
|
||||
$upscope $end
|
||||
$scope module u1 $end
|
||||
$var wire 1 & clk $end
|
||||
$var wire 1 ' reset_l $end
|
||||
$upscope $end
|
||||
$scope module u2 $end
|
||||
$var wire 1 & clk $end
|
||||
$var wire 1 ' reset_l $end
|
||||
$upscope $end
|
||||
$scope module u3 $end
|
||||
$var wire 1 & clk $end
|
||||
$var wire 1 ' reset_l $end
|
||||
$upscope $end
|
||||
$scope module u4 $end
|
||||
$var wire 1 & clk $end
|
||||
$var wire 1 ' reset_l $end
|
||||
$upscope $end
|
||||
$scope module u5 $end
|
||||
$var wire 1 & clk $end
|
||||
$var wire 1 ' reset_l $end
|
||||
$upscope $end
|
||||
$scope module u6 $end
|
||||
$var wire 1 & clk $end
|
||||
$var wire 1 ' reset_l $end
|
||||
$upscope $end
|
||||
$scope module u7 $end
|
||||
$var wire 1 & clk $end
|
||||
$var wire 1 ' reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u1_sub_top $end
|
||||
$var wire 1 ) clk $end
|
||||
$var wire 1 * reset_l $end
|
||||
$scope module sub_top $end
|
||||
$var wire 1 ) clk $end
|
||||
$var wire 1 * reset_l $end
|
||||
$scope module u0 $end
|
||||
$var wire 1 ) clk $end
|
||||
$var wire 1 * reset_l $end
|
||||
$upscope $end
|
||||
$scope module u1 $end
|
||||
$var wire 1 ) clk $end
|
||||
$var wire 1 * reset_l $end
|
||||
$upscope $end
|
||||
$scope module u2 $end
|
||||
$var wire 1 ) clk $end
|
||||
$var wire 1 * reset_l $end
|
||||
$upscope $end
|
||||
$scope module u3 $end
|
||||
$var wire 1 ) clk $end
|
||||
$var wire 1 * reset_l $end
|
||||
$upscope $end
|
||||
$scope module u4 $end
|
||||
$var wire 1 ) clk $end
|
||||
$var wire 1 * reset_l $end
|
||||
$upscope $end
|
||||
$scope module u5 $end
|
||||
$var wire 1 ) clk $end
|
||||
$var wire 1 * reset_l $end
|
||||
$upscope $end
|
||||
$scope module u6 $end
|
||||
$var wire 1 ) clk $end
|
||||
$var wire 1 * reset_l $end
|
||||
$upscope $end
|
||||
$scope module u7 $end
|
||||
$var wire 1 ) clk $end
|
||||
$var wire 1 * reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u0_sub_top.sub_top.u0 $end
|
||||
$var wire 1 , clk $end
|
||||
$var wire 1 - reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 , clk $end
|
||||
$var wire 1 - reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u0_sub_top.sub_top.u1 $end
|
||||
$var wire 1 / clk $end
|
||||
$var wire 1 0 reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 / clk $end
|
||||
$var wire 1 0 reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u0_sub_top.sub_top.u2 $end
|
||||
$var wire 1 2 clk $end
|
||||
$var wire 1 3 reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 2 clk $end
|
||||
$var wire 1 3 reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u0_sub_top.sub_top.u3 $end
|
||||
$var wire 1 5 clk $end
|
||||
$var wire 1 6 reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 5 clk $end
|
||||
$var wire 1 6 reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u0_sub_top.sub_top.u4 $end
|
||||
$var wire 1 8 clk $end
|
||||
$var wire 1 9 reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 8 clk $end
|
||||
$var wire 1 9 reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u0_sub_top.sub_top.u5 $end
|
||||
$var wire 1 ; clk $end
|
||||
$var wire 1 < reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 ; clk $end
|
||||
$var wire 1 < reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u0_sub_top.sub_top.u6 $end
|
||||
$var wire 1 > clk $end
|
||||
$var wire 1 ? reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 > clk $end
|
||||
$var wire 1 ? reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u0_sub_top.sub_top.u7 $end
|
||||
$var wire 1 A clk $end
|
||||
$var wire 1 B reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 A clk $end
|
||||
$var wire 1 B reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u1_sub_top.sub_top.u0 $end
|
||||
$var wire 1 D clk $end
|
||||
$var wire 1 E reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 D clk $end
|
||||
$var wire 1 E reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u1_sub_top.sub_top.u1 $end
|
||||
$var wire 1 G clk $end
|
||||
$var wire 1 H reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 G clk $end
|
||||
$var wire 1 H reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u1_sub_top.sub_top.u2 $end
|
||||
$var wire 1 J clk $end
|
||||
$var wire 1 K reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 J clk $end
|
||||
$var wire 1 K reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u1_sub_top.sub_top.u3 $end
|
||||
$var wire 1 M clk $end
|
||||
$var wire 1 N reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 M clk $end
|
||||
$var wire 1 N reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u1_sub_top.sub_top.u4 $end
|
||||
$var wire 1 P clk $end
|
||||
$var wire 1 Q reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 P clk $end
|
||||
$var wire 1 Q reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u1_sub_top.sub_top.u5 $end
|
||||
$var wire 1 S clk $end
|
||||
$var wire 1 T reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 S clk $end
|
||||
$var wire 1 T reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u1_sub_top.sub_top.u6 $end
|
||||
$var wire 1 V clk $end
|
||||
$var wire 1 W reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 V clk $end
|
||||
$var wire 1 W reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope module top.t.u1_sub_top.sub_top.u7 $end
|
||||
$var wire 1 Y clk $end
|
||||
$var wire 1 Z reset_l $end
|
||||
$scope module detail_code $end
|
||||
$var wire 1 Y clk $end
|
||||
$var wire 1 Z reset_l $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$enddefinitions $end
|
||||
|
||||
|
||||
#0
|
||||
0"
|
||||
0#
|
||||
0$
|
||||
0%
|
||||
06
|
||||
07
|
||||
0&
|
||||
0'
|
||||
0(
|
||||
0)
|
||||
0*
|
||||
0+
|
||||
0,
|
||||
0-
|
||||
0.
|
||||
0/
|
||||
00
|
||||
01
|
||||
02
|
||||
03
|
||||
04
|
||||
05
|
||||
06
|
||||
08
|
||||
09
|
||||
0:
|
||||
0;
|
||||
0<
|
||||
0=
|
||||
0>
|
||||
0?
|
||||
0@
|
||||
0A
|
||||
0B
|
||||
0C
|
||||
0D
|
||||
0E
|
||||
0F
|
||||
0G
|
||||
0H
|
||||
0J
|
||||
0K
|
||||
0M
|
||||
0N
|
||||
0P
|
||||
0Q
|
||||
0S
|
||||
0T
|
||||
0V
|
||||
0W
|
||||
0Y
|
||||
0Z
|
||||
|
|
|
|||
|
|
@ -3,4 +3,10 @@
|
|||
| ^~~~
|
||||
... For warning description see https://verilator.org/warn/IMPORTSTAR?v=latest
|
||||
... Use "/* verilator lint_off IMPORTSTAR */" and lint_on around source to disable this message.
|
||||
%Warning-UNUSEDPARAM: t/t_lint_importstar_bad.v:8:15: Parameter is not used: 'PAR'
|
||||
: ... note: In instance 't'
|
||||
8 | localparam PAR = 1;
|
||||
| ^~~
|
||||
... For warning description see https://verilator.org/warn/UNUSEDPARAM?v=latest
|
||||
... Use "/* verilator lint_off UNUSEDPARAM */" and lint_on around source to disable this message.
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
Loading…
Reference in New Issue