Can we covergroup inside a monitor

hai, folks.
please correct me if am wrong any where.
please follow the points here. 1,2,3
I have implemented the coverage inside the monitor instead of taking it in a separate class.

it is something like this

class monitor extends uvm_monitor;
// virtual interface_name h1;

function new();
  //point 2
  my_cov=new(); // if i do like this is throughing an error called (Syntactically this identifier appears to begin a datatype but it does not refer to a visible datatype in the current scope.)
endfunction
function void build_phase(uvm_phase phase);

endfunction

virtual task run_phase(uvm_phase phase);
  //point 3
  my_cov.sample(); // here i am calling the sample . 
endtask

//point 1
covergroup my_cov @(posedge clk);
// here i have written few coverpoints
endgroup
endclass

thank you

In reply to Vickyvinayk:

Yes you can have this. But you must decide how you are sampling the covergroup, clockwise or using the sample method.

In reply to chr_sue:

i want to sample by using the clk.

In reply to Vickyvinayk:

This might result in wrong coverage values. If you want to do this you do not need to call the sample method.
I’d use the sample metod you can call it after you have assembled your transaction.

In reply to Vickyvinayk:

Please use code tags making your code easier to read. I have added them for you.

You need to declare a covergroup before you call its constructor, so the declaration needs to be moved up to the top.

One defines covergroup sampling by either declaring it as part of its declaration or explicitly calling its sample() method, but not both.

Finally, we normally recommend creating a separate coverage collector class that is fed by an analysis port in your monitor.

In reply to dave_59:

Hai Deve,

thank you for your inputs. next time I will definitely follow the code tags.

ok I will try the coverage by writing it in a separate class.

In reply to chr_sue:

thank you chr_cue. better I will use the sample method

In reply to Vickyvinayk:

I’m using a coverage component in each agent, because I want to measure what I was stimulating with the sequencer/driver. It looks like this:

//-----------------------------------------------------------------------------
class apb_coverage extends uvm_subscriber #(apb_seq_item);
//-----------------------------------------------------------------------------

`uvm_component_utils(apb_coverage)
  apb_seq_item item;

  // Insert your covergroups here

  //------------------------------------------
  // Cover Group(s)
  //------------------------------------------
  covergroup apb_cov;
  // insert your coverpoints and bins here
    cp_0: coverpoint item.data;
    //   add bins here
    cp_1: coverpoint item.addr;
    //   add bins here
    cp_2: coverpoint item.we;
    //   add bins here
    cp_3: coverpoint item.delay;
    //   add bins here
    cp_4: coverpoint item.error;
    //   add bins here
  endgroup

  extern function new(string name = "apb_coverage", uvm_component parent);
  extern function void build_phase(uvm_phase phase);
  extern function void write(input apb_seq_item t);
endclass : apb_coverage 

//-----------------------------------------------------------------------------
// apb_coverage implementation
//-----------------------------------------------------------------------------
function apb_coverage::new(string name = "apb_coverage", uvm_component parent);
   super.new(name,parent);
   apb_is_covered = 0;
   apb_cov = new();
endfunction : new

function void apb_coverage::build_phase(uvm_phase phase);
  super.build_phase(phase);
endfunction : build_phase

function void apb_coverage::write(apb_seq_item t);
  item = t;
  apb_cov.sample();
endfunction : write

In reply to chr_sue:

thank you chr_sue. your inputs are helpful.

In reply to chr_sue:

hai, chr_sue. I have gone through the same procedure but while calling the write method, it’s throwing an error saying that it’s a virtual function. Then I googled it and came to know that the subscriber write method is a pure virtual function. so declared as below

class fifo_coverage extends uvm_subcriber#(seq_item);
// …
…remaining code here

//
pure virtual function void write(fifo_seq_item item);
this.seq=item;
sync_fifo_cov.sample();
endfunction

endclass:fifo_coverage
//==============================================================================
error:
this.seq=item;
|
xmvlog: *E,EXPENC (/proj/22FDX/bolt/soc/b0/users/kvkumar/bolt_b0/tb/uvm_env/fifo_uvc/fifo_coverage.sv,29|7): Expecting the keyword ‘endclass’.

everything is perfect but I guess something is wrong with my write method? could you please correct me if I am wrong?

In reply to Vickyvinayk:

A pure virtual function is a placeholder for an implementation. Normally it is used in a virtual class. A virtiual class cannot be constructed.
WRT your code:

class fifo_coverage extends uvm_subcriber#(fifo_seq_item);
// ..
fifo_seq_item item;
..remaining code here
..
//
virtual function void write(fifo_seq_item t);
item = t;
sync_fifo_cov.sample();
endfunction

endclass:fifo_coverage

Don’t forget to construct your covergroup.

In reply to chr_sue:
hai chr_sue, still its giving an error. here is the complete code of my coverage class


class fifo_coverage extends uvm_subscriber#(fifo_seq_item);
  `uvm_component_utils(fifo_coverage)

fifo_seq_item seq;                  // declaration of seq_item class
virtual sync_interface sync_vintf;  // interface declaration

covergroup sync_fifo_cov;

  WRITE        :coverpoint seq.write iff(!sync_vintf.rst_n) {}
  ALMOST_FULL  :coverpoint seq.almost_full iff(!sync_vintf.rst_n) {}
  FULL         :coverpoint seq.full iff(!sync_vintf.rst_n) {}
  OVERRUN      :coverpoint seq.overrun iff(!sync_vintf.rst_n) {}

  READ         :coverpoint seq.read iff(!sync_vintf.rst_n) {}
  ALMOST_EMPTY :coverpoint seq.almost_empty iff(!sync_vintf.rst_n) {}
  EMPTY        :coverpoint seq.empty iff(!sync_vintf.rst_n) {}
  UNDERRUN     :coverpoint seq.underrun iff(!sync_vintf.rst_n) {} 
endgroup

function new(string name="fifo_coverage", uvm_component parent=null);
   super.new(name,parent);
endfunction:new

function void build_phase(uvm_phase phase);
   super.build_phase(phase);
endfunction:build_phase

virtual function void write(fifo_seq_item pkt);
   seq=pkt;
   sync_fifo_cov.sample();
endfunction

endclass

                                              |

*xmvlog: E,CVMNMM fifo_coverage.sv,28|50): Virtual method ‘fifo_coverage::write’ formal argument name does not match base class ‘uvm_subscriber’.

In reply to Vickyvinayk:
Please try
function new(string name=“fifo_coverage”, uvm_component parent=null);
super.new(name,parent);
sync_fifo_cov = new();
endfunction:new

virtual function void write(fifo_seq_item t);
seq=t;
sync_fifo_cov.sample();
endfunction

You did not construct the covergroup.

In reply to chr_sue:

sry sry… actually I have seen that later and I modified it working perfectly. but What I have noticed is.

when we are writing the write function we need to pass the argument seq_item handle as “t”.


virtual function void write(seq_item t); // here if you take any handle it is not working, we need to take only "t"
seq_item_handle =t;
cg.sample();
endfunction

thank you chr_sue for your inputs.

In reply to Vickyvinayk:

The argument name of the write function has to be t because it is specified in the write function of the uvm_subscriber.

In reply to chr_sue:

yes yes perfect… I got it thank you.