验证约束
题目
"在验证一个数据传输协议时,我们有一个packet类,包含字段bit 7:0 length(表示payload字节数,范围1-255)、byte payload\[\](动态数组,存储数据)、bit 1:0 type(包类型:0=普通包,1=控制包,2=空包,3=保留)。请设计约束满足:
普通包(type=0):payload大小必须等于length,且length≥4;
控制包(type=1):payload大小固定为2(与length无关),且length=0;
空包(type=2):payload必须为空,length=0;
保留类型(type=3):禁止随机化(必须报错)。
代码
systemVerilog
class packet;
// 随机变量声明
rand bit [7:0] length; // payload 字节数,范围 1-255
rand byte payload[]; // 动态数组存储数据
rand bit [1:0] pkt_type; // 包类型:0=普通包,1=控制包,2=空包,3=保留
// 约束:禁止 type == 3
constraint type_c {
pkt_type != 3;
}
// 主约束:根据包类型设置 length 和 payload 大小
constraint packet_constraints {
// 普通包 (type=0)
if (pkt_type == 0) {
length >= 4;
payload.size() == length;
}
// 控制包 (type=1)
else if (pkt_type == 1) {
length == 0;
payload.size() == 2;
}
// 空包 (type=2)
else if (pkt_type == 2) {
length == 0;
payload.size() == 0;
}
// 保留类型 (type=3) - 通过 type_c 约束已禁止
else begin
`uvm_fatal(get_type_info(),"ERROR!!! type == 3");
end
}
// 求解顺序:先确定 pkt_type,再求解其他约束
solve pkt_type before length, payload.size();
// 构造函数
function new();
// 初始化代码
endfunction
// 显示函数
function void display();
$display("Packet: type=%0d, length=%0d, payload size=%0d",
pkt_type, length, payload.size());
endfunction
endclass
关键点说明:
- 使用
rand声明随机变量。 - 约束中使用
==进行相等比较(不是=)。 solve...before可引导求解器优先确定某些变量。- 动态数组大小通过
.size()方法约束。 - 保留类型(type=3)已在
type_c约束中排除,无需在if-else中处理。