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