diff --git a/Changes b/Changes index b187d35f3..9ea4302b0 100644 --- a/Changes +++ b/Changes @@ -21,7 +21,7 @@ Verilator 5.041 devel * Add configure `--enable-asan` to compile verilator_bin with the address sanitizer (#6404). [Geza Lore] * Add $(LDFLAGS) and $(LIBS) to when building shared libraries (#6425) (#6426). [Ahmed El-Mahmoudy] * Add IMPLICITSTATIC also on procedure variables. -* Add error on function invoking task or time-controlling statements (#6385). +* Add FUNCTIMCTL error on function invoking task or time-controlling statements (#6385). * Deprecate sensitivity list on public_flat_rw attributes (#6443). [Geza Lore] * Deprecate clocker attribute and --clk option (#6463). [Geza Lore] * Support modports referencing clocking blocks (#4555) (#6436). [Ryszard Rozak, Antmicro Ltd.] diff --git a/docs/gen/ex_FUNCTIMECTL_faulty.rst b/docs/gen/ex_FUNCTIMECTL_faulty.rst new file mode 100644 index 000000000..5c2e70053 --- /dev/null +++ b/docs/gen/ex_FUNCTIMECTL_faulty.rst @@ -0,0 +1,7 @@ +.. comment: generated by t_lint_functimectl_bad +.. code-block:: sv + :linenos: + :emphasize-lines: 2 + + function void calls_timing_ctl; + @e; // <--- Bad IEEE 1800-2023 13.4 time-controlling diff --git a/docs/gen/ex_FUNCTIMECTL_msg.rst b/docs/gen/ex_FUNCTIMECTL_msg.rst new file mode 100644 index 000000000..d7d5b8426 --- /dev/null +++ b/docs/gen/ex_FUNCTIMECTL_msg.rst @@ -0,0 +1,4 @@ +.. comment: generated by t_lint_functimectl_bad +.. code-block:: + + %Error-FUNCTIMECTL: example.v:1:5 Functions cannot contain time-controlling statements (IEEE 1800-2023 13.4) diff --git a/docs/guide/warnings.rst b/docs/guide/warnings.rst index 1d3efd556..0bdde1e5a 100644 --- a/docs/guide/warnings.rst +++ b/docs/guide/warnings.rst @@ -835,6 +835,25 @@ List Of Warnings with a newline." +.. option:: FUNCTIMECTL + + Error that a function contains a time-controlling statement or call of a + task. IEEE 1800-2023 13.4 requires this error. + + Faulty example: + + .. include:: ../../docs/gen/ex_FUNCTIMECTL_faulty.rst + + Results in: + + .. include:: ../../docs/gen/ex_FUNCTIMECTL_msg.rst + + Suppressing this error will only suppress the IEEE-required check; in + most cases Verilator treats functions and tasks identically and relies + on analysis to determine what functions/tasks need to allow time to + pass. + + .. option:: GENCLK Historical, never issued since version 5.000. diff --git a/src/V3Error.h b/src/V3Error.h index 6fbf2fdc6..b98f354fb 100644 --- a/src/V3Error.h +++ b/src/V3Error.h @@ -105,6 +105,7 @@ public: ENUMITEMWIDTH, // Error: enum item width mismatch ENUMVALUE, // Error: enum type needs explicit cast EOFNEWLINE, // End-of-file missing newline + FUNCTIMECTL, // Functions cannot have timing/delay/wait GENCLK, // Generated Clock. Historical, never issued. GENUNNAMED, // Generate unnamed, without label HIERBLOCK, // Ignored hierarchical block setting @@ -213,19 +214,19 @@ public: "BSSPACE", "CASEINCOMPLETE", "CASEOVERLAP", "CASEWITHX", "CASEX", "CASTCONST", "CDCRSTLOGIC", "CLKDATA", "CMPCONST", "COLONPLUS", "COMBDLY", "CONSTRAINTIGN", "CONTASSREG", "COVERIGN", "DECLFILENAME", "DEFOVERRIDE", "DEFPARAM", "DEPRECATED", - "ENCAPSULATED", "ENDLABEL", "ENUMITEMWIDTH", "ENUMVALUE", "EOFNEWLINE", "GENCLK", - "GENUNNAMED", "HIERBLOCK", "HIERPARAM", "IFDEPTH", "IGNOREDRETURN", "IMPERFECTSCH", - "IMPLICIT", "IMPLICITSTATIC", "IMPORTSTAR", "IMPURE", "INCABSPATH", "INFINITELOOP", - "INITIALDLY", "INSECURE", "LATCH", "LITENDIAN", "MINTYPMAXDLY", "MISINDENT", "MODDUP", - "MODMISSING", "MULTIDRIVEN", "MULTITOP", "NEWERSTD", "NOEFFECT", "NOLATCH", "NONSTD", - "NULLPORT", "PARAMNODEFAULT", "PINCONNECTEMPTY", "PINMISSING", "PINNOCONNECT", - "PINNOTFOUND", "PKGNODECL", "PREPROCZERO", "PROCASSINIT", "PROCASSWIRE", - "PROFOUTOFDATE", "PROTECTED", "PROTOTYPEMIS", "RANDC", "REALCVT", "REDEFMACRO", - "RISEFALLDLY", "SELRANGE", "SHORTREAL", "SIDEEFFECT", "SPECIFYIGN", "SPLITVAR", - "STATICVAR", "STMTDLY", "SYMRSVDWORD", "SYNCASYNCNET", "TICKCOUNT", "TIMESCALEMOD", - "UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNOPTTHREADS", "UNPACKED", "UNSIGNED", - "UNUSEDGENVAR", "UNUSEDLOOP", "UNUSEDPARAM", "UNUSEDSIGNAL", "USERERROR", "USERFATAL", - "USERINFO", "USERWARN", "VARHIDDEN", "WAITCONST", "WIDTH", "WIDTHCONCAT", + "ENCAPSULATED", "ENDLABEL", "ENUMITEMWIDTH", "ENUMVALUE", "EOFNEWLINE", "FUNCTIMECTL", + "GENCLK", "GENUNNAMED", "HIERBLOCK", "HIERPARAM", "IFDEPTH", "IGNOREDRETURN", + "IMPERFECTSCH", "IMPLICIT", "IMPLICITSTATIC", "IMPORTSTAR", "IMPURE", "INCABSPATH", + "INFINITELOOP", "INITIALDLY", "INSECURE", "LATCH", "LITENDIAN", "MINTYPMAXDLY", + "MISINDENT", "MODDUP", "MODMISSING", "MULTIDRIVEN", "MULTITOP", "NEWERSTD", "NOEFFECT", + "NOLATCH", "NONSTD", "NULLPORT", "PARAMNODEFAULT", "PINCONNECTEMPTY", "PINMISSING", + "PINNOCONNECT", "PINNOTFOUND", "PKGNODECL", "PREPROCZERO", "PROCASSINIT", + "PROCASSWIRE", "PROFOUTOFDATE", "PROTECTED", "PROTOTYPEMIS", "RANDC", "REALCVT", + "REDEFMACRO", "RISEFALLDLY", "SELRANGE", "SHORTREAL", "SIDEEFFECT", "SPECIFYIGN", + "SPLITVAR", "STATICVAR", "STMTDLY", "SYMRSVDWORD", "SYNCASYNCNET", "TICKCOUNT", + "TIMESCALEMOD", "UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNOPTTHREADS", "UNPACKED", + "UNSIGNED", "UNUSEDGENVAR", "UNUSEDLOOP", "UNUSEDPARAM", "UNUSEDSIGNAL", "USERERROR", + "USERFATAL", "USERINFO", "USERWARN", "VARHIDDEN", "WAITCONST", "WIDTH", "WIDTHCONCAT", "WIDTHEXPAND", "WIDTHTRUNC", "WIDTHXZEXPAND", "ZERODLY", "ZEROREPL", " MAX"}; return names[m_e]; } @@ -254,9 +255,9 @@ public: return (m_e == ASSIGNIN || m_e == BADSTDPRAGMA || m_e == BADVLTPRAGMA || m_e == BLKANDNBLK || m_e == BLKLOOPINIT || m_e == CONTASSREG || m_e == ENCAPSULATED || m_e == ENDLABEL || m_e == ENUMITEMWIDTH || m_e == ENUMVALUE || m_e == HIERPARAM - || m_e == IMPURE || m_e == MODMISSING || m_e == PARAMNODEFAULT - || m_e == PINNOTFOUND || m_e == PKGNODECL || m_e == PROCASSWIRE - || m_e == PROTOTYPEMIS || m_e == ZEROREPL // Says IEEE + || m_e == FUNCTIMECTL || m_e == IMPURE || m_e == MODMISSING + || m_e == PARAMNODEFAULT || m_e == PINNOTFOUND || m_e == PKGNODECL + || m_e == PROCASSWIRE || m_e == PROTOTYPEMIS || m_e == ZEROREPL // Says IEEE ); } // Warnings to mention manual diff --git a/src/V3WidthCommit.cpp b/src/V3WidthCommit.cpp index cb24076bc..774d1a1e4 100644 --- a/src/V3WidthCommit.cpp +++ b/src/V3WidthCommit.cpp @@ -67,12 +67,13 @@ private: // Called by every visitor. Edit dtypes for this node, also check for some warnings nodep->dtypep(editOneDType(nodep->dtypep())); if (m_ftaskp && m_ftaskp->verilogFunction() && m_taskRefWarn && nodep->isTimingControl()) - nodep->v3error( + nodep->v3warn( + FUNCTIMECTL, "Functions cannot contain time-controlling statements (IEEE 1800-2023 13.4)\n" - << nodep->warnContextPrimary() << "\n" - << nodep->warnMore() << "... Suggest make caller 'function " - << m_ftaskp->prettyName() << "' a task\n" - << m_ftaskp->warnContextSecondary()); + << nodep->warnContextPrimary() << "\n" + << nodep->warnMore() << "... Suggest make caller 'function " + << m_ftaskp->prettyName() << "' a task\n" + << m_ftaskp->warnContextSecondary()); } AstNodeDType* editOneDType(AstNodeDType* nodep) { // See if the dtype/refDType can be converted to a standard one @@ -439,14 +440,15 @@ private: classEncapCheck(nodep, nodep->taskp(), VN_CAST(nodep->classOrPackagep(), Class)); if (nodep->taskp() && nodep->taskp()->verilogTask() && m_ftaskp && m_ftaskp->verilogFunction() && m_taskRefWarn) { - nodep->v3error("Functions cannot invoke tasks (IEEE 1800-2023 13.4)\n" - << nodep->warnContextPrimary() << "\n" - << nodep->warnMore() << "... Suggest make caller 'function " - << m_ftaskp->prettyName() << "' a task\n" - << m_ftaskp->warnContextSecondary() << "\n" - << nodep->warnMore() << "... Or, suggest make called 'task " - << nodep->taskp()->prettyName() << "' a function void\n" - << nodep->taskp()->warnContextSecondary()); + nodep->v3warn(FUNCTIMECTL, + "Functions cannot invoke tasks (IEEE 1800-2023 13.4)\n" + << nodep->warnContextPrimary() << "\n" + << nodep->warnMore() << "... Suggest make caller 'function " + << m_ftaskp->prettyName() << "' a task\n" + << m_ftaskp->warnContextSecondary() << "\n" + << nodep->warnMore() << "... Or, suggest make called 'task " + << nodep->taskp()->prettyName() << "' a function void\n" + << nodep->taskp()->warnContextSecondary()); } if (nodep->taskp()) nodep->taskp()->user2(1); if (AstNew* const newp = VN_CAST(nodep, New)) { diff --git a/test_regress/t/t_func_bad_time.out b/test_regress/t/t_func_bad_time.out deleted file mode 100644 index d677a93ec..000000000 --- a/test_regress/t/t_func_bad_time.out +++ /dev/null @@ -1,16 +0,0 @@ -%Error: t/t_func_bad_time.v:12:5: Functions cannot contain time-controlling statements (IEEE 1800-2023 13.4) - : ... note: In instance 't' - 12 | @e; - | ^ - : ... Suggest make caller 'function calls_timing_ctl' a task - 11 | function void calls_timing_ctl; - | ^~~~~~~~~~~~~~~~ - ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. -%Error: t/t_func_bad_time.v:17:5: Functions cannot contain time-controlling statements (IEEE 1800-2023 13.4) - : ... note: In instance 't' - 17 | wait (s); - | ^~~~ - : ... Suggest make caller 'function calls_timing_ctl' a task - 11 | function void calls_timing_ctl; - | ^~~~~~~~~~~~~~~~ -%Error: Exiting due to diff --git a/test_regress/t/t_func_task_bad2.out b/test_regress/t/t_func_task_bad2.out index 174c5e0f4..ce39fdf97 100644 --- a/test_regress/t/t_func_task_bad2.out +++ b/test_regress/t/t_func_task_bad2.out @@ -1,12 +1,12 @@ -%Error: t/t_func_task_bad2.v:14:5: Functions cannot invoke tasks (IEEE 1800-2023 13.4) - : ... note: In instance 't' +%Error-FUNCTIMECTL: t/t_func_task_bad2.v:14:5: Functions cannot invoke tasks (IEEE 1800-2023 13.4) + : ... note: In instance 't' 14 | a_task(1'b0); | ^~~~~~ - : ... Suggest make caller 'function func_calls_task' a task + : ... Suggest make caller 'function func_calls_task' a task 13 | function void func_calls_task; | ^~~~~~~~~~~~~~~ - : ... Or, suggest make called 'task a_task' a function void + : ... Or, suggest make called 'task a_task' a function void 9 | task a_task; | ^~~~~~ - ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. + ... For error description see https://verilator.org/warn/FUNCTIMECTL?v=latest %Error: Exiting due to diff --git a/test_regress/t/t_lint_functimectl_bad.out b/test_regress/t/t_lint_functimectl_bad.out new file mode 100644 index 000000000..4e37bd5a0 --- /dev/null +++ b/test_regress/t/t_lint_functimectl_bad.out @@ -0,0 +1,16 @@ +%Error-FUNCTIMECTL: t/t_lint_functimectl_bad.v:12:5: Functions cannot contain time-controlling statements (IEEE 1800-2023 13.4) + : ... note: In instance 't' + 12 | @e; + | ^ + : ... Suggest make caller 'function calls_timing_ctl' a task + 11 | function void calls_timing_ctl; + | ^~~~~~~~~~~~~~~~ + ... For error description see https://verilator.org/warn/FUNCTIMECTL?v=latest +%Error-FUNCTIMECTL: t/t_lint_functimectl_bad.v:17:5: Functions cannot contain time-controlling statements (IEEE 1800-2023 13.4) + : ... note: In instance 't' + 17 | wait (s); + | ^~~~ + : ... Suggest make caller 'function calls_timing_ctl' a task + 11 | function void calls_timing_ctl; + | ^~~~~~~~~~~~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_func_bad_time.py b/test_regress/t/t_lint_functimectl_bad.py similarity index 64% rename from test_regress/t/t_func_bad_time.py rename to test_regress/t/t_lint_functimectl_bad.py index b84992e49..f0fc3f49c 100755 --- a/test_regress/t/t_func_bad_time.py +++ b/test_regress/t/t_lint_functimectl_bad.py @@ -13,4 +13,12 @@ test.scenarios('linter') test.lint(verilator_flags2=['--timing'], fails=test.vlt_all, expect_filename=test.golden_filename) +test.extract(in_filename=test.top_filename, + out_filename=test.root + "/docs/gen/ex_FUNCTIMECTL_faulty.rst", + lines="11-12") + +test.extract(in_filename=test.golden_filename, + out_filename=test.root + "/docs/gen/ex_FUNCTIMECTL_msg.rst", + lines="1-1") + test.passes() diff --git a/test_regress/t/t_func_bad_time.v b/test_regress/t/t_lint_functimectl_bad.v similarity index 100% rename from test_regress/t/t_func_bad_time.v rename to test_regress/t/t_lint_functimectl_bad.v