【FPGA篇章四】FPGA狀態機:三段式以及書寫方法


歡迎大家關注我的微信公眾賬號,支持程序媛寫出更多優秀的文章

 

 

狀態機是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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM