在 SystemVerilog 中,有两种主要的随机化方法:
-
类的
randomize()方法 - 只能在 class 中使用 -
全局的
std::randomize()函数 - 可以在任何地方使用
1、std::randomize
std::randomize 是 SystemVerilog 提供的轻量级随机化接口 ,区别于 class 内的 randomize() 方法,它无需定义类 / 约束块,可直接对任意变量(包括模块内的 reg/wire、局部变量)进行随机化,特点:
- 无类依赖:直接作用于变量,无需封装成类,适合简单随机场景;
- 动态约束:支持 inline(内联)约束,灵活控制随机值范围;
- 类型兼容:支持整数、实数、枚举、数组等几乎所有 SystemVerilog 类型;
- 返回值判断 :返回
1表示随机化成功,0表示约束冲突 / 失败,便于错误处理
std::randomize()是一个内置函数,它不需要在类中调用,也不依赖于类的rand修饰符。它可以直接对任何变量进行随机化,只要这些变量是可赋值的。
//*********第一个例子**********//
module test;
int addr;
bit [3:0] data;
enum {READ, WRITE, IDLE} op;
initial begin
// 约束1:addr在0~1023之间,且为16的倍数
if (!std::randomize(addr) with {addr >= 0; addr < 1024; addr % 16 == 0;}) begin
$error("addr randomize failed!"); // 约束冲突时报错
end
$display("addr = %0d", addr); // 输出如 16/32/128 等
// 约束2:data>5,且op不为IDLE
std::randomize(data, op) with {
data > 5;
op != IDLE;
};
$display("data = %0d, op = %s", data, op.name()); // data:6~15,op:READ/WRITE
end
endmodule
//*********第二个例子**********//
module test;
int arr[5]; // 5元素整数数组
initial begin
// 约束:数组元素都在0~100之间,且总和<200,第一个元素>最后一个
std::randomize(arr) with {
foreach (arr[i]) arr[i] inside {[0:100]}; // 每个元素0~100
sum(arr) < 200; // 数组总和<200
arr[0] > arr[4]; // 第一个元素>最后一个
};
$display("arr = %p", arr); // 输出如 '{90, 10, 20, 30, 80}
end
endmodule
与类内 randomize() 的区别
| 特性 | std::randomize |
类内 randomize() |
|---|---|---|
| 依赖 | 无类依赖,直接用 | 需定义类 + 约束块 |
| 约束 | 内联约束(临时) | 类内约束块(可重载) |
| 复用性 | 低(约束随用随写) | 高(约束封装在类中) |
| 适用场景 | 简单随机、临时激励 | 复杂测试用例、可复用激励 |
2、randomize
在类中,我们可以声明rand或randc修饰的变量,然后调用该类的randomize()方法来随机化这些变量
class pkt;
rand int addr;
rand bit [7:0] data;
// 软约束:addr默认0~1023,data默认0~200
constraint c_default {
soft addr inside {[0:1023]}; // 软约束:地址默认范围
soft data <= 200; // 软约束:数据默认上限
data >= 0; // 硬约束:数据下限不可覆盖
}
endclass
module test;
pkt p = new();
initial begin
p.randomize();//****注意****,这里是使用的pkt类的句柄进行随机化的
$display("默认约束:addr=%0d, data=%0d", p.addr, p.data); // addr:0~1023,data:0~200
if (!p.randomize() with {
addr inside {[2000:3000]}; // 覆盖soft addr约束
data == 250; // 覆盖soft data <=200约束
}) begin
$error("随机化失败");
end
$display("覆盖后:addr=%0d, data=%0d", p.addr, p.data); // addr:2000~3000,data=250
if (!p.randomize() with {
data < 0; // 与硬约束data>=0冲突
}) begin
$error("硬约束冲突,随机化失败"); // 触发报错
end
end
endmodule