Planning reset strategies: flow and functionality in OVM verification components
The article describes a methodology and appropriate code for developing a reset strategy that will work within a verification process. Specifically, the proposal has been drafted within the terms of the Open Verification Methodology.
A good reset strategy has long been a part of any design methodology, playing a vital role in its success. Reset represents a fundamental property in a protocol or system; it is the first step in the sequence of operations done during any system bring up. However, this paper addresses the increasing importance of reset strategies with regard to verification methodologies and outlines the strategy that should be followed during verification using a test bench under the Open Verification Methodology (OVM)
While developing an OVM-based IP (i.e. OVM Verification Component (OVC)), you need to get a clear perspective on how it behaves and recovers from a reset application during the course of simulation.
The basic requirements for a reset strategy can be split into two broad categories.
1. Ensure an appropriate execution of the OVC’s component hierarchy. This will essentially:
- prevent improper shutdowns;
- prevent false error messages;
- help with communication to the stimuli about the reset;
- prevent a false triggering of a passive agent’s response; and
- prevent the reception of incomplete/merged transaction(s) on the analysis port(s) (i.e. to the score-board/coverage collector etc.).
2. Ensure appropriate execution of the OVC’s object hierarchy. This will essentially:
- terminate the test case gracefully;
- help in the exercise of stimulus control at various stages; and
- help in resumption of stimuli upon reset de-activation.
Figure 1 shows the various stages of a typical reset application during the course of the simulation and corresponding stages the test bench components are expected to cycle through. Basically, the reset signal is responsible for the state of any given verification component, active or inactive.
Then, Figure 2 shows a methodology that can be followed to meet the above expectations. There may be several implementations pertaining to the system, but this approach will have a minimal impact if applied to an existing verification component.
When the reset application runs, an OVC’s behavior can be viewed from two broad perspectives:
- The reaction/behavior of various agents and bus functional models (BFMs).
- The reaction of the stimulus (i.e., the execution of the sequences and the flow of the testcase).
With regard to the first of these, the agent stops driving and reinitializes its local variables as well as objects, so that it does not carry any stale data once it is out of reset again. One way to achieve this is to monitor the reset signal asynchronously. This is done by forking out a reset monitoring thread in the run phase of OVM along with other BFM threads (that may call individual BFM task). Once the reset thread detects an active reset, it simply sets a flag that is being monitored in other BFM threads. Upon detection, these threads will be disabled and any local variables in the BFM are reinitialized. With this in mind, consider these three blocks of code.
Agent/BFM reaction and behavior
Block 1: run () phase implementation of reset monitoring
01 class master_driver extends
02 ovm driver ;
03 bit reset_check = 0;
04 virtual task run();
05 fork
06 begin
07 reset_signals();
08 reset_monitoriing();
09 end
10 begin
11 send_reset_rsp();
12 end
13 begin
14 while(1) begin
15 wait(reset_check == 1);
16 fork
17 get_and_drive();
18 wait (reset_check == 0);
19 join_any
20 disable fork;
21 initiate_transfer = ‘b0;
22 transfer_queue.delete();
23 end
24 end
25 join
26 endtask: run
27 endclass
Line 2 represents the interface, port and variable declarations. Lines 3-4 give the OVM run-phase, the initiating point for any component. Lines 6-9 give us Thread 1, reset signals to default value (via ‘reset signals()’) and asynchronous reset monitoring (for more on this, see the code in Block 2). Lines 10-12 are Thread 2, sending a dummy response on reset. Lines 13-23 give instructions to wait until the reset is asserted, fork the BFM’s main task and reset to deassert, disable the fork when any thread completes, reset signal values and clear local variables.
Block 2: asynchronous reset monitoring task
01 master_driver:: task reset_monitoring();
02 forever begin
03 fork
04 begin
05 @(negedge xmi.reset_n);
06 reset_check = 1’b0;
07 reset_signals();
08 end
09 begin
10 @(posedge xmi.reset_n);
11 reset_check = 1’b1;
12 end
13 join
14 end
15 endtask
Here, the reset signals are monitored asynchronously. Lines 4-8 show the resetting of the ‘reset_check’ flag on encountering a reset. Lines 9-12 show the resetting of the ‘reset_check’ flag on clearance of a reset.
Block 3: response on reset
01 master_driver:: task send_reset_rsp();
02 vip_transfer reset_resp;
03 forever begin
04 @(xmi.am_dry);
05 @(negedge xmi.reset_n);
06 if (response_queue.size() > 0) begin
07 reset_resp = response_queue
pop_front ();
08 wr_reset_resp.Reset_Asserted =
1’bl;
09 rsp_port.write(reset_resp);
10 end
11 end
12 endtask
This block forms and sends the response on reset and later sets the ‘Reset_Asserted’ field in response.
Stimulus reaction
There are three possible ways in which a stimulus generator can behave.
Scenario 1
It can stop the basic sequence and terminate the current transaction in it. For example, it can stop basic read/write sequences.
Scenario 2
For a complex virtual sequence above the basic sequences, there are chiefly three possible actions.
(a) The current execution of a basic sequence is terminated but the rest of the virtual sequence is continued, after reset. For example, a complex sequence invokes a combination above the read/write basic sequences. So upon reset, execution of the current basic sequence is terminated, but the complex sequence flow continues with the remaining basic read/write sequences now executed after reset de-activation.
(b) The virtual sequence is altogether restarted upon reset detection, right from the first basic sequence execution in it.
(c) The virtual sequence chooses to execute a completely different set of basic sequences, or combination thereof, between new and old basic sequences, upon reset detection.
There are many ways to code the sequences, but most of them should fall in one of the above categories.
Scenario 3
The effect of reset is propagated to the test case that invokes one or more virtual sequences, in order to exercise control over them. For example, a testcase starts multiple virtual sequences. Once again there are three main possibilities.
(a) Completely discontinue one virtual sequence upon reset detection but continue with the rest, upon reset de-activation.
(b) Restart the sequence of virtual sequences execution upon reset detection, right from the first virtual sequence.
(c) The testcase chooses to execute a completely different set of virtual sequences or combination thereof, between new and old virtual sequences upon reset detection.
For routing the reset information from driver to sequencer, one suggested approach is to add an additional field in the transaction class, so that upon reset detection, the driver stops driving transactions, but at the same time forms a dummy response in which the additional field is set and this response is routed back from the driver to the sequencer to the basic sequence using the ‘get_response’ method in OVM and then through the basic sequence to the virtual sequence to the testcase via a user-defined function called hierarchically. Also, one should stop the sequencer by calling the ‘stop_sequence()’ function in OVM.
Applied Micro Circuits Corp
215 Moffett Park Drive
Sunnyvale
CA 94089
USA
T: +1 408 542 8600
W: www.apm.com