Checking can be performed to test the success or failure of any simple or complex temporal expression. This section discusses temporal checking by means of e struct members expect and on. Temporal checking is often referred to as assertion checking.
The expect struct member defines temporal rules. If the temporal expression fails at its sampling event, the temporal rule is violated and an error is reported. If there is no dut_error() clause, the rule name is displayed. Once a rule has been defined, it can be modified using the is only syntax. The syntax for the expect struct member is shown below:
expect [rule-name is [only]] temporal-expression [else dut_error(string-exp)];
Table 9-4 shows the components of an expect struct member.
rule-name | An optional name that uniquely distinguishes the rule from other rules or events within the struct. You can use this name to override the temporal rule later. |
temporal-expression | A temporal expression that is always expected to succeed. Typically involves a temporal yield (=>) operation. |
string-exp | A string or a method that returns a string. If the temporal expression fails, the string is displayed, or the method is executed and its result is displayed. |
Example 9-9 shows the usage of an expect struct member.
This example defines an expect rule. This rule requires that the length of the bus cycle be no longer than 1000 cycles. This isthe number of clocks between the transmit_start and transmit_end event. <' struct bus_e { event bus_clk is change('top.b_clk') @sim; //Event event transmit_start is rise('top.trans') @bus_clk; //Event event transmit_end is rise('top.transmit_done') @bus_clk; //Event event bus_cycle_length; //Declare event expect bus_cycle_length is //Set up a rule for that event //If transmit_start occurs, transmit_end must occur //within 1000 cycles of @bus_clk @transmit_start => {[0..999];@transmit_end} @bus_clk else dut_error("Bus cycle did not end in 1000 cycles"); }; '> //If the bus cycle is longer than 1000 cycles, the following message //will be issued. //------------------------------------------------------- // *** Dut error at time 1000 // Checked at line 7 in @expect_msg // In bus_e-@0: // //bus_cycle_length: Bus cycle did not end in 1000 cycles //------------------------------------------------------- //Will stop execution immediately (check effect is ERROR) // // *** Error: A Dut error has occurred
The on struct member executes a block of actions immediately whenever a specified trigger event is emitted. An on struct member is similar to a regular method except that the action block for an on struct member is invoked immediately upon the emission of the trigger event. An on action block is executed before TCMs waiting for the same event.
The on action block is invoked every time the trigger event is emitted. The actions are executed in the order in which they appear in the action block. You can extend an on struct member by repeating its declaration, with a different action block. This has the same effect as using is also to extend a method. The on action block cannot contain any TCMs.
The syntax of the on struct member is as follows:
on event-type {action; ...}
Example 9-10 shows the usage of an on struct member.
Example shows the usage of the on struct member. <' struct cnt_e { event ready; event start_count; //On struct member on ready {sys.req = 0}; //When ready is emitted, set sys.req = 0. //On struct member on start_count { //When start_count is emitted, perform actions. sys.count = 0; sys.counting = 1; outf("Starting to count - sys.count = %d\n", sys.count); }; trigger()@sys.any is { //TCM that triggers the events for on struct //member. wait cycle; //Wait for next occurrence of sys.any. emit ready; //Trigger ready. wait cycle; //Wait for next occurrence of sys.any. emit start_count; //Trigger start_count. wait cycle; //Wait for next occurrence of sys.any. stop_run(); }; run() is also { start trigger(); }; }; '>