今天我們來寫狀態機。 關于狀態機呢,想必大家應該都接觸過,通俗的講就是數電里我們學的狀態轉換圖。狀態機分為兩中類型,一種叫Mealy型,一種叫Moore型。前者就是說時序邏輯的輸出不僅取決于當前的狀態,還取決于輸入,而后者就是時序邏輯的輸出僅僅取決于當前的狀態。下面兩個圖分別表示兩種不同的狀態機。 下面我們就通過代碼來寫一下狀態機,以下面的狀態轉換圖為例 首先,是一種典型的狀態機寫法,這種寫法我們稱為一段時狀態機,用于一些簡單的設計是可以的,但如果是復雜的狀態機,不建議大家用這種寫法。 //*********************************************************** //可綜合的狀態機設計的典型方法 //實現典型的狀態機設計 //********************************************** module fsm (clk,rst_n,A,k1,k2,State); input clk; input rst_n; input A; output k1,k2; output [1:0] State; reg k1; reg k2; reg [1:0] State; //當前狀態寄存器 parameter Idle = 2'b00, Start = 2'b01, Stop = 2'b10, Clear = 2'b11; //編碼 ,注意,只有在最后一句用分號,其他地方用逗號 always @(posedge clk or negedge rst_n) if(!rst_n) begin State 狀態機 //*********************************************************** //由輸出指定的碼表示狀態的狀態機 //小墨同學于2014年5月21日在金翰林宿舍作 //用于高速狀態機的設計 //********************************************** module fsm2(clk,rst_n,A,k1,k2,State); input clk; input rst_n; input A; output k1,k2; output [4:0] State; reg [4:0] State; //當前狀態寄存器 assign k1 =State[0]; assign k2 =State[4]; parameter Idle = 5'b00000, //采用毒熱編碼(每個狀態只有一個寄存器置位的狀態機這樣用的組合電路省一些,而且速度也快) Start = 5'b00010, Stop = 5'b00100, StoptoClear = 5'b11000, Clear = 5'b01010, CleartoIdle = 5'b00111; //編碼 ,注意,只有在最后一句用分號,其他地方用逗號 always @(posedge clk or negedge rst_n) if(!rst_n) State <= Idle; else case (State) //狀態判斷與組合邏輯賦值 Idle :if(A) State <= Start; else State <= Idle; Start :if(!A) State <= Stop; else State <= Start; Stop :if(A) State <=StoptoClear; else State <= Stop; StoptoClear :State <= Stop; Clear :if(!A) State <= Clear; else State <= Clear; CleartoIdle :State <= Idle; default : State <= Idle;//告訴綜合器 case語句已經指定了所有狀態,這樣綜合器就會刪除不需要的譯碼電路,使生成的電路簡單 endcase endmodule //************************************************** 這樣寫就是把狀態碼的指定與狀態機控制的輸出聯系起來,把狀態的變化直接作用于輸出,這樣做可以提高輸出信號的開關素的并節省電路器件。但這種方法也有缺點,就是快關的維持時間必須與狀態維持的時間一致,這種設計方法常用在告訴狀態機中。 下面這種寫法應該是以后我們經常要用到的,即三段式狀態機寫法,比較適合于多輸出的狀態機設計。 //*********************************************************** //*************************************************** //多輸出狀態時的狀態機 //用于多輸出時的狀態機設計,也即三段式狀態機的常見寫法,推薦! //********************************************* module fsm3 (clk,rst_n,A,k1,k2,state); input clk,rst_n,A; output k1,k2; output [1:0] state; reg k1,k2; reg [1:0] state; reg [1:0] xiaomo; parameter Idle = 2'b00, start = 2'b01, stop = 2'b10, clear = 2'b11; always @ (posedge clk or negedge rst_n) if(!rst_n) state <= Idle; else state <= xiaomo; //每一個時鐘產生一個可能的變化,即時序邏輯部分 always @ (state or A) //組合邏輯部分 begin case (state) Idle : if(A) xiaomo = start; else iaomo = Idle; start : if(!A)xiaomo = stop; else iaomo = start; stop : if(A)xiaomo = clear; else iaomo = stop; clear : if(!A) xiaomo =Idle; else iaomo = clear; default : xiaomo = 2'bxx; endcase end always @ (state or A or rst_n) //產生輸出k1的組合邏輯 if(!rst_n) k1=0; else if(state ==clear && !A) k1=1; else k1=0; always @(state or A or rst_n) //產生輸出k2的組合邏輯 if(!rst_n) k2=0; else if(state ==stop && A) k2=1; else k2=0; endmodule //************************************************** |