diff --git a/docs/guide/languages.rst b/docs/guide/languages.rst index 4865f5375..6eeb84fb1 100644 --- a/docs/guide/languages.rst +++ b/docs/guide/languages.rst @@ -461,6 +461,10 @@ chandle Treated as a "longint"; does not yet warn about operations specified as illegal on chandles. +checker + Treated as a "module"; does not yet warn about many constructs illegal + inside a checker. + disable Disable statements may be used only if the block being disabled is a block the disable statement itself is inside. This was commonly used to diff --git a/src/verilog.l b/src/verilog.l index f121b82a4..4d469100f 100644 --- a/src/verilog.l +++ b/src/verilog.l @@ -594,8 +594,8 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} { /* Keywords */ "accept_on" { ERROR_RSVD_WORD("SystemVerilog 2009"); } - "checker" { ERROR_RSVD_WORD("SystemVerilog 2009"); } - "endchecker" { ERROR_RSVD_WORD("SystemVerilog 2009"); } + "checker" { FL; return yCHECKER; } + "endchecker" { FL; return yENDCHECKER; } "eventually" { ERROR_RSVD_WORD("SystemVerilog 2009"); } "global" { FL; return yGLOBAL__LEX; } "implies" { ERROR_RSVD_WORD("SystemVerilog 2009"); } diff --git a/src/verilog.y b/src/verilog.y index 25f65230b..05ba67da4 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -562,7 +562,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"}) %token yCASEX "casex" %token yCASEZ "casez" %token yCHANDLE "chandle" -//UNSUP %token yCHECKER "checker" +%token yCHECKER "checker" %token yCLASS "class" //UNSUP %token yCLOCK "clock" %token yCLOCKING "clocking" @@ -588,7 +588,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"}) %token yELSE "else" %token yEND "end" %token yENDCASE "endcase" -//UNSUP %token yENDCHECKER "endchecker" +%token yENDCHECKER "endchecker" %token yENDCLASS "endclass" %token yENDCLOCKING "endclocking" %token yENDFUNCTION "endfunction" @@ -1261,7 +1261,7 @@ package_or_generate_item_declaration: // ==IEEE: package_or_generate_i | data_declaration { $$ = $1; } | task_declaration { $$ = $1; } | function_declaration { $$ = $1; } - //UNSUP checker_declaration { $$ = $1; } + | checker_declaration { $$ = $1; } | dpi_import_export { $$ = $1; } | extern_constraint_declaration { $$ = $1; } | class_declaration { $$ = $1; } @@ -2610,13 +2610,7 @@ module_common_item: // ==IEEE: module_common_item { $$ = nullptr; BBUNSUP($1, "Unsupported: alias statements"); } | initial_construct { $$ = $1; } | final_construct { $$ = $1; } - // // IEEE: always_construct - // // Verilator only - event_control attached to always - | yALWAYS stmtBlock { $$ = new AstAlways{$1, VAlwaysKwd::ALWAYS, nullptr, $2}; } - | yALWAYS_FF stmtBlock { $$ = new AstAlways{$1, VAlwaysKwd::ALWAYS_FF, nullptr, $2}; } - | yALWAYS_LATCH stmtBlock { $$ = new AstAlways{$1, VAlwaysKwd::ALWAYS_LATCH, nullptr, $2}; } - | yALWAYS_COMB stmtBlock { $$ = new AstAlways{$1, VAlwaysKwd::ALWAYS_COMB, nullptr, $2}; } - // + | always_construct { $$ = $1; } | loop_generate_construct { $$ = $1; } | conditional_generate_construct { $$ = $1; } | elaboration_system_task { $$ = $1; } @@ -2625,6 +2619,14 @@ module_common_item: // ==IEEE: module_common_item | error ';' { $$ = nullptr; } ; +always_construct: // IEEE: == always_construct + // // Verilator only - event_control attached to always + yALWAYS stmtBlock { $$ = new AstAlways{$1, VAlwaysKwd::ALWAYS, nullptr, $2}; } + | yALWAYS_FF stmtBlock { $$ = new AstAlways{$1, VAlwaysKwd::ALWAYS_FF, nullptr, $2}; } + | yALWAYS_LATCH stmtBlock { $$ = new AstAlways{$1, VAlwaysKwd::ALWAYS_LATCH, nullptr, $2}; } + | yALWAYS_COMB stmtBlock { $$ = new AstAlways{$1, VAlwaysKwd::ALWAYS_COMB, nullptr, $2}; } + ; + continuous_assign: // IEEE: continuous_assign yASSIGN driveStrengthE delay_controlE assignList ';' { @@ -2697,17 +2699,21 @@ generate_region: // ==IEEE: generate_region | yGENERATE yENDGENERATE { $$ = nullptr; } ; -//UNSUPc_generate_region: // IEEE: generate_region (for checkers) -//UNSUP BISONPRE_COPY(generate_region,{s/~c~/c_/g}) // {copied} -//UNSUP ; +c_generate_region: // IEEE: generate_region (for checkers) + BISONPRE_COPY(generate_region,{s/~c~/c_/g}) // {copied} + ; generate_block_or_null: // IEEE: generate_block_or_null (called from gencase/genif/genfor) // ';' // is included in // // IEEE: generate_block // // Must always return a BEGIN node, or nullptr - see GenFor construction - generate_item + ~c~generate_item { $$ = $1 ? (new AstBegin{$1->fileline(), "", $1, true, true}) : nullptr; } - | genItemBegin { $$ = $1; } + | ~c~genItemBegin { $$ = $1; } + ; + +c_generate_block_or_null: // IEEE: generate_block_or_null (for checkers) + BISONPRE_COPY(generate_block_or_null,{s/~c~/c_/g}) // {copied} ; genItemBegin: // IEEE: part of generate_block @@ -2725,27 +2731,27 @@ genItemBegin: // IEEE: part of generate_block { $$ = nullptr; GRAMMARP->endLabel($5, *$3, $5); } ; -//UNSUPc_genItemBegin: // IEEE: part of generate_block (for checkers) -//UNSUP BISONPRE_COPY(genItemBegin,{s/~c~/c_/g}) // {copied} -//UNSUP ; +c_genItemBegin: // IEEE: part of generate_block (for checkers) + BISONPRE_COPY(genItemBegin,{s/~c~/c_/g}) // {copied} + ; genItemOrBegin: // Not in IEEE, but our begin isn't under generate_item ~c~generate_item { $$ = $1; } | ~c~genItemBegin { $$ = $1; } ; -//UNSUPc_genItemOrBegin: // (for checkers) -//UNSUP BISONPRE_COPY(genItemOrBegin,{s/~c~/c_/g}) // {copied} -//UNSUP ; +c_genItemOrBegin: // (for checkers) + BISONPRE_COPY(genItemOrBegin,{s/~c~/c_/g}) // {copied} + ; genItemList: ~c~genItemOrBegin { $$ = $1; } | ~c~genItemList ~c~genItemOrBegin { $$ = addNextNull($1, $2); } ; -//UNSUPc_genItemList: // (for checkers) -//UNSUP BISONPRE_COPY(genItemList,{s/~c~/c_/g}) // {copied} -//UNSUP ; +c_genItemList: // (for checkers) + BISONPRE_COPY(genItemList,{s/~c~/c_/g}) // {copied} + ; generate_item: // IEEE: module_or_interface_or_generate_item // // Only legal when in a generate under a module (or interface under a module) @@ -2757,9 +2763,9 @@ generate_item: // IEEE: module_or_interface_or_generate_item // // so below in c_generate_item ; -//UNSUPc_generate_item: // IEEE: generate_item (for checkers) -//UNSUP checker_or_generate_item { $$ = $1; } -//UNSUP ; +c_generate_item: // IEEE: generate_item (for checkers) + checker_or_generate_item { $$ = $1; } + ; conditional_generate_construct: // ==IEEE: conditional_generate_construct yCASE '(' expr ')' ~c~case_generate_itemListE yENDCASE @@ -2770,9 +2776,9 @@ conditional_generate_construct: // ==IEEE: conditional_generate_construc { $$ = new AstGenIf{$1, $3, $5, $7}; } ; -//UNSUPc_conditional_generate_construct: // IEEE: conditional_generate_construct (for checkers) -//UNSUP BISONPRE_COPY(conditional_generate_construct,{s/~c~/c_/g}) // {copied} -//UNSUP ; +c_conditional_generate_construct: // IEEE: conditional_generate_construct (for checkers) + BISONPRE_COPY(conditional_generate_construct,{s/~c~/c_/g}) // {copied} + ; loop_generate_construct: // ==IEEE: loop_generate_construct yFOR '(' genvar_initialization ';' expr ';' genvar_iteration ')' ~c~generate_block_or_null @@ -2801,9 +2807,9 @@ loop_generate_construct: // ==IEEE: loop_generate_construct } ; -//UNSUPc_loop_generate_construct: // IEEE: loop_generate_construct (for checkers) -//UNSUP BISONPRE_COPY(loop_generate_construct,{s/~c~/c_/g}) // {copied} -//UNSUP ; +c_loop_generate_construct: // IEEE: loop_generate_construct (for checkers) + BISONPRE_COPY(loop_generate_construct,{s/~c~/c_/g}) // {copied} + ; genvar_initialization: // ==IEEE: genvar_initialization varRefBase '=' expr { $$ = new AstAssign{$2, $1, $3}; } @@ -2855,7 +2861,11 @@ genvar_iteration: // ==IEEE: genvar_iteration case_generate_itemListE: // IEEE: [{ case_generate_itemList }] /* empty */ { $$ = nullptr; } - | case_generate_itemList { $$ = $1; } + | ~c~case_generate_itemList { $$ = $1; } + ; + +c_case_generate_itemListE: // IEEE: { case_generate_item } (for checkers) + BISONPRE_COPY(case_generate_itemListE,{s/~c~/c_/g}) // {copied} ; case_generate_itemList: // IEEE: { case_generate_itemList } @@ -2863,19 +2873,19 @@ case_generate_itemList: // IEEE: { case_generate_itemList } | ~c~case_generate_itemList ~c~case_generate_item { $$ = $1; $1->addNext($2); } ; -//UNSUPc_case_generate_itemList: // IEEE: { case_generate_item } (for checkers) -//UNSUP BISONPRE_COPY(case_generate_itemList,{s/~c~/c_/g}) // {copied} -//UNSUP ; - -case_generate_item: // ==IEEE: case_generate_item - caseCondList colon generate_block_or_null { $$ = new AstCaseItem{$2, $1, $3}; } - | yDEFAULT colon generate_block_or_null { $$ = new AstCaseItem{$1, nullptr, $3}; } - | yDEFAULT generate_block_or_null { $$ = new AstCaseItem{$1, nullptr, $2}; } +c_case_generate_itemList: // IEEE: { case_generate_item } (for checkers) + BISONPRE_COPY(case_generate_itemList,{s/~c~/c_/g}) // {copied} ; -//UNSUPc_case_generate_item: // IEEE: case_generate_item (for checkers) -//UNSUP BISONPRE_COPY(case_generate_item,{s/~c~/c_/g}) // {copied} -//UNSUP ; +case_generate_item: // ==IEEE: case_generate_item + caseCondList colon ~c~generate_block_or_null { $$ = new AstCaseItem{$2, $1, $3}; } + | yDEFAULT colon ~c~generate_block_or_null { $$ = new AstCaseItem{$1, nullptr, $3}; } + | yDEFAULT ~c~generate_block_or_null { $$ = new AstCaseItem{$1, nullptr, $2}; } + ; + +c_case_generate_item: // IEEE: case_generate_item (for checkers) + BISONPRE_COPY(case_generate_item,{s/~c~/c_/g}) // {copied} + ; //************************************************ // Assignments and register declarations @@ -5935,7 +5945,6 @@ pexpr: // IEEE: property_expr (The name pexpr is important as regex complex_pexpr: // IEEE: part of property_expr, see comments there expr yP_ORMINUSGT pexpr { $$ = new AstLogOr{$2, new AstLogNot{$2, $1}, $3}; } | expr yP_OREQGT pexpr { $$ = new AstImplication{$2, $1, $3}; } - | yNOT pexpr %prec prNEGATION { $$ = new AstLogNot{$1, $2}; } | '(' complex_pexpr ')' { $$ = $2; } //UNSUP remove above, use below: // @@ -5945,7 +5954,7 @@ complex_pexpr: // IEEE: part of property_expr, see comments there // // IEEE: '(' pexpr ')' // // Expanded below // - //UNSUP yNOT pexpr %prec prNEGATION { } + | yNOT pexpr %prec prNEGATION { $$ = new AstLogNot{$1, $2}; } //UNSUP ySTRONG '(' sexpr ')' { } //UNSUP yWEAK '(' sexpr ')' { } // // IEEE: pexpr yOR pexpr @@ -6249,7 +6258,8 @@ complex_pexpr: // IEEE: part of property_expr, see comments there //UNSUPlist_of_cross_items: // ==IEEE: list_of_cross_items //UNSUP cross_item ',' cross_item { $$ = addNextNull($1, $3); } -//UNSUP | cross_item ',' cross_item ',' cross_itemList { } +//UNSUP | cross_item ',' cross_item ',' cross_itemList +//UNSUP { $$ = addNextNull(addNextNull($1, $3), $5); } //UNSUP ; //UNSUPcross_itemList: // IEEE: part of list_of_cross_items @@ -6459,67 +6469,85 @@ rs_case_item: // ==IEEE: rs_case_item //********************************************************************** // Checker -//UNSUPchecker_declaration: // ==IEEE: part of checker_declaration -//UNSUP checkerFront checker_port_listE ';' -//UNSUP checker_or_generate_itemListE yENDCHECKER endLabelE -//UNSUP { SYMP->popScope($$); } -//UNSUP ; +checker_declaration: // ==IEEE: part of checker_declaration + checkerFront checker_port_listE ';' + checker_or_generate_itemListE yENDCHECKER endLabelE + { $$ = $1; + $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); + if ($2) $1->addStmtsp($2); + if ($4) $1->addStmtsp($4); + GRAMMARP->m_modp = nullptr; + SYMP->popScope($1); + GRAMMARP->endLabel($6, $1, $6); } + ; -//UNSUPcheckerFront: // IEEE: part of checker_declaration -//UNSUP yCHECKER idAny/*checker_identifier*/ -//UNSUP { SYMP->pushNew($$); } -//UNSUP ; +checkerFront: // IEEE: part of checker_declaration + yCHECKER idAny/*checker_identifier*/ + { BBUNSUP($1, "Unsupported: checker"); + // TODO should be AstChecker not AstModule + $$ = new AstModule{$2, *$2}; + $$->modTrace(GRAMMARP->allTracingOn($$->fileline())); + $$->timeunit(PARSEP->timeLastUnit()); + $$->unconnectedDrive(PARSEP->unconnectedDrive()); + SYMP->pushNew($$); + GRAMMARP->m_modp = $$; } + ; -//UNSUPchecker_port_listE: // IEEE: [ ( [ checker_port_list ] ) ] -//UNSUP // // checker_port_item is basically the same as property_port_item, minus yLOCAL:: -//UNSUP // // Want to bet 1800-2012 adds local to checkers? -//UNSUP property_port_listE { $$ = $1; } -//UNSUP ; +checker_port_listE: // IEEE: [ ( [ checker_port_list ] ) ] + // // checker_port_item is basically the same as property_port_item, minus yLOCAL:: + // // Want to bet 1800-2012 adds local to checkers? + property_port_listE { $$ = $1; } + ; -//UNSUPchecker_or_generate_itemListE: // IEEE: [{ checker_or_generate_itemList }] -//UNSUP /* empty */ { $$ = nullptr; } -//UNSUP | checker_or_generate_itemList { $$ = $1; } -//UNSUP ; +checker_or_generate_itemListE: // IEEE: [{ checker_or_generate_itemList }] + /* empty */ { $$ = nullptr; } + | checker_or_generate_itemList { $$ = $1; } + ; -//UNSUPchecker_or_generate_itemList: // IEEE: { checker_or_generate_itemList } -//UNSUP checker_or_generate_item { $$ = $1; } -//UNSUP | checker_or_generate_itemList checker_or_generate_item { $$ = addNextNull($1, $2); } -//UNSUP ; +checker_or_generate_itemList: // IEEE: { checker_or_generate_itemList } + checker_or_generate_item { $$ = $1; } + | checker_or_generate_itemList checker_or_generate_item { $$ = addNextNull($1, $2); } + ; -//UNSUPchecker_or_generate_item: // ==IEEE: checker_or_generate_item -//UNSUP checker_or_generate_item_declaration { $$ = $1; } -//UNSUP | initial_construct { $$ = $1; } -//UNSUP // // IEEE: checker_construct -//UNSUP | yALWAYS stmtBlock { } -//UNSUP | final_construct { $$ = $1; } -//UNSUP | assertion_item { $$ = $1; } -//UNSUP | continuous_assign { $$ = $1; } -//UNSUP | checker_generate_item { $$ = $1; } -//UNSUP ; +checker_or_generate_item: // ==IEEE: checker_or_generate_item + checker_or_generate_item_declaration { $$ = $1; } + | initial_construct { $$ = $1; } + // // IEEE: checker_construct + | always_construct { $$ = $1; } + | final_construct { $$ = $1; } + | assertion_item { $$ = $1; } + | continuous_assign { $$ = $1; } + | checker_generate_item { $$ = $1; } + ; -//UNSUPchecker_or_generate_item_declaration: // ==IEEE: checker_or_generate_item_declaration -//UNSUP data_declaration { $$ = $1; } -//UNSUP | yRAND data_declaration { } -//UNSUP | function_declaration { $$ = $1; } -//UNSUP | checker_declaration { $$ = $1; } -//UNSUP | assertion_item_declaration { $$ = $1; } -//UNSUP | covergroup_declaration { $$ = $1; } -//UNSUP // // IEEE deprecated: overload_declaration -//UNSUP | genvar_declaration { $$ = $1; } -//UNSUP | clocking_declaration { $$ = $1; } -//UNSUP | yDEFAULT yCLOCKING id/*clocking_identifier*/ ';' { } -//UNSUP | yDEFAULT yDISABLE yIFF expr/*expression_or_dist*/ ';' { } -//UNSUP | ';' { $$ = nullptr; } -//UNSUP ; +checker_or_generate_item_declaration: // ==IEEE: checker_or_generate_item_declaration + data_declaration + { $$ = $1; BBUNSUP($1, "Unsupported: checker data declaration"); } + | yRAND data_declaration + { $$ = $2; BBUNSUP($1, "Unsupported: checker rand"); } + | function_declaration { $$ = $1; } + | checker_declaration + { $$ = nullptr; BBUNSUP($1, "Unsupported: recursive checker"); } + | assertion_item_declaration { $$ = $1; } + //UNSUP covergroup_declaration { $$ = $1; } + // // IEEE deprecated: overload_declaration + | genvar_declaration { $$ = $1; } + | clocking_declaration { $$ = $1; } + | yDEFAULT yCLOCKING id/*clocking_identifier*/ ';' { } + { $$ = nullptr; BBUNSUP($1, "Unsupported: checker default clocking"); } + | yDEFAULT yDISABLE yIFF expr/*expression_or_dist*/ ';' { } + { $$ = nullptr; BBUNSUP($1, "Unsupported: checker default disable iff"); } + | ';' { $$ = nullptr; } + ; -//UNSUPchecker_generate_item: // ==IEEE: checker_generate_item -//UNSUP // // Specialized for checker so need "c_" prefixes here -//UNSUP c_loop_generate_construct { $$ = $1; } -//UNSUP | c_conditional_generate_construct { $$ = $1; } -//UNSUP | c_generate_region { $$ = $1; } -//UNSUP // -//UNSUP | elaboration_system_task { $$ = $1; } -//UNSUP ; +checker_generate_item: // ==IEEE: checker_generate_item + // // Specialized for checker so need "c_" prefixes here + c_loop_generate_construct { $$ = $1; } + | c_conditional_generate_construct { $$ = $1; } + | c_generate_region { $$ = $1; } + // + | elaboration_system_task { $$ = $1; } + ; //UNSUPchecker_instantiation: //UNSUP // // Only used for procedural_assertion_item's diff --git a/test_regress/t/t_checker.out b/test_regress/t/t_checker.out new file mode 100644 index 000000000..b64cf2a82 --- /dev/null +++ b/test_regress/t/t_checker.out @@ -0,0 +1,38 @@ +%Error-UNSUPPORTED: t/t_checker.v:33:1: Unsupported: checker + 33 | checker Chk + | ^~~~~~~ + ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error-UNSUPPORTED: t/t_checker.v:36:8: Unsupported: checker data declaration + 36 | bit clk; + | ^~~ +%Error-UNSUPPORTED: t/t_checker.v:37:8: Unsupported: checker data declaration + 37 | bit in; + | ^~ +%Error-UNSUPPORTED: t/t_checker.v:38:8: Unsupported: checker data declaration + 38 | bit rst; + | ^~~ +%Error-UNSUPPORTED: t/t_checker.v:39:4: Unsupported: checker rand + 39 | rand bit randed; + | ^~~~ +%Error-UNSUPPORTED: t/t_checker.v:41:8: Unsupported: checker data declaration + 41 | int counter = 0; + | ^~~~~~~ +%Error-UNSUPPORTED: t/t_checker.v:43:8: Unsupported: checker data declaration + 43 | int ival; + | ^~~~ +%Error-UNSUPPORTED: t/t_checker.v:53:8: Unsupported: checker data declaration + 53 | int ival2; + | ^~~~~ +%Error-UNSUPPORTED: t/t_checker.v:61:4: Unsupported: checker default clocking + 61 | default clocking clk; + | ^~~~~~~ +%Error-UNSUPPORTED: t/t_checker.v:62:4: Unsupported: checker default disable iff + 62 | default disable iff rst; + | ^~~~~~~ +%Error-UNSUPPORTED: t/t_checker.v:64:4: Unsupported: checker + 64 | checker ChkChk; + | ^~~~~~~ +%Error-UNSUPPORTED: t/t_checker.v:64:12: Unsupported: recursive checker + 64 | checker ChkChk; + | ^~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_checker.pl b/test_regress/t/t_checker.pl new file mode 100755 index 000000000..1ce0595d2 --- /dev/null +++ b/test_regress/t/t_checker.pl @@ -0,0 +1,24 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2023 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(vlt => 1); + +compile( + verilator_flags2 => ['--assert'], + expect_filename => $Self->{golden_filename}, + fails => 1, + ); + +#execute( +# check_finished => 1, +# ); + +ok(1); +1; diff --git a/test_regress/t/t_checker.v b/test_regress/t/t_checker.v new file mode 100644 index 000000000..12ef18bac --- /dev/null +++ b/test_regress/t/t_checker.v @@ -0,0 +1,80 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2023 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t(/*AUTOARG*/ + // Inputs + clk + ); + input clk; + + integer cyc = 0; + + // Test loop + always @ (posedge clk) begin +`ifdef TEST_VERBOSE + $write("[%0t] cyc==%0d\n", $time, cyc); +`endif + cyc <= cyc + 1; + if (cyc == 0) begin + end + else if (cyc == 99) begin + $write("*-* All Finished *-*\n"); + $finish; + end + end + + Chk check(clk, cyc); + +endmodule + +checker Chk + // UNSUP (input clk, int in) + ; + bit clk; + bit in; + bit rst; + rand bit randed; // TODO test this + + int counter = 0; + + int ival; + final if (ival != 1234) $stop; + genvar g; + if (0) begin + initial ival = 1; + end + else begin + initial ival = 1234; + end + + int ival2; + case (1) + 0: initial ival2 = 0; + default: initial ival2 = 12345; + endcase + final if (ival2 != 12345) $stop; + + + default clocking clk; // TODO test this + default disable iff rst; // TODO test this + + checker ChkChk; // TODO flag unsupported + endchecker + + function automatic int f; // TODO test this + endfunction + + + clocking cb1 @(posedge clk); // TODO test this + input in; + output out; + endclocking + + always_ff @(posedge clk) + counter <= counter + 1'b1; + + a1: assert property (@(posedge clk) counter == in); +endchecker