move pages to top directory authored by Toru Koizumi's avatar Toru Koizumi
RISC-V プログラムの実行
============
CPU が一通り完成したら、その上でプログラムを動かすことによって動作を検証します。
## メモリへの読み込み方法
[RAM の書き方](../ro/FPGARAM)にも書いてあるとおり、メモリの初期化は、モジュール内に次のような記述をすることで行うことができます。
```verilog
initial $readmemh("/home/username/workspace/test.hex", mem)
```
したがって、ROM や RAM の Verilog ファイル中で上記のような記述をおこなうことで、プログラムの書かれた .hex ファイルを読み込むことができます。こちらで用意した開発環境で生成されるコードや最終課題のプログラムは、 ROM 用と RAM 用の .hex ファイルにわかれています。これらをそれぞれで指定して読み込むようにしましょう。
ここで、正しくプログラムを実行するためには、命令やデータのメモリ内における配置を正しく決める必要があります。今回は、下記のようにメモリマップになるよう CPU を作っていきましょう。
| アドレス | サイズ | 内容 |
|:-----------|:-----------|:-----------|
| 0x08000-0x10000 | 32KiB | .text(ROM) |
| 0x10000-0x18000 | 32KiB | .rodata + .data + .bss + .comment(RAM) |
| 0x18000-0x20000 | 32KiB | stack(RAM) |
* 0xF6FF_F070にSTBするとその値がシリアルポートに書き込まれる
* 0xFFFF_FF00からLWするとハードウェアカウンタの値が読み出される
実装における具体的な注意点としては、
* 生成される.hexファイルが32bit単位で記述されていることに注意すること
* メモリの容量を命令やデータの総量よりも多く確保すること
* シリアル出力やハードウェアカウンタ用のアドレスを間違えないこと
などがあります。
## シミュレーション方法
テストベンチについては、下記のようにごく簡単なものを用意すれば良いでしょう。
```verilog
module cpu_tb;
reg clk;
reg rst_n;
wire uart_tx;
parameter CYCLE = 100;
always #(CYCLE/2) clk = ~clk;
cpu cpu0(
.clk(clk),
.rst_n(rst_n),
.uart_tx(uart_tx)
);
initial begin
#10 clk = 1'd0;
rst_n = 1'd0;
#(CYCLE) rst_n = 1'd1;
#(プログラムの実行サイクル数以上の数字) $finish;
end
endmodule
```
こうしたテストベンチを作成したのち、 CPU のトップモジュールや下層の各モジュールと一緒に`Add Sources`で Vivado 上へと読み込むことで、シミュレーションをおこなうことができます。
\ No newline at end of file