mea1201 Posted July 9, 2014 Report Share Posted July 9, 2014 I have a method inside a concrete class defined in a module to be instantiated in the testbench. The concrete class handle is passed to the UVM agent. I chose this approach over virtual interfaces to minimize the proliferation of parameters, because the interface by definition includes a decent set of parameters. I do need to support a type parameter for modeling the data in any way useful for the verification environment, and a corresponding string parameter that is the type's name for UVM factory reasons that I won't delve into. Anyway, here is example code to illustrate what I'm trying to describe: module my_bfm#( parameter type T = byte, parameter string Tname = "", parameter BLAH = DEFAULT_BLAH ); class my_concrete extends my_abstract; task transact(input my_trans#(T, Tname) trans); // Do something... endtask : transact endclass : my_concrete endmodule : my_bfm module testbench; my_bfm#(.T(my_custom_t), .Tname("my_custom_t"), .BLAH(42)); endmodule : testbench class my_trans#(type T=byte, string Tname="") extends uvm_sequence_item; `uvm_object_param_utils(my_trans#(T)) endclass : my_trans VCS will fail at elaboration with the following: Error-[ICTTFC] Incompatible complex type usage my_monitor.svh, 42 Incompatible complex type usage in task or function call. The following expression is incompatible with the formal parameter of the task. The type of the actual is 'class my_trans#(my_custom_t,"my_custom_t")', while the type of the formal is 'class my_trans#(byte,"\000")'. Expression: this.trans Source info: my_abstract::collect_transaction (this.m_bfm, this.trans); Questa passes compilation and elaboration. It seems that VCS is not propagating the parameter overrides in the testbench to the concrete class where the method using similarly parameterized classes is defined. The UVM classes are overridden from the env with the same type/value as in the testbench. Anyone have any ideas, perhaps someone from Synopsys? Quote Link to comment Share on other sites More sharing options...
tudor.timi Posted July 10, 2014 Report Share Posted July 10, 2014 You're not showing the full code. What is my_custom_t? How do you instantiate your monitor? Quote Link to comment Share on other sites More sharing options...
mea1201 Posted July 10, 2014 Author Report Share Posted July 10, 2014 my_custom_t could be any user-defined type, such as typedef struct packed { logic parity; logic [7:0] data; } my_custom_t; I realized that I had a problem with the abstract class, which was originally defined as virtual class my_abstract#(type T=byte, string Tname=""); pure virtual task transact(input my_trans#(T, Tname) trans); endclass : my_abstract I fixed the concrete class to class my_concrete extends my_abstract#(T, Tname); But, the call to transact from the monitor, which has a handle to my_bfm via the configuration database, still causes the error where the formal is claimed to be parameterized with the defaults in the abstract class. I ended up working around this by redefining the abstract class to be non-parameterized, and redeclared the method arguments with non-parameterized base classes (uvm_sequence_item instead of my_trans#(T, Tname)). This got through VCS elaboration. However, it was painful and time-consuming debugging this kind of problem dealing with incompatible types. Quote Link to comment Share on other sites More sharing options...
dave_59 Posted July 10, 2014 Report Share Posted July 10, 2014 One recommendation is not to use defaults unless they are meaningful. Then you will be forced to provide matching overrides. virtual class my_abstract#(type T, string Tname); pure virtual task transact(input my_trans#(T, Tname) trans); endclass : my_abstract Quote Link to comment Share on other sites More sharing options...
tudor.timi Posted July 10, 2014 Report Share Posted July 10, 2014 This is a good recommendation, Dave, but some simulators unfortunately don't allow specifying a type parameter without a default. Quote Link to comment Share on other sites More sharing options...
uwes Posted July 11, 2014 Report Share Posted July 11, 2014 hi, my reading is that you need >class my_concrete extends my_abstract#(T,Tname); otherwise your class extends from the default paramterization which finally leads to a type collision. (the symbol T in your my_concrete class collides because you got my_bfm#(...)::T (the param T from the module) and my_bfm#(..)::my_concrete#()::T (the param T you inherit from abstract) /uwe Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.