詳細介紹FPGA狀態機的設計和應用_第1頁
詳細介紹FPGA狀態機的設計和應用_第2頁
詳細介紹FPGA狀態機的設計和應用_第3頁
詳細介紹FPGA狀態機的設計和應用_第4頁
詳細介紹FPGA狀態機的設計和應用_第5頁
已閱讀5頁,還剩7頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

詳細介紹FPGA狀態機的設計和應用FPGA的特點是并行執行,但如果需要處理一些具有前后順序的事件,就需要使用狀態機。狀態機是一種用于處理具有前后順序的事件的計算機模型,包含現態、條件、動作和次態四個要素,它可以將一個復雜的控制流程分解成多個互相獨立的狀態,從而簡化設計過程并提高了系統的可靠性和性能。本文將對FPGA狀態機進行詳細介紹,幫助大家了解狀態機的設計和應用。一、FPGA狀態機基礎1、基礎概念FPGA狀態機是一種能夠描述對象在運行周期內的所有狀態,以及從一個狀態到另一個狀態轉換的過程的抽象模型。狀態機可歸納為4個要素,即現態、條件、動作、次態。①現態:當前所處的狀態。②條件:當一個條件被滿足,將會觸發一個動作,或者執行一次運行狀態的變化。③動作:條件滿足后執行的動作。動作不是必需的,也可以直接遷移到新狀態而不進行任何動作。④次態:條件滿足后要跳轉到的新狀態。其中,“次態”是相對于“現態”而言的,一旦被跳轉后,“次態”就轉變成新的“現態”了。2、狀態機分類通常情況下,FPGA狀態機一般有兩種類型:Moore型狀態機:下一狀態只由當前狀態決定。Mealy型狀態機:下一狀態不但與當前狀態有關,還與當前輸入值有關。由于Mealy型狀態機的輸出與輸入有關,輸出信號很容易出現毛刺,所以一般采用Moore型狀態機。(1)Mealy狀態機輸出邏輯不但取決于當前“狀態”還取決于“輸入”,如圖所示。(2)Moore狀態機輸出邏輯僅僅取決于當前狀態,且與當前時刻的輸入無關,如圖所示。二、FPGA狀態機實現方式FPGA狀態機的描述方式主要分為3種,分別是一段式、兩段式、三段式。1、一段式狀態機一段式狀態機使用1個always塊,把狀態跳轉和寄存器輸出邏輯都寫在一起,其輸出是寄存器輸出,無毛刺,但是這種方式代碼較混亂,邏輯不清晰,難于修改和調試,應該盡量避免使用。下面給出一個一段式的Mealy狀態機示例:moduleone_state_machine(

inputclk,

inputrst_n,

input[1:0]inp,

outputregoutp

);

//定義狀態

localparamSTATE_0=0,

STATE_1=1,

STATE_2=2,

STATE_3=3;

//定義狀態寄存器和初始狀態

reg[1:0]state_r;

//初始化狀態寄存器

always@(posedgeclkornegedgerst_n)begin

if(~rst_n)begin

state_r<=STATE_0;

endelsebegin

case(state_reg)

STATE_0:begin

