マシン・コードの動作実験 1-1: ディスプレイへの文字出力

実験の概要

本実験では、FPGA を搭載した実験基板を使用し、プロセッサを FPGA 上に実現してその動作を確認する。これにより、プロセッサの動作実験の各手順の理解を目指す。 本動作実験では、 即値符号なし整数加算命令(add immediate unsigned:addiu)とストア・ワード命令(store word:sw)が未実装なプロセッサにおいて、それらの命令を含む簡単な機械語のマシン・コードを実行すると、どのような動作をするかを観察する。 本実験で観察した結果は、次のプロセッサの追加設計 1 において、 addiu と sw が正しく動くプロセッサを完成させた後、 動作確認の際の比較に用いる。

マシン・コードの動作実験 1-1

ディスプレイに文字 'B' を 1 つ表示する MIPS マシン・コード print_B.bin と、それを実行するプロセッサを FPGA 上に実現し、その動作を確認せよ。

本動作実験を下記の 1, 2, 3, 4 の手順で行いなさい。
1. MIPS マシン・コードからのメモリ・イメージファイルの作成
2. 命令メモリに格納される命令列の確認
3. 論理合成
4. FPGA を用いた回路実現

なお、本実験で使用する MIPS マシン・コード print_B.bin と、プロセッサの Verilog HDL 記述一式 mips_de2-115.tar.gz は、それぞれ下記の URL からダウンロードできる。

MIPS のマシン・コード print_B.bin:
http://www.ice.nuie.nagoya-u.ac.jp/jikken/hard/j2hard-mips/k01_addiu_sw_1_1/print_B.bin
(実験 1-1 用の MIPS マシン・コード、バイナリファイル)

プロセッサの Verilog HDL 記述一式:
http://www.ice.nuie.nagoya-u.ac.jp/jikken/hard/j2hard-mips/k01_addiu_sw_1_1/mips_de2-115.tar.gz (個別のソースファイル:cpu.v, main_ctrl.v
(本実験をとおして完成させる未完成なプロセッサ)

1. MIPS マシン・コードからのメモリ・イメージファイルの作成

本実験では図 1 のように、MIPS マシン・コードを、プロセッサの命令メモリのメモリ・イメージファイルに変換する。
MIPS マシン・コード −−−−−−→ プロセッサの命令メモリのメモリ・イメージファイル
         (変換プログラム)
図 1: MIPS マシン・コードのメモリ・イメージファイルへの変換

この変換により、 QuartusII で論理合成可能なメモリ・イメージファイルが得られる。このイメージを命令メモリに持つプロセッサを論理合成することにより、変換前のマシン・コードを実行するプロセッサが回路実現できる。

本実験では、MIPS マシン・コードの例として print_B.bin を使用する(ダウンロード )。 また変換には、変換プログラム bin2v を使用する。指導書2.2.1 節に示した環境設定を行ったのち、図 2 のようにして、MIPS マシン・コード print_B.bin からメモリ・イメージファイルを作成せよ。
bin2v print_B.bin
図 2: bin2v を使った MIPS マシン・コードのメモリ・イメージファイルへの変換

この変換により、論理合成用のメモリ・イメージファイル rom8x1024_DE2.mif が得られる。また、論理シミュレーション用の命令メモリの Verilog HDL 記述 rom8x1024_sim.v が得られる。

メモリ・イメージファイル rom8x1024_DE2.mif は、論理合成の際に QuartusII によって読まれるファイルである。 また、論理シミュレーション用の Verilog HDL 記述 rom8x1024_sim.v は、 論理シミュレーションとプロセッサが実行する命令列を確認する際に用いられる。

メモリ・イメージファイル rom8x1024_DE2.mif は、論理合成の際に QuartusII によって読まれるファイルである。 また、論理シミュレーション用の Verilog HDL 記述 rom8x1024_sim.v は、論理シミュレーションとプロセッサが実行する命令列を確認する際に用いられる。

なお、本実験で使用する MIPS マシン・コード print_B.bin は、正しいプロセッサ(即値符号なし整数加算命令 addiu と、ストア・ワード命令 sw が実装済みのプロセッサ)で動作させると、以下のような動作をする命令列を含んだバイナリ・ファイルである。
  1. データメモリ(RAM)の 0x0300 番地に 0 を格納
    addiu $s2, $s0, 0x0300
    sw $s0, 0x0000($s2)
  2. RAM の 0x0304 番地に 2 を格納
    addiu $s3, $s0, 0x0304
    addiu $s2, $s0, 0x0002
    sw $s2, 0x0000($s3)
  3. RAM の 0x0300 番地に 1 を上書き
    addiu $s3, $s0, 0x0300
    addiu $s2, $s0, 0x0001
    sw $s2, 0x0000($s3)

