verilog狀態機的三種寫法


1,單always塊結構(一段式):

always @(posedge clk ) begin

case(FSM)

st0;begin

out0;//輸出

if(case0) FSM<=st1;//狀態轉移

end

st1;begin

out1;//輸出

if(case0) FSM<=st2;//狀態轉移

end

……

default:

endcase

end

單always塊把組合邏輯和時序邏輯放在一個時序always塊描述。輸出時為寄存器輸出,所以無毛刺。但是這種方式會產生多余的觸發器(因為把組合邏輯也放在時序邏輯中實現),而且代碼難以修改調試。但對於那些簡單的狀態機,一段式還是不錯的,因為它把輸入,轉移,輸出一起體現,更方便理解。但是對於復雜狀態機就是災難了,所以最好還是養成不使用該結構的習慣。

 

雙always塊結構(兩段式):

//時序邏輯,這段一般是不變的,描述從現態轉移到次態

always @ (posedge clk) begin

current_state<=next_state;

end

 

//組合邏輯,包括轉移條件以及狀態內容(即輸出)

always @ (*) begin

case(current_state)

st0:begin

out0;

if(case0) FSM=st1; //組合邏輯使用阻塞語句

end

st1:begin

out1;

if(case1) FSM=st2;

end

……

endcase

end

二段式中,一個always塊采用同步時序描述狀態轉移;另一個采用組合邏輯判斷轉移條件,以及描述輸出。二段式便於閱讀,理解和維護,有利於綜合器優化代碼。但是由於采用的是組合邏輯輸出,容易產生毛刺,且不利於約束,也不利於綜合器和布局布線器實現高性能設計。

 

三always塊結構(三段式):

 

//第一個always塊,時序邏輯,描述現態轉移到次態

always @ (posedge clk negedge rst_n) begin

if(!rst_n)  current_state<=IDLE;

else      current_state<=next_state;

end

 

//第二個always塊,組合邏輯,描述狀態轉移的條件

always @ (current_state) begin

case(current_state)

s1:if(……) next_state=s2;//組合邏輯,采用阻塞賦值

……

endcase

end

 

//第三個always塊,時序邏輯,描述輸出

always @ (posedge clk negedge rst_n) begin

case(next_state) //這里有的是next_state,有的是current_state,需根據電路要求

s1: out1<=……;

s2: out2<=……;

default:……

endcase

end

三段式結構中,2個時序always塊分別用來描述現態邏輯轉移,及輸出賦值。組合always塊用於描述狀態轉移的條件。這種結構是寄存器輸出,輸出無毛刺,而且代碼更清晰易讀,特別是對於復雜的狀態機來說,但是消耗的面積也更多點。這是一種比較流行的狀態機結構。


免責聲明!

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



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