UVM的随机以及约束的方法很多,
一、常见的随机有如下几种:
1)$random 和$urandom
urandom%5:值得范围在0-4内变化;
int value=$random%5; 通过尝试,发现打印出来的值是:-4~4之间变化;
bit [8:0] value =$random%5, ----->打印出来value的值在508~511和0-4之间变化。
$urandom_range(0,5) --->取值范围是0,1,2,3,4,5.
2)定义类,其中用rand或者rand声明变量,然后在其他地方调用 obj.randomize() with;
class xxx_transaction;
rand bit [7:0] qu[$]; //队列的随机,调用randomize后。 另外,randc
endclass
类声明后再使用前要new一下来创建类对象;否则引用空指针错误;流程如下:
--> 定义类
class xxxxx_transaction;
rand bit [7:0] qu[$]; //队列的随机,调用randomize后 ,另外,也可以调用randc, Randc表示周期随机性,即所有的可能的值都赋值后随机值才可能重复
rand bit [3:0] array1[4]; //数组元素生成随机值
constraint array_c { array1.sum() == 30;} //使用sum方法约束数组的和
constraint array_c_e { foreach(array1[i]) array1[i] > 2;} //约束数组元素的值
rand bit [7:0] array1[3][4];
constraint array_c { foreach(array1[i,j]) array1[i][j] == i*j;} //多维数组的约束
function new();
endfunction
endclass
--> 对象声明并创建;
xxxxx_transaction tr;
tr=new();
-->tr.randomize with {};
二、约束
1)权重约束
src dis {1:=10,[1:3]:=40}; //:=表示[]内的权重都是一样的,都是40;如果用/: 表示[]内的元素均分权重40;
2)inside 操作符
src inside {[1:5]};
3)条件约束
src==1 -> dst==2;
4)solve .. before 约束引导概率分布 不会改变解得个数,只会改变值得概率分布
5)约束块控制
6)内嵌约束
7)约束使用
--》使用变量约束上限
--》带权重变量的约束
---》使用randcase和$urandom_range()随机控制
8)随机注意错误
---》尽量不要使用有符号类型
--》
已知负数求补码:计算机中负数是以补码形式存在的,补码=原码取反加1;
-4原码为10000100,(最高位符号位),补码为除符号位外,其余取反加1;即补码=11111011+1=511-4+1=508=》2^8-|4|,即位宽最大值减去负数的绝对值;
已知补码求代表的负数:
最高位是1时,表示是补码,代表的是一个负数,如何求这个负数?
1)先把补码当成无符号读取,例如补码为11111100(原码11111011+1),无符号数是508;
2)求得的结果减去2^9=512, 508-512=-4;
2)