Make/Day

毎日なにか作ります

42日目 ~ALUの検証~

こんにちは!今日はデジタル回路の話題で更新します。

今回は、ようやくALU(演算装置)の検証を行います。
ALUはCPUが様々な演算を行う要のデジタル回路です。

過去記事からのつながり

確か、設計自体は20日以上前にしたはずです。

in-reality.hatenablog.com
なんか次回には検証するとか言ってますね🙄
もうずいぶんと期間が開いてしまいましたが、案外検証までに手順があったためです。(サボってた方が多いよーな(;'∀'))

前回テストベンチで検証した際には結構あっさりと実行していましたが、実は

  • テストベンチを書く
  • ALUの理論値を取得する

という二つの作業が必要でした。そこで、前回はテストベンチのひな型を書いて用意してみたわけです。

今回すること

テストベンチの変更

今回は、ALUの理論値を取得し、テストベンチをシミュレータ上で実行し、20日前に設計した回路が正しいのか検証していきます。

まずは、前回のテストベンチから、ALUをテストするための環境に少し手を加えます。

module ALU_tb;
// 入力信号はregで生成
  reg [15:0] x, y;
  reg zx, nx, zy, ny, f, no;

// 出力信号は瞬時に値が変化するようwire型で宣言
  wire [15:0] out;
  wire zr, ng;

// 期待値を_expectedで確保しておく
  reg [15:0] out_expected;
  reg zr_expected, ng_expected;

  ALU U0 (.x(x), .y(y), .zx(zx), .nx(nx), .zy(zy), .ny(ny), .f(f), .no(no), .out(out), .zr(zr), .ng(ng));

  reg [55:0] testdata[0:35];
  integer idx;    //step数のカウント
  integer flag = 0;
  initial begin
// ここから下は前回とほぼ共通なので省略(比較部分)
  end
endmodule

これで、入力信号をレジスタで受け付けて回路へ流し、出力を理論値と比較できるようになりました。

理論値の入手

次に、理論値を用意します。本来は、自分でシミュレータを書いて自作するのですが、今回はNand2tetrisの本に従っているので、筆者が準備して下さっているデータがあります。
www.nand2tetris.org
ここから入手したデータの中に、.cmpという比較専用のファイルが入っています。
しかし、このデータ形式では一般的には使用できないため、これをdataファイルのフォーマットへ変換していきます。

//これを...
| 0000000000000000 | 1111111111111111 | 1 | 0 | 1 | 0 | 1 | 0 | 0000000000000000 | 1 | 0 |
//こうする
0000000000000000_1111111111111111_1_0_1_0_1_0_0000000000000000_1_0

適当にC言語で変換するスクリプトを作って実行すれば何とかなると思います。(さすがに手打ちはキツイ_(´ཀ`」 ∠)_)
なんやかんやで目的のフォーマットに格納された理論値が用意できれば後は実行するだけです。

実行結果

シミュレートにはmodelsimを使用しました。windowsマシンのGUIで使える偉いヤツです。テストベンチでは、実行して理論値と回路の出力がすべて一致していたらSucceeded!と、どこか間違えていたら誤った行を報告するように書いています。

35行目が間違えていた場合

それでは実際にALUの検証を行います。

Succeeded!の文字が光る

うん!これで問題なさそうですね❕(1回で通ったわけではない(* ̄з ̄) ~♪)
実はこれまで紹介してきたコードは、Verilogに書く前にこれとは別に一度ソフトウェアシミュレータをパスしていて、ほぼ確実に動くことを確認しています。とはいえ、このブログで載せたコードの動作を保証しているというわけではありません。

ここからはついにCPUの構成を行っていきます。なんだかワクワクしてきますね❕