Add SPECIFYIGN warning for specify constructs that were previously silently ignored.

This commit is contained in:
Wilson Snyder 2025-07-18 19:32:34 -04:00
parent 9b99d9697f
commit 7d43a935bd
14 changed files with 145 additions and 17 deletions

View File

@ -15,6 +15,7 @@ Verilator 5.039 devel
* Add ENUMITEMWIDTH error, and apply to X-extended and ranged values.
* Add NOEFFECT warning, replacing previous `foreach` error.
* Add SPECIFYIGN warning for specify constructs that were previously silently ignored.
* Add enum base type checking per IEEE.
* Support member-level triggers for virtual interfaces (#5166) (#6148). [Yilou Wang]
* Support disabling a fork in additional contexts (#5432 partial) (#6174) (#6183). [Ryszard Rozak, Antmicro Ltd.]

View File

@ -458,7 +458,7 @@ List Of Warnings
Warns that Verilator does not support certain forms of
:code:`constraint`, :code:`constraint_mode`, or :code:`rand_mode`, and
the construct was are ignored.
the construct was ignored.
Ignoring this warning may make Verilator randomize() simulations differ
from other simulators.
@ -486,7 +486,7 @@ List Of Warnings
Warns that Verilator does not support certain forms of
:code:`covergroup`, :code:`coverpoint`, and coverage options, and the
construct was are ignored.
construct was ignored.
Disabling the :option:`UNSUPPORTED` error also disables this warning.
@ -1779,6 +1779,18 @@ List Of Warnings
simulators.
.. option:: SPECIFYIGN
Warns that Verilator does not support certain constructs in
:code:`specify` blocks, nor :code:`$sdf_annotate`, and the construct was
ignored.
Disabling the :option:`UNSUPPORTED` error also disables this warning.
Ignoring this warning may make Verilator ignore lint checking on the
construct, and get different results from other simulators.
.. option:: SPLITVAR
Warns that a variable with a :option:`/*verilator&32;split_var*/`

View File

@ -146,6 +146,7 @@ public:
SELRANGE, // Selection index out of range
SHORTREAL, // Shortreal not supported
SIDEEFFECT, // Sideeffect ignored
SPECIFYIGN, // Specify construct ignored
SPLITVAR, // Cannot split the variable
STATICVAR, // Static variable declared in a loop with a declaration assignment
STMTDLY, // Delayed statement
@ -212,12 +213,12 @@ public:
"NEWERSTD", "NOEFFECT", "NOLATCH", "NONSTD", "NULLPORT", "PINCONNECTEMPTY",
"PINMISSING", "PINNOCONNECT", "PINNOTFOUND", "PKGNODECL", "PREPROCZERO", "PROCASSINIT",
"PROCASSWIRE", "PROFOUTOFDATE", "PROTECTED", "RANDC", "REALCVT", "REDEFMACRO",
"RISEFALLDLY", "SELRANGE", "SHORTREAL", "SIDEEFFECT", "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"};
"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];
}
// Warnings that default to off

View File

@ -1803,8 +1803,10 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
DECL_OPTION("-Wwarn-UNSUPPORTED", CbCall, []() {
FileLine::globalWarnOff(V3ErrorCode::E_UNSUPPORTED, false);
FileLine::globalWarnOff(V3ErrorCode::COVERIGN, false);
FileLine::globalWarnOff(V3ErrorCode::SPECIFYIGN, false);
V3Error::pretendError(V3ErrorCode::E_UNSUPPORTED, false);
V3Error::pretendError(V3ErrorCode::COVERIGN, false);
V3Error::pretendError(V3ErrorCode::SPECIFYIGN, false);
});
DECL_OPTION("-Wwarn-WIDTH", CbCall, []() {
FileLine::globalWarnOff(V3ErrorCode::WIDTH, false);

View File

@ -270,6 +270,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"$rewind" { FL; return yD_REWIND; }
"$rtoi" { FL; return yD_RTOI; }
"$sampled" { FL; return yD_SAMPLED; }
"$sdf_annotate" { FL; return yD_SDF_ANNOTATE; }
"$setup" { FL; return yaTIMINGSPEC; }
"$setuphold" { FL; return yD_SETUPHOLD; }
"$sformat" { FL; return yD_SFORMAT; }

View File

@ -98,6 +98,7 @@ public:
bool m_tracingParse = true; // Tracing disable for parser
bool m_inImplements = false; // Is inside class implements list
bool m_insideProperty = false; // Is inside property declaration
bool m_specifyignWarned = false; // Issued a SPECIFYIGN warning
bool m_typedPropertyPort = false; // Typed property port occurred on port lists
bool m_modportImpExpActive
= false; // Standalone ID is a tf_identifier instead of port_identifier
@ -926,6 +927,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"})
%token<fl> yD_ROSE_GCLK "$rose_gclk"
%token<fl> yD_RTOI "$rtoi"
%token<fl> yD_SAMPLED "$sampled"
%token<fl> yD_SDF_ANNOTATE "$sdf_annotate"
%token<fl> yD_SETUPHOLD "$setuphold"
%token<fl> yD_SFORMAT "$sformat"
%token<fl> yD_SFORMATF "$sformatf"
@ -4284,6 +4286,7 @@ system_t_call<nodeStmtp>: // IEEE: system_tf_call (as task)
| yD_DUMPON '(' expr ')' { $$ = new AstDumpCtl{$<fl>1, VDumpCtlType::ON}; DEL($3); }
//
| yD_C '(' cStrList ')' { $$ = (v3Global.opt.ignc() ? nullptr : new AstUCStmt{$1, $3}); }
| yD_SDF_ANNOTATE '(' exprEListE ')' { $$ = nullptr; $1->v3warn(SPECIFYIGN, "Ignoring unsupported: $sdf_annotate"); }
| yD_STACKTRACE parenE { $$ = new AstStackTraceT{$1}; }
| yD_SYSTEM '(' expr ')' { $$ = new AstSystemT{$1, $3}; }
//
@ -5353,6 +5356,11 @@ exprList<nodeExprp>:
| exprList ',' expr { $$ = $1->addNext($3); }
;
exprEListE<nodep>: // expression list with empty commas allowed
exprE { $$ = $1; }
| exprEListE ',' exprE { $$ = addNextNull($1, $3); }
;
exprDispList<nodeExprp>: // exprList for within $display
expr { $$ = $1; }
| exprDispList ',' expr { $$ = $1->addNext($3); }
@ -5825,8 +5833,12 @@ tablelVal<udpTableLineValp>:
// Specify
specify_block<nodep>: // ==IEEE: specify_block
ySPECIFY specify_itemList yENDSPECIFY { $$ = $2; }
| ySPECIFY yENDSPECIFY { $$ = nullptr; }
specifyFront specify_itemList yENDSPECIFY { $$ = $2; }
| specifyFront yENDSPECIFY { $$ = nullptr; }
;
specifyFront: // IEEE: specify_block front
ySPECIFY { GRAMMARP->m_specifyignWarned = false; }
;
specify_itemList<nodep>: // IEEE: { specify_item }
@ -5837,7 +5849,13 @@ specify_itemList<nodep>: // IEEE: { specify_item }
specify_item<nodep>: // ==IEEE: specify_item
specparam_declaration { $$ = $1; }
| system_timing_check { $$ = $1; }
| junkToSemiList ';' { $$ = nullptr; }
| junkToSemiList ';'
{ $$ = nullptr;
if (!GRAMMARP->m_specifyignWarned) {
GRAMMARP->m_specifyignWarned = true;
$1->v3warn(SPECIFYIGN, "Ignoring unsupported: specify block construct");
}
}
;
specparam_declaration<nodep>: // ==IEEE: specparam_declaration
@ -5926,9 +5944,9 @@ idAnyE<strp>:
| idAny { $$ = $1; }
;
junkToSemiList:
junkToSemi { } /* ignored */
| junkToSemiList junkToSemi { } /* ignored */
junkToSemiList<fl>:
junkToSemi { $$ = CRELINE(); }
| junkToSemiList junkToSemi { $$ = CRELINE(); }
;
junkToSemi:

View File

@ -11,7 +11,7 @@ import vltest_bootstrap
test.scenarios('simulator')
test.compile(verilator_flags2=["--no-timing"])
test.compile(verilator_flags2=["--no-timing", "-Wno-SPECIFYIGN"])
test.execute()

View File

@ -0,0 +1,22 @@
%Warning-SPECIFYIGN: t/t_gate_basic.v:50:27: Ignoring unsupported: specify block construct
50 | (nt0 *> nt0) = (0, 0);
| ^
... For warning description see https://verilator.org/warn/SPECIFYIGN?v=latest
... Use "/* verilator lint_off SPECIFYIGN */" and lint_on around source to disable this message.
%Warning-SPECIFYIGN: t/t_gate_basic.v:60:32: Ignoring unsupported: specify block construct
60 | (A1 *> Q) = (a$A1$Y, a$A1$Y);
| ^
%Error-NEEDTIMINGOPT: t/t_gate_basic.v:24:10: Use --timing or --no-timing to specify how timing controls should be handled
: ... note: In instance 't'
24 | not #(0.108) NT0 (nt0, a[0]);
| ^
... For error description see https://verilator.org/warn/NEEDTIMINGOPT?v=latest
%Error-NEEDTIMINGOPT: t/t_gate_basic.v:25:10: Use --timing or --no-timing to specify how timing controls should be handled
: ... note: In instance 't'
25 | and #1 AN0 (an0, a[0], b[0]);
| ^
%Error-NEEDTIMINGOPT: t/t_gate_basic.v:26:10: Use --timing or --no-timing to specify how timing controls should be handled
: ... note: In instance 't'
26 | nand #(2,3) ND0 (nd0, a[0], b[0], b[1]);
| ^
%Error: Exiting due to

View File

@ -0,0 +1,17 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2024 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.top_filename = 't/t_gate_basic.v'
test.lint(fails=True, expect_filename=test.golden_filename)
test.passes()

View File

@ -13,7 +13,8 @@ test.scenarios('simulator')
test.top_filename = "t/t_gate_basic.v"
test.main_time_multiplier = 10e-7 / 10e-9
test.compile(timing_loop=True, verilator_flags2=["--timing --timescale 10ns/1ns -Wno-RISEFALLDLY"])
test.compile(timing_loop=True,
verilator_flags2=["--timing --timescale 10ns/1ns -Wno-RISEFALLDLY -Wno-SPECIFYIGN"])
test.execute()

View File

@ -12,7 +12,9 @@ import vltest_bootstrap
test.scenarios('linter')
test.top_filename = "t/t_gate_basic.v"
test.lint(verilator_flags2=["--lint-only -Wall -Wno-DECLFILENAME -Wno-UNUSED --timing"],
test.lint(verilator_flags2=[
"--lint-only --timing -Wall", "-Wno-DECLFILENAME -Wno-SPECIFYIGN -Wno-UNUSED"
],
fails=True,
expect_filename=test.golden_filename)

View File

@ -0,0 +1,15 @@
%Warning-SPECIFYIGN: t/t_sdf_annotate_unsup.v:10:5: Ignoring unsupported: $sdf_annotate
10 | $sdf_annotate("file.sdf");
| ^~~~~~~~~~~~~
... For warning description see https://verilator.org/warn/SPECIFYIGN?v=latest
... Use "/* verilator lint_off SPECIFYIGN */" and lint_on around source to disable this message.
%Warning-SPECIFYIGN: t/t_sdf_annotate_unsup.v:11:5: Ignoring unsupported: $sdf_annotate
11 | $sdf_annotate("file.sdf",);
| ^~~~~~~~~~~~~
%Warning-SPECIFYIGN: t/t_sdf_annotate_unsup.v:12:5: Ignoring unsupported: $sdf_annotate
12 | $sdf_annotate("file.sdf", t);
| ^~~~~~~~~~~~~
%Warning-SPECIFYIGN: t/t_sdf_annotate_unsup.v:14:5: Ignoring unsupported: $sdf_annotate
14 | $sdf_annotate("file.sdf", t, "config_file", "log_file", "mtm_spec", "scale_factors",
| ^~~~~~~~~~~~~
%Error: Exiting due to

View File

@ -0,0 +1,16 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2024 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(fails=test.vlt_all, expect_filename=test.golden_filename)
test.passes()

View File

@ -0,0 +1,20 @@
// DESCRIPTION: Verilator: Verilog Test module for SystemVerilog 'alias'
//
// 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;
initial begin
$sdf_annotate("file.sdf");
$sdf_annotate("file.sdf",);
$sdf_annotate("file.sdf", t);
// TArguments are all optional, so test more exhaustively
$sdf_annotate("file.sdf", t, "config_file", "log_file", "mtm_spec", "scale_factors",
"scale_type");
$write("*-* All Finished *-*\n");
$finish;
end
endmodule