Can't understand how covergroup sample works

Hi,

I can’t understand how covergroup sample works

In my transaction I randomize the values. For example,

 // inputs
  rand bit[7:0] a;
  rand bit[7:0] b;
  rand bit[3:0] opcode;

  //outputs
  logic [15:0] res;
  bit error;


  constraint c_a {a >=0 ; a <=255;}
  constraint c_b {b >=0 ; b <=255;}

  constraint c_opcode {opcode >=0 ; opcode <=3;}

In scoreboard I want to verify that specific values are taken
For example,

  covergroup cover_bus;
 coverpoint opcode {bins _add={0}; bins _sub={1}; bins _mult ={2}; bins _div={3}; }
 coverpoint b {bins zero={0};}
 endgroup:cover_bus 

virtual function void write (calc_trans t);
  a=t.a;
  b=t.b;
  opcode=t.opcode;
  res=t.res;
  error=t.error;
  cover_bus.sample();

In reply to alexd555:

http://www.asic-world.com/systemverilog/coverage21.html

Above URLs are results of “covergroup instance” in google.

I read it but I can’t understand how it works.

For example,
Why I sample after that I read the signals from transaction ? look at my code please

In reply to alexd555:

A scoreboard might not be a good place to have a covergroup implemented. A seperate coverage collector component is a better approach.
But the mechanism is the same. The write function will be executed by monitor to provide transactions for further processing like coverage evaluation. This write function will be called when a transaction has been assembled. Internally you are assigning the transaction data members to local variabled where coverpoints are defined on and call the sample method of the corresponding covergroup to evaluate the functional coverage defined.

Could you give me an example ?
I want that b = 0 at least for example

In reply to alexd555:

Then you have to define an option for the coverpoint like this:
option.at_least = 1;

it doesn’t work

Do you have any idea ?

If I only sample cover_bus.sample(); and then print b then I get b=x

In reply to alexd555:

It looks like t.b is only initalized, bur it does not have a specific value.
The write method should be called in a monitor and in the monitor you have first to assemble the transaction.

I do it

....
task run_phase(uvm_phase phase);
      calc_trans tx;
    
    repeat(300)
    begin

      @(posedge ifc.clk);

      tx=calc_trans::type_id::create("tx");
      tx.a = ifc.a;
      tx.b = ifc.b;
      tx.opcode = ifc.opcode;
      tx.res=ifc.res;
      tx.error=ifc.error;

      // run write function from scoreboard
      aport.write(tx);
     end
   endtask: run_phase
   
endclass: calc_monitor

Where is my problem ?

In reply to alexd555:

The monitor should run in a forever loop, because you do not know howmany transaction you have to extract.
I’d move out the creation of the object from the loop.
The other code looks fine and you are calling the write method in the right place.
But did you check the virtual interface in the waves? b might be unknown.

My initial question was about covergroup.
I want that b=0 at least once.

Why do I need to use “forever” ? The simulation won’t stop.

In reply to alexd555:

The simulation will stop if you do not implement an objection mechanism inmthe monitor.
And this is not recommended.

Did I implement ?
If no, how can I do it ?

In reply to alexd555:

If you do not have an objection mechanism implemented the simulation stucks at runtime 0.
A good place to implement this mechanismm is in the test.
But it seems your simulation is running. Then oberve the waveforms with respect to signal b.

Hi,
What about of my original question ?

I define coverpoint for b=0 but it doesn’t work.

Can you help ?

Thanks,
Alex

In reply to alexd555:

You can define only bins for this. The syntax would be:

covergroup cg;
  coverpoint a;
  coverpoint b {
     bins zero = {0};
     bins one  = {1};
   }
endgroup

it doesn’t work

class calc_scoreboard extends  uvm_subscriber #(calc_trans);

`uvm_component_utils(calc_scoreboard)
 logic[0:7] a;
 logic[0:7] b;
 logic[0:3] opcode;
 int res;
 bit error;
 bit wrong_result;

function new (string name, uvm_component parent);
	super.new(name, parent);
  cover_bus=new;
  
endfunction : new

 function void build_phase(uvm_phase phase);
    super.build_phase(phase);
  endfunction: build_phase
 
  covergroup cover_bus;
 coverpoint opcode {bins _add={0}; bins _sub={1}; bins _mult ={2}; bins _div={3}; }
coverpoint b {bins zero={0};}
option.at_least = 1;
 endgroup:cover_bus 

virtual function void write (calc_trans t);
  a=t.a;
  b=t.b;
  opcode=t.opcode;
  res=t.res;
  error=t.error;
  cover_bus.sample();

In reply to alexd555:

Please what is not working. Does it show some entries and you are missing the one for be = 0?

I updated the code. Remove the comments.

I don’t get always b=0 at least once.