Last Updated: September 1, 2014
The anticipated culmination of the UVM for Candy Lovers series is revealed in this post. Using the created verification components and writing out a test class, the actual simulation is prepared to run.
Test
This particular example will show you how to develop a variety of sugar-free jelly beans in the form of a gift box. The test class is described below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | class jelly_bean_test extends uvm_test; `uvm_component_utils(jelly_bean_test) jelly_bean_env jb_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); begin jelly_bean_configuration jb_cfg; jb_cfg = new; assert(jb_cfg.randomize()); uvm_config_db#(jelly_bean_configuration)::set (.cntxt(this), .inst_name("*"), .field_name("config"), .value(jb_cfg)); jelly_bean_transaction::type_id::set_type_override(sugar_free_jelly_bean_transaction::get_type()); jb_env = jelly_bean_env::type_id::create(.name("jb_env"), .parent(this)); end endfunction: build_phase task run_phase(uvm_phase phase); gift_boxed_jelly_beans_sequence jb_seq; phase.raise_objection(.obj(this)); jb_seq = gift_boxed_jelly_beans_sequence::type_id::create(.name("jb_seq"), .contxt(get_full_name())); assert(jb_seq.randomize()); `uvm_info("jelly_bean_test", { "\n", jb_seq.sprint() }, UVM_LOW) jb_seq.start(jb_env.jb_agent.jb_seqr); #10ns ; phase.drop_objection(.obj(this)); endtask: run_phase endclass: jelly_bean_test |
The build_phase
executes three actions:
- the registration of the configuration of the simulation into the database (line 17)
- the direction on the usage of the
sugar_free_jelly_bean
transaction rather than thejelly_bean_transaction
(line 19) - the creation of the
jelly_bean_env
(line 20)
Lines 13 to 18 were provided for future configuration uses, and were added as placeholders. An explanation of the configuration was omitted from this series due to the lack of configuration needs. Please see Configurations if you are interested in this topic.
In the run_phase
, the created gift_boxed_jelly_beans_sequence
is ready to run.
Configuration
For reference, the source code for the jelly_bean_configuration
class is inserted below.
1 2 3 4 5 6 7 | class jelly_bean_configuration extends uvm_object; `uvm_object_utils(jelly_bean_configuration) function new(string name = ""); super.new(name); endfunction: new endclass: jelly_bean_configuration |
Top
Before proceeding with the simulation, there is a need to write the top module, which instantiates the DUT module, registers the jelly_bean_if
in the resource database, and runs the test. The top module is responsible for clock generation as well.
Update (April 2, 2014): In this tutorial, we used
uvm_resource_db
to store thejelly_bean_if
(lines 15 and 16). UVM recommends usinguvm_config_db
instead ofuvm_resource_db
as the former is more robust. You can replace the lines 15 and 16 with:
uvm_config_db#( virtual jelly_bean_if )::set( .cntxt( null ), .inst_name( "uvm_test_top.*" ), .field_name( "jelly_bean_if" ), .value( jb_slave_if ) );For more information about the configuration database, please see Configuration Database and Configuration Database Revisited.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | module top; import uvm_pkg::*; reg clk; jelly_bean_if jb_slave_if(clk); jelly_bean_taster jb_taster(jb_slave_if); initial begin // clock generation clk = 0; #5ns ; forever #5ns clk = ! clk; end initial begin uvm_resource_db#(virtual jelly_bean_if)::set (.scope("ifs"), .name("jelly_bean_if"), .val(jb_slave_if)); run_test(); end endmodule: top |
Simulation
It is now time to compile and run the simulation, as part of the finale. Posted below are the results for the simulation.
UVM_INFO @ 0: reporter [RNTST] Running test jelly_bean_test... UVM_INFO jb.sv(481) @ 0: uvm_test_top [jelly_bean_test] ----------------------------------------------------------------------- Name Type Size Value ----------------------------------------------------------------------- jb_seq gift_boxed_jelly_beans_sequence - @772 num_jelly_bean_flavors integral 32 'h2 req object - rsp object - ----------------------------------------------------------------------- UVM_INFO jb.sv(406) @ 40: uvm_test_top.jb_env.jb_sb [jelly_bean_scoreboard] You have a good sense of taste. ---------------------------------------------------------------- Name Type Size Value ---------------------------------------------------------------- jb_tx sugar_free_jelly_bean_transaction - @818 flavor flavor_e 3 CHOCOLATE color color_e 2 RED sugar_free integral 1 'h1 sour integral 1 'h1 taste taste_e 2 YUCKY ---------------------------------------------------------------- UVM_INFO jb.sv(406) @ 60: uvm_test_top.jb_env.jb_sb [jelly_bean_scoreboard] You have a good sense of taste. ---------------------------------------------------------------- Name Type Size Value ---------------------------------------------------------------- jb_tx sugar_free_jelly_bean_transaction - @834 flavor flavor_e 3 CHOCOLATE color color_e 2 GREEN sugar_free integral 1 'h1 sour integral 1 'h0 taste taste_e 2 YUMMY ---------------------------------------------------------------- UVM_INFO jb.sv(406) @ 80: uvm_test_top.jb_env.jb_sb [jelly_bean_scoreboard] You have a good sense of taste. ------------------------------------------------------------ Name Type Size Value ------------------------------------------------------------ jb_tx sugar_free_jelly_bean_transaction - @842 flavor flavor_e 3 APPLE color color_e 2 GREEN sugar_free integral 1 'h1 sour integral 1 'h1 taste taste_e 2 YUMMY ------------------------------------------------------------ UVM_INFO jb.sv(406) @ 100: uvm_test_top.jb_env.jb_sb [jelly_bean_scoreboard] You have a good sense of taste. ------------------------------------------------------------ Name Type Size Value ------------------------------------------------------------ jb_tx sugar_free_jelly_bean_transaction - @850 flavor flavor_e 3 APPLE color color_e 2 RED sugar_free integral 1 'h1 sour integral 1 'h0 taste taste_e 2 YUMMY ------------------------------------------------------------ |
With these six posts, the basic UVM tutorial is complete. While this jelly-bean machine is hypothetical, it has the ability of being rephrased with other DUT. In the next possible opportunity, I would like to review other topics omitted from these posts, such as Virtual Sequence. I hope this tutorial assisted in your further understanding on UVM.
Great website and coding example. I am still looking for a means to download the jellybean taster example.
Linc
Linc,
I added a link to download the source code.
Can you tell me the need to randomize the sequence in the test?
Thanks,
Arun
Hi Arun,
The
jb_seq
is an object ofgift_boxed_jelly_beans_sequence
class. Thegift_boxed_jelly_beans_sequence
class has onerand
property, callednum_jelly_bean_flavors
. Thejb_seq.randomize()
randomizes thisnum_jelly_bean_flavors
.Hi ,
Really nice article..
but have doubt like why have u randomised gift_box_jelly_bean sequence because it is getting randmised in the same sequence class.
And one more thing.can u please explain the concept of config db and resource db and the syntax direction to use it.
Thanks
The
gift_boxed_jelly_beans_sequence
is randomized in order to randomize its knob (num_jelly_bean_flavors
). Regarding the configuration database, I have written a new article. Let me know if you have further questions. Theuvm_config_db
provides a convenience interface to theuvm_resource_db
. You don’t need to use theuvm_resource_db
.Hi Keisuke,
Do you have any good idea for a chip level pin automation configuration in UVM verification environment? For example, we always have some pin config to put the chip into some specific working mode, such as Normal Function mode, Function Test mode, Scan mode, etc. we could use pullup/pulldown as well as register configuration setting to implement this function in module based testbench. But how do I do it in class based testbench UVM?
Thx,
Tong
Hi Tong,
If you need to drive these primary pins from a class-based object, I would probably create an interface that includes these pins and pass it to the testbench using a
uvm_config_db
.The UVM-side gets the interface via the
uvm_config_db
and stores it as a virtual interface and drives it as needed.Having said that, I guess the test mode and the scan mode might not use the normal tests that the UVM testbench provides. If that is the case, you can assign the test mode and the scan mode using the parameters of your testbench, instead of driving them from the UVM testbench.
When you run a simulation, you can set the TEST_MODE and SCAN_MODE by
defparam top.TEST_MODE=1
, etc.Hi Keisuke,
In the above jelly_bean_test, if I am calling a C function in the task and assign the return value to some local variable or jelly_bean_test property, then how do I print that value ?
EX:
You can use
$display("%h",p)
or the`uvm_info
macro as usual. Calling a C-function is transparent to the caller. You can use a C-function as if it is a SystemVerilog function.Great tutorial – helped me a lot. Thanks!
I’m glad it was helpful. Let me know if you want any new topics.
Thanks, Keisuke. Thats a very complete and well explained tutorial. Very helpful.
I am glad to hear that the tutorial was helpful.
Hello Keisuke,
Could you please tell me what role dose jelly_bean_configuration play here? In general how is it useful in testbench?
The
jelly_bean_configuration
does nothing here. I added this class as a placeholder. The configuration object is used to configure the test bench. Please see Configurations for more information.Keisuke,
How to decide what string to use for “.inst_name” argument in the uvm_config_db’s set function? Can we use any arbitrary string for this argument?
You can use an arbitrary string for the
inst_name
as long as the object who gets the field (getter) also knows theinst_name
. But typically we use the instance name of the getter (often with a wildcard,*
, if you want multiple objects to get the field) to avoid unnecessary dependency.Hello Keisuke,
Thanks for all your answers. I have an issue while i try to run the jelly bean example in this tutorial. The exact error is
UVM_ERROR @ 50: run [TEST_DONE_NOHIER] A non-hierarchical object, ‘common.run’ () was used in a call to uvm_test_done.drop_objection(). For this objection, a sequence or component is required.
UVM_FATAL @ 50: run [OBJTN_ZERO] Object “common.run” attempted to drop objection ‘run’ count below zero
I know that without looking at the code it will be difficult to say what is going wrong but any idea on what could be going wrong? I don’t know where to start looking for to fix this. Also how do we debug a uvm test bench, specifically is there a switch which will enable printing of the sequence of task call like a call stack in other languages?
It seems that the first argument of the
drop_objection
call is incorrect. You can specify+UVM_OBJECTION_TRACE
to trace objection activities when you run a simulation.Thanks Keisuke. I had make a mistake in the drop_objection argument. I had given “phase” as the argument instead of the the test object
Hi Keisuke,
Thanks for this awesome tutorial.
I’ve download the source code tutorial_1_to_6.sv and try to re-run it in EDA playground.
After fixing some syntax errors, I ran into an error which says “segmentation fault (core dumped)” thatI have not any clues.
Could you help me to take a look?
Here is the link:
http://www.edaplayground.com/x/BUb
Thank you for porting the code to EDA Playground. I found a couple of problems in your code. Please do the followings:
+UVM_TEST_NAME
to+UVM_TESTNAME
in the Compile & Run Options field on the left."jelly_bean_if"
to"jb_if"
on line 22 of agent.sv.uvm_resource_db
on line 60 of agent.sv touvm_config_db
like you did for thejelly_bean_driver
.Hi Keisuke,
Thanks for your time to help fix it.
I found if I fix all the errors in the code, except for changing the UVM lib from 1.2 to 1.1d, I still got “segmentation fault (core dumped)” error.
But if I change to 1.1d library, the code works.
Could you explain a little bit why change from UVM1.2 to UVM1.1d can resolve the problem?
Thanks in advance.
Best Regards,
Rui Huang
The code is based on UVM 1.1d, not on UVM 1.2. That doesn’t justify the core dump though.
Hi Keisuke,
1. In module top , Is test instantiation not required ?? , if so why ??
2. What does run_test() do ?
The
run_test()
task calls therun_test()
task of theuvm_root
class. It executes all the phases including thebuild_phase()
that dynamically creates a test-bench. So, you don’t need to instantiate the test-bench in the top-module.Can you help me with a query not related to UVM but SV?
Yes.
Hi Keisuke,
Can you Please clarify about the difference when we call seq in run_phase (seq.start()) and specifying the default sequence in build phase. Can you Please explain.
If you have a default sequence, it is executed automatically at the beginning of the specified phase (such as the
main_phase
). If you usestart()
, you can fully control its execution (timing, conditional execution, and the number of executions, etc.).Thank you so much for this amazing website with nice explanation.(y)
I’m glad it was useful.
Hi Keisuke,
Thanks for the nice article.
I have a test say “class test_x extends base_test”
And i have few random variables declared inside test_x.
Now if I write few constraints as part test_x, will those be randomized by default?
Because we are not explicitly calling test_x.randomize() anywhere.
Unless you call the
randomize()
method, variables in an object are not randomized. Iftest_x
is the top-level component, you could callthis.randomize()
from itsbuild_phase
for example.In Line 19: jelly_bean_transaction::type_id::set_type_override(sugar_free_jelly_bean_transaction::get_type());
Should you not call all the set_type_overrides before the super.build()?
I called the
set_type_override
in thebuild_phase
becausejelly_bean_transaction
is created in therun_phase
.