Edusemi-v4x

4.4 Verilog記述とテストベンチ構成

この章では、PoC(Proof of Concept)に含まれる3つの基本ブロック「FSM(状態遷移制御)」「MUX(選択回路)」「Adder(加算器)」を題材に、Verilog HDLによる設計とテストベンチ構成の基本を学びます。

単なるコード提示にとどまらず、各ブロックの設計意図・動作の理解・検証方法・実行方法まで一体として解説します。


🔁 FSM:有限状態機械の記述と検証

🎯 設計の目的

FSM(Finite State Machine)は、クロックに同期して状態を遷移しながら、外部入力に応じて制御信号を生成する順序回路です。

ここでは「IDLE → LOAD → EXEC → DONE → IDLE」というシンプルな4状態FSMを設計し、完了フラグflag_doneを出力する構成を取ります。

💻 Verilog記述(fsm.v)

module fsm (
    input clk,
    input rst_n,
    input start,
    output reg flag_done
);

reg [1:0] state, next_state;

localparam IDLE = 2'b00,
           LOAD = 2'b01,
           EXEC = 2'b10,
           DONE = 2'b11;

always @(posedge clk or negedge rst_n) begin
    if (!rst_n)
        state <= IDLE;
    else
        state <= next_state;
end

always @(*) begin
    next_state = state;
    flag_done = 0;
    case (state)
        IDLE: if (start) next_state = LOAD;
        LOAD: next_state = EXEC;
        EXEC: begin
            next_state = DONE;
            flag_done = 1;
        end
        DONE: next_state = IDLE;
    endcase
end

endmodule

🧪 テストベンチ(fsm_tb.v)

module fsm_tb;

reg clk, rst_n, start;
wire flag_done;

fsm uut (
    .clk(clk),
    .rst_n(rst_n),
    .start(start),
    .flag_done(flag_done)
);

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

initial begin
    $dumpfile("fsm.vcd");
    $dumpvars(0, fsm_tb);

    rst_n = 0; start = 0;
    #20 rst_n = 1;
    #30 start = 1;
    #20 start = 0;
    #200 $finish;
end

endmodule

🔀 MUX:2入力1出力の選択回路

🎯 設計の目的

MUX(Multiplexer)は、2つの入力のうちどちらか一方を選択して出力する組み合わせ論理回路です。論理回路設計の基本構造として、必ずマスターしておくべき回路です。

💻 Verilog記述(mux2to1.v)

module mux2to1 (
    input A,
    input B,
    input SEL,
    output Y
);
assign Y = SEL ? B : A;
endmodule

🧪 テストベンチ(mux_tb.v)

module mux_tb;

reg A, B, SEL;
wire Y;

mux2to1 uut (
    .A(A),
    .B(B),
    .SEL(SEL),
    .Y(Y)
);

initial begin
    $dumpfile("mux.vcd");
    $dumpvars(0, mux_tb);

    A = 0; B = 1; SEL = 0; #10;
    SEL = 1;              #10;
    A = 1; B = 0; SEL = 0; #10;
    A = 1; B = 1; SEL = 1; #10;
    $finish;
end

endmodule

➕ Adder:4ビット加算器の構成

🎯 設計の目的

Adder(加算器)は、AとBの2つの4ビットバス入力を加算し、4ビットの結果(SUM)と1ビットの繰り上がり(COUT)を出力する演算回路です。

💻 Verilog記述(adder4.v)

module adder4 (
    input  [3:0] A,
    input  [3:0] B,
    output [3:0] SUM,
    output       COUT
);
assign {COUT, SUM} = A + B;
endmodule

🧪 テストベンチ(adder_tb.v)

module adder_tb;

reg  [3:0] A, B;
wire [3:0] SUM;
wire       COUT;

adder4 uut (
    .A(A),
    .B(B),
    .SUM(SUM),
    .COUT(COUT)
);

initial begin
    $dumpfile("adder.vcd");
    $dumpvars(0, adder_tb);

    A = 4'b0011; B = 4'b0101; #10;
    A = 4'b1111; B = 4'b0001; #10;
    A = 4'b1001; B = 4'b1001; #10;
    $finish;
end

endmodule

🧰 シミュレーション自動化:Makefileの使い方

この章で設計したRTL+テストベンチは、Makefile を使って簡単にシミュレーションできます。

▶ 使用方法(コマンドライン)

make SIM=fsm
make SIM=mux2to1
make SIM=adder4

▶ クリーンアップ

make clean

🔗 次節への接続

次節 4.5 では、ここで作成したVerilog RTLを用いて、OpenLaneによる物理設計(synthesis → floorplan → route → GDS出力)に進みます。