FPGA 高手養(yǎng)成記-淺談狀態(tài)機(jī)
掃描二維碼
隨時(shí)隨地手機(jī)看文章
本文目錄
-
前言
-
狀態(tài)機(jī)簡介
-
狀態(tài)機(jī)分類
Mealy 型狀態(tài)機(jī)
Moore 型狀態(tài)機(jī) -
狀態(tài)機(jī)描述
一段式狀態(tài)機(jī)
二段式狀態(tài)機(jī)
三段式狀態(tài)機(jī) -
狀態(tài)機(jī)優(yōu)缺點(diǎn)
-
總結(jié)
-
擴(kuò)展-四段式狀態(tài)機(jī)
01. 前言
狀態(tài)機(jī)是FPGA設(shè)計(jì)中一種非常重要、非常根基的設(shè)計(jì)思想,堪稱FPGA的靈魂,貫穿FPGA設(shè)計(jì)的始終。
02. 狀態(tài)機(jī)簡介
什么是狀態(tài)機(jī):狀態(tài)機(jī)通過不同的狀態(tài)遷移來完成特定的邏輯操作(時(shí)序操作)狀態(tài)機(jī)是許多數(shù)字系統(tǒng)的核心部件, 是一類重要的時(shí)序邏輯電路。通常包括三個(gè)部分:
下一個(gè)狀態(tài)的邏輯電路
存儲狀態(tài)機(jī)當(dāng)前狀態(tài)的時(shí)序邏輯電路
輸出組合邏輯電路
03. 狀態(tài)機(jī)分類
通常, 狀態(tài)機(jī)的狀態(tài)數(shù)量有限, 稱為有限狀態(tài)機(jī)(FSM) 。由于狀態(tài)機(jī)所有觸發(fā)器的時(shí)鐘由同一脈沖邊沿觸發(fā), 故也稱之為同步狀態(tài)機(jī)。
根據(jù)狀態(tài)機(jī)的輸出信號是否與電路的輸入有關(guān)分為 Mealy 型狀態(tài)機(jī)和 Moore 型狀態(tài)機(jī)
3.1,Mealy 型狀態(tài)機(jī)
電路的輸出信號不僅與電路當(dāng)前狀態(tài)有關(guān), 還與電路的輸入有關(guān)
3.2,Moore 型狀態(tài)機(jī)
電路的輸出僅僅與各觸發(fā)器的狀態(tài), 不受電路輸入信號影響或無輸入
狀態(tài)機(jī)的狀態(tài)轉(zhuǎn)移圖, 通常也可根據(jù)輸入和內(nèi)部條件畫出。一般來說, 狀態(tài)機(jī)的設(shè)計(jì)包含下列設(shè)計(jì)步驟:
-
根據(jù)需求和設(shè)計(jì)原則, 確定是 Moore 型還是 Mealy 型狀態(tài)機(jī);
-
分析狀態(tài)機(jī)的所有狀態(tài), 對每一狀態(tài)選擇合適的編碼方式, 進(jìn)行編碼;
-
根據(jù)狀態(tài)轉(zhuǎn)移關(guān)系和輸出繪出狀態(tài)轉(zhuǎn)移圖;
-
構(gòu)建合適的狀態(tài)機(jī)結(jié)構(gòu), 對狀態(tài)機(jī)進(jìn)行硬件描述。
04. 狀態(tài)機(jī)描述
狀態(tài)機(jī)的描述通常有三種方法, 稱為一段式狀態(tài)機(jī), 二段式狀態(tài)機(jī)和三段式狀態(tài)機(jī)。
狀態(tài)機(jī)的描述通常包含以下四部分:
-
利用參數(shù)定義語句 parameter 描述狀態(tài)機(jī)各個(gè)狀態(tài)名稱, 即狀態(tài)編碼。狀態(tài)編碼通常有很多方法包含自然二進(jìn)制編碼, One-hot 編碼,格雷編碼碼等;
-
用時(shí)序的 always 塊描述狀態(tài)觸發(fā)器實(shí)現(xiàn)狀態(tài)存儲;
-
使用敏感表和 case 語句(也采用 if-else 等價(jià)語句) 描述狀態(tài)轉(zhuǎn)換邏輯;
-
描述狀態(tài)機(jī)的輸出邏輯。
下面根據(jù)狀態(tài)機(jī)的三種方法來具體說明
4.1,一段式狀態(tài)機(jī)
1module detect_1( 2input clk_i, 3input rst_n_i, 4output out_o 5); 6reg out_r; 7//狀態(tài)聲明和狀態(tài)編碼 8reg [1:0] state; 9parameter [1:0] S0=2'b00; 10parameter [1:0] S1=2'b01; 11parameter [1:0] S2=2'b10; 12parameter [1:0] S3=2'b11; 13always@(posedge clk_i) 14begin 15 if(!rst_n_i)begin 16 state<=0; 17 out_r<=1'b0; 18 end 19 else 20 case(state) 21 S0 : 22 begin 23 out_r<=1'b0; 24 state<= S1; 25 end 26 S1 : 27 begin 28 out_r<=1'b1; 29 state<= S2; 30 end 31 S2 : 32 begin 33 out_r<=1'b0; 34 state<= S3; 35 end 36 S3 : 37 begin 38 out_r<=1'b1; 39 end 40 endcase 41end 42assign out_o=out_r; 43endmodul 44
一段式狀態(tài)機(jī)是應(yīng)該避免使用的, 該寫法僅僅適用于非常簡單的狀態(tài)機(jī)設(shè)計(jì)。
4.2,兩段式狀態(tài)機(jī)
1module detect_2( 2 input clk_i, 3 input rst_n_i, 4 output out_o 5 ); 6 reg out_r; 7 //狀態(tài)聲明和狀態(tài)編碼 8 reg [1:0] Current_state; 9 reg [1:0] Next_state; 10 parameter [1:0] S0=2'b00; 11 parameter [1:0] S1=2'b01; 12 parameter [1:0] S2=2'b10; 13 parameter [1:0] S3=2'b11; 14 //時(shí)序邏輯: 描述狀態(tài)轉(zhuǎn)換 15 always@(posedge clk_i) 16 begin 17 if(!rst_n_i) 18 Current_state<=0; 19 else 20 Current_state<=Next_state; 21 end 22 //組合邏輯:描述下一狀態(tài)和輸出 23 always@(*) 24 begin 25 out_r=1'b0; 26 case(Current_state) 27 S0 : 28 begin 29 out_r=1'b0; 30 Next_state= S1; 31 end 32 S1 : 33 begin 34 out_r=1'b1; 35 Next_state= S2; 36 end 37 S2 : 38 begin 39 out_r=1'b0; 40 Next_state= S3; 41 end 42 S3 : 43 begin 44 out_r=1'b1; 45 Next_state=Next_state; 46 end 47 endcase 48 end 49 assign out_o = out_r; 50endmodule 51
兩段式狀態(tài)機(jī)采用兩個(gè) always 模塊實(shí)現(xiàn)狀態(tài)機(jī)的功能, 其中一個(gè) always 采用同步時(shí)序邏輯描述狀態(tài)轉(zhuǎn)移, 另一個(gè) always 采用組合邏輯來判斷狀態(tài)條件轉(zhuǎn)移。
4.3,三段式狀態(tài)機(jī)
1module detect_3( 2 input clk_i, 3 input rst_n_i, 4 output out_o 5 ); 6 reg out_r; 7 //狀態(tài)聲明和狀態(tài)編碼 8 reg [1:0] Current_state; 9 reg [1:0] Next_state; 10 parameter [1:0] S0=2'b00; 11 parameter [1:0] S1=2'b01; 12 parameter [1:0] S2=2'b10; 13 parameter [1:0] S3=2'b11; 14 //時(shí)序邏輯: 描述狀態(tài)轉(zhuǎn)換 15 always@(posedge clk_i) 16 begin 17 if(!rst_n_i) 18 Current_state<=0; 19 else 20 Current_state<=Next_state; 21 end 22 //組合邏輯: 描述下一狀態(tài) 23 always@(*) 24 begin 25 case(Current_state) 26 S0: 27 Next_state = S1; 28 S1: 29 Next_state = S2; 30 S2: 31 Next_state = S3; 32 S3: 33 begin 34 Next_state = Next_state; 35 end 36 default : 37 Next_state = S0; 38 endcase 39 end 40 //輸出邏輯: 讓輸出 out, 經(jīng)過寄存器 out_r 鎖存后輸出, 消除毛刺 41 always@(posedge clk_i) 42 begin 43 if(!rst_n_i) 44 out_r<=1'b0; 45 else 46 begin 47 case(Current_state) 48 S0,S2: 49 out_r<=1'b0; 50 S1,S3: 51 out_r<=1'b1; 52 default : 53 out_r<=out_r; 54 endcase 55 end 56 end 57 58 assign out_o=out_r; 59endmodule 60
三段式狀態(tài)機(jī)在第一個(gè) always 模塊采用同步時(shí)序邏輯方式描述狀態(tài)轉(zhuǎn)移, 第二個(gè)always 模塊采用組合邏輯方式描述狀態(tài)轉(zhuǎn)移規(guī)律, 第三個(gè) always 描述電路的輸出。通常讓輸出信號經(jīng)過寄存器緩存之后再輸出, 消除電路毛刺。
05. 狀態(tài)機(jī)優(yōu)缺點(diǎn)
1、一段式狀態(tài)機(jī)
只涉及時(shí)序電路,沒有競爭與冒險(xiǎn),同時(shí)消耗邏輯比較少。
但是如果狀態(tài)非常多,一段式狀態(tài)機(jī)顯得比較臃腫,不利于維護(hù)。
2、兩段式狀態(tài)機(jī)
當(dāng)一個(gè)模塊采用時(shí)序(狀態(tài)轉(zhuǎn)移),一個(gè)模塊采用組合時(shí)候(狀態(tài)機(jī)輸出),組合邏輯電路容易造成競爭與冒險(xiǎn);當(dāng)兩個(gè)模塊都采用時(shí)序,可以避免競爭與冒險(xiǎn)的存在,但是整個(gè)狀態(tài)機(jī)的時(shí)序上會延時(shí)一個(gè)周期。
兩段式狀態(tài)機(jī)是推薦的狀態(tài)機(jī)設(shè)計(jì)方法。
3、三段式狀態(tài)機(jī)
三段式狀態(tài)機(jī)在狀態(tài)轉(zhuǎn)移時(shí)采用組合邏輯電路+格雷碼,避免了組合邏輯的競爭與冒險(xiǎn);狀態(tài)機(jī)輸出采用了同步寄存器輸出,也可以避免組合邏輯電路的競爭與冒險(xiǎn);采用這兩種方法極大的降低了競爭冒險(xiǎn)。并且在狀態(tài)機(jī)的采用這種組合邏輯電路+次態(tài)寄存器輸出,避免了兩段式狀態(tài)機(jī)的延時(shí)一個(gè)周期(三段式狀態(tài)機(jī)在上一狀態(tài)中根據(jù)輸入條件判斷當(dāng)前狀態(tài)的輸出,從而在不插入額外時(shí)鐘節(jié)拍的前提下,實(shí)現(xiàn)寄存器的輸出)。
三段式狀態(tài)機(jī)也是比較推崇的,主要是由于維護(hù)方便, 組合邏輯與時(shí)序邏輯完全獨(dú)立。
06. 總結(jié)
靈活選擇狀態(tài)機(jī),不一定要拘泥理論,怎樣方便怎樣來
07.擴(kuò)展
四段式不是指三個(gè)always代碼,而是四段程序。使用四段式的寫法,可參照明德?lián)PGVIM特色指令Ztj產(chǎn)生的狀態(tài)機(jī)模板。
明·德·揚(yáng)四段式狀態(tài)機(jī)符合一次只考慮一個(gè)因素的設(shè)計(jì)理念。
-
第一段代碼,照抄格式,完全不用想其他的。
-
第二段代碼,只考慮狀態(tài)之間的跳轉(zhuǎn),也就是說各個(gè)狀態(tài)機(jī)之間跳轉(zhuǎn)關(guān)系。
-
第三段代碼,只考慮跳轉(zhuǎn)條件。
-
第四段,每個(gè)信號逐個(gè)設(shè)計(jì)。





