随机约束——数组约束

目录

内容:

数组的属性约束:

约束数组的元素:

产生唯一元素值的数组:

使用rand:

使用randc:

使用unique:

数据约束:

随机化句柄数组:


新增内容:

对于类中的属性变量,有的添加了 rand 或者 randc, 有的没有添加,在进行类的randomize() 随机化时,

  1. 当 randomize() 没有参数时, 只会对 带有rand 和 randc 的变量进行随机。
  2. 当 randomize(参数)添加参数时,参数可以是任何一个变量,即使那个变量没有 rand 关键字,这个带参数的随机函数只会对参数中的变量进行随机

例:

 类中的随机化变量尽量不要使用 带有符号的类型, 会产生随机错误。

例如

 把 byte 改成 bit 就不会产生负数了。但是又会产生多出一位,被舍弃的情况。

我们采取 如下:

 在 mcdf 这个项目中 chnl_transaction 中的变量有没有出现这样的问题呢?

 可以看到 data 使用了 bit 无符号类型。

其他的属性使用了 int 有符号类型, 但是在约束中都把它们限制到了大于0的 地方。

 

 使用立即断言 来判断 随机化的结果,并给出随机化失败后的 $fatal() 消息打印,还有其他类型的, $info $warning $error $fatal 。

 

内容:

可以约束动态数组的长度和内容

数组的属性约束:

在多数情况下,数组的大小应该给定范围,防止生成过大体积的数组或者空数组。在约束随机标量的同时,可以对随机化数组进行约束。

例:

class dyn_size;
    rand logic [31:0] d[];
    constraint d_size {d.size() inside {[1:10]}; }
endclass

可以在约束中结合数组的其他方法sum(), product(), and(), or() 和 xor()。

约束数组的元素:

SV可以利用foreach对数组的每一个元素进行约束,和直接写出固定大小数组的每一个元素的约束相比,foreach要更简洁。针对动态数组,foreach 更适合于对非固定大小数组中每个元素的约束。

例:

class good_sum5;
    rand uint len[];
constraint c_len {
    foreach (len[i]) len[i] inside {[1:255]};
    len.sum() < 1024;
    len.size() inside {[1:8]};}
endclass

随机的输出结果是:

sum = 1011, val = 83 249 197 187 152 95 40 8
sum = 1012, val = 213 252 213 44 196 20 54
sum = 370,  val = 118 76 176
sum = 976,  val = 233 187 44 157 201 81 73
sum = 412,  val = 172 167 73

产生唯一元素值的数组:

使用rand:

class UniqueSlow;
    rand bit [7:0] ua[64];
    constraint c { 
        foreach (ua[i])  //对数组中的每一个元素操作
            foreach(ua[j]) 
                if(i!=j)  // 除了元素自己
                    ua[i] ! = ua[j]; // 和其他元素比较,让值不相等
}
endclass

使用randc:

class randc8;
    randc bit [7:0] val;
endclass

class LittleUniqueArray;
    bit [7:0] ua[64];
    function void pre_randomize();
      randc8 rc8 = new();
      foreach (ua[i]) begin
        assert(rc8.randomize());
        ua[i] = rc8.val;
      end
    endfunction
endclass

(注意:randc 是周期性的产生随机值,例如 randc bit [1:0] a;    a的取值范围就是0-3,故每一轮的随机取值可能为 0-1-3-2  ——> 下一轮可能是  2-0-1-3 再下一个周期是 1-3-0-2,每一个周期内的值是唯一的。)

使用unique:

表示限定一个数组,让这个数组里的值在独一无二的范围里

数据约束:

例如下面的代码会报错:

class packet;
    rand bit[3:0] da[];
    constraint da {
        da.size() inside {[3:5]};
        foreach (da[i]) da[i] <= da[i+1];
}
endclass
packet p;
initial begin
    p = new();
    p.randomize() with {da.size() inside {3,5}; };
end

原因:

下面的随机约束da的长度在3或者5,假如是5的话, i=0,1,2,3,4,那么 da[4] <= da[5], da[5]超出了数组的范围, 所以foreach中 i 的取值范围应该是0-3,否则会报错,

应该改为 :

foreach(da[i]) begin

        if(i < = da.size() - 2)

                da[i] <= da[i+1];

end

随机化句柄数组:

1. 这个数组( array[] )中的每个元素都是个句柄

2. 对这个数组所在类 (RandArray) 进行随机化,ra.randomize() 

3. 要求这个数组中的每个句柄在随机化之前,必须实例化,不能悬空,也就是都指向对象

表示为下面的function new(); 函数中

4. 必须对这个句柄数组前加上 rand 

5.对这个句柄数组随机化,也就是对这个数组中的每个句柄所指向的对象 随机化

6.因为句柄所指向的对象所在类 RandStuff 中的变量 value 并没有添加 rand,故其值是固定不变的

7.结果显示为:ra.array[i].value = 1;

8.如果bit [1:0] value 前加上rand, 那么结果可能是 ra.array[i].value = 0:3 (0到3之间任意)

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值