Fix SYNCASYNCNET false positive with changed non-edge logic (#7980).
Fixes #7980.
This commit is contained in:
parent
d2de6b42cf
commit
f8fb1d6646
1
Changes
1
Changes
|
|
@ -67,6 +67,7 @@ Verilator 5.051 devel
|
|||
* Fix variable scope in unique on dynamic array (#7981). [Kornel Uriasz, Antmicro Ltd.]
|
||||
* Fix table optimization causing not contextually convertible to bool error (#7983). [Jakub Michalski]
|
||||
* Fix $fgets being mis-optimized away (#7976). [G-A. Kamendje]
|
||||
* Fix SYNCASYNCNET false positive with changed non-edge logic (#7980). [Oron Port]
|
||||
|
||||
|
||||
Verilator 5.050 2026-07-01
|
||||
|
|
|
|||
|
|
@ -199,6 +199,7 @@ class GateBuildVisitor final : public VNVisitorConst {
|
|||
const AstScope* m_scopep = nullptr; // Current scope being processed
|
||||
AstActive* m_activep = nullptr; // Current active
|
||||
bool m_inClockedActive = false; // Underneath clocked active
|
||||
bool m_inEdgeActive = false; // Underneath edge active
|
||||
bool m_inStaticActive = false; // Underneath static active
|
||||
bool m_inSenItem = false; // Underneath AstSenItem; any varrefs are clocks
|
||||
|
||||
|
|
@ -248,9 +249,11 @@ class GateBuildVisitor final : public VNVisitorConst {
|
|||
UASSERT_OBJ(!m_activep, nodep, "Should not nest");
|
||||
VL_RESTORER(m_activep);
|
||||
VL_RESTORER(m_inClockedActive);
|
||||
VL_RESTORER(m_inEdgeActive);
|
||||
VL_RESTORER(m_inStaticActive);
|
||||
m_activep = nodep;
|
||||
m_inClockedActive = nodep->hasClocked();
|
||||
m_inEdgeActive = nodep->sentreep() && nodep->sentreep()->hasEdge();
|
||||
m_inStaticActive = nodep->hasStatic();
|
||||
|
||||
// AstVarScope::user2 -> bool: Signal used in SenItem in *this* active block
|
||||
|
|
@ -286,7 +289,7 @@ class GateBuildVisitor final : public VNVisitorConst {
|
|||
if (m_inSenItem) {
|
||||
vVtxp->setIsClock();
|
||||
vscp->user2(true);
|
||||
} else if (m_inClockedActive && nodep->access().isReadOnly()) {
|
||||
} else if (m_inEdgeActive && nodep->access().isReadOnly()) {
|
||||
// For SYNCASYNCNET
|
||||
if (vscp->user2()) {
|
||||
if (!vVtxp->rstAsyncNodep()) vVtxp->rstAsyncNodep(nodep);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
%Warning-SYNCASYNCNET: t/t_lint_syncasyncnet_bad.v:14:9: Signal flopped as both synchronous and async: 'rst_both_l'
|
||||
t/t_lint_syncasyncnet_bad.v:52:13: ... Location of async usage
|
||||
52 | q4 <= (~rst_both_l) ? 1'b0 : d;
|
||||
%Warning-SYNCASYNCNET: t/t_lint_syncasyncnet_bad.v:9:11: Signal flopped as both synchronous and async: 'rst_both_l'
|
||||
t/t_lint_syncasyncnet_bad.v:50:13: ... Location of async usage
|
||||
50 | q4 <= (~rst_both_l) ? 1'b0 : d;
|
||||
| ^~~~~~~~~~
|
||||
t/t_lint_syncasyncnet_bad.v:34:12: ... Location of sync usage
|
||||
34 | q2 <= (rst_both_l) ? d : 1'b0;
|
||||
t/t_lint_syncasyncnet_bad.v:31:12: ... Location of sync usage
|
||||
31 | q2 <= (rst_both_l) ? d : 1'b0;
|
||||
| ^~~~~~~~~~
|
||||
... For warning description see https://verilator.org/warn/SYNCASYNCNET?v=latest
|
||||
... Use "/* verilator lint_off SYNCASYNCNET */" and lint_on around source to disable this message.
|
||||
|
|
|
|||
|
|
@ -4,18 +4,14 @@
|
|||
// SPDX-FileCopyrightText: 2010 Wilson Snyder
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk, rst_both_l, rst_sync_l, rst_async_l, d
|
||||
);
|
||||
/*AUTOINPUT*/
|
||||
module t (
|
||||
input clk,
|
||||
input rst_both_l,
|
||||
input rst_sync_l,
|
||||
input rst_async_l,
|
||||
input d
|
||||
);
|
||||
|
||||
input clk;
|
||||
input rst_both_l;
|
||||
input rst_sync_l;
|
||||
input rst_async_l;
|
||||
|
||||
input d;
|
||||
reg q1;
|
||||
reg q2;
|
||||
|
||||
|
|
@ -25,24 +21,26 @@ module t (/*AUTOARG*/
|
|||
// Beginning of autoreset for uninitialized flops
|
||||
q1 <= 1'h0;
|
||||
// End of automatics
|
||||
end else begin
|
||||
end
|
||||
else begin
|
||||
q1 <= d;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
q2 <= (rst_both_l) ? d : 1'b0;
|
||||
if (0 && q1 && q2) ;
|
||||
if (0 && q1 && q2);
|
||||
end
|
||||
|
||||
reg q3;
|
||||
reg q3;
|
||||
always @(posedge clk or negedge rst_async_l) begin
|
||||
if (~rst_async_l) begin
|
||||
/*AUTORESET*/
|
||||
// Beginning of autoreset for uninitialized flops
|
||||
q3 <= 1'h0;
|
||||
// End of automatics
|
||||
end else begin
|
||||
end
|
||||
else begin
|
||||
q3 <= d;
|
||||
end
|
||||
end
|
||||
|
|
@ -55,7 +53,17 @@ module t (/*AUTOARG*/
|
|||
reg q5;
|
||||
always @(posedge clk or negedge rst_both_l) begin
|
||||
q5 <= (~rst_both_l) ? 1'b0 : d;
|
||||
if (0 && q3 && q4 && q5) ;
|
||||
if (0 && q3 && q4 && q5);
|
||||
end
|
||||
|
||||
// Issue #7980 - should not cause a warning
|
||||
logic mirror;
|
||||
logic [15:0] settle;
|
||||
// Level-sensitive block (NO posedge/negedge): a plain combinational observer of `value`.
|
||||
always @(mirror) $display("%0d", mirror);
|
||||
always_ff @(posedge clk) begin
|
||||
mirror <= d;
|
||||
if (mirror != 1'd0) settle <= settle + 16'd1;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
|||
Loading…
Reference in New Issue