1、在UVM中,我们使用以下几个类和方法来实现随机和约束:
- uvm_random类:用于创建随机数生成器。
rand
关键字:用于声明一个随机变量。constraint
关键字:用于声明一个约束条件。unique
关键字:用于声明一个唯一约束条件。randomize()
方法:用于生成随机数并满足约束条件。
在UVM中,我们可以使用SystemVerilog语言中的随机特性来创建随机序列生成器,并使用约束来限制这些序列的范围和分布。
随机特性允许我们创建随机数生成器,用于生成随机的测试数据。例如,我们可以使用随机生成器来生成随机的输入信号,以测试设计的不同情况和边界条件。
约束允许我们定义一些条件,用于限制随机数生成器生成的值的范围和分布。例如,我们可以定义一个约束条件,使生成的随机数在某个范围内,或者按照某种分布生成。
通过结合随机特性和约束,我们可以创建出更具随机性和多样性的测试用例,以尽可能地覆盖设计的各种情况和边界条件。
2、rand和randc : 其修饰的对象必须是类的成员变量,不能是静态变量。类外的随机属性需要依靠SV预定义的随机函数std::randomsize()使用。 只有通过rand或randc声明的变量,后期通过对象调用randomize()函数才可以随机化变量。
随机求解成功则randomize返回1,否则返回0,通常添加断言来检查是否随即成功,不成功可以抛出-1。约束是声明性语句不是程序性语句。sv只能随机化二值数据类型,无法随机化出x值和z值。
同一个randc关键字定义的实例在执行随机化时是轮流值,每个元素是唯一的,但是必须是对同一变量多次随机时才会有这个性质,只有遍历所有值以后,才会出现相同的值。
3、权重赋值符号(dist关键字)
(1)“:=”代表前面的值每一个出现的权重都“=”后面的权重。
(2)“/ =”代表前面的值 均分 后面的权重。
(3)权重值和权重可以常量也可以是变量。
4、集合成员和inside赋值
(1)可以使用inside来从一个集合中取值,如果想要取集合外的值,那么直接使用一个取反符号;
(2)可以直接把数组当成一个集合,然后使用inside进行约束,注意,如果数组中某个元素出现多次,求解中不影响元素出现的概率。
(3)使用randc关键字约束数组,使其产生唯一的元素
(4)使用两层循环。
5、产生数组元素唯一的数组
(1)使用unique关键字
(2)使用两层for循环逐个元素约束
(3)使用randc配合
(4)对数组的元素赋数组索引值,然后在post_randomize中使用shuffle方法对数组的元素进行打乱。
6、静态数组、动态数组、队列、关联数组的随机化
(1)静态数组:数组的大小不变,可以对数组的每一个元素添加约束,可以放constraint或者post_randomize中。
(2)动态数组:可以使用size()约束数组的大小,使用sum()约束数组的和,使用product()约束组的积。
7、随机约束和分布
不同仿真器对于同一个约束类和种子值求解出的数值可能是不相同的。
关键词dist可以在约束中产生随机数值的权重分布。使用:=表示每一个值的权重是相同的,:/表示权重平分到每一个值。
inside是常用的约束运算符。使用$可以指定最大值和最小值。
->或者if-else可以让约束表达式在特定时刻有效。
8、constraints的一些重要属性
.caonstraints 可以是任何包括整形variables或者整形constant的expression,如:bit、reg、 logice、integer,enum、pakge、struct;
.求解存在时返回正确的值,如果constraint过度约束导致约束失败,返回error。
.constraints时双向的,所有的expression operators都认为是双向的,包含implication operator(->)。
.constraint仅支持2值变量,面对四值(X、Z)或者=== !==不支持且报错。
.constraint mode()可以用于enable或disable任何object中的named constraint block。
.rand_mode()可以用于enable或disable任何的random variable。如果一个random variable被disable了,那么他的变量就是nonrandom variable的。