systemverilog绿皮书随记(五)-- 随机化

随机化的对象:

器件配置:寄存器和系统信号

环境配置:随机化验证环境

原始输入数据:例如MCDF数据包的长度、宽度、数据间的顺序

延时:握手信号之间的时序关系,例如valid和ready、req和ack之间

协议异常:例如反馈信号给出异常,那么设计能否保持后续数据处理的稳定性

预定义的类随机函数 std::randomize()使用。即只有通过声明rand变量,并且在后期通过对象调用randomize()函数才能随机化变量

Constraint{}约束表达式的求解是由SV的约束求解器完成,满足约束的值是由**伪随机数发生器(PRNG)**从一个初始值产生

SV只能随机化2值数据类型,也就是不能随机出X值和Z值,也无法随机化字符串,不能在约束中指向句柄;

src dist{0:/40,[1:3]:/60}//权重分布 src是一个变量

c inside{[lo :hi]};//lo<= c && c<= hi

(io_space_mode) ->  addr[31] ==1'b1;//当c_io满足io_space_mode=1时执行

在一个约束表达式中最多只能使用一个关系操作符(<,<=,==,>=,>)

对约束表达式加上括号并在前面加上!即可对约束取反

约束块的控制:约束块可以调用内建的constraint_mode(int a)函数打开或者关闭约束

class Package;

    //声明随机变量

    rand int length;

    //约束变量值,两个约束相互冲突

    constraint c_short {length inside {[1:32]};};

    constraint c_long {length inside {[1000:1023]};};

endclass

Package p;//声明句柄

initial begin

    p = new();//创建的对象

    p.c_short.constraint_mode(0);//关闭c_short

    assert(p.randomize());//c_long 生效

    transmit(p);

    p.constrant_mode(0);//关掉p中所有的约束

    p.c_short.constraint_mode(1);//打开c_short

end  



内嵌约束:

randomize()with{  ;   ;};

随机化个别变量

在randomize()中传递参数变量时,只有参数列表的变量会被随机化,其他变量会被当做状态变量而不被随机化。//obj.randomize(b, c)

所有的约束仍然保持有效。【只有当对象使用constraint_mode(0)时,约束才会失效】

类里所有被rand修饰或者没被修饰的变量,只要被当做参数传递到randomize中,都会被随机化,而其他未被传递的参数(即便带rand修饰),也不会参与这次randomize()

在调用 randomize() 函数之前,一定要先为对象分配内存。//new()

调用 randomize() 函数时,会先执行类的构造函数function new()

随机数函数

$random()  //平均分布,返回32位有符号随机数

$urandom() //平均分布,返回32位无符号随机数

$urandom_rang() //在指定范围内的平均分布;  例如: $urandom_rang(0,100)

随机函数

pre_randomize() 和 post_randomize()

如果在类中定了这两个函数,那么对象在执行了randomize()之前或之后,会分别执行这两个函数。

pre_randomize() 和 post_randomize()可以看做是randomize()的回调函数

在使用randomize之前可以使rand_mode(0/1)用将随机化的变量禁止随机,然后在赋值一个常数;

调用handle.randomize(null)函数时,sv会把所有的变量当做非随机变量(“状态变量”),仅仅检查这些变量是都满足约束条件;

外部约束

随机变量谨慎使用有符号数据类型byte,int;该用成bit;还要注意限制位宽;

约束中避免使用复杂的运算,例如除法、乘法、取模(%);如果需要乘除使用右移或左移操作;对2的幂次方的取模操作可以用和掩膜的AND布尔操作代替;

数组的约束:

size() ——对数组的长度限定

sum() ——求和 ;product() ——求积 ;and() ——求与

用foreach对数组的每个元素进行约束

// 利用randc变量来辅助生成唯一元素值的数组

class randc8;

    randc bit [7:0] val;

endclass

class LittleUniqueArray;

    bit [7:0] ua[64];

    function void pre_randomize();

        randc rc8;

        rc8 = new();

        foreach (ua[i]) begin

            assert(rc8.randomize());

            ua[i]=rc8.val;

        end

    endfunction

endclass

这段代码的目的是创建一个大小为 64 的数组,其中的每个元素都是一个唯一的值。

产生随机脉冲类:

下例完成10个周期内发送4个数据的脉冲信号

Ps:单比特元素的和正常情况下也是单比特;本例中将strobe.sum()和四位的数值比较,所以数组元素的和是用4位的精度计算的;

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值