FPGA状态机设计详解:从Moore到Mealy的完整指南
前言
有限状态机(FSM)是FPGA数字逻辑设计中最为核心的设计方法之一。无论是简单的流水灯控制,还是复杂的通信协议解析,状态机都扮演着不可或缺的角色。
Moore状态机与Mealy状态机
Moore状态机
Moore状态机的输出仅取决于当前状态,与输入信号无关。其结构清晰,时序容易控制。
verilog
module fsm_moore(
input wire clk,
input wire rst_n,
input wire din,
output reg dout
);
localparam S0 = 2'b00;
localparam S1 = 2'b01;
localparam S2 = 2'b10;
localparam S3 = 2'b11;
reg [1:0] current_state, next_state;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) current_state <= S0;
else current_state <= next_state;
end
always @(*) begin
case (current_state)
S0: next_state = din ? S1 : S0;
S1: next_state = din ? S2 : S1;
S2: next_state = din ? S3 : S2;
S3: next_state = din ? S0 : S3;
default: next_state = S0;
endcase
end
always @(*) begin
case (current_state)
S3: dout = 1'b1;
default: dout = 1'b0;
endcase
end
endmodule
Mealy状态机
Mealy状态机的输出同时取决于当前状态和输入信号,响应速度更快。
verilog
module fsm_mealy(
input wire clk,
input wire rst_n,
input wire din,
output reg dout
);
localparam S0 = 2'b00;
localparam S1 = 2'b01;
localparam S2 = 2'b10;
reg [1:0] current_state, next_state;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) current_state <= S0;
else current_state <= next_state;
end
always @(*) begin
dout = 1'b0;
next_state = current_state;
case (current_state)
S0: if (din) begin next_state = S1; dout = 1'b1; end
S1: if (din) next_state = S2; else next_state = S0;
S2: if (!din) begin next_state = S0; dout = 1'b1; end
default: next_state = S0;
endcase
end
endmodule
三段式状态机推荐写法
- 第一段:时序逻辑,描述状态寄存器跳转
- 第二段:组合逻辑,描述下一状态产生条件
- 第三段:时序或组合逻辑,描述输出
状态机编码方式
- 二进制编码:使用最少触发器,适合资源敏感设计
- 独热码:每个状态一个触发器,译码简单,适合高速设计
- 格雷码:相邻状态仅一位变化,适合低功耗设计
总结
状态机是FPGA设计中最基础也最重要的设计方法之一。掌握Moore和Mealy的区别,熟练运用三段式写法,能够帮助开发者设计出更加可靠高效的FPGA电路。
需要系统学习FPGA的朋友,这里有一份整理的FPGA汇总课程资料,包含BD教程、Vivado教程、IP核教程等:
链接: https://pan.baidu.com/s/1pIFS8GEYu_jH1np4ZLG2Kw?pwd=wbbw 提取码: wbbw
整理不易,尽快保存