文章目录
0 概述
SystemVerilog允许用户以一种紧凑的、声明式的方式指定约束。然后由求解器处理约束,生成满足约束的随机值。
随机约束通常是在面向对象的数据抽象之上指定的,该抽象将要随机化的数据建模为包含随机变量和用户定义约束的对象。这些约束决定了可以分配给随机变量的合法值。
例子:
class Bus;
rand bit[15:0] addr;
rand bit[31:0] data;
constraint word_align {
addr[1:0] == 2’b0;}
endclass
Bus类用两个随机变量对简化的总线建模:addr和data,它们代表总线上的地址和数据值。word_align约束声明addr的随机值必须是按字对齐的(低2位为0,4byte=1word)。
例化:
Bus bus = new;
repeat (50) begin
if ( bus.randomize() == 1 )
$display ("addr = %16h data = %h\n", bus.addr, bus.data);
else
$display ("Randomization failed.\n");
end
调用 randomize() 会为所有随机变量产生约束范围内的随机值。
在上面的程序测试中,创建一个总线对象,然后随机化50次。检查每个随机化的结果是否成功。如果随机化成功,则打印addr和data的新随机值;如果随机化失败,就会打印一条错误消息。本例中,只有addr值受约束,而data值不受约束。无约束变量在其声明范围内被赋任何值。
约束编程是一种功能强大的方法,它允许用户构建通用的、可重用的对象,稍后可以对这些对象进行扩展或约束,以执行特定的功能。这种方法既不同于传统的过程式编程,也不同于传统的面向对象编程,如下例所示,它扩展了Bus类:
typedef enum {
low, mid, high} AddrType;
class MyBus extends Bus;
rand AddrType atype;
constraint addr_range
{
(atype == low ) -> addr inside {
[0 : 15] };
(atype == mid ) -> addr inside {
[16 : 127]};
(atype == high) -> addr inside {
[128 : 255]};
}
endclass
MyBus类继承了Bus类的所有随机变量和约束,并添加了一个名为atype的随机变量,该随机变量用于使用另一个约束控制地址范围。addr_range约束使用 蕴涵词(implication,->) 来根据atype的随机值从三个范围约束中选择一个。
当一个MyBus对象被随机化时,addr、data和type的值将被计算出来,以便满足所有的约束。使用继承来构建分层约束系统使通用模型的开发成为可能,这些模型可以被约束来执行特定于应用程序的功能。
调用:
task exercise_bus (MyBus bus);
int res;
// EXAMPLE 1: restrict to low addresses
res = bus.randomize() with {
atype == low;};
// EXAMPLE 2: restrict to address between 10 and 20
res = bus.randomize() with {
10 <= addr && addr <= 20;};
// EXAMPLE 3: restrict data values to powers-of-two
res = bus.

本文详细介绍了SystemVerilog中如何使用随机变量、约束块以及约束编程技术。通过示例展示了如何声明和使用rand及randc关键字定义随机变量,以及如何设置约束以指定变量的合法值。约束包括membership、分布、蕴涵、if...else、迭代和全局约束,支持函数调用和变量排序。此外,文章还讨论了静态约束块、约束保护以及如何通过solve before实现变量排序。这些功能使SystemVerilog能够生成满足特定条件的随机激励,用于验证设计的正确性。
最低0.47元/天 解锁文章
7400

被折叠的 条评论
为什么被折叠?



