Fix false BLKSEQ on non-edged sensitivity list (#6492).

This commit is contained in:
Wilson Snyder 2025-09-27 20:50:32 -04:00
parent 3b623dc12e
commit 7ef3b808ea
7 changed files with 55 additions and 5 deletions

View File

@ -76,6 +76,7 @@ Verilator 5.041 devel
* Fix Windows compilation of Verilator with spaces in the path (#6477). [Fabian Keßler-Schulz]
* Fix PROTOTYPEMIS error on implicit logic (#6482). [Alex Solomatnikov]
* Fix configure misdetecting C++14 (#6488). [Thomas O'Keeffe]
* Fix false BLKSEQ on non-edged sensitivity list (#6492). [Oron Port]
Verilator 5.040 2025-08-30

View File

@ -1660,6 +1660,7 @@ public:
void multi(bool flag) { m_multi = true; }
// METHODS
bool hasClocked() const; // Includes a clocked statement
bool hasEdge() const; // Includes a posedge/negedge/bothedge clocked statement
bool hasStatic() const; // Includes a STATIC SenItem
bool hasInitial() const; // Includes a INITIAL SenItem
bool hasFinal() const; // Includes a FINAL SenItem

View File

@ -1244,6 +1244,13 @@ bool AstSenTree::hasClocked() const {
}
return false;
}
bool AstSenTree::hasEdge() const {
UASSERT_OBJ(sensesp(), this, "SENTREE without any SENITEMs under it");
for (AstSenItem* senp = sensesp(); senp; senp = VN_AS(senp->nextp(), SenItem)) {
if (senp->edgeType().anEdge()) return true;
}
return false;
}
bool AstSenTree::hasStatic() const {
UASSERT_OBJ(sensesp(), this, "SENTREE without any SENITEMs under it");
for (AstSenItem* senp = sensesp(); senp; senp = VN_AS(senp->nextp(), SenItem)) {

View File

@ -53,7 +53,7 @@ class WidthCommitVisitor final : public VNVisitor {
VMemberMap m_memberMap; // Member names cached for fast lookup
bool m_taskRefWarn = true; // Allow task reference warnings
bool m_underSel = false; // Under AstMemberSel or AstSel
bool m_underAlwaysClocked = false; // Under always with sequential SenTree
bool m_underAlwaysEdged = false; // Under always with sequential SenTree
std::vector<AstNew*> m_virtualNewsp; // Instantiations of virtual classes
std::vector<AstNodeFTask*> m_tasksp; // All the tasks, we will check if they are ever called
@ -219,9 +219,9 @@ private:
return;
}
}
VL_RESTORER(m_underAlwaysClocked);
m_underAlwaysClocked
= nodep->sentreep() && nodep->sentreep()->sensesp() && nodep->sentreep()->hasClocked();
VL_RESTORER(m_underAlwaysEdged);
m_underAlwaysEdged
= nodep->sentreep() && nodep->sentreep()->sensesp() && nodep->sentreep()->hasEdge();
// Iterate will delete ComboStar sentrees, so after above
iterateChildren(nodep);
editDType(nodep);
@ -396,7 +396,7 @@ private:
iterateChildren(nodep);
editDType(nodep);
// Lint
if (m_underAlwaysClocked) {
if (m_underAlwaysEdged) {
const bool ignore = nodep->lhsp()->forall([&](const AstVarRef* refp) {
// Ignore reads (e.g.: index expressions)
if (refp->access().isReadOnly()) return true;

View File

@ -112,6 +112,8 @@ def read_messages():
for filename in test.glob_some(test.root + "/src/*"):
if not os.path.isfile(filename):
continue
if '#' in filename:
continue
with open(filename, 'r', encoding="utf8") as fh:
lineno = 0
read_next = None

View File

@ -0,0 +1,16 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2025 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
import vltest_bootstrap
test.scenarios('linter')
test.lint(verilator_flags2=['-Wall', '-Wno-DECLFILENAME'])
test.passes()

View File

@ -0,0 +1,23 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2025 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
module t (
lhs,
o
);
input wire [7:0] lhs;
output reg [7:0] o;
wire [7:0] shifted;
always @(shifted or lhs) begin
if (lhs[7]) o = shifted ^ 8'h1b;
else o = shifted;
end
assign shifted = lhs << 1;
endmodule