Vivado仿真停滞问题求助:备用内存代码仿真异常
根据你描述的情况——代码在Icarus Verilog+GTKWave下完全正常,但Vivado仿真出现异常甚至疑似停滞——大概率是两款仿真引擎对Verilog语法、时间尺度或仿真设置的处理细节差异导致的。我整理了几个常见的排查方向和解决方案,你可以逐一尝试:
1. 补全明确的时间尺度声明
Vivado的XSim对时间单位/精度的要求比Icarus严格很多,你的Testbench里用到了#0.1、#0.2、#52.9这类小数延迟,如果没有明确的timescale声明,XSim可能无法正确解析这些延迟,导致时序混乱甚至仿真停滞。
解决方案:
在你的trial_tb模块最顶部添加时间尺度声明,比如:
`timescale 1ns/10ps module trial_tb; // 原Testbench代码...
这样#0.1就对应10ps,所有延迟值都是精度的整数倍,XSim就能正确处理了。
2. 调整仿真dump与结束指令
XSim对$dumpfile和$dumpvars的支持和Icarus有细微差异,有时候VCD文件生成异常会导致仿真看起来停滞;另外#90 $finish的时间点可能过早,Testbench里的读写操作还没完成。
解决方案:
- 先把
$finish改成$stop,这样仿真会在#90时刻暂停而不是直接退出,你可以在XSim界面手动检查信号状态; - 暂时注释掉
$dumpfile和$dumpvars相关代码,直接在Vivado仿真界面手动添加uut的所有信号到波形窗口,看是否能正常捕获波形; - 如果需要保留VCD dump,可以尝试只dump顶层模块,或者调整
$dumpvars的参数为$dumpvars(1, trial_tb),指定dump的层次深度。
3. 将端口位置连接改为名字连接
你当前例化SRAM_repair用的是位置连接方式:
SRAM_repair uut (clk, rst_n, bist_enable, we, wraddr, data_in, re, rdaddr, data_out, repair_fail, repair_finish);
这种方式虽然简洁,但如果SRAM_repair模块的端口顺序有过调整(哪怕你自己没注意到),会导致信号连接错误,Icarus可能不会抛出明显错误,但XSim的仿真行为会异常。
解决方案:
改成名字连接的方式,彻底避免端口顺序错误:
SRAM_repair uut ( .clk(clk), .rst_n(rst_n), .bist_enable(bist_enable), .we(we), .wraddr(wraddr), .data_in(data_in), .re(re), .rdaddr(rdaddr), .data_out(data_out), .repair_fail(repair_fail), .repair_finish(repair_finish) );
4. 检查Vivado仿真的日志与设置
很多时候仿真异常的原因都藏在日志里,你可以:
- 查看Elaboration阶段的日志,检查有没有端口不匹配、未定义信号、语法警告等问题;
- 查看Simulation阶段的日志,看是否有仿真引擎抛出的错误提示;
- 在Vivado的仿真设置中,确认
Simulation Mode是Behavioral,Target Simulator是XSim,并且勾选了Run simulation after elaboration。
5. 规范延迟值的写法
虽然#52.9这种延迟在语法上是合法的,但非整数的延迟值可能会让XSim的仿真引擎出现计算异常,建议调整为符合时间尺度的整数倍延迟,比如如果用1ns/10ps的尺度,#52.9可以写成#52900ps或者#52.9ns(明确单位),这样更清晰也更兼容。
按照上面的步骤逐一排查,应该能快速定位到Vivado仿真异常的原因。
内容的提问来源于stack exchange,提问作者abhijith

