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
The value of ADDR is read when calling the covergroup’s constructor. That is when the bins for the coverpoint are created. There is no more bin creation after constructing the covergroup.
So if ADDR has the value 0 when executing the statement
** Warning: (vsim-8546) The number of values specified ‘1’ is less than the size ‘16’ of fixed-size array bin ‘Addr’ in Coverpoint ‘addr’ of Covergroup instance '/top/xyz::access '. The ‘15’ empty bins will not contribute towards coverage.
Actually in the function I have calculated the range of address which i want to use in my covergroup.
Basically i want to do this
memory_range : coverpoint range {bins addr = {[base_addr, final_addr]};}
which will be dependant on the size of the memory for which i have defined a function. The size and base_addr are read from registers inside the function.
function void calc();
bit [3:0] size;
register read to get size;
register read to get base_addr;
case(size)
4’b0000: begin
Max_addr = ‘h10000;
Final_addr= base_addr+max_addr;
covergroup.sample();
end
4’b0001: …….
endfunction
How should I access the base addr and final addr from the function in my covergroup?
You still have not explained your situation very well. Functional coverage in SystemVerilog works by creating in set of value bins associated with a coverpoint, and a set of coverpoints or grouped within a covergroup. The bins are set up once during the covergroup’s constructor. The the covergroup repeatedly samples the values of the coverpoint, and the matching value bins are incremented with hits. You call sample() repeatedly hoping the every bin gets hot.
You need to explain what value will be repeatedly sampled and compared with the predefined set of bin values. Perhaps you need to show an example set of data that would be sampled, and explain which bins would be hit those values.