Sub-Class "checker" does not override all virtual methods of abstract superclass 'ovm_subscriber"

Guys,

I’m getting as like error below… when I tried to create a subscriber extending the OVM one.

Basically, what I want is, In my agent, monitor transmitting a stream of data through analysis port to the checker inside the agent.Checker needs to receive that data on its analysis export and verify the same on task.

Help me how to get this done.

Send me some peace of reference code for the same.

Thanks

John

Hi John, you will need to provide an implementation of the write() method in your checker exactly as per the virtual prototype in ovm_subscriber class - write() must be a function, not a task. And make sure that you pass the type parameterization of your data type.
See OVM/AnalysisConnections | Verification Academy for more example code. A useful summary is:

class mychecker extends ovm_subscriber #(mydata); `ovm_component_utils(mychecker)

function new( string name , ovm_component parent);
super.new( name , parent );
endfunction

function void write(mydata d);

endfunction

endclass

BTW, “checker” is a keyword in SV 1800-2009.

In reply to dave_59:

Thanks, but… I’m getting error as below…

**Argument name ‘item’ for virtual method ‘write’ in sub class ‘dsp_stream_checker’ does not match the argument name ‘t’ in superclass ‘ovm_subscriber__1’.

Here is the super class:**

*virtual class ovm_subscriber #(type T=int) extends ovm_component;

typedef ovm_subscriber #(T) this_type;

// Port: analysis_export
//
// This export provides access to the write method, which derived subscribers
// must implement.

ovm_analysis_imp #(T, this_type) analysis_export;

// Function: new
//
// Creates and initializes an instance of this class using the normal
// constructor arguments for <ovm_component>: ~name~ is the name of the
// instance, and ~parent~ is the handle to the hierarchical parent, if any.

function new (string name, ovm_component parent);
super.new(name, parent);
analysis_export = new(“analysis_imp”, this);
endfunction

// Function: write
//
// A pure virtual method that must be defined in each subclass. Access
// to this method by outside components should be done via the
// analysis_export.

pure virtual function void write(T t);

endclass*
**
Here is my sub-class…**

class dsp_stream_checker extends ovm_subscriber #(dsp_sequence_item);

`ovm_component_utils(dsp_stream_checker);

function new(string name = “dsp_stream_checker”, ovm_component parent);
super.new(name, parent);
endfunction

//ovm_analysis_export (#dsp_sequence_item) a_exp;
// Need to create an export on new data type?

function void write (dsp_sequence_item item);
$display(“I am here”);
endfunction

endclass

Please explain…

Thanks.

John

In reply to John Verif:

Because SV has argument binding by name, the argument names in your subclass must match the argument names in the super class. So your write() method should look like

function void write (T t);
$display("I am here");
endfunction

In reply to dave_59:

I have few questions on this topic
[edited out 2 questions]
3. Assume dsp_sequence_item has an a field named my_var, is it legal to write something like:

function void write (T t);
  $display("my variable %d", t.my_var);
endfunction

If this cannot be done then what is the option to access the variables of such a class?
Probably this question is also related to 2 above

Thanks

In reply to manishp.p18:

As long as type T (or a super of T) has a variable called my_var, then you can access t.my_var.

class stack #(type T = int);
   local T items[];
   task push( T a ); ... endtask
   task pop( ref T a ); ... endtask
endclass

The above class defines a generic stack class that can be instantiated with any arbitrary type:
stack is; // default: a stack of int’s

I am taking an example from LRM to clarify further.
In the above example, the default type is int and hence I cannot reference a member of type T (example a.variable_in_a) even though I might actually pass a class object when I instantiate the above class. To quote from the LRM -

Any type can be supplied as a parameter, including a user-defined type such as a class or struct.

Is my observation correct? Is this a limitation?

As a side observation.
Polymorphism also has similar rules (a virtual function can only access variables available in the base class). But such restrictions are needed due to late binding (with my average OOPs understanding).

In reply to manishp.p18:

A parameterized class is a generic type, not a concrete type. It’s only when the class has been specialized by instantiation or a typedef during elaboration that references are checked. You could have written the class with no default type

class stack #(type T);
   local T items[];
   task push( T a );
       a.variable_in_a
 ... endtask
   task pop( ref T a ); ... endtask
endclass

The only difference is that you are required to provide a parameter when you instatiate. In both cases, the reference is not checked until after the final result of the parametrization is known.

Your side observation is incorrect. A virtual method can access anything available from the class it is declared in. On the other hand, a class variable has visibility to only the members or methods that have been declared in the class type of the variable. You can assign a derived subclass handle to a base class variable and call the virtual method in the subclass.

In reply to dave_59:

thanks