Merge branch 'master' into develop-v5

This commit is contained in:
Geza Lore 2022-04-29 17:14:11 +01:00
commit 88bb7cdca6
21 changed files with 315 additions and 108 deletions

View File

@ -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]

View File

@ -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

View File

@ -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);
if (m_check == CT_INITIAL) { // Issue appropriate warning
nodep->v3warn(INITIALDLY, "Delayed assignments (<=) in initial or final block\n" if (m_check == CT_INITIAL) {
<< nodep->warnMore() nodep->v3warn(INITIALDLY,
<< "... Suggest blocking assignments (=)"); "Non-blocking assignment '<=' in initial/final block\n"
} else if (m_check == CT_LATCH) { << nodep->warnMore()
// Suppress. Shouldn't matter that the interior of the latch races << "... This will be executed as a blocking assignment '='!");
} else if (!(VN_IS(nodep->lhsp(), VarRef) } else {
&& VN_AS(nodep->lhsp(), VarRef)->varp()->isLatched())) { nodep->v3warn(COMBDLY,
nodep->v3warn(COMBDLY, "Delayed assignments (<=) in non-clocked" "Non-blocking assignment '<=' in combinational logic process\n"
" (non flop or latch) block\n" << nodep->warnMore()
<< nodep->warnMore() << "... This will be executed as a blocking assignment '='!");
<< "... Suggest blocking assignments (=)");
// 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());
nodep->replaceWith(newp);
VL_DO_DANGLING(nodep->deleteTree(), nodep);
} }
// Convert to blocking assignment
nodep->replaceWith(new AstAssign{nodep->fileline(), //
nodep->lhsp()->unlinkFrBack(), //
nodep->rhsp()->unlinkFrBack()});
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};
} }

View File

@ -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;

View File

@ -33,6 +33,7 @@
#include "V3UniqueNames.h" #include "V3UniqueNames.h"
#include <algorithm> #include <algorithm>
#include <memory>
#include <type_traits> #include <type_traits>
//###################################################################### //######################################################################

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

21
test_regress/t/t_func_link.pl Executable file
View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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