文章目录
前言
以下是一个完整的SystemVerilog测试平台示例,包含约束随机地址生成、日志输出和波形生成功能:
代码示例:
c
// filename: addr_gen_tb.sv
`timescale 1ns/1ps
module addr_gen_tb;
// 声明时钟信号
logic clk;
// 声明随机地址生成类
class RandomAddress;
rand bit [15:0] addr;
// 地址范围约束:0x1000 - 0xFFFF
constraint valid_range {
addr inside {[16'h1000:16'hffff]};
}
endclass
// 测试平台变量
bit [15:0] current_addr;
RandomAddress addr_gen = new();
int error_count = 0;
// 生成时钟(50MHz)
initial begin
clk = 0;
forever #10 clk = ~clk;
end
// 波形记录初始化
initial begin
$dumpfile("waves.fsdb");
$dumpvars(0, addr_gen_tb);
end
// 主测试程序
initial begin
$display("=== Starting Test ===");
repeat (20) begin
@(negedge clk);
if (!addr_gen.randomize()) begin
$error("Randomization failed!");
error_count++;
end
else begin
current_addr = addr_gen.addr;
$display("[%0t] Generated address: 0x%h", $time, current_addr);
// 验证地址范围
if (!(current_addr >= 16'h1000 && current_addr <= 16'hffff)) begin
$error("Address out of range: 0x%h", current_addr);
error_count++;
end
end
#5; // 添加少量延迟用于波形观察
end
$display("\n=== Test Summary ===");
$display("Total errors: %0d", error_count);
if (error_count == 0) $display("TEST PASSED");
else $display("TEST FAILED");
$finish;
end
endmodule
运行方法:
- 使用Synopsys VCS:
bash
vcs -sverilog addr_gen_tb.sv
./simv
- 使用Cadence Xcelium:
bash
xrun -sv addr_gen_tb.sv
查看结果:
-
日志输出示例:
=== Starting Test ===
Generated address: 0x3a7b
Generated address: 0xf42c
Generated address: 0x8d01
...
=== Test Summary ===
Total errors: 0
TEST PASSED -
查看波形(以VCS为例):
bash
verdi -wave waves.fsdb &
关键功能说明:
-
随机约束类
RandomAddress
:- 使用
rand
关键字声明随机变量 inside
约束确保地址在0x1000-0xFFFF之间
- 使用
-
测试平台特性:
- 自动生成时钟信号(50MHz)
- 每次生成地址后自动验证范围
- 错误计数和最终测试结果统计
- 详细的时序日志输出(包含时间戳)
-
波形生成:
- 使用
$dumpfile
和$dumpvars
生成VCD格式波形 - 记录所有层次信号(参数0表示记录所有层次)
- 使用
-
验证机制:
- 自动检查随机化成功状态
- 二次验证地址范围
- 错误计数器自动累加
这个示例可以:
- 生成符合要求的随机地址
- 自动验证地址有效性
- 输出带时间戳的详细日志
- 生成可用于调试的波形文件
- 提供清晰的测试结果总结
扩展功能建议:
添加覆盖率收集:
c
xcovergroup addr_cg;
xcoverpoint gen.addr {
xbins low = {[16'h1000:16'h7FFF]};
xbins high = {[16'h8000:16'hFFFF]};
}
xendgroup
在类中实例化覆盖率对象
多约束组合:
c
constraint even_addr {
addr % 2 == 0; // 生成偶数地址[4](@ref)
}