Hi, I want to write for 12 bit signal, using wildcard.
Here is sample code.
module fcov_rate
(
// Clock and Resets
input [12:0] i_rx_config
);
covergroup client_rate;
option.per_instance = 1;
RX_CLIENT_RATE : coverpoint i_rx_config
{
wildcard bins RATE_0 = {12'b????_????_??10};
wildcard bins RATE_1 = {12'b????_????_??01};
wildcard bins RATE_2 = {12'b????_????_01??};
wildcard bins RATE_3 = {12'b????_??01_????};
wildcard bins RATE_4 = {12'b????_01??_????};
wildcard bins RATE_5 = {12'b???1_????_????};
wildcard bins RATE_6 = {12'b??1?_????_????};
wildcard bins RATE_7 = {12'b?1??_????_????};
}
endgroup
client_rate cov_config_inst;
//////////////////////////////////////////////////
initial begin
cov_config_inst = new();
end
endmodule
With this wildcard method, I am able to achieve desired coverage, but let’s say if I have 32 bit register and want to write coverage on that, then wildcard will be messy,
I can not use 32’b???..??? (?/X for 32 bits). So, I tried with following code,
module fcov_rate
(
// Clock and Resets
input [31:0] i_tx_config
);
covergroup client_rate;
option.per_instance = 1;
TX_CLIENT_RATE : coverpoint i_tx_config
{
wildcard bins RATE_0 = {i_tx_config[1:0] == 2'b10};
wildcard bins RATE_1 = {i_tx_config[1:0] == 2'b01};
wildcard bins RATE_2 = {i_tx_config[3:2] == 2'b01};
wildcard bins RATE_3 = {i_tx_config[5:4] == 2'b01};
wildcard bins RATE_4 = {i_tx_config[7:6] == 2'b01};
}
endgroup
client_rate cov_config_inst;
//////////////////////////////////////////////////
initial begin
cov_config_inst = new();
end
endmodule
Above code is compile clean, but not able to hit bins.
Is there any other way to just part-select of coverpoint reference.
I know that I can achieve this using multiple coverpoint, but I don’t want to write new coverpoint for each case like,
FCOV_TX_CLIENT_RATE : coverpoint i_tx_config[1:0]
{
wildcard bins RATE_0 = {2};
wildcard bins RATE_1 = {1};
}
FCOV_TX_CLIENT_RATE : coverpoint i_tx_config[3:2]
{
wildcard bins RATE_2 = {1};
}
FCOV_TX_CLIENT_RATE : coverpoint i_tx_config[5:4]
{
wildcard bins RATE_3 = {1};
}
Is there any better solution ?
In reply to J_M:
It’s hard to find a generic algorithm for the bins in your code, but there are a couple approaches you can take.
You can use a bin set expression to create a list of matching bin values
bit [12:0] rate[8][] = '{ {12'b????_????_?010,12'b????_????_?110}.
{12'b????_????_??01}.
...
}; // you can use whatever procedural code you want to
// construct this array before constructing the covergroup
covergroup client_rate;
option.per_instance = 1;
RX_CLIENT_RATE : coverpoint i_rx_config
{
wildcard bins RATE_0 = rate[0];
wildcard bins RATE_1 = rate[1];
wildcard bins RATE_2 = rate[2];
wildcard bins RATE_3 = rate[3];
wildcard bins RATE_4 = rate[4];
wildcard bins RATE_5 = rate[5];
wildcard bins RATE_6 = rate[6];
wildcard bins RATE_7 = rate[7];
endgroup
You can send your coverpoint values through a function and use its return value to select a bin.
bit [12:0] rate[8][] = '{ {12'b????_????_?010,12'b????_????_?110}.
{12'b????_????_??01}.
...
}; // you can use whatever procedural code you want to
// construct this array before constring the covergroup
covergroup client_rate;
option.per_instance = 1;
RX_CLIENT_RATE : coverpoint somefunc(i_rx_config)
{
bins RATE[8] = {[0:7]};
}
endgroup
function int somefunc(bit [12:0] samp);
return ... some value between 0 and 7
Hi Dave,
Thanks for your reply, yes definitely I can use ?/X and pass it using variable or function.
Here I used defined based coverage and using ‘iff’ I am hitting the bins.
`define CLIENT_RATE(DIR, REF, ID) \
``DIR``_CLIENT_RATE_``ID : coverpoint 1 iff (!i_sample) \
{ \
bins RATE_0 = {1} iff (``REF[``ID][0]); \
bins RATE_1 = {1} iff (``REF[``ID][1]); \
bins RATE_2 = {1} iff (``REF[``ID][2]); \
bins RATE_3 = {1} iff (``REF[``ID][3]); \
bins RATE_4 = {1} iff (``REF[``ID][4]); \
bins RATE_5 = {1} iff (``REF[``ID][5]); \
bins RATE_6 = {1} iff (``REF[``ID][6]); \
bins RATE_7 = {1} iff (``REF[``ID][7]); \
bins RATE_8 = {1} iff (``REF[``ID][8]); \
bins RATE_9 = {1} iff (``REF[``ID][9]); \
}
module fcov_rate
(
// Clock and Resets
input [9:0][12:0] i_rx_config
);
covergroup client_rate;
option.per_instance = 1;
`CLIENT_RATE(RX,i_rx_cfg,0)
`CLIENT_RATE(RX,i_rx_cfg,1)
endgroup
client_rate cov_config_inst;
initial begin
cov_config_inst = new();
end
endmodule
Above code serves my purpose and able to use same define multiple times by just passing different reference to the define.
Now let say I have 8 different client_cfg(client_cfg[8]) and I am passing different cfg instance in define reference. but client_cfg 0 to 6 support RATE_0 to RATE_9 and client_cfg only support RATE_0 to RATE_5. So I my coverage goal is not achieving 100% as RATE_6 to RATE_9 are not present for client_cfg[7], client_cfg[8] and client_cfg[9].
Do we have any method to not define bins if certain condition is not matched/satisfied?
Line below example,
`define CLIENT_RATE(DIR, REF, ID) \
``DIR``_CLIENT_RATE_``ID : coverpoint 1 iff (!i_sample) \
{ \
bins RATE_0 = {1} iff (``REF[``ID][0]); \
bins RATE_1 = {1} iff (``REF[``ID][1]); \
bins RATE_2 = {1} iff (``REF[``ID][2]); \
bins RATE_3 = {1} iff (``REF[``ID][3]); \
bins RATE_4 = {1} iff (``REF[``ID][4]); \
bins RATE_5 = {1} iff (``REF[``ID][5]); \
bins RATE_6 = {1} iff (``REF[``ID][6]); \
if(``ID < 7) begin \
bins RATE_7 = {1} iff (``REF[``ID][7]); \
bins RATE_8 = {1} iff (``REF[``ID][8]); \
bins RATE_9 = {1} iff (``REF[``ID][9]); \
end \
}
In reply to J_M:
The is no way to evaluate an expression as part of a macro, and there is no way to conditionally create a named bin within a coverpoint. You can control the size of an array of bins, and the values in each bin at construction.
If you want to pursue using a macro, you could do
`define CLIENT_RATE(DIR, REF, ID) \
DIR``_CLIENT_RATE_``ID : coverpoint 1 iff (!i_sample) \
{ \
bins RATE_0 = {1} iff (REF[ID][0]); \
bins RATE_1 = {1} iff (REF[ID][1]); \
bins RATE_2 = {1} iff (REF[ID][2]); \
bins RATE_3 = {1} iff (REF[ID][3]); \
bins RATE_4 = {1} iff (REF[ID][4]); \
bins RATE_5 = {1} iff (REF[ID][5]); \
bins RATE_6 = {1} iff (REF`ID][6]); \
bins RATE_7 = {1} iff (REF[ID][7] || ID >=7); \
bins RATE_8 = {1} iff (REF[ID][8] || ID >=7); \
bins RATE_9 = {1} iff (REF[ID][9] || ID >=7); \
end \
}
This will slightly skew partial coverage results, but not what’s needed to get 100%
BTW: you do not need to be using all over the place except when you need to concatenate an identifier like: DIR
CLIENT_RATE``ID