mirror of
https://github.com/verilator/verilator.git
synced 2025-04-16 01:26:54 +00:00
Merge branch 'master' into develop-v5
This commit is contained in:
commit
46de9460a6
5
Changes
5
Changes
@ -23,12 +23,15 @@ Verilator 4.221 devel
|
||||
|
||||
* Split --prof-threads into --prof-exec and --prof-pgo (#3365). [Geza Lore, Shunyao CAD]
|
||||
* Deprecate 'vluint64_t' and similar types (#3255).
|
||||
* Raise error on assignment to const in initial blocks. [Geza Lore, Shunyao CAD]
|
||||
* Fix MSVC localtime_s (#3124).
|
||||
* Fix Bison 3.8.2 error (#3366). [elike-ypq]
|
||||
* Fix rare bug in -Oz (V3Localize) (#3286). [Geza Lore, Shunyao CAD]
|
||||
* Fix tracing interfaces inside interfaces (#3309). [Kevin Millis]
|
||||
* Fix filenames with dots overwriting debug .vpp files (#3373).
|
||||
* Fix including VK_USER_OBJS in make library (#3370). [Julien Margetts]
|
||||
|
||||
* Fix crash in recursive module inlining (#3393). [david-sawatzke]
|
||||
* Fix --protect-ids mangling names of library methods. [Geza Lore, Shunyao CAD]
|
||||
|
||||
Verilator 4.220 2022-03-12
|
||||
==========================
|
||||
|
@ -410,16 +410,16 @@ public:
|
||||
}
|
||||
template <typename Func> VlQueue find_last(Func with_func) const {
|
||||
IData index = m_deque.size() - 1;
|
||||
for (auto it = m_deque.rbegin(); it != m_deque.rend(); ++it) {
|
||||
if (with_func(index, *it)) return VlQueue::cons(*it);
|
||||
for (auto& item : vlstd::reverse_view(m_deque)) {
|
||||
if (with_func(index, item)) return VlQueue::cons(item);
|
||||
--index;
|
||||
}
|
||||
return VlQueue{};
|
||||
}
|
||||
template <typename Func> VlQueue<IData> find_last_index(Func with_func) const {
|
||||
IData index = m_deque.size() - 1;
|
||||
for (auto it = m_deque.rbegin(); it != m_deque.rend(); ++it) {
|
||||
if (with_func(index, *it)) return VlQueue<IData>::cons(index);
|
||||
for (auto& item : vlstd::reverse_view(m_deque)) {
|
||||
if (with_func(index, item)) return VlQueue<IData>::cons(index);
|
||||
--index;
|
||||
}
|
||||
return VlQueue<IData>{};
|
||||
|
@ -521,6 +521,19 @@ using ssize_t = uint32_t; ///< signed size_t; returned from read()
|
||||
// Conversions
|
||||
|
||||
namespace vlstd {
|
||||
|
||||
template <typename T> struct reverse_wrapper {
|
||||
const T& m_v;
|
||||
|
||||
explicit reverse_wrapper(const T& a_v)
|
||||
: m_v(a_v) {}
|
||||
inline auto begin() -> decltype(m_v.rbegin()) { return m_v.rbegin(); }
|
||||
inline auto end() -> decltype(m_v.rend()) { return m_v.rend(); }
|
||||
};
|
||||
|
||||
// C++20's std::ranges::reverse_view
|
||||
template <typename T> reverse_wrapper<T> reverse_view(const T& v) { return reverse_wrapper<T>(v); }
|
||||
|
||||
// C++17's std::as_const
|
||||
template <class T> T const& as_const(T& v) { return v; }
|
||||
}; // namespace vlstd
|
||||
|
@ -422,6 +422,14 @@ private:
|
||||
virtual void visit(AstActive* nodep) override {
|
||||
// Actives are being formed, so we can ignore any already made
|
||||
}
|
||||
virtual void visit(AstInitialStatic* nodep) override {
|
||||
// Relink to IACTIVE, unless already under it
|
||||
UINFO(4, " INITIAL " << nodep << endl);
|
||||
const ActiveDlyVisitor dlyvisitor{nodep, ActiveDlyVisitor::CT_INITIAL};
|
||||
AstActive* const wantactivep = m_namer.getIActive(nodep->fileline());
|
||||
nodep->unlinkFrBack();
|
||||
wantactivep->addStmtsp(nodep);
|
||||
}
|
||||
virtual void visit(AstInitial* nodep) override {
|
||||
// Relink to IACTIVE, unless already under it
|
||||
UINFO(4, " INITIAL " << nodep << endl);
|
||||
|
@ -98,7 +98,7 @@ private:
|
||||
? static_cast<AstNode*>(
|
||||
new AstCMath(fl, "vlSymsp->_vm_contextp__->assertOn()", 1))
|
||||
: static_cast<AstNode*>(new AstConst(fl, AstConst::BitFalse())))),
|
||||
nodep, nullptr);
|
||||
nodep);
|
||||
newp->user1(true); // Don't assert/cover this if
|
||||
return newp;
|
||||
}
|
||||
@ -154,7 +154,7 @@ private:
|
||||
}
|
||||
|
||||
if (bodysp && passsp) bodysp = bodysp->addNext(passsp);
|
||||
ifp = new AstIf(nodep->fileline(), propp, bodysp, nullptr);
|
||||
ifp = new AstIf(nodep->fileline(), propp, bodysp);
|
||||
bodysp = ifp;
|
||||
} else if (VN_IS(nodep, Assert) || VN_IS(nodep, AssertIntrinsic)) {
|
||||
if (nodep->immediate()) {
|
||||
@ -313,8 +313,7 @@ private:
|
||||
AstIf* const ifp = new AstIf(
|
||||
nodep->fileline(), new AstLogNot(nodep->fileline(), ohot),
|
||||
newFireAssert(nodep,
|
||||
"synthesis parallel_case, but multiple matches found"),
|
||||
nullptr);
|
||||
"synthesis parallel_case, but multiple matches found"));
|
||||
ifp->branchPred(VBranchPred::BP_UNLIKELY);
|
||||
nodep->addNotParallelp(ifp);
|
||||
}
|
||||
@ -384,7 +383,7 @@ private:
|
||||
new AstLogAnd{fl, new AstLogNot{fl, newMonitorOffVarRefp(nodep, VAccess::READ)},
|
||||
new AstEq{fl, new AstConst{fl, monNum},
|
||||
newMonitorNumVarRefp(nodep, VAccess::READ)}},
|
||||
stmtsp, nullptr};
|
||||
stmtsp};
|
||||
ifp->branchPred(VBranchPred::BP_UNLIKELY);
|
||||
AstNode* const newp = new AstAlwaysPostponed{fl, ifp};
|
||||
m_modp->addStmtp(newp);
|
||||
@ -402,8 +401,7 @@ private:
|
||||
nodep->replaceWith(newsetp);
|
||||
// Add "always_comb if (__Vstrobe) begin $display(...); __Vstrobe = '0; end"
|
||||
AstNode* const stmtsp = nodep;
|
||||
AstIf* const ifp
|
||||
= new AstIf{fl, new AstVarRef{fl, varp, VAccess::READ}, stmtsp, nullptr};
|
||||
AstIf* const ifp = new AstIf{fl, new AstVarRef{fl, varp, VAccess::READ}, stmtsp};
|
||||
ifp->branchPred(VBranchPred::BP_UNLIKELY);
|
||||
AstNode* const newp = new AstAlwaysPostponed{fl, ifp};
|
||||
stmtsp->addNext(new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE},
|
||||
|
@ -1135,49 +1135,33 @@ void AstNode::v3errorEndFatal(std::ostringstream& str) const {
|
||||
VL_UNREACHABLE
|
||||
}
|
||||
|
||||
string AstNode::locationStr() const {
|
||||
string str = "... In instance ";
|
||||
const AstNode* backp = this;
|
||||
int itmax = 10000; // Max iterations before giving up on location search
|
||||
while (backp) {
|
||||
if (VL_UNCOVERABLE(--itmax < 0)) {
|
||||
// Likely some circular back link, and V3Ast is trying to report a low-level error
|
||||
UINFO(1, "Ran out of iterations finding locationStr on " << backp << endl);
|
||||
return ""; // LCOV_EXCL_LINE
|
||||
}
|
||||
const AstScope* scopep;
|
||||
if ((scopep = VN_CAST(backp, Scope))) {
|
||||
// The design is flattened and there are no useful scopes
|
||||
// This is probably because of inlining
|
||||
if (scopep->isTop()) break;
|
||||
string AstNode::instanceStr() const {
|
||||
// Max iterations before giving up on location search,
|
||||
// in case we have some circular reference bug.
|
||||
constexpr unsigned maxIterations = 10000;
|
||||
unsigned iterCount = 0;
|
||||
|
||||
str += scopep->prettyName();
|
||||
return str;
|
||||
for (const AstNode* backp = this; backp; backp = backp->backp(), ++iterCount) {
|
||||
if (VL_UNCOVERABLE(iterCount >= maxIterations)) return ""; // LCOV_EXCL_LINE
|
||||
|
||||
// Prefer the enclosing scope, if there is one. This is always under the enclosing module,
|
||||
// so just pick it up when encountered
|
||||
if (const AstScope* const scopep = VN_CAST(backp, Scope)) {
|
||||
return scopep->isTop() ? "" : "... In instance " + scopep->prettyName();
|
||||
}
|
||||
backp = backp->backp();
|
||||
}
|
||||
backp = this;
|
||||
while (backp) {
|
||||
const AstModule* modp;
|
||||
const AstNodeVarRef* nvrp;
|
||||
if ((modp = VN_CAST(backp, Module)) && !modp->hierName().empty()) {
|
||||
str += modp->hierName();
|
||||
return str;
|
||||
} else if ((nvrp = VN_CAST(backp, NodeVarRef))) {
|
||||
const string prettyName = nvrp->prettyName();
|
||||
// VarRefs have not been flattened yet and do not contain location information
|
||||
if (prettyName != nvrp->name()) {
|
||||
str += prettyName;
|
||||
return str;
|
||||
}
|
||||
|
||||
// If scopes don't exist, report an example instance of the enclosing module
|
||||
if (const AstModule* const modp = VN_CAST(backp, Module)) {
|
||||
const string instanceName = modp->someInstanceName();
|
||||
return instanceName.empty() ? "" : "... In instance " + instanceName;
|
||||
}
|
||||
backp = backp->backp();
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
void AstNode::v3errorEnd(std::ostringstream& str) const {
|
||||
if (!m_fileline) {
|
||||
V3Error::v3errorEnd(str, locationStr());
|
||||
V3Error::v3errorEnd(str, instanceStr());
|
||||
} else {
|
||||
std::ostringstream nsstr;
|
||||
nsstr << str.str();
|
||||
@ -1187,7 +1171,7 @@ void AstNode::v3errorEnd(std::ostringstream& str) const {
|
||||
const_cast<AstNode*>(this)->dump(nsstr);
|
||||
nsstr << endl;
|
||||
}
|
||||
m_fileline->v3errorEnd(nsstr, locationStr());
|
||||
m_fileline->v3errorEnd(nsstr, instanceStr());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1447,7 +1447,7 @@ private:
|
||||
bool gateOnly);
|
||||
void deleteTreeIter();
|
||||
void deleteNode();
|
||||
string locationStr() const;
|
||||
string instanceStr() const;
|
||||
|
||||
public:
|
||||
static void relinkOneLink(AstNode*& pointpr, AstNode* newp);
|
||||
@ -3077,7 +3077,8 @@ class AstNodeModule VL_NOT_FINAL : public AstNode {
|
||||
private:
|
||||
string m_name; // Name of the module
|
||||
const string m_origName; // Name of the module, ignoring name() changes, for dot lookup
|
||||
string m_hierName; // Hierarchical name for errors, etc.
|
||||
string m_someInstanceName; // Hierarchical name of some arbitrary instance of this module.
|
||||
// Used for user messages only.
|
||||
bool m_modPublic : 1; // Module has public references
|
||||
bool m_modTrace : 1; // Tracing this module
|
||||
bool m_inLibrary : 1; // From a library, no error if not used, never top level
|
||||
@ -3119,8 +3120,8 @@ public:
|
||||
// ACCESSORS
|
||||
virtual void name(const string& name) override { m_name = name; }
|
||||
virtual string origName() const override { return m_origName; }
|
||||
string hierName() const { return m_hierName; }
|
||||
void hierName(const string& hierName) { m_hierName = hierName; }
|
||||
string someInstanceName() const { return m_someInstanceName; }
|
||||
void someInstanceName(const string& name) { m_someInstanceName = name; }
|
||||
bool inLibrary() const { return m_inLibrary; }
|
||||
void inLibrary(bool flag) { m_inLibrary = flag; }
|
||||
void level(int level) { m_level = level; }
|
||||
|
@ -1914,14 +1914,14 @@ private:
|
||||
bool m_pure = false; // Pure optimizable
|
||||
public:
|
||||
AstCMethodHard(FileLine* fl, AstNode* fromp, VFlagChildDType, const string& name,
|
||||
AstNode* pinsp)
|
||||
AstNode* pinsp = nullptr)
|
||||
: ASTGEN_SUPER_CMethodHard(fl, false)
|
||||
, m_name{name} {
|
||||
setOp1p(fromp);
|
||||
dtypep(nullptr); // V3Width will resolve
|
||||
addNOp2p(pinsp);
|
||||
}
|
||||
AstCMethodHard(FileLine* fl, AstNode* fromp, const string& name, AstNode* pinsp)
|
||||
AstCMethodHard(FileLine* fl, AstNode* fromp, const string& name, AstNode* pinsp = nullptr)
|
||||
: ASTGEN_SUPER_CMethodHard(fl, false)
|
||||
, m_name{name} {
|
||||
setOp1p(fromp);
|
||||
@ -3407,7 +3407,7 @@ public:
|
||||
};
|
||||
|
||||
class AstInitialAutomatic final : public AstNodeProcedure {
|
||||
// initial for automatic variables
|
||||
// Automatic variable initialization
|
||||
// That is, it runs every function start, or class construction
|
||||
public:
|
||||
AstInitialAutomatic(FileLine* fl, AstNode* bodysp)
|
||||
@ -3415,6 +3415,15 @@ public:
|
||||
ASTNODE_NODE_FUNCS(InitialAutomatic)
|
||||
};
|
||||
|
||||
class AstInitialStatic final : public AstNodeProcedure {
|
||||
// Static variable initialization
|
||||
// That is, it runs at the beginning of simulation, before 'initial' blocks
|
||||
public:
|
||||
AstInitialStatic(FileLine* fl, AstNode* bodysp)
|
||||
: ASTGEN_SUPER_InitialStatic(fl, bodysp) {}
|
||||
ASTNODE_NODE_FUNCS(InitialStatic)
|
||||
};
|
||||
|
||||
class AstAlways final : public AstNodeProcedure {
|
||||
const VAlwaysKwd m_keyword;
|
||||
|
||||
@ -4610,7 +4619,7 @@ public:
|
||||
|
||||
class AstWhile final : public AstNodeStmt {
|
||||
public:
|
||||
AstWhile(FileLine* fl, AstNode* condp, AstNode* bodysp, AstNode* incsp = nullptr)
|
||||
AstWhile(FileLine* fl, AstNode* condp, AstNode* bodysp = nullptr, AstNode* incsp = nullptr)
|
||||
: ASTGEN_SUPER_While(fl) {
|
||||
setOp2p(condp);
|
||||
addNOp3p(bodysp);
|
||||
@ -4714,7 +4723,7 @@ private:
|
||||
bool m_unique0Pragma; // unique0 case
|
||||
bool m_priorityPragma; // priority case
|
||||
public:
|
||||
AstIf(FileLine* fl, AstNode* condp, AstNode* ifsp, AstNode* elsesp = nullptr)
|
||||
AstIf(FileLine* fl, AstNode* condp, AstNode* ifsp = nullptr, AstNode* elsesp = nullptr)
|
||||
: ASTGEN_SUPER_If(fl, condp, ifsp, elsesp) {
|
||||
m_uniquePragma = false;
|
||||
m_unique0Pragma = false;
|
||||
|
@ -427,8 +427,7 @@ private:
|
||||
if (++depth > CASE_ENCODER_GROUP_DEPTH) depth = 1;
|
||||
if (depth == 1) { // First group or starting new group
|
||||
itemnextp = nullptr;
|
||||
AstIf* const newp
|
||||
= new AstIf(itemp->fileline(), ifexprp->cloneTree(true), nullptr, nullptr);
|
||||
AstIf* const newp = new AstIf(itemp->fileline(), ifexprp->cloneTree(true));
|
||||
if (groupnextp) {
|
||||
groupnextp->addElsesp(newp);
|
||||
} else {
|
||||
@ -448,7 +447,7 @@ private:
|
||||
VL_DO_DANGLING(itemexprp->deleteTree(), itemexprp);
|
||||
itemexprp = new AstConst(itemp->fileline(), AstConst::BitTrue());
|
||||
}
|
||||
AstIf* const newp = new AstIf(itemp->fileline(), itemexprp, istmtsp, nullptr);
|
||||
AstIf* const newp = new AstIf(itemp->fileline(), itemexprp, istmtsp);
|
||||
if (itemnextp) {
|
||||
itemnextp->addElsesp(newp);
|
||||
} else {
|
||||
|
@ -716,6 +716,7 @@ private:
|
||||
// Ignores
|
||||
virtual void visit(AstInitial*) override {}
|
||||
virtual void visit(AstInitialAutomatic*) override {}
|
||||
virtual void visit(AstInitialStatic*) override {}
|
||||
virtual void visit(AstTraceDecl*) override {}
|
||||
virtual void visit(AstCoverToggle*) override {}
|
||||
virtual void visit(AstNodeDType*) override {}
|
||||
|
@ -153,6 +153,11 @@ private:
|
||||
iterateChildren(nodep);
|
||||
if (m_packageScopep) { m_toScopeMoves.push_back(std::make_pair(nodep, m_packageScopep)); }
|
||||
}
|
||||
virtual void visit(AstInitialStatic* nodep) override {
|
||||
// But not AstInitialAutomatic, which remains under the class
|
||||
iterateChildren(nodep);
|
||||
if (m_packageScopep) { m_toScopeMoves.push_back(std::make_pair(nodep, m_packageScopep)); }
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeMath* nodep) override {} // Short circuit
|
||||
virtual void visit(AstNodeStmt* nodep) override {} // Short circuit
|
||||
@ -173,7 +178,7 @@ public:
|
||||
vscp->scopep(scopep);
|
||||
vscp->unlinkFrBack();
|
||||
scopep->addVarp(vscp);
|
||||
} else if (VN_IS(nodep, Initial)) {
|
||||
} else if (VN_IS(nodep, Initial) || VN_IS(nodep, InitialStatic)) {
|
||||
nodep->unlinkFrBack();
|
||||
scopep->addActivep(nodep);
|
||||
} else {
|
||||
|
@ -185,7 +185,7 @@ private:
|
||||
AstIf* makeActiveIf(AstSenTree* sensesp) {
|
||||
AstNode* const senEqnp = createSenseEquation(sensesp->sensesp());
|
||||
UASSERT_OBJ(senEqnp, sensesp, "No sense equation, shouldn't be in sequent activation.");
|
||||
AstIf* const newifp = new AstIf(sensesp->fileline(), senEqnp, nullptr, nullptr);
|
||||
AstIf* const newifp = new AstIf(sensesp->fileline(), senEqnp);
|
||||
return newifp;
|
||||
}
|
||||
void clearLastSen() {
|
||||
@ -310,8 +310,8 @@ private:
|
||||
AstNode* const origp = nodep->origp()->unlinkFrBack();
|
||||
AstNode* const changeWrp = nodep->changep()->unlinkFrBack();
|
||||
AstNode* const changeRdp = ConvertWriteRefsToRead::main(changeWrp->cloneTree(false));
|
||||
AstIf* const newp = new AstIf(
|
||||
nodep->fileline(), new AstXor(nodep->fileline(), origp, changeRdp), incp, nullptr);
|
||||
AstIf* const newp
|
||||
= new AstIf(nodep->fileline(), new AstXor(nodep->fileline(), origp, changeRdp), incp);
|
||||
// We could add another IF to detect posedges, and only increment if so.
|
||||
// It's another whole branch though versus a potential memory miss.
|
||||
// We'll go with the miss.
|
||||
|
@ -351,8 +351,7 @@ private:
|
||||
"Delayed assignment misoptimized; prev var found w/o associated IF");
|
||||
} else {
|
||||
postLogicp = new AstIf(nodep->fileline(),
|
||||
new AstVarRef(nodep->fileline(), setvscp, VAccess::READ),
|
||||
nullptr, nullptr);
|
||||
new AstVarRef(nodep->fileline(), setvscp, VAccess::READ));
|
||||
UINFO(9, " Created " << postLogicp << endl);
|
||||
finalp->addStmtp(postLogicp);
|
||||
finalp->user3p(setvscp); // Remember IF's vset variable
|
||||
|
@ -161,7 +161,7 @@ private:
|
||||
new AstCMath(funcp->fileline(),
|
||||
string("&(") + funcp->scopep()->nameVlSym() + ")",
|
||||
64)),
|
||||
returnp, nullptr);
|
||||
returnp);
|
||||
newfuncp->addStmtsp(ifp);
|
||||
} else {
|
||||
newfuncp->addStmtsp(returnp);
|
||||
|
@ -406,7 +406,7 @@ public:
|
||||
virtual void visit(AstCMethodHard* nodep) override {
|
||||
iterate(nodep->fromp());
|
||||
puts(".");
|
||||
puts(nodep->nameProtect());
|
||||
puts(nodep->name());
|
||||
puts("(");
|
||||
bool comma = false;
|
||||
for (AstNode* subnodep = nodep->pinsp(); subnodep; subnodep = subnodep->nextp()) {
|
||||
|
@ -333,8 +333,8 @@ class EmitMkHierVerilation final {
|
||||
const V3HierBlockPlan::HierVector blocks
|
||||
= m_planp->hierBlocksSorted(); // leaf comes first
|
||||
// List in order of leaf-last order so that linker can resolve dependency
|
||||
for (auto it = blocks.rbegin(); it != blocks.rend(); ++it) {
|
||||
of.puts("\t" + (*it)->hierLib(true) + " \\\n");
|
||||
for (auto& block : vlstd::reverse_view(blocks)) {
|
||||
of.puts("\t" + block->hierLib(true) + " \\\n");
|
||||
}
|
||||
of.puts("\n");
|
||||
|
||||
|
195
src/V3EmitV.cpp
195
src/V3EmitV.cpp
@ -52,10 +52,10 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep) override { iterateAndNextNull(nodep->modulesp()); }
|
||||
virtual void visit(AstNetlist* nodep) override { iterateAndNextConstNull(nodep->modulesp()); }
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
putfs(nodep, nodep->verilogKwd() + " " + prefixNameProtect(nodep) + ";\n");
|
||||
iterateChildren(nodep);
|
||||
iterateChildrenConst(nodep);
|
||||
putqs(nodep, "end" + nodep->verilogKwd() + "\n");
|
||||
}
|
||||
virtual void visit(AstPort* nodep) override {}
|
||||
@ -65,7 +65,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
puts(nodep->prettyName());
|
||||
puts(";\n");
|
||||
// Only putfs the first time for each visitor; later for same node is putqs
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
iterateAndNextConstNull(nodep->stmtsp());
|
||||
putfs(nodep, nodep->isFunction() ? "endfunction\n" : "endtask\n");
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
} else {
|
||||
putbs("begin : " + nodep->name() + "\n");
|
||||
}
|
||||
iterateChildren(nodep);
|
||||
iterateChildrenConst(nodep);
|
||||
puts("end\n");
|
||||
}
|
||||
virtual void visit(AstFork* nodep) override {
|
||||
@ -84,75 +84,76 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
} else {
|
||||
putbs("fork : " + nodep->name() + "\n");
|
||||
}
|
||||
iterateChildren(nodep);
|
||||
iterateChildrenConst(nodep);
|
||||
puts(nodep->joinType().verilogKwd());
|
||||
puts("\n");
|
||||
}
|
||||
virtual void visit(AstFinal* nodep) override {
|
||||
putfs(nodep, "final begin\n");
|
||||
iterateChildren(nodep);
|
||||
iterateChildrenConst(nodep);
|
||||
putqs(nodep, "end\n");
|
||||
}
|
||||
virtual void visit(AstInitial* nodep) override {
|
||||
putfs(nodep, "initial begin\n");
|
||||
iterateChildren(nodep);
|
||||
iterateChildrenConst(nodep);
|
||||
putqs(nodep, "end\n");
|
||||
}
|
||||
virtual void visit(AstInitialAutomatic* nodep) override { iterateChildren(nodep); }
|
||||
virtual void visit(AstInitialAutomatic* nodep) override { iterateChildrenConst(nodep); }
|
||||
virtual void visit(AstInitialStatic* nodep) override { iterateChildrenConst(nodep); }
|
||||
virtual void visit(AstAlways* nodep) override {
|
||||
putfs(nodep, "always ");
|
||||
if (m_sensesp) {
|
||||
iterateAndNextNull(m_sensesp);
|
||||
iterateAndNextConstNull(m_sensesp);
|
||||
} // In active
|
||||
else {
|
||||
iterateAndNextNull(nodep->sensesp());
|
||||
iterateAndNextConstNull(nodep->sensesp());
|
||||
}
|
||||
putbs(" begin\n");
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextConstNull(nodep->bodysp());
|
||||
putqs(nodep, "end\n");
|
||||
}
|
||||
virtual void visit(AstAlwaysPublic* nodep) override {
|
||||
putfs(nodep, "/*verilator public_flat_rw ");
|
||||
if (m_sensesp) {
|
||||
iterateAndNextNull(m_sensesp);
|
||||
iterateAndNextConstNull(m_sensesp);
|
||||
} // In active
|
||||
else {
|
||||
iterateAndNextNull(nodep->sensesp());
|
||||
iterateAndNextConstNull(nodep->sensesp());
|
||||
}
|
||||
putqs(nodep, " ");
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextConstNull(nodep->bodysp());
|
||||
putqs(nodep, "*/\n");
|
||||
}
|
||||
virtual void visit(AstNodeAssign* nodep) override {
|
||||
if (VN_IS(nodep, AssignForce)) puts("force ");
|
||||
iterateAndNextNull(nodep->lhsp());
|
||||
iterateAndNextConstNull(nodep->lhsp());
|
||||
putfs(nodep, " " + nodep->verilogKwd() + " ");
|
||||
iterateAndNextNull(nodep->rhsp());
|
||||
iterateAndNextConstNull(nodep->rhsp());
|
||||
if (!m_suppressSemi) puts(";\n");
|
||||
}
|
||||
virtual void visit(AstAssignDly* nodep) override {
|
||||
iterateAndNextNull(nodep->lhsp());
|
||||
iterateAndNextConstNull(nodep->lhsp());
|
||||
putfs(nodep, " <= ");
|
||||
iterateAndNextNull(nodep->rhsp());
|
||||
iterateAndNextConstNull(nodep->rhsp());
|
||||
puts(";\n");
|
||||
}
|
||||
virtual void visit(AstAssignAlias* nodep) override {
|
||||
putbs("alias ");
|
||||
iterateAndNextNull(nodep->lhsp());
|
||||
iterateAndNextConstNull(nodep->lhsp());
|
||||
putfs(nodep, " = ");
|
||||
iterateAndNextNull(nodep->rhsp());
|
||||
iterateAndNextConstNull(nodep->rhsp());
|
||||
if (!m_suppressSemi) puts(";\n");
|
||||
}
|
||||
virtual void visit(AstAssignW* nodep) override {
|
||||
putfs(nodep, "assign ");
|
||||
iterateAndNextNull(nodep->lhsp());
|
||||
iterateAndNextConstNull(nodep->lhsp());
|
||||
putbs(" = ");
|
||||
iterateAndNextNull(nodep->rhsp());
|
||||
iterateAndNextConstNull(nodep->rhsp());
|
||||
if (!m_suppressSemi) puts(";\n");
|
||||
}
|
||||
virtual void visit(AstRelease* nodep) override {
|
||||
puts("release ");
|
||||
iterateAndNextNull(nodep->lhsp());
|
||||
iterateAndNextConstNull(nodep->lhsp());
|
||||
if (!m_suppressSemi) puts(";\n");
|
||||
}
|
||||
virtual void visit(AstBreak*) override {
|
||||
@ -172,7 +173,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
putfs(nodep, "");
|
||||
puts(nodep->edgeType().verilogKwd());
|
||||
if (nodep->sensp()) puts(" ");
|
||||
iterateChildren(nodep);
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
virtual void visit(AstNodeCase* nodep) override {
|
||||
putfs(nodep, "");
|
||||
@ -183,7 +184,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
}
|
||||
puts(nodep->verilogKwd());
|
||||
puts(" (");
|
||||
iterateAndNextNull(nodep->exprp());
|
||||
iterateAndNextConstNull(nodep->exprp());
|
||||
puts(")\n");
|
||||
if (const AstCase* const casep = VN_CAST(nodep, Case)) {
|
||||
if (casep->fullPragma() || casep->parallelPragma()) {
|
||||
@ -192,22 +193,22 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
if (casep->parallelPragma()) puts(" parallel_case");
|
||||
}
|
||||
}
|
||||
iterateAndNextNull(nodep->itemsp());
|
||||
iterateAndNextConstNull(nodep->itemsp());
|
||||
putqs(nodep, "endcase\n");
|
||||
}
|
||||
virtual void visit(AstCaseItem* nodep) override {
|
||||
if (nodep->condsp()) {
|
||||
iterateAndNextNull(nodep->condsp());
|
||||
iterateAndNextConstNull(nodep->condsp());
|
||||
} else {
|
||||
putbs("default");
|
||||
}
|
||||
putfs(nodep, ": begin ");
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextConstNull(nodep->bodysp());
|
||||
putqs(nodep, "end\n");
|
||||
}
|
||||
virtual void visit(AstComment* nodep) override {
|
||||
puts(string("// ") + nodep->name() + "\n");
|
||||
iterateChildren(nodep);
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
virtual void visit(AstContinue*) override {
|
||||
putbs("continue");
|
||||
@ -222,13 +223,13 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
putfs(nodep, nodep->verilogKwd());
|
||||
putbs("(");
|
||||
if (fileOrStrgp) {
|
||||
iterateAndNextNull(fileOrStrgp);
|
||||
iterateAndNextConstNull(fileOrStrgp);
|
||||
putbs(", ");
|
||||
}
|
||||
putsQuoted(text);
|
||||
for (AstNode* expp = exprsp; expp; expp = expp->nextp()) {
|
||||
puts(", ");
|
||||
iterateAndNextNull(expp);
|
||||
iterateAndNextConstNull(expp);
|
||||
}
|
||||
puts(");\n");
|
||||
}
|
||||
@ -254,32 +255,32 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
virtual void visit(AstFOpen* nodep) override {
|
||||
putfs(nodep, nodep->verilogKwd());
|
||||
putbs("(");
|
||||
iterateAndNextNull(nodep->filenamep());
|
||||
iterateAndNextConstNull(nodep->filenamep());
|
||||
putbs(", ");
|
||||
iterateAndNextNull(nodep->modep());
|
||||
iterateAndNextConstNull(nodep->modep());
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstFOpenMcd* nodep) override {
|
||||
putfs(nodep, nodep->verilogKwd());
|
||||
putbs("(");
|
||||
iterateAndNextNull(nodep->filenamep());
|
||||
iterateAndNextConstNull(nodep->filenamep());
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstFClose* nodep) override {
|
||||
putfs(nodep, nodep->verilogKwd());
|
||||
putbs("(");
|
||||
if (nodep->filep()) iterateAndNextNull(nodep->filep());
|
||||
if (nodep->filep()) iterateAndNextConstNull(nodep->filep());
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstFFlush* nodep) override {
|
||||
putfs(nodep, nodep->verilogKwd());
|
||||
putbs("(");
|
||||
if (nodep->filep()) iterateAndNextNull(nodep->filep());
|
||||
if (nodep->filep()) iterateAndNextConstNull(nodep->filep());
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstJumpBlock* nodep) override {
|
||||
putbs("begin : label" + cvtToStr(nodep->labelNum()) + "\n");
|
||||
if (nodep->stmtsp()) iterateAndNextNull(nodep->stmtsp());
|
||||
if (nodep->stmtsp()) iterateAndNextConstNull(nodep->stmtsp());
|
||||
puts("end\n");
|
||||
}
|
||||
virtual void visit(AstJumpGo* nodep) override {
|
||||
@ -291,27 +292,27 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
virtual void visit(AstNodeReadWriteMem* nodep) override {
|
||||
putfs(nodep, nodep->verilogKwd());
|
||||
putbs("(");
|
||||
if (nodep->filenamep()) iterateAndNextNull(nodep->filenamep());
|
||||
if (nodep->filenamep()) iterateAndNextConstNull(nodep->filenamep());
|
||||
putbs(", ");
|
||||
if (nodep->memp()) iterateAndNextNull(nodep->memp());
|
||||
if (nodep->memp()) iterateAndNextConstNull(nodep->memp());
|
||||
if (nodep->lsbp()) {
|
||||
putbs(", ");
|
||||
iterateAndNextNull(nodep->lsbp());
|
||||
iterateAndNextConstNull(nodep->lsbp());
|
||||
}
|
||||
if (nodep->msbp()) {
|
||||
putbs(", ");
|
||||
iterateAndNextNull(nodep->msbp());
|
||||
iterateAndNextConstNull(nodep->msbp());
|
||||
}
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstSysFuncAsTask* nodep) override {
|
||||
iterateAndNextNull(nodep->lhsp());
|
||||
iterateAndNextConstNull(nodep->lhsp());
|
||||
puts(";\n");
|
||||
}
|
||||
virtual void visit(AstSysIgnore* nodep) override {
|
||||
putfs(nodep, nodep->verilogKwd());
|
||||
putbs("(");
|
||||
iterateAndNextNull(nodep->exprsp());
|
||||
iterateAndNextConstNull(nodep->exprsp());
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstNodeFor* nodep) override {
|
||||
@ -319,31 +320,31 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
{
|
||||
VL_RESTORER(m_suppressSemi);
|
||||
m_suppressSemi = true;
|
||||
iterateAndNextNull(nodep->initsp());
|
||||
iterateAndNextConstNull(nodep->initsp());
|
||||
puts(";");
|
||||
iterateAndNextNull(nodep->condp());
|
||||
iterateAndNextConstNull(nodep->condp());
|
||||
puts(";");
|
||||
iterateAndNextNull(nodep->incsp());
|
||||
iterateAndNextConstNull(nodep->incsp());
|
||||
}
|
||||
puts(") begin\n");
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextConstNull(nodep->bodysp());
|
||||
putqs(nodep, "end\n");
|
||||
}
|
||||
virtual void visit(AstRepeat* nodep) override {
|
||||
putfs(nodep, "repeat (");
|
||||
iterateAndNextNull(nodep->countp());
|
||||
iterateAndNextConstNull(nodep->countp());
|
||||
puts(") begin\n");
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextConstNull(nodep->bodysp());
|
||||
putfs(nodep, "end\n");
|
||||
}
|
||||
virtual void visit(AstWhile* nodep) override {
|
||||
iterateAndNextNull(nodep->precondsp());
|
||||
iterateAndNextConstNull(nodep->precondsp());
|
||||
putfs(nodep, "while (");
|
||||
iterateAndNextNull(nodep->condp());
|
||||
iterateAndNextConstNull(nodep->condp());
|
||||
puts(") begin\n");
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextNull(nodep->incsp());
|
||||
iterateAndNextNull(nodep->precondsp()); // Need to recompute before next loop
|
||||
iterateAndNextConstNull(nodep->bodysp());
|
||||
iterateAndNextConstNull(nodep->incsp());
|
||||
iterateAndNextConstNull(nodep->precondsp()); // Need to recompute before next loop
|
||||
putfs(nodep, "end\n");
|
||||
}
|
||||
virtual void visit(AstNodeIf* nodep) override {
|
||||
@ -354,28 +355,28 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
if (ifp->unique0Pragma()) puts("unique0 ");
|
||||
}
|
||||
puts("if (");
|
||||
iterateAndNextNull(nodep->condp());
|
||||
iterateAndNextConstNull(nodep->condp());
|
||||
puts(") begin\n");
|
||||
iterateAndNextNull(nodep->ifsp());
|
||||
iterateAndNextConstNull(nodep->ifsp());
|
||||
if (nodep->elsesp()) {
|
||||
putqs(nodep, "end\n");
|
||||
putqs(nodep, "else begin\n");
|
||||
iterateAndNextNull(nodep->elsesp());
|
||||
iterateAndNextConstNull(nodep->elsesp());
|
||||
}
|
||||
putqs(nodep, "end\n");
|
||||
}
|
||||
virtual void visit(AstPast* nodep) override {
|
||||
putfs(nodep, "$past(");
|
||||
iterateAndNextNull(nodep->exprp());
|
||||
iterateAndNextConstNull(nodep->exprp());
|
||||
if (nodep->ticksp()) {
|
||||
puts(", ");
|
||||
iterateAndNextNull(nodep->ticksp());
|
||||
iterateAndNextConstNull(nodep->ticksp());
|
||||
}
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstReturn* nodep) override {
|
||||
putfs(nodep, "return ");
|
||||
iterateAndNextNull(nodep->lhsp());
|
||||
iterateAndNextConstNull(nodep->lhsp());
|
||||
puts(";\n");
|
||||
}
|
||||
virtual void visit(AstStop* nodep) override { putfs(nodep, "$stop;\n"); }
|
||||
@ -401,22 +402,22 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
virtual void visit(AstScopeName* nodep) override {}
|
||||
virtual void visit(AstCStmt* nodep) override {
|
||||
putfs(nodep, "$_CSTMT(");
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextConstNull(nodep->bodysp());
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstCMath* nodep) override {
|
||||
putfs(nodep, "$_CMATH(");
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextConstNull(nodep->bodysp());
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstUCStmt* nodep) override {
|
||||
putfs(nodep, "$c(");
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextConstNull(nodep->bodysp());
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstUCFunc* nodep) override {
|
||||
putfs(nodep, "$c(");
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
iterateAndNextConstNull(nodep->bodysp());
|
||||
puts(")");
|
||||
}
|
||||
|
||||
@ -450,27 +451,27 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
case 'k': putbs(""); break;
|
||||
case 'l': {
|
||||
UASSERT_OBJ(lhsp, nodep, "emitVerilog() references undef node");
|
||||
iterateAndNextNull(lhsp);
|
||||
iterateAndNextConstNull(lhsp);
|
||||
break;
|
||||
}
|
||||
case 'r': {
|
||||
UASSERT_OBJ(rhsp, nodep, "emitVerilog() references undef node");
|
||||
iterateAndNextNull(rhsp);
|
||||
iterateAndNextConstNull(rhsp);
|
||||
break;
|
||||
}
|
||||
case 't': {
|
||||
UASSERT_OBJ(thsp, nodep, "emitVerilog() references undef node");
|
||||
iterateAndNextNull(thsp);
|
||||
iterateAndNextConstNull(thsp);
|
||||
break;
|
||||
}
|
||||
case 'o': {
|
||||
UASSERT_OBJ(thsp, nodep, "emitVerilog() references undef node");
|
||||
iterateAndNextNull(fhsp);
|
||||
iterateAndNextConstNull(fhsp);
|
||||
break;
|
||||
}
|
||||
case 'd': {
|
||||
UASSERT_OBJ(nodep->dtypep(), nodep, "emitVerilog() references undef node");
|
||||
iterateAndNextNull(nodep->dtypep());
|
||||
iterateAndNextConstNull(nodep->dtypep());
|
||||
break;
|
||||
}
|
||||
default: nodep->v3fatalSrc("Unknown emitVerilog format code: %" << c); break;
|
||||
@ -494,10 +495,10 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
}
|
||||
virtual void visit(AstAttrOf* nodep) override {
|
||||
putfs(nodep, "$_ATTROF(");
|
||||
iterateAndNextNull(nodep->fromp());
|
||||
iterateAndNextConstNull(nodep->fromp());
|
||||
if (nodep->dimp()) {
|
||||
putbs(", ");
|
||||
iterateAndNextNull(nodep->dimp());
|
||||
iterateAndNextConstNull(nodep->dimp());
|
||||
}
|
||||
puts(")");
|
||||
}
|
||||
@ -516,11 +517,11 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
}
|
||||
virtual void visit(AstNodeCond* nodep) override {
|
||||
putbs("(");
|
||||
iterateAndNextNull(nodep->condp());
|
||||
iterateAndNextConstNull(nodep->condp());
|
||||
putfs(nodep, " ? ");
|
||||
iterateAndNextNull(nodep->expr1p());
|
||||
iterateAndNextConstNull(nodep->expr1p());
|
||||
putbs(" : ");
|
||||
iterateAndNextNull(nodep->expr2p());
|
||||
iterateAndNextConstNull(nodep->expr2p());
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstRange* nodep) override {
|
||||
@ -532,21 +533,21 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
puts(cvtToStr(nodep->rightConst()));
|
||||
puts("]");
|
||||
} else {
|
||||
iterateAndNextNull(nodep->leftp());
|
||||
iterateAndNextConstNull(nodep->leftp());
|
||||
puts(":");
|
||||
iterateAndNextNull(nodep->rightp());
|
||||
iterateAndNextConstNull(nodep->rightp());
|
||||
puts("]");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstSel* nodep) override {
|
||||
iterateAndNextNull(nodep->fromp());
|
||||
iterateAndNextConstNull(nodep->fromp());
|
||||
puts("[");
|
||||
if (VN_IS(nodep->lsbp(), Const)) {
|
||||
if (nodep->widthp()->isOne()) {
|
||||
if (VN_IS(nodep->lsbp(), Const)) {
|
||||
puts(cvtToStr(VN_AS(nodep->lsbp(), Const)->toSInt()));
|
||||
} else {
|
||||
iterateAndNextNull(nodep->lsbp());
|
||||
iterateAndNextConstNull(nodep->lsbp());
|
||||
}
|
||||
} else {
|
||||
puts(cvtToStr(VN_AS(nodep->lsbp(), Const)->toSInt()
|
||||
@ -555,20 +556,20 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
puts(cvtToStr(VN_AS(nodep->lsbp(), Const)->toSInt()));
|
||||
}
|
||||
} else {
|
||||
iterateAndNextNull(nodep->lsbp());
|
||||
iterateAndNextConstNull(nodep->lsbp());
|
||||
putfs(nodep, "+:");
|
||||
iterateAndNextNull(nodep->widthp());
|
||||
iterateAndNextConstNull(nodep->widthp());
|
||||
puts("]");
|
||||
}
|
||||
puts("]");
|
||||
}
|
||||
virtual void visit(AstSliceSel* nodep) override {
|
||||
iterateAndNextNull(nodep->fromp());
|
||||
iterateAndNextConstNull(nodep->fromp());
|
||||
puts(cvtToStr(nodep->declRange()));
|
||||
}
|
||||
virtual void visit(AstTypedef* nodep) override {
|
||||
putfs(nodep, "typedef ");
|
||||
iterateAndNextNull(nodep->dtypep());
|
||||
iterateAndNextConstNull(nodep->dtypep());
|
||||
puts(" ");
|
||||
puts(nodep->prettyName());
|
||||
puts(";\n");
|
||||
@ -578,7 +579,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
putfs(nodep, nodep->prettyName());
|
||||
if (nodep->rangep()) {
|
||||
puts(" ");
|
||||
iterateAndNextNull(nodep->rangep());
|
||||
iterateAndNextConstNull(nodep->rangep());
|
||||
puts(" ");
|
||||
} else if (nodep->isRanged()) {
|
||||
puts(" [");
|
||||
@ -592,14 +593,14 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
}
|
||||
virtual void visit(AstNodeArrayDType* nodep) override {
|
||||
iterate(nodep->subDTypep());
|
||||
iterateAndNextNull(nodep->rangep());
|
||||
iterateAndNextConstNull(nodep->rangep());
|
||||
}
|
||||
virtual void visit(AstNodeUOrStructDType* nodep) override {
|
||||
puts(nodep->verilogKwd() + " ");
|
||||
if (nodep->packed()) puts("packed ");
|
||||
puts("\n");
|
||||
puts("{");
|
||||
iterateAndNextNull(nodep->membersp());
|
||||
iterateAndNextConstNull(nodep->membersp());
|
||||
puts("}");
|
||||
}
|
||||
virtual void visit(AstMemberDType* nodep) override {
|
||||
@ -616,10 +617,10 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
putfs(nodep, nodep->prettyName());
|
||||
}
|
||||
puts("(");
|
||||
iterateAndNextNull(nodep->pinsp());
|
||||
iterateAndNextConstNull(nodep->pinsp());
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstArg* nodep) override { iterateAndNextNull(nodep->exprp()); }
|
||||
virtual void visit(AstArg* nodep) override { iterateAndNextConstNull(nodep->exprp()); }
|
||||
virtual void visit(AstPrintTimeScale* nodep) override {
|
||||
puts(nodep->verilogKwd());
|
||||
puts(";\n");
|
||||
@ -654,8 +655,8 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
virtual void visit(AstConst* nodep) override { putfs(nodep, nodep->num().ascii(true, true)); }
|
||||
|
||||
// Just iterate
|
||||
virtual void visit(AstTopScope* nodep) override { iterateChildren(nodep); }
|
||||
virtual void visit(AstScope* nodep) override { iterateChildren(nodep); }
|
||||
virtual void visit(AstTopScope* nodep) override { iterateChildrenConst(nodep); }
|
||||
virtual void visit(AstScope* nodep) override { iterateChildrenConst(nodep); }
|
||||
virtual void visit(AstVar* nodep) override {
|
||||
if (nodep->isIO()) {
|
||||
putfs(nodep, nodep->verilogKwd());
|
||||
@ -686,7 +687,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
}
|
||||
virtual void visit(AstActive* nodep) override {
|
||||
m_sensesp = nodep->sensesp();
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
iterateAndNextConstNull(nodep->stmtsp());
|
||||
m_sensesp = nullptr;
|
||||
}
|
||||
virtual void visit(AstParseRef* nodep) override { puts(nodep->prettyName()); }
|
||||
@ -700,7 +701,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||
// Default
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
puts(string("\n???? // ") + nodep->prettyTypeName() + "\n");
|
||||
iterateChildren(nodep);
|
||||
iterateChildrenConst(nodep);
|
||||
// Not v3fatalSrc so we keep processing
|
||||
if (!m_suppressUnknown) {
|
||||
nodep->v3error(
|
||||
@ -754,10 +755,10 @@ class EmitVStreamVisitor final : public EmitVBaseVisitor {
|
||||
virtual void putqs(AstNode*, const string& str) override { putbs(str); }
|
||||
|
||||
public:
|
||||
EmitVStreamVisitor(AstNode* nodep, std::ostream& os)
|
||||
EmitVStreamVisitor(const AstNode* nodep, std::ostream& os)
|
||||
: EmitVBaseVisitor{false, nullptr}
|
||||
, m_os(os) { // Need () or GCC 4.8 false warning
|
||||
iterate(nodep);
|
||||
iterate(const_cast<AstNode*>(nodep));
|
||||
}
|
||||
virtual ~EmitVStreamVisitor() override = default;
|
||||
};
|
||||
@ -828,12 +829,12 @@ class EmitVPrefixedVisitor final : public EmitVBaseVisitor {
|
||||
}
|
||||
|
||||
public:
|
||||
EmitVPrefixedVisitor(AstNode* nodep, std::ostream& os, const string& prefix, int flWidth,
|
||||
EmitVPrefixedVisitor(const AstNode* nodep, std::ostream& os, const string& prefix, int flWidth,
|
||||
AstSenTree* domainp, bool user3mark)
|
||||
: EmitVBaseVisitor{false, domainp}
|
||||
, m_formatter{os, prefix, flWidth} {
|
||||
if (user3mark) VNUser3InUse::check();
|
||||
iterate(nodep);
|
||||
iterate(const_cast<AstNode*>(nodep));
|
||||
}
|
||||
virtual ~EmitVPrefixedVisitor() override = default;
|
||||
};
|
||||
@ -841,11 +842,11 @@ public:
|
||||
//######################################################################
|
||||
// EmitV class functions
|
||||
|
||||
void V3EmitV::verilogForTree(AstNode* nodep, std::ostream& os) {
|
||||
void V3EmitV::verilogForTree(const AstNode* nodep, std::ostream& os) {
|
||||
{ EmitVStreamVisitor{nodep, os}; }
|
||||
}
|
||||
|
||||
void V3EmitV::verilogPrefixedTree(AstNode* nodep, std::ostream& os, const string& prefix,
|
||||
void V3EmitV::verilogPrefixedTree(const AstNode* nodep, std::ostream& os, const string& prefix,
|
||||
int flWidth, AstSenTree* domainp, bool user3mark) {
|
||||
{ EmitVPrefixedVisitor{nodep, os, prefix, flWidth, domainp, user3mark}; }
|
||||
}
|
||||
|
@ -27,8 +27,8 @@ class AstSenTree;
|
||||
|
||||
class V3EmitV final {
|
||||
public:
|
||||
static void verilogForTree(AstNode* nodep, std::ostream& os = std::cout);
|
||||
static void verilogPrefixedTree(AstNode* nodep, std::ostream& os, const string& prefix,
|
||||
static void verilogForTree(const AstNode* nodep, std::ostream& os = std::cout);
|
||||
static void verilogPrefixedTree(const AstNode* nodep, std::ostream& os, const string& prefix,
|
||||
int flWidth, AstSenTree* domainp, bool user3mark);
|
||||
static void emitvFiles();
|
||||
static void debugEmitV(const string& filename);
|
||||
|
@ -183,7 +183,7 @@ void V3Error::suppressThisWarning() {
|
||||
|
||||
string V3Error::warnMore() { return string(msgPrefix().size(), ' '); }
|
||||
|
||||
void V3Error::v3errorEnd(std::ostringstream& sstr, const string& locationStr) {
|
||||
void V3Error::v3errorEnd(std::ostringstream& sstr, const string& extra) {
|
||||
#if defined(__COVERITY__) || defined(__cppcheck__)
|
||||
if (s_errorCode == V3ErrorCode::EC_FATAL) __coverity_panic__(x);
|
||||
#endif
|
||||
@ -209,10 +209,10 @@ void V3Error::v3errorEnd(std::ostringstream& sstr, const string& locationStr) {
|
||||
// Suppress duplicate messages
|
||||
if (s_messages.find(msg) != s_messages.end()) return;
|
||||
s_messages.insert(msg);
|
||||
if (!locationStr.empty()) {
|
||||
const string locationMsg = warnMore() + locationStr + "\n";
|
||||
if (!extra.empty()) {
|
||||
const string extraMsg = warnMore() + extra + "\n";
|
||||
const size_t pos = msg.find('\n');
|
||||
msg.insert(pos + 1, locationMsg);
|
||||
msg.insert(pos + 1, extraMsg);
|
||||
}
|
||||
// Output
|
||||
if (
|
||||
|
@ -313,7 +313,7 @@ public:
|
||||
static void vlAbortOrExit();
|
||||
static void vlAbort();
|
||||
// static, but often overridden in classes.
|
||||
static void v3errorEnd(std::ostringstream& sstr, const string& locationStr = "");
|
||||
static void v3errorEnd(std::ostringstream& sstr, const string& extra = "");
|
||||
};
|
||||
|
||||
// Global versions, so that if the class doesn't define a operator, we get the functions anyways.
|
||||
|
@ -340,15 +340,15 @@ void FileLine::modifyStateInherit(const FileLine* fromp) {
|
||||
}
|
||||
}
|
||||
|
||||
void FileLine::v3errorEnd(std::ostringstream& sstr, const string& locationStr) {
|
||||
void FileLine::v3errorEnd(std::ostringstream& sstr, const string& extra) {
|
||||
std::ostringstream nsstr;
|
||||
if (lastLineno()) nsstr << this;
|
||||
nsstr << sstr.str();
|
||||
nsstr << endl;
|
||||
std::ostringstream lstr;
|
||||
if (!locationStr.empty()) {
|
||||
if (!extra.empty()) {
|
||||
lstr << std::setw(ascii().length()) << " "
|
||||
<< ": " << locationStr;
|
||||
<< ": " << extra;
|
||||
}
|
||||
m_waive = V3Config::waive(this, V3Error::errorCode(), sstr.str());
|
||||
if (warnIsOff(V3Error::errorCode()) || m_waive) {
|
||||
|
@ -245,7 +245,7 @@ public:
|
||||
void modifyWarnOff(V3ErrorCode code, bool flag) { warnOff(code, flag); }
|
||||
|
||||
// OPERATORS
|
||||
void v3errorEnd(std::ostringstream& str, const string& locationStr = "");
|
||||
void v3errorEnd(std::ostringstream& str, const string& extra = "");
|
||||
void v3errorEndFatal(std::ostringstream& str);
|
||||
/// When building an error, prefix for printing continuation lines
|
||||
/// e.g. information referring to the same FileLine as before
|
||||
|
@ -299,9 +299,8 @@ private:
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {});
|
||||
}
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, false, [=]() {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, false, [=]() { //
|
||||
m_hash += nodep->origName();
|
||||
m_hash += nodep->hierName();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstNodePreSel* nodep) override {
|
||||
|
@ -190,8 +190,7 @@ private:
|
||||
|
||||
// Iterate through all modules in bottom-up order.
|
||||
// Make a final inlining decision for each.
|
||||
for (auto it = m_allMods.rbegin(); it != m_allMods.rend(); ++it) {
|
||||
AstNodeModule* const modp = *it;
|
||||
for (AstNodeModule* const modp : vlstd::reverse_view(m_allMods)) {
|
||||
|
||||
// If we're going to inline some modules into this one,
|
||||
// update user4 (statement count) to reflect that:
|
||||
@ -647,7 +646,11 @@ private:
|
||||
m_scope += "__DOT__" + nodep->name();
|
||||
}
|
||||
|
||||
if (AstModule* const modp = VN_CAST(nodep->modp(), Module)) {
|
||||
if (VN_IS(nodep->modp(), Iface)) {
|
||||
nodep->addIntfRefp(new AstIntfRef{nodep->fileline(), m_scope});
|
||||
}
|
||||
{
|
||||
AstNodeModule* const modp = nodep->modp();
|
||||
// Pass Cell pointers down to the next module
|
||||
for (AstPin* pinp = nodep->pinsp(); pinp; pinp = VN_AS(pinp->nextp(), Pin)) {
|
||||
AstVar* const varp = pinp->modVarp();
|
||||
@ -666,9 +669,6 @@ private:
|
||||
}
|
||||
|
||||
iterateChildren(modp);
|
||||
} else if (VN_IS(nodep->modp(), Iface)) {
|
||||
nodep->addIntfRefp(new AstIntfRef(nodep->fileline(), m_scope));
|
||||
// No need to iterate on interface cells
|
||||
}
|
||||
}
|
||||
virtual void visit(AstAssignVarScope* nodep) override {
|
||||
|
@ -263,10 +263,10 @@ private:
|
||||
UINFO(8, " DISABLE " << nodep << endl);
|
||||
iterateChildren(nodep);
|
||||
AstNodeBlock* blockp = nullptr;
|
||||
for (auto it = m_blockStack.rbegin(); it != m_blockStack.rend(); ++it) {
|
||||
UINFO(9, " UNDERBLK " << *it << endl);
|
||||
if ((*it)->name() == nodep->name()) {
|
||||
blockp = *it;
|
||||
for (AstNodeBlock* const stackp : vlstd::reverse_view(m_blockStack)) {
|
||||
UINFO(9, " UNDERBLK " << stackp << endl);
|
||||
if (stackp->name() == nodep->name()) {
|
||||
blockp = stackp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -275,7 +275,7 @@ private:
|
||||
if (nodep->lifetime().isAutomatic()) {
|
||||
nodep->addNextHere(new AstInitialAutomatic{newfl, assp});
|
||||
} else {
|
||||
nodep->addNextHere(new AstInitial{newfl, assp});
|
||||
nodep->addNextHere(new AstInitialStatic{newfl, assp});
|
||||
}
|
||||
} // 4. Under blocks, it's an initial value to be under an assign
|
||||
else {
|
||||
|
@ -266,7 +266,7 @@ private:
|
||||
// and we also need to keep track of it for comparisons later.
|
||||
m_mgCondp = m_mgCondp->cloneTree(false);
|
||||
// Create equivalent 'if' statement and insert it before the first node
|
||||
AstIf* const resultp = new AstIf(m_mgCondp->fileline(), m_mgCondp, nullptr, nullptr);
|
||||
AstIf* const resultp = new AstIf(m_mgCondp->fileline(), m_mgCondp);
|
||||
m_mgFirstp->addHereThisAsNext(resultp);
|
||||
// Unzip the list and insert under branches
|
||||
AstNode* nextp = m_mgFirstp;
|
||||
|
@ -662,6 +662,9 @@ class OrderBuildVisitor final : public VNVisitor {
|
||||
virtual void visit(AstInitialAutomatic* nodep) override { //
|
||||
iterateLogic(nodep);
|
||||
}
|
||||
virtual void visit(AstInitialStatic* nodep) override { //
|
||||
iterateLogic(nodep);
|
||||
}
|
||||
virtual void visit(AstAlways* nodep) override { //
|
||||
iterateLogic(nodep);
|
||||
}
|
||||
|
203
src/V3Param.cpp
203
src/V3Param.cpp
@ -555,14 +555,12 @@ class ParamProcessor final {
|
||||
cellp->v3error("Exceeded maximum --module-recursion-depth of "
|
||||
<< v3Global.opt.moduleRecursionDepth());
|
||||
}
|
||||
// Keep tree sorted by level. Append to end of sub-list at the same level. This is
|
||||
// important because due to the way recursive modules are handled, different
|
||||
// parametrizations of the same recursive module end up with the same level (which in
|
||||
// itself is a bit unfortunate). Nevertheless, as a later parametrization must not be above
|
||||
// an earlier parametrization of a recursive module, it is sufficient to add to the end of
|
||||
// the sub-list to keep the modules topologically sorted.
|
||||
// Keep tree sorted by level. Note: Different parametrizations of the same recursive module
|
||||
// end up with the same level, which we will need to fix up at the end, as we do not know
|
||||
// up front how recursive modules are expanded, and a later expansion might re-use an
|
||||
// earlier expansion (see t_recursive_module_bug_2).
|
||||
AstNodeModule* insertp = srcModp;
|
||||
while (VN_IS(insertp->nextp(), NodeModule)
|
||||
while (insertp->nextp()
|
||||
&& VN_AS(insertp->nextp(), NodeModule)->level() <= newmodp->level()) {
|
||||
insertp = VN_AS(insertp->nextp(), NodeModule);
|
||||
}
|
||||
@ -761,7 +759,7 @@ class ParamProcessor final {
|
||||
}
|
||||
|
||||
public:
|
||||
void cellDeparam(AstCell* nodep, AstNodeModule* modp, const string& hierName) {
|
||||
void cellDeparam(AstCell* nodep, AstNodeModule* modp, const string& someInstanceName) {
|
||||
m_modp = modp;
|
||||
// Cell: Check for parameters in the instantiation.
|
||||
// We always run this, even if no parameters, as need to look for interfaces,
|
||||
@ -772,7 +770,7 @@ public:
|
||||
// Evaluate all module constants
|
||||
V3Const::constifyParamsEdit(nodep);
|
||||
AstNodeModule* const srcModp = nodep->modp();
|
||||
srcModp->hierName(hierName + "." + nodep->name());
|
||||
srcModp->someInstanceName(someInstanceName + "." + nodep->name());
|
||||
|
||||
// Make sure constification worked
|
||||
// Must be a separate loop, as constant conversion may have changed some pointers.
|
||||
@ -843,79 +841,99 @@ public:
|
||||
// Process parameter visitor
|
||||
|
||||
class ParamVisitor final : public VNVisitor {
|
||||
// NODE STATE
|
||||
// AstNodeModule::user1 -> bool: already fixed level
|
||||
|
||||
// STATE
|
||||
ParamProcessor m_processor; // De-parameterize a cell, build modules
|
||||
UnrollStateful m_unroller; // Loop unroller
|
||||
|
||||
AstNodeModule* m_modp = nullptr; // Current module being processed
|
||||
bool m_iterateModule = false; // Iterating module body
|
||||
string m_generateHierName; // Generate portion of hierarchy name
|
||||
string m_unlinkedTxt; // Text for AstUnlinkedRef
|
||||
std::deque<AstCell*> m_cellps; // Cells left to process (in this module)
|
||||
std::deque<AstCell*> m_cellps; // Cells left to process (in current module)
|
||||
|
||||
std::multimap<int, AstNodeModule*> m_todoModps; // Modules left to process
|
||||
// Map from AstNodeModule to set of all AstNodeModules that instantiates it.
|
||||
std::unordered_map<AstNodeModule*, std::unordered_set<AstNodeModule*>> m_parentps;
|
||||
|
||||
// METHODS
|
||||
VL_DEBUG_FUNC; // Declare debug()
|
||||
|
||||
void visitCellDeparam(AstCell* nodep, const string& hierName) {
|
||||
// Cell: Check for parameters in the instantiation.
|
||||
iterateChildren(nodep);
|
||||
UASSERT_OBJ(nodep->modp(), nodep, "Not linked?");
|
||||
m_processor.cellDeparam(nodep, m_modp, hierName);
|
||||
// Remember to process the child module at the end of the module
|
||||
m_todoModps.emplace(nodep->modp()->level(), nodep->modp());
|
||||
}
|
||||
void visitModules() {
|
||||
// Loop on all modules left to process
|
||||
// Hitting a cell adds to the appropriate level of this level-sorted list,
|
||||
// so since cells originally exist top->bottom we process in top->bottom order too.
|
||||
while (!m_todoModps.empty()) {
|
||||
const auto itm = m_todoModps.cbegin();
|
||||
AstNodeModule* const nodep = itm->second;
|
||||
m_todoModps.erase(itm);
|
||||
if (!nodep->user5SetOnce()) { // Process once; note clone() must clear so we do it
|
||||
// again
|
||||
m_modp = nodep;
|
||||
UINFO(4, " MOD " << nodep << endl);
|
||||
if (m_modp->hierName().empty()) m_modp->hierName(m_modp->origName());
|
||||
iterateChildren(nodep);
|
||||
// Note above iterate may add to m_todoModps
|
||||
//
|
||||
// Process interface cells, then non-interface which may ref an interface cell
|
||||
for (int nonIf = 0; nonIf < 2; ++nonIf) {
|
||||
for (AstCell* const cellp : m_cellps) {
|
||||
if ((nonIf == 0 && VN_IS(cellp->modp(), Iface))
|
||||
|| (nonIf == 1 && !VN_IS(cellp->modp(), Iface))) {
|
||||
string fullName(m_modp->hierName());
|
||||
if (const string* const genHierNamep = (string*)cellp->user5p()) {
|
||||
fullName += *genHierNamep;
|
||||
cellp->user5p(nullptr);
|
||||
VL_DO_DANGLING(delete genHierNamep, genHierNamep);
|
||||
}
|
||||
VL_DO_DANGLING(visitCellDeparam(cellp, fullName), cellp);
|
||||
}
|
||||
void visitCells(AstNodeModule* nodep) {
|
||||
UASSERT_OBJ(!m_iterateModule, nodep, "Should not nest");
|
||||
std::multimap<int, AstNodeModule*> workQueue;
|
||||
workQueue.emplace(nodep->level(), nodep);
|
||||
m_generateHierName = "";
|
||||
m_iterateModule = true;
|
||||
|
||||
// Visit all cells under module, recursively
|
||||
do {
|
||||
const auto itm = workQueue.cbegin();
|
||||
AstNodeModule* const modp = itm->second;
|
||||
workQueue.erase(itm);
|
||||
|
||||
// Process once; note user5 will be cleared on specialization, so we will do the
|
||||
// specialized module if needed
|
||||
if (modp->user5SetOnce()) continue;
|
||||
|
||||
// TODO: this really should be an assert, but classes and hier_blocks are special...
|
||||
if (modp->someInstanceName().empty()) modp->someInstanceName(modp->origName());
|
||||
|
||||
// Iterate the body
|
||||
iterateChildren(modp);
|
||||
|
||||
// Process interface cells, then non-interface cells, which may reference an interface
|
||||
// cell.
|
||||
for (bool doInterface : {true, false}) {
|
||||
for (AstCell* const cellp : m_cellps) {
|
||||
if (doInterface != VN_IS(cellp->modp(), Iface)) continue;
|
||||
|
||||
// Visit parameters in the instantiation.
|
||||
iterateChildren(cellp);
|
||||
|
||||
// Update path
|
||||
string someInstanceName(modp->someInstanceName());
|
||||
if (const string* const genHierNamep = cellp->user5u().to<string*>()) {
|
||||
someInstanceName += *genHierNamep;
|
||||
cellp->user5p(nullptr);
|
||||
VL_DO_DANGLING(delete genHierNamep, genHierNamep);
|
||||
}
|
||||
|
||||
// Apply parameter specialization
|
||||
m_processor.cellDeparam(cellp, modp, someInstanceName);
|
||||
|
||||
// Add the (now potentially specialized) child module to the work queue
|
||||
workQueue.emplace(cellp->modp()->level(), cellp->modp());
|
||||
|
||||
// Add to the hierarchy registry
|
||||
m_parentps[cellp->modp()].insert(modp);
|
||||
}
|
||||
m_cellps.clear();
|
||||
m_modp = nullptr;
|
||||
UINFO(4, " MOD-done\n");
|
||||
}
|
||||
m_cellps.clear();
|
||||
} while (!workQueue.empty());
|
||||
|
||||
m_iterateModule = false;
|
||||
}
|
||||
|
||||
// Fix up level of module, based on who instantiates it
|
||||
void fixLevel(AstNodeModule* modp) {
|
||||
if (modp->user1SetOnce()) return; // Already fixed
|
||||
if (m_parentps[modp].empty()) return; // Leave top levels alone
|
||||
int maxParentLevel = 0;
|
||||
for (AstNodeModule* parentp : m_parentps[modp]) {
|
||||
fixLevel(parentp); // Ensure parent level is correct
|
||||
maxParentLevel = std::max(maxParentLevel, parentp->level());
|
||||
}
|
||||
if (modp->level() <= maxParentLevel) modp->level(maxParentLevel + 1);
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
if (nodep->dead()) {
|
||||
UINFO(4, " MOD-dead. " << nodep << endl); // Marked by LinkDot
|
||||
return;
|
||||
} else if (nodep->recursiveClone()) {
|
||||
// Fake, made for recursive elimination
|
||||
UINFO(4, " MOD-recursive-dead. " << nodep << endl);
|
||||
nodep->dead(true); // So Dead checks won't count references to it
|
||||
return;
|
||||
}
|
||||
//
|
||||
if (!nodep->dead() && VN_IS(nodep, Class)) {
|
||||
if (nodep->recursiveClone()) nodep->dead(true); // Fake, made for recursive elimination
|
||||
if (nodep->dead()) return; // Marked by LinkDot (and above)
|
||||
|
||||
// Warn on unsupported parametrised class
|
||||
if (VN_IS(nodep, Class)) {
|
||||
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
if (const AstVar* const varp = VN_CAST(stmtp, Var)) {
|
||||
if (varp->isParam()) {
|
||||
@ -924,24 +942,21 @@ class ParamVisitor final : public VNVisitor {
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
if (m_modp) {
|
||||
|
||||
if (m_iterateModule) { // Iterating body
|
||||
UINFO(4, " MOD-under-MOD. " << nodep << endl);
|
||||
iterateChildren(nodep);
|
||||
} else if (nodep->level() <= 2 // Haven't added top yet, so level 2 is the top
|
||||
|| VN_IS(nodep, Class) // Nor moved classes
|
||||
|| VN_IS(nodep, Package)) { // Likewise haven't done wrapTopPackages yet
|
||||
// Add request to END of modules left to process
|
||||
m_todoModps.emplace(nodep->level(), nodep);
|
||||
m_generateHierName = "";
|
||||
visitModules();
|
||||
} else if (nodep->user5()) {
|
||||
UINFO(4, " MOD-done " << nodep << endl); // Already did it
|
||||
} else {
|
||||
// Should have been done by now, if not dead
|
||||
UINFO(4, " MOD-dead? " << nodep << endl);
|
||||
return;
|
||||
}
|
||||
|
||||
// Start traversal at root-like things
|
||||
if (nodep->level() <= 2 // Haven't added top yet, so level 2 is the top
|
||||
|| VN_IS(nodep, Class) // Nor moved classes
|
||||
|| VN_IS(nodep, Package)) { // Likewise haven't done wrapTopPackages yet
|
||||
visitCells(nodep);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstCell* nodep) override {
|
||||
// Must do ifaces first, so push to list and do in proper order
|
||||
string* const genHierNamep = new string(m_generateHierName);
|
||||
@ -1195,10 +1210,38 @@ class ParamVisitor final : public VNVisitor {
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit ParamVisitor(AstNetlist* nodep)
|
||||
: m_processor{nodep} {
|
||||
explicit ParamVisitor(AstNetlist* netlistp)
|
||||
: m_processor{netlistp} {
|
||||
// Relies on modules already being in top-down-order
|
||||
iterate(nodep);
|
||||
iterate(netlistp);
|
||||
|
||||
// Re-sort module list to be in topological order and fix-up incorrect levels. We need to
|
||||
// do this globally at the end due to the presence of recursive modules, which might be
|
||||
// expanded in orders that reuse earlier specializations later at a lower level.
|
||||
{
|
||||
// Gather modules
|
||||
std::vector<AstNodeModule*> modps;
|
||||
for (AstNodeModule *modp = netlistp->modulesp(), *nextp; modp; modp = nextp) {
|
||||
nextp = VN_AS(modp->nextp(), NodeModule);
|
||||
modp->unlinkFrBack();
|
||||
modps.push_back(modp);
|
||||
}
|
||||
|
||||
// Fix-up levels
|
||||
{
|
||||
const VNUser1InUse user1InUse;
|
||||
for (AstNodeModule* const modp : modps) fixLevel(modp);
|
||||
}
|
||||
|
||||
// Sort by level
|
||||
std::stable_sort(modps.begin(), modps.end(),
|
||||
[](const AstNodeModule* ap, const AstNodeModule* bp) {
|
||||
return ap->level() < bp->level();
|
||||
});
|
||||
|
||||
// Re-insert modules
|
||||
for (AstNodeModule* const modp : modps) netlistp->addModulep(modp);
|
||||
}
|
||||
}
|
||||
virtual ~ParamVisitor() override = default;
|
||||
VL_UNCOPYABLE(ParamVisitor);
|
||||
|
@ -128,8 +128,7 @@ public:
|
||||
}
|
||||
void showUpward() { // LCOV_EXCL_START
|
||||
UINFO(1, "ParseSym Stack:\n");
|
||||
for (auto it = m_sympStack.rbegin(); it != m_sympStack.rend(); ++it) {
|
||||
VSymEnt* const symp = *it;
|
||||
for (VSymEnt* const symp : vlstd::reverse_view(m_sympStack)) {
|
||||
UINFO(1, " " << symp->nodep() << endl);
|
||||
}
|
||||
UINFO(1, "ParseSym Current: " << symCurrentp()->nodep() << endl);
|
||||
|
@ -526,9 +526,9 @@ public:
|
||||
}
|
||||
void checkRelativesCp(GraphWay way) const {
|
||||
const EdgeSet& edges = m_edges[way];
|
||||
for (EdgeSet::const_reverse_iterator it = edges.rbegin(); it != edges.rend(); ++it) {
|
||||
const LogicMTask* const relativep = (*it).key();
|
||||
const uint32_t cachedCp = (*it).value();
|
||||
for (const auto& edge : vlstd::reverse_view(edges)) {
|
||||
const LogicMTask* const relativep = edge.key();
|
||||
const uint32_t cachedCp = edge.value();
|
||||
partCheckCachedScoreVsActual(cachedCp, relativep->critPathCost(way.invert())
|
||||
+ relativep->stepCost());
|
||||
}
|
||||
@ -555,12 +555,12 @@ public:
|
||||
// wayEdgeEndp(way, withoutp). This should take 2 iterations max.
|
||||
const EdgeSet& edges = m_edges[way.invert()];
|
||||
uint32_t result = 0;
|
||||
for (EdgeSet::const_reverse_iterator it = edges.rbegin(); it != edges.rend(); ++it) {
|
||||
if ((*it).key() != withoutp->furtherp(way.invert())) {
|
||||
for (const auto& edge : vlstd::reverse_view(edges)) {
|
||||
if (edge.key() != withoutp->furtherp(way.invert())) {
|
||||
// Use the cached cost. It could be a small overestimate
|
||||
// due to stepping. This is consistent with critPathCost()
|
||||
// which also returns the cached cost.
|
||||
result = (*it).value();
|
||||
result = edge.value();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -182,11 +182,11 @@ public:
|
||||
}
|
||||
m_whyNotOptimizable = why;
|
||||
std::ostringstream stack;
|
||||
for (auto it = m_callStack.rbegin(); it != m_callStack.rend(); ++it) {
|
||||
AstFuncRef* const funcp = (*it)->m_funcp;
|
||||
for (auto& callstack : vlstd::reverse_view(m_callStack)) {
|
||||
AstFuncRef* const funcp = callstack->m_funcp;
|
||||
stack << "\n " << funcp->fileline() << "... Called from "
|
||||
<< funcp->prettyName() << "() with parameters:";
|
||||
V3TaskConnects* tconnects = (*it)->m_tconnects;
|
||||
V3TaskConnects* tconnects = callstack->m_tconnects;
|
||||
for (V3TaskConnects::iterator conIt = tconnects->begin();
|
||||
conIt != tconnects->end(); ++conIt) {
|
||||
AstVar* const portp = conIt->first;
|
||||
|
@ -367,7 +367,7 @@ private:
|
||||
AstNode* const condp
|
||||
= new AstAnd(fl, select(fl, outputAssignedTableVscp, indexVscp),
|
||||
new AstConst(fl, outputChgMask));
|
||||
outsetp = new AstIf(fl, condp, outsetp, nullptr);
|
||||
outsetp = new AstIf(fl, condp, outsetp);
|
||||
}
|
||||
|
||||
stmtsp->addNext(outsetp);
|
||||
|
@ -656,7 +656,7 @@ private:
|
||||
condp = condp ? new AstOr(flp, condp, selp) : selp;
|
||||
}
|
||||
}
|
||||
ifp = new AstIf(flp, condp, nullptr, nullptr);
|
||||
ifp = new AstIf(flp, condp);
|
||||
if (!always) ifp->branchPred(VBranchPred::BP_UNLIKELY);
|
||||
subFuncp->addStmtsp(ifp);
|
||||
subStmts += ifp->nodeCount();
|
||||
|
@ -190,6 +190,27 @@ private:
|
||||
|
||||
std::string getScopeChar(VltTraceScope sct) { return std::string(1, (char)(0x80 + sct)); }
|
||||
|
||||
std::string addAboveInterface(const std::string& scopeName) {
|
||||
std::string out;
|
||||
// Hierarchical interfaces didn't know if interface vs module
|
||||
// above them. so convert a scope string to have the interface character.
|
||||
// Uses list of scopes to see what's an interface above.
|
||||
size_t begin = 0;
|
||||
while (true) {
|
||||
const size_t end = scopeName.find(' ', begin);
|
||||
if (end == string::npos) break;
|
||||
const string& extra = scopeName.substr(begin, end - begin);
|
||||
out += extra;
|
||||
if (m_scopeSubFuncps.count(out + getScopeChar(VLT_TRACE_SCOPE_INTERFACE) + " ")) {
|
||||
out += getScopeChar(VLT_TRACE_SCOPE_INTERFACE) + " ";
|
||||
} else {
|
||||
out += " ";
|
||||
}
|
||||
begin = end + 1;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
void addTraceDecl(const VNumRange& arrayRange,
|
||||
int widthOverride) { // If !=0, is packed struct/array where basicp size
|
||||
// misreflects one element
|
||||
@ -199,8 +220,10 @@ private:
|
||||
} else if (const AstBasicDType* const bdtypep = m_traValuep->dtypep()->basicp()) {
|
||||
bitRange = bdtypep->nrange();
|
||||
}
|
||||
addToSubFunc(new AstTraceDecl{m_traVscp->fileline(), m_traName, m_traVscp->varp(),
|
||||
m_traValuep->cloneTree(false), bitRange, arrayRange});
|
||||
auto* const newp
|
||||
= new AstTraceDecl{m_traVscp->fileline(), m_traName, m_traVscp->varp(),
|
||||
m_traValuep->cloneTree(false), bitRange, arrayRange};
|
||||
addToSubFunc(newp);
|
||||
}
|
||||
|
||||
void addIgnore(const char* why) {
|
||||
@ -217,17 +240,14 @@ private:
|
||||
UASSERT_OBJ(!m_traVscp, nodep, "Should not nest");
|
||||
UASSERT_OBJ(m_traName.empty(), nodep, "Should not nest");
|
||||
|
||||
FileLine* const flp = nodep->fileline();
|
||||
VL_RESTORER(m_currScopep);
|
||||
m_currScopep = nodep;
|
||||
|
||||
// Gather all signals under this AstScope
|
||||
iterateChildrenConst(nodep);
|
||||
|
||||
// If nothing to trace in this scope, then job done
|
||||
if (m_signals.empty()) {
|
||||
m_currScopep = nullptr;
|
||||
return;
|
||||
}
|
||||
if (m_signals.empty()) return;
|
||||
|
||||
// Sort signals, first by enclosing instance, then by source location, then by name
|
||||
std::stable_sort(m_signals.begin(), m_signals.end(), [](const Signal& a, const Signal& b) {
|
||||
@ -239,6 +259,7 @@ private:
|
||||
});
|
||||
|
||||
// Build trace initialization functions for this AstScope
|
||||
FileLine* const flp = nodep->fileline();
|
||||
PathAdjustor pathAdjustor{flp, [&](AstNodeStmt* stmtp) { addToSubFunc(stmtp); }};
|
||||
for (const Signal& signal : m_signals) {
|
||||
// Adjust name prefix based on path in hierarchy
|
||||
@ -278,6 +299,7 @@ private:
|
||||
scopeName = scopeName.substr(0, lastDot + 1);
|
||||
const size_t scopeLen = scopeName.length();
|
||||
|
||||
UASSERT_OBJ(cellp->intfRefp(), cellp, "Interface without tracing reference");
|
||||
for (AstIntfRef *irp = cellp->intfRefp(), *nextIrp; irp; irp = nextIrp) {
|
||||
nextIrp = VN_AS(irp->nextp(), IntfRef);
|
||||
|
||||
@ -288,6 +310,9 @@ private:
|
||||
|
||||
string scopeName = AstNode::vcdName(irp->name());
|
||||
if (scopeName.substr(0, 4) == "TOP ") scopeName.erase(0, 4);
|
||||
// Note this insert doesn't know what above is interfaces.
|
||||
// Perhaps all scopes should be changed to include the VLT_TRACE_SCOPE characters.
|
||||
// Instead we fix up when printing m_scopeSubFuncps
|
||||
scopeName += getScopeChar(VLT_TRACE_SCOPE_INTERFACE) + ' ';
|
||||
m_scopeSubFuncps.emplace(scopeName, m_subFuncps);
|
||||
|
||||
@ -300,8 +325,6 @@ private:
|
||||
if (VString::startsWith(scopeName, "TOP ")) scopeName.erase(0, 4);
|
||||
m_scopeSubFuncps.emplace(scopeName, std::move(m_subFuncps));
|
||||
}
|
||||
|
||||
m_currScopep = nullptr;
|
||||
}
|
||||
virtual void visit(AstVarScope* nodep) override {
|
||||
UASSERT_OBJ(m_currScopep, nodep, "AstVarScope not under AstScope");
|
||||
@ -454,9 +477,10 @@ public:
|
||||
// Build top level trace initialization functions
|
||||
PathAdjustor pathAdjustor{flp, [&](AstNodeStmt* stmtp) { addToTopFunc(stmtp); }};
|
||||
for (const auto& item : m_scopeSubFuncps) {
|
||||
const std::string scopeName = item.first;
|
||||
const std::string scopeNameInterfaced = addAboveInterface(scopeName);
|
||||
// Adjust name prefix based on path in hierarchy
|
||||
pathAdjustor.adjust(item.first);
|
||||
|
||||
pathAdjustor.adjust(scopeNameInterfaced);
|
||||
// Call all sub functions for this path
|
||||
for (AstCFunc* const subFuncp : item.second) {
|
||||
AstCCall* const callp = new AstCCall{flp, subFuncp};
|
||||
|
@ -127,8 +127,7 @@ private:
|
||||
(needDly ? static_cast<AstNode*>(
|
||||
new AstAssignDly(fl, prep, new AstVarRef(fl, varp, VAccess::READ)))
|
||||
: static_cast<AstNode*>(
|
||||
new AstAssign(fl, prep, new AstVarRef(fl, varp, VAccess::READ)))),
|
||||
nullptr);
|
||||
new AstAssign(fl, prep, new AstVarRef(fl, varp, VAccess::READ)))));
|
||||
newp->branchPred(VBranchPred::BP_LIKELY);
|
||||
newp->isBoundsCheck(true);
|
||||
if (debug() >= 9) newp->dumpTree(cout, " _new: ");
|
||||
|
@ -1366,7 +1366,7 @@ private:
|
||||
switch (nodep->attrType()) {
|
||||
case VAttrType::DIM_SIZE: {
|
||||
AstNode* const newp = new AstCMethodHard(
|
||||
nodep->fileline(), nodep->fromp()->unlinkFrBack(), "size", nullptr);
|
||||
nodep->fileline(), nodep->fromp()->unlinkFrBack(), "size");
|
||||
newp->dtypeSetSigned32();
|
||||
newp->didWidth(true);
|
||||
newp->protect(false);
|
||||
@ -1384,7 +1384,7 @@ private:
|
||||
case VAttrType::DIM_RIGHT:
|
||||
case VAttrType::DIM_HIGH: {
|
||||
AstNode* const sizep = new AstCMethodHard(
|
||||
nodep->fileline(), nodep->fromp()->unlinkFrBack(), "size", nullptr);
|
||||
nodep->fileline(), nodep->fromp()->unlinkFrBack(), "size");
|
||||
sizep->dtypeSetSigned32();
|
||||
sizep->didWidth(true);
|
||||
sizep->protect(false);
|
||||
@ -2041,7 +2041,8 @@ private:
|
||||
if (nodep->access().isWriteOrRW() && nodep->varp()->direction() == VDirection::CONSTREF) {
|
||||
nodep->v3error("Assigning to const ref variable: " << nodep->prettyNameQ());
|
||||
} else if (nodep->access().isWriteOrRW() && nodep->varp()->isConst() && !m_paramsOnly
|
||||
&& (!m_ftaskp || !m_ftaskp->isConstructor()) && !VN_IS(m_procedurep, Initial)) {
|
||||
&& (!m_ftaskp || !m_ftaskp->isConstructor())
|
||||
&& !VN_IS(m_procedurep, InitialStatic)) {
|
||||
// Too loose, but need to allow our generated first assignment
|
||||
// Move this to a property of the AstInitial block
|
||||
nodep->v3error("Assigning to const variable: " << nodep->prettyNameQ());
|
||||
@ -2676,8 +2677,8 @@ private:
|
||||
if (nodep->name() == "num" // function int num()
|
||||
|| nodep->name() == "size") {
|
||||
methodOkArguments(nodep, 0, 0);
|
||||
newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), "size",
|
||||
nullptr); // So don't need num()
|
||||
newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
"size"); // So don't need num()
|
||||
newp->dtypeSetSigned32();
|
||||
} else if (nodep->name() == "first" // function int first(ref index)
|
||||
|| nodep->name() == "last" //
|
||||
@ -2703,7 +2704,7 @@ private:
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::WRITE);
|
||||
if (!nodep->pinsp()) {
|
||||
newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
"clear", nullptr);
|
||||
"clear");
|
||||
newp->makeStatement();
|
||||
} else {
|
||||
AstNode* const index_exprp = methodCallAssocIndexExpr(nodep, adtypep);
|
||||
@ -2731,7 +2732,7 @@ private:
|
||||
methodOkArguments(nodep, 0, 0);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ);
|
||||
newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name(), nullptr);
|
||||
nodep->name());
|
||||
if (nodep->name() == "unique_index") {
|
||||
newp->dtypep(queueDTypeIndexedBy(adtypep->keyDTypep()));
|
||||
} else {
|
||||
@ -2794,19 +2795,16 @@ private:
|
||||
if (nodep->name() == "at") { // Created internally for []
|
||||
methodOkArguments(nodep, 1, 1);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::WRITE);
|
||||
newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), "at",
|
||||
nullptr);
|
||||
newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), "at");
|
||||
newp->dtypeFrom(adtypep->subDTypep());
|
||||
} else if (nodep->name() == "size") {
|
||||
methodOkArguments(nodep, 0, 0);
|
||||
newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), "size",
|
||||
nullptr);
|
||||
newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), "size");
|
||||
newp->dtypeSetSigned32();
|
||||
} else if (nodep->name() == "delete") { // function void delete()
|
||||
methodOkArguments(nodep, 0, 0);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::WRITE);
|
||||
newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), "clear",
|
||||
nullptr);
|
||||
newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), "clear");
|
||||
newp->makeStatement();
|
||||
} else if (nodep->name() == "and" || nodep->name() == "or" || nodep->name() == "xor"
|
||||
|| nodep->name() == "sum" || nodep->name() == "product") {
|
||||
@ -2837,7 +2835,7 @@ private:
|
||||
methodOkArguments(nodep, 0, 0);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ);
|
||||
newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name(), nullptr);
|
||||
nodep->name());
|
||||
if (nodep->name() == "unique_index") {
|
||||
newp->dtypep(newp->findQueueIndexDType());
|
||||
} else {
|
||||
@ -2883,27 +2881,25 @@ private:
|
||||
if (nodep->name() == "at") { // Created internally for []
|
||||
methodOkArguments(nodep, 1, 1);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::WRITE);
|
||||
newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), "at",
|
||||
nullptr);
|
||||
newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), "at");
|
||||
newp->dtypeFrom(adtypep->subDTypep());
|
||||
} else if (nodep->name() == "num" // function int num()
|
||||
|| nodep->name() == "size") {
|
||||
methodOkArguments(nodep, 0, 0);
|
||||
newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), "size",
|
||||
nullptr);
|
||||
newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(), "size");
|
||||
newp->dtypeSetSigned32();
|
||||
} else if (nodep->name() == "delete") { // function void delete([input integer index])
|
||||
methodOkArguments(nodep, 0, 1);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::WRITE);
|
||||
if (!nodep->pinsp()) {
|
||||
newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
"clear", nullptr);
|
||||
"clear");
|
||||
newp->makeStatement();
|
||||
} else {
|
||||
AstNode* const index_exprp = methodCallQueueIndexExpr(nodep);
|
||||
if (index_exprp->isZero()) { // delete(0) is a pop_front
|
||||
newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
"pop_front", nullptr);
|
||||
"pop_front");
|
||||
newp->dtypeFrom(adtypep->subDTypep());
|
||||
newp->makeStatement();
|
||||
} else {
|
||||
@ -2933,7 +2929,7 @@ private:
|
||||
// Returns element, so method both consumes (reads) and modifies the queue
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READWRITE);
|
||||
newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name(), nullptr);
|
||||
nodep->name());
|
||||
newp->dtypeFrom(adtypep->subDTypep());
|
||||
if (!nodep->firstAbovep()) newp->makeStatement();
|
||||
} else if (nodep->name() == "push_back" || nodep->name() == "push_front") {
|
||||
@ -2972,7 +2968,7 @@ private:
|
||||
methodOkArguments(nodep, 0, 0);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ);
|
||||
newp = new AstCMethodHard(nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name(), nullptr);
|
||||
nodep->name());
|
||||
if (nodep->name() == "unique_index") {
|
||||
newp->dtypep(newp->findQueueIndexDType());
|
||||
} else {
|
||||
@ -3850,8 +3846,7 @@ private:
|
||||
} else if (VN_IS(fromDtp, DynArrayDType) || VN_IS(fromDtp, QueueDType)) {
|
||||
if (varp) {
|
||||
auto* const leftp = new AstConst{fl, AstConst::Signed32{}, 0};
|
||||
auto* const sizep
|
||||
= new AstCMethodHard{fl, fromp->cloneTree(false), "size", nullptr};
|
||||
auto* const sizep = new AstCMethodHard{fl, fromp->cloneTree(false), "size"};
|
||||
sizep->dtypeSetSigned32();
|
||||
sizep->didWidth(true);
|
||||
sizep->protect(false);
|
||||
|
@ -3111,7 +3111,7 @@ statement_item<nodep>: // IEEE: statement_item
|
||||
//
|
||||
// // IEEE: conditional_statement
|
||||
| unique_priorityE yIF '(' expr ')' stmtBlock %prec prLOWER_THAN_ELSE
|
||||
{ AstIf* const newp = new AstIf{$2, $4, $6, nullptr};
|
||||
{ AstIf* const newp = new AstIf{$2, $4, $6};
|
||||
$$ = newp;
|
||||
if ($1 == uniq_UNIQUE) newp->uniquePragma(true);
|
||||
if ($1 == uniq_UNIQUE0) newp->unique0Pragma(true);
|
||||
@ -3180,7 +3180,7 @@ statement_item<nodep>: // IEEE: statement_item
|
||||
$$ = $2->cloneTree(true);
|
||||
$$->addNext(new AstWhile($1,$5,$2));
|
||||
}
|
||||
else $$ = new AstWhile($1,$5,nullptr); }
|
||||
else $$ = new AstWhile($1,$5); }
|
||||
// // IEEE says array_identifier here, but dotted accepted in VMM and 1800-2009
|
||||
| yFOREACH '(' idClassSelForeach ')' stmtBlock { $$ = new AstForeach($1, $3, $5); }
|
||||
//
|
||||
|
@ -8,19 +8,28 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
# Version 2.0.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(vlt => 1);
|
||||
scenarios(simulator => 1);
|
||||
|
||||
compile();
|
||||
|
||||
if ($Self->{vlt_all}) {
|
||||
# The word 'this' (but only the whole word 'this' should have been replaced
|
||||
# in the contents.
|
||||
my $file = glob_one("$Self->{obj_dir}/$Self->{VM_PREFIX}___024root__DepSet_*__0.cpp");
|
||||
my $text = file_contents($file);
|
||||
error("$file has 'this->clk'") if ($text =~ m/\bthis->clk\b/);
|
||||
error("$file does not have 'xthis'") if ($text !~ m/\bxthis\b/);
|
||||
error("$file does not have 'thisx'") if ($text !~ m/\bthisx\b/);
|
||||
error("$file does not have 'xthisx'") if ($text !~ m/\bxthisx\b/);
|
||||
my $has_this = 0;
|
||||
my $has_xthis = 0;
|
||||
my $has_thisx = 0;
|
||||
my $has_xthisx = 0;
|
||||
for my $file (glob_all("$Self->{obj_dir}/$Self->{VM_PREFIX}___024root__DepSet_*__0.cpp")) {
|
||||
my $text = file_contents($file);
|
||||
$has_this = 1 if ($text =~ m/\bthis->clk\b/);
|
||||
$has_xthis = 1 if ($text =~ m/\bxthis\b/);
|
||||
$has_thisx = 1 if ($text =~ m/\bthisx\b/);
|
||||
$has_xthisx = 1 if ($text =~ m/\bxthisx\b/);
|
||||
}
|
||||
error("Some file has 'this->clk'") if $has_this;
|
||||
error("No file has 'xthis'") if !$has_xthis;
|
||||
error("No file has 'thisx'") if !$has_thisx;
|
||||
error("No file has 'xthisx'") if !$has_xthisx;
|
||||
}
|
||||
|
||||
ok(1);
|
||||
|
@ -22,9 +22,9 @@ module t(/*AUTOARG*/
|
||||
event ev [3:0];
|
||||
`endif
|
||||
|
||||
int cyc;
|
||||
int cyc = 0;
|
||||
|
||||
int last_event;
|
||||
int last_event = 0;
|
||||
always @(e1) begin
|
||||
`WRITE_VERBOSE(("[%0t] e1\n", $time));
|
||||
if (!e1.triggered) $stop;
|
||||
|
@ -1,5 +1,4 @@
|
||||
%Error: t/t_force_bad_rw.v:14:20: Unsupported: Signals used via read-write reference cannot be forced
|
||||
: ... In instance t.unnamedblk1.unnamedblk1.index
|
||||
14 | foreach (ass[index]) begin
|
||||
| ^~~~~
|
||||
%Error: Exiting due to
|
||||
|
@ -1,5 +1,4 @@
|
||||
%Error: t/t_fuzz_eqne_bad.v:12:23: Slice operator VARREF 't.b' on non-slicable (e.g. non-vector) right-hand-side operand
|
||||
: ... In instance t.b
|
||||
12 | initial c = (a != &b);
|
||||
| ^
|
||||
%Error: Exiting due to
|
||||
|
@ -1,7 +1,6 @@
|
||||
$version Generated by VerilatedVcd $end
|
||||
$date Wed Dec 4 07:47:51 2019
|
||||
$end
|
||||
$timescale 1ps $end
|
||||
$date Thu Apr 14 07:06:40 2022 $end
|
||||
$timescale 1ps $end
|
||||
|
||||
$scope module top $end
|
||||
$var wire 1 0 clk $end
|
||||
@ -57,6 +56,10 @@ $timescale 1ps $end
|
||||
$var wire 1 0 clk $end
|
||||
$var wire 32 # cyc [31:0] $end
|
||||
$var wire 32 * value [31:0] $end
|
||||
$scope interface inner $end
|
||||
$var wire 32 # cyc [31:0] $end
|
||||
$var wire 32 3 value [31:0] $end
|
||||
$upscope $end
|
||||
$scope struct the_struct $end
|
||||
$var wire 32 + val100 [31:0] $end
|
||||
$var wire 32 , val200 [31:0] $end
|
||||
@ -130,6 +133,10 @@ $timescale 1ps $end
|
||||
$var wire 1 0 clk $end
|
||||
$var wire 32 # cyc [31:0] $end
|
||||
$var wire 32 - value [31:0] $end
|
||||
$scope interface inner $end
|
||||
$var wire 32 # cyc [31:0] $end
|
||||
$var wire 32 4 value [31:0] $end
|
||||
$upscope $end
|
||||
$scope struct the_struct $end
|
||||
$var wire 32 . val100 [31:0] $end
|
||||
$var wire 32 / val200 [31:0] $end
|
||||
@ -180,6 +187,10 @@ $timescale 1ps $end
|
||||
$var wire 1 0 clk $end
|
||||
$var wire 32 # cyc [31:0] $end
|
||||
$var wire 32 $ value [31:0] $end
|
||||
$scope interface inner $end
|
||||
$var wire 32 # cyc [31:0] $end
|
||||
$var wire 32 1 value [31:0] $end
|
||||
$upscope $end
|
||||
$scope struct the_struct $end
|
||||
$var wire 32 % val100 [31:0] $end
|
||||
$var wire 32 & val200 [31:0] $end
|
||||
@ -189,6 +200,10 @@ $timescale 1ps $end
|
||||
$var wire 1 0 clk $end
|
||||
$var wire 32 # cyc [31:0] $end
|
||||
$var wire 32 ' value [31:0] $end
|
||||
$scope interface inner $end
|
||||
$var wire 32 # cyc [31:0] $end
|
||||
$var wire 32 2 value [31:0] $end
|
||||
$upscope $end
|
||||
$scope struct the_struct $end
|
||||
$var wire 32 ( val100 [31:0] $end
|
||||
$var wire 32 ) val200 [31:0] $end
|
||||
@ -236,6 +251,10 @@ b00000000000000000000001111101010 -
|
||||
b00000000000000000000010001001110 .
|
||||
b00000000000000000000010010110010 /
|
||||
00
|
||||
b00000000000000000000000000000000 1
|
||||
b00000000000000000000000000000000 2
|
||||
b00000000000000000000000000000000 3
|
||||
b00000000000000000000000000000000 4
|
||||
#10
|
||||
b00000000000000000000000000000001 #
|
||||
b00000000000000000000000000000010 $
|
||||
|
@ -11,10 +11,16 @@ typedef struct packed {
|
||||
integer val200;
|
||||
} struct_t;
|
||||
|
||||
// This interface is not connected to any cells
|
||||
interface ifc_inner(input integer cyc);
|
||||
integer value;
|
||||
endinterface
|
||||
|
||||
interface ifc (input logic clk,
|
||||
input integer cyc);
|
||||
integer value;
|
||||
struct_t the_struct;
|
||||
ifc_inner inner (.*);
|
||||
endinterface
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
$date
|
||||
Tue Feb 22 23:55:07 2022
|
||||
Thu Apr 14 07:06:50 2022
|
||||
|
||||
$end
|
||||
$version
|
||||
@ -59,6 +59,10 @@ $upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope interface intf_in_sub_all $end
|
||||
$scope interface inner $end
|
||||
$var wire 32 " cyc [31:0] $end
|
||||
$var integer 32 , value [31:0] $end
|
||||
$upscope $end
|
||||
$var wire 1 ! clk $end
|
||||
$var wire 32 " cyc [31:0] $end
|
||||
$var integer 32 ) value [31:0] $end
|
||||
@ -113,10 +117,10 @@ $scope module ac3 $end
|
||||
$scope interface intf_for_check $end
|
||||
$var wire 1 ! clk $end
|
||||
$var wire 32 " cyc [31:0] $end
|
||||
$var integer 32 , value [31:0] $end
|
||||
$var integer 32 - value [31:0] $end
|
||||
$scope struct the_struct $end
|
||||
$var logic 32 - val100 [31:0] $end
|
||||
$var logic 32 . val200 [31:0] $end
|
||||
$var logic 32 . val100 [31:0] $end
|
||||
$var logic 32 / val200 [31:0] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
@ -124,20 +128,24 @@ $scope module as3 $end
|
||||
$scope interface intf_for_struct $end
|
||||
$var wire 1 ! clk $end
|
||||
$var wire 32 " cyc [31:0] $end
|
||||
$var integer 32 , value [31:0] $end
|
||||
$var integer 32 - value [31:0] $end
|
||||
$scope struct the_struct $end
|
||||
$var logic 32 - val100 [31:0] $end
|
||||
$var logic 32 . val200 [31:0] $end
|
||||
$var logic 32 . val100 [31:0] $end
|
||||
$var logic 32 / val200 [31:0] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope interface intf_in_sub_all $end
|
||||
$scope interface inner $end
|
||||
$var wire 32 " cyc [31:0] $end
|
||||
$var integer 32 0 value [31:0] $end
|
||||
$upscope $end
|
||||
$var wire 1 ! clk $end
|
||||
$var wire 32 " cyc [31:0] $end
|
||||
$var integer 32 , value [31:0] $end
|
||||
$var integer 32 - value [31:0] $end
|
||||
$scope struct the_struct $end
|
||||
$var logic 32 - val100 [31:0] $end
|
||||
$var logic 32 . val200 [31:0] $end
|
||||
$var logic 32 . val100 [31:0] $end
|
||||
$var logic 32 / val200 [31:0] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope interface intf_one $end
|
||||
@ -182,6 +190,10 @@ $upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope interface intf_1 $end
|
||||
$scope interface inner $end
|
||||
$var wire 32 " cyc [31:0] $end
|
||||
$var integer 32 1 value [31:0] $end
|
||||
$upscope $end
|
||||
$var wire 1 ! clk $end
|
||||
$var wire 32 " cyc [31:0] $end
|
||||
$var integer 32 # value [31:0] $end
|
||||
@ -191,6 +203,10 @@ $var logic 32 % val200 [31:0] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope interface intf_2 $end
|
||||
$scope interface inner $end
|
||||
$var wire 32 " cyc [31:0] $end
|
||||
$var integer 32 2 value [31:0] $end
|
||||
$upscope $end
|
||||
$var wire 1 ! clk $end
|
||||
$var wire 32 " cyc [31:0] $end
|
||||
$var integer 32 & value [31:0] $end
|
||||
@ -226,9 +242,13 @@ $upscope $end
|
||||
$enddefinitions $end
|
||||
#0
|
||||
$dumpvars
|
||||
b00000000000000000000010010110010 .
|
||||
b00000000000000000000010001001110 -
|
||||
b00000000000000000000001111101010 ,
|
||||
b00000000000000000000000000000000 2
|
||||
b00000000000000000000000000000000 1
|
||||
b00000000000000000000000000000000 0
|
||||
b00000000000000000000010010110010 /
|
||||
b00000000000000000000010001001110 .
|
||||
b00000000000000000000001111101010 -
|
||||
b00000000000000000000000000000000 ,
|
||||
b00000000000000000000010010110001 +
|
||||
b00000000000000000000010001001101 *
|
||||
b00000000000000000000001111101001 )
|
||||
@ -253,16 +273,16 @@ b00000000000000000000000011001011 (
|
||||
b00000000000000000000001111101010 )
|
||||
b00000000000000000000010001001110 *
|
||||
b00000000000000000000010010110010 +
|
||||
b00000000000000000000001111101011 ,
|
||||
b00000000000000000000010001001111 -
|
||||
b00000000000000000000010010110011 .
|
||||
b00000000000000000000001111101011 -
|
||||
b00000000000000000000010001001111 .
|
||||
b00000000000000000000010010110011 /
|
||||
#15
|
||||
0!
|
||||
#20
|
||||
1!
|
||||
b00000000000000000000010010110100 .
|
||||
b00000000000000000000010001010000 -
|
||||
b00000000000000000000001111101100 ,
|
||||
b00000000000000000000010010110100 /
|
||||
b00000000000000000000010001010000 .
|
||||
b00000000000000000000001111101100 -
|
||||
b00000000000000000000010010110011 +
|
||||
b00000000000000000000010001001111 *
|
||||
b00000000000000000000001111101011 )
|
||||
@ -287,16 +307,16 @@ b00000000000000000000000011001101 (
|
||||
b00000000000000000000001111101100 )
|
||||
b00000000000000000000010001010000 *
|
||||
b00000000000000000000010010110100 +
|
||||
b00000000000000000000001111101101 ,
|
||||
b00000000000000000000010001010001 -
|
||||
b00000000000000000000010010110101 .
|
||||
b00000000000000000000001111101101 -
|
||||
b00000000000000000000010001010001 .
|
||||
b00000000000000000000010010110101 /
|
||||
#35
|
||||
0!
|
||||
#40
|
||||
1!
|
||||
b00000000000000000000010010110110 .
|
||||
b00000000000000000000010001010010 -
|
||||
b00000000000000000000001111101110 ,
|
||||
b00000000000000000000010010110110 /
|
||||
b00000000000000000000010001010010 .
|
||||
b00000000000000000000001111101110 -
|
||||
b00000000000000000000010010110101 +
|
||||
b00000000000000000000010001010001 *
|
||||
b00000000000000000000001111101101 )
|
||||
@ -321,16 +341,16 @@ b00000000000000000000000011001111 (
|
||||
b00000000000000000000001111101110 )
|
||||
b00000000000000000000010001010010 *
|
||||
b00000000000000000000010010110110 +
|
||||
b00000000000000000000001111101111 ,
|
||||
b00000000000000000000010001010011 -
|
||||
b00000000000000000000010010110111 .
|
||||
b00000000000000000000001111101111 -
|
||||
b00000000000000000000010001010011 .
|
||||
b00000000000000000000010010110111 /
|
||||
#55
|
||||
0!
|
||||
#60
|
||||
1!
|
||||
b00000000000000000000010010111000 .
|
||||
b00000000000000000000010001010100 -
|
||||
b00000000000000000000001111110000 ,
|
||||
b00000000000000000000010010111000 /
|
||||
b00000000000000000000010001010100 .
|
||||
b00000000000000000000001111110000 -
|
||||
b00000000000000000000010010110111 +
|
||||
b00000000000000000000010001010011 *
|
||||
b00000000000000000000001111101111 )
|
||||
@ -355,16 +375,16 @@ b00000000000000000000000011010001 (
|
||||
b00000000000000000000001111110000 )
|
||||
b00000000000000000000010001010100 *
|
||||
b00000000000000000000010010111000 +
|
||||
b00000000000000000000001111110001 ,
|
||||
b00000000000000000000010001010101 -
|
||||
b00000000000000000000010010111001 .
|
||||
b00000000000000000000001111110001 -
|
||||
b00000000000000000000010001010101 .
|
||||
b00000000000000000000010010111001 /
|
||||
#75
|
||||
0!
|
||||
#80
|
||||
1!
|
||||
b00000000000000000000010010111010 .
|
||||
b00000000000000000000010001010110 -
|
||||
b00000000000000000000001111110010 ,
|
||||
b00000000000000000000010010111010 /
|
||||
b00000000000000000000010001010110 .
|
||||
b00000000000000000000001111110010 -
|
||||
b00000000000000000000010010111001 +
|
||||
b00000000000000000000010001010101 *
|
||||
b00000000000000000000001111110001 )
|
||||
@ -389,16 +409,16 @@ b00000000000000000000000011010011 (
|
||||
b00000000000000000000001111110010 )
|
||||
b00000000000000000000010001010110 *
|
||||
b00000000000000000000010010111010 +
|
||||
b00000000000000000000001111110011 ,
|
||||
b00000000000000000000010001010111 -
|
||||
b00000000000000000000010010111011 .
|
||||
b00000000000000000000001111110011 -
|
||||
b00000000000000000000010001010111 .
|
||||
b00000000000000000000010010111011 /
|
||||
#95
|
||||
0!
|
||||
#100
|
||||
1!
|
||||
b00000000000000000000010010111100 .
|
||||
b00000000000000000000010001011000 -
|
||||
b00000000000000000000001111110100 ,
|
||||
b00000000000000000000010010111100 /
|
||||
b00000000000000000000010001011000 .
|
||||
b00000000000000000000001111110100 -
|
||||
b00000000000000000000010010111011 +
|
||||
b00000000000000000000010001010111 *
|
||||
b00000000000000000000001111110011 )
|
||||
@ -423,16 +443,16 @@ b00000000000000000000000011010101 (
|
||||
b00000000000000000000001111110100 )
|
||||
b00000000000000000000010001011000 *
|
||||
b00000000000000000000010010111100 +
|
||||
b00000000000000000000001111110101 ,
|
||||
b00000000000000000000010001011001 -
|
||||
b00000000000000000000010010111101 .
|
||||
b00000000000000000000001111110101 -
|
||||
b00000000000000000000010001011001 .
|
||||
b00000000000000000000010010111101 /
|
||||
#115
|
||||
0!
|
||||
#120
|
||||
1!
|
||||
b00000000000000000000010010111110 .
|
||||
b00000000000000000000010001011010 -
|
||||
b00000000000000000000001111110110 ,
|
||||
b00000000000000000000010010111110 /
|
||||
b00000000000000000000010001011010 .
|
||||
b00000000000000000000001111110110 -
|
||||
b00000000000000000000010010111101 +
|
||||
b00000000000000000000010001011001 *
|
||||
b00000000000000000000001111110101 )
|
||||
@ -457,16 +477,16 @@ b00000000000000000000000011010111 (
|
||||
b00000000000000000000001111110110 )
|
||||
b00000000000000000000010001011010 *
|
||||
b00000000000000000000010010111110 +
|
||||
b00000000000000000000001111110111 ,
|
||||
b00000000000000000000010001011011 -
|
||||
b00000000000000000000010010111111 .
|
||||
b00000000000000000000001111110111 -
|
||||
b00000000000000000000010001011011 .
|
||||
b00000000000000000000010010111111 /
|
||||
#135
|
||||
0!
|
||||
#140
|
||||
1!
|
||||
b00000000000000000000010011000000 .
|
||||
b00000000000000000000010001011100 -
|
||||
b00000000000000000000001111111000 ,
|
||||
b00000000000000000000010011000000 /
|
||||
b00000000000000000000010001011100 .
|
||||
b00000000000000000000001111111000 -
|
||||
b00000000000000000000010010111111 +
|
||||
b00000000000000000000010001011011 *
|
||||
b00000000000000000000001111110111 )
|
||||
@ -491,16 +511,16 @@ b00000000000000000000000011011001 (
|
||||
b00000000000000000000001111111000 )
|
||||
b00000000000000000000010001011100 *
|
||||
b00000000000000000000010011000000 +
|
||||
b00000000000000000000001111111001 ,
|
||||
b00000000000000000000010001011101 -
|
||||
b00000000000000000000010011000001 .
|
||||
b00000000000000000000001111111001 -
|
||||
b00000000000000000000010001011101 .
|
||||
b00000000000000000000010011000001 /
|
||||
#155
|
||||
0!
|
||||
#160
|
||||
1!
|
||||
b00000000000000000000010011000010 .
|
||||
b00000000000000000000010001011110 -
|
||||
b00000000000000000000001111111010 ,
|
||||
b00000000000000000000010011000010 /
|
||||
b00000000000000000000010001011110 .
|
||||
b00000000000000000000001111111010 -
|
||||
b00000000000000000000010011000001 +
|
||||
b00000000000000000000010001011101 *
|
||||
b00000000000000000000001111111001 )
|
||||
@ -525,16 +545,16 @@ b00000000000000000000000011011011 (
|
||||
b00000000000000000000001111111010 )
|
||||
b00000000000000000000010001011110 *
|
||||
b00000000000000000000010011000010 +
|
||||
b00000000000000000000001111111011 ,
|
||||
b00000000000000000000010001011111 -
|
||||
b00000000000000000000010011000011 .
|
||||
b00000000000000000000001111111011 -
|
||||
b00000000000000000000010001011111 .
|
||||
b00000000000000000000010011000011 /
|
||||
#175
|
||||
0!
|
||||
#180
|
||||
1!
|
||||
b00000000000000000000010011000100 .
|
||||
b00000000000000000000010001100000 -
|
||||
b00000000000000000000001111111100 ,
|
||||
b00000000000000000000010011000100 /
|
||||
b00000000000000000000010001100000 .
|
||||
b00000000000000000000001111111100 -
|
||||
b00000000000000000000010011000011 +
|
||||
b00000000000000000000010001011111 *
|
||||
b00000000000000000000001111111011 )
|
||||
@ -559,16 +579,16 @@ b00000000000000000000000011011101 (
|
||||
b00000000000000000000001111111100 )
|
||||
b00000000000000000000010001100000 *
|
||||
b00000000000000000000010011000100 +
|
||||
b00000000000000000000001111111101 ,
|
||||
b00000000000000000000010001100001 -
|
||||
b00000000000000000000010011000101 .
|
||||
b00000000000000000000001111111101 -
|
||||
b00000000000000000000010001100001 .
|
||||
b00000000000000000000010011000101 /
|
||||
#195
|
||||
0!
|
||||
#200
|
||||
1!
|
||||
b00000000000000000000010011000110 .
|
||||
b00000000000000000000010001100010 -
|
||||
b00000000000000000000001111111110 ,
|
||||
b00000000000000000000010011000110 /
|
||||
b00000000000000000000010001100010 .
|
||||
b00000000000000000000001111111110 -
|
||||
b00000000000000000000010011000101 +
|
||||
b00000000000000000000010001100001 *
|
||||
b00000000000000000000001111111101 )
|
||||
@ -593,6 +613,6 @@ b00000000000000000000000011011111 (
|
||||
b00000000000000000000001111111110 )
|
||||
b00000000000000000000010001100010 *
|
||||
b00000000000000000000010011000110 +
|
||||
b00000000000000000000001111111111 ,
|
||||
b00000000000000000000010001100011 -
|
||||
b00000000000000000000010011000111 .
|
||||
b00000000000000000000001111111111 -
|
||||
b00000000000000000000010001100011 .
|
||||
b00000000000000000000010011000111 /
|
||||
|
@ -1,5 +1,5 @@
|
||||
$date
|
||||
Tue Feb 22 23:55:19 2022
|
||||
Thu Apr 14 07:06:59 2022
|
||||
|
||||
$end
|
||||
$version
|
||||
@ -58,6 +58,10 @@ $upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope interface intf_in_sub_all $end
|
||||
$scope interface inner $end
|
||||
$var wire 32 " cyc [31:0] $end
|
||||
$var integer 32 , value [31:0] $end
|
||||
$upscope $end
|
||||
$var wire 1 ! clk $end
|
||||
$var wire 32 " cyc [31:0] $end
|
||||
$var integer 32 ) value [31:0] $end
|
||||
@ -112,10 +116,10 @@ $scope module ac3 $end
|
||||
$scope interface intf_for_check $end
|
||||
$var wire 1 ! clk $end
|
||||
$var wire 32 " cyc [31:0] $end
|
||||
$var integer 32 , value [31:0] $end
|
||||
$var integer 32 - value [31:0] $end
|
||||
$scope struct the_struct $end
|
||||
$var logic 32 - val100 [31:0] $end
|
||||
$var logic 32 . val200 [31:0] $end
|
||||
$var logic 32 . val100 [31:0] $end
|
||||
$var logic 32 / val200 [31:0] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
@ -123,20 +127,24 @@ $scope module as3 $end
|
||||
$scope interface intf_for_struct $end
|
||||
$var wire 1 ! clk $end
|
||||
$var wire 32 " cyc [31:0] $end
|
||||
$var integer 32 , value [31:0] $end
|
||||
$var integer 32 - value [31:0] $end
|
||||
$scope struct the_struct $end
|
||||
$var logic 32 - val100 [31:0] $end
|
||||
$var logic 32 . val200 [31:0] $end
|
||||
$var logic 32 . val100 [31:0] $end
|
||||
$var logic 32 / val200 [31:0] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope interface intf_in_sub_all $end
|
||||
$scope interface inner $end
|
||||
$var wire 32 " cyc [31:0] $end
|
||||
$var integer 32 0 value [31:0] $end
|
||||
$upscope $end
|
||||
$var wire 1 ! clk $end
|
||||
$var wire 32 " cyc [31:0] $end
|
||||
$var integer 32 , value [31:0] $end
|
||||
$var integer 32 - value [31:0] $end
|
||||
$scope struct the_struct $end
|
||||
$var logic 32 - val100 [31:0] $end
|
||||
$var logic 32 . val200 [31:0] $end
|
||||
$var logic 32 . val100 [31:0] $end
|
||||
$var logic 32 / val200 [31:0] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope interface intf_one $end
|
||||
@ -181,6 +189,10 @@ $upscope $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope interface intf_1 $end
|
||||
$scope interface inner $end
|
||||
$var wire 32 " cyc [31:0] $end
|
||||
$var integer 32 1 value [31:0] $end
|
||||
$upscope $end
|
||||
$var wire 1 ! clk $end
|
||||
$var wire 32 " cyc [31:0] $end
|
||||
$var integer 32 # value [31:0] $end
|
||||
@ -190,6 +202,10 @@ $var logic 32 % val200 [31:0] $end
|
||||
$upscope $end
|
||||
$upscope $end
|
||||
$scope interface intf_2 $end
|
||||
$scope interface inner $end
|
||||
$var wire 32 " cyc [31:0] $end
|
||||
$var integer 32 2 value [31:0] $end
|
||||
$upscope $end
|
||||
$var wire 1 ! clk $end
|
||||
$var wire 32 " cyc [31:0] $end
|
||||
$var integer 32 & value [31:0] $end
|
||||
@ -225,9 +241,13 @@ $upscope $end
|
||||
$enddefinitions $end
|
||||
#0
|
||||
$dumpvars
|
||||
b00000000000000000000010010110010 .
|
||||
b00000000000000000000010001001110 -
|
||||
b00000000000000000000001111101010 ,
|
||||
b00000000000000000000000000000000 2
|
||||
b00000000000000000000000000000000 1
|
||||
b00000000000000000000000000000000 0
|
||||
b00000000000000000000010010110010 /
|
||||
b00000000000000000000010001001110 .
|
||||
b00000000000000000000001111101010 -
|
||||
b00000000000000000000000000000000 ,
|
||||
b00000000000000000000010010110001 +
|
||||
b00000000000000000000010001001101 *
|
||||
b00000000000000000000001111101001 )
|
||||
@ -252,9 +272,9 @@ b00000000000000000000000011001011 (
|
||||
b00000000000000000000001111101010 )
|
||||
b00000000000000000000010001001110 *
|
||||
b00000000000000000000010010110010 +
|
||||
b00000000000000000000001111101011 ,
|
||||
b00000000000000000000010001001111 -
|
||||
b00000000000000000000010010110011 .
|
||||
b00000000000000000000001111101011 -
|
||||
b00000000000000000000010001001111 .
|
||||
b00000000000000000000010010110011 /
|
||||
#11
|
||||
#12
|
||||
#13
|
||||
@ -267,9 +287,9 @@ b00000000000000000000010010110011 .
|
||||
#19
|
||||
#20
|
||||
1!
|
||||
b00000000000000000000010010110100 .
|
||||
b00000000000000000000010001010000 -
|
||||
b00000000000000000000001111101100 ,
|
||||
b00000000000000000000010010110100 /
|
||||
b00000000000000000000010001010000 .
|
||||
b00000000000000000000001111101100 -
|
||||
b00000000000000000000010010110011 +
|
||||
b00000000000000000000010001001111 *
|
||||
b00000000000000000000001111101011 )
|
||||
@ -302,9 +322,9 @@ b00000000000000000000000011001101 (
|
||||
b00000000000000000000001111101100 )
|
||||
b00000000000000000000010001010000 *
|
||||
b00000000000000000000010010110100 +
|
||||
b00000000000000000000001111101101 ,
|
||||
b00000000000000000000010001010001 -
|
||||
b00000000000000000000010010110101 .
|
||||
b00000000000000000000001111101101 -
|
||||
b00000000000000000000010001010001 .
|
||||
b00000000000000000000010010110101 /
|
||||
#31
|
||||
#32
|
||||
#33
|
||||
@ -317,9 +337,9 @@ b00000000000000000000010010110101 .
|
||||
#39
|
||||
#40
|
||||
1!
|
||||
b00000000000000000000010010110110 .
|
||||
b00000000000000000000010001010010 -
|
||||
b00000000000000000000001111101110 ,
|
||||
b00000000000000000000010010110110 /
|
||||
b00000000000000000000010001010010 .
|
||||
b00000000000000000000001111101110 -
|
||||
b00000000000000000000010010110101 +
|
||||
b00000000000000000000010001010001 *
|
||||
b00000000000000000000001111101101 )
|
||||
@ -352,9 +372,9 @@ b00000000000000000000000011001111 (
|
||||
b00000000000000000000001111101110 )
|
||||
b00000000000000000000010001010010 *
|
||||
b00000000000000000000010010110110 +
|
||||
b00000000000000000000001111101111 ,
|
||||
b00000000000000000000010001010011 -
|
||||
b00000000000000000000010010110111 .
|
||||
b00000000000000000000001111101111 -
|
||||
b00000000000000000000010001010011 .
|
||||
b00000000000000000000010010110111 /
|
||||
#51
|
||||
#52
|
||||
#53
|
||||
@ -367,9 +387,9 @@ b00000000000000000000010010110111 .
|
||||
#59
|
||||
#60
|
||||
1!
|
||||
b00000000000000000000010010111000 .
|
||||
b00000000000000000000010001010100 -
|
||||
b00000000000000000000001111110000 ,
|
||||
b00000000000000000000010010111000 /
|
||||
b00000000000000000000010001010100 .
|
||||
b00000000000000000000001111110000 -
|
||||
b00000000000000000000010010110111 +
|
||||
b00000000000000000000010001010011 *
|
||||
b00000000000000000000001111101111 )
|
||||
@ -402,9 +422,9 @@ b00000000000000000000000011010001 (
|
||||
b00000000000000000000001111110000 )
|
||||
b00000000000000000000010001010100 *
|
||||
b00000000000000000000010010111000 +
|
||||
b00000000000000000000001111110001 ,
|
||||
b00000000000000000000010001010101 -
|
||||
b00000000000000000000010010111001 .
|
||||
b00000000000000000000001111110001 -
|
||||
b00000000000000000000010001010101 .
|
||||
b00000000000000000000010010111001 /
|
||||
#71
|
||||
#72
|
||||
#73
|
||||
@ -417,9 +437,9 @@ b00000000000000000000010010111001 .
|
||||
#79
|
||||
#80
|
||||
1!
|
||||
b00000000000000000000010010111010 .
|
||||
b00000000000000000000010001010110 -
|
||||
b00000000000000000000001111110010 ,
|
||||
b00000000000000000000010010111010 /
|
||||
b00000000000000000000010001010110 .
|
||||
b00000000000000000000001111110010 -
|
||||
b00000000000000000000010010111001 +
|
||||
b00000000000000000000010001010101 *
|
||||
b00000000000000000000001111110001 )
|
||||
@ -452,9 +472,9 @@ b00000000000000000000000011010011 (
|
||||
b00000000000000000000001111110010 )
|
||||
b00000000000000000000010001010110 *
|
||||
b00000000000000000000010010111010 +
|
||||
b00000000000000000000001111110011 ,
|
||||
b00000000000000000000010001010111 -
|
||||
b00000000000000000000010010111011 .
|
||||
b00000000000000000000001111110011 -
|
||||
b00000000000000000000010001010111 .
|
||||
b00000000000000000000010010111011 /
|
||||
#91
|
||||
#92
|
||||
#93
|
||||
@ -467,9 +487,9 @@ b00000000000000000000010010111011 .
|
||||
#99
|
||||
#100
|
||||
1!
|
||||
b00000000000000000000010010111100 .
|
||||
b00000000000000000000010001011000 -
|
||||
b00000000000000000000001111110100 ,
|
||||
b00000000000000000000010010111100 /
|
||||
b00000000000000000000010001011000 .
|
||||
b00000000000000000000001111110100 -
|
||||
b00000000000000000000010010111011 +
|
||||
b00000000000000000000010001010111 *
|
||||
b00000000000000000000001111110011 )
|
||||
@ -502,9 +522,9 @@ b00000000000000000000000011010101 (
|
||||
b00000000000000000000001111110100 )
|
||||
b00000000000000000000010001011000 *
|
||||
b00000000000000000000010010111100 +
|
||||
b00000000000000000000001111110101 ,
|
||||
b00000000000000000000010001011001 -
|
||||
b00000000000000000000010010111101 .
|
||||
b00000000000000000000001111110101 -
|
||||
b00000000000000000000010001011001 .
|
||||
b00000000000000000000010010111101 /
|
||||
#111
|
||||
#112
|
||||
#113
|
||||
@ -517,9 +537,9 @@ b00000000000000000000010010111101 .
|
||||
#119
|
||||
#120
|
||||
1!
|
||||
b00000000000000000000010010111110 .
|
||||
b00000000000000000000010001011010 -
|
||||
b00000000000000000000001111110110 ,
|
||||
b00000000000000000000010010111110 /
|
||||
b00000000000000000000010001011010 .
|
||||
b00000000000000000000001111110110 -
|
||||
b00000000000000000000010010111101 +
|
||||
b00000000000000000000010001011001 *
|
||||
b00000000000000000000001111110101 )
|
||||
@ -552,9 +572,9 @@ b00000000000000000000000011010111 (
|
||||
b00000000000000000000001111110110 )
|
||||
b00000000000000000000010001011010 *
|
||||
b00000000000000000000010010111110 +
|
||||
b00000000000000000000001111110111 ,
|
||||
b00000000000000000000010001011011 -
|
||||
b00000000000000000000010010111111 .
|
||||
b00000000000000000000001111110111 -
|
||||
b00000000000000000000010001011011 .
|
||||
b00000000000000000000010010111111 /
|
||||
#131
|
||||
#132
|
||||
#133
|
||||
@ -567,9 +587,9 @@ b00000000000000000000010010111111 .
|
||||
#139
|
||||
#140
|
||||
1!
|
||||
b00000000000000000000010011000000 .
|
||||
b00000000000000000000010001011100 -
|
||||
b00000000000000000000001111111000 ,
|
||||
b00000000000000000000010011000000 /
|
||||
b00000000000000000000010001011100 .
|
||||
b00000000000000000000001111111000 -
|
||||
b00000000000000000000010010111111 +
|
||||
b00000000000000000000010001011011 *
|
||||
b00000000000000000000001111110111 )
|
||||
@ -602,9 +622,9 @@ b00000000000000000000000011011001 (
|
||||
b00000000000000000000001111111000 )
|
||||
b00000000000000000000010001011100 *
|
||||
b00000000000000000000010011000000 +
|
||||
b00000000000000000000001111111001 ,
|
||||
b00000000000000000000010001011101 -
|
||||
b00000000000000000000010011000001 .
|
||||
b00000000000000000000001111111001 -
|
||||
b00000000000000000000010001011101 .
|
||||
b00000000000000000000010011000001 /
|
||||
#151
|
||||
#152
|
||||
#153
|
||||
@ -617,9 +637,9 @@ b00000000000000000000010011000001 .
|
||||
#159
|
||||
#160
|
||||
1!
|
||||
b00000000000000000000010011000010 .
|
||||
b00000000000000000000010001011110 -
|
||||
b00000000000000000000001111111010 ,
|
||||
b00000000000000000000010011000010 /
|
||||
b00000000000000000000010001011110 .
|
||||
b00000000000000000000001111111010 -
|
||||
b00000000000000000000010011000001 +
|
||||
b00000000000000000000010001011101 *
|
||||
b00000000000000000000001111111001 )
|
||||
@ -652,9 +672,9 @@ b00000000000000000000000011011011 (
|
||||
b00000000000000000000001111111010 )
|
||||
b00000000000000000000010001011110 *
|
||||
b00000000000000000000010011000010 +
|
||||
b00000000000000000000001111111011 ,
|
||||
b00000000000000000000010001011111 -
|
||||
b00000000000000000000010011000011 .
|
||||
b00000000000000000000001111111011 -
|
||||
b00000000000000000000010001011111 .
|
||||
b00000000000000000000010011000011 /
|
||||
#171
|
||||
#172
|
||||
#173
|
||||
@ -667,9 +687,9 @@ b00000000000000000000010011000011 .
|
||||
#179
|
||||
#180
|
||||
1!
|
||||
b00000000000000000000010011000100 .
|
||||
b00000000000000000000010001100000 -
|
||||
b00000000000000000000001111111100 ,
|
||||
b00000000000000000000010011000100 /
|
||||
b00000000000000000000010001100000 .
|
||||
b00000000000000000000001111111100 -
|
||||
b00000000000000000000010011000011 +
|
||||
b00000000000000000000010001011111 *
|
||||
b00000000000000000000001111111011 )
|
||||
@ -702,9 +722,9 @@ b00000000000000000000000011011101 (
|
||||
b00000000000000000000001111111100 )
|
||||
b00000000000000000000010001100000 *
|
||||
b00000000000000000000010011000100 +
|
||||
b00000000000000000000001111111101 ,
|
||||
b00000000000000000000010001100001 -
|
||||
b00000000000000000000010011000101 .
|
||||
b00000000000000000000001111111101 -
|
||||
b00000000000000000000010001100001 .
|
||||
b00000000000000000000010011000101 /
|
||||
#191
|
||||
#192
|
||||
#193
|
||||
@ -717,9 +737,9 @@ b00000000000000000000010011000101 .
|
||||
#199
|
||||
#200
|
||||
1!
|
||||
b00000000000000000000010011000110 .
|
||||
b00000000000000000000010001100010 -
|
||||
b00000000000000000000001111111110 ,
|
||||
b00000000000000000000010011000110 /
|
||||
b00000000000000000000010001100010 .
|
||||
b00000000000000000000001111111110 -
|
||||
b00000000000000000000010011000101 +
|
||||
b00000000000000000000010001100001 *
|
||||
b00000000000000000000001111111101 )
|
||||
@ -752,9 +772,9 @@ b00000000000000000000000011011111 (
|
||||
b00000000000000000000001111111110 )
|
||||
b00000000000000000000010001100010 *
|
||||
b00000000000000000000010011000110 +
|
||||
b00000000000000000000001111111111 ,
|
||||
b00000000000000000000010001100011 -
|
||||
b00000000000000000000010011000111 .
|
||||
b00000000000000000000001111111111 -
|
||||
b00000000000000000000010001100011 .
|
||||
b00000000000000000000010011000111 /
|
||||
#211
|
||||
#212
|
||||
#213
|
||||
|
@ -25,11 +25,11 @@ module t (/*AUTOARG*/
|
||||
|
||||
// verilator lint_off UNOPTFLAT
|
||||
reg [31:0] e2,f2,g2,h2;
|
||||
always @ (/*AS*/f2) begin
|
||||
always @ (/*AS*/f2, g2) begin
|
||||
h2 = {g2[15:0], g2[31:16]};
|
||||
g2 = {f2[15:0], f2[31:16]};
|
||||
end
|
||||
always @ (/*AS*/in_a) begin
|
||||
always @ (/*AS*/in_a, e2) begin
|
||||
f2 = {e2[15:0], e2[31:16]};
|
||||
e2 = in_a;
|
||||
end
|
||||
|
16
test_regress/t/t_recursive_module_bug_2.pl
Executable file
16
test_regress/t/t_recursive_module_bug_2.pl
Executable file
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2022 by Geza Lore. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
compile();
|
||||
|
||||
ok(1);
|
||||
1;
|
21
test_regress/t/t_recursive_module_bug_2.v
Normal file
21
test_regress/t/t_recursive_module_bug_2.v
Normal file
@ -0,0 +1,21 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// Copyright 2022 by Geza Lore. 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.
|
||||
|
||||
module a #(parameter N) ();
|
||||
generate if (N > 1) begin
|
||||
// With N == 5, this will first expand N == 2, then expand N == 3,
|
||||
// which instantiates N == 2. This requires fixing up topological order
|
||||
// in V3Param.
|
||||
a #(.N( N/2)) sub_lo();
|
||||
a #(.N(N-N/2)) sub_hi();
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
module top();
|
||||
a #(.N(5)) root ();
|
||||
endmodule
|
Loading…
Reference in New Issue
Block a user