if(inp==2'b00)begin

state_r<=STATE_0;

outp<=0;

endelseif(inp==2'b01)begin

state_r<=STATE_1;

outp<=1;

endelseif(inp==2'b10)begin

state_r<=STATE_2;

outp<=0;

endelsebegin

state_r<=STATE_3;

outp<=1;

end

end

STATE_1:begin

if(inp==2'b00)begin

state_r<=STATE_1;

outp<=1;

endelseif(inp==2'b01)begin

state_r<=STATE_2;

outp<=0;

endelseif(inp==2'b10)begin

state_r<=STATE_3;

outp<=1;

endelsebegin

state_r<=STATE_0;

outp<=0;

end

end

STATE_2:begin

if(inp==2'b00)begin

state_r<=STATE_2;

outp<=0;

endelseif(inp==2'b01)begin

state_r<=STATE_3;

outp<=1;

endelseif(inp==2'b10)begin

state_r<=STATE_0;

outp<=0;

endelsebegin

state_r<=STATE_1;

outp<=1;

end

end

STATE_3:begin

if(inp==2'b00)begin

state_r<=STATE_3;

outp<=1;

endelseif(inp==2'b01)begin

state_r<=STATE_0;

outp<=0;

endelseif(inp==2'b10)begin

state_r<=STATE_1;

outp<=1;

endelsebegin

state_reg<=STATE_2;

outp<=0;

end

end

endcase

end

end

endmodule2、二段式狀態機二段式狀態機使用2個always塊,都是時序邏輯,其中一個always塊用于寫狀態機的狀態跳轉邏輯,另一個always塊用于寫當前狀態下的寄存器輸出邏輯。這種方式邏輯代碼清晰,易于調試和理解,是比較推薦的一個方式。下面給出一個二段式的Moore狀態機示例:modulestate_machine(

inputclk,

inputrst_n,

outputregout_reg

);

//狀態寄存器和下一個狀態寄存器

reg[1:0]state_r;

//狀態定義

parameterIDLE=2'b00;

parameterSTATE1=2'b01;

parameterSTATE2=2'b10;

parameterSTATE3=2'b11;

//always@(posedgeclkornegedgerst_n)時序邏輯代碼塊,實現狀態跳轉邏輯

always@(posedgeclkornegedgerst_n)begin

if(~rst_n)begin

state_r<=IDLE;

endelsebegin

case(state_r)

IDLE:begin

state_r<=STATE1;

end

STATE1:begin

state_r<=STATE2;

end

STATE2:begin

state_r<=STATE3;

end

STATE3:begin

state_r<=IDLE;

end

endcase

end

end

//always@(*)時序邏輯代碼塊,實現狀態輸出邏輯

always@(posedgeclkornegedgerst_n)begin

if(~rst_n)begin

out_reg<=1'b0;

endelsebegin

case(state_r)

IDLE:begin

out_reg<=1'b0;

end

STATE1:begin

out_reg<=1'b1;

end

STATE2:begin

out_reg<=1'b1;

end

STATE3:begin

out_reg<=1'b0;

end

endcase

end

end

endmodule3、三段式狀態機三段式狀態機使用3個always塊,其中一個組合always塊用于寫狀態機的狀態跳轉邏輯,一個時序always塊用于緩存狀態寄存器,另一個always塊用于寫當前狀態下的寄存器輸出邏輯。這種方式邏輯代碼清晰,易于調試和理解,也是比較推薦的一個方式。modulestate_machine(

inputclk,

inputrst_n,

input[1:0]inp,

outputregoutp

);

//定義狀態

localparamSTATE_0=0,

STATE_1=1,

STATE_2=2,

STATE_3=3;

//定義狀態寄存器和初始狀態

reg[1:0]state_r,next_state;

//定義狀態寄存器

always@(posedgeclkornegedgerst_n)begin

if(~rst_n)begin

state_r<=STATE_0;

endelsebegin

state_r<=next_state;

end

end

//定義狀態轉移邏輯

always@(*)begin

case(state_r)

STATE_0:begin

if(inp==2'b00)begin

next_state=STATE_0;

endelseif(inp==2'b01)begin

next_state=STATE_1;

endelseif(inp==2'b10)begin

next_state=STATE_2;

endelsebegin

next_state=STATE_3;

end

end

STATE_1:begin

if(inp==2'b00)begin

next_state=STATE_1;

endelseif(inp==2'b01)begin

next_state=STATE_2;

endelseif(inp==2'b10)begin

next_state=STATE_3;

endelsebegin

next_state=STATE_0;

end

end

STATE_2:begin

if(inp==2'b00)begin

next_state=STATE_2;

endelseif(inp==2'b01)begin

next_state=STATE_3;

endelseif(inp==2'b10)begin

next_state=STATE_0;

endelsebegin

next_state=STATE_1;

end

end

STATE_3:begin

if(inp==2'b00)begin

next_state=STATE_3;

endelseif(inp==2'b01)begin

next_state=STATE_0;

endelseif(inp==2'b10)begin

next_state=STATE_1;

endelsebegin

next_state=STATE_2;

end

end

endcase

end

//定義輸出邏輯

always@(*)begin

case(state_r)

STATE_0:outp=0;

STATE_1:outp=1;

STATE_2:outp=0;

STATE_3:outp=1;

endcase

end

endmodule注意:組合邏輯代碼中,if語句和case語句必須寫滿,否則容易形成latch,導致實際運行出問題。三、狀態機的編碼方式1、獨熱碼獨熱碼(One-hot)是一種狀態編碼方式,其特點是對于任意給定的狀態,狀態寄存器中只有1位為1,其余位都為0。使用獨熱碼可以簡化譯碼邏輯電路,因為狀態機只需對寄存器中的一位進行譯碼,同時可用省下的面積抵消額外觸發器占用的面積。相比于其他類型的有限狀態機,加入更多的狀態時,獨熱碼的譯碼邏輯并不會變得更加復雜,速度僅取決于到某特定狀態的轉移數量。此外,獨熱碼還具有諸如設計簡單、修改靈活、易于綜合和調試等優點。但值得注意的是,相對于二進制碼,獨熱碼速度更快但占用面積較大。modulestate_machine(

inputclk,

outputreg[3:0]state_out

);

localparamSTATE_A=4'b0001;

localparamSTATE_B=4'b0010;

localparamSTATE_C=4'b0100;

localparamSTATE_D=4'b1000;

reg[3:0]current_state,next_state;

always@(posedgeclk)begin

current_state<=next_state;//當時鐘上升沿到來時更新狀態

end

always@(*)begin

case(current_state)

STATE_A:next_state=STATE_B;

STATE_B:next_state=STATE_C;

STATE_C:next_state=STATE_D;

STATE_D:next_state=STATE_A;

default:next_state=STATE_A;//默認情況下返回初始狀態

endcase

end

assignstate_out=current_state;//將當前狀態作為輸出

endmodule2、格雷碼格雷碼是一種相鄰的兩個碼組之間僅有一位不同的編碼方式。在格雷碼中,相鄰的兩個碼組之間僅有一位不同,這種編碼方式可以用于實現相鄰的兩個狀態之間只有一位不同的狀態機;FPGA中的狀態機通常需要高速運行,因此使用格雷碼可以減少狀態轉換的開銷,并提高時序性能。modulegray_code_state_machine(

inputclk,

outputreg[3:0]state_out

);

localparamG0=4'b0000;

localparamG1=4'b0001;

localparamG2=4'b0011;

localparamG3=4'b0010;

reg[3:0]current_state,next_state;

always@(posedgeclk)begin

current_state<=next_state;//當時鐘上升沿到來時更新狀態

end

always@(*)begin

case(current_state)

G0:next_state=G1;

G1:next_state=G3;

G2:next_state=G0;

G3:next_state=G2;

default:next_state=G0;//默認情況下返回初始狀態

endcase

end

assignstate_out=current_state;//將當前狀態作為輸出

endmodule3、普通二進制碼FPGA狀態機可以用普通二進制碼表示,不同狀態按照二進制數累加表示,是常用的一種方式,仿真調試時,狀態顯示清晰,易于理解代碼。modulebinary_state_machine(

inputclk,

outputreg[1:0]state_out

);

localparamSTATE_A=2'b00;

localparamSTATE_B=2'b01;

localparamSTATE_C=2'b10;

reg[1:0]current_state,next_state;

always@(posedgeclk)begin

current_state<=next_state;//當時鐘上升沿到來時更新狀態

end

always@(*)begin

case(current_state)

STATE_A:next_state=STATE_B;

STATE_B:next_state=STATE_C;

STATE_C:next_state=STATE_A;

default:next_state=STATE_A;//默認情況下返回初始狀態

endcase

end

assignstate_out=current_state;//將當前狀態作為輸出

endmodule4、格雷

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論