Merge pull request #1445 from larsclausen/procedural-block-prefix-label
Support prefix labels on procedural blocks
This commit is contained in:
commit
31d1850bc8
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
// Check that different prefix and post-begin labels are rejected.
|
||||||
|
|
||||||
|
module test;
|
||||||
|
initial LABEL_A: begin : LABEL_B
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
// Check that matching prefix and post-begin labels are rejected.
|
||||||
|
|
||||||
|
module test;
|
||||||
|
initial LABEL: begin : LABEL
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -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
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
// Check that different prefix and post-fork labels are rejected.
|
||||||
|
|
||||||
|
module test;
|
||||||
|
initial LABEL_A: fork : LABEL_B
|
||||||
|
join
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
// Check that matching prefix and post-fork labels are rejected.
|
||||||
|
|
||||||
|
module test;
|
||||||
|
initial LABEL: fork : LABEL
|
||||||
|
join
|
||||||
|
endmodule
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -82,6 +82,7 @@ br_gh1256b vvp_tests/br_gh1256b.json
|
||||||
br_gh1258a vvp_tests/br_gh1258a.json
|
br_gh1258a vvp_tests/br_gh1258a.json
|
||||||
br_gh1258b vvp_tests/br_gh1258b.json
|
br_gh1258b vvp_tests/br_gh1258b.json
|
||||||
br_gh1286 vvp_tests/br_gh1286.json
|
br_gh1286 vvp_tests/br_gh1286.json
|
||||||
|
br_gh1321 vvp_tests/br_gh1321.json
|
||||||
br_gh1323 vvp_tests/br_gh1323.json
|
br_gh1323 vvp_tests/br_gh1323.json
|
||||||
br_gh1384 vvp_tests/br_gh1384.json
|
br_gh1384 vvp_tests/br_gh1384.json
|
||||||
br_gh1385 vvp_tests/br_gh1385.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_assign_pattern_auto_force_fail vvp_tests/sv_assign_pattern_auto_force_fail.json
|
||||||
sv_automatic_2state vvp_tests/sv_automatic_2state.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_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_string1 vvp_tests/sv_byte_array_string1.json
|
||||||
sv_byte_array_string2 vvp_tests/sv_byte_array_string2.json
|
sv_byte_array_string2 vvp_tests/sv_byte_array_string2.json
|
||||||
sv_byte_array_string3 vvp_tests/sv_byte_array_string3.json
|
sv_byte_array_string3 vvp_tests/sv_byte_array_string3.json
|
||||||
|
|
@ -320,6 +324,9 @@ sv_default_port_value2 vvp_tests/sv_default_port_value2.json
|
||||||
sv_default_port_value3 vvp_tests/sv_default_port_value3.json
|
sv_default_port_value3 vvp_tests/sv_default_port_value3.json
|
||||||
sv_foreach9 vvp_tests/sv_foreach9.json
|
sv_foreach9 vvp_tests/sv_foreach9.json
|
||||||
sv_foreach10 vvp_tests/sv_foreach10.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 vvp_tests/sv_interface.json
|
||||||
sv_interface_identifier_block_name vvp_tests/sv_interface_identifier_block_name.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
|
sv_interface_identifier_instance_name vvp_tests/sv_interface_identifier_instance_name.json
|
||||||
|
|
@ -420,6 +427,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_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_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_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_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_name vvp_tests/sv_type_identifier_discipline_name.json
|
||||||
sv_type_identifier_discipline_nature_ref vvp_tests/sv_type_identifier_discipline_nature_ref.json
|
sv_type_identifier_discipline_nature_ref vvp_tests/sv_type_identifier_discipline_nature_ref.json
|
||||||
|
|
@ -429,6 +437,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_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_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_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_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_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
|
sv_type_identifier_genvar_name vvp_tests/sv_type_identifier_genvar_name.json
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"type" : "normal",
|
||||||
|
"source" : "br_gh1321.v",
|
||||||
|
"iverilog-args" : [ "-g2005-sv" ]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"type" : "normal",
|
||||||
|
"source" : "sv_block_prefix_label.v",
|
||||||
|
"iverilog-args" : [ "-g2005-sv" ]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"type" : "CE",
|
||||||
|
"source" : "sv_block_prefix_name_diff_fail.v",
|
||||||
|
"iverilog-args" : [ "-g2005-sv" ]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"type" : "CE",
|
||||||
|
"source" : "sv_block_prefix_name_same_fail.v",
|
||||||
|
"iverilog-args" : [ "-g2005-sv" ]
|
||||||
|
}
|
||||||
|
|
@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"type" : "CE",
|
||||||
|
"source" : "sv_fork_prefix_name_diff_fail.v",
|
||||||
|
"iverilog-args" : [ "-g2005-sv" ]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"type" : "CE",
|
||||||
|
"source" : "sv_fork_prefix_name_same_fail.v",
|
||||||
|
"iverilog-args" : [ "-g2005-sv" ]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"type" : "normal",
|
||||||
|
"source" : "sv_type_identifier_block_prefix_label_name.v",
|
||||||
|
"iverilog-args" : [ "-g2005-sv" ]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"type" : "normal",
|
||||||
|
"source" : "sv_type_identifier_fork_prefix_label_name.v",
|
||||||
|
"iverilog-args" : [ "-g2005-sv" ]
|
||||||
|
}
|
||||||
153
parse.y
153
parse.y
|
|
@ -594,6 +594,71 @@ static void procedural_item_list_add_declaration(const YYLTYPE&loc,
|
||||||
procedural_item_list_add_ports(list, ports);
|
procedural_item_list_add_ports(list, ports);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PBlock *pform_start_block(const YYLTYPE&loc, const char *name,
|
||||||
|
PBlock::BL_TYPE block_type)
|
||||||
|
{
|
||||||
|
auto block = pform_push_block_scope(loc, name, block_type);
|
||||||
|
current_block_stack.push(block);
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *pform_start_block_with_labels(
|
||||||
|
const YYLTYPE&loc, const YYLTYPE&name_loc,
|
||||||
|
char *prefix_label, char *block_name,
|
||||||
|
std::list<named_pexpr_t> *attributes,
|
||||||
|
PBlock::BL_TYPE block_type)
|
||||||
|
{
|
||||||
|
std::unique_ptr<char[]> prefix_label_ptr(prefix_label);
|
||||||
|
std::unique_ptr<char[]> block_name_ptr(block_name);
|
||||||
|
|
||||||
|
if (prefix_label_ptr && block_name_ptr) {
|
||||||
|
yyerror(name_loc,
|
||||||
|
"error: A block cannot have both a prefix label and a block name.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *name = block_name_ptr ? block_name_ptr.get()
|
||||||
|
: prefix_label_ptr.get();
|
||||||
|
auto block = pform_start_block(loc, name, block_type);
|
||||||
|
pform_bind_attributes(block->attributes, attributes);
|
||||||
|
|
||||||
|
return block_name_ptr ? block_name_ptr.release()
|
||||||
|
: prefix_label_ptr.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
static PBlock *pform_finish_block(const YYLTYPE&block_loc,
|
||||||
|
const YYLTYPE&end_loc, const char *type,
|
||||||
|
char *raw_name, char *end_label,
|
||||||
|
PBlock::BL_TYPE block_type,
|
||||||
|
procedural_item_list_t *raw_items)
|
||||||
|
{
|
||||||
|
std::unique_ptr<char[]> name_ptr(raw_name);
|
||||||
|
std::unique_ptr<procedural_item_list_t> items(raw_items);
|
||||||
|
|
||||||
|
const char *name = name_ptr.get();
|
||||||
|
bool keep_scope = name || items->has_decls;
|
||||||
|
pform_pop_block_scope(keep_scope);
|
||||||
|
assert(! current_block_stack.empty());
|
||||||
|
auto block = current_block_stack.top();
|
||||||
|
current_block_stack.pop();
|
||||||
|
|
||||||
|
if (keep_scope) {
|
||||||
|
if (block_type != PBlock::BL_SEQ)
|
||||||
|
block->set_join_type(block_type);
|
||||||
|
} else {
|
||||||
|
delete block;
|
||||||
|
block = new PBlock(block_type);
|
||||||
|
FILE_NAME(block, block_loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (items->statements)
|
||||||
|
block->set_statement(*items->statements);
|
||||||
|
|
||||||
|
check_end_label(end_loc, type, name, end_label);
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
static void port_declaration_context_init(void)
|
static void port_declaration_context_init(void)
|
||||||
{
|
{
|
||||||
port_declaration_context.port_type = NetNet::PINOUT;
|
port_declaration_context.port_type = NetNet::PINOUT;
|
||||||
|
|
@ -756,6 +821,11 @@ Module::port_t *module_declare_interface_port(const YYLTYPE&loc, char *type,
|
||||||
std::vector<Statement*>*statement_list;
|
std::vector<Statement*>*statement_list;
|
||||||
struct procedural_item_list_t *procedural_item_list;
|
struct procedural_item_list_t *procedural_item_list;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
char *label;
|
||||||
|
std::list<named_pexpr_t> *attributes;
|
||||||
|
} block_prefix;
|
||||||
|
|
||||||
decl_assignment_t*decl_assignment;
|
decl_assignment_t*decl_assignment;
|
||||||
std::list<decl_assignment_t*>*decl_assignments;
|
std::list<decl_assignment_t*>*decl_assignments;
|
||||||
|
|
||||||
|
|
@ -1046,6 +1116,8 @@ Module::port_t *module_declare_interface_port(const YYLTYPE&loc, char *type,
|
||||||
%type <procedural_item_list> block_item_or_statement_list_opt
|
%type <procedural_item_list> block_item_or_statement_list_opt
|
||||||
%type <procedural_item_list> tf_item_or_statement_list
|
%type <procedural_item_list> tf_item_or_statement_list
|
||||||
%type <procedural_item_list> tf_item_or_statement_list_opt
|
%type <procedural_item_list> tf_item_or_statement_list_opt
|
||||||
|
%type <block_prefix> block_prefix_opt
|
||||||
|
%type <text> sequential_block_start parallel_block_start
|
||||||
|
|
||||||
%type <statement> analog_statement
|
%type <statement> analog_statement
|
||||||
|
|
||||||
|
|
@ -7292,6 +7364,34 @@ subroutine_call
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
block_prefix_opt
|
||||||
|
: /* empty */
|
||||||
|
{ $$.label = nullptr;
|
||||||
|
$$.attributes = nullptr;
|
||||||
|
}
|
||||||
|
| identifier_name ':' attribute_list_opt
|
||||||
|
{ pform_requires_sv(@1, "Block prefix label");
|
||||||
|
$$.label = $1;
|
||||||
|
$$.attributes = $3;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
sequential_block_start
|
||||||
|
: block_prefix_opt K_begin label_opt
|
||||||
|
{ $$ = pform_start_block_with_labels(@2, @3, $1.label, $3,
|
||||||
|
$1.attributes, PBlock::BL_SEQ);
|
||||||
|
@$ = @2;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
parallel_block_start
|
||||||
|
: block_prefix_opt K_fork label_opt
|
||||||
|
{ $$ = pform_start_block_with_labels(@2, @3, $1.label, $3,
|
||||||
|
$1.attributes, PBlock::BL_PAR);
|
||||||
|
@$ = @2;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
statement_item /* This is roughly statement_item in the LRM */
|
statement_item /* This is roughly statement_item in the LRM */
|
||||||
|
|
||||||
/* assign and deassign statements are procedural code to do
|
/* assign and deassign statements are procedural code to do
|
||||||
|
|
@ -7333,29 +7433,12 @@ statement_item /* This is roughly statement_item in the LRM */
|
||||||
the declarations. The scope is popped at the end of the block. */
|
the declarations. The scope is popped at the end of the block. */
|
||||||
|
|
||||||
/* In SystemVerilog an unnamed block can contain variable declarations. */
|
/* In SystemVerilog an unnamed block can contain variable declarations. */
|
||||||
| K_begin label_opt
|
| sequential_block_start block_item_or_statement_list_opt K_end label_opt
|
||||||
{ PBlock*tmp = pform_push_block_scope(@1, $2, PBlock::BL_SEQ);
|
{ if (!$1 && $2->has_decls) {
|
||||||
current_block_stack.push(tmp);
|
|
||||||
}
|
|
||||||
block_item_or_statement_list_opt K_end label_opt
|
|
||||||
{ std::unique_ptr<procedural_item_list_t> items($4);
|
|
||||||
if (!$2 && items->has_decls) {
|
|
||||||
pform_block_decls_requires_sv();
|
pform_block_decls_requires_sv();
|
||||||
}
|
}
|
||||||
bool keep_scope = $2 || items->has_decls;
|
$$ = pform_finish_block(@1, @4, "block", $1, $4,
|
||||||
pform_pop_block_scope(keep_scope);
|
PBlock::BL_SEQ, $2);
|
||||||
assert(! current_block_stack.empty());
|
|
||||||
auto tmp = current_block_stack.top();
|
|
||||||
current_block_stack.pop();
|
|
||||||
if (!keep_scope) {
|
|
||||||
delete tmp;
|
|
||||||
tmp = new PBlock(PBlock::BL_SEQ);
|
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
}
|
|
||||||
if (items->statements) tmp->set_statement(*items->statements);
|
|
||||||
check_end_label(@6, "block", $2, $6);
|
|
||||||
delete[]$2;
|
|
||||||
$$ = tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fork-join blocks are very similar to begin-end blocks. In fact,
|
/* fork-join blocks are very similar to begin-end blocks. In fact,
|
||||||
|
|
@ -7364,31 +7447,11 @@ statement_item /* This is roughly statement_item in the LRM */
|
||||||
code generator can do the right thing. */
|
code generator can do the right thing. */
|
||||||
|
|
||||||
/* In SystemVerilog an unnamed block can contain variable declarations. */
|
/* In SystemVerilog an unnamed block can contain variable declarations. */
|
||||||
| K_fork label_opt
|
| parallel_block_start block_item_or_statement_list_opt join_keyword label_opt
|
||||||
{ PBlock*tmp = pform_push_block_scope(@1, $2, PBlock::BL_PAR);
|
{ if (!$1 && $2->has_decls) {
|
||||||
current_block_stack.push(tmp);
|
pform_requires_sv(@2, "Variable declaration in unnamed block");
|
||||||
}
|
|
||||||
block_item_or_statement_list_opt join_keyword label_opt
|
|
||||||
{ std::unique_ptr<procedural_item_list_t> items($4);
|
|
||||||
if (!$2 && items->has_decls) {
|
|
||||||
pform_requires_sv(@4, "Variable declaration in unnamed block");
|
|
||||||
}
|
}
|
||||||
bool keep_scope = $2 || items->has_decls;
|
$$ = pform_finish_block(@1, @4, "fork", $1, $4, $3, $2);
|
||||||
pform_pop_block_scope(keep_scope);
|
|
||||||
assert(! current_block_stack.empty());
|
|
||||||
auto tmp = current_block_stack.top();
|
|
||||||
current_block_stack.pop();
|
|
||||||
if (keep_scope) {
|
|
||||||
tmp->set_join_type($5);
|
|
||||||
} else {
|
|
||||||
delete tmp;
|
|
||||||
tmp = new PBlock($5);
|
|
||||||
FILE_NAME(tmp, @1);
|
|
||||||
}
|
|
||||||
if (items->statements) tmp->set_statement(*items->statements);
|
|
||||||
check_end_label(@6, "fork", $2, $6);
|
|
||||||
delete[]$2;
|
|
||||||
$$ = tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
| K_disable hierarchy_identifier ';'
|
| K_disable hierarchy_identifier ';'
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue