What is the difference between ovm_transaction and ovm_sequence_item?

Hi Sir,

I am working on AXI 1.0 now and truing to develop AXI OVC. I used ovm_sequence_item for generating sequences for APB protocol.But for AXI one of my college told me use ovm_transaction instead of ovm_sequence_item. what shall i use ovm_sequence_item or `ovm_transation to generate the sequences.

what is the difference between them.
how does the below code works,how are they different from one another???
where the difference comes???

Please guide me

class master_transfer extends `ovm_transaction;
rand [31:0] waddr;
rand [31:0] wdata;
rand [3:0] wsize;
rand [31:0] wlength;

//factory registration

//

endclass

class master_transfer extends `ovm_sequence_item;
rand [31:0] waddr;
rand [31:0] wdata;
rand [3:0] wsize;
rand [31:0] wlength;

//factory registration

//

endclass

If you want to the OVM sequence/sequencer/driver components for generating and sending sequence items, you must extend your class from ovm_sequence_item. It has the extra bookkeeping information needed to arbitrate and route transactions.

The UVM has effectively deprecated uvm_transaction in favor of making everybody use uvm_sequence_item.

In reply to dave_59:

can u please elaborate it? or is their any website where i can get answer for it???

You can find the information you are looking for here:

http://verificationacademy.com/uvm-ovm/Ovm/Sequences/Overview

There is a diagram that explains the class hierarchy on this page, as well as links to other pages which explain more about how to design your sequence_items etc.

hello Sir,
i am working on axi1.0 now .my protocol demands ID tag for every write address,data, response etc trasactions.
how can i make it???

for that i have created d following transactions:-

class write_addr_phase extends ovm_transaction;

rand [31:0] waddr;
rand [31:0] wlen;
rand [31:0] wlsize;

//added contraints
//factory registration
endclass

class write_data_phase extends ovm_transaction;

rand [31:0] data;
rand [31:0] strb;
rand [31:0] wlen;

//added contraints
//factory registration
endclass

class write_transaction extends ovm_transaction;
write_addr wa;
write_data wd;
function new();
wa = new();
wd = new();
endfunction
endclass

#####################################################################################

second doubt: as of my knowledge ovm_sequence_item extends from ovm_transaction;but i have more than 3 transaction(mentioned above).

i am confused from which ovm_transaction , ovm_sequence_item is extended from???

how can i use these transactions in generating the ovn_sequence_item??? and sequences as well??

please help me

Murali Hanumanth

In reply to murali anumanth:

Murali,

Your question doesn’t seem to be correct. The basic ovm_sequence_item class is extended from basic ovm_transaction class. So it is better to extend all your data (or transaction) class from the ovm_sequence_item class, rather than from ovm_transaction. It will give you more flexibilit becuase it has more features.

What do you mean by generating ovm_sequence_item? You can create an OVM sequence by using any of the data item. Data item are derived from ovm_sequence_item. You can combine addr/data & and all related stuffs to a single class, which needs to be extended from ovm_sequence_item. using that new class, you need to creatte sequences.

Let me know if you need more help in understanding.

Murali

In reply to mpattaje:

Hello Sir,

Thank you for your reply.

My question is Can I use ovm_transaction as properties in Ovm_sequence_item??
Is the below code correct??

class write_waddr_phase extends ovm_transaction;
     rand [3:0] awid ;
     rand [31:0] waddr; 
     rand [31:0] wlen; 
     rand [31:0] wlsize;
    //added contraints
    //factory registration
 endclass

  class write_wdata_phase extends ovm_transaction;
       rand [31:0] data;
       rand [31:0] strb;
       rand [31:0] wlen;
       //added contraints
       //factory registration
   endclass

class write_wresp_phase extends ovm_transaction;
        rand [3:0] bid;
 endclass

 class read_raddr_phase extends ovm_transaction;
     rand [3:0] arid ;
     rand [31:0] raddr; 
     rand [31:0] rlen; 
     rand [31:0] rsize;
    //added contraints
    //factory registration
 endclass

  class read_rdata_phase extends ovm_transaction;
       rand [31:0] rdata;
       rand [3:0] rid ;
       //added contraints
       //factory registration
   endclass


  //building the ovm_sequence_ITEM

   class basic_transfer extends ovm_sequence_item;
     write_waddr_phase  wap;
     write_wdata_phase  wdp;
     write_wresp_phase  wrp;
     read_raddr_phase   rap;
     read_rdata_phase   rdp; 
  
 `ovm_component_utils_begin(basic_transfer)
    `ovm_field_object ( wap ,OVM_ALL_ON)
    `ovm_field_object ( wdp ,OVM_ALL_ON)
    `ovm_field_object ( wresp ,OVM_ALL_ON) 
    `ovm_field_object ( rap ,OVM_ALL_ON)
    `ovm_field_object ( rdp ,OVM_ALL_ON)
   `ovm_component_utils_end
