Is there a easier way in SV to define coverpoint to do a toggle coverage on every bit of a 32 bit vector. Meaning If I have a 32-bit interrupt mask vector and I just want to see if each interrupt was either masked or unmasked , I usually have to code 32 lines of code. for instance
You could write a covergroup with a single coverpoint that you construct multiple times in an array generated by a for loop. (the covergroup declaration must not be embedded inside a class)
I would like to use this approach inside a class, but if I understand your example correctly the covergroup declaration cannot be embedded in the class. How do I create something similar inside a class?
Pseudo code:
class my_coverage extends uvm_subscriber #(apb_seq_item);
:
covergroup output_en_cg (input bit position, ref bit vector);
encoding: coverpoint (('1b1<<position & vector) !=0)
{
bins hit = {1};
}
option.per_instance = 1;
endgroup: output_en_cg
output_en_cg g1[16];
:
function new(string name = "my_coverage", uvm_component parent = null);
super.new(name, parent);
foreach (g1[i]) begin
g1[1] = new(i, output_enable_reg[15:0]);
end
endfunction
endclass
My example code doesn’t compile (no surprise). Ideas?
Paul,You can simply move the covergroup declaration outside of the class. The covergroup does not reference any members of the class directly, you pass them in as constructor arguments. You did not show the declaration of output_en_reg.
Is causing the following compiler error: Syntactically this identifier appears to begin a datatype but it does not refer to a visible datatype in the current scope.
I guess I need to declare the covergroup outside the module, but I’m not sure what that would look like. Can anyone provide an example of what that looks like in my case?
In your original solution you mentioned, (the covergroup declaration must not be embedded inside a class). Could you explain what you meant by this ?
where do you define the covergroup definition then ? (lets say you have class extended from uvm_subscriber and you get the transaction from an analysis port)
Put the covergroup declaration in front of the class definition. This means that all coverpoint expressions must be passed in as arguments to the covergroup.
The problem is when you declare a covergroup inside a class, it is implicitly declared as a covergroup variable with the same name as the covergroup. Therefore you cannot use the covergroup name as a type to declare another covergroup variable or, in this case, an array of covergroup variables.
Hello Dave, thanks it works well!
because the covergroups declaration is outside the class, i can use parameter to determine the width:
covergroup mask (input bit [MASK_WIDTH-1:0] position ,ref bit [MASK_WIDTH-1:0] vector);
mask_cp : coverpoint (position & vector) !=0;
option.per_instance = 1;
//option.comment = "";
endgroup
but if i would like to make it be more flexible, i mean the width will get different value each time, so then a constant parameter is not good for me.
i thought to do it by the factory registration, like that:
`ovm_field_int (m_mask_width, OVM_ALL_ON)
but with this way my covergroups will not recognize it.
how can i declare my covergroups like that?
I am trying to execute this piece of code but it results in only one bin getting created(with address all 0’s) instead of 16. could you suggest what might be going wrong here? basically the address value assigned in the function is not seen by the covergroup. Is there any other way i could do this?
Code is as follows:
class xyz ;
bit[31:0] address;
bit[31:0] ADDR;
covergroup access();
addr : coverpoint ADDR { bins Addr[16] = {[0:address]}};
endgroup
function void calc();
address = 'h10000;
access.sample();
endfunction
fucntion new();
access = new();
endfunction
task run();
forever begin
calc();
end
endtask