有限狀態機,(英語:Finite-state machine, FSM),又稱有限狀態自動機,簡稱狀態機,是表示有限個狀態以及在這些狀態之間的轉移和動作等行為的數學模型。
有限狀態機是指輸出取決於過去輸入部分和當前輸入部分的時序邏輯電路。一般來說,除了輸入部分和輸出部分外,有限狀態機還含有一組具有“記憶”功能的寄存器,這些寄存器的功能是記憶有限狀態機的內部狀態,它們常被稱為狀態寄存器。在有限狀態機中,狀態寄存器的的下一個狀態不僅與輸入信號有關,而且還與該寄存器的當前狀態有關,因此有限狀態機又可以認為是組合邏輯和寄存器邏輯的一種組合。其中,寄存器邏輯的功能是存儲有限狀態機的內部狀態;而組合邏輯又可以分為次態邏輯和輸出邏輯兩部分,次態邏輯的功能是確定有限狀態機的下一個狀態,輸出邏輯的功能是確定有限狀態機的輸出。
以下是用FSM自由控制的led,
module led_test(clk,led_out); input clk; output reg[3:0] led_out; reg[3:0] state=4'b0000; reg[31:0] timer=32'd0; parameter state_0=4'b0000; parameter state_1=4'b0001; parameter state_2=4'b0010; parameter state_3=4'b0100; parameter state_4=4'b1000; always@(posedge clk) begin case(state) state_0: if(timer>=32'd9999_9999) begin state<=state_1; led_out<=state_1; timer<=32'd0; end else begin state<=state; led_out<=led_out; timer=timer+32'd1; end state_1: if(timer>=32'd9999_9999) begin state<=state_2; led_out<=state_2; timer<=32'd0; end else begin state<=state; led_out<=led_out; timer=timer+32'd1; end state_2: if(timer>=32'd9999_9999) begin state<=state_3; led_out<=state_3; timer<=32'd0; end else begin state<=state; led_out<=led_out; timer=timer+32'd1; end state_3: if(timer>=32'd9999_9999) begin state<=state_4; led_out<=state_4; timer<=32'd0; end else begin state<=state; led_out<=led_out; timer=timer+32'd1; end state_3: if(timer>=32'd9999_9999) begin state<=state_4; led_out<=state_4; timer<=32'd0; end else begin state<=state; led_out<=led_out; timer=timer+32'd1; end state_4: if(timer>=32'd9999_9999) begin state<=state_0; led_out<=state_0; timer<=32'd0; end else begin state<=state; led_out<=led_out; timer=timer+32'd1; end default: state<=state_0; endcase end endmodule
以下是用一個按鍵來控制LED流動的開始,當按下按鍵10s后LED會開始流動。
module practice(clk,key,led); input clk; //時鍾輸入 50Mhz input key; //按鍵 output reg[3:0] led; //4位LED reg[31:0] count=32'd0; //一個計數器,如果編譯軟件不優化,將生成32個D觸發器 reg[2:0] state=3'd0; parameter state_0=3'd0; parameter state_1=3'd1; parameter state_2=3'd2; parameter state_3=3'd3; parameter state_4=3'd4; reg[31:0] key_count; //按鍵按下的時間控制寄存器 always@(posedge clk) begin case(state) state_0: begin if(key == 1'b0) key_count <= key_count + 32'd1; else key_count <= 32'd0; if(key_count >= 32'd49_999_999) state <= state_1; else state <= state; led <= 4'b0000; end state_1: begin led <= 4'b0001; if(count == 32'd4999_9999) begin state <= state_2;//1秒后進入下一個狀態 count <= 32'd0; end else begin state <= state; count <= count + 32'd1; end end state_2: begin led <= 4'b0010; if(count == 32'd9999_9999) begin state <= state_3;//1秒后進入下一個狀態 count <= 32'd0; end else begin state <= state; count <= count + 32'd1; end end state_3: begin led <= 4'b0100; if(count == 32'd1_4999_9999) begin state <= state_4;//1秒后進入下一個狀態 count <= 32'd0; end else begin state <= state; count <= count + 32'd1; end end state_4: begin led <= 4'b1000; if(count == 32'd1_9999_9999) begin state <= state_1;//1秒后進入下一個狀態 count <= 32'd0; end else begin state <= state; count <= count + 32'd1; end end default: //最好不要忘了寫default,寫別是組合邏輯使用case,不寫會有大麻煩 state <= state_1; endcase end endmodule