From 8b52bd817f2dca3e84b60a1e6424b4aa5f58b40c Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 30 Apr 2025 22:00:06 -0400 Subject: [PATCH] Add PROCINITASSIGN on initial assignments to process variables (#2481). --- Changes | 1 + docs/gen/ex_PROCASSINIT_faulty.rst | 12 ++++ docs/gen/ex_PROCASSINIT_fixed.rst | 15 +++++ docs/gen/ex_PROCASSINIT_msg.rst | 12 ++++ docs/guide/exe_verilator.rst | 6 +- docs/guide/warnings.rst | 31 +++++++++- examples/make_protect_lib/secret_impl.v | 23 +++++--- examples/make_protect_lib/top.v | 24 +++++--- src/V3Error.h | 10 ++-- src/V3Undriven.cpp | 40 ++++++++++++- test_regress/t/t_EXAMPLE.v | 2 +- test_regress/t/t_delay.v | 2 +- test_regress/t/t_format_wide_decimal.v | 6 +- test_regress/t/t_lint_procassinit_bad.out | 21 +++++++ test_regress/t/t_lint_procassinit_bad.py | 30 ++++++++++ test_regress/t/t_lint_procassinit_bad.v | 56 +++++++++++++++++++ .../t/t_lint_removed_unused_loop_bad.v | 12 ++-- test_regress/t/t_net_delay.out | 44 +++++++-------- test_regress/t/t_net_delay.v | 4 +- 19 files changed, 292 insertions(+), 59 deletions(-) create mode 100644 docs/gen/ex_PROCASSINIT_faulty.rst create mode 100644 docs/gen/ex_PROCASSINIT_fixed.rst create mode 100644 docs/gen/ex_PROCASSINIT_msg.rst create mode 100644 test_regress/t/t_lint_procassinit_bad.out create mode 100755 test_regress/t/t_lint_procassinit_bad.py create mode 100644 test_regress/t/t_lint_procassinit_bad.v diff --git a/Changes b/Changes index 12858d5d7..786656ca0 100644 --- a/Changes +++ b/Changes @@ -14,6 +14,7 @@ Verilator 5.037 devel **Other:** * Add BADVLTPRAGMA on unknown Verilator pragmas (#5945). [Shou-Li Hsu] +* Add PROCINITASSIGN on initial assignments to process variables (#2481). [Niraj Menon] * Fix filename backslash escapes in C code (#5947). * Fix sign extension of signed compared with unsigned case items (#5968). * Fix constant propagation making upper bits Xs (#5969). diff --git a/docs/gen/ex_PROCASSINIT_faulty.rst b/docs/gen/ex_PROCASSINIT_faulty.rst new file mode 100644 index 000000000..c21130841 --- /dev/null +++ b/docs/gen/ex_PROCASSINIT_faulty.rst @@ -0,0 +1,12 @@ +.. comment: generated by t_lint_procassinit_bad +.. code-block:: sv + :linenos: + :emphasize-lines: 1,5 + + logic flop_out = 1; // <--- Warning + + always @(posedge clk, negedge reset_l) begin + if (enable) begin + flop_out <= ~in; // <--- Use of initialized + end + end diff --git a/docs/gen/ex_PROCASSINIT_fixed.rst b/docs/gen/ex_PROCASSINIT_fixed.rst new file mode 100644 index 000000000..f5a3f3711 --- /dev/null +++ b/docs/gen/ex_PROCASSINIT_fixed.rst @@ -0,0 +1,15 @@ +.. comment: generated by t_lint_procassinit_bad +.. code-block:: sv + :linenos: + :emphasize-lines: 5 + + logic flop2_out; + + always @(posedge clk, negedge reset_l) begin + if (!reset_l) begin + flop2_out <= '1; // <--- Added reset init + end + else if (enable) begin + flop2_out <= ~in; + end + end diff --git a/docs/gen/ex_PROCASSINIT_msg.rst b/docs/gen/ex_PROCASSINIT_msg.rst new file mode 100644 index 000000000..4fe084952 --- /dev/null +++ b/docs/gen/ex_PROCASSINIT_msg.rst @@ -0,0 +1,12 @@ +.. comment: generated by t_lint_procassinit_bad +.. code-block:: + + %Warning-PROCASSINIT: example.v:1:21 Procedural assignment to declaration with initial value: 'flop_out' + : ... note: In instance 't' + : ... Location of variable initialization + 26 | logic flop_out = 1; + | ^ + example.v:1:10 ... Location of variable process write + : ... Perhaps should initialize instead using a reset in this process + 30 | flop_out <= ~in; + | ^~~~~~~~ diff --git a/docs/guide/exe_verilator.rst b/docs/guide/exe_verilator.rst index 2f2b1cdfe..c75d21f3a 100644 --- a/docs/guide/exe_verilator.rst +++ b/docs/guide/exe_verilator.rst @@ -1880,9 +1880,9 @@ Summary: ``-Wwarn-ASSIGNDLY`` ``-Wwarn-BLKSEQ`` ``-Wwarn-DECLFILENAME`` ``-Wwarn-DEFPARAM`` ``-Wwarn-EOFNEWLINE`` ``-Wwarn-GENUNNAMED`` ``-Wwarn-IMPORTSTAR`` ``-Wwarn-INCABSPATH`` ``-Wwarn-PINCONNECTEMPTY`` - ``-Wwarn-PINNOCONNECT`` ``-Wwarn-SYNCASYNCNET`` ``-Wwarn-UNDRIVEN`` - ``-Wwarn-UNUSEDGENVAR`` ``-Wwarn-UNUSEDLOOP`` ``-Wwarn-UNUSEDPARAM`` - ``-Wwarn-UNUSEDSIGNAL`` ``-Wwarn-VARHIDDEN``. + ``-Wwarn-PINNOCONNECT`` ``-Wwarn-PROCASSINIT`` ``-Wwarn-SYNCASYNCNET`` + ``-Wwarn-UNDRIVEN`` ``-Wwarn-UNUSEDGENVAR`` ``-Wwarn-UNUSEDLOOP`` + ``-Wwarn-UNUSEDPARAM`` ``-Wwarn-UNUSEDSIGNAL`` ``-Wwarn-VARHIDDEN``. .. option:: --x-assign diff --git a/docs/guide/warnings.rst b/docs/guide/warnings.rst index b6cf9622f..9e03d38d2 100644 --- a/docs/guide/warnings.rst +++ b/docs/guide/warnings.rst @@ -1471,6 +1471,35 @@ List Of Warnings a var/reg must be used as the target of procedural assignments. +.. option:: PROCINITASSIGN + + Warns that the specified signal is given an initial value where it is + declared, and is also driven in an always process. Typically such + initial values should instead be set using a reset signal inside the + process, to match requirements of hardware synthesis tools. + + Faulty example: + + .. include:: ../../docs/gen/ex_PROCINITASSIGN_faulty.rst + + Results in: + + .. include:: ../../docs/gen/ex_PROCINITASSIGN_msg.rst + + One possible fix, adding a reset to the always: + + .. include:: ../../docs/gen/ex_PROCINITASSIGN_fixed.rst + + Alternatively, use an initial block for the initialization: + + .. code-block:: sv + + initial flop_out = 1; // <--- Fixed + + Disabled by default as this is a code-style warning; it will simulate + correctly. + + .. option:: PROFOUTOFDATE Warns that threads were scheduled using estimated costs, even though @@ -2164,7 +2193,7 @@ List Of Warnings .. include:: ../../docs/gen/ex_VARHIDDEN_msg.rst - To resolve this, rename the variable to an unique name. + To resolve this, rename the inner or outer variable to an unique name. .. option:: WAITCONST diff --git a/examples/make_protect_lib/secret_impl.v b/examples/make_protect_lib/secret_impl.v index 2a12a272c..dc9fe1c6b 100644 --- a/examples/make_protect_lib/secret_impl.v +++ b/examples/make_protect_lib/secret_impl.v @@ -12,19 +12,26 @@ module secret_impl input [31:0] a, input [31:0] b, output logic [31:0] x, - input clk); + input clk, + input reset_l); - logic [31:0] accum_q = 0; - logic [31:0] secret_value = 9; + logic [31:0] accum_q; + logic [31:0] secret_value; initial $display("[%0t] %m: initialized", $time); always @(posedge clk) begin - accum_q <= accum_q + a; - if (accum_q > 10) - x <= b; - else - x <= a + b + secret_value; + if (!reset_l) begin + accum_q <= 0; + secret_value <= 9; + end + else begin + accum_q <= accum_q + a; + if (accum_q > 10) + x <= b; + else + x <= a + b + secret_value; + end end endmodule diff --git a/examples/make_protect_lib/top.v b/examples/make_protect_lib/top.v index b9b71ef87..031764292 100644 --- a/examples/make_protect_lib/top.v +++ b/examples/make_protect_lib/top.v @@ -8,26 +8,36 @@ module top (input clk); - integer cyc = 0; - logic [31:0] a = 0; - logic [31:0] b = 0; + int cyc; + logic reset_l; + logic [31:0] a; + logic [31:0] b; logic [31:0] x; - verilated_secret secret (.a, .b, .x, .clk); + verilated_secret secret (.a, .b, .x, .clk, .reset_l); always @(posedge clk) begin $display("[%0t] cyc=%0d a=%0d b=%0d x=%0d", $time, cyc, a, b, x); cyc <= cyc + 1; if (cyc == 0) begin + reset_l <= 0; + a <= 0; + b <= 0; + end + else if (cyc == 1) begin + reset_l <= 1; a <= 5; b <= 7; - end else if (cyc == 1) begin + end + else if (cyc == 2) begin a <= 6; b <= 2; - end else if (cyc == 2) begin + end + else if (cyc == 3) begin a <= 1; b <= 9; - end else if (cyc > 3) begin + end + else if (cyc > 4) begin $display("Done"); $finish; end diff --git a/src/V3Error.h b/src/V3Error.h index e051147e8..591128e8e 100644 --- a/src/V3Error.h +++ b/src/V3Error.h @@ -129,6 +129,7 @@ public: PINNOTFOUND, // instance port name not found in it's module PKGNODECL, // Error: Package/class needs to be predeclared PREPROCZERO, // Preprocessor expression with zero + PROCASSINIT, // Procedural assignment versus initialization PROCASSWIRE, // Procedural assignment on wire PROFOUTOFDATE, // Profile data out of date PROTECTED, // detected `pragma protected @@ -206,7 +207,7 @@ public: "INCABSPATH", "INFINITELOOP", "INITIALDLY", "INSECURE", "LATCH", "LITENDIAN", "MINTYPMAXDLY", "MISINDENT", "MODDUP", "MULTIDRIVEN", "MULTITOP", "NEWERSTD", "NOLATCH", "NONSTD", "NULLPORT", "PINCONNECTEMPTY", - "PINMISSING", "PINNOCONNECT", "PINNOTFOUND", "PKGNODECL", "PREPROCZERO", "PROCASSWIRE", + "PINMISSING", "PINNOCONNECT", "PINNOTFOUND", "PKGNODECL", "PREPROCZERO", "PROCASSINIT", "PROCASSWIRE", "PROFOUTOFDATE", "PROTECTED", "RANDC", "REALCVT", "REDEFMACRO", "RISEFALLDLY", "SELRANGE", "SHORTREAL", "SIDEEFFECT", "SPLITVAR", "STATICVAR", "STMTDLY", "SYMRSVDWORD", "SYNCASYNCNET", @@ -259,9 +260,10 @@ public: return (m_e == ASSIGNDLY // More than style, but for backward compatibility || m_e == BLKSEQ || m_e == DECLFILENAME || m_e == DEFPARAM || m_e == EOFNEWLINE || m_e == GENUNNAMED || m_e == IMPORTSTAR || m_e == INCABSPATH - || m_e == PINCONNECTEMPTY || m_e == PINNOCONNECT || m_e == SYNCASYNCNET - || m_e == UNDRIVEN || m_e == UNUSEDGENVAR || m_e == UNUSEDLOOP - || m_e == UNUSEDPARAM || m_e == UNUSEDSIGNAL || m_e == VARHIDDEN); + || m_e == PINCONNECTEMPTY || m_e == PINNOCONNECT || m_e == PROCASSINIT + || m_e == SYNCASYNCNET || m_e == UNDRIVEN || m_e == UNUSEDGENVAR + || m_e == UNUSEDLOOP || m_e == UNUSEDPARAM || m_e == UNUSEDSIGNAL + || m_e == VARHIDDEN); } // Warnings that are unused only bool unusedError() const VL_MT_SAFE { diff --git a/src/V3Undriven.cpp b/src/V3Undriven.cpp index 130b3f498..7e9903018 100644 --- a/src/V3Undriven.cpp +++ b/src/V3Undriven.cpp @@ -46,6 +46,8 @@ class UndrivenVarEntry final { const FileLine* m_alwCombFileLinep = nullptr; // File line of always_comb of var if driven // within always_comb, else nullptr const AstNodeVarRef* m_nodep = nullptr; // varref if driven, else nullptr + const AstNode* m_initStaticp = nullptr; // varref if in InitialStatic driven + const AstNode* m_procWritep = nullptr; // varref if written in process const FileLine* m_nodeFileLinep = nullptr; // File line of varref if driven, else nullptr bool m_underGen = false; // Under a generate @@ -129,6 +131,11 @@ public: m_alwCombp = alwCombp; m_alwCombFileLinep = fileLinep; } + + const AstNode* initStaticp() const { return m_initStaticp; } + void initStaticp(const AstNode* nodep) { m_initStaticp = nodep; } + const AstNode* procWritep() const { return m_procWritep; } + void procWritep(const AstNode* nodep) { m_procWritep = nodep; } void underGenerate() { m_underGen = true; } bool isUnderGen() const { return m_underGen; } bool isDrivenWhole() const { return m_wholeFlags[FLAG_DRIVEN]; } @@ -172,6 +179,18 @@ public: // Combine bits into overall state AstVar* const nodep = m_varp; + if (initStaticp() && procWritep() && !nodep->isClassMember() && !nodep->isFuncLocal()) { + initStaticp()->v3warn( + PROCASSINIT, + "Procedural assignment to declaration with initial value: " + << nodep->prettyNameQ() << '\n' + << initStaticp()->warnMore() << "... Location of variable initialization\n" + << initStaticp()->warnContextPrimary() << '\n' + << procWritep()->warnOther() << "... Location of variable process write\n" + << procWritep()->warnMore() + << "... Perhaps should initialize instead using a reset in this process\n" + << procWritep()->warnContextSecondary()); + } if (nodep->isGenVar()) { // Genvar if (!nodep->isIfaceRef() && !nodep->isUsedParam() && !unusedMatch(nodep)) { nodep->v3warn(UNUSEDGENVAR, "Genvar is not used: " << nodep->prettyNameQ()); @@ -277,10 +296,12 @@ class UndrivenVisitor final : public VNVisitorConst { std::array, 3> m_entryps; // Nodes to delete when finished bool m_inBBox = false; // In black box; mark as driven+used bool m_inContAssign = false; // In continuous assignment + bool m_inInitialStatic = false; // In InitialStatic bool m_inProcAssign = false; // In procedural assignment bool m_inFTaskRef = false; // In function or task call bool m_inInoutOrRefPin = false; // Connected to pin that is inout const AstNodeFTask* m_taskp = nullptr; // Current task + const AstAlways* m_alwaysp = nullptr; // Current always of either type const AstAlways* m_alwaysCombp = nullptr; // Current always if combo, otherwise nullptr // METHODS @@ -384,9 +405,8 @@ class UndrivenVisitor final : public VNVisitorConst { nodep->v3warn(PROCASSWIRE, "Procedural assignment to wire, perhaps intended var" << " (IEEE 1800-2023 6.5): " << nodep->prettyNameQ()); - } - if (m_inContAssign && !nodep->varp()->varType().isContAssignable() - && !nodep->fileline()->language().systemVerilog()) { + } else if (m_inContAssign && !nodep->varp()->varType().isContAssignable() + && !nodep->fileline()->language().systemVerilog()) { nodep->v3warn(CONTASSREG, "Continuous assignment to reg, perhaps intended wire" << " (IEEE 1364-2005 6.1; Verilog only, legal in SV): " @@ -448,6 +468,13 @@ class UndrivenVisitor final : public VNVisitorConst { if (m_alwaysCombp) entryp->drivenAlwaysCombWhole(m_alwaysCombp, m_alwaysCombp->fileline()); } + if (nodep->access().isWriteOrRW()) { + UINFO(1, "ww is=" << m_inInitialStatic << " ipa=" << m_inProcAssign << " " << nodep + << endl); + if (m_inInitialStatic && !entryp->initStaticp()) entryp->initStaticp(nodep); + if (m_alwaysp && m_inProcAssign && !entryp->procWritep()) + entryp->procWritep(nodep); + } if (m_inBBox || nodep->access().isReadOrRW() || fdrv // Inouts have only isWrite set, as we don't have more @@ -480,9 +507,16 @@ class UndrivenVisitor final : public VNVisitorConst { m_inContAssign = true; iterateChildrenConst(nodep); } + void visit(AstInitialStatic* nodep) override { + VL_RESTORER(m_inInitialStatic); + m_inInitialStatic = true; + iterateChildrenConst(nodep); + } void visit(AstAlways* nodep) override { + VL_RESTORER(m_alwaysp); VL_RESTORER(m_alwaysCombp); AstNode::user2ClearTree(); + m_alwaysp = nodep; if (nodep->keyword() == VAlwaysKwd::ALWAYS_COMB) { UINFO(9, " " << nodep << endl); m_alwaysCombp = nodep; diff --git a/test_regress/t/t_EXAMPLE.v b/test_regress/t/t_EXAMPLE.v index b00361778..a5d815b13 100644 --- a/test_regress/t/t_EXAMPLE.v +++ b/test_regress/t/t_EXAMPLE.v @@ -26,7 +26,7 @@ module t(/*AUTOARG*/ ); input clk; - integer cyc = 0; + int cyc; reg [63:0] crc; reg [63:0] sum; diff --git a/test_regress/t/t_delay.v b/test_regress/t/t_delay.v index e541a10d0..9f1cb5420 100644 --- a/test_regress/t/t_delay.v +++ b/test_regress/t/t_delay.v @@ -12,7 +12,7 @@ module t (/*AUTOARG*/ ); input clk; - integer cyc=1; + int cyc; reg [31:0] dly0; wire [31:0] dly1; diff --git a/test_regress/t/t_format_wide_decimal.v b/test_regress/t/t_format_wide_decimal.v index 2b2a04835..b45b816e4 100644 --- a/test_regress/t/t_format_wide_decimal.v +++ b/test_regress/t/t_format_wide_decimal.v @@ -12,8 +12,10 @@ module t_format_wide_decimal(/*AUTOARG*/ ); input clk; - int cycle = 0; - bit [1023:0] x = '1; + int cycle; + bit [1023:0] x; + + initial x = '1; always @(posedge clk) begin if (cycle == 0) begin diff --git a/test_regress/t/t_lint_procassinit_bad.out b/test_regress/t/t_lint_procassinit_bad.out new file mode 100644 index 000000000..f54e793a1 --- /dev/null +++ b/test_regress/t/t_lint_procassinit_bad.out @@ -0,0 +1,21 @@ +%Warning-PROCASSINIT: t/t_lint_procassinit_bad.v:26:21: Procedural assignment to declaration with initial value: 'flop_out' + : ... note: In instance 't' + : ... Location of variable initialization + 26 | logic flop_out = 1; + | ^ + t/t_lint_procassinit_bad.v:30:10: ... Location of variable process write + : ... Perhaps should initialize instead using a reset in this process + 30 | flop_out <= ~in; + | ^~~~~~~~ + ... For warning description see https://verilator.org/warn/PROCASSINIT?v=latest + ... Use "/* verilator lint_off PROCASSINIT */" and lint_on around source to disable this message. +%Warning-PROCASSINIT: t/t_lint_procassinit_bad.v:48:21: Procedural assignment to declaration with initial value: 'bad_comb' + : ... note: In instance 't' + : ... Location of variable initialization + 48 | logic bad_comb = 1; + | ^ + t/t_lint_procassinit_bad.v:51:7: ... Location of variable process write + : ... Perhaps should initialize instead using a reset in this process + 51 | bad_comb = ok2; + | ^~~~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_lint_procassinit_bad.py b/test_regress/t/t_lint_procassinit_bad.py new file mode 100755 index 000000000..05ca0a399 --- /dev/null +++ b/test_regress/t/t_lint_procassinit_bad.py @@ -0,0 +1,30 @@ +#!/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('vlt') + +test.lint(verilator_flags2=['-Wall -Wno-DECLFILENAME'], + fails=True, + expect_filename=test.golden_filename) + +test.extract(in_filename=test.top_filename, + out_filename="../docs/gen/ex_PROCASSINIT_faulty.rst", + lines="26-32") + +test.extract(in_filename=test.top_filename, + out_filename="../docs/gen/ex_PROCASSINIT_fixed.rst", + lines="36-45") + +test.extract(in_filename=test.golden_filename, + out_filename="../docs/gen/ex_PROCASSINIT_msg.rst", + lines="1-9") + +test.passes() diff --git a/test_regress/t/t_lint_procassinit_bad.v b/test_regress/t/t_lint_procassinit_bad.v new file mode 100644 index 000000000..6b8e11d85 --- /dev/null +++ b/test_regress/t/t_lint_procassinit_bad.v @@ -0,0 +1,56 @@ +// 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(/*AUTOARG*/ + // Inputs + clk, reset_l, in, enable + ); + input clk; + input reset_l; + input in; + input enable; + + logic ok1 = 1; + logic ok2 = 1; + logic ok3 = ok2; + + initial begin + ok1 = 1; + end + + //== Faulty example + + logic flop_out = 1; // <--- Warning + + always @(posedge clk, negedge reset_l) begin + if (enable) begin + flop_out <= ~in; // <--- Use of initialized + end + end + + //== Fixed example + + logic flop2_out; + + always @(posedge clk, negedge reset_l) begin + if (!reset_l) begin + flop2_out <= '1; // <--- Added reset init + end + else if (enable) begin + flop2_out <= ~in; + end + end + + // Combo version + logic bad_comb = 1; // but this is not fine + + always @* begin + bad_comb = ok2; + end + + wire _unused_ok = &{1'b0, flop_out, flop2_out, bad_comb, ok1, ok2, ok3}; + +endmodule diff --git a/test_regress/t/t_lint_removed_unused_loop_bad.v b/test_regress/t/t_lint_removed_unused_loop_bad.v index 7bd5b195d..5ec480ede 100644 --- a/test_regress/t/t_lint_removed_unused_loop_bad.v +++ b/test_regress/t/t_lint_removed_unused_loop_bad.v @@ -28,10 +28,10 @@ endmodule // module unused - no warning for any of statements inside module unused(input clk); - reg unused_variable_while = 0; - reg unused_variable_do_while = 0; - reg unused_variable_for = 0; - const logic always_false = 0; + bit unused_variable_while; + bit unused_variable_do_while; + bit unused_variable_for; + const bit always_false = 0; always @(posedge clk) begin while(unused_variable_while) begin @@ -259,7 +259,7 @@ module clock_init_race(input clk, input reset_l); logic m_3_reset = reset_l; assign m_2_clock = clk; assign m_3_clock = clk; - int m_3_counter = 0; + int m_3_counter; initial begin $write("*-* START TEST *-*\n"); end @@ -271,7 +271,7 @@ module clock_init_race(input clk, input reset_l); end end - reg m_2_ticked = 1'b0; + bit m_2_ticked; always @(posedge m_2_clock) if (!m_2_reset) begin m_2_ticked = 1'b1; end diff --git a/test_regress/t/t_net_delay.out b/test_regress/t/t_net_delay.out index eab2df885..ca9804540 100644 --- a/test_regress/t/t_net_delay.out +++ b/test_regress/t/t_net_delay.out @@ -1,37 +1,37 @@ -%Warning-STMTDLY: t/t_net_delay.v:14:11: Ignoring delay on this statement due to --no-timing +%Warning-STMTDLY: t/t_net_delay.v:16:11: Ignoring delay on this statement due to --no-timing : ... note: In instance 't' - 14 | always #2 clk = ~clk; + 16 | always #2 clk = ~clk; | ^ ... For warning description see https://verilator.org/warn/STMTDLY?v=latest ... Use "/* verilator lint_off STMTDLY */" and lint_on around source to disable this message. -%Warning-STMTDLY: t/t_net_delay.v:20:14: Ignoring delay on this statement due to --no-timing +%Warning-STMTDLY: t/t_net_delay.v:22:14: Ignoring delay on this statement due to --no-timing : ... note: In instance 't' - 20 | wire[3:0] #3 val1; + 22 | wire[3:0] #3 val1; | ^ -%Warning-STMTDLY: t/t_net_delay.v:21:14: Ignoring delay on this statement due to --no-timing - : ... note: In instance 't' - 21 | wire[3:0] #3 val2; - | ^ -%Warning-ASSIGNDLY: t/t_net_delay.v:22:14: Ignoring timing control on this assignment/primitive due to --no-timing - : ... note: In instance 't' - 22 | wire[3:0] #5 val3 = cyc; - | ^ - ... For warning description see https://verilator.org/warn/ASSIGNDLY?v=latest - ... Use "/* verilator lint_off ASSIGNDLY */" and lint_on around source to disable this message. %Warning-STMTDLY: t/t_net_delay.v:23:14: Ignoring delay on this statement due to --no-timing : ... note: In instance 't' - 23 | wire[3:0] #5 val4; + 23 | wire[3:0] #3 val2; | ^ %Warning-ASSIGNDLY: t/t_net_delay.v:24:14: Ignoring timing control on this assignment/primitive due to --no-timing : ... note: In instance 't' - 24 | wire[3:0] #3 val5 = x, val6 = cyc; + 24 | wire[3:0] #5 val3 = cyc; | ^ -%Warning-ASSIGNDLY: t/t_net_delay.v:27:11: Ignoring timing control on this assignment/primitive due to --no-timing - : ... note: In instance 't' - 27 | assign #3 val2 = cyc; - | ^ -%Warning-STMTDLY: t/t_net_delay.v:39:26: Ignoring delay on this statement due to --no-timing + ... For warning description see https://verilator.org/warn/ASSIGNDLY?v=latest + ... Use "/* verilator lint_off ASSIGNDLY */" and lint_on around source to disable this message. +%Warning-STMTDLY: t/t_net_delay.v:25:14: Ignoring delay on this statement due to --no-timing : ... note: In instance 't' - 39 | always @(posedge clk) #1 begin + 25 | wire[3:0] #5 val4; + | ^ +%Warning-ASSIGNDLY: t/t_net_delay.v:26:14: Ignoring timing control on this assignment/primitive due to --no-timing + : ... note: In instance 't' + 26 | wire[3:0] #3 val5 = x, val6 = cyc; + | ^ +%Warning-ASSIGNDLY: t/t_net_delay.v:29:11: Ignoring timing control on this assignment/primitive due to --no-timing + : ... note: In instance 't' + 29 | assign #3 val2 = cyc; + | ^ +%Warning-STMTDLY: t/t_net_delay.v:41:26: Ignoring delay on this statement due to --no-timing + : ... note: In instance 't' + 41 | always @(posedge clk) #1 begin | ^ %Error: Exiting due to diff --git a/test_regress/t/t_net_delay.v b/test_regress/t/t_net_delay.v index 514504a6b..9822f1827 100644 --- a/test_regress/t/t_net_delay.v +++ b/test_regress/t/t_net_delay.v @@ -9,14 +9,16 @@ module t; // verilator lint_off UNOPTFLAT + // verilator lint_off PROCASSINIT logic clk = 0; // verilator lint_on UNOPTFLAT + // verilator lint_on PROCASSINIT always #2 clk = ~clk; // verilator lint_off UNDRIVEN wire[3:0] x; // verilator lint_on UNDRIVEN - reg[3:0] cyc = 0; + bit [3:0] cyc; wire[3:0] #3 val1; wire[3:0] #3 val2; wire[3:0] #5 val3 = cyc;