Vous êtes sur la page 1sur 10

UVM Document

UVM_factory

One more example: In your Ethernet verification environment, you have different drivers to support
different interfaces for 10mbps,100mps and 1G. Now you want to reuse the same environment for 10G
verification. Inside somewhere deep in the hierarchy, while building the components, as a driver
components ,your current environment can only select 10mmps/100mps/1G drivers using configuration
settings. How to add one more driver to the current drivers list of drivers so that from the testcase you
could configure the environment to work for 10G.

Using the uvm fatroy, it is very easy to solve the above two requirements. Only classs extended from
uvm_object and uvm_component are supported for this.

There are three basic steps to be followed for using uvm factory.

1) Registration
2) Construction
3) Overriding

The factory makes it is possible to override the type of uvm component /object or instance of a uvm
component/object in2 ways. They are based on uvm component/object type or uvm
compoenent/object name.
UVM_REG
A reg block generally corresponds to a design component with its own host processor interface(s),
address decoding, and memory-mapped registers and memories. All data values are modeled as fields.
Fields represent a contiguous set of bits. Fields are wholly contained in a register. A register may span
multiple addresses. The smallest register model that can be used is a block. A block may contain one
register and no memories, or thousands of registers and gigabytes of memory. Repeated structures may
be modelled as register arrays, register file arrays, or block arrays. When we use blocks we can use read
and write methods in the corresponding abstraction class or basically a class where your model has been
defined.
Reg block = reg field + memory + memory block+
Register model is responsible for accessing the correct address and it never uses address but names to
read and write the correct field register or memory.
Register packages provide methodology and automation to enable productive reusable register related
verification logic.
Using this your registers are independent and not tied to any protocol. Due to this if the protocol
changes then your models wont change




RGM_DB = Root component for all memories and registers in the design
RGM_OP = RGM operations that model read and write access to register and memories
RGM_SEQ = read/write applied to registers and memories using register sequencer
RGM_SEQR = Dedicated sequencer for register operations
Notes from mentor graphics
Anatomy of a UVM component

The build method is top down and hence as every component gets created its build phase is
called and in turn this creates sub components.
The connect is a bottom up method
The driver and the sequencer are connected using sequence port
Driver has sequence_item_port and sequencer has sequence_driver_export
Registeration takes place in the following fashion type::type_id::create(name, parent)
The uvm test bench is divided into two separate parts



Here in the above picture we can see tow set hireacrhy
1. For data(The data is lighter in hirerachy and over head and that s good this as we are going to
use a lot of data)
The data constructor has just one argument(name)
Once the env gets created objects get created and hence they are dynamic.
2. For components
For the uvm_sequence we extend it from uvm_sequence_item and not from uvm_transaction
as uvm_sequence_item contains more methos to help connect the sequencer to the driver.They
are created at runtime at time zero, hence they are quasi static.

The sequence data is registered with the uvm_objects util macro while each component is registered
with the uv_component macro

Using resource DB and config DB
static function void set(input string scope, input string name, Tval, input
uvm_object accessor=null)
uvm_resource_db#(bit)::set("CHECKS_DISABLE", "disable_scoreboard", 1,this)
static function bit read_by_name(input string scope, input string name, inout
T val, input uvm_object accessor=null)
uvm_resource_db#(bit)::read_by_name("CHECKS_DISABLE", disable_scoreboard", disable_sb)

It is important to note that all of the methods of the uvm_resource_db class are static so they must be
called using the scope resolution operator, ::. As mentioned previously, the classes are type-
parameterized by the type of the resource so this has to be specified. In the examples above, we're
using resources of type bit. The first argument of the set() function is the string scope which one can
think of as a category. Multiple elements can be added to the database with the same scope, but the
name, which is the second argument, must be unique across all elements having the same type and
scope. However, if you are accessing an element by type where the scope is the only lookup parameter,
then there can only be one object of that type using that scope name. The third argument of the set()
function is the actual value that is to be stored in the database. The final argument this is for bugging.
It allows messages to show where the set() originated. If this argument is not used, then the default is
null. In this example, disable is being set to 1. When retrieving the value in the scoreboard, the
read_by_name() function is used. The first two arguments of the function are the same. The value is
being looked up by the scope and the name. The value that is retrieved is stored in the disable_sb
bit through an inout function argument. The read_by_name() function also returns a b

Customizing your environment______ DVCon UVm
Factory
We can register things to the factory . Objects and Components.
Now lets say you have a data packet going in. For some test you want to send a specific short packet
which has length <30
Hence
Class datapacket extends uvm_sequence_item;
rand bit[5:0] length;
rand bit[7:0] data;
constraint c {length > 10; length<64;}
endclass
class short_packet extends datapacket;
constraint c{length < 30};
endclass
now during verification if you want to override packet with short packet then if you have used the create
methods thruout, It will check if there is any override and if there is any then it will use the overridden
sequence
eg:
two ways to override

1. Lets say you want to over ride the datapacket with short_packet. Then in the test you will do
datapacket::type_id::set_type_override:short_packet,get_type());
in general
object::type_id::set_type_override:derived_object,get_type());
Now u just want to replace the data packet in agent zero with a specific packet
Datapacket::type_id::type_override:short_packet,get_type(),my_env.agent*0+.*);
2. Lets say you want to override a component then you can do a instance based over ride
My_driver::type_id::set_inst_override:driver_v1,get_type(),my_env.agent*1+);
Doulos _ uvm TLm and Sequences
Everything gets created during the build phase and then things get connected during the connect phase.
Within uvm tlm you have put, get peek which are blocking as well as try_get, try_peek, try_put which
are non blocking and write

If you use put then you will never loose a transaction because it will never go to the next transction until
this is put on the bust same for get and peek. With these three you will never miss a transaction going
out or coming in.
In uvm tlm the producer puts a transaction while the consumer implements it.. It does not pull it
So in uvm both pull and push are used
In put control and data both go from left to right
In pull control goes left to right and data goes from right to left




Here the driver has the port and the sequencer has the export
Now the one who has the port demands an interface while the sequencer provides one. Hence there is a
contract between the driver and the sequencer
The monitor is connected with a type of port-export known as the analysis port. This is a broadcast port.
The cool thing about this port is wether you connect the monitor to zero one or more subscriber it
doesnt matter

Driver Sequencer = static -> Created only once
Sequences, transactions, sequence_items = dynamic->


Coverage
Now if you want to do protocol coverage/ bus coverage then you have to put it into the agent but if you
want to do function coverage then you put it outside the agent a you want to keep that agent for that
bus no matter what the design.