endclass

    class my_sequence extends ovm_sequence#(basic_transfer);
     //fac reg
     
     virtual task body();
      `ovm_do_with(req,{wap.waddr=8'h 0000_0000;wlen=2;})
      `ovm_do_with(req,{wap.wdata=8'h AAAAA_0000;wstrb=1001})
       ...
       ...
      endtask
     endclass

Now i want to set ID tag for each transaction with in a sequence and as well as for each each sequence.
where can i use set_transaction_id method to set the id tag for each each transaction class.

how can i make it ?

#####################################################################################

Murali Hanumanth

In reply to murali anumanth:

Murali,

  1. Yes, you can use ovm_transaction class object in the ovm_sequence_item class. But why do you need to do that? For an user, there is no difference between an ovm_transaction class & ovm_sequence_item class. They can be used in the same manner.
  2. There is no such hierarchy needed as you did, which is more confusing
  3. Just get rid of basic_transfer class. Whatever sequence you need to create, do that in my_sequence class by creating the wap/wdp etc objects there.
  4. My one more suggestion is to combine address-phase & data-phase into a single transaction (sequence item) so taht it will be easy for post-processing.
  5. set_transaction_id can be used only after you create that transaction. You can do the following in the my_sequence class:
virtual task body();

  wap = write_waddr_phase::type_id::create("wap");
  wdp = write_waddr_phase::type_id::create("wdp");

  start_item(wap);
  wap.set_transaction_id(1);
  assert(wap.randomize());
  finish_item(wap);

  start_item(wdp);
  wdp.set_transaction_id(1); // I hope you want to give same ID for a seq
  assert(wdp.randomize());
  finish_item(wdp);

endtask

In reply to mpattaje:

Hi mpattaje,
Thank you for your fruitful and patience replies.!!!

So you are saying that ovm_seq_item is not requirred.sequences(my_sequence) can be generated by using the ovm_trasactions(wap,wdp).

I tried it . It is giving an Error stating

ERROR : "this.wap of type ‘axi_waddr_phase’ does not match item of type 'ovm_sequence_item ".

I didnot use use any ovm_sequence_item here.

please reply,
regards,
Murali.A

If you want to send transactional data to an ovm_driver via a sequencer then you have to create a sequence_item extended from ovm_sequence_item class. An ovm_transaction will not have a number of hooks that are needed for the sequence/sequencer/driver communications and you shouldn’t be using it for this purpose - that’s why you got an error.

When designing your sequence_item for the AXI bus you should consider what information is needed for the driver to be able to execute an AXI bus access. If you are going to specify each phase in the AXI bus protocol there is nothing to stop you having all the relvent fields in your sequence_item or putting them into objects which are part of the sequence_item.

In reply to mperyer:

hello mperyer,
you want me to declare all the variables(waddr,wsize,wlen,wdata,wstrobe,raddr,…) in ovm_sequence_item itself and generate sequences using this ovm_sequence_item??

Is this what you are trying to say??

if it so? then how can i set IDtags (awid,wid,bid,arid,rid) for each individual transactions??

how can i set ID tag for ovm_transaction ( waddr,wdata,wresp transactions).

please do reply, i have stuck at this point.
regards,
Murali.A

In reply to murali anumanth:

Murali,

ovm_seq_item class is just extension of ovm_transaction class. By using that in the place of ovm_tansaction, you can get rid of your error & it is helpful for sequencer working. And all the methods & stuffs supported in ovm_transaction class is also supported in ovm_seq_item class. You just need two: ovm_seq_item class for wap, wdp et & ovm_sequence class for making a sequence out of them.

The way of supplying tagID will not change by the above change. You can do it by many ways.

Please let me know if it is still confusing.

In reply to murali anumanth:

hi mpattaje,

Thank you for your fruitful reply.
i got you, u are saying “to use ovm_sequence_item instead of ovm_trasaction and all the methods of ovm_transaction is also applicable for ovm_sequence_item as it is its subclass”.Till here its clear for me.

but my doubt is where do i actually declare write_addr_phase(wap) and write_data_phase(wdp) and so on…? How can i differentiate these phases seperatly??

please , can you give example of basic model of how my ovm_sequence_item should be for axi protocol???

Thanking You,
Murali.A

In reply to murali anumanth:

You have to declare & create them in ovm_sequence.

In reply to mpattaje:

hello patteji,

below example is your previous reply (24 july ), in this example you asked me to create transactions wap and wdp( wap,wdp extends ovm_transaction)inside my_sequence( extends ovm_sequence).

in the yesterdays reply you asked me not use ovm_trasactions.

According to you what actually wap is extending from in the below example.???
###############################################################################

virtual task body();

wap = write_waddr_phase::type_id::create(“wap”);
wdp = write_waddr_phase::type_id::create(“wdp”);

start_item(wap);
wap.set_transaction_id(1);
assert(wap.randomize());
finish_item(wap);

start_item(wdp);
wdp.set_transaction_id(1); // I hope you want to give same ID for a seq
assert(wdp.randomize());
finish_item(wdp);

endtask
###############################################################################

In reply to mpattaje:

Murali,

Others & I here already indicated that ovm_seq_item is extension of ovm_transactions. Therefore wap/wdp should extend from ovm_seq_item class. They are created at ovm_sequence class, as you understood correctly.

Hope you are clear now.

Muralikrishna Pattaje

In reply to mpattaje:

Hi Pattaji,

Is this right??

class write_waddr_phase extends ovm_sequence_item;
     rand [3:0] awid ;
     rand [31:0] waddr; 
     rand [31:0] wlen; 
     rand [31:0] wlsize;
    //added contraints
    //factory registration
 endclass
 
  class write_wdata_phase extends ovm_sequence_item;
       rand [31:0] data;
       rand [31:0] strb;
       rand [31:0] wlen;
       //added contraints
       //factory registration
   endclass
 
class write_wresp_phase extends ovm_sequence_item;
        rand [3:0] bid;
 endclass
 
 class read_raddr_phase extends ovm_sequence_item;
     rand [3:0] arid ;
     rand [31:0] raddr; 
     rand [31:0] rlen; 
     rand [31:0] rsize;
    //added contraints
    //factory registration
 endclass
 
  class read_rdata_phase extends ovm_sequence_item;
       rand [31:0] rdata;
       rand [3:0] rid ;
       //added contraints
       //factory registration
   endclass
 
 
 

 //building the ovm_sequence
 
class my_sequence extends ovm_sequence;
     write_waddr_phase  wap;
     write_wdata_phase  wdp;
     write_wresp_phase  wrp;
     read_raddr_phase   rap;
     read_rdata_phase   rdp; 
 
virtual task body();
  wap = write_waddr_phase::type_id::create("wap");
  wdp = write_waddr_phase::type_id::create("wdp");
  ...
  ...
  ...
  start_item(wap);
  wap.set_transaction_id(1);
  assert(wap.randomize());
  finish_item(wap);
 
  start_item(wdp);
  wdp.set_transaction_id(1); // I hope you want to give same ID for a seq
  assert(wdp.randomize());
  finish_item(wdp);
  
 ...
 ...
 ...
endtask
endclass

please correct me ,if iam wrong.
regards,
Murali

In reply to murali anumanth:

Yes, perfectly fine, if that compiles & simulates :)

In reply to murali anumanth:

Hi Dave,

In UVM 1.1.c package which is the latest UVM package, I do see uvm_transaction class and also in UVM class reference manual. So is really uvm_transaction is deprecated or not?

Second, what is actually difference between uvm_transaction class and uvm_sequence_item? I read somewhere that if you do not want to randomize your transaction in sequences the derive your transaction item from uvm_transaction otherwise use uvm_sequence_item so that you can use inline constraint to provide more constraints to your transaction item.

Can you please elaborate more on the difference?

Thanks & Regards
Pratik Shah

In reply to Pratik Shah:

The PDF reference manual has not been updated in a while, but the source code and HTML is what you should be looking at. It says

// CLASS: uvm_transaction
//
// The uvm_transaction class is the root base class for UVM transactions.
// Inheriting all the methods of uvm_object, uvm_transaction adds a timing and
// recording interface.
//
// This class provides timestamp properties, notification events, and transaction
// recording support.
//
// Use of this class as a base for user-defined transactions
// is deprecated. Its subtype, <uvm_sequence_item>, shall be used as the
// base class for all user-defined transaction types.

Use of any UVM class is independent on how you randomize it. You can always add random variables and constraints to any UVM class. And you can add constraints to any UVM class by extending it, or adding inline constraints. You must use a class extended from uvm_sequence_item to send from a sequence.