歡迎大家關注我的微信公眾賬號,支持程序媛寫出更多優秀的文章
狀態機是fpga設計中極其重要的一種技巧,狀態機通過不同的狀態遷移來完成特定的邏輯操作,掌握狀態機的寫法可以使fpga的開發事半功倍。
狀態機的分類
Moore型狀態機:狀態機的變化只與當前的狀態有關
Mealy型狀態機:狀態機的變化不僅與當前的狀態有關,還與輸入有關
如何創建狀態機
狀態機的創建可以分為一段式,兩段式和三段式
一段式:主要是講所有的狀態變化以及導致的輸出變化都寫在了一個always模塊中。
兩段式:一個always模塊采用同步時序描述狀態轉移;另一個always模塊采用組合邏輯判斷狀態轉移條件,描述狀態轉移規律以及輸出。
三段式:一個always模塊采用同步時序描述狀態轉移;一個always模塊采用組合邏輯判斷狀態轉移條件,描述狀態轉移規律;另一個always模塊描述狀態輸出(可以用組合電路輸出,也可以時序電路輸出)。
舉個例子:從循環輸入的字母中做連續檢測,當連續檢測到“hello”時,將led燈進行狀態的翻轉,繼續進行下一次的檢測。
一段式的編寫方式:
1 module hello( 2 input clk,//系統時鍾信號 50mHz 3 input rst_n,//系統復位信號,低電平有效 4 input [7:0] data,//連續輸入的字母 5 output reg led//led燈 6 ); 7 8 //設置需要改變的狀態 9 parameter checkh = 5'b0000_1, 10 checke = 5'b0001_0, 11 checkla = 5'b0010_0, 12 checklb = 5'b0100_0, 13 checko = 5'b1000_0; 14 15 reg [4:0]state; 16 17 always @(posedge clk or negedge rst_n) 18 if(!rst_n) 19 begin 20 led <= 1'b0; 21 state <= checkh; 22 end 23 else 24 begin 25 case (state) 26 checkh: 27 if(data == "h") state <= checke; 28 else state <= checkh; 29 checke: 30 if(data == "e") state <= checkla; 31 else state <= checkh; 32 checkla: 33 if(data == "l") state <= checklb; 34 else state <= checkh; 35 checklb: 36 if(data == "l") state <= checko; 37 else state <= checkh; 38 checko: 39 if(data == "o") 40 begin 41 led <= ~led; 42 state <= checkh; 43 end 44 else state <= checkh; 45 default:state <= checkh; 46 endcase 47 end 48 49 endmodule
二段式的編寫方式:
1 module hello( 2 input clk, 3 input rst_n, 4 input [7:0] data, 5 output reg led 6 ); 7 8 parameter checkh = 5'b0000_1, 9 checke = 5'b0001_0, 10 checkla = 5'b0010_0, 11 checklb = 5'b0100_0, 12 checko = 5'b1000_0; 13 14 reg [4:0] cstate; // 當前狀態 15 reg [4:0] nstate; // 下一狀態 16 17 always @(posedge clk or negedge rst_n) 18 if(!rst_n) 19 cstate <= checkh; 20 else 21 cstate <= nstate; 22 23 always @(cstate or data) 24 case (cstate) 25 checkh: 26 if(data == "h") nstate <= checke; 27 else nstate <= checkh; 28 checke: 29 if(data == "e") nstate <= checkla; 30 else nstate <= checkh; 31 checkla: 32 if(data == "l") nstate <= checklb; 33 else nstate <= checkh; 34 checklb: 35 if(data == "l") nstate <= checko; 36 else nstate <= checkh; 37 checko: 38 if(data == "o") 39 begin 40 led <= ~led; 41 nstate <= checkh; 42 end 43 else nstate <= checkh; 44 default:nstate <= checkh; 45 endcase 46 47 endmodule
三段式的編寫方式:
1 module hello( 2 input clk, 3 input rst_n, 4 input [7:0] data, 5 output reg led 6 ); 7 8 parameter checkh = 5'b0000_1, 9 checke = 5'b0001_0, 10 checkla = 5'b0010_0, 11 checklb = 5'b0100_0, 12 checko = 5'b1000_0; 13 14 reg [4:0] cstate; // 當前狀態 15 reg [4:0] nstate; // 下一狀態 16 17 //復位信號,clk的處理(主要是對初始狀態進行賦值操作) 18 always @(posedge clk or negedge rst_n) 19 if(!rst_n) 20 cstate <= checkh; 21 else 22 cstate <= nstate; 23 24 //狀態遷移的處理 25 always @(cstate or data) 26 case (cstate) 27 checkh: 28 if(data == "h") nstate <= checke; 29 else nstate <= checkh; 30 checke: 31 if(data == "e") nstate <= checkla; 32 else nstate <= checkh; 33 checkla: 34 if(data == "l") nstate <= checklb; 35 else nstate <= checkh; 36 checklb: 37 if(data == "l") nstate <= checko; 38 else nstate <= checkh; 39 checko: 40 if(data == "o") 41 begin 42 nstate <= checkh; 43 end 44 else nstate <= checkh; 45 default:nstate <= checkh; 46 endcase 47 48 //輸出數據的處理 49 always @(posedge clk or negedge rst_n) 50 if(!rst_n) 51 led <= 1'b1; 52 53 else 54 case (cstate) 55 checko: 56 if(data == "o") 57 led <= ~led; 58 default; 59 endcase 60 61 endmodule