概述
随着设计变得越来越大,要产生一个完整的激励来测试设计的功能也变得越来越困难。
定向激励的测试方法早已经无法满足检查功能完整性的要求。
SoC的集成度提高带来的模块之间交互的复杂度也是指数攀升,这就使得验证工程师无法预测接下来用户使用过程中会发生什么样的状况。
目前动态仿真验证的主流方法: 随机-约束
随机约束测试(CRT,Constrained-Random Test)
随机约束测试即能够产生你感兴趣的、你想不到的的测试向量,通过回归测试、替换随机种子的方式来提高单位测试用例的覆盖率收集效率。
覆盖率是为了量化随机的效率和结果所指定出来的量化标准。
随机测试带来的负担:
- 随机测试带来的额外负担是环境的复杂度会提高,因为从环境组件上考虑不再只需要发送激励的组件,而且还包括监测器、比较器等。
- 随机测试带来的环境复杂度还包括由于对环境复用和测试复用带来的组件封装要求,这会使得代码量加大。
- 这种额外的代码量、环境集成要求也随之带来了更加灵活、更易集成复用的验证环境。
在引入了随机特性和功能覆盖率以后,这增加了环境的复杂的度和实现难度,但也使得环境和测试用例在复用和验证效率方面更有优势 。
基于MCDT的SV实验主要目的在于帮助同学建立验证环境结构的概念以及理解测试激励的生成及发送过程。
如何简单的产生一个随机数
在我们学习如何定义一个“随机”属性类之前,先了解一下如何利用系统函数产生一个随机数吧。
module _stim;
bit [15:0] addr ;
bit [31:0] data ;
function bit gen_stim() ;
bit success,rd_wr ;
//call std::randomize
success = randomize( addr,data,rd_wr ) ;
return rd_wr ;
endfunction
...
endmodule
//randomize()函数会有返回值
//如果randomize()函数中的参数随机化成功,返回值是1,失败是0。
//声明的向量都可以被randomize()系统函数随机化。
通过系统函数std: :randomize()对一些变量即可完成随机化,或者理解为产生随机数并赋予这些变量。
我们还可以通过其它一些与随机数生成有关的系统函数来产生。
$urandom() //可以生成一个32位的无符号随机数。
$urandom_range(maxval,minval=O)//可以生成介于maxval与minval之间的数。
在仿真中,每次调用这些函数,它们将产生不同的随机值 。决定随机数生成的,依赖于仿真内部的随机数生成器。影响随机数生成器的是仿真时传入的随机种子。
什么是系统而有机的组织随机变量
单纯的产生一些随机数,往往无法满足激励的合法性要求。
比起以上我们独立地生成一些随机数,在向DUT产生随机激励时,为了符合协议、满足测试需求,我们还需要添加一些约束。
约束的作用:
- 这些约束会使得变量朝着希望他们变化的方向去随机。
- 这些约束也会对变量与变量之间的关系生效。
因此,我们需要一个载体去容纳这些变量以及它们之间的约束。这个载体即是类,而类的成员变量均可声明为“随机”属性,用rand或者randc来表示。(类中如果有声明随机变量,往往也会伴随着针对这些变量的随机约束)
随机变量
任何类中的整形(bit/byte/int)变量都可以声明为rand/randc(随机属性)。
定长数组、动态数组、关联数组和队列都可以声明为rand/randc(随机属性),可以对动态数组和队列的长度加以约束。
rand bit [7:0] len;
rand integer data[];
constraint db { data.size == len; }
指向对象的句柄成员,也可以声明为rand(不能被声明为randc),随机时该句柄指向对象中的随机变量也会一并被随机。
非组合型结构体可以声明为rand,非组合型的成员可以声明为rand/randc。
typedef struct {
randc int addr = 1 + constant;
int crc;
rand byte data [] = {1,2,3,4};
}header;
rand header h1 ;
修饰符rand和randc
对于rand修饰符,表示在可生成的范围内,每个值的可能性是相同的。
rand bit [7:0] y;
对于randc修饰符,它的值将会随机并且遍历其可取值范围。
randc bit [1:0] y;
以抽扑克牌举例说明两种随机化方式:
rand:每次抽出一张牌以后,在接下来抽第二张牌的时候,把第一张牌放回去。那么前后两次,有一定的概率抽到同一张牌。
randc:每次抽出一张牌以后,在接下来抽第二张牌的时候,把第一张牌不放回去。每一次抽取的牌都不一样,只有当经过54次遍历后,才会重新洗牌。