Jump to content
Sign in to follow this  
adhingra

creating parameterized class (virtual interface) using factory

Recommended Posts

I am trying to create a class using factory type_id:: create method and pass virtual interface type as parameter. But i am getting compile error with interface type not compatible.

But, If i try to create the class using default "new" method. Everything works fine. Then i can assign the virtual interface any handle using dot "." operator.

So the question is does factory type_id create method allows creating classes having interface as parameter?

I have created two interface and created one env class that can take interface as parameter. In the top while declaring the ENV class. I am defining both instance with respective interface type. Later while creating, I used factory method which gives compile error. If i replace the factory instance with legacy new method. All works fine.

Code looks like :

//======================================================================

interface bist_inf (...);

…

endinterface

interface l2bist_inf (...);

…

endinterface

typedef virtual bist_inf bist_vif;

class bist_env #(type vif=bist_vif) extends uvm_env ;

......

endclass

//======================================================================

class basic_test extends uvm_test;

typedef virtual bist_inf L1_bist_vif;

typedef virtual l2bist_inf L2_bist_vif;

bist_env #(virtual bist_inf) env_bist_wrap2;

bist_env #(virtual l2bist_inf) env_bist_wrap3;

virtual function void build_phase(uvm_phase);

super.build_phase(phase);

env_bist_wrap2 = bist_env#(virtual bist_inf)::type_id::create("env_bist_wrap2", this);

env_bist_wrap3 = bist_env #(virtual l2bist_inf)::type_id::create("env_bist_wrap3", this);

endfunction

..

endclass

Share this post


Link to post
Share on other sites

Below is the error message.

We are creating two classes. One with interface bist_inf and another with l2bist_inf. There is no compile error for creation of first class which is explained below.

Line in the error message correspond to

env_bist_wrap3 = bist_env #(virtual l2bist_inf)::type_id::create("env_bist_wrap3", this);

As the class bist_env is declared with type "type vif=bist_vif" and bist_vif is declared as follows

typedef virtual bist_inf bist_vif;"

So to me it looks like Factory is treating class "bist_env" of type bist_inf. This is because if i replace the typedef and point bist_vif to other interface which is " l2bist_inf". Then i compile error on creation of first class which is associated with bist_inf.

**************

Error-[sV-ICA] Illegal class assignment

.....cpa_tests.sv, 86

"this.env_bist_wrap3 = uvm_pkg::__vcs_dummy_uvm_component_registry_20_.create("env_bist_wrap3", this, "\000");"

Expression

'uvm_pkg::__vcs_dummy_uvm_component_registry_20_.create("env_bist_wrap3",

this, "\000")' on rhs is not a class or a compatible class and hence cannot

be assigned to a class handle on lhs.

Please make sure that the lhs and rhs expressions are compatible.

Share this post


Link to post
Share on other sites

Is there anything wrong with the usage of type_id::create method?

VCS throws error saying LHS and RHS are not compatible. But we have declared class env_bist_wrap3 with interface type l2bist_inf. Am i missing something here?

Share this post


Link to post
Share on other sites

How have you registered bist_env with the factory?

When we register a component with factory like:-

`uvm_component_param_utils(bist_env #(virtual bist_inf) )

and call create method:-

env_bist_wrap2 = bist_env#(virtual bist_inf)::type_id::create("env_bist_wrap2", this);

env_bist_wrap3 = bist_env #(virtual l2bist_inf)::type_id::create("env_bist_wrap3", this);

Here,bist_env is the one registered with the factory for the parameter type bist_inf and not l2bist_inf.

as create definition goes like :-

static function T create(string name, uvm_component parent, ...);

31 uvm_object obj;

32 uvm_factory f = uvm_factory::get();

33 ...

34 obj = f.create_component_by_type(get(),contxt,name,parent);

35 if (!$cast(create, obj)) begin

36 string msg;

37 msg = {<"... error message ...">};

38 uvm_report_fatal("FCTTYP", msg, UVM_NONE);

39 end

40 endfunction

Here T is the uvm_component registered with the factory in your case bist_env#(virtual bist_inf).

I guess that is why there is a difference when you are using "new" and "create".

For more information you can look into uvm_registry.svh header.

Share this post


Link to post
Share on other sites

@ shalsays

Yes! I registers the class to the factory with parameter. Only mistake was...

Class is declared as

class bist_env #(type vif=bist_vif) extends uvm_env ;

and

I was doing `uvm_component_param_utils(bist_env #(bist_vif) )

Now, I though bist_vif is declared as "typedef virtual interface bist_inf". So it would be treated as virtual. But that's actually a type and not parameter name.

Now when registering to factory i gave "vif" and all works well..

`uvm_component_param_utils(bist_env #(vif) )

Does UVM ignores this, and treat it as nothing is passed as parameter.

Thanks shalsays for pointing me to factory registration.

Share this post


Link to post
Share on other sites

Welcome..

Good to see that my explanation could solve your problem :)

The registered component will have parameter as interface.

As the "type vif =bist_vif" will make vif as interface type.

So, in your case you are passing an interface type as a parameter while registering.

Now, that interface can be bist_inf or l2bist_inf.

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  

×