見出し画像

Mac mini上にRTLシミュレーション環境を構築してみる

背景

Mac 上にデジタル回路シミュレーション環境を構築してみよう。

やったこと

まず最初に、MacにIcarus Verilogとgtkwaveをインストールしましたが、gtkwaveの方がMac OS 14に対応していないので動作しませんでした。

Icarus Verilog:ロジックシミュレーター
gtkwave:波形ビューワー

で、Parallels DesktopをインストールしてMac上にWindows11の動作環境を作りました。(サブスク、年間11000円)
Windows11ではIcarus Verilogとgtkwaveのインストールは即完了します。インストール方法は他のネット参照。

シミュレーションしてみる

これまで素数を求めるのを追求してきたので、素数を求める回路をシミュレーションしてもらおう。コードはChatGPTに書いてもらいます。
コード
divider32.v

module divider32 (
    input clk,
    input start,
    input [31:0] dividend,
    input [31:0] divisor,
    output reg [31:0] quotient,
    output reg [31:0] remainder,
    output reg done
);
    reg [63:0] temp_dividend;
    reg [31:0] temp_divisor;
    reg [5:0] bit;
    reg running; // 計算中かどうかを示すフラグ

    always @(posedge clk) begin
        if (start && !running) begin
            if (divisor == 32'b0) begin
                // divisorが0の場合の処理
                done <= 1;
                quotient <= 32'b0;
                remainder <= 32'b0;
                running <= 0;
            end else begin
                quotient <= 32'b0;
                remainder <= 32'b0;
                temp_dividend <= {32'b0, dividend};
                temp_divisor <= divisor;
                bit <= 6'd32;
                done <= 0;
                running <= 1;
            end
        end else if (running) begin
            if (bit > 0) begin
                remainder = remainder << 1;
                remainder[0] = temp_dividend[63];
                temp_dividend = temp_dividend << 1;
                bit = bit - 1;
                if (remainder >= temp_divisor) begin
                    remainder = remainder - temp_divisor;
                    quotient = quotient << 1;
                    quotient[0] = 1;
                end else begin
                    quotient = quotient << 1;
                end
            end else begin
                done <= 1;
                running <= 0; // 計算終了
            end
        end
    end
endmodule

合ってる?
回路合成は可能な感じです。
テストベンチは、test_divider32.v

module test_divider32;
    reg clk;
    reg start;
    reg [31:0] dividend;
    reg [31:0] divisor;
    wire [31:0] quotient;
    wire [31:0] remainder;
    wire done;

    // テスト対象のモジュールをインスタンス化
    divider32 uut (
        .clk(clk),
        .start(start),
        .dividend(dividend),
        .divisor(divisor),
        .quotient(quotient),
        .remainder(remainder),
        .done(done)
    );

    // クロック信号の生成
    always #5 clk = ~clk; // 10ns周期のクロック

    initial begin
        // VCDダンプファイルの生成設定
        $dumpfile("simulation.vcd");
        $dumpvars(0, test_divider32);

        // 初期化
        clk = 0;
        start = 0;
        dividend = 0;
        divisor = 0;

        // 100ns待つ
        #100;

        // テストケース1
        dividend = 32'd100;
        divisor = 32'd3;
        start = 1;
        #10;
        start = 0;

        // doneが1になるまで待つ
        wait(done);
        #10;

        // 結果を表示
        $display("Test Case 1: 100 / 3");
        $display("Quotient: %d", quotient); // 期待値: 33
        $display("Remainder: %d", remainder); // 期待値: 1

        // 100ns待つ
        #100;

        // テストケース2
        dividend = 32'd250;
        divisor = 32'd5;
        start = 1;
        #10;
        start = 0;

        // doneが1になるまで待つ
        wait(done);
        #10;

        // 結果を表示
        $display("Test Case 2: 250 / 5");
        $display("Quotient: %d", quotient); // 期待値: 50
        $display("Remainder: %d", remainder); // 期待値: 0

        // シミュレーション終了メッセージ
        $display("Simulation finished.");
        $finish;
    end

    initial begin
        // シミュレーション強制終了タイミング
        #100000;
        $finish;
    end
endmodule

実行は

iverilog -o divider_sim divider32.v test_divider32.v
vvp divider_sim

シミュレーション波形

ChatGPTが出力したコードでは正常動作しません。
まだその程度のAIなのか?今日はAIのご機嫌が悪いのでしょう。

所感

私はChatGPTさんの間違いをデバッグする仕事をしているわけではありませんので・・・ここで終わりでしょうか。
実際では、回路をずらっと並べて並列回路にしても、素数を計算する専用回路など使い道ないと思います。CPU(ソフトウェア)を使うべきです。
信号処理や画像処理でなければ専用回路の(コスパの)意味はないでしょうね。

(終わり)

いいなと思ったら応援しよう!