Name temporary variables based on hash of related node.
This improves output stability by removing sequence numbers and hence can improve ccache hit rate. No functional change intended.
This commit is contained in:
parent
5adc856950
commit
00fe36f44c
|
|
@ -2849,7 +2849,6 @@ private:
|
||||||
bool m_recursive : 1; // Recursive module
|
bool m_recursive : 1; // Recursive module
|
||||||
bool m_recursiveClone : 1; // If recursive, what module it clones, otherwise nullptr
|
bool m_recursiveClone : 1; // If recursive, what module it clones, otherwise nullptr
|
||||||
int m_level = 0; // 1=top module, 2=cell off top module, ...
|
int m_level = 0; // 1=top module, 2=cell off top module, ...
|
||||||
int m_varNum = 0; // Incrementing variable number
|
|
||||||
int m_typeNum = 0; // Incrementing implicit type number
|
int m_typeNum = 0; // Incrementing implicit type number
|
||||||
VLifetime m_lifetime; // Lifetime
|
VLifetime m_lifetime; // Lifetime
|
||||||
VTimescale m_timeunit; // Global time unit
|
VTimescale m_timeunit; // Global time unit
|
||||||
|
|
@ -2890,7 +2889,6 @@ public:
|
||||||
void level(int level) { m_level = level; }
|
void level(int level) { m_level = level; }
|
||||||
int level() const { return m_level; }
|
int level() const { return m_level; }
|
||||||
bool isTop() const { return level() == 1; }
|
bool isTop() const { return level() == 1; }
|
||||||
int varNumGetInc() { return ++m_varNum; }
|
|
||||||
int typeNumGetInc() { return ++m_typeNum; }
|
int typeNumGetInc() { return ++m_typeNum; }
|
||||||
void modPublic(bool flag) { m_modPublic = flag; }
|
void modPublic(bool flag) { m_modPublic = flag; }
|
||||||
bool modPublic() const { return m_modPublic; }
|
bool modPublic() const { return m_modPublic; }
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
#include "V3Width.h"
|
#include "V3Width.h"
|
||||||
#include "V3Simulate.h"
|
#include "V3Simulate.h"
|
||||||
#include "V3Stats.h"
|
#include "V3Stats.h"
|
||||||
|
#include "V3UniqueNames.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
@ -601,6 +602,9 @@ private:
|
||||||
AstNode* m_scopep = nullptr; // Current scope
|
AstNode* m_scopep = nullptr; // Current scope
|
||||||
AstAttrOf* m_attrp = nullptr; // Current attribute
|
AstAttrOf* m_attrp = nullptr; // Current attribute
|
||||||
VDouble0 m_statBitOpReduction; // Ops reduced in ConstBitOpTreeVisitor
|
VDouble0 m_statBitOpReduction; // Ops reduced in ConstBitOpTreeVisitor
|
||||||
|
const bool m_globalPass; // ConstVisitor invoked as a global pass
|
||||||
|
static uint32_t s_globalPassNum; // Counts number of times ConstVisitor invoked as global pass
|
||||||
|
V3UniqueNames m_concswapNames; // For generating unique temporary variable names
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
VL_DEBUG_FUNC; // Declare debug()
|
VL_DEBUG_FUNC; // Declare debug()
|
||||||
|
|
@ -1762,14 +1766,16 @@ private:
|
||||||
newp = AstNode::addNext(newp, asn2ap);
|
newp = AstNode::addNext(newp, asn2ap);
|
||||||
} else {
|
} else {
|
||||||
UASSERT_OBJ(m_modp, nodep, "Not under module");
|
UASSERT_OBJ(m_modp, nodep, "Not under module");
|
||||||
|
UASSERT_OBJ(m_globalPass, nodep,
|
||||||
|
"Should not reach here when not invoked on whole AstNetlist");
|
||||||
// We could create just one temp variable, but we'll get better optimization
|
// We could create just one temp variable, but we'll get better optimization
|
||||||
// if we make one per term.
|
// if we make one per term.
|
||||||
string name1 = (string("__Vconcswap") + cvtToStr(m_modp->varNumGetInc()));
|
AstVar* const temp1p
|
||||||
string name2 = (string("__Vconcswap") + cvtToStr(m_modp->varNumGetInc()));
|
= new AstVar(sel1p->fileline(), AstVarType::BLOCKTEMP,
|
||||||
AstVar* temp1p = new AstVar(sel1p->fileline(), AstVarType::BLOCKTEMP, name1,
|
m_concswapNames.get(sel1p), VFlagLogicPacked(), msb1 - lsb1 + 1);
|
||||||
VFlagLogicPacked(), msb1 - lsb1 + 1);
|
AstVar* const temp2p
|
||||||
AstVar* temp2p = new AstVar(sel2p->fileline(), AstVarType::BLOCKTEMP, name2,
|
= new AstVar(sel2p->fileline(), AstVarType::BLOCKTEMP,
|
||||||
VFlagLogicPacked(), msb2 - lsb2 + 1);
|
m_concswapNames.get(sel2p), VFlagLogicPacked(), msb2 - lsb2 + 1);
|
||||||
m_modp->addStmtp(temp1p);
|
m_modp->addStmtp(temp1p);
|
||||||
m_modp->addStmtp(temp2p);
|
m_modp->addStmtp(temp2p);
|
||||||
AstNodeAssign* asn1ap
|
AstNodeAssign* asn1ap
|
||||||
|
|
@ -1931,6 +1937,7 @@ private:
|
||||||
VL_RESTORER(m_modp);
|
VL_RESTORER(m_modp);
|
||||||
{
|
{
|
||||||
m_modp = nodep;
|
m_modp = nodep;
|
||||||
|
m_concswapNames.reset();
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3197,7 +3204,9 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
explicit ConstVisitor(ProcMode pmode) {
|
ConstVisitor(ProcMode pmode, bool globalPass)
|
||||||
|
: m_globalPass{globalPass}
|
||||||
|
, m_concswapNames{globalPass ? ("__Vconcswap_" + cvtToStr(s_globalPassNum++)) : ""} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
switch (pmode) {
|
switch (pmode) {
|
||||||
case PROC_PARAMS: m_doV = true; m_doNConst = true; m_params = true;
|
case PROC_PARAMS: m_doV = true; m_doNConst = true; m_params = true;
|
||||||
|
|
@ -3225,6 +3234,8 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uint32_t ConstVisitor::s_globalPassNum = 0;
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
// Const class functions
|
// Const class functions
|
||||||
|
|
||||||
|
|
@ -3237,7 +3248,7 @@ AstNode* V3Const::constifyParamsEdit(AstNode* nodep) {
|
||||||
|
|
||||||
// Make sure we've sized everything first
|
// Make sure we've sized everything first
|
||||||
nodep = V3Width::widthParamsEdit(nodep);
|
nodep = V3Width::widthParamsEdit(nodep);
|
||||||
ConstVisitor visitor{ConstVisitor::PROC_PARAMS};
|
ConstVisitor visitor{ConstVisitor::PROC_PARAMS, /* globalPass: */ false};
|
||||||
if (AstVar* varp = VN_CAST(nodep, Var)) {
|
if (AstVar* varp = VN_CAST(nodep, Var)) {
|
||||||
// If a var wants to be constified, it's really a param, and
|
// If a var wants to be constified, it's really a param, and
|
||||||
// we want the value to be constant. We aren't passed just the
|
// we want the value to be constant. We aren't passed just the
|
||||||
|
|
@ -3267,7 +3278,7 @@ AstNode* V3Const::constifyGenerateParamsEdit(AstNode* nodep) {
|
||||||
|
|
||||||
// Make sure we've sized everything first
|
// Make sure we've sized everything first
|
||||||
nodep = V3Width::widthGenerateParamsEdit(nodep);
|
nodep = V3Width::widthGenerateParamsEdit(nodep);
|
||||||
ConstVisitor visitor{ConstVisitor::PROC_GENERATE};
|
ConstVisitor visitor{ConstVisitor::PROC_GENERATE, /* globalPass: */ false};
|
||||||
if (AstVar* varp = VN_CAST(nodep, Var)) {
|
if (AstVar* varp = VN_CAST(nodep, Var)) {
|
||||||
// If a var wants to be constified, it's really a param, and
|
// If a var wants to be constified, it's really a param, and
|
||||||
// we want the value to be constant. We aren't passed just the
|
// we want the value to be constant. We aren't passed just the
|
||||||
|
|
@ -3285,7 +3296,7 @@ void V3Const::constifyAllLint(AstNetlist* nodep) {
|
||||||
// Only call from Verilator.cpp, as it uses user#'s
|
// Only call from Verilator.cpp, as it uses user#'s
|
||||||
UINFO(2, __FUNCTION__ << ": " << endl);
|
UINFO(2, __FUNCTION__ << ": " << endl);
|
||||||
{
|
{
|
||||||
ConstVisitor visitor{ConstVisitor::PROC_V_WARN};
|
ConstVisitor visitor{ConstVisitor::PROC_V_WARN, /* globalPass: */ true};
|
||||||
(void)visitor.mainAcceptEdit(nodep);
|
(void)visitor.mainAcceptEdit(nodep);
|
||||||
} // Destruct before checking
|
} // Destruct before checking
|
||||||
V3Global::dumpCheckGlobalTree("const", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
V3Global::dumpCheckGlobalTree("const", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||||
|
|
@ -3294,14 +3305,14 @@ void V3Const::constifyAllLint(AstNetlist* nodep) {
|
||||||
void V3Const::constifyCpp(AstNetlist* nodep) {
|
void V3Const::constifyCpp(AstNetlist* nodep) {
|
||||||
UINFO(2, __FUNCTION__ << ": " << endl);
|
UINFO(2, __FUNCTION__ << ": " << endl);
|
||||||
{
|
{
|
||||||
ConstVisitor visitor{ConstVisitor::PROC_CPP};
|
ConstVisitor visitor{ConstVisitor::PROC_CPP, /* globalPass: */ true};
|
||||||
(void)visitor.mainAcceptEdit(nodep);
|
(void)visitor.mainAcceptEdit(nodep);
|
||||||
} // Destruct before checking
|
} // Destruct before checking
|
||||||
V3Global::dumpCheckGlobalTree("const_cpp", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
V3Global::dumpCheckGlobalTree("const_cpp", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
AstNode* V3Const::constifyEdit(AstNode* nodep) {
|
AstNode* V3Const::constifyEdit(AstNode* nodep) {
|
||||||
ConstVisitor visitor{ConstVisitor::PROC_V_NOWARN};
|
ConstVisitor visitor{ConstVisitor::PROC_V_NOWARN, /* globalPass: */ false};
|
||||||
nodep = visitor.mainAcceptEdit(nodep);
|
nodep = visitor.mainAcceptEdit(nodep);
|
||||||
return nodep;
|
return nodep;
|
||||||
}
|
}
|
||||||
|
|
@ -3312,7 +3323,7 @@ void V3Const::constifyAllLive(AstNetlist* nodep) {
|
||||||
// IE doesn't prune dead statements, as we need to do some usability checks after this
|
// IE doesn't prune dead statements, as we need to do some usability checks after this
|
||||||
UINFO(2, __FUNCTION__ << ": " << endl);
|
UINFO(2, __FUNCTION__ << ": " << endl);
|
||||||
{
|
{
|
||||||
ConstVisitor visitor{ConstVisitor::PROC_LIVE};
|
ConstVisitor visitor{ConstVisitor::PROC_LIVE, /* globalPass: */ true};
|
||||||
(void)visitor.mainAcceptEdit(nodep);
|
(void)visitor.mainAcceptEdit(nodep);
|
||||||
} // Destruct before checking
|
} // Destruct before checking
|
||||||
V3Global::dumpCheckGlobalTree("const", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
V3Global::dumpCheckGlobalTree("const", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||||
|
|
@ -3322,14 +3333,14 @@ void V3Const::constifyAll(AstNetlist* nodep) {
|
||||||
// Only call from Verilator.cpp, as it uses user#'s
|
// Only call from Verilator.cpp, as it uses user#'s
|
||||||
UINFO(2, __FUNCTION__ << ": " << endl);
|
UINFO(2, __FUNCTION__ << ": " << endl);
|
||||||
{
|
{
|
||||||
ConstVisitor visitor{ConstVisitor::PROC_V_EXPENSIVE};
|
ConstVisitor visitor{ConstVisitor::PROC_V_EXPENSIVE, /* globalPass: */ true};
|
||||||
(void)visitor.mainAcceptEdit(nodep);
|
(void)visitor.mainAcceptEdit(nodep);
|
||||||
} // Destruct before checking
|
} // Destruct before checking
|
||||||
V3Global::dumpCheckGlobalTree("const", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
V3Global::dumpCheckGlobalTree("const", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
AstNode* V3Const::constifyExpensiveEdit(AstNode* nodep) {
|
AstNode* V3Const::constifyExpensiveEdit(AstNode* nodep) {
|
||||||
ConstVisitor visitor{ConstVisitor::PROC_V_EXPENSIVE};
|
ConstVisitor visitor{ConstVisitor::PROC_V_EXPENSIVE, /* globalPass: */ false};
|
||||||
nodep = visitor.mainAcceptEdit(nodep);
|
nodep = visitor.mainAcceptEdit(nodep);
|
||||||
return nodep;
|
return nodep;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include "V3Global.h"
|
#include "V3Global.h"
|
||||||
#include "V3Depth.h"
|
#include "V3Depth.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
|
#include "V3UniqueNames.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
@ -39,11 +40,11 @@ private:
|
||||||
// NODE STATE
|
// NODE STATE
|
||||||
|
|
||||||
// STATE
|
// STATE
|
||||||
AstNodeModule* m_modp = nullptr; // Current module
|
|
||||||
AstCFunc* m_cfuncp = nullptr; // Current block
|
AstCFunc* m_cfuncp = nullptr; // Current block
|
||||||
AstNode* m_stmtp = nullptr; // Current statement
|
AstNode* m_stmtp = nullptr; // Current statement
|
||||||
int m_depth = 0; // How deep in an expression
|
int m_depth = 0; // How deep in an expression
|
||||||
int m_maxdepth = 0; // Maximum depth in an expression
|
int m_maxdepth = 0; // Maximum depth in an expression
|
||||||
|
V3UniqueNames m_tempNames; // For generating unique temporary variable names
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
VL_DEBUG_FUNC; // Declare debug()
|
VL_DEBUG_FUNC; // Declare debug()
|
||||||
|
|
@ -51,10 +52,8 @@ private:
|
||||||
void createDeepTemp(AstNode* nodep) {
|
void createDeepTemp(AstNode* nodep) {
|
||||||
UINFO(6, " Deep " << nodep << endl);
|
UINFO(6, " Deep " << nodep << endl);
|
||||||
// if (debug() >= 9) nodep->dumpTree(cout, "deep:");
|
// if (debug() >= 9) nodep->dumpTree(cout, "deep:");
|
||||||
|
AstVar* const varp = new AstVar{nodep->fileline(), AstVarType::STMTTEMP,
|
||||||
const string newvarname = (string("__Vdeeptemp") + cvtToStr(m_modp->varNumGetInc()));
|
m_tempNames.get(nodep), nodep->dtypep()};
|
||||||
AstVar* const varp
|
|
||||||
= new AstVar{nodep->fileline(), AstVarType::STMTTEMP, newvarname, nodep->dtypep()};
|
|
||||||
UASSERT_OBJ(m_cfuncp, nodep, "Deep expression not under a function");
|
UASSERT_OBJ(m_cfuncp, nodep, "Deep expression not under a function");
|
||||||
m_cfuncp->addInitsp(varp);
|
m_cfuncp->addInitsp(varp);
|
||||||
// Replace node tree with reference to var
|
// Replace node tree with reference to var
|
||||||
|
|
@ -70,21 +69,13 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
// VISITORS
|
// VISITORS
|
||||||
virtual void visit(AstNodeModule* nodep) override {
|
|
||||||
UINFO(4, " MOD " << nodep << endl);
|
|
||||||
VL_RESTORER(m_modp);
|
|
||||||
{
|
|
||||||
m_modp = nodep;
|
|
||||||
m_cfuncp = nullptr;
|
|
||||||
iterateChildren(nodep);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
virtual void visit(AstCFunc* nodep) override {
|
virtual void visit(AstCFunc* nodep) override {
|
||||||
VL_RESTORER(m_cfuncp);
|
VL_RESTORER(m_cfuncp);
|
||||||
{
|
{
|
||||||
m_cfuncp = nodep;
|
m_cfuncp = nodep;
|
||||||
m_depth = 0;
|
m_depth = 0;
|
||||||
m_maxdepth = 0;
|
m_maxdepth = 0;
|
||||||
|
m_tempNames.reset();
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -149,7 +140,10 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
explicit DepthVisitor(AstNetlist* nodep) { iterate(nodep); }
|
explicit DepthVisitor(AstNetlist* nodep)
|
||||||
|
: m_tempNames{"__Vdeeptemp"} {
|
||||||
|
iterate(nodep);
|
||||||
|
}
|
||||||
virtual ~DepthVisitor() override = default;
|
virtual ~DepthVisitor() override = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,8 @@
|
||||||
#include "V3Global.h"
|
#include "V3Global.h"
|
||||||
#include "V3Premit.h"
|
#include "V3Premit.h"
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
#include "V3DupFinder.h"
|
|
||||||
#include "V3Stats.h"
|
#include "V3Stats.h"
|
||||||
|
#include "V3UniqueNames.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
@ -92,17 +92,17 @@ private:
|
||||||
// AstNodeMath::user() -> bool. True if iterated already
|
// AstNodeMath::user() -> bool. True if iterated already
|
||||||
// AstShiftL::user2() -> bool. True if converted to conditional
|
// AstShiftL::user2() -> bool. True if converted to conditional
|
||||||
// AstShiftR::user2() -> bool. True if converted to conditional
|
// AstShiftR::user2() -> bool. True if converted to conditional
|
||||||
// *::user4() -> See PremitAssignVisitor
|
// *::user3() -> See PremitAssignVisitor
|
||||||
AstUser1InUse m_inuser1;
|
AstUser1InUse m_inuser1;
|
||||||
AstUser2InUse m_inuser2;
|
AstUser2InUse m_inuser2;
|
||||||
|
|
||||||
// STATE
|
// STATE
|
||||||
AstNodeModule* m_modp = nullptr; // Current module
|
|
||||||
AstCFunc* m_cfuncp = nullptr; // Current block
|
AstCFunc* m_cfuncp = nullptr; // Current block
|
||||||
AstNode* m_stmtp = nullptr; // Current statement
|
AstNode* m_stmtp = nullptr; // Current statement
|
||||||
AstWhile* m_inWhilep = nullptr; // Inside while loop, special statement additions
|
AstWhile* m_inWhilep = nullptr; // Inside while loop, special statement additions
|
||||||
AstTraceInc* m_inTracep = nullptr; // Inside while loop, special statement additions
|
AstTraceInc* m_inTracep = nullptr; // Inside while loop, special statement additions
|
||||||
bool m_assignLhs = false; // Inside assignment lhs, don't breakup extracts
|
bool m_assignLhs = false; // Inside assignment lhs, don't breakup extracts
|
||||||
|
V3UniqueNames m_tempNames; // For generating unique temporary variable names
|
||||||
|
|
||||||
VDouble0 m_extractedToConstPool; // Statistic tracking
|
VDouble0 m_extractedToConstPool; // Statistic tracking
|
||||||
|
|
||||||
|
|
@ -184,9 +184,8 @@ private:
|
||||||
nodep->deleteTree();
|
nodep->deleteTree();
|
||||||
++m_extractedToConstPool;
|
++m_extractedToConstPool;
|
||||||
} else {
|
} else {
|
||||||
// Keep as local temporary
|
// Keep as local temporary. Name based on hash of node for output stability.
|
||||||
const string name = string("__Vtemp") + cvtToStr(m_modp->varNumGetInc());
|
varp = new AstVar(fl, AstVarType::STMTTEMP, m_tempNames.get(nodep), nodep->dtypep());
|
||||||
varp = new AstVar(fl, AstVarType::STMTTEMP, name, nodep->dtypep());
|
|
||||||
m_cfuncp->addInitsp(varp);
|
m_cfuncp->addInitsp(varp);
|
||||||
// Put assignment before the referencing statement
|
// Put assignment before the referencing statement
|
||||||
insertBeforeStmt(new AstAssign(fl, new AstVarRef(fl, varp, VAccess::WRITE), nodep));
|
insertBeforeStmt(new AstAssign(fl, new AstVarRef(fl, varp, VAccess::WRITE), nodep));
|
||||||
|
|
@ -202,16 +201,13 @@ private:
|
||||||
// VISITORS
|
// VISITORS
|
||||||
virtual void visit(AstNodeModule* nodep) override {
|
virtual void visit(AstNodeModule* nodep) override {
|
||||||
UINFO(4, " MOD " << nodep << endl);
|
UINFO(4, " MOD " << nodep << endl);
|
||||||
UASSERT_OBJ(m_modp == nullptr, nodep, "Nested modules ?");
|
|
||||||
m_modp = nodep;
|
|
||||||
m_cfuncp = nullptr;
|
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
m_modp = nullptr;
|
|
||||||
}
|
}
|
||||||
virtual void visit(AstCFunc* nodep) override {
|
virtual void visit(AstCFunc* nodep) override {
|
||||||
VL_RESTORER(m_cfuncp);
|
VL_RESTORER(m_cfuncp);
|
||||||
{
|
{
|
||||||
m_cfuncp = nodep;
|
m_cfuncp = nodep;
|
||||||
|
m_tempNames.reset();
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -412,7 +408,10 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
explicit PremitVisitor(AstNetlist* nodep) { iterate(nodep); }
|
explicit PremitVisitor(AstNetlist* nodep)
|
||||||
|
: m_tempNames{"__Vtemp"} {
|
||||||
|
iterate(nodep);
|
||||||
|
}
|
||||||
virtual ~PremitVisitor() {
|
virtual ~PremitVisitor() {
|
||||||
V3Stats::addStat("Optimizations, Prelim extracted value to ConstPool",
|
V3Stats::addStat("Optimizations, Prelim extracted value to ConstPool",
|
||||||
m_extractedToConstPool);
|
m_extractedToConstPool);
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,7 @@
|
||||||
#include "V3Global.h"
|
#include "V3Global.h"
|
||||||
#include "V3SplitVar.h"
|
#include "V3SplitVar.h"
|
||||||
#include "V3Stats.h"
|
#include "V3Stats.h"
|
||||||
|
#include "V3UniqueNames.h"
|
||||||
|
|
||||||
#include <algorithm> // sort
|
#include <algorithm> // sort
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
@ -124,6 +125,10 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
struct SplitVarImpl {
|
struct SplitVarImpl {
|
||||||
|
// NODE STATE
|
||||||
|
// AstNodeModule::user1() -> Block number counter for generating unique names
|
||||||
|
AstUser1InUse m_user1InUse; // Only used in SplitUnpackedVarVisitor
|
||||||
|
|
||||||
static AstNodeAssign* newAssign(FileLine* fileline, AstNode* lhsp, AstNode* rhsp,
|
static AstNodeAssign* newAssign(FileLine* fileline, AstNode* lhsp, AstNode* rhsp,
|
||||||
const AstVar* varp) {
|
const AstVar* varp) {
|
||||||
if (varp->isFuncLocal() || varp->isFuncReturn()) {
|
if (varp->isFuncLocal() || varp->isFuncReturn()) {
|
||||||
|
|
@ -184,27 +189,27 @@ struct SplitVarImpl {
|
||||||
static const char* cannotSplitPackedVarReason(const AstVar* varp);
|
static const char* cannotSplitPackedVarReason(const AstVar* varp);
|
||||||
|
|
||||||
template <class T_ALWAYSLIKE>
|
template <class T_ALWAYSLIKE>
|
||||||
static void insertBeginCore(T_ALWAYSLIKE* ap, AstNodeStmt* stmtp, AstNodeModule* modp) {
|
void insertBeginCore(T_ALWAYSLIKE* ap, AstNodeStmt* stmtp, AstNodeModule* modp) {
|
||||||
if (ap->isJustOneBodyStmt() && ap->bodysp() == stmtp) {
|
if (ap->isJustOneBodyStmt() && ap->bodysp() == stmtp) {
|
||||||
stmtp->unlinkFrBack();
|
stmtp->unlinkFrBack();
|
||||||
// Insert begin-end because temp value may be inserted to this block later.
|
// Insert begin-end because temp value may be inserted to this block later.
|
||||||
const std::string name = "__VsplitVarBlk" + cvtToStr(modp->varNumGetInc());
|
const std::string name = "__VsplitVarBlk" + cvtToStr(modp->user1Inc(1));
|
||||||
ap->addStmtp(new AstBegin{ap->fileline(), name, stmtp});
|
ap->addStmtp(new AstBegin{ap->fileline(), name, stmtp});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void insertBeginCore(AstInitial* initp, AstNodeStmt* stmtp, AstNodeModule* modp) {
|
void insertBeginCore(AstInitial* initp, AstNodeStmt* stmtp, AstNodeModule* modp) {
|
||||||
if (initp->isJustOneBodyStmt() && initp->bodysp() == stmtp) {
|
if (initp->isJustOneBodyStmt() && initp->bodysp() == stmtp) {
|
||||||
stmtp->unlinkFrBack();
|
stmtp->unlinkFrBack();
|
||||||
// Insert begin-end because temp value may be inserted to this block later.
|
// Insert begin-end because temp value may be inserted to this block later.
|
||||||
FileLine* const fl = initp->fileline();
|
FileLine* const fl = initp->fileline();
|
||||||
const std::string name = "__VsplitVarBlk" + cvtToStr(modp->varNumGetInc());
|
const std::string name = "__VsplitVarBlk" + cvtToStr(modp->user1Inc(1));
|
||||||
initp->replaceWith(new AstInitial{fl, new AstBegin{fl, name, stmtp}});
|
initp->replaceWith(new AstInitial{fl, new AstBegin{fl, name, stmtp}});
|
||||||
VL_DO_DANGLING(initp->deleteTree(), initp);
|
VL_DO_DANGLING(initp->deleteTree(), initp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void insertBeginIfNecessary(AstNodeStmt* stmtp, AstNodeModule* modp) {
|
void insertBeginIfNecessary(AstNodeStmt* stmtp, AstNodeModule* modp) {
|
||||||
AstNode* const backp = stmtp->backp();
|
AstNode* const backp = stmtp->backp();
|
||||||
if (AstAlways* const ap = VN_CAST(backp, Always)) {
|
if (AstAlways* const ap = VN_CAST(backp, Always)) {
|
||||||
insertBeginCore(ap, stmtp, modp);
|
insertBeginCore(ap, stmtp, modp);
|
||||||
|
|
@ -401,6 +406,7 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
|
||||||
size_t m_numSplit = 0;
|
size_t m_numSplit = 0;
|
||||||
// List for SplitPackedVarVisitor
|
// List for SplitPackedVarVisitor
|
||||||
SplitVarRefsMap m_refsForPackedSplit;
|
SplitVarRefsMap m_refsForPackedSplit;
|
||||||
|
V3UniqueNames m_tempNames; // For generating unique temporary variable names
|
||||||
|
|
||||||
static AstVarRef* isTargetVref(AstNode* nodep) {
|
static AstVarRef* isTargetVref(AstNode* nodep) {
|
||||||
if (AstVarRef* const refp = VN_CAST(nodep, VarRef)) {
|
if (AstVarRef* const refp = VN_CAST(nodep, VarRef)) {
|
||||||
|
|
@ -457,6 +463,7 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
|
||||||
UASSERT_OBJ(!m_modp, m_modp, "Nested module declaration");
|
UASSERT_OBJ(!m_modp, m_modp, "Nested module declaration");
|
||||||
UASSERT_OBJ(m_refs.empty(), nodep, "The last module didn't finish split()");
|
UASSERT_OBJ(m_refs.empty(), nodep, "The last module didn't finish split()");
|
||||||
m_modp = nodep;
|
m_modp = nodep;
|
||||||
|
m_tempNames.reset();
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
split();
|
split();
|
||||||
m_modp = nullptr;
|
m_modp = nullptr;
|
||||||
|
|
@ -593,7 +600,7 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static AstNode* toInsertPoint(AstNode* insertp) {
|
AstNode* toInsertPoint(AstNode* insertp) {
|
||||||
if (AstNodeStmt* const stmtp = VN_CAST(insertp, NodeStmt)) {
|
if (AstNodeStmt* const stmtp = VN_CAST(insertp, NodeStmt)) {
|
||||||
if (!stmtp->isStatement()) insertp = stmtp->backp();
|
if (!stmtp->isStatement()) insertp = stmtp->backp();
|
||||||
}
|
}
|
||||||
|
|
@ -603,8 +610,7 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
|
||||||
const std::string& name_prefix, std::vector<AstVar*>& vars,
|
const std::string& name_prefix, std::vector<AstVar*>& vars,
|
||||||
int start_idx, bool lvalue, bool ftask) {
|
int start_idx, bool lvalue, bool ftask) {
|
||||||
FileLine* const fl = nodep->fileline();
|
FileLine* const fl = nodep->fileline();
|
||||||
const std::string name
|
const std::string name = m_tempNames.get(nodep) + "__" + name_prefix;
|
||||||
= "__VsplitVar" + cvtToStr(m_modp->varNumGetInc()) + "__" + name_prefix;
|
|
||||||
AstNodeAssign* const assignp = VN_CAST(context, NodeAssign);
|
AstNodeAssign* const assignp = VN_CAST(context, NodeAssign);
|
||||||
if (assignp) {
|
if (assignp) {
|
||||||
// "always_comb a = b;" to "always_comb begin a = b; end" so that local
|
// "always_comb a = b;" to "always_comb begin a = b; end" so that local
|
||||||
|
|
@ -765,7 +771,8 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit SplitUnpackedVarVisitor(AstNetlist* nodep)
|
explicit SplitUnpackedVarVisitor(AstNetlist* nodep)
|
||||||
: m_refs{} {
|
: m_refs{}
|
||||||
|
, m_tempNames{"__VsplitVar"} {
|
||||||
iterate(nodep);
|
iterate(nodep);
|
||||||
}
|
}
|
||||||
~SplitUnpackedVarVisitor() override {
|
~SplitUnpackedVarVisitor() override {
|
||||||
|
|
|
||||||
|
|
@ -18,22 +18,47 @@
|
||||||
|
|
||||||
#ifndef VERILATOR_V3UNIQUENAMES_H_
|
#ifndef VERILATOR_V3UNIQUENAMES_H_
|
||||||
#define VERILATOR_V3UNIQUENAMES_H_
|
#define VERILATOR_V3UNIQUENAMES_H_
|
||||||
|
|
||||||
#include "config_build.h"
|
#include "config_build.h"
|
||||||
#include "verilatedos.h"
|
#include "verilatedos.h"
|
||||||
|
|
||||||
|
#include "V3Hasher.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
class V3UniqueNames final {
|
class V3UniqueNames final {
|
||||||
|
const std::string m_prefix; // Prefix to attach to all names
|
||||||
|
|
||||||
std::unordered_map<std::string, unsigned> m_multiplicity; // Suffix number for given key
|
std::unordered_map<std::string, unsigned> m_multiplicity; // Suffix number for given key
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Return argument, appended with a unique suffix each time we are called with the same
|
V3UniqueNames()
|
||||||
// argument.
|
: m_prefix{""} {}
|
||||||
|
explicit V3UniqueNames(const std::string& prefix)
|
||||||
|
: m_prefix{prefix} {}
|
||||||
|
|
||||||
|
// Return argument, prepended with the prefix if any, then appended with a unique suffix each
|
||||||
|
// time we are called with the same argument.
|
||||||
std::string get(const std::string& name) {
|
std::string get(const std::string& name) {
|
||||||
const unsigned num = m_multiplicity.emplace(name, 0).first->second++;
|
const unsigned num = m_multiplicity.emplace(name, 0).first->second++;
|
||||||
return name + "__" + cvtToStr(num);
|
std::string result;
|
||||||
|
if (!m_prefix.empty()) {
|
||||||
|
result += m_prefix;
|
||||||
|
result += "_";
|
||||||
}
|
}
|
||||||
|
result += name;
|
||||||
|
result += "__";
|
||||||
|
result += cvtToStr(num);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return hash of node as string, prepended with the prefix if any, appended with a unique
|
||||||
|
// suffix each time we are called with a node that hashes to the same value.
|
||||||
|
std::string get(const AstNode* nodep) { return get(V3Hasher::uncachedHash(nodep).toString()); }
|
||||||
|
|
||||||
|
// Reset to initial state (as if just constructed)
|
||||||
|
void reset() { m_multiplicity.clear(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // Guard
|
#endif // Guard
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@
|
||||||
#include "V3Ast.h"
|
#include "V3Ast.h"
|
||||||
#include "V3Const.h"
|
#include "V3Const.h"
|
||||||
#include "V3Stats.h"
|
#include "V3Stats.h"
|
||||||
|
#include "V3UniqueNames.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
@ -57,6 +58,8 @@ private:
|
||||||
AstAssignDly* m_assigndlyp = nullptr; // Current assignment
|
AstAssignDly* m_assigndlyp = nullptr; // Current assignment
|
||||||
bool m_constXCvt = false; // Convert X's
|
bool m_constXCvt = false; // Convert X's
|
||||||
VDouble0 m_statUnkVars; // Statistic tracking
|
VDouble0 m_statUnkVars; // Statistic tracking
|
||||||
|
V3UniqueNames m_lvboundNames; // For generating unique temporary variable names
|
||||||
|
V3UniqueNames m_xrandNames; // For generating unique temporary variable names
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
VL_DEBUG_FUNC; // Declare debug()
|
VL_DEBUG_FUNC; // Declare debug()
|
||||||
|
|
@ -113,11 +116,10 @@ private:
|
||||||
UINFO(4, "Edit BOUNDLVALUE " << newp << endl);
|
UINFO(4, "Edit BOUNDLVALUE " << newp << endl);
|
||||||
replaceHandle.relink(newp);
|
replaceHandle.relink(newp);
|
||||||
} else {
|
} else {
|
||||||
const string name = (string("__Vlvbound") + cvtToStr(m_modp->varNumGetInc()));
|
AstVar* const varp
|
||||||
AstVar* varp = new AstVar(fl, AstVarType::MODULETEMP, name, prep->dtypep());
|
= new AstVar(fl, AstVarType::MODULETEMP, m_lvboundNames.get(prep), prep->dtypep());
|
||||||
m_modp->addStmtp(varp);
|
m_modp->addStmtp(varp);
|
||||||
|
AstNode* const abovep = prep->backp(); // Grab above point before we replace 'prep'
|
||||||
AstNode* abovep = prep->backp(); // Grab above point before lose it w/ next replace
|
|
||||||
prep->replaceWith(new AstVarRef(fl, varp, VAccess::WRITE));
|
prep->replaceWith(new AstVarRef(fl, varp, VAccess::WRITE));
|
||||||
AstIf* newp = new AstIf(
|
AstIf* newp = new AstIf(
|
||||||
fl, condp,
|
fl, condp,
|
||||||
|
|
@ -142,6 +144,8 @@ private:
|
||||||
{
|
{
|
||||||
m_modp = nodep;
|
m_modp = nodep;
|
||||||
m_constXCvt = true;
|
m_constXCvt = true;
|
||||||
|
m_lvboundNames.reset();
|
||||||
|
m_xrandNames.reset();
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -322,15 +326,16 @@ private:
|
||||||
// Make a Vxrand variable
|
// Make a Vxrand variable
|
||||||
// We use the special XTEMP type so it doesn't break pure functions
|
// We use the special XTEMP type so it doesn't break pure functions
|
||||||
UASSERT_OBJ(m_modp, nodep, "X number not under module");
|
UASSERT_OBJ(m_modp, nodep, "X number not under module");
|
||||||
const string newvarname = (string("__Vxrand") + cvtToStr(m_modp->varNumGetInc()));
|
AstVar* const newvarp
|
||||||
AstVar* newvarp = new AstVar(nodep->fileline(), AstVarType::XTEMP, newvarname,
|
= new AstVar(nodep->fileline(), AstVarType::XTEMP, m_xrandNames.get(nodep),
|
||||||
VFlagLogicPacked(), nodep->width());
|
VFlagLogicPacked(), nodep->width());
|
||||||
++m_statUnkVars;
|
++m_statUnkVars;
|
||||||
AstNRelinker replaceHandle;
|
AstNRelinker replaceHandle;
|
||||||
nodep->unlinkFrBack(&replaceHandle);
|
nodep->unlinkFrBack(&replaceHandle);
|
||||||
AstNodeVarRef* newref1p = new AstVarRef(nodep->fileline(), newvarp, VAccess::READ);
|
AstNodeVarRef* const newref1p
|
||||||
|
= new AstVarRef(nodep->fileline(), newvarp, VAccess::READ);
|
||||||
replaceHandle.relink(newref1p); // Replace const with varref
|
replaceHandle.relink(newref1p); // Replace const with varref
|
||||||
AstInitial* newinitp = new AstInitial(
|
AstInitial* const newinitp = new AstInitial(
|
||||||
nodep->fileline(),
|
nodep->fileline(),
|
||||||
new AstAssign(
|
new AstAssign(
|
||||||
nodep->fileline(),
|
nodep->fileline(),
|
||||||
|
|
@ -342,7 +347,7 @@ private:
|
||||||
nodep->dtypep(), true)))));
|
nodep->dtypep(), true)))));
|
||||||
// Add inits in front of other statement.
|
// Add inits in front of other statement.
|
||||||
// In the future, we should stuff the initp into the module's constructor.
|
// In the future, we should stuff the initp into the module's constructor.
|
||||||
AstNode* afterp = m_modp->stmtsp()->unlinkFrBackWithNext();
|
AstNode* const afterp = m_modp->stmtsp()->unlinkFrBackWithNext();
|
||||||
m_modp->addStmtp(newvarp);
|
m_modp->addStmtp(newvarp);
|
||||||
m_modp->addStmtp(newinitp);
|
m_modp->addStmtp(newinitp);
|
||||||
m_modp->addStmtp(afterp);
|
m_modp->addStmtp(afterp);
|
||||||
|
|
@ -476,7 +481,11 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
explicit UnknownVisitor(AstNetlist* nodep) { iterate(nodep); }
|
explicit UnknownVisitor(AstNetlist* nodep)
|
||||||
|
: m_lvboundNames{"__Vlvbound"}
|
||||||
|
, m_xrandNames{"__Vxrand"} {
|
||||||
|
iterate(nodep);
|
||||||
|
}
|
||||||
virtual ~UnknownVisitor() override { //
|
virtual ~UnknownVisitor() override { //
|
||||||
V3Stats::addStat("Unknowns, variables created", m_statUnkVars);
|
V3Stats::addStat("Unknowns, variables created", m_statUnkVars);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,9 @@
|
||||||
<cfunc fl="d60" loc="d,60,4,60,10" name="_sequent__TOP__1">
|
<cfunc fl="d60" loc="d,60,4,60,10" name="_sequent__TOP__1">
|
||||||
<var fl="d22" loc="d,22,13,22,16" name="__Vdly__t.cyc" dtype_id="3" vartype="integer" origName="__Vdly__t__DOT__cyc"/>
|
<var fl="d22" loc="d,22,13,22,16" name="__Vdly__t.cyc" dtype_id="3" vartype="integer" origName="__Vdly__t__DOT__cyc"/>
|
||||||
<var fl="d23" loc="d,23,9,23,10" name="__Vdly__t.e" dtype_id="2" vartype="my_t" origName="__Vdly__t__DOT__e"/>
|
<var fl="d23" loc="d,23,9,23,10" name="__Vdly__t.e" dtype_id="2" vartype="my_t" origName="__Vdly__t__DOT__e"/>
|
||||||
<var fl="d67" loc="d,67,119,67,123" name="__Vtemp1" dtype_id="4" vartype="string" origName="__Vtemp1"/>
|
<var fl="d67" loc="d,67,119,67,123" name="__Vtemp_h########__0" dtype_id="4" vartype="string" origName="__Vtemp_h########__0"/>
|
||||||
<var fl="d77" loc="d,77,119,77,123" name="__Vtemp2" dtype_id="4" vartype="string" origName="__Vtemp2"/>
|
<var fl="d77" loc="d,77,119,77,123" name="__Vtemp_h########__1" dtype_id="4" vartype="string" origName="__Vtemp_h########__1"/>
|
||||||
<var fl="d87" loc="d,87,119,87,123" name="__Vtemp3" dtype_id="4" vartype="string" origName="__Vtemp3"/>
|
<var fl="d87" loc="d,87,119,87,123" name="__Vtemp_h########__2" dtype_id="4" vartype="string" origName="__Vtemp_h########__2"/>
|
||||||
<assignpre fl="d64" loc="d,64,3,64,4" dtype_id="5">
|
<assignpre fl="d64" loc="d,64,3,64,4" dtype_id="5">
|
||||||
<varref fl="d64" loc="d,64,3,64,4" name="t.e" dtype_id="5"/>
|
<varref fl="d64" loc="d,64,3,64,4" name="t.e" dtype_id="5"/>
|
||||||
<varref fl="d64" loc="d,64,3,64,4" name="__Vdly__t.e" dtype_id="5"/>
|
<varref fl="d64" loc="d,64,3,64,4" name="__Vdly__t.e" dtype_id="5"/>
|
||||||
|
|
@ -93,11 +93,11 @@
|
||||||
</ccast>
|
</ccast>
|
||||||
</and>
|
</and>
|
||||||
</arraysel>
|
</arraysel>
|
||||||
<varref fl="d67" loc="d,67,119,67,123" name="__Vtemp1" dtype_id="4"/>
|
<varref fl="d67" loc="d,67,119,67,123" name="__Vtemp_h########__0" dtype_id="4"/>
|
||||||
</assign>
|
</assign>
|
||||||
<display fl="d67" loc="d,67,38,67,44" displaytype="$write">
|
<display fl="d67" loc="d,67,38,67,44" displaytype="$write">
|
||||||
<sformatf fl="d67" loc="d,67,38,67,44" name="%%Error: t/t_enum_type_methods.v:67: got='%@' exp='E01' " dtype_id="4">
|
<sformatf fl="d67" loc="d,67,38,67,44" name="%%Error: t/t_enum_type_methods.v:67: got='%@' exp='E01' " dtype_id="4">
|
||||||
<varref fl="d67" loc="d,67,119,67,123" name="__Vtemp1" dtype_id="4"/>
|
<varref fl="d67" loc="d,67,119,67,123" name="__Vtemp_h########__0" dtype_id="4"/>
|
||||||
</sformatf>
|
</sformatf>
|
||||||
</display>
|
</display>
|
||||||
<stop fl="d67" loc="d,67,136,67,141"/>
|
<stop fl="d67" loc="d,67,136,67,141"/>
|
||||||
|
|
@ -343,11 +343,11 @@
|
||||||
</ccast>
|
</ccast>
|
||||||
</and>
|
</and>
|
||||||
</arraysel>
|
</arraysel>
|
||||||
<varref fl="d77" loc="d,77,119,77,123" name="__Vtemp2" dtype_id="4"/>
|
<varref fl="d77" loc="d,77,119,77,123" name="__Vtemp_h########__1" dtype_id="4"/>
|
||||||
</assign>
|
</assign>
|
||||||
<display fl="d77" loc="d,77,38,77,44" displaytype="$write">
|
<display fl="d77" loc="d,77,38,77,44" displaytype="$write">
|
||||||
<sformatf fl="d77" loc="d,77,38,77,44" name="%%Error: t/t_enum_type_methods.v:77: got='%@' exp='E03' " dtype_id="4">
|
<sformatf fl="d77" loc="d,77,38,77,44" name="%%Error: t/t_enum_type_methods.v:77: got='%@' exp='E03' " dtype_id="4">
|
||||||
<varref fl="d77" loc="d,77,119,77,123" name="__Vtemp2" dtype_id="4"/>
|
<varref fl="d77" loc="d,77,119,77,123" name="__Vtemp_h########__1" dtype_id="4"/>
|
||||||
</sformatf>
|
</sformatf>
|
||||||
</display>
|
</display>
|
||||||
<stop fl="d77" loc="d,77,136,77,141"/>
|
<stop fl="d77" loc="d,77,136,77,141"/>
|
||||||
|
|
@ -593,11 +593,11 @@
|
||||||
</ccast>
|
</ccast>
|
||||||
</and>
|
</and>
|
||||||
</arraysel>
|
</arraysel>
|
||||||
<varref fl="d87" loc="d,87,119,87,123" name="__Vtemp3" dtype_id="4"/>
|
<varref fl="d87" loc="d,87,119,87,123" name="__Vtemp_h########__2" dtype_id="4"/>
|
||||||
</assign>
|
</assign>
|
||||||
<display fl="d87" loc="d,87,38,87,44" displaytype="$write">
|
<display fl="d87" loc="d,87,38,87,44" displaytype="$write">
|
||||||
<sformatf fl="d87" loc="d,87,38,87,44" name="%%Error: t/t_enum_type_methods.v:87: got='%@' exp='E04' " dtype_id="4">
|
<sformatf fl="d87" loc="d,87,38,87,44" name="%%Error: t/t_enum_type_methods.v:87: got='%@' exp='E04' " dtype_id="4">
|
||||||
<varref fl="d87" loc="d,87,119,87,123" name="__Vtemp3" dtype_id="4"/>
|
<varref fl="d87" loc="d,87,119,87,123" name="__Vtemp_h########__2" dtype_id="4"/>
|
||||||
</sformatf>
|
</sformatf>
|
||||||
</display>
|
</display>
|
||||||
<stop fl="d87" loc="d,87,136,87,141"/>
|
<stop fl="d87" loc="d,87,136,87,141"/>
|
||||||
|
|
@ -845,7 +845,7 @@
|
||||||
<cfunc fl="d22" loc="d,22,17,22,18" name="_initial__TOP__2">
|
<cfunc fl="d22" loc="d,22,17,22,18" name="_initial__TOP__2">
|
||||||
<var fl="d27" loc="d,27,11,27,14" name="t.all" dtype_id="4" vartype="string" origName="t__DOT__all"/>
|
<var fl="d27" loc="d,27,11,27,14" name="t.all" dtype_id="4" vartype="string" origName="t__DOT__all"/>
|
||||||
<var fl="d51" loc="d,51,17,51,18" name="t.unnamedblk1.e" dtype_id="2" vartype="my_t" origName="t__DOT__unnamedblk1__DOT__e"/>
|
<var fl="d51" loc="d,51,17,51,18" name="t.unnamedblk1.e" dtype_id="2" vartype="my_t" origName="t__DOT__unnamedblk1__DOT__e"/>
|
||||||
<var fl="d48" loc="d,48,123,48,127" name="__Vtemp4" dtype_id="4" vartype="string" origName="__Vtemp4"/>
|
<var fl="d48" loc="d,48,123,48,127" name="__Vtemp_h########__0" dtype_id="4" vartype="string" origName="__Vtemp_h########__0"/>
|
||||||
<assign fl="d22" loc="d,22,17,22,18" dtype_id="3">
|
<assign fl="d22" loc="d,22,17,22,18" dtype_id="3">
|
||||||
<const fl="d22" loc="d,22,17,22,18" name="32'sh0" dtype_id="7"/>
|
<const fl="d22" loc="d,22,17,22,18" name="32'sh0" dtype_id="7"/>
|
||||||
<varref fl="d22" loc="d,22,17,22,18" name="t.cyc" dtype_id="3"/>
|
<varref fl="d22" loc="d,22,17,22,18" name="t.cyc" dtype_id="3"/>
|
||||||
|
|
@ -1298,11 +1298,11 @@
|
||||||
</ccast>
|
</ccast>
|
||||||
</and>
|
</and>
|
||||||
</arraysel>
|
</arraysel>
|
||||||
<varref fl="d48" loc="d,48,123,48,127" name="__Vtemp4" dtype_id="4"/>
|
<varref fl="d48" loc="d,48,123,48,127" name="__Vtemp_h########__0" dtype_id="4"/>
|
||||||
</assign>
|
</assign>
|
||||||
<display fl="d48" loc="d,48,42,48,48" displaytype="$write">
|
<display fl="d48" loc="d,48,42,48,48" displaytype="$write">
|
||||||
<sformatf fl="d48" loc="d,48,42,48,48" name="%%Error: t/t_enum_type_methods.v:48: got='%@' exp='E03' " dtype_id="4">
|
<sformatf fl="d48" loc="d,48,42,48,48" name="%%Error: t/t_enum_type_methods.v:48: got='%@' exp='E03' " dtype_id="4">
|
||||||
<varref fl="d48" loc="d,48,123,48,127" name="__Vtemp4" dtype_id="4"/>
|
<varref fl="d48" loc="d,48,123,48,127" name="__Vtemp_h########__0" dtype_id="4"/>
|
||||||
</sformatf>
|
</sformatf>
|
||||||
</display>
|
</display>
|
||||||
<stop fl="d48" loc="d,48,140,48,145"/>
|
<stop fl="d48" loc="d,48,140,48,145"/>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue