Creating multiple handles for covergroup in new constructor

class A;
covergroup cg;
endgroup

extern function new(string name, uvm_component parent);
endclass

function A::new(string name, uvm_component parent);
super.new(name,parent);
cg cg_tx = new;
cg cg_rx = new;
endfunction

For the above code I am getting the error,
10: token is ‘cg_tx’
cg cg_tx = new;

I want multiple handles of covergroup ‘cg’ created say cg_tx and cg_rx. How can this be done?

When you have an embedded covergroup (declare a covergroup inside the class), the covergroup object and class object are merged into a single object. That is why the cg constructor has to be inside the class constructor, and you are not allowed to declare multiple instances of an embedded covergroup.

If you really want multiple covergroup instances for a single class object, you will have to declare the covergroup outside the class, and pass all the coverpoint data through arguments to the covergroup’s constructor.

In reply to dave_59:

Hi Dave,

Please provide more information on what you mean by outside of the class?

If possible, provide a simple example.

it will be great.

Thanks.

In reply to SKUPPAM:
https://verificationacademy.com/forums/coverage/creating-new-instances-covergroup-using-array.#reply-41565

In reply to dave_59:

Thanks Dave, it helped.

Tried a simple example. might be helpful others.

Dave, correct me if anything wrong in the usage.

class x;
int y;
endclass

covergroup x2 (ref x z1);
option.per_instance = 1;
coverpoint z1.y {
bins x1 = {3};
}
endgroup

class cg;

x t;

x2 t1,t2;
function new ();
t=new();
t1 = new(t);
t2 = new(t);
fork
call();
join_none
endfunction

task call ();
int cnt ;
repeat (40) begin
t.y = cnt;
if (cnt [0]) t1.sample();
if (!cnt [0]) t2.sample();
cnt = cnt +1;
#10;
$display (“sample \n”);
end
endtask

endclass

module tb;
cg q1;
initial begin
q1 = new();
#10000;
$finish;
$display (“done”);
end
endmodule

In reply to SKUPPAM:

I try to understand what your objective is, having two instances of the same covergroup in one component. Would be great if you could say a few words regarding this.
Thanks
Christoph

In reply to chr_sue:

SOrry if it had created a confusion.

The example is a trial to check, if i am able to create two instances by moving the CG outside or not. its just a dummy.

But, i want to use this concept in cases of multiple channels and separate it by id’s.

In reply to SKUPPAM:

You did not create confusion. But I was doing about 20 OVM and UVM projects with very different applications during the last years and I was never facing a topic like yours. But of course it is an interesting topic.
Coverage collection is a theme where the UVM User Guide does not give clear guidelines.
My project practice showed a good place for placing a functional coverage collector is in the agent. This way you can at least measure what was generate by the sequencer. My agents have always a sequencer/driver and a monitor/coverage collector pair. Following this advice you would not need several instances of the same coverage collector outside of an agent.

In reply to SKUPPAM:
Hi Skuppam,

Did your example work? i understand that you are passing the class itself as a reference to the covergroup.
Am also trying to declare covergroup outside class and declaring multiple coverpoints inside covergroup. how do i make this work? please give a working example.

With Regards
Ajay

In reply to Ajay2112:

The example that i have given above worked and i dont have any issue

In reply to dave_59:

hi

I am using embedded cover group in my TB,


class baby_coverage extends uvm_subscriber #(baby_pkt); 
  
  `uvm_component_utils(baby_coverage)  
   uvm_analysis_imp #(baby_pkt,baby_coverage) baby_coverage_imp;

  covergroup baby_covergroup;
   option.per_instance = 1;
	//----------------------------------------------
	//                COVERPOINTS       
	//----------------------------------------------
	coverpoint pktt.READ_FROM_INVALID_STATE 
				{
				bins PIPE_0_READ_FROM_INVLAID[] = { 	pktt.DADY_0_PIPE_0_baby_RD_FROM_INVALID, 
													pktt.DADY_1_PIPE_0_baby_RD_FROM_INVALID,
													pktt.DADY_2_PIPE_0_baby_RD_FROM_INVALID,
													pktt.DADY_3_PIPE_0_baby_RD_FROM_INVALID,
													pktt.DADY_4_PIPE_0_baby_RD_FROM_INVALID,
													pktt.DADY_5_PIPE_0_baby_RD_FROM_INVALID,
													pktt.DADY_6_PIPE_0_baby_RD_FROM_INVALID,
													pktt.DADY_7_PIPE_0_baby_RD_FROM_INVALID
													};
				bins PIPE_1_READ_FROM_INVLAID[] = { 	pktt.DADY_0_PIPE_1_baby_RD_FROM_INVALID, 
													pktt.DADY_1_PIPE_1_baby_RD_FROM_INVALID,
													pktt.DADY_2_PIPE_1_baby_RD_FROM_INVALID,
													pktt.DADY_3_PIPE_1_baby_RD_FROM_INVALID,
													pktt.DADY_4_PIPE_1_baby_RD_FROM_INVALID,
													pktt.DADY_5_PIPE_1_baby_RD_FROM_INVALID,
													pktt.DADY_6_PIPE_1_baby_RD_FROM_INVALID,
													pktt.DADY_7_PIPE_1_baby_RD_FROM_INVALID
													};
				bins PIPE_2_READ_FROM_INVLAID[] = { 	pktt.DADY_0_PIPE_2_baby_RD_FROM_INVALID, 
													pktt.DADY_1_PIPE_2_baby_RD_FROM_INVALID,
													pktt.DADY_2_PIPE_2_baby_RD_FROM_INVALID,
													pktt.DADY_3_PIPE_2_baby_RD_FROM_INVALID,
													pktt.DADY_4_PIPE_2_baby_RD_FROM_INVALID,
													pktt.DADY_5_PIPE_2_baby_RD_FROM_INVALID,
													pktt.DADY_6_PIPE_2_baby_RD_FROM_INVALID,
													pktt.DADY_7_PIPE_2_baby_RD_FROM_INVALID
													};
				bins PIPE_3_READ_FROM_INVLAID[] = { 	pktt.DADY_0_PIPE_3_baby_RD_FROM_INVALID, 
													pktt.DADY_1_PIPE_3_baby_RD_FROM_INVALID,
													pktt.DADY_2_PIPE_3_baby_RD_FROM_INVALID,
													pktt.DADY_3_PIPE_3_baby_RD_FROM_INVALID,
													pktt.DADY_4_PIPE_3_baby_RD_FROM_INVALID,
													pktt.DADY_5_PIPE_3_baby_RD_FROM_INVALID,
													pktt.DADY_6_PIPE_3_baby_RD_FROM_INVALID,
													pktt.DADY_7_PIPE_3_baby_RD_FROM_INVALID
													};
				bins PIPE_4_READ_FROM_INVLAID[] = { 	pktt.DADY_0_PIPE_4_baby_RD_FROM_INVALID, 
													pktt.DADY_1_PIPE_4_baby_RD_FROM_INVALID,
													pktt.DADY_2_PIPE_4_baby_RD_FROM_INVALID,
													pktt.DADY_3_PIPE_4_baby_RD_FROM_INVALID,
													pktt.DADY_4_PIPE_4_baby_RD_FROM_INVALID,
													pktt.DADY_5_PIPE_4_baby_RD_FROM_INVALID,
													pktt.DADY_6_PIPE_4_baby_RD_FROM_INVALID,
													pktt.DADY_7_PIPE_4_baby_RD_FROM_INVALID
													};
				bins PIPE_5_READ_FROM_INVLAID[] = { 	pktt.DADY_0_PIPE_5_baby_RD_FROM_INVALID, 
													pktt.DADY_1_PIPE_5_baby_RD_FROM_INVALID,
													pktt.DADY_2_PIPE_5_baby_RD_FROM_INVALID,
													pktt.DADY_3_PIPE_5_baby_RD_FROM_INVALID,
													pktt.DADY_4_PIPE_5_baby_RD_FROM_INVALID,
													pktt.DADY_5_PIPE_5_baby_RD_FROM_INVALID,
													pktt.DADY_6_PIPE_5_baby_RD_FROM_INVALID,
													pktt.DADY_7_PIPE_5_baby_RD_FROM_INVALID
													};
				} 
				....


  endgroup : baby_covergroup
   
  function new(string name = "baby_coverage", uvm_component parent);
    super.new(name, parent);
    baby_covergroup = new();  //[ERROR]
	$display("baby_covergroup object created"); 
  endfunction 
   baby_pkt pktt;	

  virtual function void write (input baby_pkt t1);
	//pktt = t1;
	$cast(pktt,t1.clone());
    baby_covergroup.sample();
  endfunction

  function void build_phase(uvm_phase phase);
  super.build_phase(phase);
    baby_coverage_imp = new("baby_coverage_imp", this);
	$display("baby_coverage_imp object created"); 
  endfunction : build_phase

endclass

for the above code, I am getting NOA [Null object access] error at line
baby_covergroup = new(); //[ERROR]
the object at dereference depth 1 is being used before it was constructed/allocated.
make sure that the object is allocated before using it

can anyone help me, this code is syntax correct, I am getting this issue at run time,

In reply to Jintu K Joseph:

Looks like you did not construct the component baby_coverage. Could you please check.

In reply to chr_sue:
from first reply [When you have an embedded covergroup (declare a covergroup inside the class), the covergroup object and class object are merged into a single object. That is why the CG constructor has to be inside the class constructor, and you are not allowed to declare multiple instances of an embedded covergroup.] so I think we need not construct the object for this case,
&
If construct the object like
baby_covergroup baby_covergroup;
I am getting a compilation error, this usage is not allowed
I am getting the error when I am creating the object[ baby_covergroup = new(); //[ERROR]

In reply to Jintu K Joseph:

I asked for the component baby_coberage which is a component having in the baby_covergroup.

In reply to Jintu K Joseph:

Please use code tags. I have added them for you.

You are referencing pktt in your covergroup. You will need to create a handle for pktt prior to creating your covergroup:


baby_pkt pktt; 

function new(string name = "baby_coverage", uvm_component parent);
  super.new(name, parent);
  pktt = new("pktt");
  baby_covergroup = new(); //[ERROR]
  $display("baby_covergroup object created");
endfunction

In reply to cgales:

I have updated the code as follows, still facing same NOA error:

class baby_coverage extends uvm_subscriber #(baby_pkt);

`uvm_component_utils(baby_coverage)
uvm_analysis_imp #(baby_pkt,baby_coverage) baby_coverage_imp;
baby_pkt pktt;

