diff --git a/parse.y b/parse.y index 9a0a5df2d..c4c3b5585 100644 --- a/parse.y +++ b/parse.y @@ -575,6 +575,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector %type udp_initial_expr_opt %type register_variable net_variable event_variable endlabel_opt class_declaration_endlabel_opt +%type block_identifier_opt %type register_variable_list net_variable_list event_variable_list %type list_of_identifiers loop_variables %type list_of_port_identifiers list_of_variable_port_identifiers @@ -652,6 +653,9 @@ static void current_function_set_statement(const YYLTYPE&loc, vector %type statement statement_item statement_or_null %type compressed_statement %type loop_statement for_step jump_statement +%type concurrent_assertion_statement +%type deferred_immediate_assertion_statement +%type simple_immediate_assertion_statement %type procedural_assertion_statement %type statement_or_null_list statement_or_null_list_opt @@ -667,6 +671,7 @@ static void current_function_set_statement(const YYLTYPE&loc, vector %type non_integer_type %type assert_or_assume +%type deferred_mode %type atom2_type %type module_start module_end @@ -724,6 +729,7 @@ assert_or_assume assertion_item /* IEEE1800-2012: A.6.10 */ : concurrent_assertion_item + | deferred_immediate_assertion_item ; assignment_pattern /* IEEE1800-2005: A.6.7.1 */ @@ -744,7 +750,9 @@ assignment_pattern /* IEEE1800-2005: A.6.7.1 */ implements it in a LALR way. */ block_identifier_opt /* */ : IDENTIFIER ':' + { $$ = $1; } | + { $$ = 0; } ; class_declaration /* IEEE1800-2005: A.1.2 */ @@ -988,16 +996,92 @@ class_new /* IEEE1800-2005 A.2.4 */ concurrent_assertion_statement and checker_instantiation rules. */ concurrent_assertion_item /* IEEE1800-2012 A.2.10 */ - : block_identifier_opt K_assert K_property '(' property_spec ')' statement_or_null + : block_identifier_opt concurrent_assertion_statement + { delete $1; + delete $2; + } + ; + +concurrent_assertion_statement /* IEEE1800-2012 A.2.10 */ + : assert_or_assume K_property '(' property_spec ')' statement_or_null %prec less_than_K_else + { /* */ + if (gn_assertions_flag) { + yyerror(@1, "sorry: concurrent_assertion_item not supported." + " Try -gno-assertion to turn this message off."); + } + $$ = 0; + } + | assert_or_assume K_property '(' property_spec ')' K_else statement_or_null + { /* */ + if (gn_assertions_flag) { + yyerror(@1, "sorry: concurrent_assertion_item not supported." + " Try -gno-assertion to turn this message off."); + } + $$ = 0; + } + | assert_or_assume K_property '(' property_spec ')' statement_or_null K_else statement_or_null + { /* */ + if (gn_assertions_flag) { + yyerror(@1, "sorry: concurrent_assertion_item not supported." + " Try -gno-assertion to turn this message off."); + } + $$ = 0; + } + | K_cover K_property '(' property_spec ')' statement_or_null + { /* */ + if (gn_assertions_flag) { + yyerror(@1, "sorry: concurrent_assertion_item not supported." + " Try -gno-assertion to turn this message off."); + } + $$ = 0; + } + /* For now, cheat, and use property_spec for the sequence specification. + They are syntactically identical. */ + | K_cover K_sequence '(' property_spec ')' statement_or_null + { /* */ + if (gn_assertions_flag) { + yyerror(@1, "sorry: concurrent_assertion_item not supported." + " Try -gno-assertion to turn this message off."); + } + $$ = 0; + } + | K_restrict K_property '(' property_spec ')' ';' { /* */ if (gn_assertions_flag) { yyerror(@2, "sorry: concurrent_assertion_item not supported." " Try -gno-assertion to turn this message off."); } + $$ = 0; } - | block_identifier_opt K_assert K_property '(' error ')' statement_or_null + | assert_or_assume K_property '(' error ')' statement_or_null %prec less_than_K_else { yyerrok; yyerror(@2, "error: Error in property_spec of concurrent assertion item."); + $$ = 0; + } + | assert_or_assume K_property '(' error ')' K_else statement_or_null + { yyerrok; + yyerror(@2, "error: Error in property_spec of concurrent assertion item."); + $$ = 0; + } + | assert_or_assume K_property '(' error ')' statement_or_null K_else statement_or_null + { yyerrok; + yyerror(@2, "error: Error in property_spec of concurrent assertion item."); + $$ = 0; + } + | K_cover K_property '(' error ')' statement_or_null + { yyerrok; + yyerror(@2, "error: Error in property_spec of concurrent assertion item."); + $$ = 0; + } + | K_cover K_sequence '(' error ')' statement_or_null + { yyerrok; + yyerror(@2, "error: Error in property_spec of concurrent assertion item."); + $$ = 0; + } + | K_restrict K_property '(' error ')' ';' + { yyerrok; + yyerror(@2, "error: Error in property_spec of concurrent assertion item."); + $$ = 0; } ; @@ -1167,6 +1251,81 @@ data_type_or_implicit_or_void } ; +deferred_immediate_assertion_item /* IEEE1800-2012: A.6.10 */ + : block_identifier_opt deferred_immediate_assertion_statement + { delete $1; + delete $2; + } + ; + +deferred_immediate_assertion_statement /* IEEE1800-2012 A.6.10 */ + : assert_or_assume deferred_mode '(' expression ')' statement_or_null %prec less_than_K_else + { + if (gn_assertions_flag) { + yyerror(@1, "sorry: Deferred assertions are not supported." + " Try -gno-assertion to turn this message off."); + } + delete $4; + delete $6; + $$ = 0; + } + | assert_or_assume deferred_mode '(' expression ')' K_else statement_or_null + { + if (gn_assertions_flag) { + yyerror(@1, "sorry: Deferred assertions are not supported." + " Try -gno-assertion to turn this message off."); + } + delete $4; + delete $7; + $$ = 0; + } + | assert_or_assume deferred_mode '(' expression ')' statement_or_null K_else statement_or_null + { + if (gn_assertions_flag) { + yyerror(@1, "sorry: Deferred assertions are not supported." + " Try -gno-assertion to turn this message off."); + } + delete $4; + delete $6; + delete $8; + $$ = 0; + } + | K_cover deferred_mode '(' expression ')' statement_or_null + { + /* Coverage collection is not currently supported. */ + delete $4; + delete $6; + $$ = 0; + } + | assert_or_assume deferred_mode '(' error ')' statement_or_null %prec less_than_K_else + { yyerror(@1, "error: Malformed conditional expression."); + $$ = $6; + } + | assert_or_assume deferred_mode '(' error ')' K_else statement_or_null + { yyerror(@1, "error: Malformed conditional expression."); + $$ = $7; + } + | assert_or_assume deferred_mode '(' error ')' statement_or_null K_else statement_or_null + { yyerror(@1, "error: Malformed conditional expression."); + $$ = $6; + } + | K_cover deferred_mode '(' error ')' statement_or_null + { yyerror(@1, "error: Malformed conditional expression."); + $$ = $6; + } + ; + +deferred_mode + : '#' DEC_NUMBER + { if (!$2->is_zero()) { + yyerror(@2, "error: Delay value must be zero for deferred assertion."); + } + delete $2; + $$ = 0; } + | K_final + { $$ = 1; } + ; + /* NOTE: The "module" rule of the description combines the module_declaration, program_declaration, and interface_declaration rules from the standard description. */ @@ -1846,65 +2005,17 @@ port_direction_opt | { $$ = NetNet::PIMPLICIT; } ; -property_expr /* IEEE1800-2012 A.2.10 */ - : expression +procedural_assertion_statement /* IEEE1800-2012 A.6.10 */ + : concurrent_assertion_statement + { $$ = $1; } + | simple_immediate_assertion_statement + { $$ = $1; } + | deferred_immediate_assertion_statement + { $$ = $1; } ; -procedural_assertion_statement /* IEEE1800-2012 A.6.10 */ - // $assertcontrol is not yet supported. - : assert_or_assume '(' expression ')' statement_or_null %prec less_than_K_else - { - if (gn_assertions_flag) { - listarg_list; - PCallTask*tmp1 = new PCallTask(lex_strings.make("$error"), arg_list); - FILE_NAME(tmp1, @1); - PCondit*tmp2 = new PCondit($3, $5, tmp1); - FILE_NAME(tmp2, @1); - $$ = tmp2; - } else { - $$ = 0; - } - } - | assert_or_assume '(' expression ')' K_else statement_or_null - { - if (gn_assertions_flag) { - PCondit*tmp = new PCondit($3, 0, $6); - FILE_NAME(tmp, @1); - $$ = tmp; - } else { - $$ = 0; - } - } - | assert_or_assume '(' expression ')' statement_or_null K_else statement_or_null - { - if (gn_assertions_flag) { - PCondit*tmp = new PCondit($3, $5, $7); - FILE_NAME(tmp, @1); - $$ = tmp; - } else { - $$ = 0; - } - } - | K_cover '(' expression ')' statement_or_null - // Coverage collection is not currently supported. - { $$ = 0; } - - | assert_or_assume '(' error ')' statement_or_null %prec less_than_K_else - { yyerror(@1, "error: Malformed conditional expression."); - $$ = $5; - } - | assert_or_assume '(' error ')' K_else statement_or_null - { yyerror(@1, "error: Malformed conditional expression."); - $$ = $6; - } - | assert_or_assume '(' error ')' statement_or_null K_else statement_or_null - { yyerror(@1, "error: Malformed conditional expression."); - $$ = $5; - } - | K_cover '(' error ')' statement_or_null - { yyerror(@1, "error: Malformed conditional expression."); - $$ = $5; - } +property_expr /* IEEE1800-2012 A.2.10 */ + : expression ; /* The property_qualifier rule is as literally described in the LRM, @@ -1957,6 +2068,72 @@ signing /* IEEE1800-2005: A.2.2.1 */ | K_unsigned { $$ = false; } ; +simple_immediate_assertion_statement /* IEEE1800-2012 A.6.10 */ + : assert_or_assume '(' expression ')' statement_or_null %prec less_than_K_else + { + if (gn_assertions_flag) { + listarg_list; + PCallTask*tmp1 = new PCallTask(lex_strings.make("$error"), arg_list); + FILE_NAME(tmp1, @1); + PCondit*tmp2 = new PCondit($3, $5, tmp1); + FILE_NAME(tmp2, @1); + $$ = tmp2; + } else { + delete $3; + delete $5; + $$ = 0; + } + } + | assert_or_assume '(' expression ')' K_else statement_or_null + { + if (gn_assertions_flag) { + PCondit*tmp = new PCondit($3, 0, $6); + FILE_NAME(tmp, @1); + $$ = tmp; + } else { + delete $3; + delete $6; + $$ = 0; + } + } + | assert_or_assume '(' expression ')' statement_or_null K_else statement_or_null + { + if (gn_assertions_flag) { + PCondit*tmp = new PCondit($3, $5, $7); + FILE_NAME(tmp, @1); + $$ = tmp; + } else { + delete $3; + delete $5; + delete $7; + $$ = 0; + } + } + | K_cover '(' expression ')' statement_or_null + { + /* Coverage collection is not currently supported. */ + delete $3; + delete $5; + $$ = 0; + } + | assert_or_assume '(' error ')' statement_or_null %prec less_than_K_else + { yyerror(@1, "error: Malformed conditional expression."); + $$ = $5; + } + | assert_or_assume '(' error ')' K_else statement_or_null + { yyerror(@1, "error: Malformed conditional expression."); + $$ = $6; + } + | assert_or_assume '(' error ')' statement_or_null K_else statement_or_null + { yyerror(@1, "error: Malformed conditional expression."); + $$ = $5; + } + | K_cover '(' error ')' statement_or_null + { yyerror(@1, "error: Malformed conditional expression."); + $$ = $5; + } + ; + simple_type_or_string /* IEEE1800-2005: A.2.2.1 */ : integer_vector_type { ivl_variable_type_t use_vtype = $1;