This commit is contained in:
Lucas Amaral 2026-06-10 15:38:07 +02:00 committed by GitHub
commit d09278f515
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 78 additions and 6 deletions

View File

@ -325,3 +325,4 @@ Yogish Sekhar
24bit-xjkp
Zubin Jain
Muzaffer Kal
Lucas Amaral

View File

@ -2191,6 +2191,34 @@ List Of Warnings
correctly.
.. option:: SYNTHUNPACKED
Warns that a module IO port uses an unpacked array. Synthesis tools
(e.g., Yosys, Cadence Genus, Synopsys Design Compiler) accept the
construct but typically flatten the unpacked dimensions to packed bits
in the netlist. The resulting post-synthesis port signature no longer
matches the pre-synthesis source, so a testbench that drove the RTL
through these ports cannot connect to the netlist without modification,
making gate-level simulation (GLS) harder.
For example:
.. code-block:: sv
module dut(input wire [7:0] data [0:3]); // Will get SYNTHUNPACKED
...
endmodule
To keep the pre- and post-synthesis port signatures aligned, flatten
the port to a packed vector at the module boundary, or wrap the array
in a packed struct.
Disabled by default since not all flows go through synthesis. Enable
with ``-Wwarn-SYNTHUNPACKED`` to surface it. Ignoring this warning does
not affect Verilator simulation; it only flags a downstream GLS
compatibility hazard.
.. option:: TASKNSVAR
Error when a call to a task or function has an inout from that task tied

View File

@ -168,6 +168,7 @@ public:
SUPERNFIRST, // Super.new must be first statement
SYMRSVDWORD, // Symbol is Reserved Word
SYNCASYNCNET, // Mixed sync + async reset
SYNTHUNPACKED, // Unpacked array on IO port (synth packs these, breaking GLS)
TICKCOUNT, // Too large tick count
TIMESCALEMOD, // Need timescale for module
UNDRIVEN, // No drivers
@ -238,16 +239,17 @@ public:
"PROCASSWIRE", "PROFOUTOFDATE", "PROTECTED", "PROTOTYPEMIS", "RANDC", "REALCVT",
"REDEFMACRO", "RISEFALLDLY", "SELRANGE", "SHORTREAL", "SIDEEFFECT", "SPECIFYIGN",
"SPLITVAR", "STATICVAR", "STMTDLY", "SUPERNFIRST", "SYMRSVDWORD", "SYNCASYNCNET",
"TICKCOUNT", "TIMESCALEMOD", "UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNOPTTHREADS",
"UNPACKED", "UNSATCONSTR", "UNSIGNED", "UNUSED", "UNUSEDGENVAR", "UNUSEDLOOP",
"UNUSEDPARAM", "UNUSEDSIGNAL", "USERERROR", "USERFATAL", "USERINFO", "USERWARN",
"VARHIDDEN", "WAITCONST", "WIDTH", "WIDTHCONCAT", "WIDTHEXPAND", "WIDTHTRUNC",
"WIDTHXZEXPAND", "ZERODLY", "ZEROREPL", " MAX"};
"SYNTHUNPACKED", "TICKCOUNT", "TIMESCALEMOD", "UNDRIVEN", "UNOPT", "UNOPTFLAT",
"UNOPTTHREADS", "UNPACKED", "UNSATCONSTR", "UNSIGNED", "UNUSED", "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
bool defaultsOff() const VL_MT_SAFE {
return (m_e == IMPERFECTSCH || m_e == I_CELLDEFINE || styleError());
return (m_e == IMPERFECTSCH || m_e == I_CELLDEFINE || m_e == SYNTHUNPACKED
|| styleError());
}
// Warnings that warn about nasty side effects
bool dangerous() const VL_MT_SAFE { return (m_e == COMBDLY); }

View File

@ -3045,6 +3045,19 @@ class WidthVisitor final : public VNVisitor {
userIterateAndNext(nodep->delayp(), WidthVP{nodep->dtypep(), PRELIM}.p());
UINFO(4, "varWidthed " << nodep);
// UINFOTREE(1, nodep, "", "InitOut");
// Warn about unpacked arrays on module IO ports. Synthesis tools
// typically flatten these to packed bits in the netlist, which breaks
// pre-synthesis testbench connectivity for gate-level simulation.
if (nodep->isIO() && !nodep->isIfaceRef()) {
if (VN_IS(nodep->dtypep()->skipRefp(), UnpackArrayDType)) {
nodep->v3warn(SYNTHUNPACKED,
"Unpacked array on port "
<< nodep->prettyNameQ()
<< " is typically flattened to packed bits by synthesis,"
" breaking pre-synthesis testbench connectivity for"
" gate-level simulation");
}
}
nodep->didWidth(true);
nodep->doingWidth(false);
}

View File

@ -0,0 +1,7 @@
%Warning-SYNTHUNPACKED: t/t_lint_synthunpacked_bad.v:6:28: Unpacked array on port 'data' is typically flattened to packed bits by synthesis, breaking pre-synthesis testbench connectivity for gate-level simulation
: ... note: In instance 't'
6 | module t (input wire [7:0] data [0:3]);
| ^~~~
... For warning description see https://verilator.org/warn/SYNTHUNPACKED?v=latest
... Use "/* verilator lint_off SYNTHUNPACKED */" and lint_on around source to disable this message.
%Error: Exiting due to

View File

@ -0,0 +1,13 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Lint test for SYNTHUNPACKED warning
#
# SPDX-FileCopyrightText: 2026 Wilson Snyder
# SPDX-License-Identifier: CC0-1.0
import vltest_bootstrap
test.scenarios('linter')
test.lint(fails=True, v_flags2=['-Wwarn-SYNTHUNPACKED'], expect_filename=test.golden_filename)
test.passes()

View File

@ -0,0 +1,8 @@
// DESCRIPTION: Verilator: Test of SYNTHUNPACKED warning on unpacked port
//
// SPDX-FileCopyrightText: 2026 Lucas Amaral
// SPDX-License-Identifier: CC0-1.0
module t (input wire [7:0] data [0:3]);
initial $display("data[0]=%h", data[0]);
endmodule