“本文主要分享了在Verilog設計過程中狀態機的一些設計方法。
關于狀態機
狀態機本質是對具有邏輯順序或時序順序事件的一種描述方法,也就是說具有邏輯順序和時序規律的事情都適用狀態機描述。狀態機的基本要素有三個:狀態、輸出和輸入。
根據狀態機的輸出是否與輸入條件有關,可將狀態機分為:
摩爾(Moore)型和米里(Mealy)型。
摩爾型狀態機:輸出僅與當前狀態有關,而與輸入條件無關。
米里型狀態機:輸出不僅依賴于當前狀態,還取決于輸入條件。
狀態機的邏輯通常用“case”語句或者“if-else”語句來描述,枚舉當前狀態和輸入的所有可能組合,并為下一個狀態和輸出制定適當的值。
RTL級狀態機描述常用語法:
wire、reg;
parameter,用于描述狀態名稱,增強代碼可讀性;
always,根據主時鐘沿,完成同步時序的狀態遷移;根據信號敏感表,完成組合邏輯輸出。
case/endcase:其中default是可選的關鍵字,用于指明當所列的所有條件都不匹配時的操作;一般的FSM設計都會加上default關鍵字描述FSM所需的補集狀態。
task/endtask。
幾種狀態機的描述方法
一段式FSM描述方法:一個always塊里面,即描述狀態轉移,又描述狀態的輸入和輸出。
兩段式FSM描述方法:兩個always塊,一個采用同步時序描述狀態轉移;另一個模塊采用組合邏輯判斷狀態轉移條件,描述狀態轉移規律。
三段式FSM描述方法:第一個always模塊采用同步時序描述狀態轉移;第二個采用組合邏輯判斷狀態轉移條件,描述狀態轉移規律;第三個always模塊使用同步時序電路,描述每個狀態的輸出。
一段式:
reg [2:0] Next_State;//下一個狀態 parameter IDLE = 3‘b000; parameter S1 = 3’b001; parameter S2 = 3‘b010; parameter CLEAR = 3’b100;
//--------------------------------------------------------------------------------//------ 在一個always中包含狀態、輸入和輸出。 always@(posedge clk or posedge rst) begin if(rst) begin Next_State 《= IDLE; out 《= 2‘b00; end else begin case(Next_State) IDLE : begin if(key_in == 1’b1) begin Next_State 《= S1; out 《= 2‘b01;
end else begin Next_State 《= IDLE; out 《= 2’b00; end end S1 : begin if(key_in == 1‘b1) begin Next_State 《= S2; out 《= 2’b10; end else begin Next_State 《= S1; out 《= 2‘b01;
end end S2 : begin if(key_in == 1’b1) begin Next_State 《= CLEAR; out 《= 2‘b11; end else begin Next_State 《= S2; out 《= 2’b10; end end CLEAR : begin if(key_in == 1‘b1) begin Next_State 《= IDLE; out 《= 2’b00;
end else begin Next_State 《= CLEAR; out 《= 2‘b11; end end endcase end end
兩段式:
reg [2:0] Next_State;//下一個狀態 reg [2:0] Current_State;//當前狀態
parameter IDLE = 3’b000; parameter S1 = 3‘b001; parameter S2 = 3’b010; parameter CLEAR = 3‘b100;
//-------------------------------------------------------------------------------- always@(posedge clk or posedge rst) begin if(rst) Current_State 《= IDLE; else Current_State 《= Next_State; end always@(*)
// always@(rst or Current_State or key_in) begin case(Current_State) IDLE : begin idle_out;// out = 2’b00; if(key_in == 1‘b1) Next_State = S1; else Next_State = IDLE; end S1 : begin s1_out;// out = 2’b01; if(key_in == 1‘b1) Next_State = S2; else Next_State = S1; end S2 : begin s2_out;// out = 2’b10; if(key_in == 1‘b1) Next_State = CLEAR; else Next_State = S2; end CLEAR : begin clear_out;
// out = 2’b11; if(key_in == 1‘b1) Next_State = IDLE; else Next_State = CLEAR; end endcase end
//-------------------------------------------------------------------------------- task idle_out; out = 2’b00; endtask task s1_out; out = 2‘b01; endtask
task s2_out; out = 2’b10; endtask
task clear_out; out = 2‘b11; endtask
三段式:
//-------------------------------------------------------------------------------- reg [2:0] Next_State;//下一個狀態 reg [2:0] Current_State;//當前狀態 parameter IDLE = 3’b000; parameter S1 = 3‘b001; parameter S2 = 3’b010; parameter CLEAR = 3‘b100;
//-------------------------------------------------------------------------------- always@(posedge clk or posedge rst) begin if(rst) Current_State 《= IDLE; else Current_State 《= Next_State; end
//--------------------------------------------------------------------------------// always@(rst or Current_State or key_in) always@(*) begin case(Current_State) IDLE : begin if(key_in == 1’b1) Next_State = S1; else Next_State = IDLE; end S1 : begin if(key_in == 1‘b1) Next_State = S2; else Next_State = S1; end S2 : begin if(key_in == 1’b1) Next_State = CLEAR; else Next_State = S2; end CLEAR : begin if(key_in == 1‘b1) Next_State = IDLE; else Next_State = CLEAR; end endcase end
//-------------------------------------------------------------------------------- always@(posedge clk or posedge rst) begin if(rst) begin out 《= 2’b00; end else begin case(Next_State) IDLE : begin out 《= 2‘b00; end S1 : begin out 《= 2’b01; end S2 : begin out 《= 2‘b10; end CLEAR : begin out 《= 2’b11; end endcase end end
//--------------------------------------------------------------------------------
結論:
一段式狀態機比較適合在狀態較少的情況下使用,因為所有的狀態、輸入和輸出都在一起,可能不是很適合閱讀、理解、維護;
二段式狀態機比一段式要容易理解,但是由于輸出是組合邏輯,容易存在不穩定與毛刺隱患;
三段式狀態機比一段式更容易理解,用時序邏輯代替組合邏輯消除了不穩定與毛刺的隱患,但是代碼量會稍微多一點;
責任編輯:haq
-
Verilog
+關注
關注
28文章
1351瀏覽量
110077 -
狀態機
+關注
關注
2文章
492瀏覽量
27529
原文標題:Verilog基礎知識學習筆記(四)
文章出處:【微信號:zhuyandz,微信公眾號:FPGA之家】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論