covergroup baby_covergroup;
option.per_instance = 1;
//----------------------------------------------
// COVERPOINTS
//----------------------------------------------
coverpoint pktt.READ_FROM_INVALID_STATE
{
bins PIPE_0_READ_FROM_INVLAID = {
pktt.DADY_0_PIPE_0_baby_RD_FROM_INVALID,
pktt.DADY_1_PIPE_0_baby_RD_FROM_INVALID,
pktt.DADY_2_PIPE_0_baby_RD_FROM_INVALID,
pktt.DADY_3_PIPE_0_baby_RD_FROM_INVALID,
pktt.DADY_4_PIPE_0_baby_RD_FROM_INVALID,
pktt.DADY_5_PIPE_0_baby_RD_FROM_INVALID,
pktt.DADY_6_PIPE_0_baby_RD_FROM_INVALID,
pktt.DADY_7_PIPE_0_baby_RD_FROM_INVALID
};
bins PIPE_1_READ_FROM_INVLAID = {
pktt.DADY_0_PIPE_1_baby_RD_FROM_INVALID,
pktt.DADY_1_PIPE_1_baby_RD_FROM_INVALID,
pktt.DADY_2_PIPE_1_baby_RD_FROM_INVALID,
pktt.DADY_3_PIPE_1_baby_RD_FROM_INVALID,
pktt.DADY_4_PIPE_1_baby_RD_FROM_INVALID,
pktt.DADY_5_PIPE_1_baby_RD_FROM_INVALID,
pktt.DADY_6_PIPE_1_baby_RD_FROM_INVALID,
pktt.DADY_7_PIPE_1_baby_RD_FROM_INVALID
};
bins PIPE_2_READ_FROM_INVLAID = {
pktt.DADY_0_PIPE_2_baby_RD_FROM_INVALID,
pktt.DADY_1_PIPE_2_baby_RD_FROM_INVALID,
pktt.DADY_2_PIPE_2_baby_RD_FROM_INVALID,
pktt.DADY_3_PIPE_2_baby_RD_FROM_INVALID,
pktt.DADY_4_PIPE_2_baby_RD_FROM_INVALID,
pktt.DADY_5_PIPE_2_baby_RD_FROM_INVALID,
pktt.DADY_6_PIPE_2_baby_RD_FROM_INVALID,
pktt.DADY_7_PIPE_2_baby_RD_FROM_INVALID
};
bins PIPE_3_READ_FROM_INVLAID = {
pktt.DADY_0_PIPE_3_baby_RD_FROM_INVALID,
pktt.DADY_1_PIPE_3_baby_RD_FROM_INVALID,
pktt.DADY_2_PIPE_3_baby_RD_FROM_INVALID,
pktt.DADY_3_PIPE_3_baby_RD_FROM_INVALID,
pktt.DADY_4_PIPE_3_baby_RD_FROM_INVALID,
pktt.DADY_5_PIPE_3_baby_RD_FROM_INVALID,
pktt.DADY_6_PIPE_3_baby_RD_FROM_INVALID,
pktt.DADY_7_PIPE_3_baby_RD_FROM_INVALID
};
bins PIPE_4_READ_FROM_INVLAID = {
pktt.DADY_0_PIPE_4_baby_RD_FROM_INVALID,
pktt.DADY_1_PIPE_4_baby_RD_FROM_INVALID,
pktt.DADY_2_PIPE_4_baby_RD_FROM_INVALID,
pktt.DADY_3_PIPE_4_baby_RD_FROM_INVALID,
pktt.DADY_4_PIPE_4_baby_RD_FROM_INVALID,
pktt.DADY_5_PIPE_4_baby_RD_FROM_INVALID,
pktt.DADY_6_PIPE_4_baby_RD_FROM_INVALID,
pktt.DADY_7_PIPE_4_baby_RD_FROM_INVALID
};
bins PIPE_5_READ_FROM_INVLAID = {
pktt.DADY_0_PIPE_5_baby_RD_FROM_INVALID,
pktt.DADY_1_PIPE_5_baby_RD_FROM_INVALID,
pktt.DADY_2_PIPE_5_baby_RD_FROM_INVALID,
pktt.DADY_3_PIPE_5_baby_RD_FROM_INVALID,
pktt.DADY_4_PIPE_5_baby_RD_FROM_INVALID,
pktt.DADY_5_PIPE_5_baby_RD_FROM_INVALID,
pktt.DADY_6_PIPE_5_baby_RD_FROM_INVALID,
pktt.DADY_7_PIPE_5_baby_RD_FROM_INVALID
};
endgroup : baby_covergroup

function new(string name = “baby_coverage”, uvm_component parent);
super.new(name, parent);
baby_covergroup = new(); //[ERROR]
$display(“baby_covergroup object created”);
endfunction

virtual function void write (input baby_pkt t1);
//pktt = t1;
$cast(pktt,t1.clone());
baby_covergroup.sample();
endfunction

function void build_phase(uvm_phase phase);
super.build_phase(phase);
baby_coverage_imp = new(“baby_coverage_imp”, this);
$display(“baby_coverage_imp object created”);
endfunction : build_phase

endclass

In reply to Jintu K Joseph:

A few other things you should clean-up before continuing with your construction problem.
(1) the uvm_subscriber class has itself a built-in analysis_export/imp. You do not have to add another one explicitly.
(2) the write function of the analysis_export/imp is a pure virtual function, i.e. the prototype lokks like this:
pure virtual function void write( T t). The argumnet name is t and not t1 as you are using.

Please correct these issues and modify the connection to the buil-in analysisi_port in the right way.

In reply to Jintu K Joseph:

Look at my previous response. You need to create pktt prior to creating the covergroup.

In reply to cgales:

I tried this too, still getting same issue

In reply to Jintu K Joseph:

Could you please share some more code, best would be the whole example.
If you do not want to share with the community you can send it to my email address
christoph@christoph-suehnel.de