1. 项目概述
这个项目实现了一个基于SystemVerilog的UVM(Universal Verification Methodology)风格的验证环境,用于测试双端队列数据收发功能。整个验证平台模拟了真实芯片验证中的典型架构,包含数据生成、驱动、监测、检查和参考模型等组件,能够自动生成测试数据、发送数据包、收集响应并验证功能正确性。
2. 验证环境架构解析
2.1 核心组件与数据流
验证环境采用分层设计,主要组件包括:
- pkt_gen:数据包生成器,负责产生随机测试数据
- pkt_drv:驱动器,将生成的数据按照协议时序发送到DUT
- pkt_mon:监测器,捕获DUT输入和输出接口的数据
- pkt_rm:参考模型,实现与DUT相同的算法逻辑
- pkt_chk:检查器,比较DUT输出与参考模型结果
- environment:顶层环境,集成所有组件并协调运行
数据流向为:gen → drv → DUT → mon → chk,同时mon也会将输入数据发送给rm,rm处理后发送给chk作为预期结果。
2.2 接口定义
项目定义了标准的接口协议:
systemverilog复制interface pkt_if(input clk, rst_n);
logic [7:0] data;
logic sop; // 包起始指示
logic eop; // 包结束指示
logic vld; // 数据有效指示
// 驱动和监测的时钟块
clocking drv @(posedge clk);
output data, sop, eop, vld;
endclocking
clocking mon @(posedge clk);
input data, sop, eop, vld;
endclocking
endinterface
这种接口设计支持全双工通信,包含数据有效标志和包边界指示,是工业级验证接口的典型实现。
3. 关键实现细节
3.1 数据包结构设计
数据包采用面向对象方式建模,核心类是pkt_data:
systemverilog复制class pkt_data;
rand bit [7:0] payload_q[$]; // 数据负载队列
rand int interval; // 包间隔
rand int pkt_len; // 包长度
bit [10:0] data[$]; // 格式化后的数据
// 随机约束
constraint pkt_len_cons {
pkt_len inside {[1:50]}; // 包长度1-50
};
constraint interval_cons {
interval inside {[3:6]}; // 包间隔3-6周期
};
endclass
这种设计允许灵活生成不同长度和间隔的数据包,满足各种测试场景需求。
3.2 数据打包与解包
数据包需要按照接口协议格式化:
systemverilog复制function void pkt_data::pack();
foreach (this.payload_q[i]) begin
if (i==0 & i==pkt_len-1) // 单字节包
this.data.push_back({1'b1, 1'b1, 1'b1, payload_q[i]});
else if (i==0) // 包起始
this.data.push_back({1'b1, 1'b1, 1'b0, payload_q[i]});
else if (i==pkt_len-1) // 包结束
this.data.push_back({1'b1, 1'b0, 1'b1, payload_q[i]});
else // 包中间数据
this.data.push_back({1'b1, 1'b0, 1'b0, payload_q[i]});
end
// 添加包间隔
for(int i=0; i<interval; i++)
this.data.push_front({'0});
endfunction
这种打包方式确保每个数据周期都带有正确的控制信号,符合接口协议要求。
3.3 参考模型实现
参考模型(pkt_rm)实现了与DUT相同的处理逻辑:
systemverilog复制function pkt_data pkt_rm::data_trans(pkt_data in_data);
pkt_data tmp;
tmp = in_data.copy();
foreach(in_data.payload_q[i]) begin
if (i >= 1) begin
// 异或运算处理数据
tmp.payload_q[i-1] = in_data.payload_q[i-1] ^ in_data.payload_q[i];
end
end
tmp.payload_q[in_data.pkt_len - 1] = in_data.payload_q[in_data.pkt_len - 1];
return tmp;
endfunction
参考模型采用与DUT相同的算法,但用更高级的SystemVerilog实现,作为验证的黄金参考。
4. 测试平台搭建
4.1 环境配置
环境配置通过env_cfg类实现:
systemverilog复制class env_cfg;
bit chk_idle; // 检查器空闲标志
bit gen_idle; // 生成器空闲标志
bit drv_idle; // 驱动器空闲标志
bit mon_idle; // 监测器空闲标志
int env_wait_pkt_time = 10000; // 环境超时设置
int mon_wait_pkt_time = 1000; // 监测器超时
int drv_wait_pkt_time = 1000; // 驱动器超时
int chk_wait_pkt_time = 1000; // 检查器超时
endclass
这些配置参数控制验证环境的运行行为,如超时设置和各组件状态监控。
4.2 测试用例设计
项目提供了两种测试用例:
- 基础测试(base_test):随机生成不同长度的数据包
- 完整性测试(sanity_case):固定10字节长度的数据包测试
systemverilog复制class sanity_case_data extends pkt_data;
constraint pkt_len_cons {
pkt_len == 10; // 固定包长度
};
endclass
这种设计既保证了随机性测试,又有确定性测试用例,验证更全面。
5. 运行与调试
5.1 编译运行脚本
项目使用Makefile管理编译和运行:
makefile复制# 编译选项
CMP_OPTIONS += -f $(FILELIST) -P $(VERDI_P) -l $(SIM_LOG) -o $(EXEC_SIMV)
CMP_OPTIONS += +v2k +define+RTL_SAIF +notimingcheck +nospecify +vpi +memcbk
CMP_OPTIONS += -sverilog -full64 -debug_all -ntb_opts uvm-1.2
# 运行选项
RUN_OPTIONS += +ntb_random_seed=$(SEED) +tc_name=$(tc) -l $(RUN_LOG)
RUN_OPTIONS += +fsdbfile+$(RUN_WAVE) -ucli -do ../cfg/run.do
这些选项配置了仿真工具(VCS)的各种参数,包括文件列表、调试选项、波形记录等。
5.2 波形调试
项目支持生成FSDB波形文件,可使用Verdi工具进行调试。关键信号包括:
- 输入接口:data_in, sop_in_vld, eop_in_vld, data_in_vld
- 输出接口:data_out, sop_out_vld, eop_out_vld, data_out_vld
- 内部信号:data_in_ff1, data_in_merge等
6. 验证结果分析
检查器(pkt_chk)会统计并报告验证结果:
systemverilog复制function pkt_chk::report();
$display("----------------------------------------");
$display("[CHECKER REPORT]expect pkt_num=%0d, actual pkt_num=%0d, match pkt_num=%0d, not match pkt_num=%0d",
in_expect, in_actual, match, not_match);
$display("----------------------------------------");
endfunction
典型输出示例如下:
code复制[CHECKER REPORT]expect pkt_num=10, actual pkt_num=10, match pkt_num=10, not match pkt_num=0
这表示所有预期的数据包都正确接收,且内容与参考模型一致。
7. 项目扩展与优化建议
7.1 功能扩展方向
- 增加错误注入测试:在驱动器中添加错误注入功能,验证DUT的鲁棒性
- 性能统计:添加吞吐量、延迟等性能指标统计
- 协议覆盖:支持更多协议选项,如CRC校验、重传机制等
7.2 代码优化建议
- 参数化设计:将数据位宽等参数提取为宏或参数,提高代码复用性
- 回调机制:添加回调函数,方便在不修改原有代码的情况下扩展功能
- 日志分级:实现更细致的日志分级控制,便于调试
7.3 验证质量提升
- 功能覆盖率:添加功能覆盖率收集,确保充分验证
- 断言验证:添加SVA断言,实时检查协议合规性
- 随机约束优化:细化随机约束,生成更有针对性的测试场景
这个项目完整实现了一个基于UVM风格的验证环境,涵盖了从数据生成到结果检查的全流程,是学习现代验证方法的优秀范例。通过这个框架,可以方便地扩展更多测试用例和验证场景,适合各种数据通信协议的验证需求。