Verilog state/next_state型状态机为何被视为FPGA最佳实践?
关于FSM两段式写法的时钟周期误解与最佳实践解析
首先纠正你的核心误解:你贴出的代码写法并不是论文推荐的标准两段式FSM结构,这也是你觉得多时钟周期的原因。正确的推荐写法是用一个时序always块更新状态寄存器,另一个组合always块计算下一个状态,代码结构应该是这样:
// 时序块:同步更新状态寄存器 always @(posedge clock or negedge reset_n) begin if(!reset_n) state <= IDLE; else state <= next_state; end // 组合块:组合逻辑计算next_state always @(*) begin next_state = state; // 默认保持当前状态,避免锁存器 case(state) IDLE: begin if(start_signal) next_state = RUNNING; end RUNNING: begin if(done_signal) next_state = IDLE; end // 其他状态逻辑... endcase end
为什么这种写法不会多时钟周期?
在这个结构里:
- 组合逻辑块
@(*)会在state或任何输入信号变化时立即计算出next_state,这个值会在时钟上升沿到来前稳定。 - 当下一个时钟上升沿(比如第N个)到来时,时序块会把
state更新为已经计算好的next_state,状态切换在同一个时钟周期内完成,完全不存在你担心的多一个周期延迟问题。
你之前看到的两个时序块的写法是错误的,这种写法才会导致next_state需要一个时钟周期更新,再等一个周期才能同步到state,属于错误的实现方式,并非论文推荐的最佳实践。
为什么两段式FSM是最佳实践?
- 结构清晰易维护:把状态存储(时序逻辑)和状态转移计算(组合逻辑)完全分开,代码逻辑一目了然,后期修改状态转移规则或添加新状态时更不容易出错。
- 避免意外锁存器:组合块用
@(*)触发,自动包含所有输入信号,只要给next_state设置默认值(比如next_state = state),就能避免综合器生成意外的锁存器,这是FPGA设计中必须避免的问题。 - 时序优化更可控:组合逻辑的延迟可以单独分析,时序路径明确,更容易做时序约束和优化,保证设计在目标FPGA上满足时钟频率要求。
- 输出毛刺抑制:如果输出由状态寄存器直接驱动(或单独用时序块驱动),可以避免组合逻辑输出带来的毛刺,提高系统稳定性。
内容的提问来源于stack exchange,提问作者fsctl
相关产品推荐
相关产品推荐

