Jump to content

Abstract cast

Recommended Posts

I have an application where I have two objects, the only thing I know for sure is they are both extensions of uvm_object. However, I can do something useful if I know if one is an extension of the other.

It would be nice if uvm_object_wrapper had some kind of is_a() function.

class uvm_object_wrapper;
    virtual function bit is_a_base_of(uvm_object obj);
        // macro generated extension would implement a $cast() to test the is_a relationship.

That way I could find out if the type of Y is an extension of the type of X.


Even better would be an is_a method that can be used like:


But I think implementation would be more complicated.


Link to comment
Share on other sites

You probably need to explain what the useful thing you want to do if you did know. There's probably a very different way to approach it.

Also, are you aware of the difference between X.get_object_type() versus classX::get_type()

if you have

ClassX X;

X = ClassX::type_id::create(...);

if (ClassX::get_type() != X.get_object_type()) // then you know X has an object whose type is an extension of ClassX

Link to comment
Share on other sites

In my other thread I have a function

function uvm_sequence_item_queue get_completed_items();
      get_completed_items = m_completed_items;

I wanted it to have a type_filter parameter. So if you passed in a type_filter, rather than returning everything, it would return a filtered subset. Since I didn't figure that out, I create a parameterized helper function that uses $cast to do the test.

This following example should be a little more clear. I have an incomplete function called filter(). What should I put in place of my comment /* x is_a type_filter */?

program test;

import uvm_pkg::*;

class A extends uvm_object;
   function new (string name = "A");
   endfunction // new
endclass // A

class AA extends A;
   function new (string name = "AA");
   endfunction // new
endclass // AA

class B extends uvm_object;
   function new (string name = "B");
   endfunction // new
endclass // B

typedef uvm_object uvm_object_queue[$];

function uvm_object_queue filter(const ref uvm_object q[$], input uvm_object_wrapper type_filter);
   filter = q.find(x) with (/* x is_a type_filter */);
endfunction // filter

initial begin
   A a;
   AA aa;
   B b;
   uvm_object o[$];
   uvm_object_wrapper type_filter;
   uvm_object f[$];

   a = new("a");
   aa = new("aa");
   b = new("b");

   // is_a A
   $write("\n\n\n ---- is a A ----\n");
   f = filter(o,A::get_type());
   // should yield two objects in f: a and aa.

   // is_a AA
   $write("\n\n\n ---- is a AA ----\n");
   f = filter(o,AA::get_type());
   // should yield one object in f: aa

   // is_a B
   $write("\n\n\n ---- is a B ----\n");
   f = filter(o,B::get_type());
   // should yield one object in f: b


endprogram // test


Link to comment
Share on other sites

This is something that could be added to the factory, but for now you can add this virtual method to your classes

virtual function bit is_a(uvm_object_wrapper am_a);
     if (my_type::get_type() == am_a.get_object_type())
          return 1;
          return super.is_a(am_a);
The base class returns false if no match.
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...