Add error on localparam value from hierarchical path (#6456).
This commit is contained in:
parent
f970485e19
commit
7f85d7f453
1
Changes
1
Changes
|
|
@ -17,6 +17,7 @@ Verilator 5.041 devel
|
||||||
* Add configure `--enable-asan` to compile verilator_bin with the address sanitizer (#6404). [Geza Lore]
|
* 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 $(LDFLAGS) and $(LIBS) to when building shared libraries (#6425) (#6426). [Ahmed El-Mahmoudy]
|
||||||
* Add ASSIGNEQEXPR when use `=` inside expressions (#5567). [Ethan Sifferman]
|
* Add ASSIGNEQEXPR when use `=` inside expressions (#5567). [Ethan Sifferman]
|
||||||
|
* Add error on localparam value from hierarchical path (#6456). [Luca Rufer]
|
||||||
* Deprecate sensitivity list on public_flat_rw attributes (#6443). [Geza Lore]
|
* Deprecate sensitivity list on public_flat_rw attributes (#6443). [Geza Lore]
|
||||||
* Support modports referencing clocking blocks (#4555) (#6436). [Ryszard Rozak, Antmicro Ltd.]
|
* Support modports referencing clocking blocks (#4555) (#6436). [Ryszard Rozak, Antmicro Ltd.]
|
||||||
* Support pure functions in sensitivity lists (#6393). [Krzysztof Bieganski, Antmicro Ltd.]
|
* Support pure functions in sensitivity lists (#6393). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||||
|
|
|
||||||
|
|
@ -1416,6 +1416,13 @@ class ParamVisitor final : public VNVisitor {
|
||||||
if (nodep->user2SetOnce()) return; // Process once
|
if (nodep->user2SetOnce()) return; // Process once
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
if (nodep->isParam()) {
|
if (nodep->isParam()) {
|
||||||
|
// See if any Future before we process
|
||||||
|
if (nodep->valuep())
|
||||||
|
nodep->valuep()->foreach([&](const AstVarXRef* refp) {
|
||||||
|
refp->v3error("Parameter values cannot be hierarchical"
|
||||||
|
" (IEEE 1800-2023 6.20.2): "
|
||||||
|
<< nodep->prettyNameQ());
|
||||||
|
});
|
||||||
if (!nodep->valuep() && !VN_IS(m_modp, Class)) {
|
if (!nodep->valuep() && !VN_IS(m_modp, Class)) {
|
||||||
nodep->v3error("Parameter without default value is never given value"
|
nodep->v3error("Parameter without default value is never given value"
|
||||||
<< " (IEEE 1800-2023 6.20.1): " << nodep->prettyNameQ());
|
<< " (IEEE 1800-2023 6.20.1): " << nodep->prettyNameQ());
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
import vltest_bootstrap
|
import vltest_bootstrap
|
||||||
|
|
||||||
test.scenarios('simulator')
|
test.scenarios('simulator_st')
|
||||||
|
|
||||||
test.compile()
|
test.compile()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ interface intf
|
||||||
endinterface
|
endinterface
|
||||||
|
|
||||||
module sub (intf.modp the_intf_port [4]);
|
module sub (intf.modp the_intf_port [4]);
|
||||||
localparam int intf_foo = the_intf_port[0].FOO;
|
const int intf_foo = the_intf_port[0].FOO;
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
if (intf_foo != 4) $stop;
|
if (intf_foo != 4) $stop;
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ module Core(
|
||||||
);
|
);
|
||||||
|
|
||||||
// this will constify and valDiv2 will have the default value
|
// this will constify and valDiv2 will have the default value
|
||||||
localparam valDiv4Upper = intf.valDiv2;
|
const int valDiv4Upper = intf.valDiv2;
|
||||||
|
|
||||||
SimpleIntf #(.VAL(68)) core_intf ();
|
SimpleIntf #(.VAL(68)) core_intf ();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
import vltest_bootstrap
|
import vltest_bootstrap
|
||||||
|
|
||||||
test.scenarios('simulator')
|
test.scenarios('simulator_st')
|
||||||
|
|
||||||
test.compile()
|
test.compile()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ endinterface
|
||||||
|
|
||||||
module t ();
|
module t ();
|
||||||
simple_bus sb_intf();
|
simple_bus sb_intf();
|
||||||
localparam LP = $bits(sb_intf.payload.data);
|
const int LP = $bits(sb_intf.payload.data);
|
||||||
simple_bus #(.PARAMETER($bits(sb_intf.DUMMY))) simple();
|
simple_bus #(.PARAMETER($bits(sb_intf.DUMMY))) simple();
|
||||||
simple_bus #(.PARAMETER($bits(sb_intf.x))) simple2();
|
simple_bus #(.PARAMETER($bits(sb_intf.x))) simple2();
|
||||||
initial begin
|
initial begin
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
import vltest_bootstrap
|
import vltest_bootstrap
|
||||||
|
|
||||||
test.scenarios('simulator')
|
test.scenarios('simulator_st')
|
||||||
|
|
||||||
test.compile()
|
test.compile()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,9 +45,9 @@ module t (/*AUTOARG*/
|
||||||
.intf_array (array_interface)
|
.intf_array (array_interface)
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam THE_TOP_FOO = the_interface.FOO;
|
const int THE_TOP_FOO = the_interface.FOO;
|
||||||
localparam THE_TOP_FOO_BITS = $bits({the_interface.FOO, the_interface.FOO});
|
const int THE_TOP_FOO_BITS = $bits({the_interface.FOO, the_interface.FOO});
|
||||||
localparam THE_ARRAY_FOO = array_interface[0].FOO;
|
const int THE_ARRAY_FOO = array_interface[0].FOO;
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
if (THE_TOP_FOO != 5) begin
|
if (THE_TOP_FOO != 5) begin
|
||||||
|
|
@ -75,12 +75,12 @@ module testmod
|
||||||
test_if.mp intf_array [1:0]
|
test_if.mp intf_array [1:0]
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam THE_FOO = intf.FOO;
|
const int THE_FOO = intf.FOO;
|
||||||
localparam THE_OTHER_FOO = intf_no_mp.FOO;
|
const int THE_OTHER_FOO = intf_no_mp.FOO;
|
||||||
localparam THE_ARRAY_FOO = intf_array[0].FOO;
|
const int THE_ARRAY_FOO = intf_array[0].FOO;
|
||||||
localparam THE_BAR = intf.BAR;
|
const int THE_BAR = intf.BAR;
|
||||||
localparam THE_OTHER_BAR = intf_no_mp.BAR;
|
const int THE_OTHER_BAR = intf_no_mp.BAR;
|
||||||
localparam THE_ARRAY_BAR = intf_array[0].BAR;
|
const int THE_ARRAY_BAR = intf_array[0].BAR;
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
if (THE_FOO != 5) begin
|
if (THE_FOO != 5) begin
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
%Error: t/t_param_hier_bad.v:26:32: Parameter values cannot be hierarchical (IEEE 1800-2023 6.20.2): 'SUB_Y'
|
||||||
|
: ... note: In instance 't'
|
||||||
|
26 | localparam int SUB_Y = u_sub.Y;
|
||||||
|
| ^
|
||||||
|
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||||
|
%Error: Exiting due to
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/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('linter')
|
||||||
|
|
||||||
|
test.lint(fails=True, expect_filename=test.golden_filename)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// verilog_format: off
|
||||||
|
`define stop $stop
|
||||||
|
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
|
||||||
|
// verilog_format: on
|
||||||
|
|
||||||
|
module sub #(
|
||||||
|
parameter int X = 1
|
||||||
|
) ();
|
||||||
|
|
||||||
|
localparam int Y = X;
|
||||||
|
localparam int Z = X;
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module t;
|
||||||
|
localparam int MY_X = 2;
|
||||||
|
|
||||||
|
sub #(.X(MY_X)) u_sub ();
|
||||||
|
|
||||||
|
localparam int SUB_Y = u_sub.Y; // <--- BAD: IEEE 1800-2023 6.20.2 no hierarchical
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
`checkd(SUB_Y, 1);
|
||||||
|
`checkd(u_sub.X, 2);
|
||||||
|
`checkd(u_sub.Y, 1);
|
||||||
|
`checkd(u_sub.Z, 2);
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
Loading…
Reference in New Issue