Quick Start
- 安装支持SystemVerilog-2012的仿真器:推荐使用QuestaSim 2025.1或VCS 2026.03,确保支持随机化与UVM 1.2。
- 创建随机化测试文件:编写一个SystemVerilog文件(如
random_test.sv),在其中定义随机类与约束。 - 编写顶层测试台:实例化设计待测(DUT)和随机化驱动器,将两者通过接口连接。
- 控制随机种子:在仿真脚本中启用
+ntb_random_seed=1(或等效选项),确保结果可复现。 - 运行仿真:执行仿真命令,观察日志中随机化变量是否按约束生成(如地址对齐、数据范围)。
- 收集覆盖率:启用代码覆盖率与功能覆盖率,确认随机化测试覆盖了边界条件(如FIFO满/空、跨时钟域握手)。
- 优化仿真速度:若仿真过慢,可启用编译优化(如
-O4)或使用并行仿真(-j 4)。 - 验收标准:随机化测试在10分钟内运行1000次迭代,且无任何断言失败。
前置条件与环境
下表列出了推荐的项目配置与替代方案,确保随机化测试在仿真与综合阶段均能顺利执行。
| 项目 | 推荐值 | 说明 | 替代方案 |
|---|---|---|---|
| 器件/板卡 | Xilinx Virtex UltraScale+ (xcvu9p) | 用于综合验证随机化测试的FPGA目标 | Intel Agilex 7 |
| EDA版本 | QuestaSim 2025.1 / VCS 2026.03 | 支持SystemVerilog随机化与UVM 1.2 | Xcelium 24.09 |
| 仿真器 | QuestaSim(命令行模式) | 提供随机种子控制与覆盖率收集 | VCS / Riviera-PRO |
| 时钟/复位 | 100 MHz系统时钟,异步低有效复位 | 随机化测试需在复位释放后启动 | 50 MHz或200 MHz |
| 接口依赖 | AXI4-Stream / AXI4-Lite | 用于驱动随机化激励到DUT | 自定义握手协议 |
| 约束文件 | SDC(时序约束)+ 随机约束(SV内) | SDC用于综合后仿真,SV约束用于前仿真 | 仅SV约束 |
目标与验收标准
- 功能点:随机化测试能生成合法的AXI4-Stream事务,即TVALID/TREADY握手正确,数据长度在1~1024字节之间随机。
- 性能指标:仿真速度≥1000个事务/秒(在100 MHz时钟下)。
- 资源/Fmax:随机化测试本身不消耗FPGA资源(仅仿真),但DUT综合后Fmax≥200 MHz。
- 验收方式:日志中所有随机化变量均满足约束(无
randomize()失败);功能覆盖率≥90%(覆盖边界情况如最大/最小数据长度、背压周期)。
实施步骤
工程结构
- 创建目录
sim/(存放仿真脚本)、rtl/(存放DUT)、tb/(存放测试台与随机化类)。 - 在
tb/下放置axi_stream_driver.sv(随机化驱动器)和test_top.sv。 - 在
sim/下编写run.do(QuestaSim脚本)或Makefile。
关键模块:随机化类
class AxiStreamTransaction;
rand bit [7:0] data[];
rand int length;
rand bit tlast;
constraint c_length { length inside {[1:1024]}; }
constraint c_data_size { data.size() == length; }
constraint c_tlast { tlast == (length > 0); }
endclass
逐行说明
- 第1行:定义一个类
AxiStreamTransaction,用于封装AXI4-Stream事务。 - 第2行:声明随机化动态数组
data[],8位宽,长度可变。 - 第3行:声明随机化整数
length,表示数据字节数。 - 第4行:声明随机化位
tlast,指示是否为最后一个数据。 - 第5行:约束
length在1到1024之间,避免零长度事务。 - 第6行:约束
data数组大小等于length,确保一致性。 - 第7行:约束
tlast在length > 0时为1,符合AXI4-Stream规范(每个事务最后拍tlast置位)。
关键模块:随机化驱动器
class AxiStreamDriver;
virtual axi_stream_if vif;
function new(virtual axi_stream_if vif);
this.vif = vif;
endfunction
task run(int num_trans);
repeat (num_trans) begin
AxiStreamTransaction tr = new();
if (!tr.randomize()) $fatal("Randomization failed");
drive_transaction(tr);
end
endtask
task drive_transaction(AxiStreamTransaction tr);
foreach (tr.data[i]) begin
@(posedge vif.clk);
vif.tdata <= tr.data[i];
vif.tvalid <= 1;
@(posedge vif.clk && vif.tready);
end
vif.tlast <= 1;
@(posedge vif.clk);
vif.tvalid <= 0;
vif.tlast <= 0;
endtask
endclass
逐行说明
- 第1行:定义类
AxiStreamDriver,负责驱动随机化事务到DUT。 - 第2行:声明虚拟接口
vif,用于连接DUT的信号。 - 第3行:定义构造函数
new,接收虚拟接口参数。 - 第4行:将传入的虚拟接口赋值给内部变量
vif。 - 第5行:定义任务
run,参数为事务数量num_trans。 - 第6行:循环执行
num_trans次。 - 第7行:创建
AxiStreamTransaction对象tr。 - 第8行:调用
randomize(),若失败则打印致命错误并终止仿真。 - 第9行:调用
drive_transaction任务驱动事务到接口。 - 第10行:结束
run任务。 - 第11行:定义
drive_transaction任务,参数为AxiStreamTransaction对象。 - 第12行:遍历
tr.data数组的每个元素。 - 第13行:等待时钟上升沿。
- 第14行:将当前数据赋值给
tdata。 - 第15行:置位
tvalid,表示数据有效。 - 第16行:等待时钟上升沿且
tready为高(握手完成)。 - 第17行:结束
foreach循环。 - 第18行:置位
tlast,表示最后一个数据。 - 第19行:等待一个时钟周期。
- 第20行:清零
tvalid。 - 第21行:清零
tlast。 - 第22行:结束
drive_transaction任务。
验证结果
运行仿真后,检查日志文件:
- 确认所有
randomize()调用均成功,无致命错误。 - 观察事务长度
length是否均匀分布在1~1024之间。 - 检查功能覆盖率报告,确保边界条件(如长度为1、1024,背压周期)被覆盖。
排障指南
- 随机化失败:检查约束是否矛盾(如
length范围与data.size()约束冲突)。 - 仿真速度慢:尝试启用仿真器编译优化(如
-O4),或减少覆盖率收集的粒度。 - 断言失败:确认DUT的握手时序与随机化驱动器一致(如
tready信号处理)。
扩展建议
- 引入UVM环境,将随机化驱动器封装为
uvm_sequence,实现更复杂的场景(如背压、错误注入)。 - 使用SystemVerilog断言(SVA)自动检查事务合法性,减少人工日志分析。
- 对于大型设计,可并行运行多个随机种子以加速覆盖率收敛。
参考
- IEEE Std 1800-2012: SystemVerilog Language Reference Manual
- ARM AMBA AXI4-Stream Protocol Specification
- QuestaSim User’s Manual (Chapter: Randomization and Coverage)
附录:完整仿真脚本示例
# run.do (QuestaSim)
vlib work
vlog -sv -O4 random_test.sv
vlog -sv -O4 test_top.sv
vsim -c -do "run -all; coverage save -onexit coverage.ucdb; exit" +ntb_random_seed=1 work.test_top
将上述脚本保存为run.do,在终端执行vsim -do run.do即可启动仿真。

评论 0
暂无评论,快来抢沙发吧