MacでVerilogのシミュレーションをしてみる1

MacでFreeのVerilogシミュレーションツールを使用して、原始的なCPUを作って動かしてみる。

初めにVerilogのシミュレータと波形ビューワーをインストールする。

brew install icarus-verilog
brew install gtkwave

 インストールが完了したらエディタでCPUのHDLを書いてみる。

CPUの基本動作は命令のFetch(読み込み)→Decode(命令解釈)→Execute(実行)を繰り返す。Fetchに戻る前に次の命令が格納されているアドレスを進める。図にすると以下のような感じ。

f:id:k_igrs:20210701230521j:plain

そこでクロックが入力されるたびにステート(状態)が遷移するHDLを書く。

module state_m (CK,RB,Q,PC);
input  CK,RB;
output [3:0] Q;
output [9:0] PC;
reg  [3:0] Q;
reg  [9:0] PC;
wire [3:0] state;
assign state = Q;

always @( posedge CK, negedge RB ) begin
        if ( RB == 1'b0 ) begin
                        Q  <=4'b1111;
                        PC <= 10'h000;
                end
        else 
                begin
                        case ( state )
                                4'b0000:begin
                                        Q <= 4'b0001;
                                end
                                4'b0001:begin
                                        Q <= 4'b0010;
                                end
                                4'b0010:begin
                                        Q <= 4'b0000;
                                        PC <= PC + 1;
                                end
                                4'b1111:begin
                                        Q <= 4'b0000;
                                end
                                default:Q <= 4'b0000;
                        endcase
                end
        end
endmodule

 この回路の動作を確認するため、テストベンチを書いてみる。テストベンチは設計した回路が正しく動作しているか確認するため、回路に対してテスト信号を入力する。

ここではリセット(RB)とクロック(CK)がテスト入力となる。

      1 module STATE_TEST;
      2 
      3 reg CK, RB;
      4 wire [3:0] Q;
      5 wire [9:0] PC;
      6 
      7 state_m inst_statem(CK,RB,Q,PC);
      8 always
      9 #20 CK <= ~CK;
     10 
     11 initial begin
     12         $dumpfile("statetest.vcd");
     13         $dumpvars(2, STATE_TEST);
     14 
     15         RB = 0; CK = 0;
     16         #90 RB = 1;
     17         #800 $finish;
     18 end
     19 endmodule

 7行目は回路の呼び出し。

8-9行目はクロックの記述。Unit Timeで20毎に反転する。

12-13行目はシミュレーション結果の出力の記述。

 17行目の$finishでシミュレーション終了。

以下のようにしてshellでコマンドを入力しシミュレーションを実行し、実行結果であるvcdファイルを出力する。

iverilog -o statetest -s STATE_TEST statetest.v state_m.v
vvp statetest out

波形ビューワで実行結果を確認する

>open statetest.vcd

実行結果

f:id:k_igrs:20210701234447j:plain