Sampling covergroup of parameter array - systemverilog - system-verilog

Let's say I have an array of parameters I want to use in a covergroup.
In order to interate over all the parameters in the array I tried to use a for loop in this manner:
array [5];
covergroup param;
coefficient: coverpoint array[i]{
bin low = {0:50};
bins high = {51:100};
}
for (i=0;i<5;i++)
param = new(i);
for (i=0;i<5;i++)
param.sample(i);
I'm not really sure how to solve this rather than creating a coverpoint for every cell in the array, but that's just messy and wrong.

Pass the input argument to the covergroup.
int array [5];
covergroup param (ref int a);
coefficient: coverpoint a{
bin low = {0:50};
bins high = {51:100};
}
endgroup
for (i=0;i<5;i++)
param = new(array[i]);
for (i=0;i<5;i++)
param.sample();

Related

coverpoint to check if 2 signals are active at the same time

I am trying to write a cover point to check where 2 signals should occurring at the same time or not.
covergroup signal#(posedge clk)
signals : coverpoint (a, b){
bins on_off = {2'b11}
}
I just wanted to know whether it is the correct path of writing the cover point.
I think you meant to write coverpoint {a,b} using concatenation braces. That would work. Another thing you can do is
covergroup signal #(posedge clk);
signals : coverpoint a&b {
bins on = {1};
}
endgroup

ignore coverage bin of one instance of covergroup

How to ignore coverage bin for particular instance;
how to ignore bins one for cov2 instance ?
class cov extends uvm_subscriber # (transfer)
function new(string name, uvm_component parent);
super.new(name,parent);
cov_tr = new();
cov_tr.set_inst_name();
endfunction
function void write(transfer t);
ignore_one = t.ignore_one;
cov_tr.sample();
endfunction
covergroup cov_tr;
option.per_instance = 1;
tr_value : coverpoint tr_val {
bins one : 1;
bins next : [2:7];
}
endgroup
cov cov1,cov2;
master1.connect(cov1.analysis_port);
master2.connect(cov2.analysis_port);
You can use stop method to stop collection of coverage, in a procedural block.
cov2.cov_tr.stop();
This is not possible. Binning must be exactly the same for any instance of a given covergroup.

Systemverilog cross coverpoint syntax question

Hi I am new to stackoverflow and systemverilog/uvm. I am currently trying to get the a cross coverpoint to catch the condition that (a==b) && (c==d), regardless of what value they are. I have tried the following crosses and none of them seem to be working.
covergroup abcd_tracking with function sample (bit [7:0] a, bit [7:0] b, bit [7:0] c, bit [7:0] d);
coverpoint a {
bins a_bin[1] = {[0:$]};
}
coverpoint b {
bins b_bin[1] = {[0:$]};
}
coverpoint c {
bins c_bin[1] = {[0:$]};
}
coverpoint d {
bins d_bin[1] = {[0:$]};
abcd_cross : cross a,b,c,d
{
bins abcd_bin = abcd_cross with( (a==b) && (c==d) );
}
abcd_cross_2 : cross a,b,c,d
{
bins abcd_2_bin = ( binsof(a) intersect(b) && binsof(c) intersect(d) );
}
abcd_cross_3 : cross a,b,c,d
{
bins abcd_3_bin = ( binsof(a) intersect{[0:$]} with (a==b) && binsof(c) intersect{[0:$]} with (c==d) );
}
This should actually be an illegal condition that never gets hit, but the 3 cross coverpoints seem to be constantly getting hit even though checking with my log files, the sampled variables don't meet the condition I am trying to define in my cross coverpoint. What is the proper syntax for catching this particular condition: " (a==b) && (c==d) " ?
You have a number of syntax errors, but event beyond that, I think you have some misconceptions on how coverpoints and crosses work.
Your four coverpoints have only one bin for all possible values. That means each bin gets hit on the first sample with any value, which is 100% coverage for each of the four coverpoints on the first sample. And since a cross creates bins for all possible bin combinations, you only get one cross bin on the first sample. So each of the three crosses are covered on the first sample.
If you want a separate bin for each value of a coverpoint, you need to write
coverpoint a {
bins a_bin[256] = {[0:$]};
}
Now a simple cross of a,b,c,d would create 256*256*257*256 = 232 cross bins. Bins of a cross are automatically generated and you only specify bins if you want them merged or ignored. If are only interested in the cases where (a==b) && (c==d), you have ignore all the other bins with
abcd: cross a,b,c,d {
ignore_bins not_equal = abcd with( a!=b || c!=d);
}

SystemVerilog covergroup include coverpoint based on parameter

I'm creating coverage for my design and I want to reuse a covergroup definition for multiple instances. The first instance should use all of the coverpoints as intended, but for the second instance, I want to exclude some of the coverpoints in the covergroup.
I was thinking I could use an input to the covergroup and iff () the unwanted coverpoints such that the first instance ties the input to 1 and the second instance ties the input to 0. However I think this will still show the coverpoints for the second instance as always not hit, and I want them to not be included at all.
covergroup cg_address(input bit enable) # (posedge clock);
address_check: coverpoint (address){
bins addr_0 = {5'd0};
bins addr_1 = {5'd1};
}
data_check: coverpoint (data) iff (enable){
bins data_0 = {10'd0};
bins data_1 = {10'd1};
}
endgroup : cg_address
cg_address cg_address_inst0 = new(1'b1);
cg_address cg_address_inst1 = new(1'b0); //want this one to exclude data_check coverpoint
I know the above code won't work because the second instance will still have the data_check coverpoint, it will just never hit either bin because the enable is tied to 0. Is there any other way I can try to exclude the data_check coverpoint for the second instance?
You need to do two things:
Set the weight of the coverpoint to 0.
Turn on option.per_instance = 1; for the covergroup.
For example:
covergroup cg_address(input bit enable) # (posedge clock);
option.per_instance = 1;
address_check: coverpoint (address){
bins addr_0 = {5'd0};
bins addr_1 = {5'd1};
}
data_check: coverpoint (data) {
option.weight = enable;
bins data_0 = {10'd0};
bins data_1 = {10'd1};
}
endgroup : cg_address
cg_address cg_address_inst0 = new(1);
cg_address cg_address_inst1 = new(0); //want this one to exclude data_check coverpoint

Systemverilog coverage point for multiple of n

I am trying to create a bin in my coverage group to sample values that are multiple of n (where n is a constant integer in my case 15). So far, I have came
up with the following code:
class rx_port;
int unsigned rx_rates[];
...
covergroup rx_cov with function sample (int unsigned rate);
coverpoint rate{
bins no_rate = {0};
bins mul_of_15 = {SOME_PRE_DEFINED_PATTERN};
}
endgroup;
....
endclass
Where SOME_PRE_DEFINED_PATTERN is an array of int from 0 to a system macro with the step of 15. I am not sure if this is the correct/best way of generating this bin. Any better suggestion?
How about writing some helper functions:
module FIFTEEN;
class rx_port;
typedef enum {IS_ZERO, IS_DIVISIBLE_BY_15, IS_NOT_DIVISIBLE_BY_15} rate_type;
function new;
rx_cov=new;
endfunction
local function rate_type covergroup_helper(input int unsigned i);
if (i==0) return IS_ZERO;
if (i%15==0) return IS_DIVISIBLE_BY_15;
return IS_NOT_DIVISIBLE_BY_15;
endfunction
function sample (input int unsigned i);
rx_cov.sample(covergroup_helper(i));
endfunction
covergroup rx_cov with function sample (rate_type rate);
coverpoint rate;
endgroup;
endclass
rx_port R = new;
initial
begin
void'(R.sample(0));
void'(R.sample(30));
void'(R.sample(31));
$display("coverage R.rx_cov.get_coverage= %f", R.rx_cov.get_coverage);
end
endmodule
https://www.edaplayground.com/x/65v7
Here I've written a function that determines whether its input is divisible by 15 or not and another function which calls that to do the sampling. You could combine those functions together, but I like the division of labour in my example.
It turns out that there is a better way:
module FIFTEEN;
class rx_port;
function new;
rx_cov=new;
endfunction
function sample (input int unsigned i);
rx_cov.sample(i);
endfunction
covergroup rx_cov with function sample (int unsigned rate);
coverpoint rate {
bins IS_ZERO = {0};
bins IS_DIVISIBLE_BY_15 = {[1:$]} with ((item % 15)==0);
bins IS_NOT_DIVISIBLE_BY_15 = {[1:$]} with ((item % 15)!=0);
}
endgroup;
endclass
rx_port R = new;
initial
begin
void'(R.sample(0));
void'(R.sample(30));
void'(R.sample(31));
$display("coverage R.rx_cov.get_coverage= %f", R.rx_cov.get_coverage);
end
endmodule
https://www.edaplayground.com/x/3T5v
You can use with to specify bins. So
bins IS_DIVISIBLE_BY_15 = {[1:$]} with ((item % 15)==0);
gives you a bin that is hit whenever the value is divisible by 15 (but not 0) and
bins IS_NOT_DIVISIBLE_BY_15 = {[1:$]} with ((item % 15)!=0);
gives you a bin that is hit whenever the value is not divisible by 15.