状态机实现的功能,可拆吗?
专栏:芯想事珹 March 28, 2026, 3:38 p.m. 12 阅读
用状态机实现的功能,是否必须依赖状态机?能不能“越过状态机”,用别的逻辑等价实现?

640.gif

做数字IC与FPGA设计,很多人都有过这样的认知: 普通组合逻辑、时序逻辑能实现的功能,一定可以用状态机重写。

那反过来问:用状态机实现的功能,是否必须依赖状态机?能不能“越过状态机”,用别的逻辑等价实现?那反过来问:用状态机实现的功能,是否必须依赖状态机?能不能“越过状态机”,用别的逻辑等价实现?

答案非常肯定:可以,而且一定可以。

从数字电路理论来说,无论是米利型(输出由当前状态和输入决定)还是摩尔型(输出仅由当前状态决定)状态机,它们的数学模型都决定了,其本质就是一个反馈时序电路。

当前状态寄存器组就是反馈回路的‘状态保持’元件,而下一状态和输出的逻辑,完全可以看作是一个巨大的、描述当前状态与输入映射关系的组合逻辑真值表。因此,只要你能用真值表描述的功能,就一定能用组合逻辑实现。

所以,"拆掉"状态机,在理论上是永远成立的。

本质上,任何有限状态机(FSM),都只由两部分构成:一组寄存器,用来保存当前状态,以及组合逻辑,用来计算下一状态和输出。

状态机并不是一种“特殊硬件”,它只是一种编码范式,状态机的实现只是把控制逻辑结构化、显性化,方便人阅读、维护和工具优化。但从电路层面看,状态机没有任何特殊效果,它最终还是会被综合成寄存器+组合逻辑。

这意味着,所有能用状态机描述的控制流,都可以拆掉状态层,用计数器、移位寄存器、条件判断、布尔逻辑等方式重新组织,实现完全一样的功能与时序行为。

只不过,拆了状态机之后,简单逻辑会更简洁,复杂逻辑会变得隐晦、难维护,也容易隐藏竞争冒险、边界漏洞。

所以,对于上述问题更为准确的回答是:不是能不能拆,而是值不值得拆。

状态机是优秀工程范式,但不是枷锁,真正懂RTL的设计者,既能在复杂流程里优雅地写状态机,也能在简单场景里直接用最简逻辑实现,不被写法绑架。

以一个简单的单拍脉冲发生器为例:

1)状态机写法

module pulse_fsm( input clk, rst_n, en, output reg pulse );
localparam IDLE = 1'b0;
localparam GEN = 1'b1;
reg c_state, n_state;

always @(posedge clk or negedge rst_n)begin
  if(!rst_n)
    c_state <= IDLE;
  else
    c_state <= n_state;
end

always @(*)begin
  n_state = IDLE;
  case(c_state)
  IDLE:
    if(en)n_state = GEN;
  GEN:
    n_state = IDLE;
  endcase
end

always @(*)begin
  pulse = (c_state ==&nbsp;GEN);
end

endmodule

2)等价非状态机写法

module pulse_comb_seq( input clk, rst_n, en, output pulse ); 
  reg en_r; 
  
always @(posedge clk or negedge rst_n) begin 
  if(!rst_n)
    en_r <= 1'b0; 
  else 
    en_r <= en; 
end 

assign pulse = en &~en_r); 

endmodule

两段代码功能上完全等价,状态机清晰直观,适合复杂控制,而直接寄存器+组合逻辑更精简,适合简单场景。

但试想,如果需求稍微变一下,不再是简单的边沿检测,而是需要在收到使能后,精确延迟3个时钟周期再输出一个脉冲,同时在此期间忽略新的使能信号。这时,用状态机(IDLE -> DELAY1 -> DELAY2 -> DELAY3 -> PULSE -> IDLE)依然清晰易懂。而若强行用非状态机方式,可能需要一个计数器加一堆使能标志位的互锁逻辑,代码的健壮性和可读性将有所下降。

综上,RTL设计的本质,在于基于对功能的理解,实现正确的电路,而并非死守某一种写法。

640.jpg

感谢阅读,更多文章点击这里:【专栏:芯想事珹】
公众号:【芯想事珹】

“芯想事珹”,先进制程IC设计与SoC定制技术交流分享平台。

最新20篇 开设专栏