2. 命令メモリに格納される命令列の確認

本実験では、プロセッサの命令メモリに格納される命令列の確認を行う。この確認には、bin2v により生成された論理シミュレーション用の Verilog HDL 記述 rom8x1024_sim.v を使用する。

図 3 に rom8x1024_sim.v の一部を示す。図 3 の case ブロック内の各行は、本実験で設計するプロセッサにおける、命令メモリの 10-bit アドレスとそこに格納される 32-bit 命令の機械語の記述である。また、各行の // 以降のコメント部には、その行に記述されているアドレスと命令に関する説明が記述されている。コメント部には、実際の MIPS の命令メモリにおけるアドレスと、命令名、命令の意味が記述されている。命令の意味の記述では、シンボル REG[0], REG[1], ..., REG[31] により、レジスタ 0 番から 31 番、$s0, ..., $s31 を表す。また、シンボル RAM[w] により、データメモリの w 番地を表す。

<省略>
case (word_addr)
 <省略>
 10'h00b: data = 32'h24020300; // 0040002c: ADDIU, REG[2]<=REG[0]+768(=0x00000300);  ここが PC=0x002c の命令
 10'h00c: data = 32'hac400000; // 00400030: SW, RAM[REG[2]+0]<=REG[0];
 10'h00d: data = 32'h24030304; // 00400034: ADDIU, REG[3]<=REG[0]+772(=0x00000304);
 10'h00e: data = 32'h24020002; // 00400038: ADDIU, REG[2]<=REG[0]+2(=0x00000002);
 10'h00f: data = 32'hac620000; // 0040003c: SW, RAM[REG[3]+0]<=REG[2];
 10'h010: data = 32'h24030300; // 00400040: ADDIU, REG[3]<=REG[0]+768(=0x00000300);
 10'h011: data = 32'h24020001; // 00400044: ADDIU, REG[2]<=REG[0]+1(=0x00000001);
 10'h012: data = 32'hac620000; // 00400048: SW, RAM[REG[3]+0]<=REG[2];
 <省略>
endcase
<省略>
図 3: rom8x1024_sim.v の一部

例えば、図 3 の case ブロック内の最初の記述は、本実験で設計するプロセッサの命令メモリの 0x00b 番地に機械語 0x24020300 が格納されていることを表している。 また、この命令は実際の MIPS では 0x0040002c: に格納され、 命令名は addiu、レジスタ 2 番にレジスタ 0 番(常に 0)+768 の結果をセットする命令であることを表している。

なお、本実験で設計するプロセッサのプログラムカウンタ PC=(0x h3 h2 h1 h0) が指す命令は、本プロセッサの命令メモリでは、アドレスを右に 2-bit シフトした (0x h3 h2 h1 h0) >> 2 番地に格納されている。 例えば、本実験で設計するプロセッサの PC=0x002c が指す命令は、 本プロセッサの命令メモリの (0x002c) >> 2、即ち 0x000b 番地に格納されている。

また、本実験で設計するプロセッサのプログラムカウンタ PC=(0x h3 h2 h1 h0) が指す命令は、実際の MIPS の命令メモリでは、アドレスの上位に 0x0040 を付加した (0x0040 h3 h2 h1 h0) 番地に格納されている。

print_B.bin から生成された rom8x1024_sim.v, または、図 3 の Verilog HDL 記述を解析し、以下の 1, 2, 3, 4, 5 について答えよ。 なお、addiu は即値符号なし整数加算命令、sw はレジスタの値をメモリに転送するストア・ワード命令、レジスタ 0 番の値は常に 0 である。
  1. プロセッサが PC=0x002c の命令を実行した直後のレジスタ REG[2] の値を予想せよ。
  2. プロセッサが PC=0x0030 の命令を実行した後の RAM の 768 (0x00000300) 番地の値を予想せよ。
  3. プロセッサが PC=0x0034 番地の命令を実行した後の REG[3] の値を予想せよ。
  4. プロセッサが PC=0x003c の命令を実行すると、RAM の何番地の値が変化し、変化後の値はいくらかを予想せよ。
  5. プロセッサが PC=0x0048 の命令を実行すると、RAM の何番地の値が変化し、変化前、変化後の値はそれぞれいくらかを予想せよ。

