Jump to content
Sign in to follow this  
drianf0

type_id of the uvm_sequence_base

Recommended Posts

Hello,

I would like to write a generic virtual sequence, which will spawn another sequences. Since I would like to to keep it generic, the type of spawned sequences should be defined by the overriding facility of the factory.

My problem is that the code:

class vir_seq extends uvm_sequencer#();
...
virtual task pre_body();
uvm_sequence_base seq;
seq = uvm_sequence_base::type_id::create("my_name");
endtask;
...

instead of creating the overriding type (let's say my_seq), creates vir_seq.

One comment: I use the uvm_sequence_base instead of the uvm_sequence#(T) because I don't want to have the parametrized vir_seq (from my experience parameters always imply troubles at the end...). Is any other, more clean way, to avoid parameters ? I know, the that the uvm_sequence_base inherits type_id from uvm_sequence_item (so by default, without overriding, an item should be created). However, fact that I get every time vir_seq confuses me.

To understand better the issue and isolate the problem, I end up with the following simple example:

import uvm_pkg::*;
`include <uvm_macros.svh>
   
module top;
   test a();
endmodule // top

class seq extends uvm_sequence#();

   `m_uvm_object_registry_internal(seq, seq)  //   <- MACRO 1
//   `uvm_object_utils (seq)
   
   function new();
      super.new();
      $display(uvm_sequence_base::type_id::type_name ); //  <- DISPLAY 2
   endfunction // new

endclass // seq

program automatic test;

   task start();
      seq s;
      $display(uvm_sequence_base::type_id::type_name );   // <- DISPLAY 1 
      s = new();            
   endtask // start
      
   initial
      start();
   	
endprogram // test

Display 1, as expected, returns always 'uvm_sequence_item'. Output of Display 2 depends whether the Macro 1 (which is a part of `uvm_object_utils) is commented or not, returning respectively 'uvm_sequence_item' or 'seq'

I would be grateful for an explanation why the above simulation doesn't follow my expectations.

Thank you in advance.

Regards,

Adrian

Share this post


Link to post
Share on other sites

However, fact that I get every time vir_seq confuses me.

It seems this is due to a simulator bug. Consider:

class C1;

int i;

endclass

class C2 #(type T) extends C1;

endclass

class C3 extends C2#(int);

int i;

function void f();

C1::i = 123;

endfunction

endclass

With Questa, f() writes this.i, not C1::i. The statement:

seq = uvm_sequence_base::type_id::create();

is slightly more complicated since uvm_sequence_base does not have a type_id, but it inherits one from uvm_sequence_item. Still, the type_id used (with Questa) is this.type_id, which is similar to f() above writing this.i.

A possible workaround is to call create() on the type_id of the parameterized base, for example:

task pre_body();

typedef uvm_sequence#(uvm_sequence_item) that;

if (!$cast(seq, that::type_id::create("my_name"))) BigBadError();

endtask

Now, the compiler will not use this.type_id, but that::type_id which is the type_id of uvm_sequence_item.

Erling

Share this post


Link to post
Share on other sites

Dear Erling,

Thanks a lot for your reply. The issue has been reported to Mentor Graphics. They confirmed it is a bug ( Defect DVT-31448 ).

Your idea of possible workaround of course works.

Adrian

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×