systemverilog学习 ---- coverage完结&& 数组操作方法1

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的大小进行排序。

猜你喜欢

转载自blog.csdn.net/weixin_45614076/article/details/126478210