This commit is contained in:
parent
3992da6027
commit
7607f0e7fa
1
Changes
1
Changes
|
|
@ -28,6 +28,7 @@ Verilator 5.045 devel
|
|||
* Support nested interface as port connection (#5066) (#6986). [Leela Pakanati]
|
||||
* Support solve..before constraints (#5647) (#7123). [Yilou Wang]
|
||||
* Support structure initial values (#6130).
|
||||
* Support proper automatic/static initialization, and remove STATICVAR warning (#6405).
|
||||
* Support vpi_put/vpi_get forcing of signals (#5933) (#6704). [Christian Hecken]
|
||||
* Support detailed failure info for constraint violations (#6617) (#6883). [Yilou Wang]
|
||||
* Support `unique` constraints (on 1D static arrays) (#6810) (#6878). [Srinivasan Venkataramanan]
|
||||
|
|
|
|||
|
|
@ -1982,13 +1982,10 @@ List Of Warnings
|
|||
|
||||
.. option:: STATICVAR
|
||||
|
||||
Warns that a static variable declared in a loop with declaration assignment
|
||||
was converted to automatic. Often such variables were intended to
|
||||
instead be declared "automatic".
|
||||
Historical, never issued since version 5.046.
|
||||
|
||||
Ignoring this warning may make Verilator differ from other simulators,
|
||||
which will treat the variable as static. Verilator may in future versions also
|
||||
treat the variable as static.
|
||||
Warned that a static variable was declared in a loop with declaration
|
||||
assignment, and Verilator converted it to an "automatic".
|
||||
|
||||
|
||||
.. option:: STMTDLY
|
||||
|
|
|
|||
|
|
@ -756,6 +756,38 @@ public:
|
|||
ASTGEN_MEMBERS_AstFireEvent;
|
||||
bool isDelayed() const { return m_delayed; }
|
||||
};
|
||||
class AstInitialAutomaticStmt final : public AstNodeStmt {
|
||||
// Automatic variable initialization in a statement position
|
||||
// Used during early stages to record an initial initialization of a variable
|
||||
// Moves later to an appropriate constructor, or AstInitialAutomatic, or
|
||||
// AstCFunc normal statement
|
||||
// Children: {statement list usually only with assignments}
|
||||
// @astgen op1 := stmtsp : List[AstNode]
|
||||
public:
|
||||
AstInitialAutomaticStmt(FileLine* fl, AstNode* stmtsp)
|
||||
: ASTGEN_SUPER_InitialAutomaticStmt(fl) {
|
||||
addStmtsp(stmtsp);
|
||||
}
|
||||
ASTGEN_MEMBERS_AstInitialAutomaticStmt;
|
||||
int instrCount() const override { return 0; }
|
||||
bool isPure() override { return true; }
|
||||
};
|
||||
class AstInitialStaticStmt final : public AstNodeStmt {
|
||||
// Static variable initialization in a statement position
|
||||
// Used during early stages to record a static initialization of a variable
|
||||
// Moves later to an appropriate constructor, or AstInitialStatic, or
|
||||
// AstCFunc normal statement
|
||||
// Children: {statement list usually only with assignments}
|
||||
// @astgen op1 := stmtsp : List[AstNode]
|
||||
public:
|
||||
AstInitialStaticStmt(FileLine* fl, AstNode* stmtsp)
|
||||
: ASTGEN_SUPER_InitialStaticStmt(fl) {
|
||||
addStmtsp(stmtsp);
|
||||
}
|
||||
ASTGEN_MEMBERS_AstInitialStaticStmt;
|
||||
int instrCount() const override { return 0; }
|
||||
bool isPure() override { return true; }
|
||||
};
|
||||
class AstJumpBlock final : public AstNodeStmt {
|
||||
// Block of code that might contain AstJumpGo statements as children,
|
||||
// which when exectued branch to right after the referenced AstJumpBlock.
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ class BeginVisitor final : public VNVisitor {
|
|||
// STATE - for current visit position (use VL_RESTORER)
|
||||
AstNodeModule* m_modp = nullptr; // Current module
|
||||
AstNodeFTask* m_ftaskp = nullptr; // Current function/task
|
||||
AstNodeProcedure* m_procedurep = nullptr; // Current procedure
|
||||
AstNode* m_liftedp = nullptr; // Local nodes we are lifting into m_ftaskp
|
||||
string m_displayScope; // Name of %m in $display/AstScopeName
|
||||
string m_namedScope; // Name of begin blocks above us
|
||||
|
|
@ -120,17 +121,6 @@ class BeginVisitor final : public VNVisitor {
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
void visit(AstFork* nodep) override {
|
||||
dotNames(nodep->name(), nodep->fileline(), "__FORK__");
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
{
|
||||
// Keep begins in forks to group their statements together
|
||||
VL_RESTORER(m_keepBegins);
|
||||
m_keepBegins = true;
|
||||
iterateAndNextNull(nodep->forksp());
|
||||
}
|
||||
nodep->name("");
|
||||
}
|
||||
void visit(AstForeach* nodep) override {
|
||||
VL_DO_DANGLING(V3Begin::convertToWhile(nodep), nodep);
|
||||
}
|
||||
|
|
@ -158,6 +148,11 @@ class BeginVisitor final : public VNVisitor {
|
|||
m_unnamedScope = "";
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
void visit(AstNodeProcedure* nodep) override {
|
||||
VL_RESTORER(m_procedurep);
|
||||
m_procedurep = nodep;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
void visit(AstNodeFTask* nodep) override {
|
||||
UINFO(8, " " << nodep);
|
||||
// Rename it
|
||||
|
|
@ -212,6 +207,27 @@ class BeginVisitor final : public VNVisitor {
|
|||
}
|
||||
VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
|
||||
}
|
||||
void visit(AstFork* nodep) override {
|
||||
dotNames(nodep->name(), nodep->fileline(), "__FORK__");
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
{
|
||||
// Keep begins in forks to group their statements together
|
||||
VL_RESTORER(m_keepBegins);
|
||||
m_keepBegins = true;
|
||||
iterateAndNextNull(nodep->forksp());
|
||||
}
|
||||
AstNode* addsp = nullptr;
|
||||
if (AstNode* const declsp = nodep->declsp()) {
|
||||
declsp->unlinkFrBackWithNext();
|
||||
addsp = AstNode::addNext(addsp, declsp);
|
||||
}
|
||||
if (AstNode* const stmtsp = nodep->stmtsp()) {
|
||||
stmtsp->unlinkFrBackWithNext();
|
||||
addsp = AstNode::addNext(addsp, stmtsp);
|
||||
}
|
||||
if (addsp) nodep->addHereThisAsNext(addsp);
|
||||
nodep->name("");
|
||||
}
|
||||
void visit(AstBegin* nodep) override {
|
||||
// Begin blocks were only useful in variable creation, change names and delete
|
||||
UINFO(8, " " << nodep);
|
||||
|
|
@ -246,6 +262,41 @@ class BeginVisitor final : public VNVisitor {
|
|||
}
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
void visit(AstNodeBlock* nodep) override {
|
||||
// Begin/Fork blocks were only useful in variable creation, change names and delete
|
||||
UINFO(8, " " << nodep);
|
||||
VL_RESTORER(m_displayScope);
|
||||
VL_RESTORER(m_namedScope);
|
||||
VL_RESTORER(m_unnamedScope);
|
||||
{
|
||||
VL_RESTORER(m_keepBegins);
|
||||
m_keepBegins = VN_IS(nodep, Fork);
|
||||
dotNames(nodep->name(), nodep->fileline(),
|
||||
VN_IS(nodep, Fork) ? "__FORK__" : "__BEGIN__");
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
if (m_keepBegins) {
|
||||
nodep->name("");
|
||||
return;
|
||||
}
|
||||
AstNode* addsp = nullptr;
|
||||
if (AstNode* const declsp = nodep->declsp()) {
|
||||
declsp->unlinkFrBackWithNext();
|
||||
addsp = AstNode::addNext(addsp, declsp);
|
||||
}
|
||||
if (AstNode* const stmtsp = nodep->stmtsp()) {
|
||||
stmtsp->unlinkFrBackWithNext();
|
||||
addsp = AstNode::addNext(addsp, stmtsp);
|
||||
}
|
||||
if (addsp) {
|
||||
nodep->replaceWith(addsp);
|
||||
} else {
|
||||
nodep->unlinkFrBack();
|
||||
}
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
void visit(AstVar* nodep) override {
|
||||
// If static variable, move it outside a function.
|
||||
if (nodep->lifetime().isStatic() && m_ftaskp) {
|
||||
|
|
@ -263,6 +314,28 @@ class BeginVisitor final : public VNVisitor {
|
|||
liftNode(nodep);
|
||||
}
|
||||
}
|
||||
void visit(AstInitialAutomaticStmt* nodep) override {
|
||||
// Automatic sets go at the current location
|
||||
nodep->replaceWith(nodep->stmtsp()->unlinkFrBackWithNext());
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
void visit(AstInitialStaticStmt* nodep) override {
|
||||
// As we moved static variables, move static initializers too
|
||||
if (nodep->user1SetOnce()) return; // Don't double-add text's
|
||||
AstNode* wasUnderp = m_ftaskp;
|
||||
if (!m_ftaskp) wasUnderp = m_procedurep;
|
||||
if (wasUnderp) {
|
||||
if (nodep->stmtsp()) {
|
||||
AstNode* const newp = new AstInitialStatic{
|
||||
nodep->fileline(), nodep->stmtsp()->unlinkFrBackWithNext()};
|
||||
wasUnderp->addHereThisAsNext(newp);
|
||||
iterateChildren(newp);
|
||||
}
|
||||
VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
|
||||
} else {
|
||||
nodep->v3fatalSrc("InitialStaticStmt under unexpected grand-parent");
|
||||
}
|
||||
}
|
||||
void visit(AstTypedef* nodep) override {
|
||||
if (m_unnamedScope != "") {
|
||||
// Rename it
|
||||
|
|
|
|||
|
|
@ -3329,6 +3329,17 @@ class ConstVisitor final : public VNVisitor {
|
|||
varrefp->varp()->valuep(initvaluep);
|
||||
}
|
||||
}
|
||||
void visit(AstCReset* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (!m_doNConst) return;
|
||||
const AstBasicDType* const bdtypep = VN_CAST(nodep->dtypep()->skipRefp(), BasicDType);
|
||||
if (!bdtypep) return;
|
||||
if (!bdtypep->isZeroInit()) return;
|
||||
AstConst* const newp = new AstConst{nodep->fileline(), V3Number{nodep, bdtypep}};
|
||||
UINFO(9, "CRESET(0) => CONST(0) " << nodep);
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
void visit(AstCvtArrayToArray* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
// Handle the case where we have a stream operation inside a cast conversion
|
||||
|
|
|
|||
|
|
@ -456,21 +456,22 @@ void EmitCFunc::emitCCallArgs(const AstNodeCCall* nodep, const string& selfPoint
|
|||
puts(")");
|
||||
}
|
||||
|
||||
void EmitCFunc::emitDereference(AstNode* nodep, const string& pointer) {
|
||||
std::string EmitCFunc::dereferenceString(const std::string& pointer) {
|
||||
if (pointer[0] == '(' && pointer[1] == '&') {
|
||||
// remove "address of" followed by immediate dereference
|
||||
// Note: this relies on only the form '(&OBJECT)' being used by Verilator
|
||||
putns(nodep, pointer.substr(2, pointer.length() - 3));
|
||||
puts(".");
|
||||
return pointer.substr(2, pointer.length() - 3) + '.';
|
||||
} else {
|
||||
if (pointer == "vlSelf" && m_usevlSelfRef) {
|
||||
puts("vlSelfRef.");
|
||||
return "vlSelfRef.";
|
||||
} else {
|
||||
putns(nodep, pointer);
|
||||
puts("->");
|
||||
return pointer + "->";
|
||||
}
|
||||
}
|
||||
}
|
||||
void EmitCFunc::emitDereference(AstNode* nodep, const string& pointer) {
|
||||
putns(nodep, dereferenceString(pointer));
|
||||
}
|
||||
|
||||
void EmitCFunc::emitCvtPackStr(AstNode* nodep) {
|
||||
if (const AstConst* const constp = VN_CAST(nodep, Const)) {
|
||||
|
|
@ -527,13 +528,16 @@ void EmitCFunc::emitSetVarConstant(const string& assignString, AstConst* constp)
|
|||
puts(";\n");
|
||||
}
|
||||
|
||||
void EmitCFunc::emitVarReset(AstVar* varp, bool constructing) {
|
||||
// 'constructing' indicates that the object was just constructed, so no need to clear it also
|
||||
void EmitCFunc::emitVarReset(const string& prefix, AstVar* varp, bool constructing) {
|
||||
// 'constructing' indicates that the object was just constructed, so if it is a string or
|
||||
// something that starts off clear already, no need to clear it again
|
||||
AstNodeDType* const dtypep = varp->dtypep()->skipRefp();
|
||||
const string vlSelf = VSelfPointerText::replaceThis(m_useSelfForThis, "this->");
|
||||
const string varNameProtected = (VN_IS(m_modp, Class) || varp->isFuncLocal())
|
||||
? varp->nameProtect()
|
||||
: vlSelf + varp->nameProtect();
|
||||
const string varNameProtected
|
||||
= ((VN_IS(m_modp, Class) || varp->isFuncLocal()) || !prefix.empty())
|
||||
? varp->nameProtect()
|
||||
: vlSelf + varp->nameProtect();
|
||||
const string newPrefix = prefix + varNameProtected;
|
||||
if (varp->isIO() && m_modp->isTop() && optSystemC()) {
|
||||
// System C top I/O doesn't need loading, as the lower level subinst code does it.}
|
||||
} else if (varp->isParam()) {
|
||||
|
|
@ -546,47 +550,45 @@ void EmitCFunc::emitVarReset(AstVar* varp, bool constructing) {
|
|||
// TODO merge this functionality with V3EmitCConstInit.h visitors
|
||||
if (VN_IS(dtypep, AssocArrayDType)) {
|
||||
if (initarp->defaultp()) {
|
||||
emitSetVarConstant(varNameProtected + ".atDefault()",
|
||||
VN_AS(initarp->defaultp(), Const));
|
||||
emitSetVarConstant(newPrefix + ".atDefault()", VN_AS(initarp->defaultp(), Const));
|
||||
}
|
||||
if (!constructing) puts(varNameProtected + ".clear();");
|
||||
const auto& mapr = initarp->map();
|
||||
for (const auto& itr : mapr) {
|
||||
AstNode* const valuep = itr.second->valuep();
|
||||
emitSetVarConstant(varNameProtected + ".at(" + cvtToStr(itr.first) + ")",
|
||||
emitSetVarConstant(newPrefix + ".at(" + cvtToStr(itr.first) + ")",
|
||||
VN_AS(valuep, Const));
|
||||
}
|
||||
} else if (VN_IS(dtypep, WildcardArrayDType)) {
|
||||
if (initarp->defaultp()) {
|
||||
emitSetVarConstant(varNameProtected + ".atDefault()",
|
||||
VN_AS(initarp->defaultp(), Const));
|
||||
emitSetVarConstant(newPrefix + ".atDefault()", VN_AS(initarp->defaultp(), Const));
|
||||
}
|
||||
if (!constructing) puts(varNameProtected + ".clear();");
|
||||
if (!constructing) puts(newPrefix + ".clear();");
|
||||
const auto& mapr = initarp->map();
|
||||
for (const auto& itr : mapr) {
|
||||
AstNode* const valuep = itr.second->valuep();
|
||||
emitSetVarConstant(varNameProtected + ".at(" + cvtToStr(itr.first) + ")",
|
||||
emitSetVarConstant(newPrefix + ".at(" + cvtToStr(itr.first) + ")",
|
||||
VN_AS(valuep, Const));
|
||||
}
|
||||
} else if (AstUnpackArrayDType* const adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
|
||||
if (initarp->defaultp()) {
|
||||
puts("for (int __Vi = 0; __Vi < " + cvtToStr(adtypep->elementsConst()));
|
||||
puts("; ++__Vi) {\n");
|
||||
emitSetVarConstant(varNameProtected + "[__Vi]", VN_AS(initarp->defaultp(), Const));
|
||||
emitSetVarConstant(newPrefix + "[__Vi]", VN_AS(initarp->defaultp(), Const));
|
||||
puts("}\n");
|
||||
}
|
||||
const auto& mapr = initarp->map();
|
||||
for (const auto& itr : mapr) {
|
||||
AstNode* const valuep = itr.second->valuep();
|
||||
emitSetVarConstant(varNameProtected + "[" + cvtToStr(itr.first) + "]",
|
||||
emitSetVarConstant(newPrefix + "[" + cvtToStr(itr.first) + "]",
|
||||
VN_AS(valuep, Const));
|
||||
}
|
||||
} else {
|
||||
varp->v3fatalSrc("InitArray under non-arrayed var");
|
||||
}
|
||||
} else {
|
||||
putns(varp, emitVarResetRecurse(varp, constructing, varNameProtected, dtypep, 0, "",
|
||||
varp->valuep()));
|
||||
putns(varp,
|
||||
emitVarResetRecurse(varp, constructing, newPrefix, dtypep, 0, "", varp->valuep()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -209,12 +209,13 @@ public:
|
|||
AstNode* thsp);
|
||||
void emitCCallArgs(const AstNodeCCall* nodep, const string& selfPointer, bool inProcess);
|
||||
void emitDereference(AstNode* nodep, const string& pointer);
|
||||
std::string dereferenceString(const std::string& pointer);
|
||||
void emitCvtPackStr(AstNode* nodep);
|
||||
void emitCvtWideArray(AstNode* nodep, AstNode* fromp);
|
||||
void emitConstant(AstConst* nodep);
|
||||
void emitConstantString(const AstConst* nodep);
|
||||
void emitSetVarConstant(const string& assignString, AstConst* constp);
|
||||
void emitVarReset(AstVar* varp, bool constructing);
|
||||
void emitVarReset(const string& prefix, AstVar* varp, bool constructing);
|
||||
string emitVarResetRecurse(const AstVar* varp, bool constructing,
|
||||
const string& varNameProtected, AstNodeDType* dtypep, int depth,
|
||||
const string& suffix, const AstNode* valuep);
|
||||
|
|
@ -526,8 +527,29 @@ public:
|
|||
|
||||
void visit(AstNodeAssign* nodep) override {
|
||||
if (AstCReset* const resetp = VN_CAST(nodep->rhsp(), CReset)) {
|
||||
AstVar* const varp = VN_AS(nodep->lhsp(), NodeVarRef)->varp();
|
||||
emitVarReset(varp, resetp->constructing());
|
||||
// TODO get rid of emitVarReset and instead let AstNodeAssign understand how to init
|
||||
// anything
|
||||
AstNode* fromp = nodep->lhsp();
|
||||
// Fork needs to use a member select. Nothing else should be possible before VarRef.
|
||||
if (AstMemberSel* const sfromp = VN_CAST(fromp, MemberSel)) {
|
||||
// Fork-DynScope generated pointer to previously automatic variable
|
||||
AstVar* const memberVarp = sfromp->varp();
|
||||
fromp = sfromp->fromp();
|
||||
if (AstNullCheck* const sfromp = VN_CAST(fromp, NullCheck)) fromp = sfromp->lhsp();
|
||||
AstNodeVarRef* const fromVarRefp = VN_AS(fromp, NodeVarRef);
|
||||
emitVarReset(
|
||||
("VL_NULL_CHECK("s
|
||||
+ (fromVarRefp->selfPointer().isEmpty()
|
||||
? ""
|
||||
: dereferenceString(fromVarRefp->selfPointerProtect(m_useSelfForThis)))
|
||||
+ fromVarRefp->varp()->nameProtect() + ", \""
|
||||
+ V3OutFormatter::quoteNameControls(protect(nodep->fileline()->filename()))
|
||||
+ "\", " + std::to_string(nodep->fileline()->lineno()) + ")->"),
|
||||
memberVarp, resetp->constructing());
|
||||
} else {
|
||||
AstVar* const varp = VN_AS(fromp, NodeVarRef)->varp();
|
||||
emitVarReset("", varp, resetp->constructing());
|
||||
}
|
||||
return;
|
||||
}
|
||||
bool paren = true;
|
||||
|
|
|
|||
|
|
@ -182,6 +182,8 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public VNVisitorConst {
|
|||
}
|
||||
void visit(AstInitialAutomatic* nodep) override { iterateChildrenConst(nodep); }
|
||||
void visit(AstInitialStatic* nodep) override { iterateChildrenConst(nodep); }
|
||||
void visit(AstInitialAutomaticStmt* nodep) override { iterateChildrenConst(nodep); }
|
||||
void visit(AstInitialStaticStmt* nodep) override { iterateChildrenConst(nodep); }
|
||||
void visit(AstAlways* nodep) override {
|
||||
if (const AstAssignW* const ap = VN_CAST(nodep->stmtsp(), AssignW)) {
|
||||
if (!ap->nextp()) {
|
||||
|
|
|
|||
|
|
@ -335,13 +335,31 @@ class DynScopeVisitor final : public VNVisitor {
|
|||
auto r = m_frames.emplace(nodep, framep);
|
||||
if (r.second) m_frameOrder.push_back(nodep);
|
||||
}
|
||||
void bindInitIterate(AstNode* stmtsp, ForkDynScopeFrame* framep) {
|
||||
for (AstNode* stmtp = stmtsp; stmtp; stmtp = stmtp->nextp()) {
|
||||
if (AstAssign* const asgnp = VN_CAST(stmtp, Assign)) {
|
||||
bindNodeToDynScope(asgnp->lhsp(), framep);
|
||||
iterate(asgnp->rhsp());
|
||||
} else if (AstInitialAutomaticStmt* astmtp
|
||||
= VN_CAST(stmtp, InitialAutomaticStmt)) { // Moves in V3Begin
|
||||
// Underlying assign RHS might use function argument, so can't just
|
||||
// move whole thing into the new class's constructor/statements
|
||||
bindInitIterate(astmtp->stmtsp(), framep);
|
||||
} else if (AstInitialStaticStmt* astmtp
|
||||
= VN_CAST(stmtp, InitialStaticStmt)) { // Moves in V3Begin
|
||||
bindInitIterate(astmtp->stmtsp(), framep);
|
||||
} else {
|
||||
stmtp->v3fatalSrc("Invalid node under block item initialization part of fork");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool needsDynScope(const AstVarRef* refp) const {
|
||||
const AstVar* const varp = refp->varp();
|
||||
const bool localLifetime = varp->isFuncLocal() || varp->lifetime().isAutomatic();
|
||||
return
|
||||
// Can this variable escape the scope
|
||||
((m_forkDepth > varp->user1()) && localLifetime)
|
||||
((m_forkDepth > varp->user1()) && varp->isFuncLocal())
|
||||
&& varp->lifetime().isAutomatic()
|
||||
&& (
|
||||
// Is it mutated
|
||||
(varp->isClassHandleValue() ? refp->user2() : refp->access().isWriteOrRW())
|
||||
|
|
@ -384,18 +402,14 @@ class DynScopeVisitor final : public VNVisitor {
|
|||
for (AstNode* declp = nodep->declsp(); declp; declp = declp->nextp()) {
|
||||
AstVar* const varp = VN_CAST(declp, Var);
|
||||
UASSERT_OBJ(varp, declp, "Invalid node under block item initialization part of fork");
|
||||
if (!framep->instance().initialized()) framep->createInstancePrototype();
|
||||
framep->captureVarInsert(varp);
|
||||
bindNodeToDynScope(varp, framep);
|
||||
}
|
||||
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
if (AstAssign* const asgnp = VN_CAST(stmtp, Assign)) {
|
||||
bindNodeToDynScope(asgnp->lhsp(), framep);
|
||||
iterate(asgnp->rhsp());
|
||||
} else {
|
||||
stmtp->v3fatalSrc("Invalid node under block item initialization part of fork");
|
||||
UASSERT_OBJ(!varp->lifetime().isNone(), nodep, "Variable's lifetime is unknown");
|
||||
if (varp->lifetime().isAutomatic()) { // else V3Begin will move later
|
||||
if (!framep->instance().initialized()) framep->createInstancePrototype();
|
||||
framep->captureVarInsert(varp);
|
||||
bindNodeToDynScope(varp, framep);
|
||||
}
|
||||
}
|
||||
bindInitIterate(nodep->stmtsp(), framep);
|
||||
|
||||
for (AstNode* stmtp = nodep->forksp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
m_afterTimingControl = false;
|
||||
|
|
@ -526,6 +540,7 @@ class ForkVisitor final : public VNVisitor {
|
|||
|
||||
// STATE - for current AstFork item
|
||||
bool m_inFork = false; // Traversal in an async fork
|
||||
bool m_inInitStmt = false; // Traversal in InitialStaticStmt/InitialAutomaticStmt
|
||||
std::set<AstVar*> m_forkLocalsp; // Variables local to a given fork
|
||||
AstVar* m_capturedVarsp = nullptr; // Local copies of captured variables
|
||||
AstArg* m_capturedArgsp = nullptr; // References to captured variables (as args)
|
||||
|
|
@ -650,7 +665,8 @@ class ForkVisitor final : public VNVisitor {
|
|||
// If this ref is to a variable that will move into the task, then nothing to do
|
||||
if (m_forkLocalsp.count(varp)) return;
|
||||
|
||||
if (nodep->access().isWriteOrRW() && (!nodep->isClassHandleValue() || nodep->user2())) {
|
||||
if (nodep->access().isWriteOrRW() && (!nodep->isClassHandleValue() || nodep->user2())
|
||||
&& !m_inInitStmt) {
|
||||
nodep->v3warn(
|
||||
E_LIFETIME,
|
||||
"Invalid reference: Process might outlive variable "
|
||||
|
|
@ -671,6 +687,17 @@ class ForkVisitor final : public VNVisitor {
|
|||
}
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
void visit(AstInitialAutomaticStmt* nodep) override {
|
||||
VL_RESTORER(m_inInitStmt);
|
||||
m_inInitStmt = true;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
void visit(AstInitialStaticStmt* nodep) override {
|
||||
VL_RESTORER(m_inInitStmt);
|
||||
m_inInitStmt = true;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
void visit(AstThisRef* nodep) override {}
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
|
|
|
|||
|
|
@ -456,6 +456,13 @@ class GateOkVisitor final : public VNVisitorConst {
|
|||
clearSimple("Not a buffer (goes to a clock)");
|
||||
}
|
||||
}
|
||||
void visit(AstCReset* nodep) override {
|
||||
if (!m_isSimple) return;
|
||||
// CReset is pure because we can optimize assignments, but if is
|
||||
// the only assignment to a variable we still need to initial
|
||||
// assign to get randomization etc
|
||||
clearSimple("CReset");
|
||||
}
|
||||
//--------------------
|
||||
void visit(AstNode* nodep) override {
|
||||
if (!m_isSimple) return; // Fastpath
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ class LinkLValueVisitor final : public VNVisitor {
|
|||
bool m_setStrengthSpecified = false; // Set that var has assignment with strength specified.
|
||||
bool m_inFunc = false; // Set if inside AstNodeFTask
|
||||
bool m_inInitialStatic = false; // Set if inside AstInitialStatic
|
||||
bool m_inInitialStaticStmt = false; // Set if inside AstInitialStaticStmt
|
||||
VAccess m_setRefLvalue; // Set VarRefs to lvalues for pin assignments
|
||||
|
||||
// VISITORS
|
||||
|
|
@ -113,7 +114,7 @@ class LinkLValueVisitor final : public VNVisitor {
|
|||
iterateAndNextNull(nodep->rhsp());
|
||||
}
|
||||
|
||||
if (m_inInitialStatic && m_inFunc) {
|
||||
if ((m_inInitialStatic || m_inInitialStaticStmt) && m_inFunc) {
|
||||
const bool rhsHasIO = nodep->rhsp()->exists([](const AstNodeVarRef* const refp) {
|
||||
// Exclude module I/O referenced from a function/task.
|
||||
return refp->varp() && refp->varp()->isIO()
|
||||
|
|
@ -147,6 +148,11 @@ class LinkLValueVisitor final : public VNVisitor {
|
|||
m_inInitialStatic = true;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
void visit(AstInitialStaticStmt* nodep) override {
|
||||
VL_RESTORER(m_inInitialStaticStmt);
|
||||
m_inInitialStaticStmt = true;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
void visit(AstRelease* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
VL_RESTORER(m_setContinuously);
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ class LinkParseVisitor final : public VNVisitor {
|
|||
AstNodeProcedure* m_procedurep = nullptr; // Current procedure
|
||||
AstNodeFTask* m_ftaskp = nullptr; // Current task
|
||||
AstNodeBlock* m_blockp = nullptr; // Current AstNodeBlock
|
||||
AstNodeStmt* m_blockAddAutomaticStmtp = nullptr; // Initial statements to add to block
|
||||
AstNodeStmt* m_blockAddStaticStmtp = nullptr; // Initial statements to add to block
|
||||
AstNodeDType* m_dtypep = nullptr; // Current data type
|
||||
AstNodeExpr* m_defaultInSkewp = nullptr; // Current default input skew
|
||||
AstNodeExpr* m_defaultOutSkewp = nullptr; // Current default output skew
|
||||
|
|
@ -66,9 +68,9 @@ class LinkParseVisitor final : public VNVisitor {
|
|||
int m_beginDepth = 0; // How many begin blocks above current node within current AstNodeModule
|
||||
int m_randSequenceNum = 0; // RandSequence uniqify number
|
||||
VLifetime m_lifetime = VLifetime::STATIC_IMPLICIT; // Propagating lifetime
|
||||
bool m_insideLoop = false; // True if the node is inside a loop
|
||||
bool m_lifetimeAllowed = false; // True to allow lifetime settings
|
||||
bool m_moduleWithGenericIface = false; // If current module contains generic interface
|
||||
std::set<AstVar*> m_portDups; // Non-ANSI port datatype duplicating input/output decls
|
||||
|
||||
// STATE - Statistic tracking
|
||||
VDouble0 m_statModules; // Number of modules seen
|
||||
|
|
@ -181,6 +183,54 @@ class LinkParseVisitor final : public VNVisitor {
|
|||
<< nodep->warnContextSecondary());
|
||||
}
|
||||
|
||||
void collectPorts(AstNode* nodeListp) {
|
||||
// V3LinkDot hasn't run yet, so have VAR for pre-IEEE 'input' and
|
||||
// separate var for pre-IEEE 'integer'.
|
||||
std::unordered_map<std::string, AstVar*> portNames;
|
||||
for (AstNode* nodep = nodeListp; nodep; nodep = nodep->nextp()) {
|
||||
if (AstVar* const varp = VN_CAST(nodep, Var)) {
|
||||
if (varp->isIO()) portNames.emplace(varp->name(), varp);
|
||||
}
|
||||
}
|
||||
for (AstNode* nodep = nodeListp; nodep; nodep = nodep->nextp()) {
|
||||
if (AstVar* const varp = VN_CAST(nodep, Var)) {
|
||||
if (varp->isIO()) continue;
|
||||
const auto it = portNames.find(varp->name());
|
||||
if (it == portNames.end()) continue;
|
||||
AstVar* const iop = it->second;
|
||||
UINFO(9, "Non-ANSI port dtype declaration " << varp);
|
||||
if (!iop->valuep() && varp->valuep())
|
||||
iop->valuep(varp->valuep()->unlinkFrBackWithNext());
|
||||
m_portDups.emplace(varp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AstNode* getVarsAndUnlink(AstNode* stmtsp) {
|
||||
AstNode* varsp = nullptr;
|
||||
for (AstNode *nextp, *itemp = stmtsp; itemp; itemp = nextp) {
|
||||
nextp = itemp->nextp();
|
||||
if (VN_IS(itemp, Var)) varsp = AstNode::addNext(varsp, itemp->unlinkFrBack());
|
||||
}
|
||||
return varsp;
|
||||
}
|
||||
AstNodeStmt* getBlockAdds() {
|
||||
AstNodeStmt* addsp = nullptr;
|
||||
// Add a single AstInitial...Stmt as the statements within may
|
||||
// depend on each other, e.g. "var a=1; var b=a;" (but must be a constant expression)
|
||||
if (m_blockAddStaticStmtp)
|
||||
addsp = AstNode::addNext(addsp,
|
||||
new AstInitialStaticStmt{m_blockAddStaticStmtp->fileline(),
|
||||
m_blockAddStaticStmtp});
|
||||
if (m_blockAddAutomaticStmtp)
|
||||
addsp = AstNode::addNext(
|
||||
addsp, new AstInitialAutomaticStmt{m_blockAddAutomaticStmtp->fileline(),
|
||||
m_blockAddAutomaticStmtp});
|
||||
m_blockAddStaticStmtp = nullptr;
|
||||
m_blockAddAutomaticStmtp = nullptr;
|
||||
return addsp;
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
void visit(AstNodeFTask* nodep) override {
|
||||
if (nodep->user1SetOnce()) return; // Process only once.
|
||||
|
|
@ -191,6 +241,10 @@ class LinkParseVisitor final : public VNVisitor {
|
|||
cleanFileline(nodep);
|
||||
VL_RESTORER(m_ftaskp);
|
||||
m_ftaskp = nodep;
|
||||
VL_RESTORER(m_blockAddAutomaticStmtp);
|
||||
m_blockAddAutomaticStmtp = nullptr;
|
||||
VL_RESTORER(m_blockAddStaticStmtp);
|
||||
m_blockAddStaticStmtp = nullptr;
|
||||
VL_RESTORER(m_lifetime);
|
||||
VL_RESTORER(m_lifetimeAllowed);
|
||||
m_lifetimeAllowed = true;
|
||||
|
|
@ -212,7 +266,26 @@ class LinkParseVisitor final : public VNVisitor {
|
|||
<< nodep->warnMore() << "... May have intended 'static "
|
||||
<< nodep->verilogKwd() << "'");
|
||||
}
|
||||
|
||||
VL_RESTORER(m_portDups);
|
||||
collectPorts(nodep->stmtsp());
|
||||
|
||||
iterateChildren(nodep);
|
||||
|
||||
// If let, the statement must go first
|
||||
AstNode* stmtsp = nullptr;
|
||||
if (VN_IS(nodep, Let) && nodep->stmtsp()) stmtsp = nodep->stmtsp()->unlinkFrBack();
|
||||
// Move all Vars to front of function
|
||||
stmtsp = AstNode::addNextNull(stmtsp, getVarsAndUnlink(nodep->stmtsp()));
|
||||
// Follow vars by m_blockAddp's (if any)
|
||||
stmtsp = AstNode::addNextNull(stmtsp, getBlockAdds());
|
||||
if (stmtsp) {
|
||||
if (nodep->stmtsp()) {
|
||||
nodep->stmtsp()->addHereThisAsNext(stmtsp);
|
||||
} else {
|
||||
nodep->addStmtsp(stmtsp);
|
||||
}
|
||||
}
|
||||
}
|
||||
void visit(AstNodeDType* nodep) override { visitIterateNodeDType(nodep); }
|
||||
void visit(AstConstraint* nodep) override {
|
||||
|
|
@ -267,19 +340,13 @@ class LinkParseVisitor final : public VNVisitor {
|
|||
cleanFileline(nodep);
|
||||
UINFO(9, "VAR " << nodep);
|
||||
if (nodep->valuep()) nodep->hasUserInit(true);
|
||||
if (m_insideLoop && nodep->lifetime().isNone() && nodep->varType() == VVarType::VAR
|
||||
&& !nodep->direction().isAny()) {
|
||||
nodep->lifetime(VLifetime::AUTOMATIC_IMPLICIT);
|
||||
}
|
||||
if (nodep->lifetime().isStatic() && m_insideLoop && nodep->valuep()) {
|
||||
nodep->lifetime(VLifetime::AUTOMATIC_IMPLICIT);
|
||||
nodep->v3warn(STATICVAR, "Static variable with assignment declaration declared in a "
|
||||
"loop converted to automatic");
|
||||
} else if (nodep->valuep() && nodep->lifetime().isNone() && m_lifetime.isStatic()
|
||||
&& !nodep->isIO()
|
||||
&& !nodep->isParam()
|
||||
// In task, or a procedure but not Initial/Final as executed only once
|
||||
&& ((m_ftaskp && !m_ftaskp->lifetime().isStaticExplicit()) || m_procedurep)) {
|
||||
// IEEE 1800-2026 6.21: for loop variables are automatic. verilog.y is
|
||||
// responsible for marking those.
|
||||
if (nodep->valuep() && nodep->lifetime().isNone() && m_lifetime.isStatic()
|
||||
&& !nodep->isIO()
|
||||
&& !nodep->isParam()
|
||||
// In task, or a procedure but not Initial/Final as executed only once
|
||||
&& ((m_ftaskp && !m_ftaskp->lifetime().isStaticExplicit()) || m_procedurep)) {
|
||||
if (VN_IS(m_modp, Module) && m_ftaskp) {
|
||||
m_ftaskp->v3warn(
|
||||
IMPLICITSTATIC,
|
||||
|
|
@ -415,43 +482,75 @@ class LinkParseVisitor final : public VNVisitor {
|
|||
// temporaries under an always aren't expected to be blocking
|
||||
if (m_procedurep && VN_IS(m_procedurep, Always))
|
||||
nodep->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true);
|
||||
if (nodep->valuep()) {
|
||||
FileLine* const fl = nodep->valuep()->fileline();
|
||||
// A variable with an = value can be 4 things:
|
||||
if (nodep->isParam() || (m_ftaskp && nodep->isNonOutput())) {
|
||||
// Compute initial value
|
||||
if (nodep->valuep() || nodep->needsCReset()) {
|
||||
FileLine* const fl = nodep->valuep() ? nodep->valuep()->fileline() : nodep->fileline();
|
||||
auto createValuep = [&]() -> AstNodeExpr* {
|
||||
if (nodep->valuep()) {
|
||||
return VN_AS(nodep->valuep()->unlinkFrBack(), NodeExpr);
|
||||
} else {
|
||||
return new AstCReset{fl, nodep, false};
|
||||
}
|
||||
};
|
||||
// A variable can be in these positions related to having an initial value (or not):
|
||||
if (m_portDups.find(nodep) != m_portDups.end()) {
|
||||
// 0. Non-ANSI type declaration that is really a port, but we haven't resolved yet
|
||||
// Earlier moved any valuep() under the duplicate to the IO declaration
|
||||
UINFO(9, "VarInit case0 " << nodep);
|
||||
} else if (nodep->isParam() || nodep->isGenVar()
|
||||
|| (m_ftaskp && (nodep->isNonOutput() || nodep->isFuncReturn()))) {
|
||||
// 1. Parameters and function inputs: It's a default to use if not overridden
|
||||
UINFO(9, "VarInit case1 " << nodep);
|
||||
} else if (!m_ftaskp && !VN_IS(m_modp, Class) && nodep->isNonOutput()
|
||||
&& !nodep->isInput()) {
|
||||
// 2. Module inout/ref/constref: const default to use
|
||||
nodep->v3warn(E_UNSUPPORTED,
|
||||
"Unsupported: Default value on module inout/ref/constref: "
|
||||
<< nodep->prettyNameQ());
|
||||
nodep->valuep()->unlinkFrBack()->deleteTree();
|
||||
} else if (m_blockp) {
|
||||
UINFO(9, "VarInit case2 " << nodep);
|
||||
if (nodep->valuep()) {
|
||||
nodep->v3warn(E_UNSUPPORTED,
|
||||
"Unsupported: Default value on module inout/ref/constref: "
|
||||
<< nodep->prettyNameQ());
|
||||
nodep->valuep()->unlinkFrBack()->deleteTree();
|
||||
}
|
||||
} else if (m_blockp || m_ftaskp) {
|
||||
// 3. Under blocks, it's an initial value to be under an assign
|
||||
// TODO: This is wrong if it's a static variable right?
|
||||
UINFO(9, "VarInit case3 " << nodep);
|
||||
nodep->noCReset(true);
|
||||
FileLine* const newfl = new FileLine{fl};
|
||||
newfl->warnOff(V3ErrorCode::E_CONSTWRITTEN, true);
|
||||
m_blockp->addStmtsp(
|
||||
new AstAssign{newfl, new AstVarRef{newfl, nodep, VAccess::WRITE},
|
||||
VN_AS(nodep->valuep()->unlinkFrBack(), NodeExpr)});
|
||||
AstAssign* const assp
|
||||
= new AstAssign{newfl, new AstParseRef{newfl, nodep->name()}, createValuep()};
|
||||
if (nodep->lifetime().isAutomatic()) {
|
||||
// May later make: new AstInitialAutomaticStmt{newfl, assp};
|
||||
m_blockAddAutomaticStmtp = AstNode::addNext(m_blockAddAutomaticStmtp, assp);
|
||||
} else {
|
||||
// May later make: new AstInitialStaticStmt{newfl, assp};
|
||||
m_blockAddStaticStmtp = AstNode::addNext(m_blockAddStaticStmtp, assp);
|
||||
}
|
||||
} else if (m_valueModp) {
|
||||
// 4. Under modules/class, it's the time 0 initialziation value
|
||||
// Making an AstAssign (vs AstAssignW) to a wire is an error, suppress it
|
||||
FileLine* const newfl = new FileLine{fl};
|
||||
newfl->warnOff(V3ErrorCode::PROCASSWIRE, true);
|
||||
newfl->warnOff(V3ErrorCode::E_CONSTWRITTEN, true);
|
||||
// Create a ParseRef to the wire. We cannot use the var as it may be deleted if
|
||||
// it's a port (see t_var_set_link.v)
|
||||
AstAssign* const assp
|
||||
= new AstAssign{newfl, new AstParseRef{newfl, nodep->name()},
|
||||
VN_AS(nodep->valuep()->unlinkFrBack(), NodeExpr)};
|
||||
if (nodep->lifetime().isAutomatic()) {
|
||||
nodep->addNextHere(new AstInitialAutomatic{newfl, assp});
|
||||
} else {
|
||||
nodep->addNextHere(new AstInitialStatic{newfl, assp});
|
||||
UINFO(9, "VarInit case4 " << nodep);
|
||||
if (nodep->valuep()) {
|
||||
nodep->noCReset(true);
|
||||
FileLine* const newfl = new FileLine{fl};
|
||||
newfl->warnOff(V3ErrorCode::PROCASSWIRE, true);
|
||||
newfl->warnOff(V3ErrorCode::E_CONSTWRITTEN, true);
|
||||
// Create a ParseRef to the wire. We cannot use the var as it may be deleted if
|
||||
// it's a port (see t_var_set_link.v)
|
||||
AstAssign* const assp = new AstAssign{
|
||||
newfl, new AstParseRef{newfl, nodep->name()}, createValuep()};
|
||||
AstNode* newInitp;
|
||||
// Must make a unique InitialAutomatic/Static for each
|
||||
// variable or otherwise V3Gate will assume ordering
|
||||
// within, and not properly optimize.
|
||||
if (nodep->lifetime().isAutomatic()) {
|
||||
newInitp = new AstInitialAutomatic{newfl, assp};
|
||||
} else {
|
||||
newInitp = new AstInitialStatic{newfl, assp};
|
||||
}
|
||||
nodep->addNextHere(newInitp);
|
||||
}
|
||||
} else {
|
||||
} else if (nodep->valuep()) {
|
||||
nodep->v3fatalSrc("Variable with initializer in unexpected position");
|
||||
}
|
||||
}
|
||||
|
|
@ -592,8 +691,6 @@ class LinkParseVisitor final : public VNVisitor {
|
|||
// 2. ASTSELBIT(first, var0))
|
||||
// 3. ASTSELLOOPVARS(first, var0..var1))
|
||||
// 4. DOT(DOT(first, second), ASTSELBIT(third, var0))
|
||||
VL_RESTORER(m_insideLoop);
|
||||
m_insideLoop = true;
|
||||
AstForeachHeader* const headerp = nodep->headerp();
|
||||
if (!headerp->elementsp()) {
|
||||
nodep->v3error("Foreach missing bracketed loop variable is no-operation"
|
||||
|
|
@ -605,15 +702,11 @@ class LinkParseVisitor final : public VNVisitor {
|
|||
}
|
||||
void visit(AstRepeat* nodep) override {
|
||||
cleanFileline(nodep);
|
||||
VL_RESTORER(m_insideLoop);
|
||||
m_insideLoop = true;
|
||||
checkIndent(nodep, nodep->stmtsp());
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
void visit(AstLoop* nodep) override {
|
||||
cleanFileline(nodep);
|
||||
VL_RESTORER(m_insideLoop);
|
||||
m_insideLoop = true;
|
||||
if (VN_IS(nodep->stmtsp(), LoopTest)) {
|
||||
checkIndent(nodep, nodep->stmtsp()->nextp());
|
||||
} else {
|
||||
|
|
@ -680,6 +773,10 @@ class LinkParseVisitor final : public VNVisitor {
|
|||
nodep->v3warn(E_UNSUPPORTED, "Module cannot be named 'TOP' as conflicts with "
|
||||
"Verilator top-level internals");
|
||||
}
|
||||
|
||||
VL_RESTORER(m_portDups);
|
||||
collectPorts(nodep->stmtsp());
|
||||
|
||||
iterateChildren(nodep);
|
||||
if (AstModule* const modp = VN_CAST(nodep, Module)) {
|
||||
modp->hasGenericIface(m_moduleWithGenericIface);
|
||||
|
|
@ -781,14 +878,14 @@ class LinkParseVisitor final : public VNVisitor {
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
void visit(AstNodeBlock* nodep) override {
|
||||
VL_RESTORER(m_blockAddAutomaticStmtp);
|
||||
m_blockAddAutomaticStmtp = nullptr;
|
||||
VL_RESTORER(m_blockAddStaticStmtp);
|
||||
m_blockAddStaticStmtp = nullptr;
|
||||
{
|
||||
VL_RESTORER(m_blockp);
|
||||
m_blockp = nodep;
|
||||
// Temporarily unlink the statements so variable initializers can be inserted in order
|
||||
AstNode* const stmtsp = nodep->stmtsp();
|
||||
if (stmtsp) stmtsp->unlinkFrBackWithNext();
|
||||
iterateAndNextNull(nodep->declsp());
|
||||
nodep->addStmtsp(stmtsp);
|
||||
}
|
||||
|
||||
if (AstBegin* const beginp = VN_CAST(nodep, Begin)) {
|
||||
|
|
@ -797,6 +894,20 @@ class LinkParseVisitor final : public VNVisitor {
|
|||
cleanFileline(nodep);
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
if (AstFork* const forkp = VN_CAST(nodep, Fork)) iterateAndNextNull(forkp->forksp());
|
||||
// Add statements created by AstVar vistor; can't do as-go because iteration
|
||||
// would then get confused, additionally we did already iterate the contents
|
||||
AstNode* stmtsp = nullptr;
|
||||
// Move all Vars to front of function
|
||||
stmtsp = AstNode::addNextNull(stmtsp, getVarsAndUnlink(nodep->stmtsp()));
|
||||
// Follow vars by m_blockAddp's (if any)
|
||||
stmtsp = AstNode::addNextNull(stmtsp, getBlockAdds());
|
||||
if (stmtsp) {
|
||||
if (nodep->stmtsp()) {
|
||||
nodep->stmtsp()->addHereThisAsNext(stmtsp);
|
||||
} else {
|
||||
nodep->addStmtsp(stmtsp);
|
||||
}
|
||||
}
|
||||
}
|
||||
void visit(AstCase* nodep) override {
|
||||
V3Control::applyCase(nodep);
|
||||
|
|
|
|||
|
|
@ -574,6 +574,14 @@ private:
|
|||
checkNodeInfo(nodep);
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
void visit(AstInitialAutomaticStmt* nodep) override {
|
||||
checkNodeInfo(nodep);
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
void visit(AstInitialStaticStmt* nodep) override {
|
||||
checkNodeInfo(nodep);
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
void visit(AstInitialStatic* nodep) override {
|
||||
if (jumpingOver()) return;
|
||||
if (!m_params) {
|
||||
|
|
|
|||
|
|
@ -836,10 +836,17 @@ public:
|
|||
// If this is AstVarRef and referred in the sensitivity list of always@,
|
||||
// return the sensitivity item
|
||||
AstSenItem* backSenItemp() const {
|
||||
if (const AstVarRef* const refp = VN_CAST(m_nodep, VarRef)) {
|
||||
return VN_CAST(refp->backp(), SenItem);
|
||||
}
|
||||
return nullptr;
|
||||
const AstVarRef* const refp = VN_CAST(m_nodep, VarRef);
|
||||
if (!refp) return nullptr;
|
||||
return VN_CAST(refp->backp(), SenItem);
|
||||
}
|
||||
AstNodeAssign* backCResetp() const {
|
||||
const AstVarRef* const refp = VN_CAST(m_nodep, VarRef);
|
||||
if (!refp) return nullptr;
|
||||
AstNodeAssign* const assp = VN_CAST(refp->backp(), NodeAssign);
|
||||
if (!assp) return nullptr;
|
||||
if (!VN_IS(assp->rhsp(), CReset)) return nullptr;
|
||||
return assp;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1027,7 +1034,8 @@ class SplitPackedVarVisitor final : public VNVisitor, public SplitVarImpl {
|
|||
UINFO(4, var.varp()->prettyNameQ() << "[" << msb << ":" << lsb << "] used for "
|
||||
<< ref.nodep()->prettyNameQ() << '\n');
|
||||
// LSB of varp is always 0. "lsb - var.lsb()" means this. see also SplitNewVar
|
||||
return new AstSel{fl, refp, lsb - var.lsb(), bitwidth};
|
||||
AstNodeExpr* const newp = new AstSel{fl, refp, lsb - var.lsb(), bitwidth};
|
||||
return newp;
|
||||
}
|
||||
}
|
||||
static void connectPortAndVar(const std::vector<SplitNewVar>& vars, AstVar* portp,
|
||||
|
|
@ -1083,6 +1091,7 @@ class SplitPackedVarVisitor final : public VNVisitor, public SplitVarImpl {
|
|||
dtypep->rangep(new AstRange{
|
||||
varp->fileline(), VNumRange{newvar.msb(), newvar.lsb(), basicp->ascending()}});
|
||||
newvar.varp(new AstVar{varp->fileline(), VVarType::VAR, name, dtypep});
|
||||
newvar.varp()->lifetime(varp->lifetime());
|
||||
newvar.varp()->propagateAttrFrom(varp);
|
||||
newvar.varp()->funcLocal(varp->isFuncLocal() || varp->isFuncReturn());
|
||||
// Enable this line to trace split variable directly:
|
||||
|
|
@ -1092,6 +1101,15 @@ class SplitPackedVarVisitor final : public VNVisitor, public SplitVarImpl {
|
|||
UINFO(4, newvar.varp()->prettyNameQ() << " is added for " << varp->prettyNameQ());
|
||||
}
|
||||
}
|
||||
static AstAssign* newAssignCReset(AstNodeAssign* cresetAssp, AstVar* attachVarp) {
|
||||
AstCReset* const cresetp = VN_AS(cresetAssp->rhsp(), CReset);
|
||||
AstCReset* const newCResetp = cresetp->cloneTree(false);
|
||||
newCResetp->dtypeFrom(attachVarp);
|
||||
AstAssign* const newp = new AstAssign{
|
||||
cresetAssp->fileline(),
|
||||
new AstVarRef{cresetAssp->fileline(), attachVarp, VAccess::WRITE}, newCResetp};
|
||||
return newp;
|
||||
}
|
||||
static void updateReferences(AstVar* varp, PackedVarRef& pref,
|
||||
const std::vector<SplitNewVar>& vars) {
|
||||
for (const bool lvalue : {false, true}) { // Refer the new split variables
|
||||
|
|
@ -1102,9 +1120,14 @@ class SplitPackedVarVisitor final : public VNVisitor, public SplitVarImpl {
|
|||
UASSERT_OBJ(varit != vars.end(), ref.nodep(), "Not found");
|
||||
UASSERT(!(varit->msb() < ref.lsb() || ref.msb() < varit->lsb()),
|
||||
"wrong search result");
|
||||
AstNode* prevp;
|
||||
AstNode* prevp = nullptr;
|
||||
bool inSentitivityList = false;
|
||||
if (AstSenItem* const senitemp = ref.backSenItemp()) {
|
||||
AstNodeAssign* const cresetAssp = ref.backCResetp();
|
||||
if (cresetAssp) {
|
||||
// ASSIGN(VARREF old, CRESET) convert to a creset of each new var
|
||||
cresetAssp->addNextHere(newAssignCReset(cresetAssp, varit->varp()));
|
||||
} else if (AstSenItem* const senitemp = ref.backSenItemp()) {
|
||||
// SENITEM(VARREF old) convert to a list of separate SenItems for each new var
|
||||
AstNode* const oldsenrefp = senitemp->sensp();
|
||||
oldsenrefp->replaceWith(
|
||||
new AstVarRef{senitemp->fileline(), varit->varp(), VAccess::READ});
|
||||
|
|
@ -1118,7 +1141,9 @@ class SplitPackedVarVisitor final : public VNVisitor, public SplitVarImpl {
|
|||
residue -= varit->bitwidth()) {
|
||||
++varit;
|
||||
UASSERT_OBJ(varit != vars.end(), ref.nodep(), "not enough split variables");
|
||||
if (AstSenItem* const senitemp = VN_CAST(prevp, SenItem)) {
|
||||
if (cresetAssp) {
|
||||
cresetAssp->addNextHere(newAssignCReset(cresetAssp, varit->varp()));
|
||||
} else if (AstSenItem* const senitemp = VN_CAST(prevp, SenItem)) {
|
||||
prevp = new AstSenItem{
|
||||
senitemp->fileline(), senitemp->edgeType(),
|
||||
new AstVarRef{senitemp->fileline(), varit->varp(), VAccess::READ}};
|
||||
|
|
@ -1135,7 +1160,9 @@ class SplitPackedVarVisitor final : public VNVisitor, public SplitVarImpl {
|
|||
// split()
|
||||
if (varp->isIO() && (varp->isFuncLocal() || varp->isFuncReturn()))
|
||||
connectPortAndVar(vars, varp, ref.nodep());
|
||||
if (!inSentitivityList) ref.replaceNodeWith(prevp);
|
||||
if (!inSentitivityList && !cresetAssp) ref.replaceNodeWith(prevp);
|
||||
if (cresetAssp)
|
||||
VL_DO_DANGLING(cresetAssp->unlinkFrBack()->deleteTree(), cresetAssp);
|
||||
UASSERT_OBJ(varit->msb() >= ref.msb(), varit->varp(), "Out of range");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1296,6 +1296,7 @@ class TristateVisitor final : public TristateBaseVisitor {
|
|||
void visitAssign(AstNodeAssign* nodep) {
|
||||
VL_RESTORER(m_alhs);
|
||||
VL_RESTORER(m_currentStrength);
|
||||
if (VN_IS(nodep->rhsp(), CReset)) return;
|
||||
if (m_graphing) {
|
||||
if (AstAssignW* assignWp = VN_CAST(nodep, AssignW)) {
|
||||
if (assignWp->timingControlp() || assignWp->getLhsNetDelay()) return;
|
||||
|
|
|
|||
|
|
@ -117,17 +117,17 @@ private:
|
|||
}
|
||||
|
||||
public:
|
||||
void usedWhole() {
|
||||
UINFO(9, "set u[*] " << m_varp->name());
|
||||
void usedWhole(const AstNode* nodep) {
|
||||
UINFO(9, "set u[*] " << m_varp->name() << " " << nodep);
|
||||
m_wholeFlags[FLAG_USED] = true;
|
||||
}
|
||||
void drivenWhole() {
|
||||
UINFO(9, "set d[*] " << m_varp->name());
|
||||
void drivenWhole(const AstNode* nodep) {
|
||||
UINFO(9, "set d[*] " << m_varp->name() << " " << nodep);
|
||||
m_wholeFlags[FLAG_DRIVEN] = true;
|
||||
}
|
||||
void drivenWhole(const AstNodeVarRef* nodep, const FileLine* fileLinep, bool ftaskDef) {
|
||||
m_ftaskDriven = ftaskDef && !isDrivenWhole();
|
||||
drivenWhole();
|
||||
drivenWhole(nodep);
|
||||
m_nodep = nodep;
|
||||
m_nodeFileLinep = fileLinep;
|
||||
}
|
||||
|
|
@ -301,7 +301,7 @@ public:
|
|||
}
|
||||
|
||||
void drivenViaCall(const AstNodeFTaskRef* nodep) {
|
||||
drivenWhole();
|
||||
drivenWhole(nodep);
|
||||
if (!m_callNodep) m_callNodep = nodep;
|
||||
}
|
||||
const AstNodeFTaskRef* callNodep() const { return m_callNodep; }
|
||||
|
|
@ -323,6 +323,7 @@ class UndrivenVisitor final : public VNVisitorConst {
|
|||
std::array<std::vector<UndrivenVarEntry*>, 3> m_entryps = {}; // Nodes to delete when finished
|
||||
bool m_inBBox = false; // In black box; mark as driven+used
|
||||
bool m_inContAssign = false; // In continuous assignment
|
||||
bool m_inInitialSetup = false; // In InitialAutomatic*/InitialStatic* assignment LHS
|
||||
bool m_inInitialStatic = false; // In InitialStatic
|
||||
bool m_inProcAssign = false; // In procedural assignment
|
||||
bool m_inFTaskRef = false; // In function or task call
|
||||
|
|
@ -380,16 +381,16 @@ class UndrivenVisitor final : public VNVisitorConst {
|
|||
// usr==2 for always-only checks.
|
||||
UndrivenVarEntry* const entryp = getEntryp(nodep, usr);
|
||||
if ((nodep->isNonOutput() && !funcInout) || nodep->isSigPublic()
|
||||
|| nodep->isSigUserRWPublic()
|
||||
|| nodep->hasUserInit() || nodep->isSigUserRWPublic()
|
||||
|| (m_taskp && (m_taskp->dpiImport() || m_taskp->dpiExport()))) {
|
||||
entryp->drivenWhole();
|
||||
entryp->drivenWhole(nodep);
|
||||
}
|
||||
if ((nodep->isWritable() && !funcInout) || nodep->isSigPublic()
|
||||
|| nodep->isSigUserRWPublic() || nodep->isSigUserRdPublic()
|
||||
|| (m_taskp && (m_taskp->dpiImport() || m_taskp->dpiExport()))) {
|
||||
entryp->usedWhole();
|
||||
entryp->usedWhole(nodep);
|
||||
}
|
||||
if (nodep->valuep()) entryp->drivenWhole();
|
||||
if (nodep->valuep()) entryp->drivenWhole(nodep->valuep());
|
||||
}
|
||||
// Discover variables used in bit definitions, etc
|
||||
iterateChildrenConst(nodep);
|
||||
|
|
@ -504,7 +505,10 @@ class UndrivenVisitor final : public VNVisitorConst {
|
|||
<< otherWritep->warnContextSecondary());
|
||||
}
|
||||
}
|
||||
entryp->drivenWhole(nodep, nodep->fileline(), ftaskDef);
|
||||
if (!m_inInitialSetup || nodep->varp()->hasUserInit()) {
|
||||
// Else don't count default initialization as a driver to a net/variable
|
||||
entryp->drivenWhole(nodep, nodep->fileline(), ftaskDef);
|
||||
}
|
||||
if (m_alwaysCombp && entryp->isDrivenAlwaysCombWhole()
|
||||
&& m_alwaysCombp != entryp->getAlwCombp()
|
||||
&& m_alwaysCombp->fileline() == entryp->getAlwCombFileLinep())
|
||||
|
|
@ -517,13 +521,14 @@ class UndrivenVisitor final : public VNVisitorConst {
|
|||
if (m_alwaysp && m_inProcAssign && !entryp->procWritep())
|
||||
entryp->procWritep(nodep);
|
||||
}
|
||||
if (m_inBBox || nodep->access().isReadOrRW()
|
||||
|| fdrv
|
||||
// Inouts have only isWrite set, as we don't have more
|
||||
// information and operating on module boundary, treat as
|
||||
// both read and writing
|
||||
|| m_inInoutOrRefPin)
|
||||
entryp->usedWhole();
|
||||
if ((!m_inInitialSetup || nodep->varp()->hasUserInit())
|
||||
&& (m_inBBox || nodep->access().isReadOrRW()
|
||||
|| fdrv
|
||||
// Inouts have only isWrite set, as we don't have more
|
||||
// information and operating on module boundary, treat as
|
||||
// both read and writing
|
||||
|| m_inInoutOrRefPin))
|
||||
entryp->usedWhole(nodep);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -537,9 +542,12 @@ class UndrivenVisitor final : public VNVisitorConst {
|
|||
void visit(AstAssign* nodep) override {
|
||||
VL_RESTORER(m_inProcAssign);
|
||||
m_inProcAssign = true;
|
||||
// Don't count default initialization as a driver to a net/variable
|
||||
if (VN_IS(nodep->rhsp(), CReset)) return;
|
||||
iterateChildrenConst(nodep);
|
||||
{
|
||||
VL_RESTORER(m_inInitialSetup);
|
||||
m_inInitialSetup = false;
|
||||
iterateConst(nodep->rhsp());
|
||||
}
|
||||
iterateConst(nodep->lhsp());
|
||||
}
|
||||
void visit(AstAssignDly* nodep) override {
|
||||
VL_RESTORER(m_inProcAssign);
|
||||
|
|
@ -551,9 +559,26 @@ class UndrivenVisitor final : public VNVisitorConst {
|
|||
m_inContAssign = true;
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
void visit(AstInitialAutomatic* nodep) override {
|
||||
VL_RESTORER(m_inInitialSetup);
|
||||
m_inInitialSetup = true;
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
void visit(AstInitialAutomaticStmt* nodep) override {
|
||||
VL_RESTORER(m_inInitialSetup);
|
||||
m_inInitialSetup = true;
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
void visit(AstInitialStatic* nodep) override {
|
||||
VL_RESTORER(m_inInitialStatic);
|
||||
m_inInitialStatic = true;
|
||||
VL_RESTORER(m_inInitialSetup);
|
||||
m_inInitialSetup = true;
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
void visit(AstInitialStaticStmt* nodep) override {
|
||||
VL_RESTORER(m_inInitialSetup);
|
||||
m_inInitialSetup = true;
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
void visit(AstAlways* nodep) override {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ public:
|
|||
class CaptureVisitor final : public VNVisitorConst {
|
||||
V3UndrivenCapture& m_cap;
|
||||
const AstNodeFTask* m_curTaskp = nullptr; // Current task
|
||||
bool m_inInitialSetup = false; // In InitialAutomatic*/InitialStatic* assignment LHS
|
||||
|
||||
public:
|
||||
explicit CaptureVisitor(V3UndrivenCapture& cap, AstNetlist* netlistp)
|
||||
|
|
@ -51,8 +52,28 @@ private:
|
|||
iterateAndNextConstNull(nodep->stmtsp());
|
||||
}
|
||||
|
||||
void visit(AstInitialAutomaticStmt* nodep) override {
|
||||
VL_RESTORER(m_inInitialSetup);
|
||||
m_inInitialSetup = true;
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
void visit(AstInitialStaticStmt* nodep) override {
|
||||
VL_RESTORER(m_inInitialSetup);
|
||||
m_inInitialSetup = true;
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
void visit(AstAssign* nodep) override {
|
||||
{
|
||||
VL_RESTORER(m_inInitialSetup);
|
||||
m_inInitialSetup = false;
|
||||
iterateConst(nodep->rhsp());
|
||||
}
|
||||
iterateConst(nodep->lhsp());
|
||||
}
|
||||
|
||||
void visit(AstNodeVarRef* nodep) override {
|
||||
if (m_curTaskp && nodep->access().isWriteOrRW()) {
|
||||
if (m_curTaskp && nodep->access().isWriteOrRW()
|
||||
&& (nodep->varp()->hasUserInit() || !m_inInitialSetup)) {
|
||||
UINFO(9, "undriven capture direct write in " << CaptureUtil::taskNameQ(m_curTaskp)
|
||||
<< " var=" << nodep->varp()->prettyNameQ()
|
||||
<< " at " << nodep->fileline());
|
||||
|
|
@ -163,7 +184,7 @@ void V3UndrivenCapture::noteDirectWrite(const AstNodeFTask* taskp, AstVar* varp)
|
|||
if (retVarp && varp == retVarp) return;
|
||||
|
||||
// Filter out duplicates.
|
||||
if (info.directWritesSet.insert(varp).second) { info.directWrites.push_back(varp); }
|
||||
if (info.directWritesSet.insert(varp).second) info.directWrites.push_back(varp);
|
||||
}
|
||||
|
||||
void V3UndrivenCapture::noteCallEdge(const AstNodeFTask* callerp, const AstNodeFTask* calleep) {
|
||||
|
|
|
|||
|
|
@ -5503,6 +5503,18 @@ class WidthVisitor final : public VNVisitor {
|
|||
if (AstAssign* const aitemp = VN_CAST(nodep, Assign)) {
|
||||
if (VN_IS(aitemp->rhsp(), Const) || VN_IS(aitemp->rhsp(), CReset)) return true;
|
||||
}
|
||||
if (AstInitialStaticStmt* const aitemp = VN_CAST(nodep, InitialStaticStmt)) {
|
||||
for (AstNode* stmtp = aitemp->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
if (!firstNewStatementOkRecurse(stmtp)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (AstInitialAutomaticStmt* const aitemp = VN_CAST(nodep, InitialAutomaticStmt)) {
|
||||
for (AstNode* stmtp = aitemp->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
if (!firstNewStatementOkRecurse(stmtp)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,14 +36,14 @@
|
|||
{"type":"VAR","name":"b","addr":"(DB)","loc":"d,61:48,61:49","dtypep":"(M)","origName":"b","verilogName":"b","direction":"INPUT","isFuncLocal":true,"lifetime":"VAUTOMI","varType":"PORT","dtypeName":"string","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
||||
{"type":"ASSIGN","name":"","addr":"(EB)","loc":"d,61:17,61:30","dtypep":"(U)",
|
||||
"rhsp": [
|
||||
{"type":"CRESET","name":"","addr":"(FB)","loc":"d,61:17,61:30","dtypep":"(U)"}
|
||||
{"type":"CONST","name":"1'h0","addr":"(FB)","loc":"d,61:17,61:30","dtypep":"(GB)"}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"strings_equal","addr":"(GB)","loc":"d,61:17,61:30","dtypep":"(U)","access":"WR","varp":"(BB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
||||
{"type":"VARREF","name":"strings_equal","addr":"(HB)","loc":"d,61:17,61:30","dtypep":"(U)","access":"WR","varp":"(BB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGN","name":"","addr":"(HB)","loc":"d,62:7,62:13","dtypep":"(U)",
|
||||
{"type":"ASSIGN","name":"","addr":"(IB)","loc":"d,62:7,62:13","dtypep":"(U)",
|
||||
"rhsp": [
|
||||
{"type":"EQN","name":"","addr":"(IB)","loc":"d,62:16,62:18","dtypep":"(JB)",
|
||||
{"type":"EQN","name":"","addr":"(JB)","loc":"d,62:16,62:18","dtypep":"(GB)",
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"a","addr":"(KB)","loc":"d,62:14,62:15","dtypep":"(M)","access":"RD","varp":"(CB)","varScopep":"UNLINKED","classOrPackagep":"(O)"}
|
||||
],
|
||||
|
|
@ -63,7 +63,7 @@
|
|||
"miscsp": [
|
||||
{"type":"TYPETABLE","name":"","addr":"(C)","loc":"a,0:0,0:0","constraintRefp":"UNLINKED","emptyQueuep":"UNLINKED","queueIndexp":"UNLINKED","streamp":"UNLINKED","voidp":"(OB)",
|
||||
"typesp": [
|
||||
{"type":"BASICDTYPE","name":"logic","addr":"(JB)","loc":"d,22:14,22:15","dtypep":"(JB)","keyword":"logic","generic":true,"rangep": []},
|
||||
{"type":"BASICDTYPE","name":"logic","addr":"(GB)","loc":"d,22:14,22:15","dtypep":"(GB)","keyword":"logic","generic":true,"rangep": []},
|
||||
{"type":"BASICDTYPE","name":"logic","addr":"(RB)","loc":"d,25:21,25:22","dtypep":"(RB)","keyword":"logic","range":"31:0","generic":true,"rangep": []},
|
||||
{"type":"BASICDTYPE","name":"string","addr":"(M)","loc":"d,73:7,73:13","dtypep":"(M)","keyword":"string","generic":true,"rangep": []},
|
||||
{"type":"BASICDTYPE","name":"int","addr":"(Q)","loc":"d,8:9,8:12","dtypep":"(Q)","keyword":"int","range":"31:0","generic":true,"signed":true,"rangep": []},
|
||||
|
|
|
|||
|
|
@ -324,7 +324,8 @@
|
|||
end
|
||||
000011 begin
|
||||
+000011 point: comment=block hier=top.t.t1
|
||||
Cls c;
|
||||
000011 Cls c;
|
||||
+000011 point: comment=block hier=top.t.t1
|
||||
000011 c = new(1'b1);
|
||||
+000011 point: comment=block hier=top.t.t1
|
||||
000011 c.fauto();
|
||||
|
|
@ -458,7 +459,8 @@
|
|||
|
||||
000010 function arr_t get_arr;
|
||||
+000010 point: comment=block hier=top.t.cond1
|
||||
arr_t arr;
|
||||
000010 arr_t arr;
|
||||
+000010 point: comment=block hier=top.t.cond1
|
||||
000010 return arr;
|
||||
+000010 point: comment=block hier=top.t.cond1
|
||||
endfunction
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ BRDA:225,0,0,1
|
|||
BRDA:225,0,1,10
|
||||
DA:226,1
|
||||
DA:229,11
|
||||
DA:230,11
|
||||
DA:231,11
|
||||
DA:232,11
|
||||
DA:233,11
|
||||
|
|
@ -153,6 +154,7 @@ DA:323,21
|
|||
DA:324,21
|
||||
DA:325,21
|
||||
DA:328,10
|
||||
DA:329,10
|
||||
DA:330,10
|
||||
DA:333,31
|
||||
BRDA:333,0,0,0
|
||||
|
|
|
|||
|
|
@ -401,8 +401,10 @@
|
|||
-000001 point: comment=block hier=top.t
|
||||
%000001 automatic cls null_obj = null;
|
||||
-000001 point: comment=block hier=top.t
|
||||
automatic int q[5];
|
||||
automatic int qv[$];
|
||||
%000001 automatic int q[5];
|
||||
-000001 point: comment=block hier=top.t
|
||||
%000001 automatic int qv[$];
|
||||
-000001 point: comment=block hier=top.t
|
||||
|
||||
%000001 q = '{1, 2, 2, 4, 3};
|
||||
-000001 point: comment=block hier=top.t
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ module Vt_debug_emitv_t;
|
|||
initial begin
|
||||
begin : unnamedblk1
|
||||
int signed other;
|
||||
other = /*CRESET*/;
|
||||
begin
|
||||
begin : unnamedblk2
|
||||
int signed i;
|
||||
|
|
@ -690,6 +691,7 @@ module Vt_debug_emitv_sub;
|
|||
task inc;
|
||||
input int signed i;
|
||||
output int signed o;
|
||||
o = /*CRESET*/;
|
||||
o = ({32'h1{{1'h0, i[31:1]}}} + 32'h1);
|
||||
endtask
|
||||
function f;
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ test.file_grep_not(test.obj_dir + "/" + test.vm_prefix + "_classes.mk", "vm_clas
|
|||
test.file_grep_not(test.obj_dir + "/" + test.vm_prefix + "_classes.mk", "vm_classes_2")
|
||||
|
||||
# Check combine count
|
||||
test.file_grep(test.stats, r'Node count, CFILE + (\d+)', (276 if test.vltmt else 259))
|
||||
test.file_grep(test.stats, r'Node count, CFILE + (\d+)', (275 if test.vltmt else 258))
|
||||
test.file_grep(test.stats, r'Makefile targets, VM_CLASSES_FAST + (\d+)', 2)
|
||||
test.file_grep(test.stats, r'Makefile targets, VM_CLASSES_SLOW + (\d+)', 2)
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,6 @@ test.compile(
|
|||
test.execute()
|
||||
|
||||
if test.vlt:
|
||||
test.file_grep(test.stats, r'Optimizations, Const bit op reduction\s+(\d+)', 3416)
|
||||
test.file_grep(test.stats, r'Optimizations, Const bit op reduction\s+(\d+)', 3888)
|
||||
|
||||
test.passes()
|
||||
|
|
|
|||
|
|
@ -31,9 +31,9 @@ test.compile(v_flags2=[
|
|||
|
||||
if test.vltmt:
|
||||
test.file_grep(test.obj_dir + "/V" + test.name + "__hier.dir/V" + test.name + "__stats.txt",
|
||||
r'Optimizations, Thread schedule count\s+(\d+)', 4)
|
||||
r'Optimizations, Thread schedule count\s+(\d+)', 3)
|
||||
test.file_grep(test.obj_dir + "/V" + test.name + "__hier.dir/V" + test.name + "__stats.txt",
|
||||
r'Optimizations, Thread schedule total tasks\s+(\d+)', 6)
|
||||
r'Optimizations, Thread schedule total tasks\s+(\d+)', 5)
|
||||
|
||||
test.execute()
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
{"type":"VAR","name":"__Vtrigprevexpr___TOP__clk__0","addr":"(N)","loc":"d,11:8,11:9","dtypep":"(K)","origName":"__Vtrigprevexpr___TOP__clk__0","verilogName":"__Vtrigprevexpr___TOP__clk__0","direction":"NONE","lifetime":"NONE","varType":"MODULETEMP","dtypeName":"logic","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
||||
{"type":"VAR","name":"__VactPhaseResult","addr":"(O)","loc":"d,11:8,11:9","dtypep":"(P)","origName":"__VactPhaseResult","verilogName":"__VactPhaseResult","direction":"NONE","noReset":true,"lifetime":"NONE","varType":"MODULETEMP","dtypeName":"bit","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
||||
{"type":"VAR","name":"__VnbaPhaseResult","addr":"(Q)","loc":"d,11:8,11:9","dtypep":"(P)","origName":"__VnbaPhaseResult","verilogName":"__VnbaPhaseResult","direction":"NONE","noReset":true,"lifetime":"NONE","varType":"MODULETEMP","dtypeName":"bit","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
||||
{"type":"VAR","name":"t.cyc","addr":"(R)","loc":"d,23:17,23:20","dtypep":"(S)","origName":"cyc","verilogName":"cyc","direction":"NONE","lifetime":"VSTATICI","varType":"VAR","dtypeName":"integer","hasUserInit":true,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
||||
{"type":"VAR","name":"t.cyc","addr":"(R)","loc":"d,23:17,23:20","dtypep":"(S)","origName":"cyc","verilogName":"cyc","direction":"NONE","noCReset":true,"lifetime":"VSTATICI","varType":"VAR","dtypeName":"integer","hasUserInit":true,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
||||
{"type":"VAR","name":"__VactIterCount","addr":"(T)","loc":"d,11:8,11:9","dtypep":"(U)","origName":"__VactIterCount","verilogName":"__VactIterCount","direction":"NONE","noReset":true,"lifetime":"NONE","varType":"MODULETEMP","dtypeName":"bit","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
||||
{"type":"VAR","name":"__VactTriggered","addr":"(V)","loc":"d,11:8,11:9","dtypep":"(W)","origName":"__VactTriggered","verilogName":"__VactTriggered","direction":"NONE","lifetime":"NONE","varType":"MODULETEMP","dtypeName":"","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
||||
{"type":"VAR","name":"__VnbaTriggered","addr":"(X)","loc":"d,11:8,11:9","dtypep":"(W)","origName":"__VnbaTriggered","verilogName":"__VnbaTriggered","direction":"NONE","lifetime":"NONE","varType":"MODULETEMP","dtypeName":"","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
||||
|
|
@ -2859,175 +2859,178 @@
|
|||
"lhsp": [
|
||||
{"type":"VARREF","name":"clk","addr":"(YPB)","loc":"d,15:10,15:13","dtypep":"(K)","access":"WR","varp":"(J)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGN","name":"","addr":"(ZPB)","loc":"d,23:17,23:20","dtypep":"(S)",
|
||||
{"type":"ASSIGN","name":"","addr":"(ZPB)","loc":"d,24:9,24:10","dtypep":"(M)",
|
||||
"rhsp": [
|
||||
{"type":"CRESET","name":"","addr":"(AQB)","loc":"d,23:17,23:20","dtypep":"(S)","constructing":true}
|
||||
{"type":"CRESET","name":"","addr":"(AQB)","loc":"d,24:9,24:10","dtypep":"(M)","constructing":true}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"t.cyc","addr":"(BQB)","loc":"d,23:17,23:20","dtypep":"(S)","access":"WR","varp":"(R)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
||||
{"type":"VARREF","name":"t.e","addr":"(BQB)","loc":"d,24:9,24:10","dtypep":"(M)","access":"WR","varp":"(L)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGN","name":"","addr":"(CQB)","loc":"d,24:9,24:10","dtypep":"(M)",
|
||||
{"type":"ASSIGN","name":"","addr":"(CQB)","loc":"d,11:8,11:9","dtypep":"(W)",
|
||||
"rhsp": [
|
||||
{"type":"CRESET","name":"","addr":"(DQB)","loc":"d,24:9,24:10","dtypep":"(M)","constructing":true}
|
||||
{"type":"CRESET","name":"","addr":"(DQB)","loc":"d,11:8,11:9","dtypep":"(W)","constructing":true}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"t.e","addr":"(EQB)","loc":"d,24:9,24:10","dtypep":"(M)","access":"WR","varp":"(L)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
||||
{"type":"VARREF","name":"__VactTriggered","addr":"(EQB)","loc":"d,11:8,11:9","dtypep":"(W)","access":"WR","varp":"(V)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGN","name":"","addr":"(FQB)","loc":"d,11:8,11:9","dtypep":"(W)",
|
||||
{"type":"ASSIGN","name":"","addr":"(FQB)","loc":"d,11:8,11:9","dtypep":"(K)",
|
||||
"rhsp": [
|
||||
{"type":"CRESET","name":"","addr":"(GQB)","loc":"d,11:8,11:9","dtypep":"(W)","constructing":true}
|
||||
{"type":"CRESET","name":"","addr":"(GQB)","loc":"d,11:8,11:9","dtypep":"(K)","constructing":true}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"__VactTriggered","addr":"(HQB)","loc":"d,11:8,11:9","dtypep":"(W)","access":"WR","varp":"(V)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
||||
{"type":"VARREF","name":"__Vtrigprevexpr___TOP__clk__0","addr":"(HQB)","loc":"d,11:8,11:9","dtypep":"(K)","access":"WR","varp":"(N)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGN","name":"","addr":"(IQB)","loc":"d,11:8,11:9","dtypep":"(K)",
|
||||
{"type":"ASSIGN","name":"","addr":"(IQB)","loc":"d,11:8,11:9","dtypep":"(W)",
|
||||
"rhsp": [
|
||||
{"type":"CRESET","name":"","addr":"(JQB)","loc":"d,11:8,11:9","dtypep":"(K)","constructing":true}
|
||||
{"type":"CRESET","name":"","addr":"(JQB)","loc":"d,11:8,11:9","dtypep":"(W)","constructing":true}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"__Vtrigprevexpr___TOP__clk__0","addr":"(KQB)","loc":"d,11:8,11:9","dtypep":"(K)","access":"WR","varp":"(N)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGN","name":"","addr":"(LQB)","loc":"d,11:8,11:9","dtypep":"(W)",
|
||||
"rhsp": [
|
||||
{"type":"CRESET","name":"","addr":"(MQB)","loc":"d,11:8,11:9","dtypep":"(W)","constructing":true}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"__VnbaTriggered","addr":"(NQB)","loc":"d,11:8,11:9","dtypep":"(W)","access":"WR","varp":"(X)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
||||
{"type":"VARREF","name":"__VnbaTriggered","addr":"(KQB)","loc":"d,11:8,11:9","dtypep":"(W)","access":"WR","varp":"(X)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []}
|
||||
]},
|
||||
{"type":"CUSE","name":"$unit","addr":"(OQB)","loc":"a,0:0,0:0","useType":"INT_FWD"}
|
||||
{"type":"CUSE","name":"$unit","addr":"(LQB)","loc":"a,0:0,0:0","useType":"INT_FWD"}
|
||||
]},
|
||||
{"type":"PACKAGE","name":"$unit","addr":"(E)","loc":"a,0:0,0:0","origName":"__024unit","verilogName":"\\$unit ","level":2,"inLibrary":true,"timeunit":"NONE","inlinesp": [],
|
||||
"stmtsp": [
|
||||
{"type":"VAR","name":"__Venumtab_enum_next1","addr":"(DC)","loc":"d,17:12,17:16","dtypep":"(CC)","origName":"__Venumtab_enum_next1","verilogName":"__Venumtab_enum_next1","direction":"NONE","isConst":true,"lifetime":"VSTATIC","varType":"MODULETEMP","dtypeName":"","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],
|
||||
"valuep": [
|
||||
{"type":"INITARRAY","name":"","addr":"(PQB)","loc":"d,17:12,17:16","dtypep":"(CC)","initList":" [1]=(QQB) [3]=(RQB) [4]=(SQB)",
|
||||
{"type":"INITARRAY","name":"","addr":"(MQB)","loc":"d,17:12,17:16","dtypep":"(CC)","initList":" [1]=(NQB) [3]=(OQB) [4]=(PQB)",
|
||||
"defaultp": [
|
||||
{"type":"CONST","name":"4'h0","addr":"(TQB)","loc":"d,17:12,17:16","dtypep":"(UB)"}
|
||||
{"type":"CONST","name":"4'h0","addr":"(QQB)","loc":"d,17:12,17:16","dtypep":"(UB)"}
|
||||
],
|
||||
"initsp": [
|
||||
{"type":"INITITEM","name":"","addr":"(QQB)","loc":"d,17:12,17:16",
|
||||
{"type":"INITITEM","name":"","addr":"(NQB)","loc":"d,17:12,17:16",
|
||||
"valuep": [
|
||||
{"type":"CONST","name":"4'h3","addr":"(UQB)","loc":"d,19:30,19:31","dtypep":"(UB)"}
|
||||
{"type":"CONST","name":"4'h3","addr":"(RQB)","loc":"d,19:30,19:31","dtypep":"(UB)"}
|
||||
]},
|
||||
{"type":"INITITEM","name":"","addr":"(RQB)","loc":"d,17:12,17:16",
|
||||
{"type":"INITITEM","name":"","addr":"(OQB)","loc":"d,17:12,17:16",
|
||||
"valuep": [
|
||||
{"type":"CONST","name":"4'h4","addr":"(VQB)","loc":"d,20:30,20:31","dtypep":"(UB)"}
|
||||
{"type":"CONST","name":"4'h4","addr":"(SQB)","loc":"d,20:30,20:31","dtypep":"(UB)"}
|
||||
]},
|
||||
{"type":"INITITEM","name":"","addr":"(SQB)","loc":"d,17:12,17:16",
|
||||
{"type":"INITITEM","name":"","addr":"(PQB)","loc":"d,17:12,17:16",
|
||||
"valuep": [
|
||||
{"type":"CONST","name":"4'h1","addr":"(WQB)","loc":"d,18:30,18:31","dtypep":"(UB)"}
|
||||
{"type":"CONST","name":"4'h1","addr":"(TQB)","loc":"d,18:30,18:31","dtypep":"(UB)"}
|
||||
]}
|
||||
]}
|
||||
],"attrsp": []},
|
||||
{"type":"VAR","name":"__Venumtab_enum_prev1","addr":"(XI)","loc":"d,17:12,17:16","dtypep":"(WI)","origName":"__Venumtab_enum_prev1","verilogName":"__Venumtab_enum_prev1","direction":"NONE","isConst":true,"lifetime":"VSTATIC","varType":"MODULETEMP","dtypeName":"","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],
|
||||
"valuep": [
|
||||
{"type":"INITARRAY","name":"","addr":"(XQB)","loc":"d,17:12,17:16","dtypep":"(WI)","initList":" [1]=(YQB) [3]=(ZQB) [4]=(ARB)",
|
||||
{"type":"INITARRAY","name":"","addr":"(UQB)","loc":"d,17:12,17:16","dtypep":"(WI)","initList":" [1]=(VQB) [3]=(WQB) [4]=(XQB)",
|
||||
"defaultp": [
|
||||
{"type":"CONST","name":"4'h0","addr":"(BRB)","loc":"d,17:12,17:16","dtypep":"(UB)"}
|
||||
{"type":"CONST","name":"4'h0","addr":"(YQB)","loc":"d,17:12,17:16","dtypep":"(UB)"}
|
||||
],
|
||||
"initsp": [
|
||||
{"type":"INITITEM","name":"","addr":"(YQB)","loc":"d,17:12,17:16",
|
||||
{"type":"INITITEM","name":"","addr":"(VQB)","loc":"d,17:12,17:16",
|
||||
"valuep": [
|
||||
{"type":"CONST","name":"4'h4","addr":"(CRB)","loc":"d,20:30,20:31","dtypep":"(UB)"}
|
||||
{"type":"CONST","name":"4'h4","addr":"(ZQB)","loc":"d,20:30,20:31","dtypep":"(UB)"}
|
||||
]},
|
||||
{"type":"INITITEM","name":"","addr":"(ZQB)","loc":"d,17:12,17:16",
|
||||
{"type":"INITITEM","name":"","addr":"(WQB)","loc":"d,17:12,17:16",
|
||||
"valuep": [
|
||||
{"type":"CONST","name":"4'h1","addr":"(DRB)","loc":"d,18:30,18:31","dtypep":"(UB)"}
|
||||
{"type":"CONST","name":"4'h1","addr":"(ARB)","loc":"d,18:30,18:31","dtypep":"(UB)"}
|
||||
]},
|
||||
{"type":"INITITEM","name":"","addr":"(ARB)","loc":"d,17:12,17:16",
|
||||
{"type":"INITITEM","name":"","addr":"(XQB)","loc":"d,17:12,17:16",
|
||||
"valuep": [
|
||||
{"type":"CONST","name":"4'h3","addr":"(ERB)","loc":"d,19:30,19:31","dtypep":"(UB)"}
|
||||
{"type":"CONST","name":"4'h3","addr":"(BRB)","loc":"d,19:30,19:31","dtypep":"(UB)"}
|
||||
]}
|
||||
]}
|
||||
],"attrsp": []},
|
||||
{"type":"VAR","name":"__Venumtab_enum_name1","addr":"(JM)","loc":"d,17:12,17:16","dtypep":"(IM)","origName":"__Venumtab_enum_name1","verilogName":"__Venumtab_enum_name1","direction":"NONE","isConst":true,"lifetime":"VSTATIC","varType":"MODULETEMP","dtypeName":"","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],
|
||||
"valuep": [
|
||||
{"type":"INITARRAY","name":"","addr":"(FRB)","loc":"d,17:12,17:16","dtypep":"(IM)","initList":" [1]=(GRB) [3]=(HRB) [4]=(IRB)",
|
||||
{"type":"INITARRAY","name":"","addr":"(CRB)","loc":"d,17:12,17:16","dtypep":"(IM)","initList":" [1]=(DRB) [3]=(ERB) [4]=(FRB)",
|
||||
"defaultp": [
|
||||
{"type":"CONST","name":"\\\"\\\"","addr":"(JRB)","loc":"d,17:12,17:16","dtypep":"(SB)"}
|
||||
{"type":"CONST","name":"\\\"\\\"","addr":"(GRB)","loc":"d,17:12,17:16","dtypep":"(SB)"}
|
||||
],
|
||||
"initsp": [
|
||||
{"type":"INITITEM","name":"","addr":"(GRB)","loc":"d,17:12,17:16",
|
||||
{"type":"INITITEM","name":"","addr":"(DRB)","loc":"d,17:12,17:16",
|
||||
"valuep": [
|
||||
{"type":"CONST","name":"\\\"E01\\\"","addr":"(KRB)","loc":"d,17:12,17:16","dtypep":"(SB)"}
|
||||
{"type":"CONST","name":"\\\"E01\\\"","addr":"(HRB)","loc":"d,17:12,17:16","dtypep":"(SB)"}
|
||||
]},
|
||||
{"type":"INITITEM","name":"","addr":"(HRB)","loc":"d,17:12,17:16",
|
||||
{"type":"INITITEM","name":"","addr":"(ERB)","loc":"d,17:12,17:16",
|
||||
"valuep": [
|
||||
{"type":"CONST","name":"\\\"E03\\\"","addr":"(LRB)","loc":"d,17:12,17:16","dtypep":"(SB)"}
|
||||
{"type":"CONST","name":"\\\"E03\\\"","addr":"(IRB)","loc":"d,17:12,17:16","dtypep":"(SB)"}
|
||||
]},
|
||||
{"type":"INITITEM","name":"","addr":"(IRB)","loc":"d,17:12,17:16",
|
||||
{"type":"INITITEM","name":"","addr":"(FRB)","loc":"d,17:12,17:16",
|
||||
"valuep": [
|
||||
{"type":"CONST","name":"\\\"E04\\\"","addr":"(MRB)","loc":"d,17:12,17:16","dtypep":"(SB)"}
|
||||
{"type":"CONST","name":"\\\"E04\\\"","addr":"(JRB)","loc":"d,17:12,17:16","dtypep":"(SB)"}
|
||||
]}
|
||||
]}
|
||||
],"attrsp": []},
|
||||
{"type":"SCOPE","name":"$unit","addr":"(NRB)","loc":"a,0:0,0:0","aboveScopep":"(Z)","aboveCellp":"(Y)","modp":"(E)","varsp": [],"blocksp": [],"inlinesp": []},
|
||||
{"type":"CFUNC","name":"_ctor_var_reset","addr":"(ORB)","loc":"a,0:0,0:0","slow":true,"scopep":"UNLINKED","argsp": [],"varsp": [],
|
||||
{"type":"SCOPE","name":"$unit","addr":"(KRB)","loc":"a,0:0,0:0","aboveScopep":"(Z)","aboveCellp":"(Y)","modp":"(E)","varsp": [],"blocksp": [],"inlinesp": []},
|
||||
{"type":"CFUNC","name":"_ctor_var_reset","addr":"(LRB)","loc":"a,0:0,0:0","slow":true,"scopep":"UNLINKED","argsp": [],"varsp": [],
|
||||
"stmtsp": [
|
||||
{"type":"ASSIGN","name":"","addr":"(PRB)","loc":"d,17:12,17:16","dtypep":"(CC)",
|
||||
{"type":"ASSIGN","name":"","addr":"(MRB)","loc":"d,17:12,17:16","dtypep":"(CC)",
|
||||
"rhsp": [
|
||||
{"type":"CRESET","name":"","addr":"(QRB)","loc":"d,17:12,17:16","dtypep":"(CC)","constructing":true}
|
||||
{"type":"CRESET","name":"","addr":"(NRB)","loc":"d,17:12,17:16","dtypep":"(CC)","constructing":true}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"__Venumtab_enum_next1","addr":"(RRB)","loc":"d,17:12,17:16","dtypep":"(CC)","access":"WR","varp":"(DC)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
||||
{"type":"VARREF","name":"__Venumtab_enum_next1","addr":"(ORB)","loc":"d,17:12,17:16","dtypep":"(CC)","access":"WR","varp":"(DC)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGN","name":"","addr":"(SRB)","loc":"d,17:12,17:16","dtypep":"(WI)",
|
||||
{"type":"ASSIGN","name":"","addr":"(PRB)","loc":"d,17:12,17:16","dtypep":"(WI)",
|
||||
"rhsp": [
|
||||
{"type":"CRESET","name":"","addr":"(TRB)","loc":"d,17:12,17:16","dtypep":"(WI)","constructing":true}
|
||||
{"type":"CRESET","name":"","addr":"(QRB)","loc":"d,17:12,17:16","dtypep":"(WI)","constructing":true}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"__Venumtab_enum_prev1","addr":"(URB)","loc":"d,17:12,17:16","dtypep":"(WI)","access":"WR","varp":"(XI)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
||||
{"type":"VARREF","name":"__Venumtab_enum_prev1","addr":"(RRB)","loc":"d,17:12,17:16","dtypep":"(WI)","access":"WR","varp":"(XI)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGN","name":"","addr":"(VRB)","loc":"d,17:12,17:16","dtypep":"(IM)",
|
||||
{"type":"ASSIGN","name":"","addr":"(SRB)","loc":"d,17:12,17:16","dtypep":"(IM)",
|
||||
"rhsp": [
|
||||
{"type":"CRESET","name":"","addr":"(WRB)","loc":"d,17:12,17:16","dtypep":"(IM)","constructing":true}
|
||||
{"type":"CRESET","name":"","addr":"(TRB)","loc":"d,17:12,17:16","dtypep":"(IM)","constructing":true}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"__Venumtab_enum_name1","addr":"(XRB)","loc":"d,17:12,17:16","dtypep":"(IM)","access":"WR","varp":"(JM)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
||||
{"type":"VARREF","name":"__Venumtab_enum_name1","addr":"(URB)","loc":"d,17:12,17:16","dtypep":"(IM)","access":"WR","varp":"(JM)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []}
|
||||
]}
|
||||
]}
|
||||
],
|
||||
"filesp": [
|
||||
{"type":"CFILE","name":"obj_vlt/t_json_only_debugcheck/Vt_json_only_debugcheck__Syms__Slow.cpp","addr":"(YRB)","loc":"a,0:0,0:0","source":true,"slow":true,"tblockp": []},
|
||||
{"type":"CFILE","name":"obj_vlt/t_json_only_debugcheck/Vt_json_only_debugcheck__Syms.h","addr":"(ZRB)","loc":"a,0:0,0:0","tblockp": []},
|
||||
{"type":"CFILE","name":"obj_vlt/t_json_only_debugcheck/Vt_json_only_debugcheck.h","addr":"(ASB)","loc":"a,0:0,0:0","tblockp": []},
|
||||
{"type":"CFILE","name":"obj_vlt/t_json_only_debugcheck/Vt_json_only_debugcheck.cpp","addr":"(BSB)","loc":"a,0:0,0:0","source":true,"tblockp": []},
|
||||
{"type":"CFILE","name":"obj_vlt/t_json_only_debugcheck/Vt_json_only_debugcheck__pch.h","addr":"(CSB)","loc":"a,0:0,0:0","tblockp": []},
|
||||
{"type":"CFILE","name":"obj_vlt/t_json_only_debugcheck/Vt_json_only_debugcheck_$root.h","addr":"(DSB)","loc":"a,0:0,0:0","tblockp": []},
|
||||
{"type":"CFILE","name":"obj_vlt/t_json_only_debugcheck/Vt_json_only_debugcheck_$unit.h","addr":"(ESB)","loc":"a,0:0,0:0","tblockp": []},
|
||||
{"type":"CFILE","name":"obj_vlt/t_json_only_debugcheck/Vt_json_only_debugcheck_$root__Slow.cpp","addr":"(FSB)","loc":"a,0:0,0:0","source":true,"slow":true,"tblockp": []},
|
||||
{"type":"CFILE","name":"obj_vlt/t_json_only_debugcheck/Vt_json_only_debugcheck_$root__0__Slow.cpp","addr":"(GSB)","loc":"a,0:0,0:0","source":true,"slow":true,"tblockp": []},
|
||||
{"type":"CFILE","name":"obj_vlt/t_json_only_debugcheck/Vt_json_only_debugcheck_$root__0.cpp","addr":"(HSB)","loc":"a,0:0,0:0","source":true,"tblockp": []},
|
||||
{"type":"CFILE","name":"obj_vlt/t_json_only_debugcheck/Vt_json_only_debugcheck_$unit__Slow.cpp","addr":"(ISB)","loc":"a,0:0,0:0","source":true,"slow":true,"tblockp": []},
|
||||
{"type":"CFILE","name":"obj_vlt/t_json_only_debugcheck/Vt_json_only_debugcheck_$unit__0__Slow.cpp","addr":"(JSB)","loc":"a,0:0,0:0","source":true,"slow":true,"tblockp": []}
|
||||
{"type":"CFILE","name":"obj_vlt/t_json_only_debugcheck/Vt_json_only_debugcheck__Syms__Slow.cpp","addr":"(VRB)","loc":"a,0:0,0:0","source":true,"slow":true,"tblockp": []},
|
||||
{"type":"CFILE","name":"obj_vlt/t_json_only_debugcheck/Vt_json_only_debugcheck__Syms.h","addr":"(WRB)","loc":"a,0:0,0:0","tblockp": []},
|
||||
{"type":"CFILE","name":"obj_vlt/t_json_only_debugcheck/Vt_json_only_debugcheck.h","addr":"(XRB)","loc":"a,0:0,0:0","tblockp": []},
|
||||
{"type":"CFILE","name":"obj_vlt/t_json_only_debugcheck/Vt_json_only_debugcheck.cpp","addr":"(YRB)","loc":"a,0:0,0:0","source":true,"tblockp": []},
|
||||
{"type":"CFILE","name":"obj_vlt/t_json_only_debugcheck/Vt_json_only_debugcheck__pch.h","addr":"(ZRB)","loc":"a,0:0,0:0","tblockp": []},
|
||||
{"type":"CFILE","name":"obj_vlt/t_json_only_debugcheck/Vt_json_only_debugcheck_$root.h","addr":"(ASB)","loc":"a,0:0,0:0","tblockp": []},
|
||||
{"type":"CFILE","name":"obj_vlt/t_json_only_debugcheck/Vt_json_only_debugcheck_$unit.h","addr":"(BSB)","loc":"a,0:0,0:0","tblockp": []},
|
||||
{"type":"CFILE","name":"obj_vlt/t_json_only_debugcheck/Vt_json_only_debugcheck_$root__Slow.cpp","addr":"(CSB)","loc":"a,0:0,0:0","source":true,"slow":true,"tblockp": []},
|
||||
{"type":"CFILE","name":"obj_vlt/t_json_only_debugcheck/Vt_json_only_debugcheck_$root__0__Slow.cpp","addr":"(DSB)","loc":"a,0:0,0:0","source":true,"slow":true,"tblockp": []},
|
||||
{"type":"CFILE","name":"obj_vlt/t_json_only_debugcheck/Vt_json_only_debugcheck_$root__0.cpp","addr":"(ESB)","loc":"a,0:0,0:0","source":true,"tblockp": []},
|
||||
{"type":"CFILE","name":"obj_vlt/t_json_only_debugcheck/Vt_json_only_debugcheck_$unit__Slow.cpp","addr":"(FSB)","loc":"a,0:0,0:0","source":true,"slow":true,"tblockp": []},
|
||||
{"type":"CFILE","name":"obj_vlt/t_json_only_debugcheck/Vt_json_only_debugcheck_$unit__0__Slow.cpp","addr":"(GSB)","loc":"a,0:0,0:0","source":true,"slow":true,"tblockp": []}
|
||||
],
|
||||
"miscsp": [
|
||||
{"type":"TYPETABLE","name":"","addr":"(C)","loc":"a,0:0,0:0","constraintRefp":"UNLINKED","emptyQueuep":"UNLINKED","queueIndexp":"UNLINKED","streamp":"UNLINKED","voidp":"(DB)",
|
||||
"typesp": [
|
||||
{"type":"BASICDTYPE","name":"logic","addr":"(K)","loc":"d,33:24,33:27","dtypep":"(K)","keyword":"logic","generic":true,"rangep": []},
|
||||
{"type":"BASICDTYPE","name":"logic","addr":"(HC)","loc":"d,53:16,53:17","dtypep":"(HC)","keyword":"logic","range":"31:0","generic":true,"rangep": []},
|
||||
{"type":"BASICDTYPE","name":"logic","addr":"(KSB)","loc":"d,17:17,17:18","dtypep":"(KSB)","keyword":"logic","range":"3:0","generic":true,"rangep": []},
|
||||
{"type":"ENUMDTYPE","name":"t.my_t","addr":"(LSB)","loc":"d,17:12,17:16","dtypep":"(LSB)","enum":true,"refDTypep":"(KSB)","childDTypep": [],
|
||||
{"type":"BASICDTYPE","name":"logic","addr":"(HSB)","loc":"d,17:17,17:18","dtypep":"(HSB)","keyword":"logic","range":"3:0","generic":true,"rangep": []},
|
||||
{"type":"ENUMDTYPE","name":"t.my_t","addr":"(ISB)","loc":"d,17:12,17:16","dtypep":"(ISB)","enum":true,"refDTypep":"(HSB)","childDTypep": [],
|
||||
"itemsp": [
|
||||
{"type":"ENUMITEM","name":"E01","addr":"(MSB)","loc":"d,18:24,18:27","dtypep":"(UB)","rangep": [],
|
||||
{"type":"ENUMITEM","name":"E01","addr":"(JSB)","loc":"d,18:24,18:27","dtypep":"(UB)","rangep": [],
|
||||
"valuep": [
|
||||
{"type":"CONST","name":"4'h1","addr":"(NSB)","loc":"d,18:30,18:31","dtypep":"(UB)"}
|
||||
{"type":"CONST","name":"4'h1","addr":"(KSB)","loc":"d,18:30,18:31","dtypep":"(UB)"}
|
||||
]},
|
||||
{"type":"ENUMITEM","name":"E03","addr":"(OSB)","loc":"d,19:24,19:27","dtypep":"(UB)","rangep": [],
|
||||
{"type":"ENUMITEM","name":"E03","addr":"(LSB)","loc":"d,19:24,19:27","dtypep":"(UB)","rangep": [],
|
||||
"valuep": [
|
||||
{"type":"CONST","name":"4'h3","addr":"(PSB)","loc":"d,19:30,19:31","dtypep":"(UB)"}
|
||||
{"type":"CONST","name":"4'h3","addr":"(MSB)","loc":"d,19:30,19:31","dtypep":"(UB)"}
|
||||
]},
|
||||
{"type":"ENUMITEM","name":"E04","addr":"(QSB)","loc":"d,20:24,20:27","dtypep":"(UB)","rangep": [],
|
||||
{"type":"ENUMITEM","name":"E04","addr":"(NSB)","loc":"d,20:24,20:27","dtypep":"(UB)","rangep": [],
|
||||
"valuep": [
|
||||
{"type":"CONST","name":"4'h4","addr":"(RSB)","loc":"d,20:30,20:31","dtypep":"(UB)"}
|
||||
{"type":"CONST","name":"4'h4","addr":"(OSB)","loc":"d,20:30,20:31","dtypep":"(UB)"}
|
||||
]}
|
||||
]},
|
||||
{"type":"BASICDTYPE","name":"integer","addr":"(S)","loc":"d,23:4,23:11","dtypep":"(S)","keyword":"integer","range":"31:0","generic":true,"signed":true,"rangep": []},
|
||||
{"type":"REFDTYPE","name":"my_t","addr":"(M)","loc":"d,24:4,24:8","dtypep":"(LSB)","typedefp":"UNLINKED","refDTypep":"(LSB)","classOrPackagep":"UNLINKED","typeofp": [],"classOrPackageOpp": [],"paramsp": []},
|
||||
{"type":"REFDTYPE","name":"my_t","addr":"(M)","loc":"d,24:4,24:8","dtypep":"(ISB)","typedefp":"UNLINKED","refDTypep":"(ISB)","classOrPackagep":"UNLINKED","typeofp": [],"classOrPackageOpp": [],"paramsp": []},
|
||||
{"type":"BASICDTYPE","name":"string","addr":"(SB)","loc":"d,28:4,28:10","dtypep":"(SB)","keyword":"string","generic":true,"rangep": []},
|
||||
{"type":"UNPACKARRAYDTYPE","name":"","addr":"(CC)","loc":"d,17:12,17:16","dtypep":"(CC)","declRange":"[7:0]","refDTypep":"(LSB)","childDTypep": [],
|
||||
{"type":"UNPACKARRAYDTYPE","name":"","addr":"(CC)","loc":"d,17:12,17:16","dtypep":"(CC)","declRange":"[7:0]","refDTypep":"(ISB)","childDTypep": [],
|
||||
"rangep": [
|
||||
{"type":"RANGE","name":"","addr":"(PSB)","loc":"d,17:12,17:16",
|
||||
"leftp": [
|
||||
{"type":"CONST","name":"32'h7","addr":"(QSB)","loc":"d,17:12,17:16","dtypep":"(HC)"}
|
||||
],
|
||||
"rightp": [
|
||||
{"type":"CONST","name":"32'h0","addr":"(RSB)","loc":"d,17:12,17:16","dtypep":"(HC)"}
|
||||
]}
|
||||
]},
|
||||
{"type":"UNPACKARRAYDTYPE","name":"","addr":"(WI)","loc":"d,17:12,17:16","dtypep":"(WI)","declRange":"[7:0]","refDTypep":"(ISB)","childDTypep": [],
|
||||
"rangep": [
|
||||
{"type":"RANGE","name":"","addr":"(SSB)","loc":"d,17:12,17:16",
|
||||
"leftp": [
|
||||
|
|
@ -3037,7 +3040,7 @@
|
|||
{"type":"CONST","name":"32'h0","addr":"(USB)","loc":"d,17:12,17:16","dtypep":"(HC)"}
|
||||
]}
|
||||
]},
|
||||
{"type":"UNPACKARRAYDTYPE","name":"","addr":"(WI)","loc":"d,17:12,17:16","dtypep":"(WI)","declRange":"[7:0]","refDTypep":"(LSB)","childDTypep": [],
|
||||
{"type":"UNPACKARRAYDTYPE","name":"","addr":"(IM)","loc":"d,17:12,17:16","dtypep":"(IM)","isCompound":true,"declRange":"[7:0]","refDTypep":"(SB)","childDTypep": [],
|
||||
"rangep": [
|
||||
{"type":"RANGE","name":"","addr":"(VSB)","loc":"d,17:12,17:16",
|
||||
"leftp": [
|
||||
|
|
@ -3047,27 +3050,17 @@
|
|||
{"type":"CONST","name":"32'h0","addr":"(XSB)","loc":"d,17:12,17:16","dtypep":"(HC)"}
|
||||
]}
|
||||
]},
|
||||
{"type":"UNPACKARRAYDTYPE","name":"","addr":"(IM)","loc":"d,17:12,17:16","dtypep":"(IM)","isCompound":true,"declRange":"[7:0]","refDTypep":"(SB)","childDTypep": [],
|
||||
"rangep": [
|
||||
{"type":"RANGE","name":"","addr":"(YSB)","loc":"d,17:12,17:16",
|
||||
"leftp": [
|
||||
{"type":"CONST","name":"32'h7","addr":"(ZSB)","loc":"d,17:12,17:16","dtypep":"(HC)"}
|
||||
],
|
||||
"rightp": [
|
||||
{"type":"CONST","name":"32'h0","addr":"(ATB)","loc":"d,17:12,17:16","dtypep":"(HC)"}
|
||||
]}
|
||||
]},
|
||||
{"type":"BASICDTYPE","name":"logic","addr":"(LB)","loc":"d,23:23,23:24","dtypep":"(LB)","keyword":"logic","range":"31:0","generic":true,"signed":true,"rangep": []},
|
||||
{"type":"VOIDDTYPE","name":"","addr":"(DB)","loc":"a,0:0,0:0","dtypep":"(DB)"},
|
||||
{"type":"BASICDTYPE","name":"bit","addr":"(HN)","loc":"a,0:0,0:0","dtypep":"(HN)","keyword":"bit","range":"63:0","generic":true,"rangep": []},
|
||||
{"type":"UNPACKARRAYDTYPE","name":"","addr":"(W)","loc":"d,11:8,11:9","dtypep":"(W)","declRange":"[0:0]","refDTypep":"(HN)","childDTypep": [],
|
||||
"rangep": [
|
||||
{"type":"RANGE","name":"","addr":"(BTB)","loc":"d,11:8,11:9",
|
||||
{"type":"RANGE","name":"","addr":"(YSB)","loc":"d,11:8,11:9",
|
||||
"leftp": [
|
||||
{"type":"CONST","name":"32'h0","addr":"(CTB)","loc":"d,11:8,11:9","dtypep":"(HC)"}
|
||||
{"type":"CONST","name":"32'h0","addr":"(ZSB)","loc":"d,11:8,11:9","dtypep":"(HC)"}
|
||||
],
|
||||
"rightp": [
|
||||
{"type":"CONST","name":"32'h0","addr":"(DTB)","loc":"d,11:8,11:9","dtypep":"(HC)"}
|
||||
{"type":"CONST","name":"32'h0","addr":"(ATB)","loc":"d,11:8,11:9","dtypep":"(HC)"}
|
||||
]}
|
||||
]},
|
||||
{"type":"BASICDTYPE","name":"IData","addr":"(IP)","loc":"a,0:0,0:0","dtypep":"(IP)","keyword":"IData","range":"31:0","generic":true,"rangep": []},
|
||||
|
|
@ -3081,9 +3074,9 @@
|
|||
]},
|
||||
{"type":"CONSTPOOL","name":"","addr":"(D)","loc":"a,0:0,0:0",
|
||||
"modulep": [
|
||||
{"type":"MODULE","name":"@CONST-POOL@","addr":"(ETB)","loc":"a,0:0,0:0","origName":"@CONST-POOL@","verilogName":"@CONST-POOL@","level":0,"timeunit":"NONE","inlinesp": [],
|
||||
{"type":"MODULE","name":"@CONST-POOL@","addr":"(BTB)","loc":"a,0:0,0:0","origName":"@CONST-POOL@","verilogName":"@CONST-POOL@","level":0,"timeunit":"NONE","inlinesp": [],
|
||||
"stmtsp": [
|
||||
{"type":"SCOPE","name":"TOP","addr":"(FTB)","loc":"a,0:0,0:0","aboveScopep":"UNLINKED","aboveCellp":"UNLINKED","modp":"(ETB)","varsp": [],"blocksp": [],"inlinesp": []}
|
||||
{"type":"SCOPE","name":"TOP","addr":"(CTB)","loc":"a,0:0,0:0","aboveScopep":"UNLINKED","aboveCellp":"UNLINKED","modp":"(BTB)","varsp": [],"blocksp": [],"inlinesp": []}
|
||||
]}
|
||||
]}
|
||||
]}
|
||||
|
|
|
|||
|
|
@ -82,26 +82,26 @@
|
|||
"lhsp": [
|
||||
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__val","addr":"(KC)","loc":"d,15:57,15:60","dtypep":"(H)","access":"WR","varp":"(SB)","varScopep":"(RB)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGN","name":"","addr":"(LC)","loc":"d,16:17,16:20","dtypep":"(K)",
|
||||
{"type":"ASSIGN","name":"","addr":"(LC)","loc":"d,15:34,15:37","dtypep":"(K)",
|
||||
"rhsp": [
|
||||
{"type":"CRESET","name":"","addr":"(MC)","loc":"d,16:17,16:20","dtypep":"(K)"}
|
||||
{"type":"CRESET","name":"","addr":"(MC)","loc":"d,15:34,15:37","dtypep":"(K)"}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__ret","addr":"(NC)","loc":"d,16:17,16:20","dtypep":"(K)","access":"WR","varp":"(UB)","varScopep":"(TB)","classOrPackagep":"UNLINKED"}
|
||||
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__Vfuncout","addr":"(NC)","loc":"d,15:34,15:37","dtypep":"(K)","access":"WR","varp":"(QB)","varScopep":"(PB)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGN","name":"","addr":"(OC)","loc":"d,17:13,17:14","dtypep":"(WB)",
|
||||
{"type":"ASSIGN","name":"","addr":"(OC)","loc":"d,16:17,16:20","dtypep":"(K)",
|
||||
"rhsp": [
|
||||
{"type":"CRESET","name":"","addr":"(PC)","loc":"d,17:13,17:14","dtypep":"(WB)"}
|
||||
{"type":"CRESET","name":"","addr":"(PC)","loc":"d,16:17,16:20","dtypep":"(K)"}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(QC)","loc":"d,17:13,17:14","dtypep":"(WB)","access":"WR","varp":"(XB)","varScopep":"(VB)","classOrPackagep":"UNLINKED"}
|
||||
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__ret","addr":"(QC)","loc":"d,16:17,16:20","dtypep":"(K)","access":"WR","varp":"(UB)","varScopep":"(TB)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGN","name":"","addr":"(RC)","loc":"d,15:34,15:37","dtypep":"(K)",
|
||||
{"type":"ASSIGN","name":"","addr":"(RC)","loc":"d,17:13,17:14","dtypep":"(WB)",
|
||||
"rhsp": [
|
||||
{"type":"CRESET","name":"","addr":"(SC)","loc":"d,15:34,15:37","dtypep":"(K)"}
|
||||
{"type":"CRESET","name":"","addr":"(SC)","loc":"d,17:13,17:14","dtypep":"(WB)"}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__Vfuncout","addr":"(TC)","loc":"d,15:34,15:37","dtypep":"(K)","access":"WR","varp":"(QB)","varScopep":"(PB)","classOrPackagep":"UNLINKED"}
|
||||
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(TC)","loc":"d,17:13,17:14","dtypep":"(WB)","access":"WR","varp":"(XB)","varScopep":"(VB)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGN","name":"","addr":"(UC)","loc":"d,18:11,18:12","dtypep":"(WB)",
|
||||
"rhsp": [
|
||||
|
|
@ -204,26 +204,26 @@
|
|||
"lhsp": [
|
||||
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__val","addr":"(ME)","loc":"d,15:57,15:60","dtypep":"(H)","access":"WR","varp":"(BC)","varScopep":"(AC)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGN","name":"","addr":"(NE)","loc":"d,16:17,16:20","dtypep":"(K)",
|
||||
{"type":"ASSIGN","name":"","addr":"(NE)","loc":"d,15:34,15:37","dtypep":"(K)",
|
||||
"rhsp": [
|
||||
{"type":"CRESET","name":"","addr":"(OE)","loc":"d,16:17,16:20","dtypep":"(K)"}
|
||||
{"type":"CRESET","name":"","addr":"(OE)","loc":"d,15:34,15:37","dtypep":"(K)"}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__ret","addr":"(PE)","loc":"d,16:17,16:20","dtypep":"(K)","access":"WR","varp":"(DC)","varScopep":"(CC)","classOrPackagep":"UNLINKED"}
|
||||
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__Vfuncout","addr":"(PE)","loc":"d,15:34,15:37","dtypep":"(K)","access":"WR","varp":"(ZB)","varScopep":"(YB)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGN","name":"","addr":"(QE)","loc":"d,17:13,17:14","dtypep":"(WB)",
|
||||
{"type":"ASSIGN","name":"","addr":"(QE)","loc":"d,16:17,16:20","dtypep":"(K)",
|
||||
"rhsp": [
|
||||
{"type":"CRESET","name":"","addr":"(RE)","loc":"d,17:13,17:14","dtypep":"(WB)"}
|
||||
{"type":"CRESET","name":"","addr":"(RE)","loc":"d,16:17,16:20","dtypep":"(K)"}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(SE)","loc":"d,17:13,17:14","dtypep":"(WB)","access":"WR","varp":"(FC)","varScopep":"(EC)","classOrPackagep":"UNLINKED"}
|
||||
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__ret","addr":"(SE)","loc":"d,16:17,16:20","dtypep":"(K)","access":"WR","varp":"(DC)","varScopep":"(CC)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGN","name":"","addr":"(TE)","loc":"d,15:34,15:37","dtypep":"(K)",
|
||||
{"type":"ASSIGN","name":"","addr":"(TE)","loc":"d,17:13,17:14","dtypep":"(WB)",
|
||||
"rhsp": [
|
||||
{"type":"CRESET","name":"","addr":"(UE)","loc":"d,15:34,15:37","dtypep":"(K)"}
|
||||
{"type":"CRESET","name":"","addr":"(UE)","loc":"d,17:13,17:14","dtypep":"(WB)"}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__Vfuncout","addr":"(VE)","loc":"d,15:34,15:37","dtypep":"(K)","access":"WR","varp":"(ZB)","varScopep":"(YB)","classOrPackagep":"UNLINKED"}
|
||||
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(VE)","loc":"d,17:13,17:14","dtypep":"(WB)","access":"WR","varp":"(FC)","varScopep":"(EC)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGN","name":"","addr":"(WE)","loc":"d,18:11,18:12","dtypep":"(WB)",
|
||||
"rhsp": [
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ import vltest_bootstrap
|
|||
test.scenarios('vlt')
|
||||
test.top_filename = "t/t_static_in_loop.v"
|
||||
|
||||
test.lint(fails=True, expect_filename=test.golden_filename)
|
||||
test.compile()
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -6,9 +6,9 @@
|
|||
|
||||
module t;
|
||||
initial begin
|
||||
automatic int x = 0;
|
||||
static int x = 0;
|
||||
while (x < 10) begin : outer_loop
|
||||
automatic int y = 0;
|
||||
static int y = 0;
|
||||
while (y < x) begin : inner_loop
|
||||
static int a = 0;
|
||||
a++;
|
||||
|
|
@ -16,7 +16,7 @@ module t;
|
|||
end
|
||||
x++;
|
||||
end
|
||||
if (outer_loop.inner_loop.a != 45) $stop;
|
||||
if (outer_loop.inner_loop.a != 9) $stop;
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
|
|
|
|||
|
|
@ -34,19 +34,6 @@
|
|||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aLocalWaitClass::_ctor_var_reset
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aClkClass::new
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aClkClass::_ctor_var_reset
|
||||
-V{t#,#}+ Vt_timing_debug2___024root___timing_ready
|
||||
-V{t#,#}+ Vt_timing_debug2___024root___eval_initial
|
||||
-V{t#,#}+ Vt_timing_debug2_t___eval_initial__TOP__t__Vtiming__0
|
||||
-V{t#,#}+ Vt_timing_debug2___024root____VbeforeTrig_h########__0
|
||||
-V{t#,#} Suspending process waiting for @([event] t.ec.e) at t/t_timing_class.v:111
|
||||
-V{t#,#}+ Vt_timing_debug2_t___eval_initial__TOP__t__Vtiming__1
|
||||
-V{t#,#}+ Vt_timing_debug2_t___eval_initial__TOP__t__Vtiming__2
|
||||
-V{t#,#}+ Vt_timing_debug2_t___eval_initial__TOP__t__Vtiming__3
|
||||
-V{t#,#}+ Vt_timing_debug2_t___eval_initial__TOP__t__Vtiming__4
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aClkClass::__VnoInFunc_count_5
|
||||
-V{t#,#} Suspending process waiting for @(posedge t::ClkClass.clk) at t/t_timing_class.v:97
|
||||
-V{t#,#}+ Vt_timing_debug2_t___eval_initial__TOP__t__Vtiming__5
|
||||
-V{t#,#}+ Vt_timing_debug2_t___eval_initial__TOP__t__Vtiming__6
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aDelayClass::new
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aDelayClass::_ctor_var_reset
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aDelay10::new
|
||||
|
|
@ -65,6 +52,19 @@
|
|||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aNoDelay::_ctor_var_reset
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aAssignDelayClass::new
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aAssignDelayClass::_ctor_var_reset
|
||||
-V{t#,#}+ Vt_timing_debug2___024root___timing_ready
|
||||
-V{t#,#}+ Vt_timing_debug2___024root___eval_initial
|
||||
-V{t#,#}+ Vt_timing_debug2_t___eval_initial__TOP__t__Vtiming__0
|
||||
-V{t#,#}+ Vt_timing_debug2___024root____VbeforeTrig_h########__0
|
||||
-V{t#,#} Suspending process waiting for @([event] t.ec.e) at t/t_timing_class.v:111
|
||||
-V{t#,#}+ Vt_timing_debug2_t___eval_initial__TOP__t__Vtiming__1
|
||||
-V{t#,#}+ Vt_timing_debug2_t___eval_initial__TOP__t__Vtiming__2
|
||||
-V{t#,#}+ Vt_timing_debug2_t___eval_initial__TOP__t__Vtiming__3
|
||||
-V{t#,#}+ Vt_timing_debug2_t___eval_initial__TOP__t__Vtiming__4
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aClkClass::__VnoInFunc_count_5
|
||||
-V{t#,#} Suspending process waiting for @(posedge t::ClkClass.clk) at t/t_timing_class.v:97
|
||||
-V{t#,#}+ Vt_timing_debug2_t___eval_initial__TOP__t__Vtiming__5
|
||||
-V{t#,#}+ Vt_timing_debug2_t___eval_initial__TOP__t__Vtiming__6
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aDelay10::__VnoInFunc_do_delay
|
||||
-V{t#,#}+ Vt_timing_debug2_t___eval_initial__TOP__t__Vtiming__7
|
||||
-V{t#,#}+ Vt_timing_debug2_t__03a__03aForkClass::new
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
#!/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('simulator')
|
||||
|
||||
test.compile(verilator_flags2=['--timing'])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,226 @@
|
|||
// 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 checkd(gotv,expv) if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end
|
||||
`define checkd_elab(gotv,expv) if ((gotv) !== (expv)) begin $error("%%Error: %s:%0d: got=%0d exp=%0d", `__FILE__,`__LINE__, (gotv), (expv)); end
|
||||
// verilog_format: on
|
||||
|
||||
class Cls;
|
||||
|
||||
task tsk();
|
||||
for (int i = 0; i < 3; i++) begin
|
||||
/*automatic*/ int tj_auto;
|
||||
/*automatic*/ int tj_auto_init = 10;
|
||||
/*automatic*/ int tqueue_auto[$];
|
||||
/*automatic*/ int tqueue_auto_init[$] = '{1};
|
||||
static int tj_static; // = 0
|
||||
static int tj_static_init = 10;
|
||||
static int tqueue_static[$];
|
||||
static int tqueue_static_init[$] = '{1};
|
||||
|
||||
$display("Function iteration %0d:", i);
|
||||
tj_auto = tj_auto + 1;
|
||||
`checkd(tj_auto, 1);
|
||||
|
||||
tj_auto_init = tj_auto_init + 1;
|
||||
`checkd(tj_auto_init, 11);
|
||||
|
||||
`checkd(tqueue_auto.size(), 0);
|
||||
tqueue_auto.push_back(i + 10);
|
||||
`checkd(tqueue_auto.size(), 1);
|
||||
|
||||
`checkd(tqueue_auto_init.size(), 1);
|
||||
tqueue_auto_init.push_back(i + 20);
|
||||
`checkd(tqueue_auto_init.size(), 2);
|
||||
|
||||
tj_static = tj_static + 1;
|
||||
`checkd(tj_static, i + 1);
|
||||
|
||||
tj_static_init = tj_static_init + 1;
|
||||
`checkd(tj_static_init, i + 1 + 10);
|
||||
|
||||
tqueue_static.push_back(i + 20);
|
||||
`checkd(tqueue_static.size(), i + 1);
|
||||
|
||||
tqueue_static_init.push_back(i + 20);
|
||||
`checkd(tqueue_static_init.size(), i + 2);
|
||||
end
|
||||
endtask
|
||||
|
||||
endclass
|
||||
|
||||
module t;
|
||||
|
||||
function int func_const_kj_init();
|
||||
int r;
|
||||
for (int i = 0; i < 3; i++) begin
|
||||
automatic int kj;
|
||||
automatic int kj_init = 10;
|
||||
|
||||
kj = kj + 1;
|
||||
`checkd_elab(kj, 1);
|
||||
|
||||
kj_init = kj_init + 1;
|
||||
`checkd_elab(kj_init, 11);
|
||||
r = kj_init;
|
||||
end
|
||||
return r;
|
||||
endfunction
|
||||
|
||||
localparam FUNC_CONST_KJ_INIT = func_const_kj_init();
|
||||
|
||||
task forked;
|
||||
automatic int forktop = 100;
|
||||
for (int i = 0; i < 3; i++) begin
|
||||
// fork declarations are executed before all parallel statements (IEEE 1800-2023 9.3.2)
|
||||
fork : f_named
|
||||
// Automatics-in-forks Verilator will move to a VDynScope class
|
||||
automatic int fj_auto;
|
||||
automatic int fj_auto_init = 10;
|
||||
automatic int fqueue_auto[$];
|
||||
automatic int fqueue_auto_init[$] = '{1};
|
||||
// Statics-in-forks will stay in the original task
|
||||
static int fj_static; // = 0
|
||||
static int fj_static_init = 10;
|
||||
static int fqueue_static[$];
|
||||
static int fqueue_static_init[$] = '{1};
|
||||
begin
|
||||
$display("Fork iteration %0d:", i);
|
||||
++forktop;
|
||||
|
||||
fj_auto = fj_auto + 1;
|
||||
`checkd(fj_auto, 1);
|
||||
|
||||
fj_auto_init = fj_auto_init + 1;
|
||||
`checkd(fj_auto_init, 11);
|
||||
|
||||
`checkd(fqueue_auto.size(), 0);
|
||||
fqueue_auto.push_back(i + 10);
|
||||
`checkd(fqueue_auto.size(), 1);
|
||||
|
||||
`checkd(fqueue_auto_init.size(), 1);
|
||||
fqueue_auto_init.push_back(i + 20);
|
||||
`checkd(fqueue_auto_init.size(), 2);
|
||||
|
||||
fj_static = fj_static + 1;
|
||||
`checkd(fj_static, i + 1);
|
||||
|
||||
fj_static_init = fj_static_init + 1;
|
||||
`checkd(fj_static_init, i + 1 + 10);
|
||||
|
||||
fqueue_static.push_back(i + 20);
|
||||
`checkd(fqueue_static.size(), i + 1);
|
||||
|
||||
fqueue_static_init.push_back(i + 20);
|
||||
`checkd(fqueue_static_init.size(), i + 2);
|
||||
end
|
||||
join
|
||||
end
|
||||
`checkd(forktop, 100 + 3);
|
||||
endtask
|
||||
|
||||
task forked_begin;
|
||||
// fork declarations are executed before all parallel statements (IEEE 1800-2023 9.3.2)
|
||||
fork : f_named
|
||||
for (int i = 0; i < 3; i++) begin
|
||||
// Automatics-in-zorks Verilator will move to a VDynScope class
|
||||
automatic int zj_auto;
|
||||
automatic int zj_auto_init = 10;
|
||||
automatic int zqueue_auto[$];
|
||||
automatic int zqueue_auto_init[$] = '{1};
|
||||
// Statics-in-forks will stay in the original task
|
||||
static int zj_static; // = 0
|
||||
static int zj_static_init = 10;
|
||||
static int zqueue_static[$];
|
||||
static int zqueue_static_init[$] = '{1};
|
||||
begin
|
||||
$display("Fork-begin iteration %0d:", i);
|
||||
|
||||
zj_auto = zj_auto + 1;
|
||||
`checkd(zj_auto, 1);
|
||||
|
||||
zj_auto_init = zj_auto_init + 1;
|
||||
`checkd(zj_auto_init, 11);
|
||||
|
||||
`checkd(zqueue_auto.size(), 0);
|
||||
zqueue_auto.push_back(i + 10);
|
||||
`checkd(zqueue_auto.size(), 1);
|
||||
|
||||
`checkd(zqueue_auto_init.size(), 1);
|
||||
zqueue_auto_init.push_back(i + 20);
|
||||
`checkd(zqueue_auto_init.size(), 2);
|
||||
|
||||
zj_static = zj_static + 1;
|
||||
`checkd(zj_static, i + 1);
|
||||
|
||||
zj_static_init = zj_static_init + 1;
|
||||
`checkd(zj_static_init, i + 1 + 10);
|
||||
|
||||
zqueue_static.push_back(i + 20);
|
||||
`checkd(zqueue_static.size(), i + 1);
|
||||
|
||||
zqueue_static_init.push_back(i + 20);
|
||||
`checkd(zqueue_static_init.size(), i + 2);
|
||||
end
|
||||
end
|
||||
join
|
||||
endtask
|
||||
|
||||
initial begin
|
||||
Cls c;
|
||||
c = new();
|
||||
c.tsk();
|
||||
|
||||
`checkd(FUNC_CONST_KJ_INIT, 11);
|
||||
|
||||
for (int i = 0; i < 3; i++) begin : p_named
|
||||
automatic int pj_auto;
|
||||
automatic int pj_auto_init = 10;
|
||||
automatic int pqueue_auto[$];
|
||||
automatic int pqueue_auto_init[$] = '{1};
|
||||
static int pj_static; // = 0
|
||||
static int pj_static_init = 10;
|
||||
static int pqueue_static[$];
|
||||
static int pqueue_static_init[$] = '{1};
|
||||
|
||||
$display("Process iteration %0d:", i);
|
||||
pj_auto = pj_auto + 1;
|
||||
`checkd(pj_auto, 1);
|
||||
`checkd(p_named.pj_auto, 1);
|
||||
|
||||
pj_auto_init = pj_auto_init + 1;
|
||||
`checkd(pj_auto_init, 11);
|
||||
|
||||
`checkd(pqueue_auto.size(), 0);
|
||||
pqueue_auto.push_back(i + 10);
|
||||
`checkd(pqueue_auto.size(), 1);
|
||||
|
||||
`checkd(pqueue_auto_init.size(), 1);
|
||||
pqueue_auto_init.push_back(i + 20);
|
||||
`checkd(pqueue_auto_init.size(), 2);
|
||||
|
||||
pj_static = pj_static + 1;
|
||||
`checkd(pj_static, i + 1);
|
||||
|
||||
pj_static_init = pj_static_init + 1;
|
||||
`checkd(pj_static_init, i + 1 + 10);
|
||||
|
||||
pqueue_static.push_back(i + 10);
|
||||
`checkd(pqueue_static.size(), i + 1);
|
||||
|
||||
pqueue_static_init.push_back(i + 20);
|
||||
`checkd(pqueue_static_init.size(), i + 2);
|
||||
end
|
||||
|
||||
forked();
|
||||
forked_begin();
|
||||
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -135,7 +135,7 @@ C 'ft/t_wrapper_context.vl17n23ttogglepagev_toggle/topocounter[9]:0-
|
|||
C 'ft/t_wrapper_context.vl17n23ttogglepagev_toggle/topocounter[9]:1->0htop0.top' 0
|
||||
C 'ft/t_wrapper_context.vl18n16ttogglepagev_toggle/topodone_o:0->1htop0.top' 1
|
||||
C 'ft/t_wrapper_context.vl18n16ttogglepagev_toggle/topodone_o:1->0htop0.top' 0
|
||||
C 'ft/t_wrapper_context.vl21n3tlinepagev_line/topoblockS21,24,28,30-32htop0.top' 1
|
||||
C 'ft/t_wrapper_context.vl21n3tlinepagev_line/topoblockS21-24,28,30-32htop0.top' 1
|
||||
C 'ft/t_wrapper_context.vl35n3tlinepagev_line/topoblockS35htop0.top' 11
|
||||
C 'ft/t_wrapper_context.vl36n5tbranchpagev_branch/topoifS36htop0.top' 1
|
||||
C 'ft/t_wrapper_context.vl36n6tbranchpagev_branch/topoelseS37htop0.top' 10
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ C 'ft/t_wrapper_context.vl17n23ttogglepagev_toggle/topocounter[9]:0-
|
|||
C 'ft/t_wrapper_context.vl17n23ttogglepagev_toggle/topocounter[9]:1->0htop1.top' 0
|
||||
C 'ft/t_wrapper_context.vl18n16ttogglepagev_toggle/topodone_o:0->1htop1.top' 1
|
||||
C 'ft/t_wrapper_context.vl18n16ttogglepagev_toggle/topodone_o:1->0htop1.top' 0
|
||||
C 'ft/t_wrapper_context.vl21n3tlinepagev_line/topoblockS21,24,28,30-32htop1.top' 1
|
||||
C 'ft/t_wrapper_context.vl21n3tlinepagev_line/topoblockS21-24,28,30-32htop1.top' 1
|
||||
C 'ft/t_wrapper_context.vl35n3tlinepagev_line/topoblockS35htop1.top' 6
|
||||
C 'ft/t_wrapper_context.vl36n5tbranchpagev_branch/topoifS36htop1.top' 1
|
||||
C 'ft/t_wrapper_context.vl36n6tbranchpagev_branch/topoelseS37htop1.top' 5
|
||||
|
|
|
|||
Loading…
Reference in New Issue