|
|
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 |