Merge branch 'master' into develop-v5
This commit is contained in:
commit
88bb7cdca6
1
Changes
1
Changes
|
|
@ -24,6 +24,7 @@ Verilator 4.221 devel
|
||||||
* Split --prof-threads into --prof-exec and --prof-pgo (#3365). [Geza Lore, Shunyao CAD]
|
* Split --prof-threads into --prof-exec and --prof-pgo (#3365). [Geza Lore, Shunyao CAD]
|
||||||
* Deprecate 'vluint64_t' and similar types (#3255).
|
* Deprecate 'vluint64_t' and similar types (#3255).
|
||||||
* Raise error on assignment to const in initial blocks. [Geza Lore, Shunyao CAD]
|
* Raise error on assignment to const in initial blocks. [Geza Lore, Shunyao CAD]
|
||||||
|
* Issue INITIALDLY/COMBDLY/BLKSEQ warnings consistent with Verilator execution. [Geza Lore, Shunyao CAD]
|
||||||
* Fix MSVC localtime_s (#3124).
|
* Fix MSVC localtime_s (#3124).
|
||||||
* Fix Bison 3.8.2 error (#3366). [elike-ypq]
|
* Fix Bison 3.8.2 error (#3366). [elike-ypq]
|
||||||
* Fix rare bug in -Oz (V3Localize) (#3286). [Geza Lore, Shunyao CAD]
|
* Fix rare bug in -Oz (V3Localize) (#3286). [Geza Lore, Shunyao CAD]
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ Adrien Le Masle
|
||||||
Ahmed El-Mahmoudy
|
Ahmed El-Mahmoudy
|
||||||
Alex Chadwick
|
Alex Chadwick
|
||||||
Àlex Torregrosa
|
Àlex Torregrosa
|
||||||
|
Aliaksei Chapyzhenka
|
||||||
Ameya Vikram Singh
|
Ameya Vikram Singh
|
||||||
Andreas Kuster
|
Andreas Kuster
|
||||||
Chris Randall
|
Chris Randall
|
||||||
|
|
@ -54,6 +55,7 @@ Josh Redford
|
||||||
Julie Schwartz
|
Julie Schwartz
|
||||||
Julien Margetts
|
Julien Margetts
|
||||||
Kaleb Barrett
|
Kaleb Barrett
|
||||||
|
Kamil Rakoczy
|
||||||
Kanad Kanhere
|
Kanad Kanhere
|
||||||
Keith Colbert
|
Keith Colbert
|
||||||
Kevin Kiningham
|
Kevin Kiningham
|
||||||
|
|
@ -112,6 +114,7 @@ Veripool API Bot
|
||||||
Victor Besyakov
|
Victor Besyakov
|
||||||
Wilson Snyder
|
Wilson Snyder
|
||||||
Xi Zhang
|
Xi Zhang
|
||||||
|
Yoda Lee
|
||||||
Yossi Nivin
|
Yossi Nivin
|
||||||
Yuri Victorovich
|
Yuri Victorovich
|
||||||
Yutetsu TAKATSUKASA
|
Yutetsu TAKATSUKASA
|
||||||
|
|
|
||||||
|
|
@ -321,75 +321,70 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
// Active AssignDly replacement functions
|
// Replace unsupported non-blocking assignments with blocking assignments
|
||||||
|
|
||||||
class ActiveDlyVisitor final : public ActiveBaseVisitor {
|
class ActiveDlyVisitor final : public ActiveBaseVisitor {
|
||||||
public:
|
public:
|
||||||
enum CheckType : uint8_t { CT_SEQ, CT_COMBO, CT_INITIAL, CT_LATCH };
|
enum CheckType : uint8_t { CT_SEQ, CT_COMB, CT_INITIAL };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const CheckType m_check; // Combo logic or other
|
// MEMBERS
|
||||||
const AstNode* const m_alwaysp; // Always we're under
|
const CheckType m_check; // Process type we are checking
|
||||||
const AstNode* m_assignp = nullptr; // In assign
|
|
||||||
// VISITORS
|
// VISITORS
|
||||||
virtual void visit(AstAssignDly* nodep) override {
|
virtual void visit(AstAssignDly* nodep) override {
|
||||||
if (m_check != CT_SEQ) {
|
// Non-blocking assignments are OK in sequential processes
|
||||||
// Convert to a non-delayed assignment
|
if (m_check == CT_SEQ) return;
|
||||||
UINFO(5, " ASSIGNDLY " << nodep << endl);
|
|
||||||
|
// Issue appropriate warning
|
||||||
if (m_check == CT_INITIAL) {
|
if (m_check == CT_INITIAL) {
|
||||||
nodep->v3warn(INITIALDLY, "Delayed assignments (<=) in initial or final block\n"
|
nodep->v3warn(INITIALDLY,
|
||||||
|
"Non-blocking assignment '<=' in initial/final block\n"
|
||||||
<< nodep->warnMore()
|
<< nodep->warnMore()
|
||||||
<< "... Suggest blocking assignments (=)");
|
<< "... This will be executed as a blocking assignment '='!");
|
||||||
} else if (m_check == CT_LATCH) {
|
} else {
|
||||||
// Suppress. Shouldn't matter that the interior of the latch races
|
nodep->v3warn(COMBDLY,
|
||||||
} else if (!(VN_IS(nodep->lhsp(), VarRef)
|
"Non-blocking assignment '<=' in combinational logic process\n"
|
||||||
&& VN_AS(nodep->lhsp(), VarRef)->varp()->isLatched())) {
|
|
||||||
nodep->v3warn(COMBDLY, "Delayed assignments (<=) in non-clocked"
|
|
||||||
" (non flop or latch) block\n"
|
|
||||||
<< nodep->warnMore()
|
<< nodep->warnMore()
|
||||||
<< "... Suggest blocking assignments (=)");
|
<< "... This will be executed as a blocking assignment '='!");
|
||||||
// Conversely, we could also suggest latches use delayed assignments, as
|
|
||||||
// recommended by Cliff Cummings?
|
|
||||||
}
|
}
|
||||||
AstNode* const newp = new AstAssign(nodep->fileline(), nodep->lhsp()->unlinkFrBack(),
|
|
||||||
nodep->rhsp()->unlinkFrBack());
|
// Convert to blocking assignment
|
||||||
nodep->replaceWith(newp);
|
nodep->replaceWith(new AstAssign{nodep->fileline(), //
|
||||||
|
nodep->lhsp()->unlinkFrBack(), //
|
||||||
|
nodep->rhsp()->unlinkFrBack()});
|
||||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
virtual void visit(AstAssign* nodep) override {
|
virtual void visit(AstAssign* nodep) override {
|
||||||
if (m_check == CT_SEQ) {
|
// Blocking assignments are always OK in combinational (and initial/final) processes
|
||||||
VL_RESTORER(m_assignp);
|
if (m_check != CT_SEQ) return;
|
||||||
m_assignp = nodep;
|
|
||||||
iterateAndNextNull(nodep->lhsp());
|
const bool ignore = nodep->lhsp()->forall<AstVarRef>([&](const AstVarRef* refp) {
|
||||||
}
|
// Ignore reads (e.g.: index expressions)
|
||||||
}
|
if (refp->access().isReadOnly()) return true;
|
||||||
virtual void visit(AstVarRef* nodep) override {
|
const AstVar* const varp = refp->varp();
|
||||||
const AstVar* const varp = nodep->varp();
|
// Ignore ...
|
||||||
if (m_check == CT_SEQ && m_assignp && !varp->isUsedLoopIdx() // Ignore loop indices
|
return varp->isUsedLoopIdx() // ... loop indices
|
||||||
&& !varp->isTemp()) {
|
|| varp->isTemp() // ... temporaries
|
||||||
// Allow turning off warnings on the always, or the variable also
|
|| varp->fileline()->warnIsOff(V3ErrorCode::BLKSEQ); // ... user said so
|
||||||
if (!m_alwaysp->fileline()->warnIsOff(V3ErrorCode::BLKSEQ)
|
});
|
||||||
&& !m_assignp->fileline()->warnIsOff(V3ErrorCode::BLKSEQ)
|
|
||||||
&& !varp->fileline()->warnIsOff(V3ErrorCode::BLKSEQ)) {
|
if (ignore) return;
|
||||||
m_assignp->v3warn(BLKSEQ,
|
|
||||||
"Blocking assignments (=) in sequential (flop or latch) block\n"
|
nodep->v3warn(BLKSEQ,
|
||||||
<< m_assignp->warnMore()
|
"Blocking assignment '=' in sequential logic process\n"
|
||||||
<< "... Suggest delayed assignments (<=)");
|
<< nodep->warnMore() //
|
||||||
m_alwaysp->fileline()->modifyWarnOff(
|
<< "... Suggest using delayed assignment '<='");
|
||||||
V3ErrorCode::BLKSEQ, true); // Complain just once for the entire always
|
|
||||||
varp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------
|
//--------------------
|
||||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
ActiveDlyVisitor(AstNode* nodep, CheckType check)
|
ActiveDlyVisitor(AstNode* nodep, CheckType check)
|
||||||
: m_check{check}
|
: m_check{check} {
|
||||||
, m_alwaysp{nodep} {
|
|
||||||
iterate(nodep);
|
iterate(nodep);
|
||||||
}
|
}
|
||||||
virtual ~ActiveDlyVisitor() override = default;
|
virtual ~ActiveDlyVisitor() override = default;
|
||||||
|
|
@ -535,12 +530,8 @@ private:
|
||||||
|
|
||||||
// Warn and/or convert any delayed assignments
|
// Warn and/or convert any delayed assignments
|
||||||
if (combo && !sequent) {
|
if (combo && !sequent) {
|
||||||
|
ActiveDlyVisitor{nodep, ActiveDlyVisitor::CT_COMB};
|
||||||
const ActiveLatchCheckVisitor latchvisitor{nodep, kwd};
|
const ActiveLatchCheckVisitor latchvisitor{nodep, kwd};
|
||||||
if (kwd == VAlwaysKwd::ALWAYS_LATCH) {
|
|
||||||
ActiveDlyVisitor{nodep, ActiveDlyVisitor::CT_LATCH};
|
|
||||||
} else {
|
|
||||||
ActiveDlyVisitor{nodep, ActiveDlyVisitor::CT_COMBO};
|
|
||||||
}
|
|
||||||
} else if (!combo && sequent) {
|
} else if (!combo && sequent) {
|
||||||
ActiveDlyVisitor{nodep, ActiveDlyVisitor::CT_SEQ};
|
ActiveDlyVisitor{nodep, ActiveDlyVisitor::CT_SEQ};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
112
src/V3Ast.h
112
src/V3Ast.h
|
|
@ -1972,47 +1972,121 @@ private:
|
||||||
} while (nodep);
|
} while (nodep);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
template <typename T_Arg, bool Default, bool VisitNext>
|
||||||
// Traverse subtree and call given function 'f' in pre-order on each node that has type 'T'.
|
static bool predicateImpl(
|
||||||
// Prefer 'foreach' over simple VNVisitor that only needs to handle a single (or a few) node
|
// Using std::conditional for const correctness in the public 'foreach' functions
|
||||||
// types, as it's easier to write, but more importantly, the dispatch to the operation function
|
typename std::conditional<std::is_const<T_Arg>::value, const AstNode*, AstNode*>::type
|
||||||
// in 'foreach' should be completely predictable by branch target caches in modern CPUs,
|
nodep,
|
||||||
// while it is basically unpredictable for VNVisitor.
|
std::function<bool(T_Arg*)> p) {
|
||||||
template <typename T_Node> void foreach (std::function<void(T_Node*)> f) {
|
|
||||||
|
// Note: Using a loop to iterate the nextp() chain, instead of tail recursion, because
|
||||||
|
// debug builds don't eliminate tail calls, causing stack overflow on long lists of nodes.
|
||||||
|
do {
|
||||||
|
// Prefetch children and next
|
||||||
|
ASTNODE_PREFETCH(nodep->op1p());
|
||||||
|
ASTNODE_PREFETCH(nodep->op2p());
|
||||||
|
ASTNODE_PREFETCH(nodep->op3p());
|
||||||
|
ASTNODE_PREFETCH(nodep->op4p());
|
||||||
|
if /* TODO: 'constexpr' in C++17 */ (VisitNext) ASTNODE_PREFETCH(nodep->nextp());
|
||||||
|
|
||||||
|
// Apply function in pre-order
|
||||||
|
if (privateTypeTest<typename std::remove_const<T_Arg>::type>(nodep)) {
|
||||||
|
if (p(static_cast<T_Arg*>(nodep)) != Default) return !Default;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Traverse children (including their 'nextp()' chains), unless futile
|
||||||
|
if (mayBeUnder<typename std::remove_const<T_Arg>::type>(nodep)) {
|
||||||
|
if (AstNode* const op1p = nodep->op1p()) {
|
||||||
|
if (predicateImpl<T_Arg, Default, true>(op1p, p) != Default) return !Default;
|
||||||
|
}
|
||||||
|
if (AstNode* const op2p = nodep->op2p()) {
|
||||||
|
if (predicateImpl<T_Arg, Default, true>(op2p, p) != Default) return !Default;
|
||||||
|
}
|
||||||
|
if (AstNode* const op3p = nodep->op3p()) {
|
||||||
|
if (predicateImpl<T_Arg, Default, true>(op3p, p) != Default) return !Default;
|
||||||
|
}
|
||||||
|
if (AstNode* const op4p = nodep->op4p()) {
|
||||||
|
if (predicateImpl<T_Arg, Default, true>(op4p, p) != Default) return !Default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Traverse 'nextp()' chain if requested
|
||||||
|
if /* TODO: 'constexpr' in C++17 */ (VisitNext) {
|
||||||
|
nodep = nodep->nextp();
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (nodep);
|
||||||
|
|
||||||
|
return Default;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T_Node> constexpr static void checkTypeParameter() {
|
||||||
static_assert(!std::is_const<T_Node>::value,
|
static_assert(!std::is_const<T_Node>::value,
|
||||||
"Type parameter 'T_Node' should not be const qualified");
|
"Type parameter 'T_Node' should not be const qualified");
|
||||||
static_assert(std::is_base_of<AstNode, T_Node>::value,
|
static_assert(std::is_base_of<AstNode, T_Node>::value,
|
||||||
"Type parameter 'T_Node' must be a subtype of AstNode");
|
"Type parameter 'T_Node' must be a subtype of AstNode");
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Traverse subtree and call given function 'f' in pre-order on each node that has type
|
||||||
|
// 'T_Node'. Prefer 'foreach' over simple VNVisitor that only needs to handle a single (or a
|
||||||
|
// few) node types, as it's easier to write, but more importantly, the dispatch to the
|
||||||
|
// operation function in 'foreach' should be completely predictable by branch target caches in
|
||||||
|
// modern CPUs, while it is basically unpredictable for VNVisitor.
|
||||||
|
template <typename T_Node> void foreach (std::function<void(T_Node*)> f) {
|
||||||
|
checkTypeParameter<T_Node>();
|
||||||
foreachImpl<T_Node, /* VisitNext: */ false>(this, f);
|
foreachImpl<T_Node, /* VisitNext: */ false>(this, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Same as above, but for 'const' nodes
|
// Same as above, but for 'const' nodes
|
||||||
template <typename T_Node> void foreach (std::function<void(const T_Node*)> f) const {
|
template <typename T_Node> void foreach (std::function<void(const T_Node*)> f) const {
|
||||||
static_assert(!std::is_const<T_Node>::value,
|
checkTypeParameter<T_Node>();
|
||||||
"Type parameter 'T_Node' should not be const qualified");
|
|
||||||
static_assert(std::is_base_of<AstNode, T_Node>::value,
|
|
||||||
"Type parameter 'T_Node' must be a subtype of AstNode");
|
|
||||||
foreachImpl<const T_Node, /* VisitNext: */ false>(this, f);
|
foreachImpl<const T_Node, /* VisitNext: */ false>(this, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Same as 'foreach' but also follows 'this->nextp()'
|
// Same as 'foreach' but also follows 'this->nextp()'
|
||||||
template <typename T_Node> void foreachAndNext(std::function<void(T_Node*)> f) {
|
template <typename T_Node> void foreachAndNext(std::function<void(T_Node*)> f) {
|
||||||
static_assert(!std::is_const<T_Node>::value,
|
checkTypeParameter<T_Node>();
|
||||||
"Type parameter 'T_Node' should not be const qualified");
|
|
||||||
static_assert(std::is_base_of<AstNode, T_Node>::value,
|
|
||||||
"Type parameter 'T_Node' must be a subtype of AstNode");
|
|
||||||
foreachImpl<T_Node, /* VisitNext: */ true>(this, f);
|
foreachImpl<T_Node, /* VisitNext: */ true>(this, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Same as 'foreach' but also follows 'this->nextp()'
|
// Same as 'foreach' but also follows 'this->nextp()'
|
||||||
template <typename T_Node> void foreachAndNext(std::function<void(const T_Node*)> f) const {
|
template <typename T_Node> void foreachAndNext(std::function<void(const T_Node*)> f) const {
|
||||||
static_assert(!std::is_const<T_Node>::value,
|
checkTypeParameter<T_Node>();
|
||||||
"Type parameter 'T_Node' should not be const qualified");
|
|
||||||
static_assert(std::is_base_of<AstNode, T_Node>::value,
|
|
||||||
"Type parameter 'T_Node' must be a subtype of AstNode");
|
|
||||||
foreachImpl<const T_Node, /* VisitNext: */ true>(this, f);
|
foreachImpl<const T_Node, /* VisitNext: */ true>(this, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Given a predicate function 'p' return true if and only if there exists a node of type
|
||||||
|
// 'T_Node' that satisfies the predicate 'p'. Returns false if no node of type 'T_Node' is
|
||||||
|
// present. Traversal is performed in some arbitrary order and is terminated as soon as the
|
||||||
|
// result can be determined.
|
||||||
|
template <typename T_Node> bool exists(std::function<bool(T_Node*)> p) {
|
||||||
|
checkTypeParameter<T_Node>();
|
||||||
|
return predicateImpl<T_Node, /* Default: */ false, /* VisitNext: */ false>(this, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Same as above, but for 'const' nodes
|
||||||
|
template <typename T_Node> void exists(std::function<bool(const T_Node*)> p) const {
|
||||||
|
checkTypeParameter<T_Node>();
|
||||||
|
return predicateImpl<const T_Node, /* Default: */ false, /* VisitNext: */ false>(this, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Given a predicate function 'p' return true if and only if all nodes of type
|
||||||
|
// 'T_Node' satisfy the predicate 'p'. Returns true if no node of type 'T_Node' is
|
||||||
|
// present. Traversal is performed in some arbitrary order and is terminated as soon as the
|
||||||
|
// result can be determined.
|
||||||
|
template <typename T_Node> bool forall(std::function<bool(T_Node*)> p) {
|
||||||
|
checkTypeParameter<T_Node>();
|
||||||
|
return predicateImpl<T_Node, /* Default: */ true, /* VisitNext: */ false>(this, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Same as above, but for 'const' nodes
|
||||||
|
template <typename T_Node> void forall(std::function<bool(const T_Node*)> p) const {
|
||||||
|
checkTypeParameter<T_Node>();
|
||||||
|
return predicateImpl<const T_Node, /* Default: */ true, /* VisitNext: */ false>(this, p);
|
||||||
|
}
|
||||||
|
|
||||||
int nodeCount() const {
|
int nodeCount() const {
|
||||||
// TODO: this should really return size_t, but need to fix use sites
|
// TODO: this should really return size_t, but need to fix use sites
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
#include "V3UniqueNames.h"
|
#include "V3UniqueNames.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <memory>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
|
|
||||||
|
|
@ -675,13 +675,14 @@ public:
|
||||||
<< ((lookupSymp->symPrefix() == "") ? "" : " as ")
|
<< ((lookupSymp->symPrefix() == "") ? "" : " as ")
|
||||||
<< ((lookupSymp->symPrefix() == "") ? "" : lookupSymp->symPrefix() + dotname)
|
<< ((lookupSymp->symPrefix() == "") ? "" : lookupSymp->symPrefix() + dotname)
|
||||||
<< " at se" << lookupSymp << endl);
|
<< " at se" << lookupSymp << endl);
|
||||||
const string prefix = lookupSymp->symPrefix();
|
string prefix = lookupSymp->symPrefix();
|
||||||
VSymEnt* foundp = nullptr;
|
VSymEnt* foundp = nullptr;
|
||||||
while (!foundp) {
|
while (!foundp) {
|
||||||
foundp = lookupSymp->findIdFallback(prefix + dotname); // Might be nullptr
|
foundp = lookupSymp->findIdFallback(prefix + dotname); // Might be nullptr
|
||||||
if (prefix.empty()) break;
|
if (prefix.empty()) break;
|
||||||
const string nextPrefix = removeLastInlineScope(prefix);
|
const string nextPrefix = removeLastInlineScope(prefix);
|
||||||
if (prefix == nextPrefix) break;
|
if (prefix == nextPrefix) break;
|
||||||
|
prefix = nextPrefix;
|
||||||
}
|
}
|
||||||
if (!foundp) baddot = dotname;
|
if (!foundp) baddot = dotname;
|
||||||
return foundp;
|
return foundp;
|
||||||
|
|
|
||||||
|
|
@ -3794,8 +3794,9 @@ private:
|
||||||
const AstSelLoopVars* const loopsp = VN_CAST(nodep->arrayp(), SelLoopVars);
|
const AstSelLoopVars* const loopsp = VN_CAST(nodep->arrayp(), SelLoopVars);
|
||||||
UASSERT_OBJ(loopsp, nodep, "No loop variables under foreach");
|
UASSERT_OBJ(loopsp, nodep, "No loop variables under foreach");
|
||||||
// if (debug()) nodep->dumpTree(cout, "-foreach-old: ");
|
// if (debug()) nodep->dumpTree(cout, "-foreach-old: ");
|
||||||
|
userIterateAndNext(loopsp->fromp(), WidthVP(SELF, BOTH).p());
|
||||||
AstNode* const fromp = loopsp->fromp();
|
AstNode* const fromp = loopsp->fromp();
|
||||||
userIterateAndNext(fromp, WidthVP(SELF, BOTH).p());
|
UASSERT_OBJ(fromp->dtypep(), fromp, "Missing data type");
|
||||||
AstNodeDType* fromDtp = fromp->dtypep()->skipRefp();
|
AstNodeDType* fromDtp = fromp->dtypep()->skipRefp();
|
||||||
// Split into for loop
|
// Split into for loop
|
||||||
AstNode* bodyp = nodep->bodysp(); // Might be null
|
AstNode* bodyp = nodep->bodysp(); // Might be null
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@
|
||||||
: ... In instance t
|
: ... In instance t
|
||||||
20 | dly_s_t dly_s;
|
20 | dly_s_t dly_s;
|
||||||
| ^~~~~
|
| ^~~~~
|
||||||
%Warning-BLKSEQ: t/t_delay.v:37:20: Blocking assignments (=) in sequential (flop or latch) block
|
%Warning-BLKSEQ: t/t_delay.v:37:20: Blocking assignment '=' in sequential logic process
|
||||||
: ... Suggest delayed assignments (<=)
|
: ... Suggest using delayed assignment '<='
|
||||||
37 | dly_s.dly = 55;
|
37 | dly_s.dly = 55;
|
||||||
| ^
|
| ^
|
||||||
%Error: Exiting due to
|
%Error: Exiting due to
|
||||||
|
|
|
||||||
|
|
@ -112,12 +112,10 @@ module t (/*AUTOARG*/);
|
||||||
strarray[1].mid.subarray[1] = 5;
|
strarray[1].mid.subarray[1] = 5;
|
||||||
strarray[2].mid.subarray[0] = 6;
|
strarray[2].mid.subarray[0] = 6;
|
||||||
strarray[2].mid.subarray[1] = 7;
|
strarray[2].mid.subarray[1] = 7;
|
||||||
`ifndef VERILATOR // Unsupported
|
|
||||||
foreach (strarray[s])
|
foreach (strarray[s])
|
||||||
foreach (strarray[s].mid.subarray[ss])
|
foreach (strarray[s].mid.subarray[ss])
|
||||||
add += strarray[s].mid.subarray[ss];
|
add += strarray[s].mid.subarray[ss];
|
||||||
`checkh(add, 'h19);
|
`checkh(add, 'h19);
|
||||||
`endif
|
|
||||||
|
|
||||||
add = 0;
|
add = 0;
|
||||||
foreach (oned[i]) begin
|
foreach (oned[i]) begin
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
#!/usr/bin/env perl
|
||||||
|
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2012 by Wilson Snyder. 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(
|
||||||
|
);
|
||||||
|
|
||||||
|
execute(
|
||||||
|
check_finished => 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||||
|
// any use, without warranty, 2012 by Wilson Snyder.
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
module Test(/*AUTOARG*/
|
||||||
|
// Outputs
|
||||||
|
out,
|
||||||
|
// Inputs
|
||||||
|
clk, in
|
||||||
|
);
|
||||||
|
|
||||||
|
// Replace this module with the device under test.
|
||||||
|
//
|
||||||
|
// Change the code in the t module to apply values to the inputs and
|
||||||
|
// merge the output values into the result vector.
|
||||||
|
|
||||||
|
input clk;
|
||||||
|
input [31:0] in;
|
||||||
|
output reg [31:0] out;
|
||||||
|
integer cyc = 0;
|
||||||
|
|
||||||
|
SubTest subtest(.out);
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
`ifdef TEST_VERBOSE
|
||||||
|
$write("[%0t] cyc==%0d\n", $time, cyc);
|
||||||
|
`endif
|
||||||
|
cyc <= cyc + 1;
|
||||||
|
if (cyc < 99) begin
|
||||||
|
subtest.block.set(in);
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
$write("[%0t] cyc==%0d\n", $time, cyc);
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module SubTest(
|
||||||
|
output logic[31:0] out
|
||||||
|
);
|
||||||
|
|
||||||
|
if (1) begin : block
|
||||||
|
|
||||||
|
function void set(logic[31:0] in);
|
||||||
|
out <= in;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
end : block
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
%Warning-INITIALDLY: t/t_initial_dlyass.v:18:9: Delayed assignments (<=) in initial or final block
|
%Warning-INITIALDLY: t/t_initial_dlyass.v:18:9: Non-blocking assignment '<=' in initial/final block
|
||||||
: ... Suggest blocking assignments (=)
|
: ... This will be executed as a blocking assignment '='!
|
||||||
18 | a <= 22;
|
18 | a <= 22;
|
||||||
| ^~
|
| ^~
|
||||||
... For warning description see https://verilator.org/warn/INITIALDLY?v=latest
|
... For warning description see https://verilator.org/warn/INITIALDLY?v=latest
|
||||||
... Use "/* verilator lint_off INITIALDLY */" and lint_on around source to disable this message.
|
... Use "/* verilator lint_off INITIALDLY */" and lint_on around source to disable this message.
|
||||||
%Warning-INITIALDLY: t/t_initial_dlyass.v:19:9: Delayed assignments (<=) in initial or final block
|
%Warning-INITIALDLY: t/t_initial_dlyass.v:19:9: Non-blocking assignment '<=' in initial/final block
|
||||||
: ... Suggest blocking assignments (=)
|
: ... This will be executed as a blocking assignment '='!
|
||||||
19 | b <= 33;
|
19 | b <= 33;
|
||||||
| ^~
|
| ^~
|
||||||
%Error: Exiting due to
|
%Error: Exiting due to
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,15 @@
|
||||||
%Warning-BLKSEQ: t/t_lint_blksync_bad.v:24:16: Blocking assignments (=) in sequential (flop or latch) block
|
%Warning-BLKSEQ: t/t_lint_blksync_bad.v:24:16: Blocking assignment '=' in sequential logic process
|
||||||
: ... Suggest delayed assignments (<=)
|
: ... Suggest using delayed assignment '<='
|
||||||
24 | sync_blk = 1'b1;
|
24 | sync_blk = 1'b1;
|
||||||
| ^
|
| ^
|
||||||
... For warning description see https://verilator.org/warn/BLKSEQ?v=latest
|
... For warning description see https://verilator.org/warn/BLKSEQ?v=latest
|
||||||
... Use "/* verilator lint_off BLKSEQ */" and lint_on around source to disable this message.
|
... Use "/* verilator lint_off BLKSEQ */" and lint_on around source to disable this message.
|
||||||
%Warning-COMBDLY: t/t_lint_blksync_bad.v:31:18: Delayed assignments (<=) in non-clocked (non flop or latch) block
|
%Warning-BLKSEQ: t/t_lint_blksync_bad.v:25:17: Blocking assignment '=' in sequential logic process
|
||||||
: ... Suggest blocking assignments (=)
|
: ... Suggest using delayed assignment '<='
|
||||||
|
25 | sync_blk2 = 1'b1;
|
||||||
|
| ^
|
||||||
|
%Warning-COMBDLY: t/t_lint_blksync_bad.v:31:18: Non-blocking assignment '<=' in combinational logic process
|
||||||
|
: ... This will be executed as a blocking assignment '='!
|
||||||
31 | combo_nblk <= 1'b1;
|
31 | combo_nblk <= 1'b1;
|
||||||
| ^~
|
| ^~
|
||||||
*** See https://verilator.org/warn/COMBDLY before disabling this,
|
*** See https://verilator.org/warn/COMBDLY before disabling this,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
%Warning-COMBDLY: t/t_lint_latch_1.v:14:10: Non-blocking assignment '<=' in combinational logic process
|
||||||
|
: ... This will be executed as a blocking assignment '='!
|
||||||
|
14 | o <= b;
|
||||||
|
| ^~
|
||||||
|
... For warning description see https://verilator.org/warn/COMBDLY?v=latest
|
||||||
|
... Use "/* verilator lint_off COMBDLY */" and lint_on around source to disable this message.
|
||||||
|
*** See https://verilator.org/warn/COMBDLY before disabling this,
|
||||||
|
else you may end up with different sim results.
|
||||||
|
%Error: Exiting due to
|
||||||
|
|
@ -11,6 +11,8 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||||
scenarios(vlt => 1);
|
scenarios(vlt => 1);
|
||||||
|
|
||||||
lint(
|
lint(
|
||||||
|
fails => 1,
|
||||||
|
expect_filename => $Self->{golden_filename},
|
||||||
);
|
);
|
||||||
|
|
||||||
ok(1);
|
ok(1);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
%Warning-COMBDLY: t/t_lint_latch_5.v:13:13: Non-blocking assignment '<=' in combinational logic process
|
||||||
|
: ... This will be executed as a blocking assignment '='!
|
||||||
|
13 | z[0] <= a[0];
|
||||||
|
| ^~
|
||||||
|
... For warning description see https://verilator.org/warn/COMBDLY?v=latest
|
||||||
|
... Use "/* verilator lint_off COMBDLY */" and lint_on around source to disable this message.
|
||||||
|
*** See https://verilator.org/warn/COMBDLY before disabling this,
|
||||||
|
else you may end up with different sim results.
|
||||||
|
%Warning-COMBDLY: t/t_lint_latch_5.v:17:13: Non-blocking assignment '<=' in combinational logic process
|
||||||
|
: ... This will be executed as a blocking assignment '='!
|
||||||
|
17 | z[1] <= a[1];
|
||||||
|
| ^~
|
||||||
|
%Error: Exiting due to
|
||||||
|
|
@ -11,6 +11,8 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||||
scenarios(vlt => 1);
|
scenarios(vlt => 1);
|
||||||
|
|
||||||
lint(
|
lint(
|
||||||
|
fails => 1,
|
||||||
|
expect_filename => $Self->{golden_filename},
|
||||||
);
|
);
|
||||||
|
|
||||||
ok(1);
|
ok(1);
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,16 @@
|
||||||
|
%Warning-COMBDLY: t/t_lint_latch_bad.v:18:10: Non-blocking assignment '<=' in combinational logic process
|
||||||
|
: ... This will be executed as a blocking assignment '='!
|
||||||
|
18 | bl <= a;
|
||||||
|
| ^~
|
||||||
|
... For warning description see https://verilator.org/warn/COMBDLY?v=latest
|
||||||
|
... Use "/* verilator lint_off COMBDLY */" and lint_on around source to disable this message.
|
||||||
|
*** See https://verilator.org/warn/COMBDLY before disabling this,
|
||||||
|
else you may end up with different sim results.
|
||||||
%Warning-NOLATCH: t/t_lint_latch_bad.v:17:4: No latches detected in always_latch block
|
%Warning-NOLATCH: t/t_lint_latch_bad.v:17:4: No latches detected in always_latch block
|
||||||
17 | always_latch begin
|
17 | always_latch begin
|
||||||
| ^~~~~~~~~~~~
|
| ^~~~~~~~~~~~
|
||||||
... For warning description see https://verilator.org/warn/NOLATCH?v=latest
|
%Warning-COMBDLY: t/t_lint_latch_bad.v:25:10: Non-blocking assignment '<=' in combinational logic process
|
||||||
... Use "/* verilator lint_off NOLATCH */" and lint_on around source to disable this message.
|
: ... This will be executed as a blocking assignment '='!
|
||||||
%Warning-COMBDLY: t/t_lint_latch_bad.v:25:10: Delayed assignments (<=) in non-clocked (non flop or latch) block
|
|
||||||
: ... Suggest blocking assignments (=)
|
|
||||||
25 | bc <= a;
|
25 | bc <= a;
|
||||||
| ^~
|
| ^~
|
||||||
*** See https://verilator.org/warn/COMBDLY before disabling this,
|
|
||||||
else you may end up with different sim results.
|
|
||||||
%Error: Exiting due to
|
%Error: Exiting due to
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,13 @@
|
||||||
|
%Warning-COMBDLY: t/t_lint_latch_bad_2.v:13:10: Non-blocking assignment '<=' in combinational logic process
|
||||||
|
: ... This will be executed as a blocking assignment '='!
|
||||||
|
13 | o <= b;
|
||||||
|
| ^~
|
||||||
|
... For warning description see https://verilator.org/warn/COMBDLY?v=latest
|
||||||
|
... Use "/* verilator lint_off COMBDLY */" and lint_on around source to disable this message.
|
||||||
|
*** See https://verilator.org/warn/COMBDLY before disabling this,
|
||||||
|
else you may end up with different sim results.
|
||||||
%Warning-LATCH: t/t_lint_latch_bad_2.v:11:4: Latch inferred for signal 'o' (not all control paths of combinational always assign a value)
|
%Warning-LATCH: t/t_lint_latch_bad_2.v:11:4: Latch inferred for signal 'o' (not all control paths of combinational always assign a value)
|
||||||
: ... Suggest use of always_latch for intentional latches
|
: ... Suggest use of always_latch for intentional latches
|
||||||
11 | always @(a or b)
|
11 | always @(a or b)
|
||||||
| ^~~~~~
|
| ^~~~~~
|
||||||
... For warning description see https://verilator.org/warn/LATCH?v=latest
|
|
||||||
... Use "/* verilator lint_off LATCH */" and lint_on around source to disable this message.
|
|
||||||
%Error: Exiting due to
|
%Error: Exiting due to
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,29 @@
|
||||||
|
%Warning-COMBDLY: t/t_lint_latch_bad_3.v:25:8: Non-blocking assignment '<=' in combinational logic process
|
||||||
|
: ... This will be executed as a blocking assignment '='!
|
||||||
|
25 | o5 <= 1'b0;
|
||||||
|
| ^~
|
||||||
|
... For warning description see https://verilator.org/warn/COMBDLY?v=latest
|
||||||
|
... Use "/* verilator lint_off COMBDLY */" and lint_on around source to disable this message.
|
||||||
|
*** See https://verilator.org/warn/COMBDLY before disabling this,
|
||||||
|
else you may end up with different sim results.
|
||||||
|
%Warning-COMBDLY: t/t_lint_latch_bad_3.v:37:16: Non-blocking assignment '<=' in combinational logic process
|
||||||
|
: ... This will be executed as a blocking assignment '='!
|
||||||
|
37 | o5 <= 1'b1;
|
||||||
|
| ^~
|
||||||
|
%Warning-COMBDLY: t/t_lint_latch_bad_3.v:42:16: Non-blocking assignment '<=' in combinational logic process
|
||||||
|
: ... This will be executed as a blocking assignment '='!
|
||||||
|
42 | o5 <= a;
|
||||||
|
| ^~
|
||||||
|
%Warning-COMBDLY: t/t_lint_latch_bad_3.v:63:16: Non-blocking assignment '<=' in combinational logic process
|
||||||
|
: ... This will be executed as a blocking assignment '='!
|
||||||
|
63 | o5 <= ~b;
|
||||||
|
| ^~
|
||||||
|
%Warning-COMBDLY: t/t_lint_latch_bad_3.v:70:12: Non-blocking assignment '<=' in combinational logic process
|
||||||
|
: ... This will be executed as a blocking assignment '='!
|
||||||
|
70 | o4 <= 1'b0;
|
||||||
|
| ^~
|
||||||
%Warning-LATCH: t/t_lint_latch_bad_3.v:18:1: Latch inferred for signal 'o5' (not all control paths of combinational always assign a value)
|
%Warning-LATCH: t/t_lint_latch_bad_3.v:18:1: Latch inferred for signal 'o5' (not all control paths of combinational always assign a value)
|
||||||
: ... Suggest use of always_latch for intentional latches
|
: ... Suggest use of always_latch for intentional latches
|
||||||
18 | always @(reset or en or a or b)
|
18 | always @(reset or en or a or b)
|
||||||
| ^~~~~~
|
| ^~~~~~
|
||||||
... For warning description see https://verilator.org/warn/LATCH?v=latest
|
|
||||||
... Use "/* verilator lint_off LATCH */" and lint_on around source to disable this message.
|
|
||||||
%Warning-COMBDLY: t/t_lint_latch_bad_3.v:70:12: Delayed assignments (<=) in non-clocked (non flop or latch) block
|
|
||||||
: ... Suggest blocking assignments (=)
|
|
||||||
70 | o4 <= 1'b0;
|
|
||||||
| ^~
|
|
||||||
*** See https://verilator.org/warn/COMBDLY before disabling this,
|
|
||||||
else you may end up with different sim results.
|
|
||||||
%Error: Exiting due to
|
%Error: Exiting due to
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,12 @@
|
||||||
|
%Warning-COMBDLY: t/t_lint_nolatch_bad.v:13:10: Non-blocking assignment '<=' in combinational logic process
|
||||||
|
: ... This will be executed as a blocking assignment '='!
|
||||||
|
13 | o <= b;
|
||||||
|
| ^~
|
||||||
|
... For warning description see https://verilator.org/warn/COMBDLY?v=latest
|
||||||
|
... Use "/* verilator lint_off COMBDLY */" and lint_on around source to disable this message.
|
||||||
|
*** See https://verilator.org/warn/COMBDLY before disabling this,
|
||||||
|
else you may end up with different sim results.
|
||||||
%Warning-NOLATCH: t/t_lint_nolatch_bad.v:11:4: No latches detected in always_latch block
|
%Warning-NOLATCH: t/t_lint_nolatch_bad.v:11:4: No latches detected in always_latch block
|
||||||
11 | always_latch @(a or b)
|
11 | always_latch @(a or b)
|
||||||
| ^~~~~~~~~~~~
|
| ^~~~~~~~~~~~
|
||||||
... For warning description see https://verilator.org/warn/NOLATCH?v=latest
|
|
||||||
... Use "/* verilator lint_off NOLATCH */" and lint_on around source to disable this message.
|
|
||||||
%Error: Exiting due to
|
%Error: Exiting due to
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue