diff --git a/compiler.h b/compiler.h index d2a0eaea1..5da8790fc 100644 --- a/compiler.h +++ b/compiler.h @@ -157,6 +157,10 @@ extern bool gn_icarus_misc_flag; is false, then skip elaboration of specify behavior. */ extern bool gn_specify_blocks_flag; +/* If this flag is true, then elaborate assertions. If this flag is + false, then stub out assertion statements. */ +extern bool gn_assertions_flag; + /* If this flag is true, then support/elaborate Verilog-AMS. */ extern bool gn_verilog_ams_flag; diff --git a/driver/main.c b/driver/main.c index 6b9cd0153..b86bacba7 100644 --- a/driver/main.c +++ b/driver/main.c @@ -122,6 +122,7 @@ char depmode = 'a'; const char*generation = "2005"; const char*gen_specify = "no-specify"; +const char*gen_assertions = "assertions"; const char*gen_xtypes = "xtypes"; const char*gen_icarus = "icarus-misc"; const char*gen_io_range_error = "io-range-error"; @@ -678,6 +679,12 @@ int process_generation(const char*name) else if (strcmp(name,"no-specify") == 0) gen_specify = "no-specify"; + else if (strcmp(name,"assertions") == 0) + gen_assertions = "assertions"; + + else if (strcmp(name,"no-assertions") == 0) + gen_assertions = "no-assertions"; + else if (strcmp(name,"std-include") == 0) gen_std_include = 1; @@ -1090,6 +1097,7 @@ int main(int argc, char **argv) if (mtm != 0) fprintf(iconfig_file, "-T:%s\n", mtm); fprintf(iconfig_file, "generation:%s\n", generation); fprintf(iconfig_file, "generation:%s\n", gen_specify); + fprintf(iconfig_file, "generation:%s\n", gen_assertions); fprintf(iconfig_file, "generation:%s\n", gen_xtypes); fprintf(iconfig_file, "generation:%s\n", gen_io_range_error); fprintf(iconfig_file, "generation:%s\n", gen_strict_ca_eval); diff --git a/main.cc b/main.cc index 40d887c93..7b7e36001 100644 --- a/main.cc +++ b/main.cc @@ -104,6 +104,7 @@ generation_t generation_flag = GN_DEFAULT; bool gn_icarus_misc_flag = true; bool gn_cadence_types_flag = true; bool gn_specify_blocks_flag = true; +bool gn_assertions_flag = true; bool gn_io_range_error_flag = true; bool gn_strict_ca_eval_flag = false; bool gn_strict_expr_width_flag = false; @@ -307,6 +308,12 @@ static void process_generation_flag(const char*gen) } else if (strcmp(gen,"no-specify") == 0) { gn_specify_blocks_flag = false; + } else if (strcmp(gen,"assertions") == 0) { + gn_assertions_flag = true; + + } else if (strcmp(gen,"no-assertions") == 0) { + gn_assertions_flag = false; + } else if (strcmp(gen,"verilog-ams") == 0) { gn_verilog_ams_flag = true; diff --git a/parse.y b/parse.y index db6ceb8b4..32e4d15bb 100644 --- a/parse.y +++ b/parse.y @@ -673,6 +673,10 @@ static void current_function_set_statement(const YYLTYPE&loc, vector /* source_text ::= [ timeunits_declaration ] { description } */ source_text : description_list | ; +assertion_item /* IEEE1800-2012: A.6.10 */ + : concurrent_assertion_item + ; + assignment_pattern /* IEEE1800-2005: A.6.7.1 */ : K_LP expression_list_proper '}' { PEAssignPattern*tmp = new PEAssignPattern(*$2); @@ -687,6 +691,13 @@ assignment_pattern /* IEEE1800-2005: A.6.7.1 */ } ; + /* Some rules have a ... [ block_identifier ':' ] ... part. This + implements it in a LALR way. */ +block_identifier_opt /* */ + : IDENTIFIER ':' + | + ; + class_declaration /* IEEE1800-2005: A.1.2 */ : K_virtual_opt K_class class_identifier class_declaration_extends_opt ';' { pform_start_class_declaration(@2, $3, $4.type, $4.exprs); } @@ -886,6 +897,23 @@ class_new /* IEEE1800-2005 A.2.4 */ } ; + /* The concurrent_assertion_item pulls together the + 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 + { /* */ + if (gn_assertions_flag) { + yyerror(@2, "sorry: concurrent_assertion_item not supported." + " Try -gno-assertion to turn this message off."); + } + } + | block_identifier_opt K_assert K_property '(' error ')' statement_or_null + { yyerrok; + yyerror(@2, "error: Error in property_spec of concurrent assertion item."); + } + ; + constraint_block_item /* IEEE1800-2005 A.1.9 */ : constraint_expression ; @@ -1527,6 +1555,10 @@ port_direction_opt | { $$ = NetNet::PIMPLICIT; } ; +property_expr /* IEEE1800-2012 A.2.10 */ + : expression + ; + /* The property_qualifier rule is as literally described in the LRM, but the use is usually as { property_qualifier }, which is implemented bt the property_qualifier_opt rule below. */ @@ -1546,6 +1578,20 @@ property_qualifier_list /* IEEE1800-2005 A.1.8 */ | property_qualifier { $$ = $1; } ; + /* The property_spec rule uses some helper rules to implement this + rule from the LRM: + [ clocking_event ] [ disable iff ( expression_or_dist ) ] property_expr + This does it is a YACC friendly way. */ + +property_spec /* IEEE1800-2012 A.2.10 */ + : clocking_event_opt property_spec_disable_iff_opt property_expr + ; + +property_spec_disable_iff_opt /* */ + : K_disable K_iff '(' expression ')' + | + ; + random_qualifier /* IEEE1800-2005 A.1.8 */ : K_rand { $$ = property_qualifier_t::make_rand(); } | K_randc { $$ = property_qualifier_t::make_randc(); } @@ -2647,7 +2693,12 @@ dr_strength1 | K_weak1 { $$.str1 = IVL_DR_WEAK; } ; -event_control +clocking_event_opt /* */ + : event_control + | + ; + +event_control /* A.K.A. clocking_event */ : '@' hierarchy_identifier { PEIdent*tmpi = new PEIdent(*$2); PEEvent*tmpe = new PEEvent(PEEvent::ANYEDGE, tmpi); @@ -4385,6 +4436,8 @@ module_item | attribute_list_opt K_analog analog_statement { pform_make_analog_behavior(@2, IVL_PR_ALWAYS, $3); } + | attribute_list_opt assertion_item + | class_declaration | task_declaration diff --git a/scripts/devel-stub.conf b/scripts/devel-stub.conf index 4f485caa5..202c7eed5 100644 --- a/scripts/devel-stub.conf +++ b/scripts/devel-stub.conf @@ -8,6 +8,7 @@ # generation:2009 generation:specify +generation:assertions generation:xtypes generation:verilog-ams iwidth:32