Using VMM Consensus to end your test
Posted by JL Gray on August 23rd, 2010
Asif Jafri, Verification Consultant, Verilab
One topic that is often overlooked is how does one end a test. One common approach has been to use pound delays or count the number of transactions generated. While this worked well for directed test environments this approach is not well suited for use with constrained random testbenches. Usually there are several threads running in parallel and to be able to intelligently tell whether all test criterions are met, we need a more centralized approach to manage and decide test completion. vmm_group now has a mechanism to centrally manage test completion with the use of VMM Consensus.To better explain the usage let’s try to build an example:
1. Instantiate a vmm_voter class to indicate consensus or oppose end of test.
vmm_voter end_voter;
2. Identify the participants that will need to consent before the test ends. These participants can be in the form of transactors which will consent when idle, channels consent when empty, notifications and vmm_consensus. Add the voters in the vmm_group::build_ph()
vmm_consensus::register_*
3. Add vmm_consensus::wait_for _consensus() to vmm_group::wait_for_end() method. Once all participants consent, the test will complete.
vmm_voter end_voter;
2. Identify the participants that will need to consent before the test ends. These participants can be in the form of transactors which will consent when idle, channels consent when empty, notifications and vmm_consensus. Add the voters in the vmm_group::build_ph()
vmm_consensus::register_*
3. Add vmm_consensus::wait_for _consensus() to vmm_group::wait_for_end() method. Once all participants consent, the test will complete.
class tb_top extends vmm_group;
`vmm_typename(tb_top)vmm_voter end_voter;
function void build_ph();
transaction_channel master_chan;
slave_transactor slave_xactor;
end_voter = end_vote.register_channel(master_chan);
end_voter = end_vote.register_xactor(slave_xactor);
endfunction
transaction_channel master_chan;
slave_transactor slave_xactor;
end_voter = end_vote.register_channel(master_chan);
end_voter = end_vote.register_xactor(slave_xactor);
endfunction
task wait_for_end();
super.wait_for_end();
end_vote.wait_for_consensus();
endtask
endclass: tb_top
The code above shows how we can instantiate various voters that will participate in the test completion.
The figure below shows how a participant opposes test completion, while all other participants have given consent.
One of the simplest forms of usage is to oppose completion using the command above before a completing some given task like programming registers or pulling reset and then giving consent by using the command: this.consent(“Programming Completed”); There is often a need to force consensus to end a test if one of the opposing blocks is not releasing. This can be achieved by using the forced command.
You can choose to use the consensus_force_thru command to pass to propagate the force up.
Using these techniques to end your test will make your testbench scalable and reusable over various projects.








November 6th, 2012 at 10:37 pm
Are you sure this code works? I am getting “Could not find member ‘wait_for_end’ in class ‘vmm_group’.
November 7th, 2012 at 4:50 pm
Hi Martin,
It looks like you’ve found an issue with the code example presented here. The code:
task wait_for_end();
super.wait_for_end();
end_vote.wait_for_consensus();
endtask
…should have been placed inside of an extension to vmm_env, not vmm_group.
class my_env extends vmm_env;
task wait_for_end();
super.wait_for_end();
end_vote.wait_for_consensus();
endtask
endclass: vmm_env
Everything else from the original example should be ok.