如何用Verilog验证单端口RAM 无需查看波形即可自动校验读写数据
单端口SRAM自动校验实现方案
核心实现逻辑
通过在testbench的module作用域声明全局期望存储数组,记录每个地址的写入数据,读取操作完成后直接和期望数组对比,自动输出校验结果。
具体实现步骤
- 第一步:在testbench的module域(不要定义在task内部)声明对应位宽、深度的期望存储数组,同时增加错误计数变量,示例如下:
// 请根据你的SRAM实际位宽、深度调整参数 parameter DATA_WIDTH = 32; parameter ADDR_WIDTH = 10; parameter DEPTH = 1 << ADDR_WIDTH; reg [DATA_WIDTH-1:0] expected_mem [0:DEPTH-1]; integer error_cnt = 0;
- 第二步:修改你的
write_read任务,每次生成随机数先存入期望数组再执行写操作,读操作完成后直接对比读数据和期望数组的对应值,修正原代码for循环语法错误后的示例如下:
task write_read; integer i; reg [DATA_WIDTH-1:0] wr_data; reg [DATA_WIDTH-1:0] rd_data; begin // 提前写入地址0的初始值,避免第一次读i-1=0时出现未知值误报 wr_data = $urandom; expected_mem[0] = wr_data; write_mode(0, wr_data); for (i=1; i<=20; i=i+1) begin // 生成随机数先存到临时变量和期望数组,再调用写任务 wr_data = $urandom; expected_mem[i] = wr_data; write_mode(i, wr_data); // 调用读任务,读取i-1地址 read_mode(i-1); // 此处请根据你read_mode的输出延迟补充必要的#延迟,确保读数据已稳定 // 例如read_mode后1拍出数据就加 #1; rd_data = <你的RAM读数据端口信号名>; // 数据对比 if(rd_data !== expected_mem[i-1]) begin $display("ERROR: 地址0x%0h 读取值0x%0h 与期望值0x%0h 不匹配", i-1, rd_data, expected_mem[i-1]); error_cnt = error_cnt + 1; end else begin $display("INFO: 地址0x%0h 读写校验通过", i-1); end end // 所有循环完成后打印最终校验结果 if(error_cnt == 0) begin $display("======================================"); $display("TEST PASSED: 所有地址读写校验无错误"); $display("======================================"); end else begin $display("======================================"); $display("TEST FAILED: 共发现%0d个读写错误", error_cnt); $display("======================================"); end $finish; end endtask
- 第三步:批量工程适配
你可以将上述逻辑统一嵌入所有工程的testbench模板中,仿真时直接生成日志文件,批量执行时通过grep "TEST PASSED\|TEST FAILED\|ERROR"即可快速批量筛选所有工程的测试结果,无需打开Verdi波形核对。
注意事项
- 对比时请使用
!==而非!=,避免RAM输出X/Z态时无法识别的问题 - 读数据采样的延迟必须和你自定义
read_mode任务的输出时序对齐,确保采样时读数据已经稳定 - 如果你的SRAM有字节掩码等特殊功能,需要对应调整期望数组的写入逻辑,仅更新掩码对应的字节
内容的提问来源于stack exchange,提问作者John_cena
相关产品推荐
相关产品推荐

