Verilog 时序逻辑:验证同步复位与计数器回绕
设计两位计数器,在时钟上升沿更新,使用同步复位和自检测试平台观察 0 到 3 的回绕行为。
本节目标
设计两位计数器,在时钟上升沿更新,使用同步复位和自检测试平台观察 0 到 3 的回绕行为。
环境与运行方法
安装 Icarus Verilog,保存为 lesson.v,执行 iverilog -g2012 -s testbench -o lesson lesson.v,再执行 vvp lesson。这是仿真验证,不代表已经通过 FPGA 综合、时序分析或硬件测试。
核心思路
时序逻辑在指定时钟事件更新状态。非阻塞赋值用于寄存器更新,让多个寄存器以旧状态计算下一状态。同步复位也只在时钟边沿生效,不是复位信号变化就立刻清零。
完整示例
module counter(input wire clk, reset, output reg [1:0] count);
always @(posedge clk) begin
if (reset) count <= 2'd0;
else count <= count + 2'd1;
end
endmodule
module testbench;
reg clk = 0, reset = 1;
wire [1:0] count;
integer expected;
counter dut(clk, reset, count);
always #5 clk = ~clk;
initial begin
@(posedge clk); #1;
if (count !== 2'd0) $fatal(1, "reset failed");
@(negedge clk); reset = 0;
for (expected = 1; expected <= 4; expected = expected + 1) begin
@(posedge clk); #1;
if (count !== (expected % 4)) $fatal(1, "count failed");
$display("%0d", count);
end
$finish;
end
endmodule预期输出
1
2
3
0逐步理解
测试在下降沿撤销复位,避免与被测上升沿同时改变输入产生竞争。检查时等待一个小仿真步,让非阻塞赋值完成更新。两位寄存器只能表示 0 到 3,加一后自然回绕到零。
硬件里时钟和复位还涉及建立保持时间、跨时钟域与复位释放等问题,本例只验证逻辑仿真。不能把通过仿真直接当成电路已满足目标频率。
常见问题与边界
- 同步复位与异步复位敏感列表不同。
- 测试驱动与采样时刻应避开竞争。
- 位宽决定回绕范围,软件整数直觉不一定适用。
动手练习
把 count 宽度改成三位,同时修改测试预期。
参考答案
三位计数器应在 7 后回到 0,需要同步修改常量宽度、测试循环与取模范围为 8。只改寄存器声明会使原测试不再对应新契约。
文章回复
0 条公开回复