
田中太郎
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を使用してステートマシンを作成しました
コメント