天天看點

Verilog實作二段式和三段式有限狀态機

有限狀态機(Finite State Machine,FSM)又稱為狀态機,為時序邏輯電路中常采用的一種形式,也是時序電路的通用模型任何時序電路,都可以表示為有限狀态機。

1、狀态機的概述

狀态機一般由寄存器群組合邏輯兩部分組成,寄存器主要是存儲狀态,而組合邏輯主要用于産生輸出和激勵信号。

狀态機,根據輸出信号是否目前的輸入信号,分為米利型(Mealy)和穆爾型(Moore)。米利型狀态機的輸出由狀态機的目前狀态和目前輸入一起決定,當輸入信号不與時鐘同步時輸出也不與時鐘同步。而穆爾型狀态機的輸出狀态隻取決于目前狀态,與目前的輸入狀态無關,輸出的改變需要等待一個時鐘周期才能展現在輸出上。

Verilog實作二段式和三段式有限狀态機
Verilog實作二段式和三段式有限狀态機

2、狀态編碼

為了适應不同的應用場景,狀态機有着不同的編碼方式,常見的編碼有:8421BCD碼,格雷碼,約翰遜碼,獨熱碼。編碼方式對比如表2-1所示:

表2-1

Verilog實作二段式和三段式有限狀态機

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 
           

測試代碼可見二段式測試代碼

仿真結果如圖:

Verilog實作二段式和三段式有限狀态機

繼續閱讀