Why didn't Verilog testbench didn't phases?
A Verilog testbench would have all its components made of static containers or modules. So each module will have a set of ports or signals that it can utilize to communicate with other testbench components. Since a
module is static, all modules will be created at beginning of the simulation and we won't have to worry about any component getting called without it being created or initialized. It would be useful to have some run-time phases for resetting DUT, driving the actual stimulus and maybe another phase to enable and run checkers.
module driver (...); task reset_phase (...); task run_phase (...); task check_phase (...); initial begin reset_phase (); run_phase (); check_phase (); end endmodule module tb_top; dut d0 (...); driver drvr (...); checker1 chk0 (...); checker2 chk1 (...); endmodule
Verilog testbenches are limited in functionality and are not scalable.
Why System-Verilog testbench require phases ?
System Verilog changes the whole game with the introduction of OOP (Object Oriented Programming) features. This enables the creation of well structured entities that can be reused and deployed when required. These entities are
class objects, and it is possible to create a brand new object in the middle of the entire simulation, say at time Xns. What this means is that testbench components can be created at different times, and hence you could end up calling a component while it hasn't been initialized yet leading to wrong testbench outputs. Also, different companies could have their own hierarchy and arrangement of testbench environments and it would be very difficult to do plug-and-play of verification IPs. So, synchronization between testbench components is a key requirement.
typedef class driver; typedef class monitor; class env; driver d0; monitor mon0; function init_drvr (); d0 = new (); // initialize endfunction function init_mon (); mon0 = new (); // initialize endfunction endclass
How do UVM phases help ?
All testbench components are derived from the same class
uvm_component which follow a particular set of phases that are executed one after the other. So the flow of simulation is more structured and predictable in UVM. Do not confuse this with the phases of compilation, elaboration and simulation of an EDA tool. Those are steps required to prepare the necessary software environment to run a simulation. The kind of phases in UVM start when the simulator runs the code.
The first logical step is to create an object of all the required testbench components, and the next step would be to connect them together. And consequently, the first step is called
build_phase followed by the
connect_phase. Testbenches can grow in complexity and would be pretty useful to display the topography or its hierarchical structure in
end_of_elaboration_phase. As the name suggests, this is the time when everything has been built and connected and the appropriate time to display the structure information. Note that build phase goes from the top of the hierarchy towards the bottom, while connect phase goes from bottom towards the top.
Remember that all of the above phases were executed at 0ns, and time has not advanced even one bit. So now it is time to run the stimulus and exercise different patterns on the design. This is achieved in the
run_phase which can further be broken into sub-phases as shown in the diagram below. Simulation stops time advancement as soon as
run_phase is over, and executes a couple of other steps like
report_phase to wrap up and exit gracefully.
- build_phase - Used to instantiate and create component objects
- connect_phase - Used to connect between various components
- run_phase - Phase when simulation happens and consumes time
- check_phase - Check the output with expected values
- report_phase - Report failures, errors and passes
To add more flexibility, there are
post callbacks to all the runtime phases.
|Phase||Upon Entry||Typical Uses||Exit Criteria|
|build||Top-Level components are instantiated under
|connect||All components have been instantiated||
|end_of_elaboration||Verification environment has been assembled||
||Components run over various run-time phases||
||All data has been collected and summarized|
|check||All data has been collected||Check that no unaccounted for data remain||Test is known to have passed or failed|
|report||Test is known to have passed or failed||
||End of test|
|final||All test-related activity has completed||
||Ready to exit simulator|