Add regression tests for prefix labels on procedural blocks

Check the reproducer from GitHub issue #1321, which uses a prefix label on a
begin-end block inside an `always_comb` process.

Check prefix labels on sequential and parallel blocks. Place attributes between
the labels and block keywords, verify that the sequential label creates a named
scope, cover all fork join types, and use matching closing labels.

Check separately that visible type identifiers can be shadowed by prefix labels
on sequential and parallel blocks.

Check that matching and different block names after `begin` or `fork` are
rejected when a prefix label is already present.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
Lars-Peter Clausen 2026-07-18 11:23:03 -07:00
parent fd902d1501
commit 9c56f0172d
19 changed files with 223 additions and 0 deletions

View File

@ -0,0 +1,18 @@
module test;
logic a;
always_comb begin
my_blk: begin
a = 1'b1;
end
end
initial begin
#1;
if (a !== 1'b1) begin
$display("FAILED(%0d). Expected 1, got %b", `__LINE__, a);
end else begin
$display("PASSED");
end
end
endmodule

View File

@ -0,0 +1,29 @@
// Check that sequential block prefix labels work.
module test;
reg failed;
reg value;
initial begin
failed = 1'b0;
value = 1'b0;
BLOCK_LABEL: (* keep = 1 *) begin
value = 1'b1;
disable BLOCK_LABEL;
value = 1'b0;
end : BLOCK_LABEL
if (value !== 1'b1) begin
$display("FAILED(%0d). Block prefix label did not create a named scope",
`__LINE__);
failed = 1'b1;
end
if (!failed) begin
$display("PASSED");
end
end
endmodule

View File

@ -0,0 +1,6 @@
// Check that different prefix and post-begin labels are rejected.
module test;
initial LABEL_A: begin : LABEL_B
end
endmodule

View File

@ -0,0 +1,6 @@
// Check that matching prefix and post-begin labels are rejected.
module test;
initial LABEL: begin : LABEL
end
endmodule

View File

@ -0,0 +1,36 @@
// Check that fork prefix labels work with all join types.
module test;
reg failed;
reg [2:0] value;
initial begin
failed = 1'b0;
value = 3'b000;
FORK_LABEL: (* keep = 1 *) fork
value[0] = 1'b1;
join : FORK_LABEL
FORK_ANY_LABEL: (* keep = 1 *) fork
value[1] = 1'b1;
join_any : FORK_ANY_LABEL
FORK_NONE_LABEL: (* keep = 1 *) fork
value[2] = 1'b1;
join_none : FORK_NONE_LABEL
wait fork;
if (value !== 3'b111) begin
$display("FAILED(%0d). Fork prefix labels did not execute all blocks",
`__LINE__);
failed = 1'b1;
end
if (!failed) begin
$display("PASSED");
end
end
endmodule

View File

@ -0,0 +1,6 @@
// Check that different prefix and post-fork labels are rejected.
module test;
initial LABEL_A: fork : LABEL_B
join
endmodule

View File

@ -0,0 +1,6 @@
// Check that matching prefix and post-fork labels are rejected.
module test;
initial LABEL: fork : LABEL
join
endmodule

View File

@ -0,0 +1,29 @@
// Check that sequential block prefix labels can shadow type identifiers.
typedef int T;
module test;
reg failed;
reg value;
initial begin
failed = 1'b0;
value = 1'b0;
T: begin
value = 1'b1;
end : T
if (value !== 1'b1) begin
$display("FAILED(%0d). Block prefix label did not hide typedef",
`__LINE__);
failed = 1'b1;
end
if (!failed) begin
$display("PASSED");
end
end
endmodule

View File

@ -0,0 +1,29 @@
// Check that fork prefix labels can shadow type identifiers.
typedef int T;
module test;
reg failed;
reg value;
initial begin
failed = 1'b0;
value = 1'b0;
T: fork
value = 1'b1;
join : T
if (value !== 1'b1) begin
$display("FAILED(%0d). Fork prefix label did not hide typedef",
`__LINE__);
failed = 1'b1;
end
if (!failed) begin
$display("PASSED");
end
end
endmodule

View File

@ -82,6 +82,7 @@ br_gh1256b vvp_tests/br_gh1256b.json
br_gh1258a vvp_tests/br_gh1258a.json
br_gh1258b vvp_tests/br_gh1258b.json
br_gh1286 vvp_tests/br_gh1286.json
br_gh1321 vvp_tests/br_gh1321.json
br_gh1323 vvp_tests/br_gh1323.json
br_gh1384 vvp_tests/br_gh1384.json
br_gh1385 vvp_tests/br_gh1385.json
@ -264,6 +265,9 @@ sv_array_cassign_single_fail1 vvp_tests/sv_array_cassign_single_fail1.json
sv_assign_pattern_auto_force_fail vvp_tests/sv_assign_pattern_auto_force_fail.json
sv_automatic_2state vvp_tests/sv_automatic_2state.json
sv_bad_member_lval_proc_fail vvp_tests/sv_bad_member_lval_proc_fail.json
sv_block_prefix_label vvp_tests/sv_block_prefix_label.json
sv_block_prefix_name_diff_fail vvp_tests/sv_block_prefix_name_diff_fail.json
sv_block_prefix_name_same_fail vvp_tests/sv_block_prefix_name_same_fail.json
sv_byte_array_string1 vvp_tests/sv_byte_array_string1.json
sv_byte_array_string2 vvp_tests/sv_byte_array_string2.json
sv_byte_array_string3 vvp_tests/sv_byte_array_string3.json
@ -315,6 +319,9 @@ sv_default_port_value2 vvp_tests/sv_default_port_value2.json
sv_default_port_value3 vvp_tests/sv_default_port_value3.json
sv_foreach9 vvp_tests/sv_foreach9.json
sv_foreach10 vvp_tests/sv_foreach10.json
sv_fork_prefix_label vvp_tests/sv_fork_prefix_label.json
sv_fork_prefix_name_diff_fail vvp_tests/sv_fork_prefix_name_diff_fail.json
sv_fork_prefix_name_same_fail vvp_tests/sv_fork_prefix_name_same_fail.json
sv_interface vvp_tests/sv_interface.json
sv_interface_identifier_block_name vvp_tests/sv_interface_identifier_block_name.json
sv_interface_identifier_instance_name vvp_tests/sv_interface_identifier_instance_name.json
@ -411,6 +418,7 @@ sv_type_identifier_assert_label vvp_tests/sv_type_identifier_assert_label.json
sv_type_identifier_attribute_name vvp_tests/sv_type_identifier_attribute_name.json
sv_type_identifier_attribute_target vvp_tests/sv_type_identifier_attribute_target.json
sv_type_identifier_block_label_name vvp_tests/sv_type_identifier_block_label_name.json
sv_type_identifier_block_prefix_label_name vvp_tests/sv_type_identifier_block_prefix_label_name.json
sv_type_identifier_config_name vvp_tests/sv_type_identifier_config_name.json
sv_type_identifier_discipline_name vvp_tests/sv_type_identifier_discipline_name.json
sv_type_identifier_discipline_nature_ref vvp_tests/sv_type_identifier_discipline_nature_ref.json
@ -420,6 +428,7 @@ sv_type_identifier_for_name vvp_tests/sv_type_identifier_for_name.json
sv_type_identifier_foreach_array_name vvp_tests/sv_type_identifier_foreach_array_name.json
sv_type_identifier_foreach_name vvp_tests/sv_type_identifier_foreach_name.json
sv_type_identifier_fork_label_name vvp_tests/sv_type_identifier_fork_label_name.json
sv_type_identifier_fork_prefix_label_name vvp_tests/sv_type_identifier_fork_prefix_label_name.json
sv_type_identifier_function_name vvp_tests/sv_type_identifier_function_name.json
sv_type_identifier_generate_label_name vvp_tests/sv_type_identifier_generate_label_name.json
sv_type_identifier_genvar_name vvp_tests/sv_type_identifier_genvar_name.json

View File

@ -0,0 +1,5 @@
{
"type" : "normal",
"source" : "br_gh1321.v",
"iverilog-args" : [ "-g2005-sv" ]
}

View File

@ -0,0 +1,5 @@
{
"type" : "normal",
"source" : "sv_block_prefix_label.v",
"iverilog-args" : [ "-g2005-sv" ]
}

View File

@ -0,0 +1,5 @@
{
"type" : "CE",
"source" : "sv_block_prefix_name_diff_fail.v",
"iverilog-args" : [ "-g2005-sv" ]
}

View File

@ -0,0 +1,5 @@
{
"type" : "CE",
"source" : "sv_block_prefix_name_same_fail.v",
"iverilog-args" : [ "-g2005-sv" ]
}

View File

@ -0,0 +1,9 @@
{
"type" : "normal",
"source" : "sv_fork_prefix_label.v",
"iverilog-args" : [ "-g2005-sv" ],
"vlog95" : {
"__comment" : "join_any, join_none, and wait fork are not supported",
"type" : "CE"
}
}

View File

@ -0,0 +1,5 @@
{
"type" : "CE",
"source" : "sv_fork_prefix_name_diff_fail.v",
"iverilog-args" : [ "-g2005-sv" ]
}

View File

@ -0,0 +1,5 @@
{
"type" : "CE",
"source" : "sv_fork_prefix_name_same_fail.v",
"iverilog-args" : [ "-g2005-sv" ]
}

View File

@ -0,0 +1,5 @@
{
"type" : "normal",
"source" : "sv_type_identifier_block_prefix_label_name.v",
"iverilog-args" : [ "-g2005-sv" ]
}

View File

@ -0,0 +1,5 @@
{
"type" : "normal",
"source" : "sv_type_identifier_fork_prefix_label_name.v",
"iverilog-args" : [ "-g2005-sv" ]
}