三種狀態機——分析、對比和小結

 

 

本文簡化所有邏輯重點講解狀態機的框架。

先給幾點小結:

小結1.在原理圖和實際變現上來說,一段式和三段式完全一致,但在代碼量大的情況下三段式代碼更容易維護。

小結2.二段式的輸出由組合邏輯驅動,不僅可能輸出毛刺,而且不利於時許約束、分析。

小結3.狀態機有着流水線的“缺點”:上電之初若不全面指定初始狀態,則可能有若干個時鐘的無效輸出。

 

狀態機一般有3個基本組成要素:

要素1.新狀態

要素2.當前狀態

要素3.輸出

 

當每個clk到來,要完成3個任務:

任務1.將“新狀態”賦給“當前狀態”

任務2.產生下一個“新狀態”(可能包含組合邏輯)

任務3.根據“當前狀態”產生輸出(可能包含組合邏輯)

 

以下分別給出三種狀態機的框架代碼、原理圖、仿真激勵代碼和仿真波形圖

 

一段式:

形式上,丟掉“新狀態”這個媒介,直接把新狀態的值賦給“當前狀態”,故沒有任務2。

形式上,在一個觸發器裏完成任務1、3,但實際上這需要2個觸發器,因爲1個觸發器只有一組輸出/輸入。

module one_state_machine(
    input clk,
    input rest_n,
    output out
    );
    
reg out,current_state,next_state;    

always@(posedge clk or negedge rest_n) //״̬תӆ
begin
    if(!rest_n)  
        begin out <= 1'd0;current_state <= 1'b0; end
    else      
        case(current_state)
            1'b0:   begin out <= 1'b1;current_state <= 1'b1; end
            1'b1:   begin out <= 1'b0;current_state <= 1'b0; end
            default:begin out <= 1'b0;current_state <= 1'b1; end
        endcase
end

endmodule

 

二段式:

用1個觸發器完成任務1,用一個組合邏輯完成任務2、3。最後的輸出由組合邏輯驅動,可能會產生毛刺,不利於時序分析和優化。

module two_state_machine(
    input clk,
    input rest_n,
    output out
    );
    
reg out,current_state,next_state;    

always@(posedge clk or negedge rest_n) //״̬תӆ
begin
    if(!rest_n)  
        current_state<=1'b0;
    else      
        current_state<=next_state;
end

always@(*)
begin
    case(current_state)
        1'b0:   begin out = 1'd1; next_state = 1'b1; end
        1'b1:   begin out = 1'd0; next_state = 1'b0; end
        default:begin out = 1'd0; next_state = 1'b1; end
    endcase
end

endmodule

 

三段式:

一個觸發器完成任務1,一個組合邏輯完成任務2,一個觸發器完成任務3

module three_state_machine(
    input clk,
    input rest_n,
    output out
    );
    
reg out,current_state,next_state;    

always@(posedge clk or negedge rest_n) 
begin
    if(!rest_n)  
        current_state<=1'b0;
    else      
        current_state<=next_state;
end

always @ (current_state)
begin
    case(current_state)
        1'b0:   next_state = 1'b1;
        1'b1:   next_state = 1'b0;
        default:next_state = 1'b1;
    endcase
end

always@(posedge clk or negedge rest_n)
begin
    if(!rest_n)
        out <= 1'd0;
    else
        case(current_state)
        1'b0:   out <= 1'd1;
        1'b1:   out <= 1'd0;
        default:out <= 1'd0;
        endcase
end

endmodule

 

仿真激勵代碼:

`timescale 1ns / 1ps
module testbench_one_state_machine;
reg clk,rest_n;
wire out;   

one_state_machine U0 (
         .clk(clk),
         .rest_n(rest_n),
         .out(out)
         );

initial 
begin// this process block specifies the stimulus. 
    rest_n = 0;
    #50
    rest_n = 1;
end

initial begin
    clk = 0;
    forever #10 clk = ~clk;
end

endmodule

 

本文邏輯簡單,三種狀態機波形幾乎一致。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章