3. 論理合成

本実験では、addiu 命令と sw 命令が未実装なプロセッサならびに命令メモリ、その他周辺回路の論理合成を行う。 論理合成には、bin2v により生成された論理合成用のメモリ・イメージファイル rom8x1024_DE2.mif とプロセッサの Verilog HDL 記述一式 mips_de2-115.tar.gz(ダウンロード)を使用する。

mips_de2-115.tar.gz を展開して得られるソース一式と rom8x1024_DE2.mif を、Quartus II により論理合成すると FPGA にダウンロード可能なストリーム・アウト・ファイル DE2_115_Default.sof が得られる。

mips_de2-115.tar.gz を図 4 のようにして展開し、プロセッサのソース一式を得る。

tar xvfz ./mips_de2-115.tar.gz
図 4: tar を使った展開

本実験をとおして完成させる未完成なプロセッサの Verilog HDL 記述一式が、展開時に作成されるディレクトリ mips_de2-115 内のサブディレクトリ MIPS 内に展開される。また、メイン制御回路の Verilog HDL 記述 main_ctrl.v も同じサブディレクトリ mips_de2-115/MIPS 内に作成される。

命令メモリのメモリ・イメージファイル rom8x1024_DE2.mif をディレクトリ mips_de2-115 にコピーし、ディレクトリ mips_de2-115 に cd して、図 5 のように論理合成を行う。

quartus_sh --flow compile DE2_115_Default
図 5: quartus_sh を使ったプロセッサの論理合成

なお、論理合成には計算機の性能により 5 分から 20 分程度の時間がかかる。 論理合成が完了すると、ディレクトリ mips_de2-115 内に FPGA にダウンロード可能なプロセッサ等の回路一式のストリーム・アウト・ファイル DE2_115_Default.sof が生成される。

4. FPGA を用いた回路実現

本実験では、addiu 命令と sw 命令が未実装なプロセッサの実際の動作を観察する。 観察した結果は、次のプロセッサの追加設計 1 において、addiu と sw が正しく動くプロセッサを完成させた後、動作確認の際の比較に用いる。 本実験には、論理合成により生成されたプロセッサなど回路一式のストリーム・アウト・ファイル DE2_115_Default.sof を使用する。 図 6 のように quartus_pgm を用いて、DE2_115_Default.sof を DE2-115 ボード上の FPGA にダウンロードし、動作させる。

quartus_pgm DE2_115_Default.cdf
図 6: quartus_pgm を使った FPGA へのダウンロード


DE2-115 ボード上のプッシュスイッチ key2, key3 は、それぞれプロセッサをリセットするためのスイッチ、クロックパルスを生成するためのスイッチである。 プロセッサへのクロック供給が手動モードの時、key3 を 1 回押すと、プロセッサにクロックパルスが 1 つ供給され、プロセッサは PC の指している命令メモリの命令を 1 つ実行する。 本実験で設計するプロセッサは、命令メモリの 0x0000 番地の命令から実行を開始する。

今回プロセッサが実行するマシン・コード print_B.bin はディスプレイ下部に文字 'B' を 1 つ表示するプログラムである。 key3 を連打してプロセッサにクロックパルスを送り、プロセッサにPC=0x0000 番地から PC=0x0048 番地までの命令を実行させ、ディスプレイ下部に文字 'B' が 1 つ表示されるかどうかを確認せよ。 ディスプレイ下部に文字は全く表示されないはずである。

ディスプレイ上部にはプロセッサ内部の主な信号線の現在の値が表示されている。 各信号線は、プロセッサのブロック図中の名前の似た信号線と、それぞれ対応している。 ブロック図中の線の幅はビット幅と対応しており、一番細い線は 1-bit の線、一番太い線は 32-bit の配線を表している。 また、ブロック図左下の ROM が、命令メモリである。 プロセッサはここから命令を読み、命令毎に決められた処理を行う。 ブロック図右下の RAM は、データメモリである。 2 の命令メモリに格納される命令列の確認の、1, 2, 3, 4, 5 で予想した結果と同じ正しい動作かどうかを確認せよ。 予想と異なる正しくない動作のはずである。

プロセッサが、addiu 命令と sw 命令を正しく実行できていないことが分かる。 これらの命令を正しく実行するために、プロセッサ内部で行われるデータ転送や演算などを制御しているメイン制御回路を、これらの命令を適切に処理できるものにする必要がある。

参考書


中村一博