systemverilog-随机化技术

随着设计变得越来越大,要产生一个完整的激励集来测试设计的功能也变得越来越困难。
解决的办法是采用受约束的随机测试法(CRT)自动产生测试集。

1.什么需要随机化

对DUT(待测设计)里所有关键点都采用随机化的技术。随机化使控制路径里的每个分支都可能被测试。
需要考虑的方面:

  • 器件配置
  • 环境配置
  • 原始输入数据
  • 封装后的输入数据
  • 协议异常
  • 延时
  • 事务状态
  • 错误和违规

2.随机变量类型和方法

随机化变量以及随机约束都只能在class中声明变量,class中的局部变量也不能修饰

  • rand随机变量的值在指定范围内均匀分布,如果不添加约束,随机变量可以是指定有效范围内的任何值
  • randc 声明周期性随机变量,取值按照声明的有效范围周期性出现,且数据类型只可以是bit或enum
  • randomize() 方法,如果随机化成功,则返回1,否则返回0
  • constraint_mode() 函数打开或关闭约束
  • rand_mode() 函数可以打开或关闭随机变量
//随机化范围根据位宽为0~15
rand bit[3:0] addr1;
//y为2bit无符号整形数,取值范围:0~3,在一个周期内必然会产生0、1、2、3四个数、顺序不定
//即所有可能值都取过之后随机值才可能重复
randc bit[1:0] addr2;
//关闭
packet.c.constraint_mode(0)
packet.addr1.rand_mode(0)
//打开
packet.c.constraint_mode(1)
packet.addr1.rand_mode(1)

例子:

//class
class packet;
	rand bit [2:0] addr1;
	rand bit [2:0] addr2;
	constraint c {
		add1 >2;
		add2 <5;
	}
endclass
module rand_methods;
	initial begin
		packet pkt;
		pkt = new();
		repeat(10) begin
			pkt.randomize();
			$display("\taddr1 = %0d \t addr2 = %0d",pkt.addr1,pkt.addr2);
		end
	end
endmodule

3.随机化约束constraint

  • 使用关键字constraint来添加约束语句块,指定随机变量的取值范围,或者各个变量之间的相互关系
    -约束块是并行的,所有约束表达式同时有效

3.1关系操作符约束(>、<、=、>=、<=)

在一个表达式中最多只能使用一个关系操作符,不能连续使用

声明一个约束:0<a<b<c
class Bus
	rand bit[15:0] a,b,c;
	constraint c1 {
		0 < a;
		a < b;
		b < c;
	}
endclass

3.2 范围操作符约束(inside)

class Bus;
	rand int c;
	int lo,hi;
	constrant c_range{
		c inside {[lo:hi]};
		//等价于lo<=c并且c<=hi
		!(c inside {[lo:hi]});//对约束集合的取反
	}
endclass

3.3条件约束(if-else;- >)

通常约束块里的约束表达式都是有效的,如果想让约束在某些时刻有效,可以使用条件约束。

  • - > 操作符可以产生和case操作符同效果的语句块,可以用于枚举
  • if - else 更适合“真假”类型的表达式
class BusOp;
	...
	constraint c_io {
		(io_space_mode) - >
		addr[31] == 1'b1;
	}
	constraint c_len_rw{
		if(op == READ)
			len inside {[BYTE:LWRD]};
		else
			len == LWRD;
	}
endclass

3.4 双向约束

SV的约束是双向的,这代表它会同时计算所有随机变量的约束,增加或删除任何一个约束都有可能对随机变量的取值产生影响。

class Bus;
	rand logic [15:0] r,s,t;
	constraint c_bidir{
		r < t;
		s == r;
		t < 30;
		s > 25;
	}
endclass

SV同时计算四个约束表达式,根据约束之间的限定,下表列出了三个变量的各种取值:
在这里插入图片描述

3.5内嵌约束randomize()with{}

SV允许使用 randomize()with{} 来增加额外的约束,这和在类里增加约束是等效的。

class packet;
	rand bit [2:0] addr1;
	rand bit [2:0] addr2;
endclass
module rand_methods;
	initial begin
		packet pkt;
		pkt = new();
		assert(pkt.randomize()with{addr1 >= 2;addr <= 5;});
		$display("\taddr1 = %0d \t addr2 = %0d",pkt.addr1,pkt.addr2);
		end
	end
endmodule

4.权重分布

dist操作符允许产生权重分布,这样某些值的选取机会要比其他值更大一些。
符号用 : = 或者 : /

  • : = 表示值范围内每个值的权重都是相同的
  • : / 表示权重要平均分配到范围内的每个值
    40+60*3=220
    40+60=100
rand int src,dst;
constraint c_dist{
	src dist {0:=40,[1:3]:=60};
	dst dist {0:/40,[1:3]:/60};
}

在这里插入图片描述

5.数组约束

5.1约束数组中的元素

foreach对数组的每个元素进行约束
randc产生一个随机数组,每一个元素的值都是唯一的,但要经过特殊处理

方法释义
size()对数组的长度限定
sum()求和
product()求积
and()求与
or()
xor()异或
class good
	rand uint len[];
	constraint c_len {
		foreach (len[i]) len[i] inside {[1:255]};
		len.sum() < 1024;
		len.size() inside {[1:8];};
	}
endclass

5.2利用randc变量产生唯一元素值的数组

class randc8;
    randc bit [7:0] val;
endclass
class LittleUniqueArray;
    bit [7:0] ua[64];
    function void pre_randomize();
        randc8 rc8;
        rc8 = new();
        foreach (ua[i]) begin
            assert(rc8.randomize());
            ua[i]=rc8.val;
        end
    endfunction
endclass

5.3 随机化句柄数组

如果要产生多个随机对象,就需要建立随机句柄数组。
随机句柄数组的声明一定要加rand来表示随机化的属性,同时在调用随机函数前,要保证数组中每一个句柄元素都非悬空的,故需要在随机化之前为每一个句柄元素构建对象

parameter MAX_SIZE = 10;
class RandStuff;
	bit[1:0] value = 1;
endclass:RandStuff

class RandArray;
	rand RandStuff array[];
	//约束数组大小
	constraint c{
		array.size() inside {[1:MAX_SIZE];}
	}
	function new();
	//分配最大容量
		array = new[MAX_SIZE];
		foreach(array[i])
		array[i] = new();//保证数组中每个句柄元素都非悬空
	endfunction
endclass:RandArray

RandArray ra;
initial begin
//构造数组和所有对象
ra = new();
//随机化数组但可能会减小数组
assert(ra.randomize());
foreach(ra.array[i])
	$display(ra.array[i].value);
end
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值