Merge pull request #1413 from larsclausen/type-id-vars-wires

Support declaration names shadowing type identifiers
This commit is contained in:
Cary R. 2026-07-02 09:52:03 -07:00 committed by GitHub
commit 823aa224db
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 1093 additions and 182 deletions

View File

@ -0,0 +1,103 @@
// Check that net names can shadow visible type identifiers.
typedef logic [7:0] T;
typedef int U;
typedef logic [5:0] V;
`define check(value, expected, error) \
if ((value) !== (expected)) begin \
$display("FAILED(%0d). %s", `__LINE__, error); \
$display(" expected %0h, got %0h", expected, value); \
failed = 1'b1; \
end
module net_name(output reg failed);
wire T = 1'b1;
initial begin
failed = 1'b0;
`check(T, 1'b1, "wire T did not declare a one-bit net");
end
endmodule
module net_list(output reg failed);
wire T, U;
assign T = 1'b0;
assign U = 1'b1;
initial begin
failed = 1'b0;
`check(T, 1'b0, "type identifier net list first value mismatch");
`check(U, 1'b1, "type identifier net list continuation mismatch");
end
endmodule
module net_array(output reg failed);
wire T [1:0];
assign T[0] = 1'b0;
assign T[1] = 1'b1;
initial begin
failed = 1'b0;
`check(T[0], 1'b0, "type identifier net array first value mismatch");
`check(T[1], 1'b1, "type identifier net array second value mismatch");
end
endmodule
module net_type(output reg failed);
wire T x = 8'ha5;
wire T [1:0] y = 16'h5aa5;
wire V v0, V;
wire T T;
assign v0 = 6'h2a;
assign V = 6'h15;
assign T = 8'h3c;
initial begin
failed = 1'b0;
`check($bits(x), 8, "typed net declaration width regressed");
`check(x, 8'ha5, "typed net declaration value regressed");
`check($bits(y), 16, "typed packed net declaration width regressed");
`check(y, 16'h5aa5, "typed packed net declaration value regressed");
`check($bits(v0), 6, "type identifier net declaration list first width mismatch");
`check($bits(V), 6, "type identifier net declaration list did not allow typedef name as continuation");
`check(V, 6'h15, "type identifier net declaration list value mismatch");
`check($bits(T), 8, "type-name net declaration did not keep typedef type");
`check(T, 8'h3c, "type-name net declaration value mismatch");
end
endmodule
module test;
reg failed;
wire f0;
wire f1;
wire f2;
wire f3;
net_name m0(f0);
net_list m1(f1);
net_array m2(f2);
net_type m3(f3);
initial begin
failed = 1'b0;
#1;
`check(f0, 1'b0, "wire T module failed");
`check(f1, 1'b0, "wire T, U module failed");
`check(f2, 1'b0, "wire T array module failed");
`check(f3, 1'b0, "typed wire T module failed");
if (!failed) begin
$display("PASSED");
end
end
endmodule

View File

@ -0,0 +1,236 @@
// Check that module port names can shadow visible type identifiers.
typedef logic [3:0] T;
package p;
typedef logic [5:0] PT;
endpackage
`define check(value, expected, error) \
if ((value) !== (expected)) begin \
$display("FAILED(%0d). %s", `__LINE__, error); \
$display(" expected %0h, got %0h", expected, value); \
failed = 1'b1; \
end
module ansi_name(input T);
endmodule
module ansi_type(input T x);
endmodule
module ansi_name_dim(input T [1:0]);
endmodule
module ansi_type_dim(input T [1:0] x);
endmodule
module ansi_name_list(input T, U);
endmodule
module ansi_type_list(input T x, y);
endmodule
module ansi_type_list_shadow(input T x, T);
endmodule
module ansi_type_name(input T T, output logic ok);
initial ok = ($bits(T) == 4);
endmodule
module ansi_type_redecl(input n, T x);
endmodule
module ansi_type_redecl_dim(input n, T [1:0] x);
endmodule
module ansi_name_redecl_dim(input n, T [1:0]);
endmodule
module ansi_pkg_type_redecl(input n, p::PT x);
endmodule
module ansi_pkg_type_redecl_dim(input n, p::PT [1:0] x);
endmodule
module decl_name(T);
input T;
endmodule
module decl_type(x);
input T x;
endmodule
module decl_type_dim(x);
input T [1:0] x;
endmodule
module decl_external(.T(x));
input x;
endmodule
module decl_name_list(T, U);
input T, U;
endmodule
module decl_type_list(x, y);
input T x, y;
endmodule
module decl_type_list_shadow(x, T);
input T x, T;
endmodule
module decl_type_name(T, ok);
input T T;
output logic ok;
initial ok = ($bits(T) == 4);
endmodule
module test;
reg failed;
logic n;
T t;
logic n_dim [1:0];
T [1:0] t_dim;
logic n0, n1;
T t0, t1;
logic rn;
T rt;
T [1:0] rt_dim;
logic rn_dim;
logic rt_name_dim [1:0];
logic rp_n;
logic [5:0] rp_t;
logic rp_dim_n;
logic [1:0][5:0] rp_t_dim;
logic d_n;
T d_t;
T [1:0] d_t_dim;
logic d_ext;
logic d_n0, d_n1;
T d_t0, d_t1;
T s_t0, s_t1;
T d_s_t0, d_s_t1;
T p_tn;
T d_p_tn;
logic p_tn_ok;
logic d_p_tn_ok;
ansi_name m0(n);
ansi_type m1(t);
ansi_name_dim m2(n_dim);
ansi_type_dim m3(t_dim);
ansi_name_list m4(n0, n1);
ansi_type_list m5(t0, t1);
ansi_type_list_shadow m17(s_t0, s_t1);
ansi_type_name m19(p_tn, p_tn_ok);
ansi_type_redecl m12(rn, rt);
ansi_type_redecl_dim m13(rn, rt_dim);
ansi_name_redecl_dim m14(rn_dim, rt_name_dim);
ansi_pkg_type_redecl m15(rp_n, rp_t);
ansi_pkg_type_redecl_dim m16(rp_dim_n, rp_t_dim);
decl_name m6(d_n);
decl_type m7(d_t);
decl_type_dim m8(d_t_dim);
decl_external m9(d_ext);
decl_name_list m10(d_n0, d_n1);
decl_type_list m11(d_t0, d_t1);
decl_type_list_shadow m18(d_s_t0, d_s_t1);
decl_type_name m20(d_p_tn, d_p_tn_ok);
initial begin
failed = 1'b0;
n = 1'b1;
t = 4'ha;
n_dim[0] = 1'b0;
n_dim[1] = 1'b1;
t_dim[0] = 4'h3;
t_dim[1] = 4'hc;
n0 = 1'b0;
n1 = 1'b1;
t0 = 4'h5;
t1 = 4'ha;
s_t0 = 4'h6;
s_t1 = 4'h9;
p_tn = 4'h3;
rn = 1'b1;
rt = 4'hc;
rt_dim[0] = 4'h3;
rt_dim[1] = 4'ha;
rn_dim = 1'b0;
rt_name_dim[0] = 1'b1;
rt_name_dim[1] = 1'b0;
rp_n = 1'b1;
rp_t = 6'h2a;
rp_dim_n = 1'b0;
rp_t_dim[0] = 6'h15;
rp_t_dim[1] = 6'h2a;
d_n = 1'b1;
d_t = 4'h6;
d_t_dim[0] = 4'h7;
d_t_dim[1] = 4'h8;
d_ext = 1'b0;
d_n0 = 1'b1;
d_n1 = 1'b0;
d_t0 = 4'h9;
d_t1 = 4'h6;
d_s_t0 = 4'h5;
d_s_t1 = 4'ha;
d_p_tn = 4'hc;
#1;
`check($bits(n), 1, "input T was not parsed as a port name");
`check($bits(t), 4, "input T x was not parsed as a typed port");
`check($bits(n_dim), 2, "input T [1:0] was not parsed as a port array");
`check($bits(t_dim), 8, "input T [1:0] x was not parsed as a typed port array");
`check($bits(n0), 1, "input T, U first port did not keep implicit type");
`check($bits(n1), 1, "input T, U continuation did not keep implicit type");
`check($bits(t0), 4, "input T x, y first port did not keep typedef type");
`check($bits(t1), 4, "input T x, y continuation did not keep typedef type");
`check(t0, 4'h5, "Typed port list first value mismatch");
`check(t1, 4'ha, "Typed port list continuation mismatch");
`check($bits(s_t0), 4, "input T x, T first port did not keep typedef type");
`check($bits(s_t1), 4, "input T x, T continuation did not allow typedef name as port name");
`check(s_t1, 4'h9, "Typed port list shadowing value mismatch");
`check($bits(p_tn), 4, "input T T did not keep typedef type");
`check(p_tn_ok, 1'b1, "input T T was not available as a typed port");
`check($bits(rn), 1, "input n, T x first port did not keep implicit type");
`check($bits(rt), 4, "input n, T x second port did not keep typedef type");
`check(rt, 4'hc, "Inherited-direction typedef port value mismatch");
`check($bits(rt_dim), 8, "input n, T [1:0] x did not keep typedef packed dimensions");
`check(rt_dim[0], 4'h3, "Inherited-direction typedef packed array value mismatch");
`check(rt_dim[1], 4'ha, "Inherited-direction typedef packed array value mismatch");
`check($bits(rn_dim), 1, "input n, T [1:0] first port did not keep implicit type");
`check($bits(rt_name_dim), 2, "input n, T [1:0] second port was not parsed as a port array");
`check($bits(rp_t), 6, "input n, p::PT x second port did not keep package typedef type");
`check(rp_t, 6'h2a, "Inherited-direction package typedef port value mismatch");
`check($bits(rp_t_dim), 12, "input n, p::PT [1:0] x did not keep package typedef packed dimensions");
`check(rp_t_dim[0], 6'h15, "Inherited-direction package typedef packed array value mismatch");
`check(rp_t_dim[1], 6'h2a, "Inherited-direction package typedef packed array value mismatch");
`check($bits(d_n), 1, "input T was not parsed as a port declaration name");
`check($bits(d_t), 4, "input T x was not parsed as a typed port declaration");
`check($bits(d_t_dim), 8, "input T [1:0] x was not parsed as a typed port declaration array");
`check($bits(d_ext), 1, ".T(x) was not parsed as an external port name");
`check($bits(d_n0), 1, "input T, U first declaration did not keep implicit type");
`check($bits(d_n1), 1, "input T, U continuation declaration did not keep implicit type");
`check($bits(d_t0), 4, "input T x, y first declaration did not keep typedef type");
`check($bits(d_t1), 4, "input T x, y continuation declaration did not keep typedef type");
`check(d_t0, 4'h9, "Typed port declaration list first value mismatch");
`check(d_t1, 4'h6, "Typed port declaration list continuation mismatch");
`check($bits(d_s_t0), 4, "input T x, T first declaration did not keep typedef type");
`check($bits(d_s_t1), 4, "input T x, T declaration did not allow typedef name as port name");
`check(d_s_t1, 4'ha, "Typed port declaration list shadowing value mismatch");
`check($bits(d_p_tn), 4, "non-ANSI input T T did not keep typedef type");
`check(d_p_tn_ok, 1'b1, "non-ANSI input T T was not available as a typed port");
if (!failed) begin
$display("PASSED");
end
end
endmodule

View File

@ -0,0 +1,120 @@
// Check that task and function argument names can shadow visible type identifiers.
typedef int T;
module test;
reg failed;
`define check(value, expected, error) \
if ((value) !== (expected)) begin \
$display("FAILED(%0d). %s", `__LINE__, error); \
$display(" expected %0h, got %0h", expected, value); \
failed = 1'b1; \
end
function int f_name(input T);
return ($bits(T) == 1 && T === 1'b1) ? 32'd33 : -1;
endfunction
function int f_type(input T value);
return ($bits(value) == 32) ? value : -1;
endfunction
function int f_type_list(input T value, T);
return $bits(value) + $bits(T);
endfunction
function int f_type_name(input T T);
return $bits(T);
endfunction
function int f_decl_name;
input T;
return $bits(T);
endfunction
function int f_decl_type;
input T value;
return $bits(value);
endfunction
function int f_decl_type_name;
input T T;
return $bits(T);
endfunction
task t_name(input T, output int value);
value = ($bits(T) == 1 && T === 1'b1) ? 32'd44 : -1;
endtask
task t_type(input T value, output int result);
result = ($bits(value) == 32) ? value : -1;
endtask
task t_type_list(input T value, T, output int result);
result = $bits(value) + $bits(T);
endtask
task t_type_name(input T T, output int value);
value = $bits(T);
endtask
task t_decl_name;
input T;
output int value;
value = $bits(T);
endtask
task t_decl_type;
input T value;
output int result;
result = $bits(value);
endtask
task t_decl_type_name;
input T T;
output int value;
value = $bits(T);
endtask
initial begin
int r0;
int r1;
int r2;
int r3;
int r4;
int r5;
int r6;
failed = 1'b0;
t_name(1'b1, r0);
t_type(32'd55, r1);
t_type_list(32'd11, 32'd22, r2);
t_decl_name(1'b1, r3);
t_decl_type(32'd33, r4);
t_type_name(32'd44, r5);
t_decl_type_name(32'd55, r6);
`check(f_name(1'b1), 32'd33, "Function argument did not hide typedef");
`check(f_type(32'd66), 32'd66, "Function typed argument regressed");
`check(f_type_list(32'd11, 32'd22), 64, "Function typed argument list shadowing mismatch");
`check(f_type_name(32'd33), 32, "Function type-name argument did not keep typedef type");
`check(f_decl_name(1'b1), 1, "Function non-ANSI argument did not hide typedef");
`check(f_decl_type(32'd66), 32, "Function non-ANSI typed argument regressed");
`check(f_decl_type_name(32'd77), 32, "Function non-ANSI type-name argument did not keep typedef type");
`check(r0, 32'd44, "Task argument did not hide typedef");
`check(r1, 32'd55, "Task typed argument regressed");
`check(r2, 64, "Task typed argument list shadowing mismatch");
`check(r3, 1, "Task non-ANSI argument did not hide typedef");
`check(r4, 32, "Task non-ANSI typed argument regressed");
`check(r5, 32, "Task type-name argument did not keep typedef type");
`check(r6, 32, "Task non-ANSI type-name argument did not keep typedef type");
if (!failed) begin
$display("PASSED");
end
end
endmodule

View File

@ -0,0 +1,152 @@
// Check that variable names can shadow visible type identifiers.
typedef logic [7:0] T;
typedef int V;
typedef int W;
typedef logic [6:0] A;
typedef logic [5:0] B;
typedef logic [4:0] C;
typedef logic [3:0] D;
typedef logic [2:0] E;
typedef logic [1:0] F;
typedef logic [2:0] G;
typedef logic [3:0] H;
typedef logic [4:0] I;
typedef logic [2:0] P;
bit X;
package p;
var C;
var D x, D;
var P P;
endpackage
module test;
reg failed;
`define check(value, expected, error) \
if ((value) !== (expected)) begin \
$display("FAILED(%0d). %s", `__LINE__, error); \
$display(" expected %0h, got %0h", expected, value); \
failed = 1'b1; \
end
typedef logic [3:0] X;
T outer;
T a, b;
A a0, A;
E E;
int T, U;
var V;
var B b0, B;
var F F;
X x;
function int f;
int T;
T = 32'd11;
return T;
endfunction
function int f_type_name;
H H;
H = 4'ha;
return $bits(H) + H;
endfunction
task t(output int value);
int T;
T = 32'd22;
value = T;
endtask
task t_type_name(output int value);
I I;
I = 5'h15;
value = $bits(I) + I;
endtask
initial begin
int r;
int r_type_name;
int tr_type_name;
var W;
failed = 1'b0;
outer = 8'ha5;
a = 8'h33;
b = 8'hcc;
a0 = 7'h2a;
A = 7'h15;
E = 3'h5;
T = 32'd23;
U = 32'd41;
V = 1'b1;
b0 = 6'h2a;
B = 6'h15;
F = 2'h2;
W = 1'b0;
x = 4'hc;
t(r);
t_type_name(tr_type_name);
begin : block_scope
int T;
T = 32'd7;
`check(T, 32'd7, "Block declaration did not hide typedef");
end
begin : block_type_name
G G;
G = 3'h3;
`check($bits(G), 3, "Block type-name declaration did not keep typedef type");
`check(G, 3'h3, "Block type-name declaration value mismatch");
end
r_type_name = f_type_name();
`check(outer, 8'ha5, "Typedef value changed");
`check(T, 32'd23, "Module declaration did not hide typedef");
`check(U, 32'd41, "Declaration list continuation mismatch");
`check($bits(V), 1, "Module var declaration did not hide typedef width");
`check(V, 1'b1, "Module var declaration did not hide typedef value");
`check($bits(W), 1, "Block var declaration did not hide typedef width");
`check(W, 1'b0, "Block var declaration did not hide typedef value");
`check(a, 8'h33, "Type declaration list first value mismatch");
`check(b, 8'hcc, "Type declaration list continuation mismatch");
`check($bits(a0), 7, "Type declaration list did not keep typedef type");
`check($bits(A), 7, "Type declaration list did not allow typedef name as continuation");
`check(A, 7'h15, "Type declaration list shadowing value mismatch");
`check($bits(E), 3, "Type-name declaration did not keep typedef type");
`check(E, 3'h5, "Type-name declaration value mismatch");
`check($bits(b0), 6, "Var declaration list did not keep typedef type");
`check($bits(B), 6, "Var declaration list did not allow typedef name as continuation");
`check(B, 6'h15, "Var declaration list shadowing value mismatch");
`check($bits(F), 2, "Var type-name declaration did not keep typedef type");
`check(F, 2'h2, "Var type-name declaration value mismatch");
`check($bits(p::C), 1, "Package var declaration did not hide typedef width");
`check($bits(p::x), 4, "Package type declaration list first width mismatch");
`check($bits(p::D), 4, "Package type declaration list did not allow typedef name as continuation");
`check($bits(p::P), 3, "Package type-name declaration did not keep typedef type");
`check(f(), 32'd11, "Function declaration did not hide typedef");
`check(r_type_name, 14, "Function type-name declaration mismatch");
`check(r, 32'd22, "Task declaration did not hide typedef");
`check(tr_type_name, 26, "Task type-name declaration mismatch");
`check($bits(x), 4, "Local typedef did not hide outer identifier");
`check(x, 4'hc, "Local typedef value mismatch");
if (!failed) begin
$display("PASSED");
end
end
endmodule

View File

@ -385,8 +385,12 @@ sv_type_identifier_foreach_name vvp_tests/sv_type_identifier_foreach_name.json
sv_type_identifier_genvar_name vvp_tests/sv_type_identifier_genvar_name.json
sv_type_identifier_modport_name vvp_tests/sv_type_identifier_modport_name.json
sv_type_identifier_module_name vvp_tests/sv_type_identifier_module_name.json
sv_type_identifier_net_name vvp_tests/sv_type_identifier_net_name.json
sv_type_identifier_package_item vvp_tests/sv_type_identifier_package_item.json
sv_type_identifier_port_name vvp_tests/sv_type_identifier_port_name.json
sv_type_identifier_specparam_name vvp_tests/sv_type_identifier_specparam_name.json
sv_type_identifier_task_function_argument_name vvp_tests/sv_type_identifier_task_function_argument_name.json
sv_type_identifier_variable_name vvp_tests/sv_type_identifier_variable_name.json
sv_type_param_restrict_class1 vvp_tests/sv_type_param_restrict_class1.json
sv_type_param_restrict_class2 vvp_tests/sv_type_param_restrict_class2.json
sv_type_param_restrict_class_fail1 vvp_tests/sv_type_param_restrict_class_fail1.json

View File

@ -0,0 +1,9 @@
{
"type" : "normal",
"source" : "sv_type_identifier_net_name.v",
"iverilog-args" : [ "-g2005-sv" ],
"vlog95" : {
"__comment" : "Typedefs and SystemVerilog net types are SystemVerilog",
"type" : "CE"
}
}

View File

@ -0,0 +1,9 @@
{
"type" : "normal",
"source" : "sv_type_identifier_port_name.v",
"iverilog-args" : [ "-g2005-sv" ],
"vlog95" : {
"__comment" : "Typedefs and ANSI ports are SystemVerilog",
"type" : "CE"
}
}

View File

@ -0,0 +1,9 @@
{
"type" : "normal",
"source" : "sv_type_identifier_task_function_argument_name.v",
"iverilog-args" : [ "-g2005-sv" ],
"vlog95" : {
"__comment" : "Typedefs and task/function arguments are SystemVerilog",
"type" : "CE"
}
}

View File

@ -0,0 +1,9 @@
{
"type" : "normal",
"source" : "sv_type_identifier_variable_name.v",
"iverilog-args" : [ "-g2005-sv" ],
"vlog95" : {
"__comment" : "Typedefs and block/task scope are SystemVerilog",
"type" : "CE"
}
}

619
parse.y

File diff suppressed because it is too large Load Diff

View File

@ -510,4 +510,9 @@ extern std::ostream& operator<< (std::ostream&out, const name_component_t&that);
extern std::ostream& operator<< (std::ostream&out, const index_component_t&that);
extern std::ostream& operator<< (std::ostream&out, const type_restrict_t& type);
struct pform_port_list {
std::list<pform_port_t> *ports;
data_type_t *type;
};
#endif /* IVL_pform_types_H */