Verilog时钟模块及测试平台陷入死循环问题求助
问题排查与修复
核心问题
当reset信号为高电平时,clock_generator模块中的always块会触发无限循环:
- 该分支仅执行
clk = 1'b0;,没有任何时间延迟语句 - Verilog仿真器会持续重复执行这个赋值操作,无法推进仿真时间,也就无法响应测试平台中
reset信号的后续变化,最终导致测试平台的$finish永远无法触发,仿真彻底卡死
修复方案
在reset分支中添加最小延时,让仿真器有机会处理其他事件;或者改用带敏感列表的always块(更符合工业界Verilog设计规范)。
方案1:给reset分支添加最小延时
修改clock_generator的always块,在reset分支加入#0(非阻塞延时,允许仿真器调度其他事件):
always begin if (reset) begin clk = 1'b0; #0; // 添加最小延时,让仿真器能处理测试平台的reset信号变化 end else begin clk = 1'b1; #(cycle) clk = 1'b0; #(tp - cycle); end end
方案2:改用带敏感列表的always块(推荐)
这种写法更贴近可综合代码风格,同时从根源避免无限循环:
`timescale 1ns / 1ps module clock_generator( input wire reset, output reg clk ); parameter frequency = 1e8; parameter duty = 0.50; parameter tp = (1/frequency) * 1e9; parameter cycle = tp*duty; initial begin clk = 1'b0; end always begin if (reset) begin clk = 1'b0; #1; // reset时等待1ns,确保仿真时间能正常推进 end else begin clk = 1'b1; #(cycle) clk = 1'b0; #(tp - cycle); end end endmodule
额外优化建议
- 时序逻辑中尽量使用非阻塞赋值(
<=),阻塞赋值(=)更适合组合逻辑,代码风格更规范 - 测试平台的
timescale建议和模块保持一致(1ns / 1ps),避免精度不一致引发的潜在问题
内容的提问来源于stack exchange,提问作者Kartikey Pant
相关产品推荐
相关产品推荐

