有限狀态機(Finite State Machine,FSM)又稱為狀态機,為時序邏輯電路中常采用的一種形式,也是時序電路的通用模型任何時序電路,都可以表示為有限狀态機。
1、狀态機的概述
狀态機一般由寄存器群組合邏輯兩部分組成,寄存器主要是存儲狀态,而組合邏輯主要用于産生輸出和激勵信号。
狀态機,根據輸出信号是否目前的輸入信号,分為米利型(Mealy)和穆爾型(Moore)。米利型狀态機的輸出由狀态機的目前狀态和目前輸入一起決定,當輸入信号不與時鐘同步時輸出也不與時鐘同步。而穆爾型狀态機的輸出狀态隻取決于目前狀态,與目前的輸入狀态無關,輸出的改變需要等待一個時鐘周期才能展現在輸出上。
2、狀态編碼
為了适應不同的應用場景,狀态機有着不同的編碼方式,常見的編碼有:8421BCD碼,格雷碼,約翰遜碼,獨熱碼。編碼方式對比如表2-1所示:
表2-1
BCD碼将狀态,表示成2進制數,這種編碼方式可以減少觸發器的使用。
而格雷碼和約翰遜碼,每一個狀态隻有一位不同,可以有效減少電路噪聲。
獨熱碼每一位需要一個單獨的觸發器,可以有效地減少編碼和譯碼的組合邏輯電路大小。但對觸發器數量要求較大。
3、二段式狀态機
Verilog語言中,常常采用二段式和三段式描述狀态機。其本質是對應狀态機的激勵方程,狀态轉換方程和輸出方程。三段式每一段對應一個方程,二段式則是将輸出方程和激勵方程合并在一起描述。
二段式描述五位計數器
module counter_5 (clk,rst,Q);
input clk,rst;
output Q;
reg Q;
reg [2:0]pre_state,nex_state;
parameter s0=3'b000,s1=3'b001,s2=3'b010,s3=3'b011,s4=3'b100;
always@(posedge clk or posedge rst)
begin
if (rst==1'b1) pre_state<=s0;
else pre_state<=nex_state;
end
always@(pre_state)
begin
nex_state<=3'bxxx;
Q<=1'b0;
case (pre_state)
s0:begin nex_state<=s1;Q<=1'b0;end
s1:begin nex_state<=s2;Q<=1'b0;end
s2:begin nex_state<=s3;Q<=1'b0;end
s3:begin nex_state<=s4;Q<=1'b0;end
s4:begin nex_state<=s0;Q<=1'b1;end
default:begin nex_state<=s0;Q<=1'b0;end
endcase
end
endmodule
測試代碼:
module counter_5_t;
reg clk,rst;
wire Q;
initial
begin
clk=1'b0;
forever #10 clk=~clk;
end
initial
begin
rst=1'b0;
#10 rst=1'b1;
#10 rst=1'b0;
end
counter_5 u1(.clk(clk),.rst(rst),.Q(Q));
endmodule
3、三段式
module counter3_5 (clk,rst,Q);
input clk,rst;
output Q;
reg Q;
reg [2:0] pre_state,nex_state;
parameter s0=3'b000,s1=3'b001,s2=3'b010,s3=3'b011,s4=3'b100;
always@(posedge clk or posedge rst)
begin
if (rst==1'b1) pre_state<=s0;
else pre_state<=nex_state;
end
always@(pre_state)
begin
nex_state<=3'bxxx;
case (pre_state)
s0:nex_state<=s1;
s1:nex_state<=s2;
s2:nex_state<=s3;
s3:nex_state<=s4;
s4:nex_state<=s0;
default:nex_state<=s0;
endcase
end
always@(pre_state)
begin
Q<=1'b0;
case (pre_state)
s0:Q<=1'b0;
s1:Q<=1'b0;
s2:Q<=1'b0;
s3:Q<=1'b0;
s4:Q<=1'b1;
default:Q<=1'b0;
endcase
end
endmodule
測試代碼可見二段式測試代碼
仿真結果如圖: