cross coverage
交叉覆盖率,指的是覆盖点或者变量的取值。在前面我们只讨论一个变量的所有取值作为覆盖点,但是我们还可以使用两个变量取值的排列组合作为覆盖点。表达式不能再cross中使用,一个覆盖点必须在之前被清晰的定义才行。
bit [3:0] a, b;
covergroup cg @(posedge clk);
c1:coverpoint a;
c2:coverpoint b;
c1Xc2: cross c1, c2;
endgroup:cg
在上面的例子中,定义了两个覆盖点c1和c2,基于c1,c2定义了交叉覆盖c1Xc2。
bit [3:0] a,b;
covergroup cov @(posedge clk);
aXb: cross a,b;
endgroup
在上面的例子中,每个覆盖点都有16个bins,分别是auto[0],auto[1],…,auto[15]。变量a和b的交叉被aXb所标记。交叉起来,则有256种可能的取值。
bit [3:0] a, b, c;
covergroup cov @(posedge clk);
BC: coverpoint b+c;
aXb: cross a, BC;
endgroup
在上面的例子种,这个覆盖组合依然有256种可能的取值组合,更为复杂些,可以同时使用变量和表达式,BC取值覆盖了b+c所有可能的取值组合,aXb则是变量a和覆盖点BC的取值集合。
cover option
我们可以通过一些开关选项option来控制covergroup,coverpoint和cross的行为。
at_least
指定命中bins的次数,前面提到取值落到bins范围,bins会自增,当bins命中的次数小于所指定的值时,则认为此时bins没有覆盖。默认为1.
auto_bin_max
当我们没有显示的创建bins,会自动创建,改选项可以自动指定自动创建的bin的数目,默认值为64.
cross_auto_bin_max
于auto_bin_max较为类似,不过这适用于交叉覆盖。
下面的例子展示了如何使用option
covergroup cg @(poseedge clk);
c1: coverpoint addr {option.auto_bin_max = 128;}
c2: coverpoint wr_rd {option.atleast = 2;}
c2Xc2: cross c1, c2 {option.cross_auto_bin_max = 128;}
endgroup
数组方法
数组包括数组、动态数组、队列。下面主要讨论操纵数组数据的方法。
参数化定义
有两种方法来定义常数,如下所示:
- parameter
- `define
parameter
参数必须被定义在模块内部,且需使用关键字parameter修饰。一个parameter在模块内部的一个常数,可以有选择性的在模块外部重新定义。一般是用来指定变量的位宽或者时间的延迟。
module mem_model #(
parameter ADDR_WIDTH=8;
parameter DATA_WIDTH=32;)
(clk, addr, data);
input clk;
input [ADDR_WIDTH-1:0] addr;
output [DATA_WIDTH-1:0] data;
.....
.....
endmodule
`define
它修饰的是一个全局变量,可以在被所有的文件所访问到。它改变有两种情形,一是另一个宏定义改变了这个值,或者是使用 undef语句。
`define WIDTH 8
//to avoid redefincation `ifdef can be used
`ifdef WIDTH
// do nothing (better to use `ifndef)
`else
`define WIDTH 8
`ifndef WIDTH
`define WIDTH 8
`endif
`ifdef can be used as if else
`ifdef TYPE_1
`define WIDTH 8
`else
`define WIDTH 32
`endif
//`ifdef can also be used to avoid redefining/recompiling the module/class
//In the below example
//definition of MODULE_1 is checked, if it is not defined then MODULE_1 will be
//defined and compiles the module/class inside the `ifndef ---- `endif
`ifndef MODULE_1
`define MODULE_1
module mem;
endmodule
`endif
数组排序方法
这类方法处理一维数组或者队列,可以对数据元素重新排序,有如下构建方法:
方法 | 描述 |
reverse() | 把数组里面的所有元素都倒转(封装或者是不封装) |
sort() | 升序排序所有数组里面的元素 |
rsort() | 降序排序所有数组里面的元素 |
shuffle() | 随机化数组里面元素的顺序,即打乱 |
module fixedsize_array;
//declaration of array's
int array_1[4];
int array_2[4];
int array_3[4];
int array_4[4];
initial begin
//array initialization
array_1 = '{0,1,2,3};
array_2 = '{2,3,1,0};
array_3 = '{2,3,1,0};
array_4 = '{0,1,2,3};
$display("==============reverse==============");
$display("Before:\t %p", array_1);
array_1.reverse();
$display("After :\t %p", array_1);
$display("==================================");
$display("==============sort==============");
$display("Before:\t %p", array_2);
array_2.sort();
$display("After :\t %p", array_2);
$display("==================================");
$display("==============rsort==============");
$display("Before:\t %p", array_3);
array_3.rsort();
$display("After :\t %p", array_3);
$display("==================================");
$display("==============shuffle==============");
$display("Before:\t %p", array_4);
array_4.shuffle();
$display("After :\t %p", array_4);
$display("==================================");
end
endmodule
执行结果如下:
class packet;
int a;
int b;
function void display();
$display("\t Value od a = %0d", a);
$display("\t Value of b = %0d", b);
endfunction
endclass
module assoc_array;
//declaratio of array's
packet array_1[*];
packet pkt;
initial begin
pkt = new();
pkt.a = 8;
pkt.b = 3;
array_1[3] = pkt;
pkt = new();
pkt.a = 0;
pkt.b = 6;
array_1[7] = pkt;
pkt = new();
pkt.a = 2;
pkt.b = 1;
array_1[9] = pkt;
$display("======== sort ==========");
$display("Before");
foreach (array_1[i]) begin
$display("array_1[%0d]:", i);
array_1[i].display();
end
array_1.sort with (item.a);
$display("\n After");
foreach (array_1[i]) begin
$display("array_1[%0d]:", i);
array_1[i].display();
end
$display("===========================");
end
endmodule
对于排序,如果数组元素是类的实例,并且类的变量不止一个时,排序就需要指定哪个值作为怕排序标准,此时可以提供过with指定标准。在qutasim无法执行关联数组,因此下面的实验是跑在vcs上,执行结果如下:
由此可见,我们可以通过with(item.a)让类按照其中的变量a的大小进行排序。