Is it good idea to declare config object in uvm_sequence_item

1.6k views Asked by At

I need to parametrize the uvm_sequence_item as my signal width change based on configuration.
Is it good idea to declare configuration object inside uvm_sequence_item?

Or is it possible to parametrize uvm_sequence_item like following?:

class my_sequence#(int width) extends uvm_sequence_item;

2

There are 2 answers

1
Vineeth VS On

The best way is to use the factory override mechanism instead of the config_db mechanism to choose chose the parameterized sequence/_item you want.

See below links. Its already mentioned there.

https://verificationacademy.com/cookbook/usingfactoryoverrides

https://forum.verificationacademy.com/forum/verification-methodology-discussion-forum/uvm-forum/31530-parameterized-uvm-sequence-item-and-usage-sequence

4
Tudor Timi On

The idea is that if you have a certain base class with a certain parameter, then subclasses that define different values for that parameter are not type compatible:

// base class
class my_base_class #(int PARAM = 1);
endclass

Subclasses with PARAM values 2 and 3 are not type compatible.

What you can do in your case is the following:

// common base class, no subclass
class my_base_item extends uvm_sequence_item;
  // ...
endclass

// parameterized class
class my_param_item #(int PARAM = 1) extends my_base_item;
  // ...
endclass

In your sequence you define your items as my_base_item:

class my_sequence extends uvm_sequence;
   my_base_item item;

   task body();
     item = my_base_item::type_id::create("item");
   endtask
endclass

And somewhere you set a type override depending on your config:

my_base_item::type_id::set_type_override(my_param_item #(32))::get_type(), 1);

I didn't test this out but it should work, because all parameterizations of 'my_param_item are still of type my_base_item.

In the driver you have to do some casting based on your param value:

task drive();
  // ...
  case (param) begin
    16:
      begin
        my_param_item #(16) m_item;
        $cast(m_item, item);  // item is the base item you got from the sequencer
        do_drive_16(m_item);
      end
    32:
      // ...
  end
endtask

You have to do casting like this, because you can't declare parameterizations based on dynamic values. The parameters have to be known at compile time.