Sequence Item (Transaction) Composition

Hi all,
I have seen something called sequence item composition on verification academy website and I tried to implement this but got an error !!!

Actually I have two transaction classes and want to use one transaction class’s attributes in another.

here is the example what I am trying to do:-

class trans1 extends uvm_sequence_item;
rand bit [7:0] data1;
rand bit [7:0] data2;
----
----
endclass

class trans2 extends uvm_sequence_item;
rand trans1 t;
rand bit [15:0] data;
constraint D1
   {
    data == {t.data1, t.data2};
   }
----
----
endclass

so I am using composition of class 1 in 2 class 2 here !! but its not working!!

please let me know if i will randomize trans2 class than Trans 1 will get randomize or not ?? if yes than how???

your answers will be appreciated !!

thanks
~sourabh

In reply to nocsmsourabh:

an object of t has to exist before it can be randomized; create it in the new function of trans2.

In reply to bmorris:

Hi moriris!! thanks
I tried it but didnt’t work !! it will be great help if you can provide example such that trans1 can be randomized (by randomizing trans2).

In reply to nocsmsourabh:

When you say you are getting an error or it doesn’t work, you need to explain the error you saw, and show what you expect if it did work. If you construct t before calling randomize(), it should “work”.

In reply to dave_59:
Thanks Dave !!

Actually what I am expecting if it work is that I want to map trans1’s multiple attributes in single attribute of trans2 so that I can perform operations easily in my reference model on that single attribute.

in my trans2 class I am creating object like this:-

function new(string name = “trans2”);
super.new(name);
t = trans1::type_id::create( “trans1”, this );
endfunction : new

error 1.
Illegal assignment to class mtiUvm.uvm_pkg::uvm_component from class work.tb_top_sv_unit::trans2

2.
Actual input arg. of type ‘class work.tb_top_sv_unit::trans2’ for formal ‘parent’ of ‘create’ is not compatible with the formal’s type ‘class mtiUvm.uvm_pkg::uvm_component’.

since it extends uvm_sequence_item so can’t we use create method in this if not than how to create a object in this class!!

In reply to nocsmsourabh:

In reply to nocsmsourabh:

Hi ,
you need to register the sequence_item with factory in order to use create method, try after including `uvm_object_utils lines in both the trans1 & trans2


class trans1 extends uvm_sequence_item;


`uvm_object_utils(trans1)
rand bit [7:0] data1;
rand bit [7:0] data2;
----
----
endclass
 
class trans2 extends uvm_sequence_item;


`uvm_object_utils(trans2)
rand trans1 t;
rand bit [15:0] data;
constraint D1
   {
    data == {t.data1, t.data2};
   }
----
----
endclass

In reply to ram_88:

Hi thanks !!

yes i already created register factory !!

but i am getting the same error!!

In reply to nocsmsourabh:

please post the complete code , it would be easy to sort out the issue

In reply to ram_88:

I try to understand, what the difference between trans1 and trans 2 is and why you Need this?
It Looks confusing, what you are doing.

In reply to chr_sue:

Hi!!

I want to use one transaction class in other !! how can I do it?? !!! (both the transaction classes extends uvm_sequence_item)

In reply to chr_sue:

Trans 2 have less number of attributes and trans1 have large number of attributes!!

In reply to nocsmsourabh:

What’s the Problem. You don’t have to use all data members of a class and you can even use only part seöects or parameterize the with of the data memmbers.
The key question is, is there a functional reason for using 2 different seq_item types?
The Approach is:
1 seq_item belongs to a sequence class, because it is parameterized for exactly this class.

In reply to chr_sue:

see the code Fragment:

class trans1 extends uvm_seq_item;
  `uvm_object_utils(trans1)
   rand bit [7:0] data1;
   rand bit [7:0] data2;
   rand bit [15:0] data3;
......
endcloass

class my_sequence extends uvm_sequence #(trans);
......
endclas

In reply to chr_sue:

thanks !!

Another thing I noticed was that you’re trying to use two arguments for the constructor:


function new(string name = "trans2");
super.new(name); 
t = trans1::type_id::create( "trans1", this ); // BAD!
endfunction : new

From here, you can see that the constructor only takes ONE argument, which is the name. UVM components (uvm_component) takes two arguments since there’s a hierarchical relationship which is used for build_phase, connect_phase and so on
The correct code for this will be:


function new(string name = "trans2");
super.new(name); 
t = trans1::type_id::create( "trans1"); // GOOD!
endfunction : new

I think this should get rid of both your errors.

In reply to arun.dsouza@arm.com:

This is not a really good coding style. Why do you Need to create your seq_item explicitly in the constructor?
If you are using the `uvm_do macros this will be done automatically in your body task.
Also when using start(item)/finish(item) there is no need to generate your seq_item.

In reply to nocsmsourabh:

here’s a sim of what you are trying to do.

also, there are a few easier ways to do this. you could just put data1 and data2 into a struct; that gives you a single variable to work from. that way you dont duplicate data. You can also just put the aggregate data word, and constraint into trans1, and get rid of trans2. or, you could define a couple functions with a 16b argument for writing and reading the bytes. probably many many other ways…

In reply to bmorris:

The question is still why do you need a nested seq_item?
Could class be a simple class not extended from uv_seq_item?
In the UVM a seq_item is used in a sequence.

In reply to chr_sue:

In reply to bmorris:
The question is still why do you need a nested seq_item?
Could class be a simple class not extended from uv_seq_item?
In the UVM a seq_item is used in a sequence.

I’m simply answering the question presented. At the end of my post, you’ll see that suggested removing trans2 altogether.

I don’t know if he intends to use it in a sequence or not.

In reply to chr_sue:

In reply to arun.dsouza@arm.com:
This is not a really good coding style. Why do you Need to create your seq_item explicitly in the constructor?
If you are using the `uvm_do macros this will be done automatically in your body task.
Also when using start(item)/finish(item) there is no need to generate your seq_item.

Like bmorris, I was just answering the question to solve the compile issue.

I tend to shy away from uvm_do macros because of this. While you do not need to create the transaction for start_item, you definitely need it for finish_item. Otherwise the receiving TLM imp will get a null object.

nocsmsourabh, I’m not sure what you’re trying to accomplish but in this specific context, you don’t NEED to make trans2’s data a random member. You may be better off doing this.


class trans1 extends uvm_sequence_item;
  `uvm_object_utils(trans1)
  rand bit [7:0] data1;
  rand bit [7:0] data2;
  ...
endclass
 
class trans2 extends uvm_sequence_item;
  `uvm_object_utils(trans2)
  rand trans1 t;
  bit [15:0] data;

  function void post_randomize();
    data = {t.data1, t.data2};
  endfunction : post_randomize
  ...
endclass