【system verilog】随机和约束constraint

system verilog 随机语法

1、约束块(constraint block)

约束块是类的成员,像变量、task和function一样,约束块的名字在一个类里是唯一的,约束块的声明如下:

class bus;
	rand bit [31:0] addr,data
	constraint addr_c {
		addr[1:0] == 2'b0;
	}
endclass

上面的代码中构建了一个约束块addr_c,约束快的修饰符是constrain,约束的内容是地址的低2bit为0,在调用randomize()函数随机时,随机出的地址,低2bit一直为0;

class test_a;
	bus bus_a = new();
	task bus_test;
		repeat(50) begin
			if(bus_a.randomize() == 1)
				$display ("addr = %0h data = %h\n", bus.addr, bus.data);
			else
				$display ("Randomization failed.\n");
		end
	endtask
endclass

2、约束块的取值

A、简单表达式
在约束块中,只能使用关系操作符(<,<=,==, >=,>),一个表达式只能使用一个关系操作符。

class bus
	....
	constraint data_c { 
			data > 20;
			data<100;   //不能写为   20<data<100  ,这样一个表达式就有两个关系符;
	}
endclasss

等效表达式:==,表示约束的随机值取固定值,如上面的constrain addr_c,约束地址的低2bit取0

class bus
	....
	constraint data_c { 
	       data == 32'h5a5a_5a5a
	 };   //约束data的值恒为5a5a5a5a;
endclasss

B、约束块权重取值:dist
使用dist操作符,可以是变量按我们设定的权重值随机,以增加某些值的随机概率,产生我们期望的激励,dist权重取值有两种写法:

1、:=取权重

class bus
	....
	constraint data_c { 
		data dist {0:=10,[1:3]:=80};
		//data = 0,权重为10/250,250=10+80*3;
		//data = 1/2/3的权重均为80/250;
	}
endclasss

2、:/取权重

class bus
	....
	constraint data_c { 
		data dist {0:/10,[1:3]:/90};
		//data = 0,权重为10/100;
		//data = 1/2/3的权重均为30/100;
	}
endclasss

C、inside运算符
inside运算符用于在集合set中取值,system verilog在集合中取值时,每个值取中的概率是相等的。

class bus
	....
	constraint data_c { 
		data inside {[$:5],[10:100]};		//表示在0-5和10-100中取值,$表示边界值
		! (data inside {[110:200]});   		//表示取110-200之外的值
	}
endclasss

当集合set中的值有重复的时候,每个值取值概率也是一样的,不会因为某个值重复多次,概率就增加。

class bus
	....
	int array = '{1,2,2,3,3,3,4,4,4,4}
	constraint data_c { 
		data inside array;
		//此时,1,2,3,4取到的概率是相同的	
	}
endclasss

3、约束块中的条件约束

约束块中的条件约束有两种写法:

1、隐含操作符:->

typedef enum {low, mid, high} AddrType;
class bus
	......
	rand AddrType a_type ;
	constraint data_c { 
		(a_type == low) -> addr inside {[0:50]};
		(a_type == mid) -> addr inside {[60:70]};
		(a_type == high) -> addr inside {[80:100]};
	}
endclasss

2、if-else

typedef enum {low, mid, high} AddrType;
class bus
	......
	rand AddrType a_type ;
	constraint data_c { 
		if(a_type == low)    {
			addr inside {[0:50];
		}
		esle if(a_type == mid)   { 
			addr inside {[60:70]};
		}
		else if(a_type == high)  {
			addr inside {[80:100]};
		}
	}
endclasss

3、约束块中的约束关系都是双向的
约束块代码不是自上而下的程序性代码,是声明性的代码,是并行的,所有的约束表达式同时有效。

class test;
	rand bit x;
	rand bit[1:0] y;
	cosntraint xy_c {
		y>0;
		(x==0) -> (y==0);
	}
endclass

上面代码中的,x为0时,y为0,但约束是双向的,y不为0时,x的取值不为0,解的概率如下:

xy概率xy概率
000100
010111/3
020121/3
030131/3

4、sovle…before…修改解的概率
sovle…before…不会改变解的个数和范围,只会改变各个值的概率分布。

class test;
	rand bit x;
	rand bit[1:0] y;
	cosntraint xy_c {
		(x==0) -> (y==0);
		solve x before y;
	}
endclass

sovle x before y约束的解

xy概率xy概率
001/2101/8
010111/8
020121/8
030131/8

sovle y before x约束的解

xy概率xy概率
001/8101/8
010111/4
020121/4
030131/4

soft约束语法

soft约束,用例中再约束,也如果与soft不冲突,也继续选取soft的结果。

tips:当修饰符为randc时,不要使用sovle…before…,因为randc默认最先计算,使用sovle…before…可能会带来未知错误。

随机语法

class继承,验证环境和case之间继承约束使用方法

EDA验证中如何层层约束达到高效率仿真

### 如何在 SystemVerilog 测试用例中实现约束条件 #### 使用 `constraint` 关键字定义约束条件 为了确保测试数据符合特定的要求,在 SystemVerilog 中可以通过 `constraint` 来指定这些需求。例如,当模式为小端(little endian)时长度应小于10;而大端(big endian)则要求长度大于100[^1]。 ```systemverilog class Transaction; rand bit [7:0] len; rand byte mode; constraint c_mode { (mode == 0) -> (len < 10); (mode == 1) -> (len > 100); } endclass : Transaction ``` 此代码片段展示了如何通过类成员的方式定义两个不同的模式及其对应的长度限制。这里假设使用单个位来区分两种模式,其中0代表小端模式,1代表大端模式。 #### 结合 `rand` `randomize()` 方法应用约束 除了静态地设定约束外,还可以利用 `rand` 关键字标记那些希望被随机化的变量,并调用对象实例上的 `randomize()` 函数以动态生成满足给定约束的数据集[^2]。 ```systemverilog module testbench; initial begin Transaction tr; tr = new(); repeat(5) begin if (!tr.randomize()) $fatal("Randomization failed"); $display("Mode=%d Len=%h", tr.mode, tr.len); end end endmodule : testbench ``` 上述模块中的循环会尝试五次随机化事务对象内的字段值,每次都会打印出当前选定的模式以及相应的长度。如果随机化过程未能成功,则终止仿真并报告错误信息。 #### 处理复杂逻辑关系下的多变量关联 对于更复杂的场景,可能涉及到多个变量之间的相互依赖关系。此时可以在同一个 `constraint` 块内表达这种联系,如下所示: ```systemverilog class ComplexTransaction extends Transaction; rand bit [3:0] a, b; constraint ab_relation { (a == 0) -> (b == 1); } function void post_randomize(); super.post_randomize(); // 可在此处添加额外处理逻辑 endfunction endclass : ComplexTransaction ``` 这段扩展后的类不仅继承了之前定义的基础属性,还增加了新的整型变量 `a` `b` 的约束条件——即每当 `a` 等于零的时候,`b` 必须等于一。此外,重载了 `post_randomize()` 虚函数以便在完成一次完整的随机化之后执行某些自定义的操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值