SystemVerilog|Enumでステートマシンを作成するを考える

Systemverilog
田中太郎
田中太郎

Enumを使用したステートマシンを作成します

Enumを使ったサンプルコード

Enumを使ってステートマシン(FSM)を作成しました

IDLE, DO, DONE, ENDのステートを1サイクルごとに遷移して

ステートがDOになったとき1を出力する回路です

module sample(
    input clk,
    input rst_n,
    output logic dout
);
    // Enum型をstate_tで定義
    typedef enum logic [1:0] {
        IDLE = 2'b00,
        DO   = 2'b01,
        DONE = 2'b10,
        END  = 2'b11
    } state_t; 

    state_t state_c, state_n;
    always_comb begin
        case(state_c) // IDLE->DO->DONE->END->IDLEと繰り返します
            IDLE   : state_n = DO;
            DO     : state_n = DONE;
            DONE   : state_n = END;
            default: state_n = IDLE;
        endcase
    end

    // ステートをロードします
    always_ff @(posedge clk, negedge rst_n) begin
        if (!rst_n) begin
            state_c <= '0;
        end
        else begin
            state_c <= state_n;
        end
    end

    // DOのとき、1を出力します
    always_ff @(posedge clk, negedge rst_n) begin
        if (!rst_n) begin
            dout <= '0;
        end
        else begin
            if (state_c == DO) begin
                dout <= '1;
            end
            else begin
                dout <= '0;
            end
        end
    end
endmodule

解説

// Enum型をstate_tで定義
typedef enum logic [1:0] {
    IDLE = 2'b00,
    DO   = 2'b01,
    DONE = 2'b10,
    END  = 2'b11
} state_t; 

enumは下記のように使用します

enum logic {<State1>, <State2>, … };

サンプルでは、typedefでenum型のstate_tを再定義しています

また、サンプルではすべてのステートに値を入れていますが、なくても大丈夫です

// 例えば1
typedef enum logic [1:0] {
    IDLE,
    DO  ,
    DONE,
    END
} state_t; 

IDLE = 0, DO = 1,… のように値が順番に入ります

また、最初のステートに値を入れると、その値を初期値として順番に値が入ります

// 例えば2
typedef enum logic [2:0] {
    IDLE = 3'b001,
    DO  , // 3'b010
    DONE, // 3'b011
    END   // 3'b100
} state_t; 

ちなみに、間違って同じ値を入れてしまったときはコンパイルエラーとなります

state_t state_c, state_n;
always_comb begin
    case(state_c) // IDLE->DO->DONE->END->IDLEと繰り返します
        IDLE   : state_n = DO;
        DO     : state_n = DONE;
        DONE   : state_n = END;
        default: state_n = IDLE;
    endcase
end

state_cが現在のステート、state_nが1サイクル後のステートを表しています

コメントの通り、IDLE->DO->DONE->END->IDLEと繰り返します

まとめ

Enumを使用してステートマシンを作成しました

コメント

タイトルとURLをコピーしました