SystemVerilog中的随机化及约束

        在芯片验证过程中,经常需要对驱动数据进行随机化处理和约束,来实现更多和更有效率的验证场景覆盖。在SystemVerilog中通常有以下三种方式进行随机化处理和约束:1)系统函数$random();2)标准库函数std::randomize();3)面向对象的函数randomize()。

1. 系统函数$random() 

        首先,是第一种随机方式,调用$random()及同类型函数。

#函数返回值
1$random(reg/integer/time seed)32bit有符号数
2$urandom(reg/integer/time seed)32bit无符号数
3$urandom_range(int unsigned maxval, int unsigned minval)32bit指定范围内的无符号数

        $random()和$urandom()可以通过指定函数种子来进行随机数生成,种子的类型需要为reg,整型或时间型变量。

variable = $random(seed);    //直接生成有符号数
variable = $random % 60;     //通过取余来获取一定范围内的有符号数,-59 ~ 59
variable ={$random % 60};    //通过拼接符,将其转换为无符号数,0 ~ 59

        $urandom_range()则可以通过指定参数,获取一定范围的无符号数。需要注意的是,第一个参数为最大值,第二个参数为最小值。当输入参数发生调换时,系统可以自动调换最大值和最小值。同时,由于参数列表第一个为最大值,所以当指定一个参数时,为默认最大值,而未指定的最小值参数默认为0。

variable = $urandom_range(10,4);    //生成范围为4~10的无符号数
variable = $urandom_range(4,10);    //生成范围为4~10的无符号数
variable = $urandom_range(10);      //生成范围为0~10的无符号数,最小值未指定默认为0

2. 标准库函数std::randomize()

        其次,通过调用标准库函数std::randomize()同样可以实现变量的随机化以及更灵活的约束,该约束条件的使用语法在后面章节进行讲述。

bit [3:0] variable;
std::randomize(variable);                    //随机化变量范围0~15
std::randomize(variable)with{/*约束条件*/};   //可使用灵活的约束进行范围内随机

3. 面向对象函数randomize()

        最后,通过对对象调用randomize()函数,同样可以对class内部有rand或randc修饰的变量进行有约束的随机化。在待随机对象内部可以添加约束,对变量的范围进行指定。而在对改对象进行随机化时,同样可以使用with进一步指定约束条件,但必须保证该约束条件是待随机对象内部约束条件的子集,否则发生约束冲突时,将随机化失败。解决该问题的一个方法是,在待随机对象内部的约束使用soft进行修饰,将该约束变为软约束,可以被更上层的随机约束覆盖。

class val_obj0;
    rand bit [3:0]    variable;     //通过rand修饰变量,纯随机
    constraint val_cons {/*约束条件*};
endclass

class val_obj1;
    randc bit [3:0]   variable;     //通过randc修饰变量,周期性随机(随机遍历所有值)
    constraint val_cons {/*约束条件*};
    constraint val_cons {soft /*软约束条件*}; 

endclass

class top_obj;

    val_obj0    obj0;
    val_obj0    obj1;

    function new();
        obj0 = new();
        obj1 = new();

        val.randomize();
        val.randmize()with{/*约束条件*/}; //当约束条件与对象内部约束条件冲突时,随机失败;
                                         //当对象内部约束条件为软约束时,可覆盖软约束;
    endfunction
endclass;

4. 随机约束

        标准库std::randomize()函数和面向对象的randomiz()函数进行数据的随机过程中,都可以通过"with{约束条件;}"的方式进一步约束随机范围,生成自己更关注的数据。通常,除了上述我们进行随机的函数外,还有constraint语句,以及`uvm_do_with宏等需要添加约束条件,其语法与上述相同,均是通过"with{约束条件;}"的方式进行。

std::randomize(variable)with{约束条件1;约束条件2;};
val_obj.randomize()with{约束条件1;约束条件2;};
constraint val_cons {约束条件1;约束条件2;}
`uvm_do_with(tr,{约束条件1;约束条件2;});

        约束条件一般为表达式,主要分为以下几种:

  1. 设定约束范围;
  2. 设定约束权重;
  3. 设定约束条件;
  4. 设定约束优先级;

       以下约束语法的举例以constraint为例。

        (1)对于约束范围指定,可以使用关系操作符(>,<,>=,<=,==)或者inside语句来指定随机范围,且一个表达式中只能有一个操作符。

//设定约束范围
constraint val_cons {variable < 10; variable > 4;}
constraint val_cons {variable inside {[4:10]};} //在使用[4:10]注意从小到大

        (2)对于约束权重的指定,可以使用dist来完成,分为':='和':/'两种权重分布,分别代表统一权重值和均分权重值。

//权重分布
//1的权重为4,概率为4/22; 3~10的每个值的权重为6, 每个值的概率为3/22
constraint val_cons {variable dist {0 := 4, [1:3] := 6};}
//1的权重为4,概率为4/10; 3~10的所有值权重和为6, 每个值的概率为1/10
constraint val_cons {variable dist {0 :/ 4, [1:3] :/ 6};}

        (3)对于约束条件的设定,可以使用if-else语句,'->'操作符。

constraint val_cons {if(a) variable > 5; else variable < 5;}
cosntraint val_cons {a -> variable > 5; ~a -> variable < 5;}

        (4)对于约束优先级的设定,可以使用solve-before语句进行,完成关联约束的随机先后顺序指定。

constraint a_cons {a > 10;}
constraint b_cons {b > a;}
constraint order {solve a before b;} //完成a的随机化后,再随机b

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值