Internals: Make the constant pool a regular package (#8512)

The constant pool is now an ordinary package, created with the netlist
and instantiated under $root like any other package, and most special
handling has been removed, including AstConstPool. Lookups go through
V3ConstPool, which has a singleton instance owned by V3Global. Static
methods on V3Common form the public interfce to add/find constant pool
entries.

With that, the constant pool is usable at any stage during compilation,
so enum and dimension tables created by V3Width, and enum value tables
created by V3Randomize now also live in the constant pool instead of
$unit, so identical tables are shared.

Associative array constants are handled separately from unpacked
tables, which used to be broken but unused.

Emitted constant pool variables use direct initialization, and
`constinit` with C++20 where the type allows it. This ensures we don't
change a run-time in a way that would result in unintended code size
increase.

-fno-merge-const-pool, which was introduced years ago but never prompted
a bug report is deprecated and has no effect.

This is also prep for future work.
This commit is contained in:
Geza Lore
2026-09-27 13:25:41 +01:00
committed by GitHub
parent d234caafc1
commit 348b9b6209
68 changed files with 1239 additions and 930 deletions
+5
View File
@@ -852,6 +852,11 @@ Summary:
.. option:: -fno-merge-const-pool
Deprecated and has no effect (ignored).
In versions before 5.054: Disable merging constant pool entries that have
the same value but different data types.
.. option:: -fno-reloop
.. option:: -fno-reorder
+10
View File
@@ -32,6 +32,7 @@
#include <array>
#include <atomic>
#include <deque>
#include <initializer_list>
#include <map>
#include <memory>
#include <set>
@@ -1084,6 +1085,15 @@ public:
// CONSTRUCTORS
// m_defaultValue isn't defaulted. Caller's constructor must do it.
VlAssocArray() = default;
// Construct with the given entries
explicit VlAssocArray(std::initializer_list<std::pair<const T_Key, T_Value>> init)
: m_map{init}
, m_defaultValue{} {}
// Construct with the given default value and entries
explicit VlAssocArray(const T_Value& defaultValue,
std::initializer_list<std::pair<const T_Key, T_Value>> init)
: m_map{init}
, m_defaultValue{defaultValue} {}
~VlAssocArray() = default;
VlAssocArray(const VlAssocArray&) = default;
VlAssocArray(VlAssocArray&&) = default;
+2
View File
@@ -322,8 +322,10 @@
// C++-2020
#if __cplusplus >= 202002L
# define VL_CONSTINIT_CXX20 constinit
# define VL_NO_UNIQUE_ADDRESS_CXX20 [[no_unique_address]]
#else
# define VL_CONSTINIT_CXX20
# define VL_NO_UNIQUE_ADDRESS_CXX20
#endif
+2
View File
@@ -68,6 +68,7 @@ set(HEADERS
V3Combine.h
V3Common.h
V3Const.h
V3ConstPool.h
V3Container.h
V3Control.h
V3Coverage.h
@@ -237,6 +238,7 @@ set(COMMON_SOURCES
V3Clock.cpp
V3Combine.cpp
V3Common.cpp
V3ConstPool.cpp
V3Control.cpp
V3Const__gen.cpp
V3Coverage.cpp
+1
View File
@@ -213,6 +213,7 @@ RAW_OBJS_PCH_ASTMT = \
V3Ast.o \
V3AstNodes.o \
V3Broken.o \
V3ConstPool.o \
V3Control.o \
V3EmitCBase.o \
V3EmitCConstPool.o \
+3 -2
View File
@@ -150,6 +150,7 @@ bool AstActive::hasInitial() const { return m_sentreep->hasInitial(); }
bool AstActive::hasStatic() const { return m_sentreep->hasStatic(); }
bool AstNodeModule::isDollarUnit() const { return this == v3Global.rootp()->dollarUnitPkgp(); }
bool AstNodeModule::isConstPool() const { return this == v3Global.rootp()->constPoolPkgp(); }
AstAlways::AstAlways(AstAssignW* assignp)
: ASTGEN_SUPER_Always(assignp->fileline(), assignp)
@@ -167,10 +168,10 @@ bool AstVar::sameNode(const AstNode* samep) const {
&& covergroupRefMember() == asamep->covergroupRefMember();
}
AstMatchMasked::AstMatchMasked(FileLine* fl, AstNodeExpr* lhsp, AstVarScope* matchp)
AstMatchMasked::AstMatchMasked(FileLine* fl, AstNodeExpr* lhsp, AstVarRef* matchp)
: ASTGEN_SUPER_MatchMasked(fl) {
this->lhsp(lhsp);
this->matchp(new AstVarRef{fl, matchp, VAccess::READ});
this->matchp(matchp);
dtypeSetUInt32();
}
-8
View File
@@ -882,14 +882,8 @@ class AstEnumDType final : public AstNodeDType {
// @astgen op2 := itemsp : List[AstEnumItem]
//
// @astgen ptr := m_refDTypep : Optional[AstNodeDType] // Elements of this type (post-width)
public:
using TableMap = std::map<VAttrType, AstVar*>;
private:
string m_name; // Name from upper typedef, if any
const int m_uniqueNum; // Unique ID distinguishing this dtype instance, for hashing/naming
// dist-ast-dump-suppress // Skip dumping cache
TableMap m_tableMap; // Created table for V3Width only to remove duplicates
public:
AstEnumDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstEnumItem* itemsp)
@@ -937,8 +931,6 @@ public:
return count;
}
bool isCompound() const override { return false; }
TableMap& tableMap() { return m_tableMap; }
const TableMap& tableMap() const { return m_tableMap; }
};
class AstIfaceGenericDType final : public AstNodeDType {
+1 -1
View File
@@ -1907,7 +1907,7 @@ class AstMatchMasked final : public AstNodeExpr {
// @astgen op1 := lhsp : AstNodeExpr
// @astgen op2 := matchp : AstVarRef
public:
inline AstMatchMasked(FileLine* fl, AstNodeExpr* lhsp, AstVarScope* matchp);
inline AstMatchMasked(FileLine* fl, AstNodeExpr* lhsp, AstVarRef* matchp);
ASTGEN_MEMBERS_AstMatchMasked;
string emitVerilog() override { V3ERROR_NA_RETURN(""); }
string emitC() override { return "VL_MATCHMASKED_%lq(%lw, %li, %ri)"; }
+4 -37
View File
@@ -359,6 +359,7 @@ public:
string name() const override VL_MT_STABLE { return m_name; }
virtual bool timescaleMatters() const = 0;
inline bool isDollarUnit() const; // Is the $unit package
inline bool isConstPool() const; // Is the constant pool package
// ACCESSORS
void name(const string& name) override { m_name = name; }
string origName() const override { return m_origName; }
@@ -994,40 +995,6 @@ public:
void dump(std::ostream& str) const override;
void dumpJson(std::ostream& str) const override;
};
class AstConstPool final : public AstNode {
// Container for const static data
// @astgen op1 := modulep : AstModule // m_modp below TODO: fix this mess
//
// @astgen ptr := m_modp : AstModule // The Module holding the Scope below ...
// @astgen ptr := m_scopep : AstScope // Scope holding the constant variables
std::unordered_multimap<uint32_t, AstVarScope*> m_tables; // Constant tables (unpacked arrays)
std::unordered_multimap<uint32_t, AstVarScope*> m_consts; // Constant tables (scalars)
AstVarScope* createNewEntry(const string& name, AstNodeExpr* initp);
public:
explicit AstConstPool(FileLine* fl);
ASTGEN_MEMBERS_AstConstPool;
bool maybePointedTo() const override VL_MT_SAFE { return true; }
void cloneRelink() override { V3ERROR_NA; } // Not cloneable
AstModule* modp() const { return m_modp; }
AstScope* scopep() const { return m_scopep; }
// Find a table (unpacked array) within the constant pool which is initialized with the
// given value, or create one if one does not already exists. The returned VarScope *might*
// have a different dtype than the given initp->dtypep(), including a different element type,
// but it will always have the same size and element width. In contexts where this matters,
// the caller must handle the dtype difference as appropriate.
AstVarScope* findTable(AstInitArray* initp);
// Find a constant within the constant pool which is initialized with the given value, or
// create one if one does not already exists. If 'mergeDType' is true, then the returned
// VarScope *might* have a different type than the given initp->dtypep(). In contexts where
// this matters, the caller must handle the dtype difference as appropriate. If 'mergeDType' is
// false, the returned VarScope will have _->dtypep()->sameTree(initp->dtypep()) return true.
AstVarScope* findConst(AstConst* initp, bool mergeDType);
// Rebuild hashes and missing variable scopes after potential removals
void rebuildVarScopesAndCache();
};
class AstConstraint final : public AstNode {
// Constraint
// @astgen op1 := itemsp : List[AstNode]
@@ -1571,7 +1538,7 @@ class AstNetlist final : public AstNode {
// @astgen op3 := miscsp : List[AstNode]
//
// @astgen ptr := m_typeTablep : AstTypeTable // Reference to type table, for faster lookup
// @astgen ptr := m_constPoolp : AstConstPool // Reference to constant pool, for faster lookup
// @astgen ptr := m_constPoolPkgp : AstPackage // Constant pool package
// @astgen ptr := m_dollarUnitPkgp : Optional[AstPackage] // $unit
// @astgen ptr := m_stdPackagep : Optional[AstPackage] // SystemVerilog std package
// @astgen ptr := m_stdPackageProcessp : Optional[AstClass] // SystemVerilog std process class
@@ -1615,7 +1582,6 @@ public:
return modulesp(); // First one in the list, for now
}
AstTypeTable* typeTablep() { return m_typeTablep; }
AstConstPool* constPoolp() { return m_constPoolp; }
string astConstOrigParamName(const AstConst* nodep) const;
void astConstOrigParamName(const AstConst* nodep, const string& name);
void astConstOrigParamNameErase(const AstConst* nodep);
@@ -1623,6 +1589,7 @@ public:
const AstNodeModule* containingModule(const AstNode* nodep);
// Forget remembered modules, as the tree has moved.
void clearContainingModules() { m_containingModules.clear(); }
AstPackage* constPoolPkgp() const { return m_constPoolPkgp; }
AstPackage* dollarUnitPkgp() const { return m_dollarUnitPkgp; }
void dollarUnitPkgp(AstPackage* const packagep) { m_dollarUnitPkgp = packagep; }
AstCFunc* evalFuncp(VEval eval) const { return m_evalFuncps[eval]; }
@@ -3231,7 +3198,7 @@ public:
: ASTGEN_SUPER_Package(fl, name, libname) {}
ASTGEN_MEMBERS_AstPackage;
string verilogKwd() const override { return "package"; }
bool timescaleMatters() const override { return !isDollarUnit(); }
bool timescaleMatters() const override { return !isDollarUnit() && !isConstPool(); }
};
class AstPrimitive final : public AstNodeModule {
// A primitive declaration
+6 -156
View File
@@ -21,7 +21,6 @@
#include "V3File.h"
#include "V3Global.h"
#include "V3Graph.h"
#include "V3Hasher.h"
#include "V3InstrCount.h"
#include "V3Stats.h"
#include "V3String.h"
@@ -127,59 +126,6 @@ static AstDelay* getLhsNetDelayRecurse(const AstNodeExpr* const nodep) {
return nullptr;
}
static bool sameInit(const AstConst* ap, const AstConst* bp) {
// Similarly to the AstInitArray comparison, we ignore the dtype instance, so long as they
// are compatible. For now, we assume the dtype is not relevant, as we only call this from
// V3Prelim which is a late pass.
// Compare initializers by value. This checks widths as well.
return ap->num().isCaseEq(bp->num());
}
static bool sameInit(const AstInitArray* ap, const AstInitArray* bp) {
// Unpacked array initializers must have equivalent values
// Note, sadly we can't just call ap->sameTree(pb), because both:
// - the dtypes might be different instances
// - the default/inititem children might be in different order yet still yield the same table
// See note in AstInitArray::same about the same. This function instead compares by initializer
// value, rather than by tree structure.
if (const AstAssocArrayDType* const aDTypep = VN_CAST(ap->dtypep(), AssocArrayDType)) {
const AstAssocArrayDType* const bDTypep = VN_CAST(bp->dtypep(), AssocArrayDType);
if (!bDTypep) return false;
if (!aDTypep->subDTypep()->sameTree(bDTypep->subDTypep())) return false;
if (!aDTypep->keyDTypep()->sameTree(bDTypep->keyDTypep())) return false;
UASSERT_OBJ(ap->defaultp(), ap, "Assoc InitArray should have a default");
UASSERT_OBJ(bp->defaultp(), bp, "Assoc InitArray should have a default");
if (!ap->defaultp()->sameTree(bp->defaultp())) return false;
// Compare initializer arrays by value. Note this is only called when they hash the same,
// so they likely run at most once per call to 'AstConstPool::findTable'.
// This assumes that the defaults are used in the same way.
// TODO when building the AstInitArray, remove any values matching the default
const auto& amapr = ap->map();
const auto& bmapr = bp->map();
const auto ait = amapr.cbegin();
const auto bit = bmapr.cbegin();
while (ait != amapr.cend() || bit != bmapr.cend()) {
if (ait == amapr.cend() || bit == bmapr.cend()) return false; // Different size
if (ait->first != bit->first) return false; // Different key
if (ait->second->sameTree(bit->second)) return false; // Different value
}
} else if (const AstUnpackArrayDType* const aDTypep
= VN_CAST(ap->dtypep(), UnpackArrayDType)) {
const AstUnpackArrayDType* const bDTypep = VN_CAST(bp->dtypep(), UnpackArrayDType);
if (!bDTypep) return false;
if (!aDTypep->subDTypep()->sameTree(bDTypep->subDTypep())) return false;
if (!aDTypep->rangep()->sameTree(bDTypep->rangep())) return false;
// Compare initializer arrays by value. Note this is only called when they hash the same,
// so they likely run at most once per call to 'AstConstPool::findTable'.
const uint64_t size = aDTypep->elementsConst();
for (uint64_t n = 0; n < size; ++n) {
const AstNode* const valAp = ap->getIndexDefaultedValuep(n);
const AstNode* const valBp = bp->getIndexDefaultedValuep(n);
if (!valAp->sameTree(valBp)) return false;
}
}
return true;
}
//======================================================================
// AstNode:: functions (*not* general Ast{something} functions)
@@ -1050,103 +996,6 @@ AstConst::~AstConst() {
// is set, erase the entry before this AstConst address can be reused by a different node.
if (m_num.hasOrigParamName()) v3Global.rootp()->astConstOrigParamNameErase(this);
}
AstConstPool::AstConstPool(FileLine* fl)
: ASTGEN_SUPER_ConstPool(fl)
, m_modp{new AstModule{fl, "@CONST-POOL@", "work"}}
, m_scopep{new AstScope{fl, m_modp, "@CONST-POOL@", nullptr, nullptr}} {
this->modulep(m_modp);
m_modp->addStmtsp(m_scopep);
}
AstVarScope* AstConstPool::createNewEntry(const string& name, AstNodeExpr* initp) {
FileLine* const fl = initp->fileline();
AstVar* const varp = new AstVar{fl, VVarType::MODULETEMP, name, initp->dtypep()};
varp->setConstPoolEntry();
varp->isConst(true);
varp->isStatic(true);
varp->valuep(initp->cloneTree(false));
m_modp->addStmtsp(varp);
AstVarScope* const varScopep = new AstVarScope{fl, m_scopep, varp};
m_scopep->addVarsp(varScopep);
return varScopep;
}
AstVarScope* AstConstPool::findConst(AstConst* initp, bool mergeDType) {
// Try to find an existing constant with the same value
// cppcheck-suppress unreadVariable
const V3Hash hash = initp->num().toHash();
const auto& er = m_consts.equal_range(hash.value());
for (auto it = er.first; it != er.second; ++it) {
AstVarScope* const varScopep = it->second;
const AstConst* const init2p = VN_AS(varScopep->varp()->valuep(), Const);
if (sameInit(initp, init2p)
&& (mergeDType || varScopep->dtypep()->sameTree(initp->dtypep()))) {
return varScopep; // Found identical constant
}
}
// No such constant yet, create it.
string name = "CONST_";
name += hash.toString();
name += "_";
name += cvtToStr(std::distance(er.first, er.second));
AstVarScope* const varScopep = createNewEntry(name, initp);
m_consts.emplace(hash.value(), varScopep);
return varScopep;
}
AstVarScope* AstConstPool::findTable(AstInitArray* initp) {
const AstNode* const defaultp = initp->defaultp();
// Verify initializer is well formed
UASSERT_OBJ(VN_IS(initp->dtypep(), AssocArrayDType)
|| VN_IS(initp->dtypep(), UnpackArrayDType),
initp, "Const pool table must have array dtype");
UASSERT_OBJ(!defaultp || VN_IS(defaultp, Const), initp,
"Const pool table default must be Const");
for (AstNode* nodep = initp->initsp(); nodep; nodep = nodep->nextp()) {
const AstNode* const valuep = VN_AS(nodep, InitItem)->valuep();
UASSERT_OBJ(VN_IS(valuep, Const), valuep, "Const pool table entry must be Const");
}
// Try to find an existing table with the same content
// cppcheck-suppress unreadVariable
const V3Hash hash = V3Hasher::uncachedHash(initp);
const auto& er = m_tables.equal_range(hash.value());
for (auto it = er.first; it != er.second; ++it) {
AstVarScope* const varScopep = it->second;
const AstInitArray* const init2p = VN_AS(varScopep->varp()->valuep(), InitArray);
if (sameInit(initp, init2p)) {
return varScopep; // Found identical table
}
}
// No such table yet, create it.
string name = "TABLE_";
name += hash.toString();
name += "_";
name += cvtToStr(std::distance(er.first, er.second));
AstVarScope* const varScopep = createNewEntry(name, initp);
m_tables.emplace(hash.value(), varScopep);
return varScopep;
}
void AstConstPool::rebuildVarScopesAndCache() {
m_tables.clear();
m_consts.clear();
std::unordered_map<const AstVar*, AstVarScope*> varScopeps;
for (AstVarScope* vscp = m_scopep->varsp(); vscp; vscp = VN_CAST(vscp->nextp(), VarScope)) {
varScopeps.emplace(vscp->varp(), vscp);
}
for (AstNode* nodep = m_modp->stmtsp(); nodep; nodep = nodep->nextp()) {
AstVar* const varp = VN_CAST(nodep, Var);
if (!varp) continue;
AstNode* const valuep = varp->valuep();
if (!valuep) continue;
const bool isTable = VN_IS(valuep, InitArray);
const AstConst* const constp = VN_CAST(valuep, Const);
if (!isTable && !constp) continue;
AstVarScope*& vscp = varScopeps[varp];
if (!vscp) {
vscp = new AstVarScope{varp->fileline(), m_scopep, varp};
m_scopep->addVarsp(vscp);
}
if (isTable) m_tables.emplace(V3Hasher::uncachedHash(valuep).value(), vscp);
if (constp) m_consts.emplace(constp->num().toHash().value(), vscp);
}
}
void AstConstraint::dump(std::ostream& str) const {
Super::dump(str);
if (isExternDef()) str << " [EXTDEF]";
@@ -1414,8 +1263,6 @@ void AstEmptyQueueDType::dumpSmall(std::ostream& str) const {
}
const char* AstEnumDType::broken() const {
BROKEN_RTN(!((m_refDTypep && !childDTypep()) || (!m_refDTypep && childDTypep())));
BROKEN_RTN(std::any_of(m_tableMap.begin(), m_tableMap.end(),
[](const auto& p) { return !p.second->brokeExists(); }));
return nullptr;
}
void AstEnumDType::dump(std::ostream& str) const {
@@ -1917,15 +1764,18 @@ AstNodeBiop* AstNeq::newTyped(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp
AstNetlist::AstNetlist()
: ASTGEN_SUPER_Netlist(new FileLine{FileLine::builtInFilename()})
, m_typeTablep{new AstTypeTable{fileline()}}
, m_constPoolp{new AstConstPool{fileline()}}
, m_constPoolPkgp{new AstPackage{fileline(), "__Vconstpool", "work"}}
, m_dollarUnitPkgp{new AstPackage{fileline(), AstNode::encodeName("$unit"), "work"}} {
addMiscsp(m_typeTablep);
addMiscsp(m_constPoolp);
// packages are always libraries; don't want to make them a "top"
m_dollarUnitPkgp->level(1);
m_dollarUnitPkgp->inLibrary(true);
m_dollarUnitPkgp->modTrace(false); // may reconsider later
addModulesp(m_dollarUnitPkgp);
m_constPoolPkgp->level(1);
m_constPoolPkgp->inLibrary(true);
m_constPoolPkgp->modTrace(false);
addModulesp(m_constPoolPkgp);
}
void AstNetlist::addEvalStats(const std::string& phase) {
if (!v3Global.opt.stats()) return;
@@ -1986,7 +1836,7 @@ void AstNetlist::createTopScope(AstScope* scopep) {
void AstNetlist::deleteContents() {
// Delete all netlist memory. Only for use by Verilator.cpp
m_typeTablep = nullptr;
m_constPoolp = nullptr;
m_constPoolPkgp = nullptr;
m_dollarUnitPkgp = nullptr;
m_stdPackagep = nullptr;
m_dpiExportTriggerp = nullptr;
+6
View File
@@ -26,6 +26,8 @@
#include "V3Broken.h"
#include "V3ConstPool.h"
#include <unordered_set>
VL_DEFINE_DEBUG_FUNCTIONS;
@@ -432,6 +434,10 @@ void V3Broken::brokenAll(AstNetlist* nodep) {
// Check every node in tree
const BrokenCheckVisitor cvisitor{nodep};
// Check the constant pool lookup cache refers only to nodes in the tree
const char* const whyp = V3ConstPool::broken();
UASSERT_OBJ(!whyp, nodep, "Broken constant pool cache: " << whyp);
s_allocTable.checkForLeaks();
s_linkableTable.clear();
s_brokenCntGlobal.inc();
+1 -1
View File
@@ -152,6 +152,7 @@ class CCtorsVisitor final : public VNVisitor {
// VISITORS
void visit(AstNodeModule* nodep) override {
if (nodep->isConstPool()) return; // Special emit rules
if (const AstClass* const classp = VN_CAST(nodep, Class)) {
// Interface class may only have pure virtuals and params which do not need cctor reset
if (classp->isInterfaceClass()) return;
@@ -219,7 +220,6 @@ class CCtorsVisitor final : public VNVisitor {
}
}
void visit(AstConstPool*) override {}
void visit(AstNode* nodep) override { iterateChildren(nodep); }
public:
+2
View File
@@ -86,6 +86,7 @@ class CUseVisitor final : public VNVisitorConst {
}
void visit(AstCell* nodep) override {
if (nodep->user1SetOnce()) return; // Process once
if (nodep->modp()->isConstPool()) return; // Special emit rules
// Currently no IMP_INCLUDE because we include __Syms which has them all
addNewUse(nodep, VUseType::INT_FWD_CLASS, nodep->modp()->name());
iterateChildrenConst(nodep);
@@ -115,6 +116,7 @@ void V3CUse::cUseAll() {
// Call visitor separately for each module, so visitor state is cleared
for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp;
modp = VN_AS(modp->nextp(), NodeModule)) {
if (modp->isConstPool()) continue; // Special emit rules
// Insert under this module; someday we should e.g. make Ast
// for each output file and put under that
CUseVisitor{modp};
+10 -13
View File
@@ -38,6 +38,7 @@
#include "V3Case.h"
#include "V3ConstPool.h"
#include "V3Stats.h"
VL_DEFINE_DEBUG_FUNCTIONS;
@@ -738,18 +739,15 @@ class CaseVisitor final : public VNVisitor {
}
}
// Create the table in the constant pool, unless using an inline table
AstVarScope* const tableVscp = [&]() -> AstVarScope* {
if (isTinyTable) return nullptr;
AstVarScope* vscp = v3Global.rootp()->constPoolp()->findConst(tablep, true);
// Create the lookup table reference, in the constant pool unless using an inline table
AstNodeExpr* const tableRefp = [&]() -> AstNodeExpr* {
if (isTinyTable) return tablep;
AstVarRef* const refp = V3ConstPool::findConst(tablep);
VL_DO_DANGLING(tablep->deleteTree(), tablep); // findConst clones
return vscp;
return refp;
}();
// Create the lookup table reference and index
AstNodeExpr* const tableRefp
= tableVscp ? static_cast<AstNodeExpr*>(new AstVarRef{flp, tableVscp, VAccess::READ})
: static_cast<AstNodeExpr*>(tablep);
// Create the lookup index
AstNodeExpr* const caseExprp
= new AstExtend{flp, nodep->exprp()->cloneTreePure(false), 32};
AstNodeExpr* const scalep = new AstConst{flp, entryWidth};
@@ -855,15 +853,14 @@ class CaseVisitor final : public VNVisitor {
}
// Create the tables
AstVarScope* const matchVscp = v3Global.rootp()->constPoolp()->findConst(matchp, true);
AstVarScope* const tableVscp = v3Global.rootp()->constPoolp()->findTable(tablep);
AstVarRef* const matchRefp = V3ConstPool::findConst(matchp);
AstVarRef* const tableRefp = V3ConstPool::findTable(tablep);
VL_DO_DANGLING(matchp->deleteTree(), matchp);
VL_DO_DANGLING(tablep->deleteTree(), tablep);
// AstMatchMasked produces the index of the matching entry
AstNodeExpr* const tableRefp = new AstVarRef{flp, tableVscp, VAccess::READ};
AstNodeExpr* const caseExprp = nodep->exprp()->cloneTreePure(false);
AstMatchMasked* const indexp = new AstMatchMasked{flp, caseExprp, matchVscp};
AstMatchMasked* const indexp = new AstMatchMasked{flp, caseExprp, matchRefp};
AstNodeExpr* const entryp = new AstArraySel{flp, tableRefp, indexp};
return connectDecoderOutputs(nodep, entryp, "__VcaseDecoderOut");
-1
View File
@@ -318,7 +318,6 @@ class ToStringVisitor final : public VNVisitorConst {
}
}
}
void visit(AstConstPool*) override {} // Accelerate
void visit(AstNode* nodep) override { iterateChildrenConst(nodep); }
public:
+220
View File
@@ -0,0 +1,220 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Constant pool
//
// 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: 2026 Wilson Snyder
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
//
//*************************************************************************
#include "V3PchAstMT.h"
#include "V3ConstPool.h"
//######################################################################
// V3ConstPool
bool V3ConstPool::equalMap(const AstInitArray* ap, const AstInitArray* bp) {
// Associative array initializers must have equivalent types, defaults, and entries.
// As in 'equalTable', compare by value, rather than by tree structure.
const AstAssocArrayDType* const aDTypep = VN_AS(ap->dtypep(), AssocArrayDType);
const AstAssocArrayDType* const bDTypep = VN_AS(bp->dtypep(), AssocArrayDType);
if (!aDTypep->subDTypep()->sameTree(bDTypep->subDTypep())) return false;
if (!aDTypep->keyDTypep()->sameTree(bDTypep->keyDTypep())) return false;
// The default is optional, but must be the same if present
const AstNode* const aDefaultp = ap->defaultp();
const AstNode* const bDefaultp = bp->defaultp();
UASSERT_OBJ(!aDefaultp || VN_IS(aDefaultp, Const), ap, "Const pool map default not Const");
UASSERT_OBJ(!bDefaultp || VN_IS(bDefaultp, Const), bp, "Const pool map default not Const");
if (!aDefaultp != !bDefaultp) return false;
if (aDefaultp && !aDefaultp->sameTree(bDefaultp)) return false;
// Compare the entries, which are ordered by key. Note an entry explicitly set to the
// default value makes maps compare different, which is safe, but misses merging them.
const AstInitArray::KeyItemMap& aMap = ap->map();
const AstInitArray::KeyItemMap& bMap = bp->map();
if (aMap.size() != bMap.size()) return false;
auto bIt = bMap.cbegin();
for (const auto& aItem : aMap) {
const AstNode* const aValuep = aItem.second->valuep();
const AstNode* const bValuep = bIt->second->valuep();
UASSERT_OBJ(VN_IS(aValuep, Const), aValuep, "Const pool map item not Const");
UASSERT_OBJ(VN_IS(bValuep, Const), bValuep, "Const pool map item not Const");
if (aItem.first != bIt->first) return false;
if (!aValuep->sameTree(bValuep)) return false;
++bIt;
}
return true;
}
bool V3ConstPool::equalTable(const AstInitArray* ap, const AstInitArray* bp) {
// Unpacked array initializers must have equivalent values
// Note, sadly we can't just call ap->sameTree(pb), because both:
// - the dtypes might be different instances
// - the default/inititem children might be in different order yet still yield the same table
// See note in AstInitArray::same about the same. This function instead compares by initializer
// value, rather than by tree structure.
const AstUnpackArrayDType* const aDTypep = VN_AS(ap->dtypep(), UnpackArrayDType);
const AstUnpackArrayDType* const bDTypep = VN_AS(bp->dtypep(), UnpackArrayDType);
if (!aDTypep->subDTypep()->sameTree(bDTypep->subDTypep())) return false;
// Compare the range by value, as the bounds might be differently typed constants
if (!(aDTypep->declRange() == bDTypep->declRange())) return false;
// Compare initializer arrays by value. Note this is only called when they hash the same.
const uint64_t size = aDTypep->elementsConst();
for (uint64_t n = 0; n < size; ++n) {
const AstNode* const valAp = ap->getIndexDefaultedValuep(n);
const AstNode* const valBp = bp->getIndexDefaultedValuep(n);
UASSERT_OBJ(VN_IS(valAp, Const), valAp, "Const pool table item not Const");
UASSERT_OBJ(VN_IS(valBp, Const), valBp, "Const pool table item not Const");
if (!valAp->sameTree(valBp)) return false;
}
return true;
}
size_t V3ConstPool::hashTable(const AstInitArray* initp) {
// Hash what 'equalTable' compares: the element type, the range by value, and the values
const AstUnpackArrayDType* const dtypep = VN_AS(initp->dtypep(), UnpackArrayDType);
V3Hash hash = V3Hasher::uncachedHash(dtypep->subDTypep());
hash += dtypep->left();
hash += dtypep->right();
const uint64_t size = dtypep->elementsConst();
for (uint64_t n = 0; n < size; ++n) {
hash += V3Hasher::uncachedHash(initp->getIndexDefaultedValuep(n));
}
return hash.value();
}
template <typename T_Set, typename T_Init>
AstVarRef* V3ConstPool::findOrCreate(T_Set& set, uint32_t& nextr, const char* prefixp,
T_Init* initp) {
// Rebuild the cache if invalidated
if (VL_UNLIKELY(!m_cacheValid)) {
m_cacheValid = true;
m_scopep = nullptr;
m_consts.clear();
m_maps.clear();
m_tables.clear();
m_varScopes.clear();
AstPackage* const pkgp = v3Global.rootp()->constPoolPkgp();
for (AstNode* nodep = pkgp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (AstScope* const scopep = VN_CAST(nodep, Scope)) {
if (m_stage == Stage::SCOPED) m_scopep = scopep;
continue;
}
// Otherwise must be a variable
AstVar* const varp = VN_AS(nodep, Var);
UASSERT_OBJ(varp->constPoolEntry(), varp, "Unmarked variable in constant pool");
if (VN_IS(varp->valuep(), Const)) {
m_consts.insert(varp);
} else if (const AstInitArray* const arrayp = VN_CAST(varp->valuep(), InitArray)) {
if (VN_IS(arrayp->dtypep(), AssocArrayDType)) {
m_maps.insert(varp);
} else {
m_tables.insert(varp);
}
}
}
if (m_scopep) {
for (AstVarScope* vscp = m_scopep->varsp(); vscp;
vscp = VN_AS(vscp->nextp(), VarScope)) {
m_varScopes.insert({vscp->varp(), vscp});
}
}
}
FileLine* const flp = initp->fileline();
AstNodeDType* const dtypep = initp->dtypep();
// Look up/create the variable with this value
const auto pair = set.insertLazy(initp, [&]() {
const std::string name = prefixp + std::to_string(nextr++);
AstVar* const varp = new AstVar{flp, VVarType::MODULETEMP, name, dtypep};
varp->setConstPoolEntry();
varp->lifetime(VLifetime::STATIC_EXPLICIT);
varp->isConst(true);
varp->isStatic(true);
varp->valuep(initp->cloneTree(false));
v3Global.rootp()->constPoolPkgp()->addStmtsp(varp);
return varp;
});
AstVar* const varp = *pair.first;
// Create a read reference to the entry, of the right form for the current stage
AstVarRef* refp = nullptr;
switch (m_stage) {
case Stage::UNSCOPED: {
// Before V3Scope, reference via the package, as any other package variable
AstPackage* const pkgp = v3Global.rootp()->constPoolPkgp();
refp = new AstVarRef{flp, pkgp, varp, VAccess::READ};
break;
}
case Stage::SCOPED: {
// While scoped, reference the VarScope, creating it for a new entry, or if removed
const auto vscpPair = m_varScopes.insertLazy(varp, [&]() {
AstVarScope* const vscp = new AstVarScope{varp->fileline(), m_scopep, varp};
m_scopep->addVarsp(vscp);
return std::pair<const AstVar*, AstVarScope*>{varp, vscp};
});
refp = new AstVarRef{flp, vscpPair.first->second, VAccess::READ};
break;
}
case Stage::DESCOPED: {
// After V3Descope, no VarScope is needed
refp = new AstVarRef{flp, varp, VAccess::READ};
break;
}
}
// The entry might have been created with a different, but compatible dtype
refp->dtypep(dtypep);
return refp;
}
AstVarRef* V3ConstPool::findConst(AstConst* initp) {
V3ConstPool& self = instance();
return self.findOrCreate(self.m_consts, self.m_nextConst, "CONST_", initp);
}
AstVarRef* V3ConstPool::findMap(AstInitArray* initp) {
UASSERT_OBJ(VN_IS(initp->dtypep(), AssocArrayDType), initp,
"Const pool map must have associative array dtype");
V3ConstPool& self = instance();
return self.findOrCreate(self.m_maps, self.m_nextMap, "MAP_", initp);
}
AstVarRef* V3ConstPool::findTable(AstInitArray* initp) {
UASSERT_OBJ(VN_IS(initp->dtypep(), UnpackArrayDType), initp,
"Const pool table must have unpacked array dtype");
V3ConstPool& self = instance();
return self.findOrCreate(self.m_tables, self.m_nextTable, "TABLE_", initp);
}
AstVarRef* V3ConstPool::find(AstNodeExpr* initp) {
if (AstConst* const constp = VN_CAST(initp, Const)) return findConst(constp);
if (AstInitArray* const arrayp = VN_CAST(initp, InitArray)) {
if (VN_IS(arrayp->dtypep(), AssocArrayDType)) return findMap(arrayp);
if (VN_IS(arrayp->dtypep(), UnpackArrayDType)) return findTable(arrayp);
}
initp->v3fatalSrc("Unhandled constant pool initializer");
return nullptr; // LCOV_EXCL_LINE
}
const char* V3ConstPool::broken() {
const V3ConstPool& self = instance();
if (!self.m_cacheValid) return nullptr;
BROKEN_RTN(self.m_scopep && !self.m_scopep->brokeExists());
for (const AstVar* const varp : self.m_consts) BROKEN_RTN(!varp->brokeExists());
for (const AstVar* const varp : self.m_maps) BROKEN_RTN(!varp->brokeExists());
for (const AstVar* const varp : self.m_tables) BROKEN_RTN(!varp->brokeExists());
for (const auto& pair : self.m_varScopes) {
BROKEN_RTN(!pair.first->brokeExists());
BROKEN_RTN(!pair.second->brokeExists());
}
return nullptr;
}
+163
View File
@@ -0,0 +1,163 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Constant pool
//
// 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: 2026 Wilson Snyder
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
//
//*************************************************************************
//
// V3ConstPool finds or creates entries in the constant pool package
// (AstNetlist::constPoolPkgp()), which holds read-only static data, i.e.:
// constants, maps and tables, shared across the whole design. Entries are
// ordinary package variables, deduplicated by value.
//
//*************************************************************************
#ifndef VERILATOR_V3CONSTPOOL_H_
#define VERILATOR_V3CONSTPOOL_H_
#include "config_build.h"
#include "verilatedos.h"
#include "V3Ast.h"
#include "V3HashTable.h"
#include "V3Hasher.h"
//============================================================================
class V3ConstPool final {
friend class V3Global; // Owns the instance, needs constructor access
// TYPES
// Scoping stage of the design, which determines how entries are referenced
enum class Stage : uint8_t {
UNSCOPED, // Before V3Scope: reference via the package
SCOPED, // Between V3Scope and V3Descope: reference via the VarScope
DESCOPED // After V3Descope: plain reference
};
// Hash and equality of constant entries in 'm_consts'
struct ConstHash final {
size_t operator()(const AstVar* varp) const {
return (*this)(VN_AS(varp->valuep(), Const));
}
size_t operator()(const AstConst* initp) const { return initp->num().toHash().value(); }
};
struct ConstEqual final {
bool operator()(const AstVar* ap, const AstVar* bp) const { // LCOV_EXCL_START
return (*this)(ap, VN_AS(bp->valuep(), Const)); // Only on collision while rebuild
} // LCOV_EXCL_STOP
bool operator()(const AstVar* varp, const AstConst* initp) const {
// Compare by value, which also checks the width. The dtype is ignored.
return VN_AS(varp->valuep(), Const)->num().isCaseEq(initp->num());
}
};
// Hash and equality of associative array entries in 'm_maps'
struct MapHash final {
size_t operator()(const AstVar* varp) const {
return (*this)(VN_AS(varp->valuep(), InitArray));
}
size_t operator()(const AstInitArray* initp) const {
return V3Hasher::uncachedHash(initp).value();
}
};
struct MapEqual final {
bool operator()(const AstVar* ap, const AstVar* bp) const { // LCOV_EXCL_START
return (*this)(ap, VN_AS(bp->valuep(), InitArray)); // Only on collision while rebuild
} // LCOV_EXCL_STOP
bool operator()(const AstVar* varp, const AstInitArray* initp) const {
return equalMap(VN_AS(varp->valuep(), InitArray), initp);
}
};
// Hash and equality of unpacked array entries in 'm_tables'
struct TableHash final {
size_t operator()(const AstVar* varp) const {
return (*this)(VN_AS(varp->valuep(), InitArray));
}
size_t operator()(const AstInitArray* initp) const { //
return hashTable(initp);
}
};
struct TableEqual final {
bool operator()(const AstVar* ap, const AstVar* bp) const { // LCOV_EXCL_START
return (*this)(ap, VN_AS(bp->valuep(), InitArray)); // Only on collision while rebuild
} // LCOV_EXCL_STOP
bool operator()(const AstVar* varp, const AstInitArray* initp) const {
return equalTable(VN_AS(varp->valuep(), InitArray), initp);
}
};
// MEMBERS
Stage m_stage = Stage::UNSCOPED; // Scoping stage of the design, see setScoped()/setDescoped()
bool m_cacheValid = false; // Cache below is up to date
AstScope* m_scopep = nullptr; // Scope of the constant pool, between V3Scope and V3Descope
V3HashSet<AstVar*, ConstHash, ConstEqual> m_consts; // Packed constants
V3HashSet<AstVar*, MapHash, MapEqual> m_maps; // Associative array constants (maps)
V3HashSet<AstVar*, TableHash, TableEqual> m_tables; // Unpacked array constants (tables)
V3HashMap<const AstVar*, AstVarScope*> m_varScopes; // VarScope of each entry iff m_scopep
uint32_t m_nextConst = 0; // Sequence number for naming
uint32_t m_nextMap = 0; // Sequence number for naming
uint32_t m_nextTable = 0; // Sequence number for naming
// METHODS
static V3ConstPool& instance() { return *v3Global.constPoolp(); }
static bool equalMap(const AstInitArray* ap, const AstInitArray* bp);
static bool equalTable(const AstInitArray* ap, const AstInitArray* bp);
static size_t hashTable(const AstInitArray* initp);
// Find an entry equal to the given initializer in the given set, or create one named from
// the given prefix and sequence number, and return a read reference to it
template <typename T_Set, typename T_Init>
AstVarRef* findOrCreate(T_Set& set, uint32_t& nextr, const char* prefixp, T_Init* initp);
// CONSTRUCTORS - only V3Global creates and deletes the instance
V3ConstPool() = default;
~V3ConstPool() = default;
VL_UNCOPYABLE(V3ConstPool);
VL_UNMOVABLE(V3ConstPool);
public:
// STATIC METHODS
// Find a constant packed variable with the given value, or create one if one does not
// already exist, and return a read reference to it.
// The reference has the same dtype as initp.
// The referenced variable *might* have a different, but compatible dtype.
static AstVarRef* findConst(AstConst* initp);
// Find a constant associative array (map) with the given value, or create one if one does
// not already exist, and return a read reference to it.
// The reference has the same dtype as initp.
// The referenced variable *might* have a different, but compatible dtype.
static AstVarRef* findMap(AstInitArray* initp);
// Find a constant unpacked array (table) with the given value, or create one if one does
// not already exist, and return a read reference to it.
// The reference has the same dtype as initp.
// The referenced variable *might* have a different, but compatible dtype.
static AstVarRef* findTable(AstInitArray* initp);
// Dispatch to the above based on the kind of initializer.
static AstVarRef* find(AstNodeExpr* initp);
// Invalidate the lookup cache. This must be called after deleting any Vars from the pool.
static void invalidateCache() { instance().m_cacheValid = false; }
// Notify that the design has been scoped, called by V3Scope
static void setScoped() {
V3ConstPool& self = instance();
UASSERT(self.m_stage == Stage::UNSCOPED, "Constant pool scoped twice");
self.m_stage = Stage::SCOPED;
invalidateCache();
}
// Notify that the design has been descoped, called by V3Descope
static void setDescoped() {
V3ConstPool& self = instance();
UASSERT(self.m_stage == Stage::SCOPED, "Constant pool descoped when not scoped");
self.m_stage = Stage::DESCOPED;
invalidateCache();
}
// Check the lookup cache refers only to existing nodes, for V3Broken
static const char* broken();
};
#endif // Guard
+6 -7
View File
@@ -37,6 +37,7 @@
#include "V3Dead.h"
#include "V3ConstPool.h"
#include "V3Graph.h"
#include "V3Stats.h"
@@ -371,6 +372,8 @@ class DeadVisitor final : public VNVisitor {
// Class packages might have no children, but need to remain as
// long as the class they refer to is needed
if (VN_IS(m_modp, Class) || VN_IS(m_modp, ClassPackage)) nodep->user1Inc();
// The constant pool scope must remain for entries created later
if (m_modp->isConstPool()) nodep->user1Inc();
if (!nodep->isTop() && !nodep->varsp() && !nodep->blocksp()) {
m_scopesp.push_back(nodep);
}
@@ -464,11 +467,6 @@ class DeadVisitor final : public VNVisitor {
checkDType(nodep);
checkAll(nodep);
}
void visit(AstEnumDType* nodep) override {
// Widthing during parameter evaluation may have populated the cache.
nodep->tableMap().clear();
visit(static_cast<AstNodeDType*>(nodep));
}
void visit(AstEnumItemRef* nodep) override {
iterateChildren(nodep);
checkAll(nodep);
@@ -670,7 +668,8 @@ class DeadVisitor final : public VNVisitor {
nextmodp = VN_AS(modp->nextp(), NodeModule);
// Keep $unit until m_elimCells stages. Note v3Global.opt.serializeOnly()
// won't reach this stage, and will always have an empty $unit. That's ok.
const bool keep = !m_elimCells && modp->isDollarUnit();
// The constant pool is always kept, entries might be created later.
const bool keep = (!m_elimCells && modp->isDollarUnit()) || modp->isConstPool();
if (modp->dead() || (!modp->isTop() && modp->user1() == 0 && !keep)) {
// > 2 because L1 is the wrapper, L2 is the top user module
UINFO(4, " Dead module " << modp);
@@ -842,7 +841,7 @@ public:
// We may have removed some datatypes, cleanup
nodep->typeTablep()->repairCache();
VIsCached::clearCacheTree(); // Removing assignments may affect isPure
nodep->constPoolp()->rebuildVarScopesAndCache();
V3ConstPool::invalidateCache(); // Might have deleted constant pool entries
}
~DeadVisitor() override {
V3Stats::addStatSum("Optimizations, FTasks, virtual-to-nonvirtual demotion",
+3 -1
View File
@@ -26,6 +26,7 @@
#include "V3Descope.h"
#include "V3ConstPool.h"
#include "V3EmitCBase.h"
VL_DEFINE_DEBUG_FUNCTIONS;
@@ -235,7 +236,7 @@ class DescopeVisitor final : public VNVisitor {
if (varp->isFuncLocal()) {
// Reference to function locals need no self pointer
nodep->selfPointer(VSelfPointerText{VSelfPointerText::Empty()});
} else if (scopep->modp() == v3Global.rootp()->constPoolp()->modp()) {
} else if (scopep->modp()->isConstPool()) {
// Reference to constant pool value need no self pointer
nodep->selfPointer(VSelfPointerText{VSelfPointerText::Empty()});
} else {
@@ -294,5 +295,6 @@ public:
void V3Descope::descopeAll(AstNetlist* nodep) {
UINFO(2, __FUNCTION__ << ":");
{ DescopeVisitor{nodep}; } // Destruct before checking
V3ConstPool::setDescoped();
V3Global::dumpCheckGlobalTree("descope", 0, dumpTreeEitherLevel() >= 3);
}
+2 -3
View File
@@ -794,7 +794,6 @@ AstScope* DfgVertex::scopep(ScopeCache& cache, bool tryResultVar) VL_MT_DISABLED
}
AstScope* const rootp = v3Global.rootp()->topScopep()->scopep();
AstScope* const constPoolp = v3Global.rootp()->constPoolp()->scopep();
// Note: the recursive invocation can cause a re-hash but that will not invalidate references
AstScope*& resultr = cache[this];
@@ -802,11 +801,11 @@ AstScope* DfgVertex::scopep(ScopeCache& cache, bool tryResultVar) VL_MT_DISABLED
// Mark to prevent infinite recursion on circular graphs - should never be called on such
resultr = reinterpret_cast<AstScope*>(1);
// Find scope based on sources, falling back on the root scope. Never use a package
// scope, nor the constant pool scope, so new variables are not created in those.
// scope, including the constant pool, so new variables are not created in packages.
AstScope* foundp = nullptr;
foreachSource([&](DfgVertex& src) {
AstScope* const scp = src.scopep(cache, true);
if (scp != rootp && scp != constPoolp && !VN_IS(scp->modp(), Package)) {
if (scp != rootp && !VN_IS(scp->modp(), Package)) {
foundp = scp;
return true;
}
+1 -1
View File
@@ -242,7 +242,7 @@ class DfgToAstVisitor final : DfgVisitor {
FileLine* const flp = vtxp->fileline();
AstNodeExpr* const lhsp = convertDfgVertexToAstNodeExpr(vtxp->lhsp());
AstVarScope* const matchp = vtxp->matchp()->as<DfgVertexVar>()->vscp();
m_resultp = new AstMatchMasked{flp, lhsp, matchp};
m_resultp = new AstMatchMasked{flp, lhsp, new AstVarRef{flp, matchp, VAccess::READ}};
}
void visit(DfgRep* vtxp) override {
+1 -1
View File
@@ -82,7 +82,7 @@ class DataflowOptimize final {
const bool hasExtRd = //
varp->isPrimaryIO() // Top level port - readable
|| varp->isSigUserRdPublic() // Readable by user
|| varp->constPoolEntry() // Stored in AstConstPool hashmap, but read only
|| varp->constPoolEntry() // Held in V3ConstPool lookup cache, keep
;
const bool hasExtWr = //
(varp->isPrimaryIO() && varp->isNonOutput()) // Top level port - writable
-1
View File
@@ -35,7 +35,6 @@ EmitCParentModule::EmitCParentModule() {
for (AstNode* modp = v3Global.rootp()->modulesp(); modp; modp = modp->nextp()) {
setAll(VN_AS(modp, NodeModule));
}
setAll(v3Global.rootp()->constPoolp()->modp());
}
//######################################################################
-3
View File
@@ -77,9 +77,6 @@ public:
&& !dtp->isCompound() // Non-POD members are not allowed in an anonymous aggregate
&& (varp->basicp() && !varp->basicp()->isOpaque()); // Aggregates can't be anon
}
static bool isConstPoolMod(const AstNode* modp) {
return modp == v3Global.rootp()->constPoolp()->modp();
}
};
//######################################################################
+54 -20
View File
@@ -41,30 +41,47 @@ class EmitCConstInit VL_NOT_FINAL : public EmitCBaseVisitorConst {
}
protected:
// METHODS
// Emit the initializer of a definition, for direct initialization: 'type name{...}'
void emitDirectInit(AstNode* valuep) {
if (VN_IS(valuep, InitArray) || (VN_IS(valuep, Const) && valuep->isWide())) {
iterateConst(valuep); // Already a braced initializer list
} else {
puts("{");
iterateConst(valuep);
puts("}");
}
}
// VISITORS
void visit(AstInitArray* nodep) override {
VL_RESTORER(m_unpackedWord);
if (VN_IS(nodep->dtypep()->skipRefp(), AssocArrayDType)) {
// Note the double {{ initializer. The first { starts the initializer of the
// VlAssocArray, and the second starts the initializer of m_storage within the
// VlAssocArray.
puts("{");
ofp()->putsNoTracking("{");
puts("\n");
int comma = 0;
const auto& mapr = nodep->map();
for (const auto& itr : mapr) {
if (comma++) putbs(",\n");
putns(nodep, cvtToStr(itr.first));
ofp()->printf("%" PRIx64 "ULL", itr.first);
ofp()->putsNoTracking(":");
ofp()->putsNoTracking("{");
iterateConst(nodep->getIndexValuep(itr.first));
ofp()->putsNoTracking("}");
// Braced list for the constructors of VlAssocArray: '{default, {items...}}' with a
// default value, or '{{items...}}' without.
AstNode* const defaultp = nodep->defaultp();
const AstInitArray::KeyItemMap& mapr = nodep->map();
// '{{}}' would be ambiguous, but the constant pool always has a default
UASSERT_OBJ(defaultp || !mapr.empty(), nodep,
"Empty associative array initializer without default");
puts("{\n");
if (defaultp) {
puts("/* default: */ ");
iterateConst(defaultp);
puts(",\n");
}
puts("\n");
puts("}");
ofp()->putsNoTracking("}");
puts("/* items: */ {");
bool first = true;
for (const auto& itr : mapr) {
if (!first) puts(",");
first = false;
puts("\n{");
ofp()->printf("0x%" PRIx64 "ULL", itr.first);
puts(", ");
iterateConst(nodep->getIndexValuep(itr.first));
puts("}");
}
puts("\n}\n}");
} else if (const AstUnpackArrayDType* const dtypep
= VN_CAST(nodep->dtypep()->skipRefp(), UnpackArrayDType)) {
const uint64_t size = dtypep->elementsConst();
@@ -97,7 +114,24 @@ protected:
void visit(AstConst* nodep) override {
const V3Number& num = nodep->num();
UASSERT_OBJ(!num.isFourState(), nodep, "4-state value in constant pool");
putns(nodep, num.emitC());
if (!nodep->isWide()) {
putns(nodep, num.emitC());
return;
}
// Wide values are emitted as a braced initializer list of the words, without the
// VlWide type. Note the double {{ initializer. The first { starts the initializer of
// the VlWide, and the second starts the initializer of m_storage within the VlWide.
const int words = nodep->widthWords();
putns(nodep, "{");
ofp()->putsNoTracking("{");
if (words > 4) puts("\n");
for (int n = 0; n < words; ++n) {
if (n) puts((n % 4) ? ", " : ",\n");
ofp()->printf("0x%08" PRIx32, num.edataWord(n));
}
if (words > 4) puts("\n");
puts("}");
ofp()->putsNoTracking("}");
}
void visit(AstUnbounded* nodep) override {
// e.g. when emitting a public parameter's "$" value
+16 -10
View File
@@ -35,17 +35,18 @@ class EmitCConstPool final : public EmitCConstInit {
using OutCFilePair = std::pair<V3OutCFile*, AstCFile*>;
// MEMBERS
VDouble0 m_tablesEmitted;
VDouble0 m_constsEmitted;
VDouble0 m_mapsEmitted;
VDouble0 m_tablesEmitted;
V3UniqueNames m_uniqueNames; // Generates unique file names
const std::string m_fileBaseName = EmitCUtil::topClassName() + "__ConstPool";
// METHODS
void emitVars(const AstConstPool* poolp) {
void emitVars(const AstPackage* poolp) {
UASSERT(!ofp(), "Output file should not be open");
std::vector<const AstVar*> varps;
for (AstNode* nodep = poolp->modp()->stmtsp(); nodep; nodep = nodep->nextp()) {
for (AstNode* nodep = poolp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (const AstVar* const varp = VN_CAST(nodep, Var)) varps.push_back(varp);
}
@@ -73,14 +74,18 @@ class EmitCConstPool final : public EmitCConstInit {
const std::string nameProtect
= EmitCUtil::topClassName() + "__ConstPool__" + varp->nameProtect();
puts("\n");
putns(varp, "extern const ");
putns(varp, "extern ");
// Literal types should be constinit (no code generation needed)
if (varp->dtypep()->isLiteralType()) putns(varp, "VL_CONSTINIT_CXX20 ");
putns(varp, "const ");
putns(varp, varp->dtypep()->cType(nameProtect, false, false));
putns(varp, " = ");
UASSERT_OBJ(varp, varp->valuep(), "Var without value");
iterateConst(varp->valuep());
emitDirectInit(varp->valuep());
putns(varp, ";\n");
// Keep track of stats
if (VN_IS(varp->dtypep(), UnpackArrayDType)) {
if (VN_IS(varp->dtypep(), AssocArrayDType)) {
++m_mapsEmitted;
} else if (VN_IS(varp->dtypep(), UnpackArrayDType)) {
++m_tablesEmitted;
} else {
++m_constsEmitted;
@@ -103,10 +108,11 @@ class EmitCConstPool final : public EmitCConstInit {
}
public:
explicit EmitCConstPool(const AstConstPool* poolp) {
explicit EmitCConstPool(const AstPackage* poolp) {
emitVars(poolp);
V3Stats::addStatSum("ConstPool, Tables emitted", m_tablesEmitted);
V3Stats::addStatSum("ConstPool, Constants emitted", m_constsEmitted);
V3Stats::addStatSum("ConstPool, Maps emitted", m_mapsEmitted);
V3Stats::addStatSum("ConstPool, Tables emitted", m_tablesEmitted);
}
};
@@ -115,5 +121,5 @@ public:
void V3EmitC::emitcConstPool() {
UINFO(2, __FUNCTION__ << ":");
EmitCConstPool(v3Global.rootp()->constPoolp());
EmitCConstPool(v3Global.rootp()->constPoolPkgp());
}
+2 -5
View File
@@ -85,9 +85,7 @@ class EmitCLazyDecls final : public VNVisitorConst {
void visit(AstVarRef* nodep) override {
AstVar* const varp = nodep->varp();
// Only constant pool symbols are lazy declared for now ...
if (EmitCUtil::isConstPoolMod(EmitCParentModule::get(varp))) {
lazyDeclareConstPoolVar(varp);
}
if (EmitCParentModule::get(varp)->isConstPool()) lazyDeclareConstPoolVar(varp);
}
void visit(AstNode* nodep) override { iterateChildrenConst(nodep); }
@@ -262,7 +260,6 @@ public:
const string& suffix, const AstNode* valuep);
void emitVarResetScopeHash();
void emitChangeDet();
void emitConstInit(AstNode* initp) { iterateConst(initp); }
void putCommaIterateNext(AstNode* nodep, bool comma = false) {
for (AstNode* subnodep = nodep; subnodep; subnodep = subnodep->nextp()) {
if (comma) puts(", ");
@@ -1791,7 +1788,7 @@ public:
const bool dereferenceCovergroupRef
= varp->covergroupRefMember() && nodep->access().isReadOrRW();
if (dereferenceCovergroupRef) putns(nodep, "(*");
if (EmitCUtil::isConstPoolMod(varModp)) {
if (varModp->isConstPool()) {
// Reference to constant pool variable
putns(nodep, EmitCUtil::topClassName() + "__ConstPool__");
} else if (varp->isStatic()) {
+5 -5
View File
@@ -66,6 +66,7 @@ class EmitCHeader final : public EmitCConstInit {
bool first = true;
for (const AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (const AstCell* const cellp = VN_CAST(nodep, Cell)) {
if (cellp->modp()->isConstPool()) continue; // Special emit rules
decorateFirst(first, "// CELLS\n");
putns(cellp, EmitCUtil::prefixNameProtect(cellp->modp()) + "* "
+ cellp->nameProtect() + ";\n");
@@ -175,10 +176,7 @@ class EmitCHeader final : public EmitCConstInit {
putns(varp, "static ");
puts(canBeConstexpr ? "constexpr " : "const ");
puts(varp->dtypep()->cType(varp->nameProtect(), false, false));
if (canBeConstexpr) {
puts(" = ");
iterateConst(varp->valuep());
}
if (canBeConstexpr) emitDirectInit(varp->valuep());
puts(";\n");
}
}
@@ -768,6 +766,8 @@ void V3EmitC::emitcHeaders() {
// Process each module in turn
for (const AstNode* nodep = v3Global.rootp()->modulesp(); nodep; nodep = nodep->nextp()) {
if (VN_IS(nodep, Class)) continue; // Declared with the ClassPackage
EmitCHeader::main(VN_AS(nodep, NodeModule));
const AstNodeModule* const modp = VN_AS(nodep, NodeModule);
if (modp->isConstPool()) continue; // Emitted by V3EmitCConstPool
EmitCHeader::main(modp);
}
}
+2 -4
View File
@@ -78,10 +78,7 @@ class EmitCImp final : public EmitCFunc {
putns(varp, canBeConstexpr ? "constexpr " : "const ");
const string scopedName = modName + "::" + varp->nameProtect();
putns(varp, varp->dtypep()->cType(scopedName, false, false));
if (!canBeConstexpr) {
puts(" = ");
emitConstInit(varp->valuep());
}
if (!canBeConstexpr) emitDirectInit(varp->valuep());
puts(";\n");
}
}
@@ -939,6 +936,7 @@ void V3EmitC::emitcImp() {
for (const AstNode* nodep = v3Global.rootp()->modulesp(); nodep; nodep = nodep->nextp()) {
if (VN_IS(nodep, Class)) continue; // Imped with ClassPackage
const AstNodeModule* const modp = VN_AS(nodep, NodeModule);
if (modp->isConstPool()) continue; // Emitted by V3EmitCConstPool
cfiles.emplace_back();
std::vector<AstCFile*>& slow = cfiles.back();
threadScope.enqueue([modp, &slow] { slow = EmitCImp::main(modp, /* slow: */ true); });
+2
View File
@@ -142,6 +142,7 @@ class EmitCModel final : public EmitCFunc {
"// Otherwise the application code can consider these internals.\n");
for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (const AstCell* const cellp = VN_CAST(nodep, Cell)) {
if (cellp->modp()->isConstPool()) continue; // Special emit rules
putns(cellp, EmitCUtil::prefixNameProtect(cellp->modp()) + "* const "
+ cellp->nameProtect() + ";\n");
}
@@ -325,6 +326,7 @@ class EmitCModel final : public EmitCFunc {
// Setup cell pointers
for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (const AstCell* const cellp = VN_CAST(nodep, Cell)) {
if (cellp->modp()->isConstPool()) continue; // Special emit rules
const string protName = cellp->nameProtect();
puts(" , ");
putns(cellp, protName + "{vlSymsp->TOP." + protName + "}\n");
+2 -1
View File
@@ -814,8 +814,8 @@ class EmitCSyms final : EmitCBaseVisitorConst {
if (!m_dpiHdrOnly) emitDpiImp();
}
}
void visit(AstConstPool* nodep) override {} // Ignore
void visit(AstNodeModule* nodep) override {
if (nodep->isConstPool()) return; // Special emit rules
nameCheck(nodep);
VL_RESTORER(m_modp);
VL_RESTORER(m_modCoverBins);
@@ -949,6 +949,7 @@ void EmitCSyms::emitSymHdr() {
for (AstNodeModule *nodep = v3Global.rootp()->modulesp(), *nextp; nodep; nodep = nextp) {
nextp = VN_AS(nodep->nextp(), NodeModule);
if (VN_IS(nodep, Class)) continue; // Class included earlier
if (nodep->isConstPool()) continue; // Special emit rules
putns(nodep, "#include \"" + EmitCUtil::prefixNameProtect(nodep) + ".h\"\n");
}
+2 -11
View File
@@ -139,9 +139,7 @@ class ExpandVisitor final : public VNVisitor {
// NODE STATE
// AstNode::user1() -> bool. Processed
// AstNode::user2() -> See ExpandOkVisitor
// AstVar::user3() -> bool. Is a constant pool variable
const VNUser1InUse m_inuser1;
const VNUser3InUse m_inuser3;
// STATE - for current visit position (use VL_RESTORER)
AstNode* m_stmtp = nullptr; // Current statement
@@ -386,7 +384,7 @@ class ExpandVisitor final : public VNVisitor {
bool expandWide(AstNodeAssign* nodep, AstVarRef* rhsp) {
// Special case: do not expand assignment of constant pool variables.
// V3Subst undestands these directly.
if (rhsp->varp()->user3()) return false;
if (rhsp->varp()->constPoolEntry()) return false;
if (!doExpandWide(nodep)) return false;
didPattern(VExpandPattern::ASSIGN_VARREF, nodep);
for (int w = 0; w < nodep->widthWords(); ++w) {
@@ -504,14 +502,7 @@ class ExpandVisitor final : public VNVisitor {
}
// VISITORS
void visit(AstNetlist* nodep) override {
// Mark constant pool variables
for (AstNode* np = nodep->constPoolp()->modp()->stmtsp(); np; np = np->nextp()) {
if (VN_IS(np, Var)) np->user3(true);
}
iterateAndNextNull(nodep->modulesp());
}
void visit(AstNetlist* nodep) override { iterateAndNextNull(nodep->modulesp()); }
void visit(AstCFunc* nodep) override {
VL_RESTORER(m_funcp);
+3
View File
@@ -18,6 +18,7 @@
#include "V3Global.h"
#include "V3ConstPool.h"
#include "V3EmitV.h"
#include "V3Error.h"
#include "V3File.h"
@@ -53,6 +54,7 @@ extern "C" const char* __asan_default_options() {
void V3Global::boot() {
UASSERT(!m_rootp, "call once");
m_rootp = new AstNetlist;
m_constPoolp = new V3ConstPool;
m_libMapp = new V3LibMap;
}
@@ -61,6 +63,7 @@ void V3Global::shutdown() {
VL_DO_CLEAR(delete m_hierGraphp, m_hierGraphp = nullptr); // delete nullptr is safe
VL_DO_CLEAR(delete m_threadPoolp, m_threadPoolp = nullptr); // delete nullptr is safe
VL_DO_CLEAR(delete m_libMapp, m_libMapp = nullptr); // delete nullptr is safe
VL_DO_CLEAR(delete m_constPoolp, m_constPoolp = nullptr); // delete nullptr is safe
#ifdef VL_LEAK_CHECKS
if (m_rootp) VL_DO_CLEAR(m_rootp->deleteTree(), m_rootp = nullptr);
#endif
+5
View File
@@ -38,6 +38,7 @@
#include <unordered_set>
class AstNetlist;
class V3ConstPool;
class V3HierGraph;
class V3LibMap;
class V3ThreadPool;
@@ -164,6 +165,8 @@ class V3Global final {
// Globals
// Root of entire netlist, created by makeInitNetlist(} so static constructors run first
AstNetlist* m_rootp = nullptr;
// Constant pool lookup, see V3ConstPool.h
V3ConstPool* m_constPoolp = nullptr;
// Hierarchical block graph (plan) iff hierarchical verilation is performed
V3HierGraph* m_hierGraphp = nullptr;
// Thread Pool, nullptr unless 'verilatedJobs' is known, set via threadPoolp(V3ThreadPool*)
@@ -224,6 +227,8 @@ public:
// ACCESSORS (general)
AstNetlist* rootp() const VL_MT_SAFE { return m_rootp; }
// Use V3ConstPool:: static methods instead
V3ConstPool* constPoolp() const VL_PURE { return m_constPoolp; }
V3LibMap* libMapp() const VL_PURE { return m_libMapp; }
V3ThreadPool* threadPoolp() const VL_PURE { return m_threadPoolp; }
void threadPoolp(V3ThreadPool* threadPoolp) {
+20
View File
@@ -497,12 +497,32 @@ void testEntryLifetime() {
}
UASSERT_SELFTEST(set.begin() == set.end(), true); // Erased down to empty
UASSERT_SELFTEST(alive, 0); // With every entry destroyed
// Clearing destroys every entry at once, and leaves a usable, empty set
for (size_t i = 0; i < N; ++i) set.insert(NoDefault{&alive, 7, i});
UASSERT_SELFTEST(alive, N); // Filled up again
set.clear();
UASSERT_SELFTEST(set.size(), 0); // Nothing left
UASSERT_SELFTEST(set.empty(), true); // Says so
UASSERT_SELFTEST(set.begin() == set.end(), true); // Iterates nothing
UASSERT_SELFTEST(alive, 0); // With every entry destroyed
UASSERT_SELFTEST(set.contains(size_t{7}, size_t{0}), false); // Nor finds any
set.clear(); // Clearing an empty set does nothing
UASSERT_SELFTEST(set.empty(), true); // Still empty
// Leave entries in the set, so its destructor has some to destroy
for (size_t i = 0; i < N; ++i) set.insert(NoDefault{&alive, 7, i});
UASSERT_SELFTEST(alive, N); // Live as the set goes out of scope
}
// The set is gone, so every entry it still held has been destroyed
UASSERT_SELFTEST(alive, 0); // Leaking none of them
// Clearing a set that never allocated a table does nothing
{
Set set;
set.clear();
UASSERT_SELFTEST(set.empty(), true); // Still empty
set.insert(NoDefault{&alive, 7, 0});
UASSERT_SELFTEST(set.size(), 1); // And still usable
}
UASSERT_SELFTEST(alive, 0); // Leaking nothing
}
//######################################################################
+11 -2
View File
@@ -51,8 +51,9 @@
//
// Entries are referred to by iterators, as in the STL containers, but unlike
// STL containers, the mapped value in a V3HashMap is not mutable through an
// iterator. Iterators and entry addresses stay valid until the table grows or
// an entry is erased; either invalidates all of them.
// iterator. Iterators and entry addresses stay valid until the table grows,
// an entry is erased, or the table is cleared; any of these invalidates all
// of them.
//
// Erasure uses backward shift deletion: entries following the hole are moved
// back over it where their probe run ran through it (no tombstones).
@@ -348,6 +349,14 @@ public:
if (capacity > m_capacity) resize(capacity);
}
// Remove all entries. The table stays allocated. Invalidates every iterator.
void clear() {
for (size_t i = 0; i < m_capacity; ++i) {
if (!m_table[i].isFree()) m_table[i].destroy();
}
m_size = 0;
}
// Return iterator to the entry equal to the given key, or 'end()' if there
// is none. The key is whatever T_Hash and T_Equal accept, spelled as any
// number of arguments. Same as STL containers.
-1
View File
@@ -373,7 +373,6 @@ class HierBlockUsageCollectVisitor final : public VNVisitorConst {
void visit(AstNodeStmt*) override {} // Accelerate
void visit(AstNodeExpr*) override {} // Accelerate
void visit(AstConstPool*) override {} // Accelerate
void visit(AstTypeTable*) override {} // Accelerate
void visit(AstNode* nodep) override { iterateChildrenConst(nodep); }
+2 -2
View File
@@ -256,8 +256,6 @@ class InlineModGraphBuilder final : public VNVisitor {
// VISITORS
void visit(AstNodeModule* nodep) override {
if (nodep == v3Global.rootp()->constPoolp()->modp()) return; // Ignore const pool module
UASSERT_OBJ(!m_modVtxp, nodep, "Unsupported: Nested modules");
// Create the module vertex
@@ -268,6 +266,8 @@ class InlineModGraphBuilder final : public VNVisitor {
// TODO: All references are resolved by now, but AstIfaceRefDType::cellp and
// the AstIntfRef records still name the interface instance, so keep it.
if (VN_IS(nodep, Iface)) vtxp->setNoInlineHard("Interface");
// Never inline the constant pool, even if packages become inlineable
if (nodep->isConstPool()) vtxp->setNoInlineHard("Constant pool");
// Never inline packages - TODO: conceptually fine, but why not?
if (VN_IS(nodep, Package)) vtxp->setNoInlineHard("Package");
// A --lib-create library stub instance that needs tracing must not be
+1 -2
View File
@@ -453,7 +453,6 @@ class LinkCellsVisitor final : public VNVisitor {
<< (suggest.empty() ? "" : V3Error::warnMore() + suggest));
}
}
void visit(AstConstPool* nodep) override {}
void visit(AstNodeModule* nodep) override {
// Module: Pick up modnames, so we can resolve cells later
VL_RESTORER(m_modDepth);
@@ -469,7 +468,7 @@ class LinkCellsVisitor final : public VNVisitor {
if (nodep->fileline()->filebasenameNoExt() != nodep->prettyName()
&& !v3Global.opt.isLibraryFile(nodep->fileline()->filename(), nodep->libname())
&& !VN_IS(nodep, NotFoundModule) && !nodep->recursiveClone()
&& !nodep->isDollarUnit() && m_modDepth == 1) {
&& !nodep->isDollarUnit() && !nodep->isConstPool() && m_modDepth == 1) {
// We only complain once per file, otherwise library-like files
// have a huge mess of warnings
const auto itFoundPair = m_declfnWarned.insert(nodep->fileline()->filename());
+10 -8
View File
@@ -1216,12 +1216,18 @@ class LinkDotFindVisitor final : public VNVisitor {
// (sorted before this is called).
// This may not be the module with isTop() set, as early in the steps,
// wrapTop may have not been created yet.
// $unit always exists, so nothing else, and nothing in it, means nothing was given
// $unit and the constant pool always exist, so nothing else, and nothing in $unit,
// means nothing was given
AstNodeModule* const modulesp = nodep->modulesp();
UASSERT_OBJ(modulesp, nodep, "$unit should always be in the netlist");
if (!modulesp->nextp()) {
UASSERT_OBJ(modulesp->isDollarUnit(), modulesp, "Sole module should be $unit");
if (!modulesp->stmtsp()) nodep->v3error("No top level module found");
const bool onlyBuiltins = [&]() {
for (AstNodeModule* modp = modulesp; modp; modp = VN_AS(modp->nextp(), NodeModule)) {
if (!modp->isDollarUnit() && !modp->isConstPool()) return false;
}
return true;
}();
if (onlyBuiltins && !v3Global.rootp()->dollarUnitPkgp()->stmtsp()) {
nodep->v3error("No top level module found");
}
for (AstNodeModule* modp = nodep->modulesp(); modp && modp->isTop();
modp = VN_AS(modp->nextp(), NodeModule)) {
@@ -1282,7 +1288,6 @@ class LinkDotFindVisitor final : public VNVisitor {
}
}
void visit(AstTypeTable*) override {} // FindVisitor::
void visit(AstConstPool*) override {} // FindVisitor::
void visit(AstIfaceRefDType* nodep) override { // FindVisitor::
if (!m_statep->forScopeCreation() && nodep->isVirtual() && nodep->ifacep()
&& !nodep->ifacep()->user3()) {
@@ -2474,7 +2479,6 @@ class LinkDotParamVisitor final : public VNVisitor {
// VISITORS
void visit(AstTypeTable*) override {} // ParamVisitor::
void visit(AstConstPool*) override {} // ParamVisitor::
void visit(AstNodeModule* nodep) override { // ParamVisitor::
UINFO(5, " " << nodep);
if ((nodep->dead() || !nodep->user4()) && !nodep->hierParams()) {
@@ -2676,7 +2680,6 @@ private:
// Recurse..., backward as must do packages before using packages
iterateChildrenBackwardsConst(nodep);
}
void visit(AstConstPool*) override {} // ScopeVisitor::
void visit(AstScope* nodep) override { // ScopeVisitor::
UINFO(8, " SCOPE " << nodep);
UASSERT_OBJ(m_statep->forScopeCreation(), nodep,
@@ -3843,7 +3846,6 @@ class LinkDotResolveVisitor final : public VNVisitor {
iterateChildrenBackwardsConst(nodep);
}
void visit(AstTypeTable*) override {}
void visit(AstConstPool*) override {}
void visit(AstNodeModule* nodep) override {
if (nodep->dead()) return;
LINKDOT_VISIT_START();
+3 -1
View File
@@ -1542,7 +1542,9 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
DECL_OPTION("-flocalize", FOnOff, &m_fLocalize);
DECL_OPTION("-fmerge-cond", FOnOff, &m_fMergeCond);
DECL_OPTION("-fmerge-cond-motion", FOnOff, &m_fMergeCondMotion);
DECL_OPTION("-fmerge-const-pool", FOnOff, &m_fMergeConstPool);
DECL_OPTION("-fmerge-const-pool", CbFOnOff, [fl](bool) {
fl->v3warn(DEPRECATED, "Option '-fno-merge-const-pool' is deprecated and has no effect");
});
DECL_OPTION("-freloop", FOnOff, &m_fReloop);
DECL_OPTION("-freorder", FOnOff, &m_fReorder);
DECL_OPTION("-fslice", FOnOff, &m_fSlice);
-2
View File
@@ -429,7 +429,6 @@ private:
bool m_fLocalize; // main switch: -fno-localize: convert temps to local variables
bool m_fMergeCond; // main switch: -fno-merge-cond: merge conditionals
bool m_fMergeCondMotion = true; // main switch: -fno-merge-cond-motion: perform code motion
bool m_fMergeConstPool = true; // main switch: -fno-merge-const-pool
bool m_fReloop; // main switch: -fno-reloop: reform loops
bool m_fReorder; // main switch: -fno-reorder: reorder assignments in blocks
bool m_fSlice = true; // main switch: -fno-slice: array assignment slicing
@@ -771,7 +770,6 @@ public:
bool fLocalize() const { return m_fLocalize; }
bool fMergeCond() const { return m_fMergeCond; }
bool fMergeCondMotion() const { return m_fMergeCondMotion; }
bool fMergeConstPool() const { return m_fMergeConstPool; }
bool fReloop() const { return m_fReloop; }
bool fReorder() const { return m_fReorder; }
bool fSlice() const { return m_fSlice; }
-1
View File
@@ -415,7 +415,6 @@ class OrderGraphBuilder final : public VNVisitor {
void visit(AstVarScope* nodep) override { nodep->v3fatalSrc("Should not reach V3Order"); }
void visit(AstCell* nodep) override { nodep->v3fatalSrc("Should not reach V3Order"); }
void visit(AstTypeTable* nodep) override { nodep->v3fatalSrc("Should not reach V3Order"); }
void visit(AstConstPool* nodep) override { nodep->v3fatalSrc("Should not reach V3Order"); }
void visit(AstClass* nodep) override { nodep->v3fatalSrc("Should not reach V3Order"); }
void visit(AstCFunc*) override {
// Calls to DPI exports handled with AstCCall. /* verilator public */ functions are
+7 -5
View File
@@ -28,6 +28,7 @@
#include "V3Premit.h"
#include "V3ConstPool.h"
#include "V3Stats.h"
#include "V3UniqueNames.h"
@@ -117,10 +118,12 @@ class PremitVisitor final : public VNVisitor {
if (useConstPool) {
// Extract into constant pool.
const bool merge = v3Global.opt.fMergeConstPool();
varp = v3Global.rootp()->constPoolp()->findConst(constp, merge)->varp();
AstVarRef* const refp = V3ConstPool::findConst(constp);
varp = refp->varp();
VL_DO_DANGLING(nodep->deleteTree(), nodep);
++m_extractedToConstPool;
// Replace node with reference to the constant pool entry
relinker.relink(refp);
} else {
// Keep as local temporary.
varp = newTmpFor(nodep);
@@ -129,11 +132,10 @@ class PremitVisitor final : public VNVisitor {
AstAssign* const assignp = new AstAssign{flp, refp, nodep};
// Insert before the statement
m_stmtp->addHereThisAsNext(assignp);
// Replace node with VarRef to new Var
relinker.relink(new AstVarRef{flp, varp, VAccess::READ});
}
// Replace node with VarRef to new Var
relinker.relink(new AstVarRef{flp, varp, VAccess::READ});
// Return the temporary variable
return varp;
}
+16 -21
View File
@@ -37,6 +37,7 @@
#include "V3Ast.h"
#include "V3Const.h"
#include "V3ConstPool.h"
#include "V3Error.h"
#include "V3FileLine.h"
#include "V3Global.h"
@@ -3657,7 +3658,7 @@ class RandomizeVisitor final : public VNVisitor {
// AstClass::user1() -> bool. Set true to indicate needs randomize processing
// AstVar::user2p() -> AstNodeModule*. Pointer to containing module
// AstNodeFTask::user2p() -> AstNodeModule*. Pointer to containing module
// AstEnumDType::user2() -> AstVar*. Pointer to table with enum values
// AstEnumDType::user2() -> AstVarRef*. Reference to table with enum values, to clone
// AstConstraint::user2p() -> AstTask*. Pointer to constraint setup procedure
// AstClass::user2p() -> AstVar*. Rand mode state variable
// AstVar::user3() -> bool. Handled in constraints
@@ -3686,7 +3687,6 @@ class RandomizeVisitor final : public VNVisitor {
AstNodeFTask* m_ftaskp = nullptr; // Current function/task
AstNodeStmt* m_stmtp = nullptr; // Current statement
AstDynArrayDType* m_dynarrayDtp = nullptr; // Dynamic array type (for rand mode)
size_t m_enumValueTabCount = 0; // Number of tables with enum values created
int m_randCaseNum = 0; // Randcase number within a module for var naming
int m_distNum = 0; // Dist bucket variable counter within a module for var naming
std::map<std::string, AstCDType*> m_randcDtypes; // RandC data type deduplication
@@ -4197,23 +4197,16 @@ class RandomizeVisitor final : public VNVisitor {
}
return stmtp;
}
AstVar* enumValueTabp(AstEnumDType* const nodep) {
if (nodep->user2p()) return VN_AS(nodep->user2p(), Var);
UINFO(9, "Construct Venumvaltab " << nodep);
AstVarRef* enumValueTabRefp(AstEnumDType* const nodep) {
// Return a reference to a constant table of the values of the given enum. The reference
// is cached, so the table is built only once.
if (nodep->user2p()) return VN_AS(nodep->user2p(), VarRef)->cloneTree(false);
UINFO(9, "Construct enum value table " << nodep);
AstNodeArrayDType* const vardtypep = new AstUnpackArrayDType{
nodep->fileline(), nodep->dtypep(),
new AstRange{nodep->fileline(), static_cast<int>(nodep->itemCount()), 0}};
AstInitArray* const initp = new AstInitArray{nodep->fileline(), vardtypep, nullptr};
new AstRange{nodep->fileline(), static_cast<int>(nodep->itemCount()) - 1, 0}};
v3Global.rootp()->typeTablep()->addTypesp(vardtypep);
AstVar* const varp
= new AstVar{nodep->fileline(), VVarType::MODULETEMP,
"__Venumvaltab_" + cvtToStr(m_enumValueTabCount++), vardtypep};
varp->isConst(true);
varp->isStatic(true);
varp->valuep(initp);
// Add to root, as don't know module we are in, and aids later structure sharing
v3Global.rootp()->dollarUnitPkgp()->addStmtsp(varp);
AstInitArray* const initp = new AstInitArray{nodep->fileline(), vardtypep, nullptr};
UASSERT_OBJ(nodep->itemsp(), nodep, "Enum without items");
for (AstEnumItem* itemp = nodep->itemsp(); itemp;
itemp = VN_AS(itemp->nextp(), EnumItem)) {
@@ -4221,8 +4214,12 @@ class RandomizeVisitor final : public VNVisitor {
UASSERT_OBJ(vconstp, nodep, "Enum item without constified value");
initp->addValuep(vconstp->cloneTree(false));
}
nodep->user2p(varp);
return varp;
// Share identical tables via the constant pool
AstVarRef* const refp = V3ConstPool::findTable(initp);
VL_DO_DANGLING(initp->deleteTree(), initp); // V3ConstPool::findTable clones it
pushDeletep(refp); // Deleted with the visitor - always cloned
nodep->user2p(refp);
return refp->cloneTree(false);
}
AstCDType* findVlRandCDType(FileLine* const fl, uint64_t items) {
@@ -4382,9 +4379,7 @@ class RandomizeVisitor final : public VNVisitor {
if (AstEnumDType* const enumDtp = VN_CAST(memberp ? memberp->subDTypep()->subDTypep()
: exprp->dtypep()->subDTypep(),
EnumDType)) {
AstVarRef* const tabRefp
= new AstVarRef{fl, enumValueTabp(enumDtp), VAccess::READ};
tabRefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgp());
AstVarRef* const tabRefp = enumValueTabRefp(enumDtp);
AstNodeExpr* const randp
= newRandValue(fl, randcVarp, exprp->findBasicDType(VBasicDTypeKwd::UINT32));
AstNodeExpr* const moddivp = new AstModDiv{
+3
View File
@@ -25,6 +25,8 @@
#include "V3Scope.h"
#include "V3ConstPool.h"
#include <unordered_map>
#include <unordered_set>
@@ -419,5 +421,6 @@ void V3Scope::scopeAll(AstNetlist* nodep) {
const ScopeVisitor visitor{nodep};
ScopeCleanupVisitor{nodep};
} // Destruct before checking
V3ConstPool::setScoped();
V3Global::dumpCheckGlobalTree("scope", 0, dumpTreeEitherLevel() >= 3);
}
+2 -11
View File
@@ -219,8 +219,6 @@ AstNodeExpr* SubstVarEntry::substRecord(SubstVarEntry::Record& record) {
class SubstVisitor final : public VNVisitor {
// NODE STATE - only Under AstCFunc
// AstVar::user1p -> SubstVarEntry* for assignment tracking. Also used by SubstValidVisitor
// AstVar::user2 -> bool. Is a constant pool variable
const VNUser2InUse m_user2InUse;
// STATE
std::deque<SubstVarEntry> m_entries; // Storage for SubstVarEntry instances
@@ -277,14 +275,7 @@ class SubstVisitor final : public VNVisitor {
// VISITORS
void visit(AstNetlist* nodep) override {
// Mark constant pool variables
for (AstNode* np = nodep->constPoolp()->modp()->stmtsp(); np; np = np->nextp()) {
if (VN_IS(np, Var)) np->user2(true);
}
iterateAndNextNull(nodep->modulesp());
}
void visit(AstNetlist* nodep) override { iterateAndNextNull(nodep->modulesp()); }
void visit(AstCFunc* nodep) override {
UASSERT_OBJ(!m_funcp, nodep, "Should not nest");
@@ -378,7 +369,7 @@ class SubstVisitor final : public VNVisitor {
// If it's a constant pool variable, substiute with the constant word
AstVar* const varp = refp->varp();
if (varp->user2()) {
if (varp->constPoolEntry()) {
AstConst* const constp = VN_AS(varp->valuep(), Const);
const uint32_t value = constp->num().edataWord(word);
FileLine* const flp = nodep->fileline();
+6 -1
View File
@@ -25,6 +25,7 @@
#include "V3Table.h"
#include "V3ConstPool.h"
#include "V3Simulate.h"
#include "V3Stats.h"
@@ -111,7 +112,11 @@ public:
}
AstVarScope* varScopep() {
if (!m_varScopep) m_varScopep = v3Global.rootp()->constPoolp()->findTable(m_initp);
if (!m_varScopep) {
AstVarRef* const refp = V3ConstPool::findTable(m_initp);
m_varScopep = refp->varScopep();
VL_DO_DANGLING(refp->deleteTree(), refp);
}
return m_varScopep;
}
};
+10 -5
View File
@@ -28,6 +28,7 @@
#include "V3Task.h"
#include "V3Const.h"
#include "V3ConstPool.h"
#include "V3Control.h"
#include "V3EmitCBase.h"
#include "V3Graph.h"
@@ -467,10 +468,16 @@ class TaskVisitor final : public VNVisitor {
m_scopep->addVarsp(newvscp);
return newvscp;
}
static AstVarScope* constPoolTable(AstVar* paramp) {
// Move array params in functions into constant pool, return the VarScope of the entry
AstVarRef* const refp = V3ConstPool::find(VN_AS(paramp->valuep(), InitArray));
AstVarScope* const vscp = refp->varScopep();
VL_DO_DANGLING(refp->deleteTree(), refp);
return vscp;
}
AstVarScope* createVarScope(AstVar* invarp, const string& name) {
if (invarp->isParam() && VN_IS(invarp->valuep(), InitArray)) {
// Move array params in functions into constant pool
return v3Global.rootp()->constPoolp()->findTable(VN_AS(invarp->valuep(), InitArray));
return constPoolTable(invarp);
} else {
// We could create under either the ref's scope or the ftask's scope.
// It shouldn't matter, as they are only local variables.
@@ -1424,9 +1431,7 @@ class TaskVisitor final : public VNVisitor {
// Move array parameters in functions into constant pool
portp->unlinkFrBack();
pushDeletep(portp);
AstNode* const tablep = v3Global.rootp()->constPoolp()->findTable(
VN_AS(portp->valuep(), InitArray));
portp->user2p(tablep);
portp->user2p(constPoolTable(portp));
} else {
if (portp->isIO()) {
// Move it to new function
+131 -149
View File
@@ -70,6 +70,7 @@
#include "V3Ast.h"
#include "V3Begin.h"
#include "V3Const.h"
#include "V3ConstPool.h"
#include "V3Error.h"
#include "V3Global.h"
#include "V3LinkDotIfaceCapture.h"
@@ -254,7 +255,6 @@ public:
class WidthVisitor final : public VNVisitor {
// TYPES
using TableMap = std::map<std::pair<const AstNodeDType*, VAttrType>, AstVar*>;
using PatVecMap = std::map<int, AstPatMember*>;
using DTypeMap = std::map<const std::string, AstPatMember*>;
@@ -285,10 +285,10 @@ class WidthVisitor final : public VNVisitor {
const bool m_paramsOnly; // Computing parameter value; limit operation
const bool m_doGenerate; // Do errors later inside generate statement
bool m_streamConcat = false; // True if visiting arguments of stream concatenation
int m_dtTables = 0; // Number of created data type tables
TableMap m_tableMap; // Created tables so can remove duplicates
std::map<const AstNodeDType*, AstQueueDType*>
m_queueDTypeIndexed; // Queues with given index type
// Created dimension and enum tables, mapped to a reference reading the table (always cloned)
std::map<std::pair<const AstNodeDType*, VAttrType>, AstVarRef*> m_tableMap;
// Queues with given index type
std::map<const AstNodeDType*, AstQueueDType*> m_queueDTypeIndexed;
ContainingClassFinder m_containingClassFinder;
std::unordered_set<AstVar*> m_aliasedVars; // Variables referenced in alias
std::unordered_set<const AstVar*> m_curModVars; // Variables declared in current module
@@ -2542,10 +2542,9 @@ class WidthVisitor final : public VNVisitor {
VL_DO_DANGLING(deleteTreeCaptured(nodep), nodep);
} else { // Need a runtime lookup table. Yuk.
UASSERT_OBJ(nodep->fromp() && dtypep, nodep, "Unsized expression");
AstVar* const varp = dimensionVarp(dtypep, nodep->attrType(), msbdim);
AstVarRef* const tabRefp = dimensionVarRefp(dtypep, nodep->attrType(), msbdim);
AstNodeExpr* const dimp = nodep->dimp()->unlinkFrBack();
AstNodeExpr* const newp
= new AstArraySel{nodep->fileline(), newVarRefDollarUnit(varp), dimp};
AstNodeExpr* const newp = new AstArraySel{nodep->fileline(), tabRefp, dimp};
nodep->replaceWith(newp);
VL_DO_DANGLING(deleteTreeCaptured(nodep), nodep);
}
@@ -10250,35 +10249,29 @@ class WidthVisitor final : public VNVisitor {
<< ")=" << valp);
return valp;
}
AstVar* dimensionVarp(AstNodeDType* nodep, VAttrType attrType, uint32_t msbdim) {
// Return a variable table which has specified dimension properties for this variable
const auto pair = m_tableMap.emplace(std::piecewise_construct, //
std::forward_as_tuple(nodep, attrType),
std::forward_as_tuple(nullptr));
if (pair.second) {
AstNodeArrayDType* const vardtypep
= new AstUnpackArrayDType{nodep->fileline(), nodep->findIntDType(),
new AstRange(nodep->fileline(), msbdim, 0)};
AstInitArray* const initp = new AstInitArray{nodep->fileline(), vardtypep, nullptr};
v3Global.rootp()->typeTablep()->addTypesp(vardtypep);
AstVar* const varp = new AstVar{nodep->fileline(), VVarType::MODULETEMP,
"__Vdimtab_" + VString::downcase(attrType.ascii())
+ cvtToStr(m_dtTables++),
vardtypep};
varp->isConst(true);
varp->isStatic(true);
varp->valuep(initp);
// Add to root, as don't know module we are in, and aids later structure sharing
v3Global.rootp()->dollarUnitPkgp()->addStmtsp(varp);
// Element 0 is a non-index and has speced values
initp->addValuep(dimensionValue(nodep->fileline(), nodep, attrType, 0));
for (unsigned i = 1; i < msbdim + 1; ++i) {
initp->addValuep(dimensionValue(nodep->fileline(), nodep, attrType, i));
}
userIterate(varp, nullptr); // May have already done $unit so must do this var
pair.first->second = varp;
AstVarRef* dimensionVarRefp(AstNodeDType* nodep, VAttrType attrType, uint32_t msbdim) {
// Return a reference to a constant table which has the specified dimension properties
// for this data type. The reference is cached, so the table is built only once.
AstVarRef*& cachedpr = m_tableMap[std::make_pair(nodep, attrType)];
if (cachedpr) return cachedpr->cloneTree(false);
AstNodeArrayDType* const vardtypep = new AstUnpackArrayDType{
nodep->fileline(), nodep->findIntDType(), new AstRange(nodep->fileline(), msbdim, 0)};
v3Global.rootp()->typeTablep()->addTypesp(vardtypep);
userIterate(vardtypep, WidthVP{SELF, BOTH}.p());
AstInitArray* const initp = new AstInitArray{nodep->fileline(), vardtypep, nullptr};
// Element 0 is a non-index and has speced values
initp->addValuep(dimensionValue(nodep->fileline(), nodep, attrType, 0));
for (unsigned i = 1; i < msbdim + 1; ++i) {
initp->addValuep(dimensionValue(nodep->fileline(), nodep, attrType, i));
}
return pair.first->second;
// Share identical tables via the constant pool
cachedpr = V3ConstPool::find(initp);
VL_DO_DANGLING(initp->deleteTree(), initp); // V3ConstPool::find clones it
cachedpr->varp()->didWidth(true);
pushDeletep(cachedpr); // Deleted with the visitor - always cloned
return cachedpr->cloneTree(false);
}
static uint64_t enumMaxValue(const AstNode* errNodep, const AstEnumDType* adtypep) {
// Most enums unless overridden are 32 bits, so we size array
@@ -10301,102 +10294,97 @@ class WidthVisitor final : public VNVisitor {
}
return maxval;
}
static AstVar* enumVarp(AstEnumDType* const nodep, VAttrType attrType, bool assoc,
uint32_t msbdim) {
// Return a variable table which has specified dimension properties for this variable
const auto pair = nodep->tableMap().emplace(attrType, nullptr);
if (pair.second) {
UINFO(9, "Construct Venumtab attr=" << attrType.ascii() << " assoc=" << assoc
<< " max=" << msbdim << " for " << nodep);
AstNodeDType* basep;
if (attrType == VAttrType::ENUM_NAME) {
basep = nodep->findStringDType();
} else if (attrType == VAttrType::ENUM_VALID) {
// TODO in theory we could bit-pack the bits in the table, but
// would require additional operations to extract, so only
// would be worth it for larger tables which perhaps could be
// better handled with equation generation?
basep = nodep->findBitDType();
} else {
basep = nodep->dtypep();
}
AstNodeDType* vardtypep;
if (assoc) {
vardtypep = new AstAssocArrayDType{nodep->fileline(), basep, nodep};
} else {
vardtypep = new AstUnpackArrayDType{nodep->fileline(), basep,
new AstRange(nodep->fileline(), msbdim, 0)};
}
AstInitArray* const initp = new AstInitArray{nodep->fileline(), vardtypep, nullptr};
v3Global.rootp()->typeTablep()->addTypesp(vardtypep);
// Rebuilt tables may coexist with live tables from earlier widthing.
AstVar* const varp = new AstVar{nodep->fileline(), VVarType::MODULETEMP,
"__Venumtab_" + VString::downcase(attrType.ascii())
+ cvtToStr(AstNodeDType::uniqueNumInc()),
vardtypep};
varp->lifetime(VLifetime::STATIC_EXPLICIT);
varp->isConst(true);
varp->isStatic(true);
varp->valuep(initp);
// Add to root, as don't know module we are in, and aids later structure sharing
v3Global.rootp()->dollarUnitPkgp()->addStmtsp(varp);
AstVarRef* enumVarRefp(AstEnumDType* const nodep, VAttrType attrType, bool assoc,
uint32_t msbdim) {
// Return a reference to a constant table which has the specified attrType information
// for this enum. The reference is cached, so the table is built only once.
AstVarRef*& cachedpr = m_tableMap[std::make_pair(nodep, attrType)];
if (cachedpr) return cachedpr->cloneTree(false);
// Default for all unspecified values
if (attrType == VAttrType::ENUM_NAME) {
initp->defaultp(new AstConst{nodep->fileline(), AstConst::String{}, ""});
} else if (attrType == VAttrType::ENUM_NEXT || attrType == VAttrType::ENUM_PREV) {
initp->defaultp(
new AstConst{nodep->fileline(), V3Number{nodep, nodep->width(), 0}});
} else if (attrType == VAttrType::ENUM_VALID) {
initp->defaultp(new AstConst{nodep->fileline(), AstConst::BitFalse{}});
} else {
nodep->v3fatalSrc("Bad case");
}
// Find valid values and populate
UASSERT_OBJ(nodep->itemsp(), nodep, "enum without items");
std::map<uint64_t, AstNodeExpr*> values;
{
uint64_t ordinal = 0;
AstEnumItem* const firstp = nodep->itemsp();
const AstEnumItem* prevp = firstp; // Prev must start with last item
while (prevp->nextp()) prevp = VN_AS(prevp->nextp(), EnumItem);
for (AstEnumItem* itemp = firstp; itemp;) {
AstEnumItem* const nextp = VN_AS(itemp->nextp(), EnumItem);
const AstConst* const vconstp = VN_AS(itemp->valuep(), Const);
UASSERT_OBJ(vconstp, nodep, "Enum item without constified value");
if (!vconstp->num().isAnyXZ()) { // Can 2-state runtime decode
const uint64_t i = nodep->isWide() ? ++ordinal : vconstp->toUQuad();
if (attrType == VAttrType::ENUM_NAME) {
values[i] = new AstConst{nodep->fileline(), AstConst::String{},
V3Number::displayedEnumName(itemp)};
} else if (attrType == VAttrType::ENUM_NEXT) {
values[i]
= (nextp ? nextp : firstp)->valuep()->cloneTree(false); // A const
} else if (attrType == VAttrType::ENUM_PREV) {
values[i] = prevp->valuep()->cloneTree(false); // A const
} else if (attrType == VAttrType::ENUM_VALID) {
values[i] = new AstConst{nodep->fileline(), AstConst::BitTrue{}};
} else {
nodep->v3fatalSrc("Bad case");
}
}
prevp = itemp;
itemp = nextp;
}
}
// Add all specified values to table
if (assoc) {
for (const auto& itr : values) initp->addIndexValuep(itr.first, itr.second);
} else {
for (uint64_t i = 0; i < (msbdim + 1); ++i) {
if (values[i]) initp->addIndexValuep(i, values[i]);
}
}
varp->didWidth(true); // May have already done $unit so must do this var
pair.first->second = varp;
UINFO(9, "Construct Venumtab attr=" << attrType.ascii() << " assoc=" << assoc
<< " max=" << msbdim << " for " << nodep);
AstNodeDType* basep;
if (attrType == VAttrType::ENUM_NAME) {
basep = nodep->findStringDType();
} else if (attrType == VAttrType::ENUM_VALID) {
// TODO in theory we could bit-pack the bits in the table, but
// would require additional operations to extract, so only
// would be worth it for larger tables which perhaps could be
// better handled with equation generation?
basep = nodep->findBitDType();
} else {
basep = nodep->dtypep();
}
return pair.first->second;
AstNodeDType* vardtypep;
if (assoc) {
// Key by the base type of the enum, not the enum itself, so identical maps of
// different enum types can be shared in the constant pool
vardtypep = new AstAssocArrayDType{nodep->fileline(), basep, nodep->subDTypep()};
} else {
vardtypep = new AstUnpackArrayDType{nodep->fileline(), basep,
new AstRange(nodep->fileline(), msbdim, 0)};
}
AstInitArray* const initp = new AstInitArray{nodep->fileline(), vardtypep, nullptr};
v3Global.rootp()->typeTablep()->addTypesp(vardtypep);
// Default for all unspecified values
if (attrType == VAttrType::ENUM_NAME) {
initp->defaultp(new AstConst{nodep->fileline(), AstConst::String{}, ""});
} else if (attrType == VAttrType::ENUM_NEXT || attrType == VAttrType::ENUM_PREV) {
initp->defaultp(new AstConst{nodep->fileline(), V3Number{nodep, nodep->width(), 0}});
} else if (attrType == VAttrType::ENUM_VALID) {
initp->defaultp(new AstConst{nodep->fileline(), AstConst::BitFalse{}});
} else {
nodep->v3fatalSrc("Bad case");
}
// Find valid values and populate
UASSERT_OBJ(nodep->itemsp(), nodep, "enum without items");
std::map<uint64_t, AstNodeExpr*> values;
{
uint64_t ordinal = 0;
AstEnumItem* const firstp = nodep->itemsp();
const AstEnumItem* prevp = firstp; // Prev must start with last item
while (prevp->nextp()) prevp = VN_AS(prevp->nextp(), EnumItem);
for (AstEnumItem* itemp = firstp; itemp;) {
AstEnumItem* const nextp = VN_AS(itemp->nextp(), EnumItem);
const AstConst* const vconstp = VN_AS(itemp->valuep(), Const);
UASSERT_OBJ(vconstp, nodep, "Enum item without constified value");
if (!vconstp->num().isAnyXZ()) { // Can 2-state runtime decode
const uint64_t i = nodep->isWide() ? ++ordinal : vconstp->toUQuad();
if (attrType == VAttrType::ENUM_NAME) {
values[i] = new AstConst{nodep->fileline(), AstConst::String{},
V3Number::displayedEnumName(itemp)};
} else if (attrType == VAttrType::ENUM_NEXT) {
values[i]
= (nextp ? nextp : firstp)->valuep()->cloneTree(false); // A const
} else if (attrType == VAttrType::ENUM_PREV) {
values[i] = prevp->valuep()->cloneTree(false); // A const
} else if (attrType == VAttrType::ENUM_VALID) {
values[i] = new AstConst{nodep->fileline(), AstConst::BitTrue{}};
} else {
nodep->v3fatalSrc("Bad case");
}
}
prevp = itemp;
itemp = nextp;
}
}
// Add all specified values to table
if (assoc) {
for (const auto& itr : values) initp->addIndexValuep(itr.first, itr.second);
} else {
for (uint64_t i = 0; i < (msbdim + 1); ++i) {
if (values[i]) initp->addIndexValuep(i, values[i]);
}
}
// Share identical tables via the constant pool
cachedpr = V3ConstPool::find(initp);
VL_DO_DANGLING(initp->deleteTree(), initp); // V3ConstPool::find clones it
cachedpr->varp()->didWidth(true);
pushDeletep(cachedpr); // Deleted with the visitor - always cloned
return cachedpr->cloneTree(false);
}
AstNodeExpr* enumSelect(AstNodeExpr* nodep, AstEnumDType* adtypep, VAttrType attrType) {
@@ -10430,9 +10418,8 @@ class WidthVisitor final : public VNVisitor {
itemp->valuep()->cloneTree(false)},
new AstConst{nodep->fileline(), ++ordinal}, indexp};
}
AstVar* const varp = enumVarp(adtypep, attrType, false, ordinal);
AstNodeExpr* const newp
= new AstArraySel{nodep->fileline(), newVarRefDollarUnit(varp), indexp};
AstVarRef* const tabRefp = enumVarRefp(adtypep, attrType, false, ordinal);
AstNodeExpr* const newp = new AstArraySel{nodep->fileline(), tabRefp, indexp};
newp->dtypeSetString();
VL_DO_DANGLING(pushDeletep(nodep), nodep);
return newp;
@@ -10441,11 +10428,12 @@ class WidthVisitor final : public VNVisitor {
const bool assoc = msbdim > ENUM_LOOKUP_BITS;
AstNodeExpr* newp;
if (assoc) {
AstVar* const varp = enumVarp(adtypep, attrType, true, 0);
newp = new AstAssocSel{nodep->fileline(), newVarRefDollarUnit(varp), nodep};
AstVarRef* const tabRefp = enumVarRefp(adtypep, attrType, true, 0);
newp = new AstAssocSel{nodep->fileline(), tabRefp, nodep};
} else {
const int selwidth = V3Number::log2b(msbdim) + 1; // Width to address a bit
AstVar* const varp = enumVarp(adtypep, attrType, false, (1ULL << selwidth) - 1);
AstVarRef* const tabRefp
= enumVarRefp(adtypep, attrType, false, (1ULL << selwidth) - 1);
AstNodeExpr* const boundp
= attrType == VAttrType::ENUM_NAME
&& (adtypep->width() > selwidth || msbdim != (1ULL << selwidth) - 1)
@@ -10455,7 +10443,7 @@ class WidthVisitor final : public VNVisitor {
static_cast<uint32_t>(msbdim)}}}
: nullptr;
newp = new AstArraySel{
nodep->fileline(), newVarRefDollarUnit(varp),
nodep->fileline(), tabRefp,
// Select in case widths are off due to msblen!=width
// We return "random" values if outside the range, which is fine
// as next/previous on illegal values just need something good out
@@ -10474,7 +10462,7 @@ class WidthVisitor final : public VNVisitor {
}
return newp;
}
static AstNodeExpr* enumTestValid(AstNodeExpr* valp, AstEnumDType* enumDtp) {
AstNodeExpr* enumTestValid(AstNodeExpr* valp, AstEnumDType* enumDtp) {
const uint64_t maxval = enumMaxValue(valp, enumDtp);
const bool assoc = maxval > ENUM_LOOKUP_BITS;
AstNodeExpr* testp = nullptr;
@@ -10482,13 +10470,12 @@ class WidthVisitor final : public VNVisitor {
fl_novalue->warnOff(V3ErrorCode::ENUMVALUE, true);
fl_novalue->warnOff(V3ErrorCode::CMPCONST, true);
if (assoc) {
AstVar* const varp = enumVarp(enumDtp, VAttrType::ENUM_VALID, true, 0);
testp = new AstAssocSel{fl_novalue, newVarRefDollarUnit(varp),
valp->cloneTreePure(false)};
AstVarRef* const tabRefp = enumVarRefp(enumDtp, VAttrType::ENUM_VALID, true, 0);
testp = new AstAssocSel{fl_novalue, tabRefp, valp->cloneTreePure(false)};
} else {
const int selwidth = V3Number::log2b(maxval) + 1; // Width to address a bit
AstVar* const varp
= enumVarp(enumDtp, VAttrType::ENUM_VALID, false, (1ULL << selwidth) - 1);
AstVarRef* const tabRefp
= enumVarRefp(enumDtp, VAttrType::ENUM_VALID, false, (1ULL << selwidth) - 1);
FileLine* const fl_nowidth = new FileLine{fl_novalue};
fl_nowidth->warnOff(V3ErrorCode::WIDTH, true);
testp = new AstCond{
@@ -10496,7 +10483,7 @@ class WidthVisitor final : public VNVisitor {
new AstGt{fl_nowidth, valp->cloneTreePure(false),
new AstConst{fl_nowidth, AstConst::Unsized64{}, maxval}},
new AstConst{fl_novalue, AstConst::BitFalse{}},
new AstArraySel{fl_novalue, newVarRefDollarUnit(varp),
new AstArraySel{fl_novalue, tabRefp,
new AstSel{fl_novalue, valp->cloneTreePure(false), 0, selwidth}}};
}
return testp;
@@ -10682,11 +10669,6 @@ class WidthVisitor final : public VNVisitor {
return;
}
}
static AstVarRef* newVarRefDollarUnit(AstVar* nodep) {
AstVarRef* const varrefp = new AstVarRef{nodep->fileline(), nodep, VAccess::READ};
varrefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgp());
return varrefp;
}
AstNode* nodeForUnsizedWarning(AstNode* nodep) {
// Return a nodep to use for unsized warnings, reporting on child if can
if (nodep->op1p() && nodep->op1p()->dtypep() && !nodep->op1p()->dtypep()->widthSized()) {
-4
View File
@@ -348,10 +348,6 @@ private:
if (nodep->user1SetOnce()) return; // Process once
visitIterateNodeDType(nodep);
}
void visit(AstEnumDType* nodep) override {
nodep->tableMap().clear(); // Only needed up through V3Width process
visitIterateNodeDType(nodep);
}
void visit(AstParamTypeDType* nodep) override {
if (nodep->user1SetOnce()) return; // Process once
visitIterateNodeDType(nodep);
+22
View File
@@ -0,0 +1,22 @@
#!/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.scenarios('vlt')
test.compile(verilator_flags2=["--binary", "--stats"])
test.execute()
test.file_grep(test.stats, r'ConstPool, Constants emitted\s+(\d+)', 1)
test.file_grep(test.stats, r'ConstPool, Maps emitted\s+(\d+)', 1)
test.file_grep(test.stats, r'ConstPool, Tables emitted\s+(\d+)', 2)
test.passes()
+101
View File
@@ -0,0 +1,101 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 Wilson Snyder
// SPDX-License-Identifier: CC0-1.0
// verilog_format: off
`define stop $stop
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
`define checks(gotv,expv) do if ((gotv) != (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
// verilog_format: on
// Tests constant pool entries created at different compilation stages.
// - 'color.name()' makes V3Width create the enum name table in the constant pool, before V3Scope.
// - 'sparse.name()' needs an associative array, as the enum values are too far apart for a table.
// - Array parameters in functions are moved into the constant pool by V3Task, after V3Scope.
// - The variably indexed wide constant is extracted into the constant pool by V3Premit.
typedef enum logic [1:0] {
RED,
GREEN,
BLUE
} color_e;
typedef enum logic [31:0] {
LOW = 32'h1,
HIGH = 32'h1000_0000
} sparse_e;
package pkg;
// Distinct type, but same values and names as '$unit::sparse_e', so same name map
typedef enum logic [31:0] {
LOW = 32'h1,
HIGH = 32'h1000_0000
} sparse_e;
endpackage
function automatic logic [31:0] getWord(logic [2:0] i);
// Same value as 'WIDE' below
localparam bit [255:0] WORDS = {
32'h8888_8888,
32'h7777_7777,
32'h6666_6666,
32'h5555_5555,
32'h4444_4444,
32'h3333_3333,
32'h2222_2222,
32'h1111_1111
};
return WORDS[32*i+:32];
endfunction
function automatic logic [7:0] getDigit(logic [3:0] d);
localparam logic [7:0] DIGITS[10] = '{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
return DIGITS[d];
endfunction
function automatic string getName(logic [1:0] c);
// Same as the enum name table: indexed by the enum value, empty for unused values
localparam string NAMES[3:0] = '{"", "BLUE", "GREEN", "RED"};
return NAMES[c];
endfunction
module t;
logic clk = 0;
always #5 clk = ~clk;
integer cyc = 0;
color_e color;
string names[3] = '{"RED", "GREEN", "BLUE"};
sparse_e sparse;
pkg::sparse_e pkgSparse;
localparam bit [255:0] WIDE = {
32'h8888_8888,
32'h7777_7777,
32'h6666_6666,
32'h5555_5555,
32'h4444_4444,
32'h3333_3333,
32'h2222_2222,
32'h1111_1111
};
always @(posedge clk) begin
cyc <= cyc + 1;
color = color_e'(cyc % 3);
`checks(color.name(), names[cyc%3]);
`checks(getName(2'(cyc % 3)), names[cyc%3]);
`checkh(getDigit(4'(cyc % 10)), 8'h30 + 8'(cyc % 10));
sparse = cyc[0] ? HIGH : LOW;
`checks(sparse.name(), cyc[0] ? "HIGH" : "LOW");
pkgSparse = cyc[1] ? pkg::HIGH : pkg::LOW;
`checks(pkgSparse.name(), cyc[1] ? "HIGH" : "LOW");
`checkh(WIDE[32*(cyc%8)+:32], 32'h1111_1111 * (cyc % 8 + 1));
`checkh(getWord(3'(cyc + 3)), 32'h1111_1111 * ((cyc + 3) % 8 + 1));
if (cyc == 20) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
+3 -9
View File
@@ -1,4 +1,4 @@
{"type":"NETLIST","name":"$root","addr":"(B)","loc":"a,0:0,0:0","timeunit":"1ps","timeprecision":"1ps","typeTablep":"(C)","constPoolp":"(D)","dollarUnitPkgp":"(E)",
{"type":"NETLIST","name":"$root","addr":"(B)","loc":"a,0:0,0:0","timeunit":"1ps","timeprecision":"1ps","typeTablep":"(C)","constPoolPkgp":"(D)","dollarUnitPkgp":"(E)",
"modulesp": [
{"type":"MODULE","name":"t","addr":"(F)","loc":"d,67:8,67:9","origName":"t","verilogName":"t","level":1,"depth":2,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps",
"stmtsp": [
@@ -862,7 +862,8 @@
]}
]}
]}
]}
]},
{"type":"PACKAGE","name":"__Vconstpool","addr":"(D)","loc":"a,0:0,0:0","origName":"__Vconstpool","verilogName":"__Vconstpool","level":2,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps"}
],
"miscsp": [
{"type":"TYPETABLE","addr":"(C)","loc":"a,0:0,0:0","voidp":"(GC)",
@@ -889,12 +890,5 @@
{"type":"BASICDTYPE","name":"VlRandomizer","addr":"(KC)","loc":"d,7:1,7:6","dtypep":"(KC)","keyword":"VlRandomizer","generic":true},
{"type":"BASICDTYPE","name":"bit","addr":"(OC)","loc":"d,25:12,25:16","dtypep":"(OC)","keyword":"bit","range":"63:0","generic":true},
{"type":"BASICDTYPE","name":"QData","addr":"(JF)","loc":"d,25:12,25:16","dtypep":"(JF)","keyword":"QData","range":"63:0","generic":true}
]},
{"type":"CONSTPOOL","addr":"(D)","loc":"a,0:0,0:0",
"modulep": [
{"type":"MODULE","name":"@CONST-POOL@","addr":"(JP)","loc":"a,0:0,0:0","origName":"@CONST-POOL@","verilogName":"@CONST-POOL@","unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"NONE",
"stmtsp": [
{"type":"SCOPE","name":"@CONST-POOL@","addr":"(KP)","loc":"a,0:0,0:0","modp":"(JP)"}
]}
]}
]}
+3 -1
View File
@@ -1228,7 +1228,9 @@ package Vt_debug_emitv___024unit;
disable label3;
end
endfunction
string __Venumtab_enum_name36[1:0];
endpackage
package Vt_debug_emitv___Vconstpool;
string TABLE_0[1:0];
endpackage
package Vt_debug_emitv_std;
class Vt_debug_emitv_process;
@@ -1,24 +0,0 @@
#!/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: 2024 Wilson Snyder
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('vlt_all')
test.top_filename = "t/t_extract_static_const.v"
test.golden_filename = "t/t_extract_static_const.out"
test.compile(verilator_flags2=["--stats", "--fno-merge-const-pool"])
test.execute(expect_filename=test.golden_filename)
if test.vlt_all:
test.file_grep(test.stats, r'Optimizations, Prelim extracted value to ConstPool\s+(\d+)', 8)
test.file_grep(test.stats, r'ConstPool, Constants emitted\s+(\d+)', 1)
test.passes()
+1
View File
@@ -10,5 +10,6 @@
%Warning-DEPRECATED: Option '-fno-dfg-scoped' is deprecated, use '-fno-dfg' instead.
%Warning-DEPRECATED: Option '-fno-dfg-break-cycles' is deprecated and has no effect
%Warning-DEPRECATED: Option '-fno-lift-expr' is deprecated and has no effect
%Warning-DEPRECATED: Option '-fno-merge-const-pool' is deprecated and has no effect
%Warning-DEPRECATED: Option '--assert-unroll-limit' is deprecated and has no effect.
%Error: Exiting due to
+1 -1
View File
@@ -12,7 +12,7 @@ import vltest_bootstrap
test.scenarios('vlt')
test.lint(verilator_flags2=[
"--trace-fst-thread --trace-threads 2 --order-clock-delay --clk foo --no-clk bar -fno-dfg-pre-inline -fno-dfg-post-inline -fno-dfg-scoped -fno-dfg-break-cycles -fno-lift-expr --assert-unroll-limit 1024",
"--trace-fst-thread --trace-threads 2 --order-clock-delay --clk foo --no-clk bar -fno-dfg-pre-inline -fno-dfg-post-inline -fno-dfg-scoped -fno-dfg-break-cycles -fno-lift-expr -fno-merge-const-pool --assert-unroll-limit 1024",
],
fails=True,
expect_filename=test.golden_filename)
+2 -8
View File
@@ -1,4 +1,4 @@
{"type":"NETLIST","name":"$root","addr":"(B)","loc":"a,0:0,0:0","timeunit":"1ps","timeprecision":"1ps","typeTablep":"(C)","constPoolp":"(D)","dollarUnitPkgp":"(E)",
{"type":"NETLIST","name":"$root","addr":"(B)","loc":"a,0:0,0:0","timeunit":"1ps","timeprecision":"1ps","typeTablep":"(C)","constPoolPkgp":"(D)","dollarUnitPkgp":"(E)",
"modulesp": [
{"type":"MODULE","name":"test","addr":"(F)","loc":"d,21:8,21:12","origName":"test","verilogName":"test","level":1,"depth":2,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps",
"stmtsp": [
@@ -24,6 +24,7 @@
]}
]},
{"type":"PACKAGE","name":"$unit","addr":"(E)","loc":"a,0:0,0:0","origName":"__024unit","verilogName":"\\$unit ","level":2,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps"},
{"type":"PACKAGE","name":"__Vconstpool","addr":"(D)","loc":"a,0:0,0:0","origName":"__Vconstpool","verilogName":"__Vconstpool","level":2,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps"},
{"type":"MODULE","name":"submod","addr":"(L)","loc":"d,10:8,10:14","origName":"submod","verilogName":"submod","level":2,"depth":2,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps",
"stmtsp": [
{"type":"GENBLOCK","name":"submod_gen","addr":"(U)","loc":"d,11:18,11:28",
@@ -44,12 +45,5 @@
"typesp": [
{"type":"BASICDTYPE","name":"integer","addr":"(H)","loc":"d,22:10,22:11","dtypep":"(H)","keyword":"integer","range":"31:0","generic":true,"signed":true},
{"type":"BASICDTYPE","name":"logic","addr":"(W)","loc":"d,12:10,12:16","dtypep":"(W)","keyword":"logic","generic":true}
]},
{"type":"CONSTPOOL","addr":"(D)","loc":"a,0:0,0:0",
"modulep": [
{"type":"MODULE","name":"@CONST-POOL@","addr":"(CB)","loc":"a,0:0,0:0","origName":"@CONST-POOL@","verilogName":"@CONST-POOL@","unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"NONE",
"stmtsp": [
{"type":"SCOPE","name":"@CONST-POOL@","addr":"(DB)","loc":"a,0:0,0:0","modp":"(CB)"}
]}
]}
]}
+2 -8
View File
@@ -1,4 +1,4 @@
{"type":"NETLIST","name":"$root","addr":"(B)","loc":"a,0:0,0:0","timeunit":"1ps","timeprecision":"1ps","typeTablep":"(C)","constPoolp":"(D)","dollarUnitPkgp":"(E)",
{"type":"NETLIST","name":"$root","addr":"(B)","loc":"a,0:0,0:0","timeunit":"1ps","timeprecision":"1ps","typeTablep":"(C)","constPoolPkgp":"(D)","dollarUnitPkgp":"(E)",
"modulesp": [
{"type":"MODULE","name":"t","addr":"(F)","loc":"d,7:8,7:9","origName":"t","verilogName":"t","level":1,"depth":2,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps",
"stmtsp": [
@@ -119,6 +119,7 @@
]}
]},
{"type":"PACKAGE","name":"$unit","addr":"(E)","loc":"a,0:0,0:0","origName":"__024unit","verilogName":"\\$unit ","level":2,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps"},
{"type":"PACKAGE","name":"__Vconstpool","addr":"(D)","loc":"a,0:0,0:0","origName":"__Vconstpool","verilogName":"__Vconstpool","level":2,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps"},
{"type":"MODULE","name":"mod2","addr":"(JC)","loc":"d,61:8,61:12","origName":"mod2","verilogName":"mod2","level":2,"depth":2,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps",
"stmtsp": [
{"type":"VAR","name":"clk","addr":"(RC)","loc":"d,62:11,62:14","dtypep":"(J)","origName":"clk","verilogName":"clk","direction":"INPUT","declDirection":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
@@ -180,12 +181,5 @@
{"type":"BASICDTYPE","name":"logic","addr":"(FB)","loc":"d,27:26,27:27","dtypep":"(FB)","keyword":"logic","range":"1:0","generic":true,"signed":true},
{"type":"BASICDTYPE","name":"bit","addr":"(AB)","loc":"d,27:32,27:34","dtypep":"(AB)","keyword":"bit","generic":true},
{"type":"BASICDTYPE","name":"bit","addr":"(AD)","loc":"d,29:48,29:49","dtypep":"(AD)","keyword":"bit","range":"31:0","generic":true,"signed":true}
]},
{"type":"CONSTPOOL","addr":"(D)","loc":"a,0:0,0:0",
"modulep": [
{"type":"MODULE","name":"@CONST-POOL@","addr":"(KD)","loc":"a,0:0,0:0","origName":"@CONST-POOL@","verilogName":"@CONST-POOL@","unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"NONE",
"stmtsp": [
{"type":"SCOPE","name":"@CONST-POOL@","addr":"(LD)","loc":"a,0:0,0:0","modp":"(KD)"}
]}
]}
]}
+129 -131
View File
@@ -1,4 +1,4 @@
{"type":"NETLIST","name":"$root","addr":"(B)","loc":"a,0:0,0:0","timeunit":"1ps","timeprecision":"1ps","resolvedTopModuleName":"t","typeTablep":"(C)","constPoolp":"(D)","dollarUnitPkgp":"(E)","topScopep":"(F)",
{"type":"NETLIST","name":"$root","addr":"(B)","loc":"a,0:0,0:0","timeunit":"1ps","timeprecision":"1ps","resolvedTopModuleName":"t","typeTablep":"(C)","constPoolPkgp":"(D)","dollarUnitPkgp":"(E)","topScopep":"(F)",
"modulesp": [
{"type":"MODULE","name":"$root","addr":"(G)","loc":"d,7:8,7:9","origName":"$root","verilogName":"$root","level":1,"depth":1,"modPublic":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps",
"inlinesp": [
@@ -11,273 +11,271 @@
{"type":"VAR","name":"clk","addr":"(M)","loc":"d,14:9,14:12","dtypep":"(N)","origName":"clk","verilogName":"clk","isPrimaryIO":true,"direction":"INPUT","declDirection":"INPUT","isSigPublic":true,"lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"d","addr":"(O)","loc":"d,15:15,15:16","dtypep":"(L)","origName":"d","verilogName":"d","isPrimaryIO":true,"direction":"INPUT","declDirection":"INPUT","isSigPublic":true,"lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"CELL","name":"$unit","addr":"(P)","loc":"a,0:0,0:0","modName":"__024unit","origName":"__024unit","verilogName":"\\$unit ","modp":"(E)"},
{"type":"CELL","name":"__Vconstpool","addr":"(Q)","loc":"a,0:0,0:0","modName":"__Vconstpool","origName":"__Vconstpool","verilogName":"__Vconstpool","modp":"(D)"},
{"type":"TOPSCOPE","addr":"(F)","loc":"d,7:8,7:9",
"scopep": [
{"type":"SCOPE","name":"TOP","addr":"(Q)","loc":"d,7:8,7:9","modp":"(G)",
{"type":"SCOPE","name":"TOP","addr":"(R)","loc":"d,7:8,7:9","modp":"(G)",
"varsp": [
{"type":"VARSCOPE","name":"q","addr":"(R)","loc":"d,16:21,16:22","dtypep":"(L)","isTrace":true,"scopep":"(Q)","varp":"(K)"},
{"type":"VARSCOPE","name":"clk","addr":"(S)","loc":"d,14:9,14:12","dtypep":"(N)","isTrace":true,"scopep":"(Q)","varp":"(M)"},
{"type":"VARSCOPE","name":"d","addr":"(T)","loc":"d,15:15,15:16","dtypep":"(L)","isTrace":true,"scopep":"(Q)","varp":"(O)"},
{"type":"VARSCOPE","name":"t.q","addr":"(U)","loc":"d,16:21,16:22","dtypep":"(L)","isTrace":true,"scopep":"(Q)","varp":"(V)"},
{"type":"VARSCOPE","name":"t.clk","addr":"(W)","loc":"d,14:9,14:12","dtypep":"(N)","isTrace":true,"scopep":"(Q)","varp":"(X)"},
{"type":"VARSCOPE","name":"t.d","addr":"(Y)","loc":"d,15:15,15:16","dtypep":"(L)","isTrace":true,"scopep":"(Q)","varp":"(Z)"},
{"type":"VARSCOPE","name":"t.between","addr":"(AB)","loc":"d,18:15,18:22","dtypep":"(L)","isTrace":true,"scopep":"(Q)","varp":"(BB)"},
{"type":"VARSCOPE","name":"t.direct_named","addr":"(CB)","loc":"d,19:9,19:21","dtypep":"(N)","isTrace":true,"scopep":"(Q)","varp":"(DB)"},
{"type":"VARSCOPE","name":"t.computed_named","addr":"(EB)","loc":"d,20:9,20:23","dtypep":"(N)","isTrace":true,"scopep":"(Q)","varp":"(FB)"},
{"type":"VARSCOPE","name":"t.anonymous_expr","addr":"(GB)","loc":"d,21:9,21:23","dtypep":"(N)","isTrace":true,"scopep":"(Q)","varp":"(HB)"},
{"type":"VARSCOPE","name":"t.S_IDLE","addr":"(IB)","loc":"d,23:26,23:32","dtypep":"(JB)","isTrace":true,"scopep":"(Q)","varp":"(KB)"},
{"type":"VARSCOPE","name":"t.S_FETCH","addr":"(LB)","loc":"d,24:26,24:33","dtypep":"(JB)","isTrace":true,"scopep":"(Q)","varp":"(MB)"},
{"type":"VARSCOPE","name":"t.S_EXEC","addr":"(NB)","loc":"d,25:26,25:32","dtypep":"(JB)","isTrace":true,"scopep":"(Q)","varp":"(OB)"},
{"type":"VARSCOPE","name":"t.cell2.clk","addr":"(PB)","loc":"d,62:11,62:14","dtypep":"(N)","scopep":"(Q)","varp":"(QB)"},
{"type":"VARSCOPE","name":"t.cell2.d","addr":"(RB)","loc":"d,63:17,63:18","dtypep":"(L)","scopep":"(Q)","varp":"(SB)"},
{"type":"VARSCOPE","name":"t.cell2.q","addr":"(TB)","loc":"d,64:23,64:24","dtypep":"(L)","scopep":"(Q)","varp":"(UB)"},
{"type":"VARSCOPE","name":"t.cell1.WIDTH","addr":"(VB)","loc":"d,48:15,48:20","dtypep":"(WB)","scopep":"(Q)","varp":"(XB)"},
{"type":"VARSCOPE","name":"t.cell1.clk","addr":"(YB)","loc":"d,50:11,50:14","dtypep":"(N)","scopep":"(Q)","varp":"(ZB)"},
{"type":"VARSCOPE","name":"t.cell1.d","addr":"(AC)","loc":"d,51:23,51:24","dtypep":"(L)","scopep":"(Q)","varp":"(BC)"},
{"type":"VARSCOPE","name":"t.cell1.q","addr":"(CC)","loc":"d,52:30,52:31","dtypep":"(L)","scopep":"(Q)","varp":"(DC)"},
{"type":"VARSCOPE","name":"t.cell1.IGNORED","addr":"(EC)","loc":"d,55:14,55:21","dtypep":"(WB)","scopep":"(Q)","varp":"(FC)"}
{"type":"VARSCOPE","name":"q","addr":"(S)","loc":"d,16:21,16:22","dtypep":"(L)","isTrace":true,"scopep":"(R)","varp":"(K)"},
{"type":"VARSCOPE","name":"clk","addr":"(T)","loc":"d,14:9,14:12","dtypep":"(N)","isTrace":true,"scopep":"(R)","varp":"(M)"},
{"type":"VARSCOPE","name":"d","addr":"(U)","loc":"d,15:15,15:16","dtypep":"(L)","isTrace":true,"scopep":"(R)","varp":"(O)"},
{"type":"VARSCOPE","name":"t.q","addr":"(V)","loc":"d,16:21,16:22","dtypep":"(L)","isTrace":true,"scopep":"(R)","varp":"(W)"},
{"type":"VARSCOPE","name":"t.clk","addr":"(X)","loc":"d,14:9,14:12","dtypep":"(N)","isTrace":true,"scopep":"(R)","varp":"(Y)"},
{"type":"VARSCOPE","name":"t.d","addr":"(Z)","loc":"d,15:15,15:16","dtypep":"(L)","isTrace":true,"scopep":"(R)","varp":"(AB)"},
{"type":"VARSCOPE","name":"t.between","addr":"(BB)","loc":"d,18:15,18:22","dtypep":"(L)","isTrace":true,"scopep":"(R)","varp":"(CB)"},
{"type":"VARSCOPE","name":"t.direct_named","addr":"(DB)","loc":"d,19:9,19:21","dtypep":"(N)","isTrace":true,"scopep":"(R)","varp":"(EB)"},
{"type":"VARSCOPE","name":"t.computed_named","addr":"(FB)","loc":"d,20:9,20:23","dtypep":"(N)","isTrace":true,"scopep":"(R)","varp":"(GB)"},
{"type":"VARSCOPE","name":"t.anonymous_expr","addr":"(HB)","loc":"d,21:9,21:23","dtypep":"(N)","isTrace":true,"scopep":"(R)","varp":"(IB)"},
{"type":"VARSCOPE","name":"t.S_IDLE","addr":"(JB)","loc":"d,23:26,23:32","dtypep":"(KB)","isTrace":true,"scopep":"(R)","varp":"(LB)"},
{"type":"VARSCOPE","name":"t.S_FETCH","addr":"(MB)","loc":"d,24:26,24:33","dtypep":"(KB)","isTrace":true,"scopep":"(R)","varp":"(NB)"},
{"type":"VARSCOPE","name":"t.S_EXEC","addr":"(OB)","loc":"d,25:26,25:32","dtypep":"(KB)","isTrace":true,"scopep":"(R)","varp":"(PB)"},
{"type":"VARSCOPE","name":"t.cell2.clk","addr":"(QB)","loc":"d,62:11,62:14","dtypep":"(N)","scopep":"(R)","varp":"(RB)"},
{"type":"VARSCOPE","name":"t.cell2.d","addr":"(SB)","loc":"d,63:17,63:18","dtypep":"(L)","scopep":"(R)","varp":"(TB)"},
{"type":"VARSCOPE","name":"t.cell2.q","addr":"(UB)","loc":"d,64:23,64:24","dtypep":"(L)","scopep":"(R)","varp":"(VB)"},
{"type":"VARSCOPE","name":"t.cell1.WIDTH","addr":"(WB)","loc":"d,48:15,48:20","dtypep":"(XB)","scopep":"(R)","varp":"(YB)"},
{"type":"VARSCOPE","name":"t.cell1.clk","addr":"(ZB)","loc":"d,50:11,50:14","dtypep":"(N)","scopep":"(R)","varp":"(AC)"},
{"type":"VARSCOPE","name":"t.cell1.d","addr":"(BC)","loc":"d,51:23,51:24","dtypep":"(L)","scopep":"(R)","varp":"(CC)"},
{"type":"VARSCOPE","name":"t.cell1.q","addr":"(DC)","loc":"d,52:30,52:31","dtypep":"(L)","scopep":"(R)","varp":"(EC)"},
{"type":"VARSCOPE","name":"t.cell1.IGNORED","addr":"(FC)","loc":"d,55:14,55:21","dtypep":"(XB)","scopep":"(R)","varp":"(GC)"}
],
"blocksp": [
{"type":"ALWAYS","addr":"(GC)","loc":"d,27:23,27:24","keyword":"cont_assign",
{"type":"ALWAYS","addr":"(HC)","loc":"d,27:23,27:24","keyword":"cont_assign",
"stmtsp": [
{"type":"ASSIGNW","addr":"(HC)","loc":"d,27:23,27:24","dtypep":"(N)",
{"type":"ASSIGNW","addr":"(IC)","loc":"d,27:23,27:24","dtypep":"(N)",
"rhsp": [
{"type":"EQ","addr":"(IC)","loc":"d,27:32,27:34","dtypep":"(JC)",
{"type":"EQ","addr":"(JC)","loc":"d,27:32,27:34","dtypep":"(KC)",
"lhsp": [
{"type":"CONST","name":"2'h0","addr":"(KC)","loc":"d,27:35,27:41","dtypep":"(JB)","origParamName":"S_IDLE"}
{"type":"CONST","name":"2'h0","addr":"(LC)","loc":"d,27:35,27:41","dtypep":"(KB)","origParamName":"S_IDLE"}
],
"rhsp": [
{"type":"SEL","addr":"(LC)","loc":"d,27:26,27:27","dtypep":"(JB)","widthConst":2,"declRange":"[3:0]","declElWidth":1,
{"type":"SEL","addr":"(MC)","loc":"d,27:26,27:27","dtypep":"(KB)","widthConst":2,"declRange":"[3:0]","declElWidth":1,
"fromp": [
{"type":"VARREF","name":"d","addr":"(MC)","loc":"d,27:25,27:26","dtypep":"(L)","access":"RD","varp":"(O)","varScopep":"(T)"}
{"type":"VARREF","name":"d","addr":"(NC)","loc":"d,27:25,27:26","dtypep":"(L)","access":"RD","varp":"(O)","varScopep":"(U)"}
],
"lsbp": [
{"type":"CONST","name":"2'h0","addr":"(NC)","loc":"d,27:29,27:30","dtypep":"(OC)"}
{"type":"CONST","name":"2'h0","addr":"(OC)","loc":"d,27:29,27:30","dtypep":"(PC)"}
]}
]}
],
"lhsp": [
{"type":"VARREF","name":"t.direct_named","addr":"(PC)","loc":"d,27:10,27:22","dtypep":"(N)","access":"WR","varp":"(DB)","varScopep":"(CB)"}
{"type":"VARREF","name":"t.direct_named","addr":"(QC)","loc":"d,27:10,27:22","dtypep":"(N)","access":"WR","varp":"(EB)","varScopep":"(DB)"}
]}
]},
{"type":"ALWAYS","addr":"(QC)","loc":"d,28:25,28:26","keyword":"cont_assign",
{"type":"ALWAYS","addr":"(RC)","loc":"d,28:25,28:26","keyword":"cont_assign",
"stmtsp": [
{"type":"ASSIGNW","addr":"(RC)","loc":"d,28:25,28:26","dtypep":"(N)",
{"type":"ASSIGNW","addr":"(SC)","loc":"d,28:25,28:26","dtypep":"(N)",
"rhsp": [
{"type":"EQ","addr":"(SC)","loc":"d,28:34,28:36","dtypep":"(JC)",
{"type":"EQ","addr":"(TC)","loc":"d,28:34,28:36","dtypep":"(KC)",
"lhsp": [
{"type":"CONST","name":"2'h2","addr":"(TC)","loc":"d,28:37,28:43","dtypep":"(JB)","origParamName":"S_EXEC"}
{"type":"CONST","name":"2'h2","addr":"(UC)","loc":"d,28:37,28:43","dtypep":"(KB)","origParamName":"S_EXEC"}
],
"rhsp": [
{"type":"SEL","addr":"(UC)","loc":"d,28:28,28:29","dtypep":"(JB)","widthConst":2,"declRange":"[3:0]","declElWidth":1,
{"type":"SEL","addr":"(VC)","loc":"d,28:28,28:29","dtypep":"(KB)","widthConst":2,"declRange":"[3:0]","declElWidth":1,
"fromp": [
{"type":"VARREF","name":"d","addr":"(VC)","loc":"d,28:27,28:28","dtypep":"(L)","access":"RD","varp":"(O)","varScopep":"(T)"}
{"type":"VARREF","name":"d","addr":"(WC)","loc":"d,28:27,28:28","dtypep":"(L)","access":"RD","varp":"(O)","varScopep":"(U)"}
],
"lsbp": [
{"type":"CONST","name":"2'h0","addr":"(WC)","loc":"d,28:31,28:32","dtypep":"(OC)"}
{"type":"CONST","name":"2'h0","addr":"(XC)","loc":"d,28:31,28:32","dtypep":"(PC)"}
]}
]}
],
"lhsp": [
{"type":"VARREF","name":"t.computed_named","addr":"(XC)","loc":"d,28:10,28:24","dtypep":"(N)","access":"WR","varp":"(FB)","varScopep":"(EB)"}
{"type":"VARREF","name":"t.computed_named","addr":"(YC)","loc":"d,28:10,28:24","dtypep":"(N)","access":"WR","varp":"(GB)","varScopep":"(FB)"}
]}
]},
{"type":"ALWAYS","addr":"(YC)","loc":"d,29:25,29:26","keyword":"cont_assign",
{"type":"ALWAYS","addr":"(ZC)","loc":"d,29:25,29:26","keyword":"cont_assign",
"stmtsp": [
{"type":"ASSIGNW","addr":"(ZC)","loc":"d,29:25,29:26","dtypep":"(N)",
{"type":"ASSIGNW","addr":"(AD)","loc":"d,29:25,29:26","dtypep":"(N)",
"rhsp": [
{"type":"EQ","addr":"(AD)","loc":"d,29:34,29:36","dtypep":"(JC)",
{"type":"EQ","addr":"(BD)","loc":"d,29:34,29:36","dtypep":"(KC)",
"lhsp": [
{"type":"CONST","name":"2'h2","addr":"(BD)","loc":"d,29:46,29:47","dtypep":"(CD)"}
{"type":"CONST","name":"2'h2","addr":"(CD)","loc":"d,29:46,29:47","dtypep":"(DD)"}
],
"rhsp": [
{"type":"SEL","addr":"(DD)","loc":"d,29:28,29:29","dtypep":"(JB)","widthConst":2,"declRange":"[3:0]","declElWidth":1,
{"type":"SEL","addr":"(ED)","loc":"d,29:28,29:29","dtypep":"(KB)","widthConst":2,"declRange":"[3:0]","declElWidth":1,
"fromp": [
{"type":"VARREF","name":"d","addr":"(ED)","loc":"d,29:27,29:28","dtypep":"(L)","access":"RD","varp":"(O)","varScopep":"(T)"}
{"type":"VARREF","name":"d","addr":"(FD)","loc":"d,29:27,29:28","dtypep":"(L)","access":"RD","varp":"(O)","varScopep":"(U)"}
],
"lsbp": [
{"type":"CONST","name":"2'h0","addr":"(FD)","loc":"d,29:31,29:32","dtypep":"(OC)"}
{"type":"CONST","name":"2'h0","addr":"(GD)","loc":"d,29:31,29:32","dtypep":"(PC)"}
]}
]}
],
"lhsp": [
{"type":"VARREF","name":"t.anonymous_expr","addr":"(GD)","loc":"d,29:10,29:24","dtypep":"(N)","access":"WR","varp":"(HB)","varScopep":"(GB)"}
{"type":"VARREF","name":"t.anonymous_expr","addr":"(HD)","loc":"d,29:10,29:24","dtypep":"(N)","access":"WR","varp":"(IB)","varScopep":"(HB)"}
]}
]},
{"type":"ALWAYS","addr":"(HD)","loc":"d,16:21,16:22","keyword":"cont_assign",
{"type":"ALWAYS","addr":"(ID)","loc":"d,16:21,16:22","keyword":"cont_assign",
"stmtsp": [
{"type":"ASSIGNW","addr":"(ID)","loc":"d,16:21,16:22","dtypep":"(L)",
{"type":"ASSIGNW","addr":"(JD)","loc":"d,16:21,16:22","dtypep":"(L)",
"rhsp": [
{"type":"VARREF","name":"q","addr":"(JD)","loc":"d,16:21,16:22","dtypep":"(L)","access":"RD","varp":"(K)","varScopep":"(R)"}
{"type":"VARREF","name":"q","addr":"(KD)","loc":"d,16:21,16:22","dtypep":"(L)","access":"RD","varp":"(K)","varScopep":"(S)"}
],
"lhsp": [
{"type":"VARREF","name":"t.q","addr":"(KD)","loc":"d,16:21,16:22","dtypep":"(L)","access":"WR","varp":"(V)","varScopep":"(U)"}
{"type":"VARREF","name":"t.q","addr":"(LD)","loc":"d,16:21,16:22","dtypep":"(L)","access":"WR","varp":"(W)","varScopep":"(V)"}
]}
]},
{"type":"ALWAYS","addr":"(LD)","loc":"d,14:9,14:12","keyword":"cont_assign",
{"type":"ALWAYS","addr":"(MD)","loc":"d,14:9,14:12","keyword":"cont_assign",
"stmtsp": [
{"type":"ASSIGNW","addr":"(MD)","loc":"d,14:9,14:12","dtypep":"(N)",
{"type":"ASSIGNW","addr":"(ND)","loc":"d,14:9,14:12","dtypep":"(N)",
"rhsp": [
{"type":"VARREF","name":"clk","addr":"(ND)","loc":"d,14:9,14:12","dtypep":"(N)","access":"RD","varp":"(M)","varScopep":"(S)"}
{"type":"VARREF","name":"clk","addr":"(OD)","loc":"d,14:9,14:12","dtypep":"(N)","access":"RD","varp":"(M)","varScopep":"(T)"}
],
"lhsp": [
{"type":"VARREF","name":"t.clk","addr":"(OD)","loc":"d,14:9,14:12","dtypep":"(N)","access":"WR","varp":"(X)","varScopep":"(W)"}
{"type":"VARREF","name":"t.clk","addr":"(PD)","loc":"d,14:9,14:12","dtypep":"(N)","access":"WR","varp":"(Y)","varScopep":"(X)"}
]}
]},
{"type":"ALWAYS","addr":"(PD)","loc":"d,15:15,15:16","keyword":"cont_assign",
{"type":"ALWAYS","addr":"(QD)","loc":"d,15:15,15:16","keyword":"cont_assign",
"stmtsp": [
{"type":"ASSIGNW","addr":"(QD)","loc":"d,15:15,15:16","dtypep":"(L)",
{"type":"ASSIGNW","addr":"(RD)","loc":"d,15:15,15:16","dtypep":"(L)",
"rhsp": [
{"type":"VARREF","name":"d","addr":"(RD)","loc":"d,15:15,15:16","dtypep":"(L)","access":"RD","varp":"(O)","varScopep":"(T)"}
{"type":"VARREF","name":"d","addr":"(SD)","loc":"d,15:15,15:16","dtypep":"(L)","access":"RD","varp":"(O)","varScopep":"(U)"}
],
"lhsp": [
{"type":"VARREF","name":"t.d","addr":"(SD)","loc":"d,15:15,15:16","dtypep":"(L)","access":"WR","varp":"(Z)","varScopep":"(Y)"}
{"type":"VARREF","name":"t.d","addr":"(TD)","loc":"d,15:15,15:16","dtypep":"(L)","access":"WR","varp":"(AB)","varScopep":"(Z)"}
]}
]},
{"type":"ALWAYS","addr":"(TD)","loc":"d,67:12,67:13","keyword":"cont_assign",
{"type":"ALWAYS","addr":"(UD)","loc":"d,67:12,67:13","keyword":"cont_assign",
"stmtsp": [
{"type":"ASSIGNW","addr":"(UD)","loc":"d,67:12,67:13","dtypep":"(L)",
{"type":"ASSIGNW","addr":"(VD)","loc":"d,67:12,67:13","dtypep":"(L)",
"rhsp": [
{"type":"VARREF","name":"t.between","addr":"(VD)","loc":"d,67:14,67:15","dtypep":"(L)","access":"RD","varp":"(BB)","varScopep":"(AB)"}
{"type":"VARREF","name":"t.between","addr":"(WD)","loc":"d,67:14,67:15","dtypep":"(L)","access":"RD","varp":"(CB)","varScopep":"(BB)"}
],
"lhsp": [
{"type":"VARREF","name":"q","addr":"(WD)","loc":"d,67:10,67:11","dtypep":"(L)","access":"WR","varp":"(K)","varScopep":"(R)"}
{"type":"VARREF","name":"q","addr":"(XD)","loc":"d,67:10,67:11","dtypep":"(L)","access":"WR","varp":"(K)","varScopep":"(S)"}
]}
]},
{"type":"ALWAYS","addr":"(XD)","loc":"d,62:11,62:14","keyword":"cont_assign",
{"type":"ALWAYS","addr":"(YD)","loc":"d,62:11,62:14","keyword":"cont_assign",
"stmtsp": [
{"type":"ASSIGNW","addr":"(YD)","loc":"d,62:11,62:14","dtypep":"(N)",
{"type":"ASSIGNW","addr":"(ZD)","loc":"d,62:11,62:14","dtypep":"(N)",
"rhsp": [
{"type":"VARREF","name":"clk","addr":"(ZD)","loc":"d,62:11,62:14","dtypep":"(N)","access":"RD","varp":"(M)","varScopep":"(S)"}
{"type":"VARREF","name":"clk","addr":"(AE)","loc":"d,62:11,62:14","dtypep":"(N)","access":"RD","varp":"(M)","varScopep":"(T)"}
],
"lhsp": [
{"type":"VARREF","name":"t.cell2.clk","addr":"(AE)","loc":"d,62:11,62:14","dtypep":"(N)","access":"WR","varp":"(QB)","varScopep":"(PB)"}
{"type":"VARREF","name":"t.cell2.clk","addr":"(BE)","loc":"d,62:11,62:14","dtypep":"(N)","access":"WR","varp":"(RB)","varScopep":"(QB)"}
]}
]},
{"type":"ALWAYS","addr":"(BE)","loc":"d,63:17,63:18","keyword":"cont_assign",
{"type":"ALWAYS","addr":"(CE)","loc":"d,63:17,63:18","keyword":"cont_assign",
"stmtsp": [
{"type":"ASSIGNW","addr":"(CE)","loc":"d,63:17,63:18","dtypep":"(L)",
{"type":"ASSIGNW","addr":"(DE)","loc":"d,63:17,63:18","dtypep":"(L)",
"rhsp": [
{"type":"VARREF","name":"t.between","addr":"(DE)","loc":"d,63:17,63:18","dtypep":"(L)","access":"RD","varp":"(BB)","varScopep":"(AB)"}
{"type":"VARREF","name":"t.between","addr":"(EE)","loc":"d,63:17,63:18","dtypep":"(L)","access":"RD","varp":"(CB)","varScopep":"(BB)"}
],
"lhsp": [
{"type":"VARREF","name":"t.cell2.d","addr":"(EE)","loc":"d,63:17,63:18","dtypep":"(L)","access":"WR","varp":"(SB)","varScopep":"(RB)"}
{"type":"VARREF","name":"t.cell2.d","addr":"(FE)","loc":"d,63:17,63:18","dtypep":"(L)","access":"WR","varp":"(TB)","varScopep":"(SB)"}
]}
]},
{"type":"ALWAYS","addr":"(FE)","loc":"d,64:23,64:24","keyword":"cont_assign",
{"type":"ALWAYS","addr":"(GE)","loc":"d,64:23,64:24","keyword":"cont_assign",
"stmtsp": [
{"type":"ASSIGNW","addr":"(GE)","loc":"d,64:23,64:24","dtypep":"(L)",
{"type":"ASSIGNW","addr":"(HE)","loc":"d,64:23,64:24","dtypep":"(L)",
"rhsp": [
{"type":"VARREF","name":"q","addr":"(HE)","loc":"d,64:23,64:24","dtypep":"(L)","access":"RD","varp":"(K)","varScopep":"(R)"}
{"type":"VARREF","name":"q","addr":"(IE)","loc":"d,64:23,64:24","dtypep":"(L)","access":"RD","varp":"(K)","varScopep":"(S)"}
],
"lhsp": [
{"type":"VARREF","name":"t.cell2.q","addr":"(IE)","loc":"d,64:23,64:24","dtypep":"(L)","access":"WR","varp":"(UB)","varScopep":"(TB)"}
{"type":"VARREF","name":"t.cell2.q","addr":"(JE)","loc":"d,64:23,64:24","dtypep":"(L)","access":"WR","varp":"(VB)","varScopep":"(UB)"}
]}
]},
{"type":"ALWAYS","addr":"(JE)","loc":"d,57:3,57:9","keyword":"always",
{"type":"ALWAYS","addr":"(KE)","loc":"d,57:3,57:9","keyword":"always",
"sentreep": [
{"type":"SENTREE","addr":"(KE)","loc":"d,57:10,57:11",
{"type":"SENTREE","addr":"(LE)","loc":"d,57:10,57:11",
"sensesp": [
{"type":"SENITEM","addr":"(LE)","loc":"d,57:12,57:19","edgeType":"POS",
{"type":"SENITEM","addr":"(ME)","loc":"d,57:12,57:19","edgeType":"POS",
"sensp": [
{"type":"VARREF","name":"clk","addr":"(ME)","loc":"d,57:20,57:23","dtypep":"(N)","access":"RD","varp":"(M)","varScopep":"(S)"}
{"type":"VARREF","name":"clk","addr":"(NE)","loc":"d,57:20,57:23","dtypep":"(N)","access":"RD","varp":"(M)","varScopep":"(T)"}
]}
]}
],
"stmtsp": [
{"type":"ASSIGNDLY","addr":"(NE)","loc":"d,57:27,57:29","dtypep":"(L)",
{"type":"ASSIGNDLY","addr":"(OE)","loc":"d,57:27,57:29","dtypep":"(L)",
"rhsp": [
{"type":"VARREF","name":"d","addr":"(OE)","loc":"d,57:30,57:31","dtypep":"(L)","access":"RD","varp":"(O)","varScopep":"(T)"}
{"type":"VARREF","name":"d","addr":"(PE)","loc":"d,57:30,57:31","dtypep":"(L)","access":"RD","varp":"(O)","varScopep":"(U)"}
],
"lhsp": [
{"type":"VARREF","name":"t.between","addr":"(PE)","loc":"d,57:25,57:26","dtypep":"(L)","access":"WR","varp":"(BB)","varScopep":"(AB)"}
{"type":"VARREF","name":"t.between","addr":"(QE)","loc":"d,57:25,57:26","dtypep":"(L)","access":"WR","varp":"(CB)","varScopep":"(BB)"}
]}
]},
{"type":"ALWAYS","addr":"(QE)","loc":"d,50:11,50:14","keyword":"cont_assign",
{"type":"ALWAYS","addr":"(RE)","loc":"d,50:11,50:14","keyword":"cont_assign",
"stmtsp": [
{"type":"ASSIGNW","addr":"(RE)","loc":"d,50:11,50:14","dtypep":"(N)",
{"type":"ASSIGNW","addr":"(SE)","loc":"d,50:11,50:14","dtypep":"(N)",
"rhsp": [
{"type":"VARREF","name":"clk","addr":"(SE)","loc":"d,50:11,50:14","dtypep":"(N)","access":"RD","varp":"(M)","varScopep":"(S)"}
{"type":"VARREF","name":"clk","addr":"(TE)","loc":"d,50:11,50:14","dtypep":"(N)","access":"RD","varp":"(M)","varScopep":"(T)"}
],
"lhsp": [
{"type":"VARREF","name":"t.cell1.clk","addr":"(TE)","loc":"d,50:11,50:14","dtypep":"(N)","access":"WR","varp":"(ZB)","varScopep":"(YB)"}
{"type":"VARREF","name":"t.cell1.clk","addr":"(UE)","loc":"d,50:11,50:14","dtypep":"(N)","access":"WR","varp":"(AC)","varScopep":"(ZB)"}
]}
]},
{"type":"ALWAYS","addr":"(UE)","loc":"d,51:23,51:24","keyword":"cont_assign",
{"type":"ALWAYS","addr":"(VE)","loc":"d,51:23,51:24","keyword":"cont_assign",
"stmtsp": [
{"type":"ASSIGNW","addr":"(VE)","loc":"d,51:23,51:24","dtypep":"(L)",
{"type":"ASSIGNW","addr":"(WE)","loc":"d,51:23,51:24","dtypep":"(L)",
"rhsp": [
{"type":"VARREF","name":"d","addr":"(WE)","loc":"d,51:23,51:24","dtypep":"(L)","access":"RD","varp":"(O)","varScopep":"(T)"}
{"type":"VARREF","name":"d","addr":"(XE)","loc":"d,51:23,51:24","dtypep":"(L)","access":"RD","varp":"(O)","varScopep":"(U)"}
],
"lhsp": [
{"type":"VARREF","name":"t.cell1.d","addr":"(XE)","loc":"d,51:23,51:24","dtypep":"(L)","access":"WR","varp":"(BC)","varScopep":"(AC)"}
{"type":"VARREF","name":"t.cell1.d","addr":"(YE)","loc":"d,51:23,51:24","dtypep":"(L)","access":"WR","varp":"(CC)","varScopep":"(BC)"}
]}
]},
{"type":"ALWAYS","addr":"(YE)","loc":"d,52:30,52:31","keyword":"cont_assign",
{"type":"ALWAYS","addr":"(ZE)","loc":"d,52:30,52:31","keyword":"cont_assign",
"stmtsp": [
{"type":"ASSIGNW","addr":"(ZE)","loc":"d,52:30,52:31","dtypep":"(L)",
{"type":"ASSIGNW","addr":"(AF)","loc":"d,52:30,52:31","dtypep":"(L)",
"rhsp": [
{"type":"VARREF","name":"t.between","addr":"(AF)","loc":"d,52:30,52:31","dtypep":"(L)","access":"RD","varp":"(BB)","varScopep":"(AB)"}
{"type":"VARREF","name":"t.between","addr":"(BF)","loc":"d,52:30,52:31","dtypep":"(L)","access":"RD","varp":"(CB)","varScopep":"(BB)"}
],
"lhsp": [
{"type":"VARREF","name":"t.cell1.q","addr":"(BF)","loc":"d,52:30,52:31","dtypep":"(L)","access":"WR","varp":"(DC)","varScopep":"(CC)"}
{"type":"VARREF","name":"t.cell1.q","addr":"(CF)","loc":"d,52:30,52:31","dtypep":"(L)","access":"WR","varp":"(EC)","varScopep":"(DC)"}
]}
]}
]}
]},
{"type":"VAR","name":"t.q","addr":"(V)","loc":"d,16:21,16:22","dtypep":"(L)","origName":"q","verilogName":"q","direction":"NONE","declDirection":"OUTPUT","icoMaybeWritten":true,"lifetime":"VSTATICI","varType":"WIRE","dtypeName":"logic"},
{"type":"VAR","name":"t.clk","addr":"(X)","loc":"d,14:9,14:12","dtypep":"(N)","origName":"clk","verilogName":"clk","direction":"NONE","declDirection":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"t.d","addr":"(Z)","loc":"d,15:15,15:16","dtypep":"(L)","origName":"d","verilogName":"d","direction":"NONE","declDirection":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"t.between","addr":"(BB)","loc":"d,18:15,18:22","dtypep":"(L)","origName":"between","verilogName":"between","direction":"NONE","declDirection":"NONE","icoMaybeWritten":true,"lifetime":"VSTATICI","varType":"VAR","dtypeName":"logic"},
{"type":"VAR","name":"t.direct_named","addr":"(DB)","loc":"d,19:9,19:21","dtypep":"(N)","origName":"direct_named","verilogName":"direct_named","direction":"NONE","declDirection":"NONE","icoMaybeWritten":true,"lifetime":"VSTATICI","varType":"VAR","dtypeName":"logic"},
{"type":"VAR","name":"t.computed_named","addr":"(FB)","loc":"d,20:9,20:23","dtypep":"(N)","origName":"computed_named","verilogName":"computed_named","direction":"NONE","declDirection":"NONE","icoMaybeWritten":true,"lifetime":"VSTATICI","varType":"VAR","dtypeName":"logic"},
{"type":"VAR","name":"t.anonymous_expr","addr":"(HB)","loc":"d,21:9,21:23","dtypep":"(N)","origName":"anonymous_expr","verilogName":"anonymous_expr","direction":"NONE","declDirection":"NONE","icoMaybeWritten":true,"lifetime":"VSTATICI","varType":"VAR","dtypeName":"logic"},
{"type":"VAR","name":"t.S_IDLE","addr":"(KB)","loc":"d,23:26,23:32","dtypep":"(JB)","origName":"S_IDLE","verilogName":"S_IDLE","direction":"NONE","declDirection":"NONE","isConst":true,"lifetime":"VSTATICI","varType":"LPARAM","dtypeName":"logic","isParam":true,"hasUserInit":true,
{"type":"VAR","name":"t.q","addr":"(W)","loc":"d,16:21,16:22","dtypep":"(L)","origName":"q","verilogName":"q","direction":"NONE","declDirection":"OUTPUT","icoMaybeWritten":true,"lifetime":"VSTATICI","varType":"WIRE","dtypeName":"logic"},
{"type":"VAR","name":"t.clk","addr":"(Y)","loc":"d,14:9,14:12","dtypep":"(N)","origName":"clk","verilogName":"clk","direction":"NONE","declDirection":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"t.d","addr":"(AB)","loc":"d,15:15,15:16","dtypep":"(L)","origName":"d","verilogName":"d","direction":"NONE","declDirection":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"t.between","addr":"(CB)","loc":"d,18:15,18:22","dtypep":"(L)","origName":"between","verilogName":"between","direction":"NONE","declDirection":"NONE","icoMaybeWritten":true,"lifetime":"VSTATICI","varType":"VAR","dtypeName":"logic"},
{"type":"VAR","name":"t.direct_named","addr":"(EB)","loc":"d,19:9,19:21","dtypep":"(N)","origName":"direct_named","verilogName":"direct_named","direction":"NONE","declDirection":"NONE","icoMaybeWritten":true,"lifetime":"VSTATICI","varType":"VAR","dtypeName":"logic"},
{"type":"VAR","name":"t.computed_named","addr":"(GB)","loc":"d,20:9,20:23","dtypep":"(N)","origName":"computed_named","verilogName":"computed_named","direction":"NONE","declDirection":"NONE","icoMaybeWritten":true,"lifetime":"VSTATICI","varType":"VAR","dtypeName":"logic"},
{"type":"VAR","name":"t.anonymous_expr","addr":"(IB)","loc":"d,21:9,21:23","dtypep":"(N)","origName":"anonymous_expr","verilogName":"anonymous_expr","direction":"NONE","declDirection":"NONE","icoMaybeWritten":true,"lifetime":"VSTATICI","varType":"VAR","dtypeName":"logic"},
{"type":"VAR","name":"t.S_IDLE","addr":"(LB)","loc":"d,23:26,23:32","dtypep":"(KB)","origName":"S_IDLE","verilogName":"S_IDLE","direction":"NONE","declDirection":"NONE","isConst":true,"lifetime":"VSTATICI","varType":"LPARAM","dtypeName":"logic","isParam":true,"hasUserInit":true,
"valuep": [
{"type":"CONST","name":"2'h0","addr":"(CF)","loc":"d,23:35,23:40","dtypep":"(CD)"}
{"type":"CONST","name":"2'h0","addr":"(DF)","loc":"d,23:35,23:40","dtypep":"(DD)"}
]},
{"type":"VAR","name":"t.S_FETCH","addr":"(MB)","loc":"d,24:26,24:33","dtypep":"(JB)","origName":"S_FETCH","verilogName":"S_FETCH","direction":"NONE","declDirection":"NONE","isConst":true,"lifetime":"VSTATICI","varType":"LPARAM","dtypeName":"logic","isParam":true,"hasUserInit":true,
{"type":"VAR","name":"t.S_FETCH","addr":"(NB)","loc":"d,24:26,24:33","dtypep":"(KB)","origName":"S_FETCH","verilogName":"S_FETCH","direction":"NONE","declDirection":"NONE","isConst":true,"lifetime":"VSTATICI","varType":"LPARAM","dtypeName":"logic","isParam":true,"hasUserInit":true,
"valuep": [
{"type":"CONST","name":"2'h1","addr":"(DF)","loc":"d,24:36,24:41","dtypep":"(CD)"}
{"type":"CONST","name":"2'h1","addr":"(EF)","loc":"d,24:36,24:41","dtypep":"(DD)"}
]},
{"type":"VAR","name":"t.S_EXEC","addr":"(OB)","loc":"d,25:26,25:32","dtypep":"(JB)","origName":"S_EXEC","verilogName":"S_EXEC","direction":"NONE","declDirection":"NONE","isConst":true,"lifetime":"VSTATICI","varType":"LPARAM","dtypeName":"logic","isParam":true,"hasUserInit":true,
{"type":"VAR","name":"t.S_EXEC","addr":"(PB)","loc":"d,25:26,25:32","dtypep":"(KB)","origName":"S_EXEC","verilogName":"S_EXEC","direction":"NONE","declDirection":"NONE","isConst":true,"lifetime":"VSTATICI","varType":"LPARAM","dtypeName":"logic","isParam":true,"hasUserInit":true,
"valuep": [
{"type":"CONST","name":"2'h2","addr":"(EF)","loc":"d,25:43,25:44","dtypep":"(JB)"}
{"type":"CONST","name":"2'h2","addr":"(FF)","loc":"d,25:43,25:44","dtypep":"(KB)"}
]},
{"type":"VAR","name":"t.cell2.clk","addr":"(QB)","loc":"d,62:11,62:14","dtypep":"(N)","origName":"clk","verilogName":"clk","direction":"NONE","declDirection":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"t.cell2.d","addr":"(SB)","loc":"d,63:17,63:18","dtypep":"(L)","origName":"d","verilogName":"d","direction":"NONE","declDirection":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"t.cell2.q","addr":"(UB)","loc":"d,64:23,64:24","dtypep":"(L)","origName":"q","verilogName":"q","direction":"NONE","declDirection":"OUTPUT","icoMaybeWritten":true,"lifetime":"VSTATICI","varType":"WIRE","dtypeName":"logic"},
{"type":"VAR","name":"t.cell1.WIDTH","addr":"(XB)","loc":"d,48:15,48:20","dtypep":"(WB)","origName":"WIDTH","verilogName":"WIDTH","direction":"NONE","declDirection":"NONE","isConst":true,"lifetime":"VSTATICI","varType":"GPARAM","dtypeName":"logic","isGParam":true,"isParam":true,"hasUserInit":true,
{"type":"VAR","name":"t.cell2.clk","addr":"(RB)","loc":"d,62:11,62:14","dtypep":"(N)","origName":"clk","verilogName":"clk","direction":"NONE","declDirection":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"t.cell2.d","addr":"(TB)","loc":"d,63:17,63:18","dtypep":"(L)","origName":"d","verilogName":"d","direction":"NONE","declDirection":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"t.cell2.q","addr":"(VB)","loc":"d,64:23,64:24","dtypep":"(L)","origName":"q","verilogName":"q","direction":"NONE","declDirection":"OUTPUT","icoMaybeWritten":true,"lifetime":"VSTATICI","varType":"WIRE","dtypeName":"logic"},
{"type":"VAR","name":"t.cell1.WIDTH","addr":"(YB)","loc":"d,48:15,48:20","dtypep":"(XB)","origName":"WIDTH","verilogName":"WIDTH","direction":"NONE","declDirection":"NONE","isConst":true,"lifetime":"VSTATICI","varType":"GPARAM","dtypeName":"logic","isGParam":true,"isParam":true,"hasUserInit":true,
"valuep": [
{"type":"CONST","name":"32'sh4","addr":"(FF)","loc":"d,32:14,32:15","dtypep":"(GF)"}
{"type":"CONST","name":"32'sh4","addr":"(GF)","loc":"d,32:14,32:15","dtypep":"(HF)"}
]},
{"type":"VAR","name":"t.cell1.clk","addr":"(ZB)","loc":"d,50:11,50:14","dtypep":"(N)","origName":"clk","verilogName":"clk","direction":"NONE","declDirection":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"t.cell1.d","addr":"(BC)","loc":"d,51:23,51:24","dtypep":"(L)","origName":"d","verilogName":"d","direction":"NONE","declDirection":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"t.cell1.q","addr":"(DC)","loc":"d,52:30,52:31","dtypep":"(L)","origName":"q","verilogName":"q","direction":"NONE","declDirection":"OUTPUT","icoMaybeWritten":true,"lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"t.cell1.IGNORED","addr":"(FC)","loc":"d,55:14,55:21","dtypep":"(WB)","origName":"IGNORED","verilogName":"IGNORED","direction":"NONE","declDirection":"NONE","isConst":true,"lifetime":"VSTATICI","varType":"LPARAM","dtypeName":"logic","isParam":true,"hasUserInit":true,
{"type":"VAR","name":"t.cell1.clk","addr":"(AC)","loc":"d,50:11,50:14","dtypep":"(N)","origName":"clk","verilogName":"clk","direction":"NONE","declDirection":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"t.cell1.d","addr":"(CC)","loc":"d,51:23,51:24","dtypep":"(L)","origName":"d","verilogName":"d","direction":"NONE","declDirection":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"t.cell1.q","addr":"(EC)","loc":"d,52:30,52:31","dtypep":"(L)","origName":"q","verilogName":"q","direction":"NONE","declDirection":"OUTPUT","icoMaybeWritten":true,"lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"t.cell1.IGNORED","addr":"(GC)","loc":"d,55:14,55:21","dtypep":"(XB)","origName":"IGNORED","verilogName":"IGNORED","direction":"NONE","declDirection":"NONE","isConst":true,"lifetime":"VSTATICI","varType":"LPARAM","dtypeName":"logic","isParam":true,"hasUserInit":true,
"valuep": [
{"type":"CONST","name":"32'sh1","addr":"(HF)","loc":"d,55:24,55:25","dtypep":"(GF)"}
{"type":"CONST","name":"32'sh1","addr":"(IF)","loc":"d,55:24,55:25","dtypep":"(HF)"}
]}
]},
{"type":"PACKAGE","name":"$unit","addr":"(E)","loc":"a,0:0,0:0","origName":"__024unit","verilogName":"\\$unit ","level":3,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps"}
{"type":"PACKAGE","name":"$unit","addr":"(E)","loc":"a,0:0,0:0","origName":"__024unit","verilogName":"\\$unit ","level":3,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps"},
{"type":"PACKAGE","name":"__Vconstpool","addr":"(D)","loc":"a,0:0,0:0","origName":"__Vconstpool","verilogName":"__Vconstpool","level":3,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps",
"stmtsp": [
{"type":"SCOPE","name":"__Vconstpool","addr":"(JF)","loc":"a,0:0,0:0","aboveScopep":"(R)","aboveCellp":"(Q)","modp":"(D)"}
]}
],
"miscsp": [
{"type":"TYPETABLE","addr":"(C)","loc":"a,0:0,0:0",
"typesp": [
{"type":"BASICDTYPE","name":"bit","addr":"(CD)","loc":"d,23:35,23:40","dtypep":"(CD)","keyword":"bit","range":"1:0","generic":true},
{"type":"BASICDTYPE","name":"bit","addr":"(DD)","loc":"d,23:35,23:40","dtypep":"(DD)","keyword":"bit","range":"1:0","generic":true},
{"type":"BASICDTYPE","name":"logic","addr":"(N)","loc":"d,27:32,27:34","dtypep":"(N)","keyword":"logic","generic":true},
{"type":"BASICDTYPE","name":"logic","addr":"(JB)","loc":"d,23:14,23:19","dtypep":"(JB)","keyword":"logic","range":"1:0","generic":true},
{"type":"BASICDTYPE","name":"logic","addr":"(WB)","loc":"d,48:15,48:20","dtypep":"(WB)","keyword":"logic","range":"31:0","generic":true,"signed":true},
{"type":"BASICDTYPE","name":"logic","addr":"(KB)","loc":"d,23:14,23:19","dtypep":"(KB)","keyword":"logic","range":"1:0","generic":true},
{"type":"BASICDTYPE","name":"logic","addr":"(XB)","loc":"d,48:15,48:20","dtypep":"(XB)","keyword":"logic","range":"31:0","generic":true,"signed":true},
{"type":"BASICDTYPE","name":"logic","addr":"(L)","loc":"d,16:15,16:16","dtypep":"(L)","keyword":"logic","range":"3:0","generic":true},
{"type":"BASICDTYPE","name":"logic","addr":"(OC)","loc":"d,27:26,27:27","dtypep":"(OC)","keyword":"logic","range":"1:0","generic":true,"signed":true},
{"type":"BASICDTYPE","name":"bit","addr":"(JC)","loc":"d,27:32,27:34","dtypep":"(JC)","keyword":"bit","generic":true},
{"type":"BASICDTYPE","name":"bit","addr":"(GF)","loc":"d,29:48,29:49","dtypep":"(GF)","keyword":"bit","range":"31:0","generic":true,"signed":true}
]},
{"type":"CONSTPOOL","addr":"(D)","loc":"a,0:0,0:0",
"modulep": [
{"type":"MODULE","name":"@CONST-POOL@","addr":"(IF)","loc":"a,0:0,0:0","origName":"@CONST-POOL@","verilogName":"@CONST-POOL@","unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"NONE",
"stmtsp": [
{"type":"SCOPE","name":"@CONST-POOL@","addr":"(JF)","loc":"a,0:0,0:0","modp":"(IF)"}
]}
{"type":"BASICDTYPE","name":"logic","addr":"(PC)","loc":"d,27:26,27:27","dtypep":"(PC)","keyword":"logic","range":"1:0","generic":true,"signed":true},
{"type":"BASICDTYPE","name":"bit","addr":"(KC)","loc":"d,27:32,27:34","dtypep":"(KC)","keyword":"bit","generic":true},
{"type":"BASICDTYPE","name":"bit","addr":"(HF)","loc":"d,29:48,29:49","dtypep":"(HF)","keyword":"bit","range":"31:0","generic":true,"signed":true}
]}
]}
@@ -1,4 +1,4 @@
{"type":"NETLIST","name":"$root","addr":"(B)","loc":"a,0:0,0:0","timeunit":"1ps","timeprecision":"1ps","resolvedTopModuleName":"top","typeTablep":"(C)","constPoolp":"(D)","dollarUnitPkgp":"(E)","topScopep":"(F)",
{"type":"NETLIST","name":"$root","addr":"(B)","loc":"a,0:0,0:0","timeunit":"1ps","timeprecision":"1ps","resolvedTopModuleName":"top","typeTablep":"(C)","constPoolPkgp":"(D)","dollarUnitPkgp":"(E)","topScopep":"(F)",
"modulesp": [
{"type":"MODULE","name":"$root","addr":"(G)","loc":"d,11:8,11:11","origName":"$root","verilogName":"$root","level":1,"depth":1,"modPublic":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps",
"inlinesp": [
@@ -8,52 +8,50 @@
"stmtsp": [
{"type":"VAR","name":"i_clk","addr":"(J)","loc":"d,11:24,11:29","dtypep":"(K)","origName":"i_clk","verilogName":"i_clk","isPrimaryIO":true,"direction":"INPUT","declDirection":"INPUT","isSigPublic":true,"lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"CELL","name":"$unit","addr":"(L)","loc":"a,0:0,0:0","modName":"__024unit","origName":"__024unit","verilogName":"\\$unit ","modp":"(E)"},
{"type":"CELL","name":"__Vconstpool","addr":"(M)","loc":"a,0:0,0:0","modName":"__Vconstpool","origName":"__Vconstpool","verilogName":"__Vconstpool","modp":"(D)"},
{"type":"TOPSCOPE","addr":"(F)","loc":"d,11:8,11:11",
"scopep": [
{"type":"SCOPE","name":"TOP","addr":"(M)","loc":"d,11:8,11:11","modp":"(G)",
{"type":"SCOPE","name":"TOP","addr":"(N)","loc":"d,11:8,11:11","modp":"(G)",
"varsp": [
{"type":"VARSCOPE","name":"i_clk","addr":"(N)","loc":"d,11:24,11:29","dtypep":"(K)","isTrace":true,"scopep":"(M)","varp":"(J)"},
{"type":"VARSCOPE","name":"top.i_clk","addr":"(O)","loc":"d,11:24,11:29","dtypep":"(K)","isTrace":true,"scopep":"(M)","varp":"(P)"},
{"type":"VARSCOPE","name":"top.f.i_clk","addr":"(Q)","loc":"d,7:24,7:29","dtypep":"(K)","scopep":"(M)","varp":"(R)"}
{"type":"VARSCOPE","name":"i_clk","addr":"(O)","loc":"d,11:24,11:29","dtypep":"(K)","isTrace":true,"scopep":"(N)","varp":"(J)"},
{"type":"VARSCOPE","name":"top.i_clk","addr":"(P)","loc":"d,11:24,11:29","dtypep":"(K)","isTrace":true,"scopep":"(N)","varp":"(Q)"},
{"type":"VARSCOPE","name":"top.f.i_clk","addr":"(R)","loc":"d,7:24,7:29","dtypep":"(K)","scopep":"(N)","varp":"(S)"}
],
"blocksp": [
{"type":"ALWAYS","addr":"(S)","loc":"d,11:24,11:29","keyword":"cont_assign",
{"type":"ALWAYS","addr":"(T)","loc":"d,11:24,11:29","keyword":"cont_assign",
"stmtsp": [
{"type":"ASSIGNW","addr":"(T)","loc":"d,11:24,11:29","dtypep":"(K)",
{"type":"ASSIGNW","addr":"(U)","loc":"d,11:24,11:29","dtypep":"(K)",
"rhsp": [
{"type":"VARREF","name":"i_clk","addr":"(U)","loc":"d,11:24,11:29","dtypep":"(K)","access":"RD","varp":"(J)","varScopep":"(N)"}
{"type":"VARREF","name":"i_clk","addr":"(V)","loc":"d,11:24,11:29","dtypep":"(K)","access":"RD","varp":"(J)","varScopep":"(O)"}
],
"lhsp": [
{"type":"VARREF","name":"top.i_clk","addr":"(V)","loc":"d,11:24,11:29","dtypep":"(K)","access":"WR","varp":"(P)","varScopep":"(O)"}
{"type":"VARREF","name":"top.i_clk","addr":"(W)","loc":"d,11:24,11:29","dtypep":"(K)","access":"WR","varp":"(Q)","varScopep":"(P)"}
]}
]},
{"type":"ALWAYS","addr":"(W)","loc":"d,7:24,7:29","keyword":"cont_assign",
{"type":"ALWAYS","addr":"(X)","loc":"d,7:24,7:29","keyword":"cont_assign",
"stmtsp": [
{"type":"ASSIGNW","addr":"(X)","loc":"d,7:24,7:29","dtypep":"(K)",
{"type":"ASSIGNW","addr":"(Y)","loc":"d,7:24,7:29","dtypep":"(K)",
"rhsp": [
{"type":"VARREF","name":"i_clk","addr":"(Y)","loc":"d,7:24,7:29","dtypep":"(K)","access":"RD","varp":"(J)","varScopep":"(N)"}
{"type":"VARREF","name":"i_clk","addr":"(Z)","loc":"d,7:24,7:29","dtypep":"(K)","access":"RD","varp":"(J)","varScopep":"(O)"}
],
"lhsp": [
{"type":"VARREF","name":"top.f.i_clk","addr":"(Z)","loc":"d,7:24,7:29","dtypep":"(K)","access":"WR","varp":"(R)","varScopep":"(Q)"}
{"type":"VARREF","name":"top.f.i_clk","addr":"(AB)","loc":"d,7:24,7:29","dtypep":"(K)","access":"WR","varp":"(S)","varScopep":"(R)"}
]}
]}
]}
]},
{"type":"VAR","name":"top.i_clk","addr":"(P)","loc":"d,11:24,11:29","dtypep":"(K)","origName":"i_clk","verilogName":"i_clk","direction":"NONE","declDirection":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"top.f.i_clk","addr":"(R)","loc":"d,7:24,7:29","dtypep":"(K)","origName":"i_clk","verilogName":"i_clk","direction":"NONE","declDirection":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"}
{"type":"VAR","name":"top.i_clk","addr":"(Q)","loc":"d,11:24,11:29","dtypep":"(K)","origName":"i_clk","verilogName":"i_clk","direction":"NONE","declDirection":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"top.f.i_clk","addr":"(S)","loc":"d,7:24,7:29","dtypep":"(K)","origName":"i_clk","verilogName":"i_clk","direction":"NONE","declDirection":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"}
]},
{"type":"PACKAGE","name":"$unit","addr":"(E)","loc":"a,0:0,0:0","origName":"__024unit","verilogName":"\\$unit ","level":3,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps"}
{"type":"PACKAGE","name":"$unit","addr":"(E)","loc":"a,0:0,0:0","origName":"__024unit","verilogName":"\\$unit ","level":3,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps"},
{"type":"PACKAGE","name":"__Vconstpool","addr":"(D)","loc":"a,0:0,0:0","origName":"__Vconstpool","verilogName":"__Vconstpool","level":3,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps",
"stmtsp": [
{"type":"SCOPE","name":"__Vconstpool","addr":"(BB)","loc":"a,0:0,0:0","aboveScopep":"(N)","aboveCellp":"(M)","modp":"(D)"}
]}
],
"miscsp": [
{"type":"TYPETABLE","addr":"(C)","loc":"a,0:0,0:0",
"typesp": [
{"type":"BASICDTYPE","name":"logic","addr":"(K)","loc":"d,11:18,11:23","dtypep":"(K)","keyword":"logic","generic":true}
]},
{"type":"CONSTPOOL","addr":"(D)","loc":"a,0:0,0:0",
"modulep": [
{"type":"MODULE","name":"@CONST-POOL@","addr":"(AB)","loc":"a,0:0,0:0","origName":"@CONST-POOL@","verilogName":"@CONST-POOL@","unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"NONE",
"stmtsp": [
{"type":"SCOPE","name":"@CONST-POOL@","addr":"(BB)","loc":"a,0:0,0:0","modp":"(AB)"}
]}
]}
]}
+21 -23
View File
@@ -1,4 +1,4 @@
{"type":"NETLIST","name":"$root","addr":"(B)","loc":"a,0:0,0:0","timeunit":"1ps","timeprecision":"1ps","resolvedTopModuleName":"top","typeTablep":"(C)","constPoolp":"(D)","dollarUnitPkgp":"(E)","topScopep":"(F)",
{"type":"NETLIST","name":"$root","addr":"(B)","loc":"a,0:0,0:0","timeunit":"1ps","timeprecision":"1ps","resolvedTopModuleName":"top","typeTablep":"(C)","constPoolPkgp":"(D)","dollarUnitPkgp":"(E)","topScopep":"(F)",
"modulesp": [
{"type":"MODULE","name":"$root","addr":"(G)","loc":"d,11:8,11:11","origName":"$root","verilogName":"$root","level":1,"depth":1,"modPublic":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps",
"inlinesp": [
@@ -8,52 +8,50 @@
"stmtsp": [
{"type":"VAR","name":"i_clk","addr":"(J)","loc":"d,11:24,11:29","dtypep":"(K)","origName":"i_clk","verilogName":"i_clk","isPrimaryIO":true,"direction":"INPUT","declDirection":"INPUT","isSigPublic":true,"lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"CELL","name":"$unit","addr":"(L)","loc":"a,0:0,0:0","modName":"__024unit","origName":"__024unit","verilogName":"\\$unit ","modp":"(E)"},
{"type":"CELL","name":"__Vconstpool","addr":"(M)","loc":"a,0:0,0:0","modName":"__Vconstpool","origName":"__Vconstpool","verilogName":"__Vconstpool","modp":"(D)"},
{"type":"TOPSCOPE","addr":"(F)","loc":"d,11:8,11:11",
"scopep": [
{"type":"SCOPE","name":"TOP","addr":"(M)","loc":"d,11:8,11:11","modp":"(G)",
{"type":"SCOPE","name":"TOP","addr":"(N)","loc":"d,11:8,11:11","modp":"(G)",
"varsp": [
{"type":"VARSCOPE","name":"i_clk","addr":"(N)","loc":"d,11:24,11:29","dtypep":"(K)","isTrace":true,"scopep":"(M)","varp":"(J)"},
{"type":"VARSCOPE","name":"top.i_clk","addr":"(O)","loc":"d,11:24,11:29","dtypep":"(K)","isTrace":true,"scopep":"(M)","varp":"(P)"},
{"type":"VARSCOPE","name":"top.f.i_clk","addr":"(Q)","loc":"d,7:24,7:29","dtypep":"(K)","scopep":"(M)","varp":"(R)"}
{"type":"VARSCOPE","name":"i_clk","addr":"(O)","loc":"d,11:24,11:29","dtypep":"(K)","isTrace":true,"scopep":"(N)","varp":"(J)"},
{"type":"VARSCOPE","name":"top.i_clk","addr":"(P)","loc":"d,11:24,11:29","dtypep":"(K)","isTrace":true,"scopep":"(N)","varp":"(Q)"},
{"type":"VARSCOPE","name":"top.f.i_clk","addr":"(R)","loc":"d,7:24,7:29","dtypep":"(K)","scopep":"(N)","varp":"(S)"}
],
"blocksp": [
{"type":"ALWAYS","addr":"(S)","loc":"d,11:24,11:29","keyword":"cont_assign",
{"type":"ALWAYS","addr":"(T)","loc":"d,11:24,11:29","keyword":"cont_assign",
"stmtsp": [
{"type":"ASSIGNW","addr":"(T)","loc":"d,11:24,11:29","dtypep":"(K)",
{"type":"ASSIGNW","addr":"(U)","loc":"d,11:24,11:29","dtypep":"(K)",
"rhsp": [
{"type":"VARREF","name":"i_clk","addr":"(U)","loc":"d,11:24,11:29","dtypep":"(K)","access":"RD","varp":"(J)","varScopep":"(N)"}
{"type":"VARREF","name":"i_clk","addr":"(V)","loc":"d,11:24,11:29","dtypep":"(K)","access":"RD","varp":"(J)","varScopep":"(O)"}
],
"lhsp": [
{"type":"VARREF","name":"top.i_clk","addr":"(V)","loc":"d,11:24,11:29","dtypep":"(K)","access":"WR","varp":"(P)","varScopep":"(O)"}
{"type":"VARREF","name":"top.i_clk","addr":"(W)","loc":"d,11:24,11:29","dtypep":"(K)","access":"WR","varp":"(Q)","varScopep":"(P)"}
]}
]},
{"type":"ALWAYS","addr":"(W)","loc":"d,7:24,7:29","keyword":"cont_assign",
{"type":"ALWAYS","addr":"(X)","loc":"d,7:24,7:29","keyword":"cont_assign",
"stmtsp": [
{"type":"ASSIGNW","addr":"(X)","loc":"d,7:24,7:29","dtypep":"(K)",
{"type":"ASSIGNW","addr":"(Y)","loc":"d,7:24,7:29","dtypep":"(K)",
"rhsp": [
{"type":"VARREF","name":"i_clk","addr":"(Y)","loc":"d,7:24,7:29","dtypep":"(K)","access":"RD","varp":"(J)","varScopep":"(N)"}
{"type":"VARREF","name":"i_clk","addr":"(Z)","loc":"d,7:24,7:29","dtypep":"(K)","access":"RD","varp":"(J)","varScopep":"(O)"}
],
"lhsp": [
{"type":"VARREF","name":"top.f.i_clk","addr":"(Z)","loc":"d,7:24,7:29","dtypep":"(K)","access":"WR","varp":"(R)","varScopep":"(Q)"}
{"type":"VARREF","name":"top.f.i_clk","addr":"(AB)","loc":"d,7:24,7:29","dtypep":"(K)","access":"WR","varp":"(S)","varScopep":"(R)"}
]}
]}
]}
]},
{"type":"VAR","name":"top.i_clk","addr":"(P)","loc":"d,11:24,11:29","dtypep":"(K)","origName":"i_clk","verilogName":"i_clk","direction":"NONE","declDirection":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"top.f.i_clk","addr":"(R)","loc":"d,7:24,7:29","dtypep":"(K)","origName":"i_clk","verilogName":"i_clk","direction":"NONE","declDirection":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"}
{"type":"VAR","name":"top.i_clk","addr":"(Q)","loc":"d,11:24,11:29","dtypep":"(K)","origName":"i_clk","verilogName":"i_clk","direction":"NONE","declDirection":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"top.f.i_clk","addr":"(S)","loc":"d,7:24,7:29","dtypep":"(K)","origName":"i_clk","verilogName":"i_clk","direction":"NONE","declDirection":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"}
]},
{"type":"PACKAGE","name":"$unit","addr":"(E)","loc":"a,0:0,0:0","origName":"__024unit","verilogName":"\\$unit ","level":3,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps"}
{"type":"PACKAGE","name":"$unit","addr":"(E)","loc":"a,0:0,0:0","origName":"__024unit","verilogName":"\\$unit ","level":3,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps"},
{"type":"PACKAGE","name":"__Vconstpool","addr":"(D)","loc":"a,0:0,0:0","origName":"__Vconstpool","verilogName":"__Vconstpool","level":3,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps",
"stmtsp": [
{"type":"SCOPE","name":"__Vconstpool","addr":"(BB)","loc":"a,0:0,0:0","aboveScopep":"(N)","aboveCellp":"(M)","modp":"(D)"}
]}
],
"miscsp": [
{"type":"TYPETABLE","addr":"(C)","loc":"a,0:0,0:0",
"typesp": [
{"type":"BASICDTYPE","name":"logic","addr":"(K)","loc":"d,11:18,11:23","dtypep":"(K)","keyword":"logic","generic":true}
]},
{"type":"CONSTPOOL","addr":"(D)","loc":"a,0:0,0:0",
"modulep": [
{"type":"MODULE","name":"@CONST-POOL@","addr":"(AB)","loc":"a,0:0,0:0","origName":"@CONST-POOL@","verilogName":"@CONST-POOL@","unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"NONE",
"stmtsp": [
{"type":"SCOPE","name":"@CONST-POOL@","addr":"(BB)","loc":"a,0:0,0:0","modp":"(AB)"}
]}
]}
]}
+159 -161
View File
@@ -1,4 +1,4 @@
{"type":"NETLIST","name":"$root","addr":"(B)","loc":"a,0:0,0:0","timeunit":"1ps","timeprecision":"1ps","resolvedTopModuleName":"vlvbound_test","typeTablep":"(C)","constPoolp":"(D)","dollarUnitPkgp":"(E)","topScopep":"(F)",
{"type":"NETLIST","name":"$root","addr":"(B)","loc":"a,0:0,0:0","timeunit":"1ps","timeprecision":"1ps","resolvedTopModuleName":"vlvbound_test","typeTablep":"(C)","constPoolPkgp":"(D)","dollarUnitPkgp":"(E)","topScopep":"(F)",
"modulesp": [
{"type":"MODULE","name":"$root","addr":"(G)","loc":"d,7:8,7:21","origName":"$root","verilogName":"$root","level":1,"depth":1,"modPublic":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps",
"inlinesp": [
@@ -10,351 +10,349 @@
{"type":"VAR","name":"o_a","addr":"(L)","loc":"d,10:24,10:27","dtypep":"(M)","origName":"o_a","verilogName":"o_a","isPrimaryIO":true,"direction":"OUTPUT","declDirection":"OUTPUT","isSigPublic":true,"icoMaybeWritten":true,"lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"o_b","addr":"(N)","loc":"d,11:24,11:27","dtypep":"(M)","origName":"o_b","verilogName":"o_b","isPrimaryIO":true,"direction":"OUTPUT","declDirection":"OUTPUT","isSigPublic":true,"icoMaybeWritten":true,"lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"CELL","name":"$unit","addr":"(O)","loc":"a,0:0,0:0","modName":"__024unit","origName":"__024unit","verilogName":"\\$unit ","modp":"(E)"},
{"type":"CELL","name":"__Vconstpool","addr":"(P)","loc":"a,0:0,0:0","modName":"__Vconstpool","origName":"__Vconstpool","verilogName":"__Vconstpool","modp":"(D)"},
{"type":"TOPSCOPE","addr":"(F)","loc":"d,7:8,7:21",
"scopep": [
{"type":"SCOPE","name":"TOP","addr":"(P)","loc":"d,7:8,7:21","modp":"(G)",
{"type":"SCOPE","name":"TOP","addr":"(Q)","loc":"d,7:8,7:21","modp":"(G)",
"varsp": [
{"type":"VARSCOPE","name":"i_a","addr":"(Q)","loc":"d,8:24,8:27","dtypep":"(J)","isTrace":true,"scopep":"(P)","varp":"(I)"},
{"type":"VARSCOPE","name":"i_b","addr":"(R)","loc":"d,9:24,9:27","dtypep":"(J)","isTrace":true,"scopep":"(P)","varp":"(K)"},
{"type":"VARSCOPE","name":"o_a","addr":"(S)","loc":"d,10:24,10:27","dtypep":"(M)","isTrace":true,"scopep":"(P)","varp":"(L)"},
{"type":"VARSCOPE","name":"o_b","addr":"(T)","loc":"d,11:24,11:27","dtypep":"(M)","isTrace":true,"scopep":"(P)","varp":"(N)"},
{"type":"VARSCOPE","name":"vlvbound_test.i_a","addr":"(U)","loc":"d,8:24,8:27","dtypep":"(J)","isTrace":true,"scopep":"(P)","varp":"(V)"},
{"type":"VARSCOPE","name":"vlvbound_test.i_b","addr":"(W)","loc":"d,9:24,9:27","dtypep":"(J)","isTrace":true,"scopep":"(P)","varp":"(X)"},
{"type":"VARSCOPE","name":"vlvbound_test.o_a","addr":"(Y)","loc":"d,10:24,10:27","dtypep":"(M)","isTrace":true,"scopep":"(P)","varp":"(Z)"},
{"type":"VARSCOPE","name":"vlvbound_test.o_b","addr":"(AB)","loc":"d,11:24,11:27","dtypep":"(M)","isTrace":true,"scopep":"(P)","varp":"(BB)"},
{"type":"VARSCOPE","name":"__Vfunc_vlvbound_test.foo__0__Vfuncout","addr":"(CB)","loc":"d,14:34,14:37","dtypep":"(M)","isTrace":true,"scopep":"(P)","varp":"(DB)"},
{"type":"VARSCOPE","name":"__Vfunc_vlvbound_test.foo__0__val","addr":"(EB)","loc":"d,14:57,14:60","dtypep":"(J)","isTrace":true,"scopep":"(P)","varp":"(FB)"},
{"type":"VARSCOPE","name":"__Vfunc_vlvbound_test.foo__0__ret","addr":"(GB)","loc":"d,15:17,15:20","dtypep":"(M)","isTrace":true,"scopep":"(P)","varp":"(HB)"},
{"type":"VARSCOPE","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(IB)","loc":"d,16:13,16:14","dtypep":"(JB)","isTrace":true,"scopep":"(P)","varp":"(KB)"},
{"type":"VARSCOPE","name":"__Vfunc_vlvbound_test.foo__1__Vfuncout","addr":"(LB)","loc":"d,14:34,14:37","dtypep":"(M)","isTrace":true,"scopep":"(P)","varp":"(MB)"},
{"type":"VARSCOPE","name":"__Vfunc_vlvbound_test.foo__1__val","addr":"(NB)","loc":"d,14:57,14:60","dtypep":"(J)","isTrace":true,"scopep":"(P)","varp":"(OB)"},
{"type":"VARSCOPE","name":"__Vfunc_vlvbound_test.foo__1__ret","addr":"(PB)","loc":"d,15:17,15:20","dtypep":"(M)","isTrace":true,"scopep":"(P)","varp":"(QB)"},
{"type":"VARSCOPE","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(RB)","loc":"d,16:13,16:14","dtypep":"(JB)","isTrace":true,"scopep":"(P)","varp":"(SB)"}
{"type":"VARSCOPE","name":"i_a","addr":"(R)","loc":"d,8:24,8:27","dtypep":"(J)","isTrace":true,"scopep":"(Q)","varp":"(I)"},
{"type":"VARSCOPE","name":"i_b","addr":"(S)","loc":"d,9:24,9:27","dtypep":"(J)","isTrace":true,"scopep":"(Q)","varp":"(K)"},
{"type":"VARSCOPE","name":"o_a","addr":"(T)","loc":"d,10:24,10:27","dtypep":"(M)","isTrace":true,"scopep":"(Q)","varp":"(L)"},
{"type":"VARSCOPE","name":"o_b","addr":"(U)","loc":"d,11:24,11:27","dtypep":"(M)","isTrace":true,"scopep":"(Q)","varp":"(N)"},
{"type":"VARSCOPE","name":"vlvbound_test.i_a","addr":"(V)","loc":"d,8:24,8:27","dtypep":"(J)","isTrace":true,"scopep":"(Q)","varp":"(W)"},
{"type":"VARSCOPE","name":"vlvbound_test.i_b","addr":"(X)","loc":"d,9:24,9:27","dtypep":"(J)","isTrace":true,"scopep":"(Q)","varp":"(Y)"},
{"type":"VARSCOPE","name":"vlvbound_test.o_a","addr":"(Z)","loc":"d,10:24,10:27","dtypep":"(M)","isTrace":true,"scopep":"(Q)","varp":"(AB)"},
{"type":"VARSCOPE","name":"vlvbound_test.o_b","addr":"(BB)","loc":"d,11:24,11:27","dtypep":"(M)","isTrace":true,"scopep":"(Q)","varp":"(CB)"},
{"type":"VARSCOPE","name":"__Vfunc_vlvbound_test.foo__0__Vfuncout","addr":"(DB)","loc":"d,14:34,14:37","dtypep":"(M)","isTrace":true,"scopep":"(Q)","varp":"(EB)"},
{"type":"VARSCOPE","name":"__Vfunc_vlvbound_test.foo__0__val","addr":"(FB)","loc":"d,14:57,14:60","dtypep":"(J)","isTrace":true,"scopep":"(Q)","varp":"(GB)"},
{"type":"VARSCOPE","name":"__Vfunc_vlvbound_test.foo__0__ret","addr":"(HB)","loc":"d,15:17,15:20","dtypep":"(M)","isTrace":true,"scopep":"(Q)","varp":"(IB)"},
{"type":"VARSCOPE","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(JB)","loc":"d,16:13,16:14","dtypep":"(KB)","isTrace":true,"scopep":"(Q)","varp":"(LB)"},
{"type":"VARSCOPE","name":"__Vfunc_vlvbound_test.foo__1__Vfuncout","addr":"(MB)","loc":"d,14:34,14:37","dtypep":"(M)","isTrace":true,"scopep":"(Q)","varp":"(NB)"},
{"type":"VARSCOPE","name":"__Vfunc_vlvbound_test.foo__1__val","addr":"(OB)","loc":"d,14:57,14:60","dtypep":"(J)","isTrace":true,"scopep":"(Q)","varp":"(PB)"},
{"type":"VARSCOPE","name":"__Vfunc_vlvbound_test.foo__1__ret","addr":"(QB)","loc":"d,15:17,15:20","dtypep":"(M)","isTrace":true,"scopep":"(Q)","varp":"(RB)"},
{"type":"VARSCOPE","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(SB)","loc":"d,16:13,16:14","dtypep":"(KB)","isTrace":true,"scopep":"(Q)","varp":"(TB)"}
],
"blocksp": [
{"type":"ALWAYS","addr":"(TB)","loc":"d,23:14,23:15","keyword":"cont_assign",
{"type":"ALWAYS","addr":"(UB)","loc":"d,23:14,23:15","keyword":"cont_assign",
"stmtsp": [
{"type":"COMMENT","name":"Function: foo","addr":"(UB)","loc":"d,23:16,23:19","showAt":true},
{"type":"ASSIGN","addr":"(VB)","loc":"d,23:20,23:23","dtypep":"(J)",
{"type":"COMMENT","name":"Function: foo","addr":"(VB)","loc":"d,23:16,23:19","showAt":true},
{"type":"ASSIGN","addr":"(WB)","loc":"d,23:20,23:23","dtypep":"(J)",
"rhsp": [
{"type":"VARREF","name":"i_a","addr":"(WB)","loc":"d,23:20,23:23","dtypep":"(J)","access":"RD","varp":"(I)","varScopep":"(Q)"}
{"type":"VARREF","name":"i_a","addr":"(XB)","loc":"d,23:20,23:23","dtypep":"(J)","access":"RD","varp":"(I)","varScopep":"(R)"}
],
"lhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__val","addr":"(XB)","loc":"d,14:57,14:60","dtypep":"(J)","access":"WR","varp":"(FB)","varScopep":"(EB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__val","addr":"(YB)","loc":"d,14:57,14:60","dtypep":"(J)","access":"WR","varp":"(GB)","varScopep":"(FB)"}
]},
{"type":"ASSIGN","addr":"(YB)","loc":"d,14:34,14:37","dtypep":"(M)",
{"type":"ASSIGN","addr":"(ZB)","loc":"d,14:34,14:37","dtypep":"(M)",
"rhsp": [
{"type":"CRESET","addr":"(ZB)","loc":"d,14:34,14:37","dtypep":"(M)"}
{"type":"CRESET","addr":"(AC)","loc":"d,14:34,14:37","dtypep":"(M)"}
],
"lhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__Vfuncout","addr":"(AC)","loc":"d,14:34,14:37","dtypep":"(M)","access":"WR","varp":"(DB)","varScopep":"(CB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__Vfuncout","addr":"(BC)","loc":"d,14:34,14:37","dtypep":"(M)","access":"WR","varp":"(EB)","varScopep":"(DB)"}
]},
{"type":"ASSIGN","addr":"(BC)","loc":"d,15:17,15:20","dtypep":"(M)",
{"type":"ASSIGN","addr":"(CC)","loc":"d,15:17,15:20","dtypep":"(M)",
"rhsp": [
{"type":"CRESET","addr":"(CC)","loc":"d,15:17,15:20","dtypep":"(M)"}
{"type":"CRESET","addr":"(DC)","loc":"d,15:17,15:20","dtypep":"(M)"}
],
"lhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__ret","addr":"(DC)","loc":"d,15:17,15:20","dtypep":"(M)","access":"WR","varp":"(HB)","varScopep":"(GB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__ret","addr":"(EC)","loc":"d,15:17,15:20","dtypep":"(M)","access":"WR","varp":"(IB)","varScopep":"(HB)"}
]},
{"type":"ASSIGN","addr":"(EC)","loc":"d,16:13,16:14","dtypep":"(JB)",
{"type":"ASSIGN","addr":"(FC)","loc":"d,16:13,16:14","dtypep":"(KB)",
"rhsp": [
{"type":"CRESET","addr":"(FC)","loc":"d,16:13,16:14","dtypep":"(JB)"}
{"type":"CRESET","addr":"(GC)","loc":"d,16:13,16:14","dtypep":"(KB)"}
],
"lhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(GC)","loc":"d,16:13,16:14","dtypep":"(JB)","access":"WR","varp":"(KB)","varScopep":"(IB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(HC)","loc":"d,16:13,16:14","dtypep":"(KB)","access":"WR","varp":"(LB)","varScopep":"(JB)"}
]},
{"type":"ASSIGN","addr":"(HC)","loc":"d,17:12,17:13","dtypep":"(JB)",
{"type":"ASSIGN","addr":"(IC)","loc":"d,17:12,17:13","dtypep":"(KB)",
"rhsp": [
{"type":"CONST","name":"32'sh0","addr":"(IC)","loc":"d,17:14,17:15","dtypep":"(JC)"}
{"type":"CONST","name":"32'sh0","addr":"(JC)","loc":"d,17:14,17:15","dtypep":"(KC)"}
],
"lhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(KC)","loc":"d,17:10,17:11","dtypep":"(JB)","access":"WR","varp":"(KB)","varScopep":"(IB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(LC)","loc":"d,17:10,17:11","dtypep":"(KB)","access":"WR","varp":"(LB)","varScopep":"(JB)"}
]},
{"type":"LOOP","addr":"(LC)","loc":"d,17:5,17:8","unroll":"default",
{"type":"LOOP","addr":"(MC)","loc":"d,17:5,17:8","unroll":"default",
"stmtsp": [
{"type":"LOOPTEST","addr":"(MC)","loc":"d,17:17,17:18",
{"type":"LOOPTEST","addr":"(NC)","loc":"d,17:17,17:18",
"condp": [
{"type":"GTS","addr":"(NC)","loc":"d,17:19,17:20","dtypep":"(OC)",
{"type":"GTS","addr":"(OC)","loc":"d,17:19,17:20","dtypep":"(PC)",
"lhsp": [
{"type":"CONST","name":"32'sh7","addr":"(PC)","loc":"d,17:21,17:22","dtypep":"(JC)"}
{"type":"CONST","name":"32'sh7","addr":"(QC)","loc":"d,17:21,17:22","dtypep":"(KC)"}
],
"rhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(QC)","loc":"d,17:17,17:18","dtypep":"(JB)","access":"RD","varp":"(KB)","varScopep":"(IB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(RC)","loc":"d,17:17,17:18","dtypep":"(KB)","access":"RD","varp":"(LB)","varScopep":"(JB)"}
]}
]},
{"type":"ASSIGN","addr":"(RC)","loc":"d,18:14,18:15","dtypep":"(SC)",
{"type":"ASSIGN","addr":"(SC)","loc":"d,18:14,18:15","dtypep":"(TC)",
"rhsp": [
{"type":"EQ","addr":"(TC)","loc":"d,18:29,18:31","dtypep":"(OC)",
{"type":"EQ","addr":"(UC)","loc":"d,18:29,18:31","dtypep":"(PC)",
"lhsp": [
{"type":"CONST","name":"2'h0","addr":"(UC)","loc":"d,18:32,18:37","dtypep":"(VC)"}
{"type":"CONST","name":"2'h0","addr":"(VC)","loc":"d,18:32,18:37","dtypep":"(WC)"}
],
"rhsp": [
{"type":"SEL","addr":"(WC)","loc":"d,18:20,18:21","dtypep":"(XC)","widthConst":2,"declRange":"[15:0]","declElWidth":1,
{"type":"SEL","addr":"(XC)","loc":"d,18:20,18:21","dtypep":"(YC)","widthConst":2,"declRange":"[15:0]","declElWidth":1,
"fromp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__val","addr":"(YC)","loc":"d,18:17,18:20","dtypep":"(J)","access":"RD","varp":"(FB)","varScopep":"(EB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__val","addr":"(ZC)","loc":"d,18:17,18:20","dtypep":"(J)","access":"RD","varp":"(GB)","varScopep":"(FB)"}
],
"lsbp": [
{"type":"SEL","addr":"(ZC)","loc":"d,18:22,18:23","dtypep":"(AD)","widthConst":4,
{"type":"SEL","addr":"(AD)","loc":"d,18:22,18:23","dtypep":"(BD)","widthConst":4,
"fromp": [
{"type":"MULS","addr":"(BD)","loc":"d,18:22,18:23","dtypep":"(CD)",
{"type":"MULS","addr":"(CD)","loc":"d,18:22,18:23","dtypep":"(DD)",
"lhsp": [
{"type":"CONST","name":"32'sh2","addr":"(DD)","loc":"d,18:23,18:24","dtypep":"(JC)"}
{"type":"CONST","name":"32'sh2","addr":"(ED)","loc":"d,18:23,18:24","dtypep":"(KC)"}
],
"rhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(ED)","loc":"d,18:21,18:22","dtypep":"(JB)","access":"RD","varp":"(KB)","varScopep":"(IB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(FD)","loc":"d,18:21,18:22","dtypep":"(KB)","access":"RD","varp":"(LB)","varScopep":"(JB)"}
]}
],
"lsbp": [
{"type":"CONST","name":"32'h0","addr":"(FD)","loc":"d,18:22,18:23","dtypep":"(GD)"}
{"type":"CONST","name":"32'h0","addr":"(GD)","loc":"d,18:22,18:23","dtypep":"(HD)"}
]}
]}
]}
],
"lhsp": [
{"type":"SEL","addr":"(HD)","loc":"d,18:10,18:11","dtypep":"(SC)","widthConst":1,"declRange":"[6:0]","declElWidth":1,
{"type":"SEL","addr":"(ID)","loc":"d,18:10,18:11","dtypep":"(TC)","widthConst":1,"declRange":"[6:0]","declElWidth":1,
"fromp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__ret","addr":"(ID)","loc":"d,18:7,18:10","dtypep":"(M)","access":"WR","varp":"(HB)","varScopep":"(GB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__ret","addr":"(JD)","loc":"d,18:7,18:10","dtypep":"(M)","access":"WR","varp":"(IB)","varScopep":"(HB)"}
],
"lsbp": [
{"type":"SEL","addr":"(JD)","loc":"d,18:11,18:12","dtypep":"(KD)","widthConst":3,
{"type":"SEL","addr":"(KD)","loc":"d,18:11,18:12","dtypep":"(LD)","widthConst":3,
"fromp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(LD)","loc":"d,18:11,18:12","dtypep":"(JB)","access":"RD","varp":"(KB)","varScopep":"(IB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(MD)","loc":"d,18:11,18:12","dtypep":"(KB)","access":"RD","varp":"(LB)","varScopep":"(JB)"}
],
"lsbp": [
{"type":"CONST","name":"32'h0","addr":"(MD)","loc":"d,18:11,18:12","dtypep":"(GD)"}
{"type":"CONST","name":"32'h0","addr":"(ND)","loc":"d,18:11,18:12","dtypep":"(HD)"}
]}
]}
]},
{"type":"ASSIGN","addr":"(ND)","loc":"d,17:25,17:27","dtypep":"(JB)",
{"type":"ASSIGN","addr":"(OD)","loc":"d,17:25,17:27","dtypep":"(KB)",
"rhsp": [
{"type":"ADD","addr":"(OD)","loc":"d,17:25,17:27","dtypep":"(PD)",
{"type":"ADD","addr":"(PD)","loc":"d,17:25,17:27","dtypep":"(QD)",
"lhsp": [
{"type":"CONST","name":"32'h1","addr":"(QD)","loc":"d,17:25,17:27","dtypep":"(GD)"}
{"type":"CONST","name":"32'h1","addr":"(RD)","loc":"d,17:25,17:27","dtypep":"(HD)"}
],
"rhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(RD)","loc":"d,17:24,17:25","dtypep":"(JB)","access":"RD","varp":"(KB)","varScopep":"(IB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(SD)","loc":"d,17:24,17:25","dtypep":"(KB)","access":"RD","varp":"(LB)","varScopep":"(JB)"}
]}
],
"lhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(SD)","loc":"d,17:24,17:25","dtypep":"(JB)","access":"WR","varp":"(KB)","varScopep":"(IB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(TD)","loc":"d,17:24,17:25","dtypep":"(KB)","access":"WR","varp":"(LB)","varScopep":"(JB)"}
]}
]},
{"type":"ASSIGN","addr":"(TD)","loc":"d,20:5,20:11","dtypep":"(M)",
{"type":"ASSIGN","addr":"(UD)","loc":"d,20:5,20:11","dtypep":"(M)",
"rhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__ret","addr":"(UD)","loc":"d,20:12,20:15","dtypep":"(M)","access":"RD","varp":"(HB)","varScopep":"(GB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__ret","addr":"(VD)","loc":"d,20:12,20:15","dtypep":"(M)","access":"RD","varp":"(IB)","varScopep":"(HB)"}
],
"lhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__Vfuncout","addr":"(VD)","loc":"d,20:5,20:11","dtypep":"(M)","access":"WR","varp":"(DB)","varScopep":"(CB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__Vfuncout","addr":"(WD)","loc":"d,20:5,20:11","dtypep":"(M)","access":"WR","varp":"(EB)","varScopep":"(DB)"}
]},
{"type":"ASSIGNW","addr":"(WD)","loc":"d,23:14,23:15","dtypep":"(M)",
{"type":"ASSIGNW","addr":"(XD)","loc":"d,23:14,23:15","dtypep":"(M)",
"rhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__Vfuncout","addr":"(XD)","loc":"d,23:16,23:19","dtypep":"(M)","access":"RD","varp":"(DB)","varScopep":"(CB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__Vfuncout","addr":"(YD)","loc":"d,23:16,23:19","dtypep":"(M)","access":"RD","varp":"(EB)","varScopep":"(DB)"}
],
"lhsp": [
{"type":"VARREF","name":"o_a","addr":"(YD)","loc":"d,23:10,23:13","dtypep":"(M)","access":"WR","varp":"(L)","varScopep":"(S)"}
{"type":"VARREF","name":"o_a","addr":"(ZD)","loc":"d,23:10,23:13","dtypep":"(M)","access":"WR","varp":"(L)","varScopep":"(T)"}
]}
]},
{"type":"ALWAYS","addr":"(ZD)","loc":"d,24:14,24:15","keyword":"cont_assign",
{"type":"ALWAYS","addr":"(AE)","loc":"d,24:14,24:15","keyword":"cont_assign",
"stmtsp": [
{"type":"COMMENT","name":"Function: foo","addr":"(AE)","loc":"d,24:16,24:19","showAt":true},
{"type":"ASSIGN","addr":"(BE)","loc":"d,24:20,24:23","dtypep":"(J)",
{"type":"COMMENT","name":"Function: foo","addr":"(BE)","loc":"d,24:16,24:19","showAt":true},
{"type":"ASSIGN","addr":"(CE)","loc":"d,24:20,24:23","dtypep":"(J)",
"rhsp": [
{"type":"VARREF","name":"i_b","addr":"(CE)","loc":"d,24:20,24:23","dtypep":"(J)","access":"RD","varp":"(K)","varScopep":"(R)"}
{"type":"VARREF","name":"i_b","addr":"(DE)","loc":"d,24:20,24:23","dtypep":"(J)","access":"RD","varp":"(K)","varScopep":"(S)"}
],
"lhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__val","addr":"(DE)","loc":"d,14:57,14:60","dtypep":"(J)","access":"WR","varp":"(OB)","varScopep":"(NB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__val","addr":"(EE)","loc":"d,14:57,14:60","dtypep":"(J)","access":"WR","varp":"(PB)","varScopep":"(OB)"}
]},
{"type":"ASSIGN","addr":"(EE)","loc":"d,14:34,14:37","dtypep":"(M)",
{"type":"ASSIGN","addr":"(FE)","loc":"d,14:34,14:37","dtypep":"(M)",
"rhsp": [
{"type":"CRESET","addr":"(FE)","loc":"d,14:34,14:37","dtypep":"(M)"}
{"type":"CRESET","addr":"(GE)","loc":"d,14:34,14:37","dtypep":"(M)"}
],
"lhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__Vfuncout","addr":"(GE)","loc":"d,14:34,14:37","dtypep":"(M)","access":"WR","varp":"(MB)","varScopep":"(LB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__Vfuncout","addr":"(HE)","loc":"d,14:34,14:37","dtypep":"(M)","access":"WR","varp":"(NB)","varScopep":"(MB)"}
]},
{"type":"ASSIGN","addr":"(HE)","loc":"d,15:17,15:20","dtypep":"(M)",
{"type":"ASSIGN","addr":"(IE)","loc":"d,15:17,15:20","dtypep":"(M)",
"rhsp": [
{"type":"CRESET","addr":"(IE)","loc":"d,15:17,15:20","dtypep":"(M)"}
{"type":"CRESET","addr":"(JE)","loc":"d,15:17,15:20","dtypep":"(M)"}
],
"lhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__ret","addr":"(JE)","loc":"d,15:17,15:20","dtypep":"(M)","access":"WR","varp":"(QB)","varScopep":"(PB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__ret","addr":"(KE)","loc":"d,15:17,15:20","dtypep":"(M)","access":"WR","varp":"(RB)","varScopep":"(QB)"}
]},
{"type":"ASSIGN","addr":"(KE)","loc":"d,16:13,16:14","dtypep":"(JB)",
{"type":"ASSIGN","addr":"(LE)","loc":"d,16:13,16:14","dtypep":"(KB)",
"rhsp": [
{"type":"CRESET","addr":"(LE)","loc":"d,16:13,16:14","dtypep":"(JB)"}
{"type":"CRESET","addr":"(ME)","loc":"d,16:13,16:14","dtypep":"(KB)"}
],
"lhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(ME)","loc":"d,16:13,16:14","dtypep":"(JB)","access":"WR","varp":"(SB)","varScopep":"(RB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(NE)","loc":"d,16:13,16:14","dtypep":"(KB)","access":"WR","varp":"(TB)","varScopep":"(SB)"}
]},
{"type":"ASSIGN","addr":"(NE)","loc":"d,17:12,17:13","dtypep":"(JB)",
{"type":"ASSIGN","addr":"(OE)","loc":"d,17:12,17:13","dtypep":"(KB)",
"rhsp": [
{"type":"CONST","name":"32'sh0","addr":"(OE)","loc":"d,17:14,17:15","dtypep":"(JC)"}
{"type":"CONST","name":"32'sh0","addr":"(PE)","loc":"d,17:14,17:15","dtypep":"(KC)"}
],
"lhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(PE)","loc":"d,17:10,17:11","dtypep":"(JB)","access":"WR","varp":"(SB)","varScopep":"(RB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(QE)","loc":"d,17:10,17:11","dtypep":"(KB)","access":"WR","varp":"(TB)","varScopep":"(SB)"}
]},
{"type":"LOOP","addr":"(QE)","loc":"d,17:5,17:8","unroll":"default",
{"type":"LOOP","addr":"(RE)","loc":"d,17:5,17:8","unroll":"default",
"stmtsp": [
{"type":"LOOPTEST","addr":"(RE)","loc":"d,17:17,17:18",
{"type":"LOOPTEST","addr":"(SE)","loc":"d,17:17,17:18",
"condp": [
{"type":"GTS","addr":"(SE)","loc":"d,17:19,17:20","dtypep":"(OC)",
{"type":"GTS","addr":"(TE)","loc":"d,17:19,17:20","dtypep":"(PC)",
"lhsp": [
{"type":"CONST","name":"32'sh7","addr":"(TE)","loc":"d,17:21,17:22","dtypep":"(JC)"}
{"type":"CONST","name":"32'sh7","addr":"(UE)","loc":"d,17:21,17:22","dtypep":"(KC)"}
],
"rhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(UE)","loc":"d,17:17,17:18","dtypep":"(JB)","access":"RD","varp":"(SB)","varScopep":"(RB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(VE)","loc":"d,17:17,17:18","dtypep":"(KB)","access":"RD","varp":"(TB)","varScopep":"(SB)"}
]}
]},
{"type":"ASSIGN","addr":"(VE)","loc":"d,18:14,18:15","dtypep":"(SC)",
{"type":"ASSIGN","addr":"(WE)","loc":"d,18:14,18:15","dtypep":"(TC)",
"rhsp": [
{"type":"EQ","addr":"(WE)","loc":"d,18:29,18:31","dtypep":"(OC)",
{"type":"EQ","addr":"(XE)","loc":"d,18:29,18:31","dtypep":"(PC)",
"lhsp": [
{"type":"CONST","name":"2'h0","addr":"(XE)","loc":"d,18:32,18:37","dtypep":"(VC)"}
{"type":"CONST","name":"2'h0","addr":"(YE)","loc":"d,18:32,18:37","dtypep":"(WC)"}
],
"rhsp": [
{"type":"SEL","addr":"(YE)","loc":"d,18:20,18:21","dtypep":"(XC)","widthConst":2,"declRange":"[15:0]","declElWidth":1,
{"type":"SEL","addr":"(ZE)","loc":"d,18:20,18:21","dtypep":"(YC)","widthConst":2,"declRange":"[15:0]","declElWidth":1,
"fromp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__val","addr":"(ZE)","loc":"d,18:17,18:20","dtypep":"(J)","access":"RD","varp":"(OB)","varScopep":"(NB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__val","addr":"(AF)","loc":"d,18:17,18:20","dtypep":"(J)","access":"RD","varp":"(PB)","varScopep":"(OB)"}
],
"lsbp": [
{"type":"SEL","addr":"(AF)","loc":"d,18:22,18:23","dtypep":"(AD)","widthConst":4,
{"type":"SEL","addr":"(BF)","loc":"d,18:22,18:23","dtypep":"(BD)","widthConst":4,
"fromp": [
{"type":"MULS","addr":"(BF)","loc":"d,18:22,18:23","dtypep":"(CD)",
{"type":"MULS","addr":"(CF)","loc":"d,18:22,18:23","dtypep":"(DD)",
"lhsp": [
{"type":"CONST","name":"32'sh2","addr":"(CF)","loc":"d,18:23,18:24","dtypep":"(JC)"}
{"type":"CONST","name":"32'sh2","addr":"(DF)","loc":"d,18:23,18:24","dtypep":"(KC)"}
],
"rhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(DF)","loc":"d,18:21,18:22","dtypep":"(JB)","access":"RD","varp":"(SB)","varScopep":"(RB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(EF)","loc":"d,18:21,18:22","dtypep":"(KB)","access":"RD","varp":"(TB)","varScopep":"(SB)"}
]}
],
"lsbp": [
{"type":"CONST","name":"32'h0","addr":"(EF)","loc":"d,18:22,18:23","dtypep":"(GD)"}
{"type":"CONST","name":"32'h0","addr":"(FF)","loc":"d,18:22,18:23","dtypep":"(HD)"}
]}
]}
]}
],
"lhsp": [
{"type":"SEL","addr":"(FF)","loc":"d,18:10,18:11","dtypep":"(SC)","widthConst":1,"declRange":"[6:0]","declElWidth":1,
{"type":"SEL","addr":"(GF)","loc":"d,18:10,18:11","dtypep":"(TC)","widthConst":1,"declRange":"[6:0]","declElWidth":1,
"fromp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__ret","addr":"(GF)","loc":"d,18:7,18:10","dtypep":"(M)","access":"WR","varp":"(QB)","varScopep":"(PB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__ret","addr":"(HF)","loc":"d,18:7,18:10","dtypep":"(M)","access":"WR","varp":"(RB)","varScopep":"(QB)"}
],
"lsbp": [
{"type":"SEL","addr":"(HF)","loc":"d,18:11,18:12","dtypep":"(KD)","widthConst":3,
{"type":"SEL","addr":"(IF)","loc":"d,18:11,18:12","dtypep":"(LD)","widthConst":3,
"fromp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(IF)","loc":"d,18:11,18:12","dtypep":"(JB)","access":"RD","varp":"(SB)","varScopep":"(RB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(JF)","loc":"d,18:11,18:12","dtypep":"(KB)","access":"RD","varp":"(TB)","varScopep":"(SB)"}
],
"lsbp": [
{"type":"CONST","name":"32'h0","addr":"(JF)","loc":"d,18:11,18:12","dtypep":"(GD)"}
{"type":"CONST","name":"32'h0","addr":"(KF)","loc":"d,18:11,18:12","dtypep":"(HD)"}
]}
]}
]},
{"type":"ASSIGN","addr":"(KF)","loc":"d,17:25,17:27","dtypep":"(JB)",
{"type":"ASSIGN","addr":"(LF)","loc":"d,17:25,17:27","dtypep":"(KB)",
"rhsp": [
{"type":"ADD","addr":"(LF)","loc":"d,17:25,17:27","dtypep":"(PD)",
{"type":"ADD","addr":"(MF)","loc":"d,17:25,17:27","dtypep":"(QD)",
"lhsp": [
{"type":"CONST","name":"32'h1","addr":"(MF)","loc":"d,17:25,17:27","dtypep":"(GD)"}
{"type":"CONST","name":"32'h1","addr":"(NF)","loc":"d,17:25,17:27","dtypep":"(HD)"}
],
"rhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(NF)","loc":"d,17:24,17:25","dtypep":"(JB)","access":"RD","varp":"(SB)","varScopep":"(RB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(OF)","loc":"d,17:24,17:25","dtypep":"(KB)","access":"RD","varp":"(TB)","varScopep":"(SB)"}
]}
],
"lhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(OF)","loc":"d,17:24,17:25","dtypep":"(JB)","access":"WR","varp":"(SB)","varScopep":"(RB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(PF)","loc":"d,17:24,17:25","dtypep":"(KB)","access":"WR","varp":"(TB)","varScopep":"(SB)"}
]}
]},
{"type":"ASSIGN","addr":"(PF)","loc":"d,20:5,20:11","dtypep":"(M)",
{"type":"ASSIGN","addr":"(QF)","loc":"d,20:5,20:11","dtypep":"(M)",
"rhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__ret","addr":"(QF)","loc":"d,20:12,20:15","dtypep":"(M)","access":"RD","varp":"(QB)","varScopep":"(PB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__ret","addr":"(RF)","loc":"d,20:12,20:15","dtypep":"(M)","access":"RD","varp":"(RB)","varScopep":"(QB)"}
],
"lhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__Vfuncout","addr":"(RF)","loc":"d,20:5,20:11","dtypep":"(M)","access":"WR","varp":"(MB)","varScopep":"(LB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__Vfuncout","addr":"(SF)","loc":"d,20:5,20:11","dtypep":"(M)","access":"WR","varp":"(NB)","varScopep":"(MB)"}
]},
{"type":"ASSIGNW","addr":"(SF)","loc":"d,24:14,24:15","dtypep":"(M)",
{"type":"ASSIGNW","addr":"(TF)","loc":"d,24:14,24:15","dtypep":"(M)",
"rhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__Vfuncout","addr":"(TF)","loc":"d,24:16,24:19","dtypep":"(M)","access":"RD","varp":"(MB)","varScopep":"(LB)"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__Vfuncout","addr":"(UF)","loc":"d,24:16,24:19","dtypep":"(M)","access":"RD","varp":"(NB)","varScopep":"(MB)"}
],
"lhsp": [
{"type":"VARREF","name":"o_b","addr":"(UF)","loc":"d,24:10,24:13","dtypep":"(M)","access":"WR","varp":"(N)","varScopep":"(T)"}
{"type":"VARREF","name":"o_b","addr":"(VF)","loc":"d,24:10,24:13","dtypep":"(M)","access":"WR","varp":"(N)","varScopep":"(U)"}
]}
]},
{"type":"ALWAYS","addr":"(VF)","loc":"d,8:24,8:27","keyword":"cont_assign",
{"type":"ALWAYS","addr":"(WF)","loc":"d,8:24,8:27","keyword":"cont_assign",
"stmtsp": [
{"type":"ASSIGNW","addr":"(WF)","loc":"d,8:24,8:27","dtypep":"(J)",
{"type":"ASSIGNW","addr":"(XF)","loc":"d,8:24,8:27","dtypep":"(J)",
"rhsp": [
{"type":"VARREF","name":"i_a","addr":"(XF)","loc":"d,8:24,8:27","dtypep":"(J)","access":"RD","varp":"(I)","varScopep":"(Q)"}
{"type":"VARREF","name":"i_a","addr":"(YF)","loc":"d,8:24,8:27","dtypep":"(J)","access":"RD","varp":"(I)","varScopep":"(R)"}
],
"lhsp": [
{"type":"VARREF","name":"vlvbound_test.i_a","addr":"(YF)","loc":"d,8:24,8:27","dtypep":"(J)","access":"WR","varp":"(V)","varScopep":"(U)"}
{"type":"VARREF","name":"vlvbound_test.i_a","addr":"(ZF)","loc":"d,8:24,8:27","dtypep":"(J)","access":"WR","varp":"(W)","varScopep":"(V)"}
]}
]},
{"type":"ALWAYS","addr":"(ZF)","loc":"d,9:24,9:27","keyword":"cont_assign",
{"type":"ALWAYS","addr":"(AG)","loc":"d,9:24,9:27","keyword":"cont_assign",
"stmtsp": [
{"type":"ASSIGNW","addr":"(AG)","loc":"d,9:24,9:27","dtypep":"(J)",
{"type":"ASSIGNW","addr":"(BG)","loc":"d,9:24,9:27","dtypep":"(J)",
"rhsp": [
{"type":"VARREF","name":"i_b","addr":"(BG)","loc":"d,9:24,9:27","dtypep":"(J)","access":"RD","varp":"(K)","varScopep":"(R)"}
{"type":"VARREF","name":"i_b","addr":"(CG)","loc":"d,9:24,9:27","dtypep":"(J)","access":"RD","varp":"(K)","varScopep":"(S)"}
],
"lhsp": [
{"type":"VARREF","name":"vlvbound_test.i_b","addr":"(CG)","loc":"d,9:24,9:27","dtypep":"(J)","access":"WR","varp":"(X)","varScopep":"(W)"}
{"type":"VARREF","name":"vlvbound_test.i_b","addr":"(DG)","loc":"d,9:24,9:27","dtypep":"(J)","access":"WR","varp":"(Y)","varScopep":"(X)"}
]}
]},
{"type":"ALWAYS","addr":"(DG)","loc":"d,10:24,10:27","keyword":"cont_assign",
{"type":"ALWAYS","addr":"(EG)","loc":"d,10:24,10:27","keyword":"cont_assign",
"stmtsp": [
{"type":"ASSIGNW","addr":"(EG)","loc":"d,10:24,10:27","dtypep":"(M)",
{"type":"ASSIGNW","addr":"(FG)","loc":"d,10:24,10:27","dtypep":"(M)",
"rhsp": [
{"type":"VARREF","name":"o_a","addr":"(FG)","loc":"d,10:24,10:27","dtypep":"(M)","access":"RD","varp":"(L)","varScopep":"(S)"}
{"type":"VARREF","name":"o_a","addr":"(GG)","loc":"d,10:24,10:27","dtypep":"(M)","access":"RD","varp":"(L)","varScopep":"(T)"}
],
"lhsp": [
{"type":"VARREF","name":"vlvbound_test.o_a","addr":"(GG)","loc":"d,10:24,10:27","dtypep":"(M)","access":"WR","varp":"(Z)","varScopep":"(Y)"}
{"type":"VARREF","name":"vlvbound_test.o_a","addr":"(HG)","loc":"d,10:24,10:27","dtypep":"(M)","access":"WR","varp":"(AB)","varScopep":"(Z)"}
]}
]},
{"type":"ALWAYS","addr":"(HG)","loc":"d,11:24,11:27","keyword":"cont_assign",
{"type":"ALWAYS","addr":"(IG)","loc":"d,11:24,11:27","keyword":"cont_assign",
"stmtsp": [
{"type":"ASSIGNW","addr":"(IG)","loc":"d,11:24,11:27","dtypep":"(M)",
{"type":"ASSIGNW","addr":"(JG)","loc":"d,11:24,11:27","dtypep":"(M)",
"rhsp": [
{"type":"VARREF","name":"o_b","addr":"(JG)","loc":"d,11:24,11:27","dtypep":"(M)","access":"RD","varp":"(N)","varScopep":"(T)"}
{"type":"VARREF","name":"o_b","addr":"(KG)","loc":"d,11:24,11:27","dtypep":"(M)","access":"RD","varp":"(N)","varScopep":"(U)"}
],
"lhsp": [
{"type":"VARREF","name":"vlvbound_test.o_b","addr":"(KG)","loc":"d,11:24,11:27","dtypep":"(M)","access":"WR","varp":"(BB)","varScopep":"(AB)"}
{"type":"VARREF","name":"vlvbound_test.o_b","addr":"(LG)","loc":"d,11:24,11:27","dtypep":"(M)","access":"WR","varp":"(CB)","varScopep":"(BB)"}
]}
]}
]}
]},
{"type":"VAR","name":"vlvbound_test.i_a","addr":"(V)","loc":"d,8:24,8:27","dtypep":"(J)","origName":"i_a","verilogName":"i_a","direction":"NONE","declDirection":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"vlvbound_test.i_b","addr":"(X)","loc":"d,9:24,9:27","dtypep":"(J)","origName":"i_b","verilogName":"i_b","direction":"NONE","declDirection":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"vlvbound_test.o_a","addr":"(Z)","loc":"d,10:24,10:27","dtypep":"(M)","origName":"o_a","verilogName":"o_a","direction":"NONE","declDirection":"OUTPUT","icoMaybeWritten":true,"lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"vlvbound_test.o_b","addr":"(BB)","loc":"d,11:24,11:27","dtypep":"(M)","origName":"o_b","verilogName":"o_b","direction":"NONE","declDirection":"OUTPUT","icoMaybeWritten":true,"lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"__Vfunc_vlvbound_test.foo__0__Vfuncout","addr":"(DB)","loc":"d,14:34,14:37","dtypep":"(M)","origName":"__Vfunc_vlvbound_test__DOT__foo__0__Vfuncout","verilogName":"__Vfunc_vlvbound_test.foo__0__Vfuncout","direction":"NONE","declDirection":"NONE","lifetime":"NONE","varType":"BLOCKTEMP","dtypeName":"logic"},
{"type":"VAR","name":"__Vfunc_vlvbound_test.foo__0__val","addr":"(FB)","loc":"d,14:57,14:60","dtypep":"(J)","origName":"__Vfunc_vlvbound_test__DOT__foo__0__val","verilogName":"__Vfunc_vlvbound_test.foo__0__val","direction":"NONE","declDirection":"NONE","lifetime":"NONE","varType":"BLOCKTEMP","dtypeName":"logic"},
{"type":"VAR","name":"__Vfunc_vlvbound_test.foo__0__ret","addr":"(HB)","loc":"d,15:17,15:20","dtypep":"(M)","origName":"__Vfunc_vlvbound_test__DOT__foo__0__ret","verilogName":"__Vfunc_vlvbound_test.foo__0__ret","direction":"NONE","declDirection":"NONE","lifetime":"NONE","varType":"BLOCKTEMP","dtypeName":"logic"},
{"type":"VAR","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(KB)","loc":"d,16:13,16:14","dtypep":"(JB)","origName":"__Vfunc_vlvbound_test__DOT__foo__0__i","verilogName":"__Vfunc_vlvbound_test.foo__0__i","direction":"NONE","declDirection":"NONE","lifetime":"NONE","varType":"BLOCKTEMP","dtypeName":"integer"},
{"type":"VAR","name":"__Vfunc_vlvbound_test.foo__1__Vfuncout","addr":"(MB)","loc":"d,14:34,14:37","dtypep":"(M)","origName":"__Vfunc_vlvbound_test__DOT__foo__1__Vfuncout","verilogName":"__Vfunc_vlvbound_test.foo__1__Vfuncout","direction":"NONE","declDirection":"NONE","lifetime":"NONE","varType":"BLOCKTEMP","dtypeName":"logic"},
{"type":"VAR","name":"__Vfunc_vlvbound_test.foo__1__val","addr":"(OB)","loc":"d,14:57,14:60","dtypep":"(J)","origName":"__Vfunc_vlvbound_test__DOT__foo__1__val","verilogName":"__Vfunc_vlvbound_test.foo__1__val","direction":"NONE","declDirection":"NONE","lifetime":"NONE","varType":"BLOCKTEMP","dtypeName":"logic"},
{"type":"VAR","name":"__Vfunc_vlvbound_test.foo__1__ret","addr":"(QB)","loc":"d,15:17,15:20","dtypep":"(M)","origName":"__Vfunc_vlvbound_test__DOT__foo__1__ret","verilogName":"__Vfunc_vlvbound_test.foo__1__ret","direction":"NONE","declDirection":"NONE","lifetime":"NONE","varType":"BLOCKTEMP","dtypeName":"logic"},
{"type":"VAR","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(SB)","loc":"d,16:13,16:14","dtypep":"(JB)","origName":"__Vfunc_vlvbound_test__DOT__foo__1__i","verilogName":"__Vfunc_vlvbound_test.foo__1__i","direction":"NONE","declDirection":"NONE","lifetime":"NONE","varType":"BLOCKTEMP","dtypeName":"integer"}
{"type":"VAR","name":"vlvbound_test.i_a","addr":"(W)","loc":"d,8:24,8:27","dtypep":"(J)","origName":"i_a","verilogName":"i_a","direction":"NONE","declDirection":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"vlvbound_test.i_b","addr":"(Y)","loc":"d,9:24,9:27","dtypep":"(J)","origName":"i_b","verilogName":"i_b","direction":"NONE","declDirection":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"vlvbound_test.o_a","addr":"(AB)","loc":"d,10:24,10:27","dtypep":"(M)","origName":"o_a","verilogName":"o_a","direction":"NONE","declDirection":"OUTPUT","icoMaybeWritten":true,"lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"vlvbound_test.o_b","addr":"(CB)","loc":"d,11:24,11:27","dtypep":"(M)","origName":"o_b","verilogName":"o_b","direction":"NONE","declDirection":"OUTPUT","icoMaybeWritten":true,"lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"},
{"type":"VAR","name":"__Vfunc_vlvbound_test.foo__0__Vfuncout","addr":"(EB)","loc":"d,14:34,14:37","dtypep":"(M)","origName":"__Vfunc_vlvbound_test__DOT__foo__0__Vfuncout","verilogName":"__Vfunc_vlvbound_test.foo__0__Vfuncout","direction":"NONE","declDirection":"NONE","lifetime":"NONE","varType":"BLOCKTEMP","dtypeName":"logic"},
{"type":"VAR","name":"__Vfunc_vlvbound_test.foo__0__val","addr":"(GB)","loc":"d,14:57,14:60","dtypep":"(J)","origName":"__Vfunc_vlvbound_test__DOT__foo__0__val","verilogName":"__Vfunc_vlvbound_test.foo__0__val","direction":"NONE","declDirection":"NONE","lifetime":"NONE","varType":"BLOCKTEMP","dtypeName":"logic"},
{"type":"VAR","name":"__Vfunc_vlvbound_test.foo__0__ret","addr":"(IB)","loc":"d,15:17,15:20","dtypep":"(M)","origName":"__Vfunc_vlvbound_test__DOT__foo__0__ret","verilogName":"__Vfunc_vlvbound_test.foo__0__ret","direction":"NONE","declDirection":"NONE","lifetime":"NONE","varType":"BLOCKTEMP","dtypeName":"logic"},
{"type":"VAR","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(LB)","loc":"d,16:13,16:14","dtypep":"(KB)","origName":"__Vfunc_vlvbound_test__DOT__foo__0__i","verilogName":"__Vfunc_vlvbound_test.foo__0__i","direction":"NONE","declDirection":"NONE","lifetime":"NONE","varType":"BLOCKTEMP","dtypeName":"integer"},
{"type":"VAR","name":"__Vfunc_vlvbound_test.foo__1__Vfuncout","addr":"(NB)","loc":"d,14:34,14:37","dtypep":"(M)","origName":"__Vfunc_vlvbound_test__DOT__foo__1__Vfuncout","verilogName":"__Vfunc_vlvbound_test.foo__1__Vfuncout","direction":"NONE","declDirection":"NONE","lifetime":"NONE","varType":"BLOCKTEMP","dtypeName":"logic"},
{"type":"VAR","name":"__Vfunc_vlvbound_test.foo__1__val","addr":"(PB)","loc":"d,14:57,14:60","dtypep":"(J)","origName":"__Vfunc_vlvbound_test__DOT__foo__1__val","verilogName":"__Vfunc_vlvbound_test.foo__1__val","direction":"NONE","declDirection":"NONE","lifetime":"NONE","varType":"BLOCKTEMP","dtypeName":"logic"},
{"type":"VAR","name":"__Vfunc_vlvbound_test.foo__1__ret","addr":"(RB)","loc":"d,15:17,15:20","dtypep":"(M)","origName":"__Vfunc_vlvbound_test__DOT__foo__1__ret","verilogName":"__Vfunc_vlvbound_test.foo__1__ret","direction":"NONE","declDirection":"NONE","lifetime":"NONE","varType":"BLOCKTEMP","dtypeName":"logic"},
{"type":"VAR","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(TB)","loc":"d,16:13,16:14","dtypep":"(KB)","origName":"__Vfunc_vlvbound_test__DOT__foo__1__i","verilogName":"__Vfunc_vlvbound_test.foo__1__i","direction":"NONE","declDirection":"NONE","lifetime":"NONE","varType":"BLOCKTEMP","dtypeName":"integer"}
]},
{"type":"PACKAGE","name":"$unit","addr":"(E)","loc":"a,0:0,0:0","origName":"__024unit","verilogName":"\\$unit ","level":3,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps"}
{"type":"PACKAGE","name":"$unit","addr":"(E)","loc":"a,0:0,0:0","origName":"__024unit","verilogName":"\\$unit ","level":3,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps"},
{"type":"PACKAGE","name":"__Vconstpool","addr":"(D)","loc":"a,0:0,0:0","origName":"__Vconstpool","verilogName":"__Vconstpool","level":3,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps",
"stmtsp": [
{"type":"SCOPE","name":"__Vconstpool","addr":"(MG)","loc":"a,0:0,0:0","aboveScopep":"(Q)","aboveCellp":"(P)","modp":"(D)"}
]}
],
"miscsp": [
{"type":"TYPETABLE","addr":"(C)","loc":"a,0:0,0:0",
"typesp": [
{"type":"BASICDTYPE","name":"bit","addr":"(OC)","loc":"d,17:19,17:20","dtypep":"(OC)","keyword":"bit","generic":true},
{"type":"BASICDTYPE","name":"bit","addr":"(VC)","loc":"d,18:32,18:37","dtypep":"(VC)","keyword":"bit","range":"1:0","generic":true},
{"type":"BASICDTYPE","name":"logic","addr":"(SC)","loc":"d,18:29,18:31","dtypep":"(SC)","keyword":"logic","generic":true},
{"type":"BASICDTYPE","name":"bit","addr":"(PC)","loc":"d,17:19,17:20","dtypep":"(PC)","keyword":"bit","generic":true},
{"type":"BASICDTYPE","name":"bit","addr":"(WC)","loc":"d,18:32,18:37","dtypep":"(WC)","keyword":"bit","range":"1:0","generic":true},
{"type":"BASICDTYPE","name":"logic","addr":"(TC)","loc":"d,18:29,18:31","dtypep":"(TC)","keyword":"logic","generic":true},
{"type":"BASICDTYPE","name":"logic","addr":"(J)","loc":"d,8:11,8:16","dtypep":"(J)","keyword":"logic","range":"15:0","generic":true},
{"type":"BASICDTYPE","name":"logic","addr":"(M)","loc":"d,10:12,10:17","dtypep":"(M)","keyword":"logic","range":"6:0","generic":true},
{"type":"BASICDTYPE","name":"integer","addr":"(JB)","loc":"d,16:5,16:12","dtypep":"(JB)","keyword":"integer","range":"31:0","generic":true,"signed":true},
{"type":"BASICDTYPE","name":"logic","addr":"(CD)","loc":"d,17:19,17:20","dtypep":"(CD)","keyword":"logic","range":"31:0","generic":true,"signed":true},
{"type":"BASICDTYPE","name":"logic","addr":"(KD)","loc":"d,18:10,18:11","dtypep":"(KD)","keyword":"logic","range":"2:0","generic":true,"signed":true},
{"type":"BASICDTYPE","name":"bit","addr":"(GD)","loc":"d,18:11,18:12","dtypep":"(GD)","keyword":"bit","range":"31:0","generic":true},
{"type":"BASICDTYPE","name":"logic","addr":"(XC)","loc":"d,18:20,18:21","dtypep":"(XC)","keyword":"logic","range":"1:0","generic":true},
{"type":"BASICDTYPE","name":"logic","addr":"(AD)","loc":"d,18:20,18:21","dtypep":"(AD)","keyword":"logic","range":"3:0","generic":true,"signed":true},
{"type":"BASICDTYPE","name":"logic","addr":"(PD)","loc":"d,17:25,17:27","dtypep":"(PD)","keyword":"logic","range":"31:0","generic":true},
{"type":"BASICDTYPE","name":"bit","addr":"(JC)","loc":"d,17:14,17:15","dtypep":"(JC)","keyword":"bit","range":"31:0","generic":true,"signed":true}
]},
{"type":"CONSTPOOL","addr":"(D)","loc":"a,0:0,0:0",
"modulep": [
{"type":"MODULE","name":"@CONST-POOL@","addr":"(LG)","loc":"a,0:0,0:0","origName":"@CONST-POOL@","verilogName":"@CONST-POOL@","unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"NONE",
"stmtsp": [
{"type":"SCOPE","name":"@CONST-POOL@","addr":"(MG)","loc":"a,0:0,0:0","modp":"(LG)"}
]}
{"type":"BASICDTYPE","name":"integer","addr":"(KB)","loc":"d,16:5,16:12","dtypep":"(KB)","keyword":"integer","range":"31:0","generic":true,"signed":true},
{"type":"BASICDTYPE","name":"logic","addr":"(DD)","loc":"d,17:19,17:20","dtypep":"(DD)","keyword":"logic","range":"31:0","generic":true,"signed":true},
{"type":"BASICDTYPE","name":"logic","addr":"(LD)","loc":"d,18:10,18:11","dtypep":"(LD)","keyword":"logic","range":"2:0","generic":true,"signed":true},
{"type":"BASICDTYPE","name":"bit","addr":"(HD)","loc":"d,18:11,18:12","dtypep":"(HD)","keyword":"bit","range":"31:0","generic":true},
{"type":"BASICDTYPE","name":"logic","addr":"(YC)","loc":"d,18:20,18:21","dtypep":"(YC)","keyword":"logic","range":"1:0","generic":true},
{"type":"BASICDTYPE","name":"logic","addr":"(BD)","loc":"d,18:20,18:21","dtypep":"(BD)","keyword":"logic","range":"3:0","generic":true,"signed":true},
{"type":"BASICDTYPE","name":"logic","addr":"(QD)","loc":"d,17:25,17:27","dtypep":"(QD)","keyword":"logic","range":"31:0","generic":true},
{"type":"BASICDTYPE","name":"bit","addr":"(KC)","loc":"d,17:14,17:15","dtypep":"(KC)","keyword":"bit","range":"31:0","generic":true,"signed":true}
]}
]}
+3 -9
View File
@@ -1,21 +1,15 @@
{"type":"NETLIST","name":"$root","addr":"(B)","loc":"a,0:0,0:0","timeunit":"1ps","timeprecision":"1ps","typeTablep":"(C)","constPoolp":"(D)","dollarUnitPkgp":"(E)",
{"type":"NETLIST","name":"$root","addr":"(B)","loc":"a,0:0,0:0","timeunit":"1ps","timeprecision":"1ps","typeTablep":"(C)","constPoolPkgp":"(D)","dollarUnitPkgp":"(E)",
"modulesp": [
{"type":"MODULE","name":"m","addr":"(F)","loc":"d,7:8,7:9","origName":"m","verilogName":"m","level":1,"depth":2,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps",
"stmtsp": [
{"type":"VAR","name":"clk","addr":"(G)","loc":"d,8:11,8:14","dtypep":"(H)","origName":"clk","verilogName":"clk","isPrimaryIO":true,"direction":"INPUT","declDirection":"INPUT","isSigPublic":true,"lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"}
]},
{"type":"PACKAGE","name":"$unit","addr":"(E)","loc":"a,0:0,0:0","origName":"__024unit","verilogName":"\\$unit ","level":2,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps"}
{"type":"PACKAGE","name":"$unit","addr":"(E)","loc":"a,0:0,0:0","origName":"__024unit","verilogName":"\\$unit ","level":2,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps"},
{"type":"PACKAGE","name":"__Vconstpool","addr":"(D)","loc":"a,0:0,0:0","origName":"__Vconstpool","verilogName":"__Vconstpool","level":2,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps"}
],
"miscsp": [
{"type":"TYPETABLE","addr":"(C)","loc":"a,0:0,0:0",
"typesp": [
{"type":"BASICDTYPE","name":"logic","addr":"(H)","loc":"d,8:11,8:14","dtypep":"(H)","keyword":"logic","generic":true}
]},
{"type":"CONSTPOOL","addr":"(D)","loc":"a,0:0,0:0",
"modulep": [
{"type":"MODULE","name":"@CONST-POOL@","addr":"(I)","loc":"a,0:0,0:0","origName":"@CONST-POOL@","verilogName":"@CONST-POOL@","unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"NONE",
"stmtsp": [
{"type":"SCOPE","name":"@CONST-POOL@","addr":"(J)","loc":"a,0:0,0:0","modp":"(I)"}
]}
]}
]}
+2 -8
View File
@@ -1,4 +1,4 @@
{"type":"NETLIST","name":"$root","addr":"(B)","loc":"a,0:0,0:0","timeunit":"1ps","timeprecision":"1ps","typeTablep":"(C)","constPoolp":"(D)","dollarUnitPkgp":"(E)",
{"type":"NETLIST","name":"$root","addr":"(B)","loc":"a,0:0,0:0","timeunit":"1ps","timeprecision":"1ps","typeTablep":"(C)","constPoolPkgp":"(D)","dollarUnitPkgp":"(E)",
"modulesp": [
{"type":"MODULE","name":"top","addr":"(F)","loc":"d,7:8,7:11","origName":"top","verilogName":"top","level":1,"depth":2,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps",
"stmtsp": [
@@ -34,6 +34,7 @@
]}
]},
{"type":"PACKAGE","name":"$unit","addr":"(E)","loc":"a,0:0,0:0","origName":"__024unit","verilogName":"\\$unit ","level":2,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps"},
{"type":"PACKAGE","name":"__Vconstpool","addr":"(D)","loc":"a,0:0,0:0","origName":"__Vconstpool","verilogName":"__Vconstpool","level":2,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps"},
{"type":"MODULE","name":"and2_x1","addr":"(N)","loc":"d,29:8,29:15","origName":"and2_x1","verilogName":"and2_x1","level":2,"depth":2,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps",
"stmtsp": [
{"type":"VAR","name":"a1","addr":"(P)","loc":"d,30:16,30:18","dtypep":"(H)","origName":"a1","verilogName":"a1","direction":"INPUT","declDirection":"INPUT","lifetime":"VSTATICI","varType":"WIRE","dtypeName":"logic"},
@@ -61,12 +62,5 @@
{"type":"TYPETABLE","addr":"(C)","loc":"a,0:0,0:0",
"typesp": [
{"type":"BASICDTYPE","name":"logic","addr":"(H)","loc":"d,30:16,30:18","dtypep":"(H)","keyword":"logic","generic":true}
]},
{"type":"CONSTPOOL","addr":"(D)","loc":"a,0:0,0:0",
"modulep": [
{"type":"MODULE","name":"@CONST-POOL@","addr":"(HB)","loc":"a,0:0,0:0","origName":"@CONST-POOL@","verilogName":"@CONST-POOL@","unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"NONE",
"stmtsp": [
{"type":"SCOPE","name":"@CONST-POOL@","addr":"(IB)","loc":"a,0:0,0:0","modp":"(HB)"}
]}
]}
]}
+2 -8
View File
@@ -1,4 +1,4 @@
{"type":"NETLIST","name":"$root","addr":"(B)","loc":"a,0:0,0:0","timeunit":"1ps","timeprecision":"1ps","typeTablep":"(C)","constPoolp":"(D)","dollarUnitPkgp":"(E)",
{"type":"NETLIST","name":"$root","addr":"(B)","loc":"a,0:0,0:0","timeunit":"1ps","timeprecision":"1ps","typeTablep":"(C)","constPoolPkgp":"(D)","dollarUnitPkgp":"(E)",
"modulesp": [
{"type":"MODULE","name":"m","addr":"(F)","loc":"d,12:8,12:9","origName":"m","verilogName":"m","level":1,"depth":2,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps",
"stmtsp": [
@@ -52,6 +52,7 @@
]}
]},
{"type":"PACKAGE","name":"$unit","addr":"(E)","loc":"a,0:0,0:0","origName":"__024unit","verilogName":"\\$unit ","level":2,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps"},
{"type":"PACKAGE","name":"__Vconstpool","addr":"(D)","loc":"a,0:0,0:0","origName":"__Vconstpool","verilogName":"__Vconstpool","level":2,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps"},
{"type":"IFACE","name":"ifc","addr":"(N)","loc":"d,7:11,7:14","origName":"ifc","verilogName":"ifc","level":2,"depth":2,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps",
"stmtsp": [
{"type":"VAR","name":"value","addr":"(Y)","loc":"d,8:11,8:16","dtypep":"(X)","origName":"value","verilogName":"value","direction":"NONE","declDirection":"NONE","lifetime":"VSTATICI","varType":"VAR","dtypeName":"integer"},
@@ -93,12 +94,5 @@
]},
{"type":"BASICDTYPE","name":"logic","addr":"(T)","loc":"d,33:8,33:9","dtypep":"(T)","keyword":"logic","range":"31:0","generic":true},
{"type":"BASICDTYPE","name":"string","addr":"(CB)","loc":"d,35:25,35:31","dtypep":"(CB)","keyword":"string","generic":true}
]},
{"type":"CONSTPOOL","addr":"(D)","loc":"a,0:0,0:0",
"modulep": [
{"type":"MODULE","name":"@CONST-POOL@","addr":"(DC)","loc":"a,0:0,0:0","origName":"@CONST-POOL@","verilogName":"@CONST-POOL@","unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"NONE",
"stmtsp": [
{"type":"SCOPE","name":"@CONST-POOL@","addr":"(EC)","loc":"a,0:0,0:0","modp":"(DC)"}
]}
]}
]}
+3 -9
View File
@@ -1,4 +1,4 @@
{"type":"NETLIST","name":"$root","addr":"(B)","loc":"a,0:0,0:0","timeunit":"1ps","timeprecision":"1ps","typeTablep":"(C)","constPoolp":"(D)","dollarUnitPkgp":"(E)",
{"type":"NETLIST","name":"$root","addr":"(B)","loc":"a,0:0,0:0","timeunit":"1ps","timeprecision":"1ps","typeTablep":"(C)","constPoolPkgp":"(D)","dollarUnitPkgp":"(E)",
"modulesp": [
{"type":"MODULE","name":"mh2","addr":"(F)","loc":"d,18:8,18:11","origName":"mh2","verilogName":"mh2","level":1,"depth":2,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps",
"stmtsp": [
@@ -65,7 +65,8 @@
{"type":"VAR","name":"ref_var_logic_u6","addr":"(RB)","loc":"d,58:17,58:33","dtypep":"(SB)","origName":"ref_var_logic_u6","verilogName":"ref_var_logic_u6","isPrimaryIO":true,"direction":"REF","declDirection":"REF","isSigPublic":true,"lifetime":"VSTATICI","varType":"PORT"},
{"type":"VAR","name":"y_ref_var_logic","addr":"(TB)","loc":"d,58:41,58:56","dtypep":"(K)","origName":"y_ref_var_logic","verilogName":"y_ref_var_logic","isPrimaryIO":true,"direction":"REF","declDirection":"REF","isSigPublic":true,"lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic"}
]},
{"type":"PACKAGE","name":"$unit","addr":"(E)","loc":"a,0:0,0:0","origName":"__024unit","verilogName":"\\$unit ","level":2,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps"}
{"type":"PACKAGE","name":"$unit","addr":"(E)","loc":"a,0:0,0:0","origName":"__024unit","verilogName":"\\$unit ","level":2,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps"},
{"type":"PACKAGE","name":"__Vconstpool","addr":"(D)","loc":"a,0:0,0:0","origName":"__Vconstpool","verilogName":"__Vconstpool","level":2,"depth":3,"inLibrary":true,"unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"1ps"}
],
"miscsp": [
{"type":"TYPETABLE","addr":"(C)","loc":"a,0:0,0:0",
@@ -95,12 +96,5 @@
{"type":"BASICDTYPE","name":"logic","addr":"(V)","loc":"d,34:27,34:28","dtypep":"(V)","keyword":"logic","range":"5:0","generic":true,"signed":true},
{"type":"BASICDTYPE","name":"integer","addr":"(H)","loc":"d,18:19,18:26","dtypep":"(H)","keyword":"integer","range":"31:0","generic":true,"signed":true},
{"type":"BASICDTYPE","name":"bit","addr":"(WB)","loc":"d,40:37,40:38","dtypep":"(WB)","keyword":"bit","range":"31:0","generic":true,"signed":true}
]},
{"type":"CONSTPOOL","addr":"(D)","loc":"a,0:0,0:0",
"modulep": [
{"type":"MODULE","name":"@CONST-POOL@","addr":"(BC)","loc":"a,0:0,0:0","origName":"@CONST-POOL@","verilogName":"@CONST-POOL@","unconnectedDrive":"DEFAULT_FALSE","lifetime":"NONE","timeunit":"NONE",
"stmtsp": [
{"type":"SCOPE","name":"@CONST-POOL@","addr":"(CC)","loc":"a,0:0,0:0","modp":"(BC)"}
]}
]}
]}