后实现时序仿真中数组元素未同步更新问题咨询
FSM后实现时序仿真状态跳变异常分析
问题描述
编写的同步FSM预期在SCL上升沿将状态从0递增到4后重置为0,但后实现时序仿真中出现状态跳变异常:期望01(1)→10(2),实际出现01→11→10的中间态,推测是状态位未同时变化导致。
设计与测试代码
FSM设计源码
`timescale 1ns / 1ps module fsm( input wire SCL, output wire [3:0] state ); reg [3:0] state_drv = 0; assign state = state_drv; always@(posedge SCL)begin if(state < 4)begin state_drv <= state_drv + 1; end else begin state_drv <= 0; end end endmodule
测试平台代码
`timescale 1ns / 1ps module testbench(); reg clk = 0; wire [3:0] state; wire scl; always #5 clk = ~clk; assign scl = clk; fsm is1( .SCL(clk), .state(state) ); initial begin # 10000 $finish; end endmodule
问题分析与结论
这是后仿真的正常现象
后实现时序仿真会加载真实的器件布线延迟数据,硬件电路中不同信号位的路径长度、负载不同,必然存在延迟差异,导致多bit状态切换时无法绝对同步,出现短暂的中间态(比如1→2时,低位先从1变0,高位后从0变1,中间就会出现11的状态)。而功能仿真(前仿真)不考虑延迟,所以看不到这个现象。你的Verilog代码逻辑无问题
代码使用了非阻塞赋值<=实现同步时序逻辑,这是符合FPGA/ASIC同步设计规范的写法,不存在逻辑错误。对实际功能的影响与优化建议
- 如果后续电路是在SCL上升沿同步采样state信号,这个短暂的中间态不会被捕获,因为毛刺出现在两个时钟沿之间,采样时信号已经稳定,不影响实际功能。
- 如果后续电路是异步采样state信号,则需要优化:可以将state信号打一拍再输出(用寄存器同步),或者改用格雷码编码状态(格雷码每次状态切换仅改变1bit,从根本上避免多bit跳变带来的中间态)。
内容的提问来源于stack exchange,提问作者zm597
相关产品推荐
相关产品推荐

