At last, we need to create one more block: the test. This block will derive from the uvm_test class and it will have two purposes:
- Create the env block
- Connect the sequencer to the sequence
You might be wondering why are we connecting the sequencer and the sequence in this block, instead of the agent block or the sequence block.
The reason is very simple: by specifying in the test class which sequence will be going to be generated in the sequencer, we can easily change the kind of data is transmitted to the DUT without messing with the agent’s or sequence’s code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | class simpleadder_test extends uvm_test; `uvm_component_utils(simpleadder_test) simpleadder_env sa_env; function new(string name, uvm_component parent); super.new(name, parent); endfunction: new function void build_phase(uvm_phase phase); super.build_phase(phase); sa_env = simpleadder_env::type_id::create(... endfunction: build_phase task run_phase(uvm_phase phase); simpleadder_sequence sa_seq; phase.raise_objection(.obj(this)); sa_seq = simpleadder_sequence::type_id::create(... assert(sa_seq.randomize()); sa_seq.start(sa_env.sa_agent.sa_seqr); phase.drop_objection(.obj(this)); endtask: run_phase endclass: simpleadder_test |
Code 10.1 – Code for the test class
Line 21 starts a sequencer in the desired sequence for this test.
In Figure 10.1, it’s represented the current state of our testbench.
Code 10.1 – Final state of the testbench
Our testbench is finally ready, now it’s time to execute it and check the results.
The source of the test component can be found here: