ULX3Sで確保可能なブロックRAMのサイズ
自作CPU上で例のレイトレ( レイトレをRISC-Vで動かす )を動かしたいのだけど、ULX3SのブロックRAMのサイズがあまり大きくないため、ブロックRAM内にレイトレのプログラムが収まるかどうか心配。 ULX3SのブロックRAMの上限と、レイトレプログラムのバイナリのサイズを確認してみる。
データシート上のブロックRAMの上限
ULX3S(うちのは85F)のブロックRAMのサイズを確認する。
ULX3Sが採用しているFPGAチップ「ECP5」のデータシートを確認。
ECP5のデータシートによると、18kb(ビット)のブロックメモリが208個あるらしい。だいたい 0.4MBくらいか。
18 kb * 208 = 3744 kb(ビット) = 468 KB(バイト) = 0.4 MB
https://gyazo.com/076e904b7811d658f144ccd368004e1a
ECP5データシート
実際にブロックRAMを確保してみる
次は実機で確認してみる。ブロックRAMのサイズを 64KB、128KB、256KB、512KBにして、テストプログラムでメモリ最後尾付近のアドレスの読み書きを行なう。
64KB → OK
128KB → OK
256KB → OK
512KB → OK(データシート上では 400KB ほどのはずなのに...)
結果、64KB〜512KBのどのサイズでも読み書きできた
失敗するはずだった 512KB でもちゃんと動いたのが意外。もしかしたら分散RAMが使われてたりする?
最低でも 256KB のブロックRAMが確保できることが分かった。
code:diff
diff --git a/firmware/mem_test.S b/firmware/mem_test.S
index e480bcc..9d53b99 100644
--- a/firmware/mem_test.S
+++ b/firmware/mem_test.S
@@ -14,6 +14,14 @@ _start:
lui tp, 0xf0001 // LEDアクセス用 gp
li s0, 0x40000000 // データ領域開始アドレス(SDRAM)
+ /*
+ // ブロックRAMテスト用のコード
+ li s0, 0x0007FFF0 // ブロックRAMが 512KB の場合の最後のアドレス(0x00000000 ~ 0x0007ffff)
+ li s0, 0x0003FFF0 // ブロックRAMが 256KB の場合の最後のアドレス (0x00000000 ~ 0x0003ffff))
+ li s0, 0x0001FFF0 // ブロックRAMが 128KB の場合の最後のアドレス (0x00000000 ~ 0x0001ffff))
+ li s0, 0x0000FFF0 // ブロックRAMが 64KB の場合の最後のアドレス (0x00000000 ~ 0x0000ffff))
+ */
+
// SDRAM へデータを格納して...
li t0, 'A'
sw t0, 0(s0)
diff --git a/rtl/bram_controller.sv b/rtl/bram_controller.sv
index 74b4a6d..9529adf 100644
--- a/rtl/bram_controller.sv
+++ b/rtl/bram_controller.sv
@@ -29,9 +29,11 @@ module bram_controller(
// $monitor("%t: state = %d, reset_n = %b, mem_valid = %b, mem_ready = %b, mem_addr = %h, mem_wdata = %h, mem_wstrb = %b, mem_rdata = %h", $time, state_reg, reset_n, mem_valid, mem_ready, mem_addr, mem_wdata, mem_wstrb, mem_rdata);
end
- // 0x0000 ~ 0x1FFF の 8KB の BRAM を用意
- // 1ワード = 32bit = 4byte なので、メモリの深さは 2048 となる
+ // 0x00000 ~ 0x3FFFF の 256KB の BRAM を用意
assign mem_ready = (state_reg == STATE_SEND_READY) ? 1'b1 : 1'b0;
diff --git a/rtl/ulx3s_top.sv b/rtl/ulx3s_top.sv
index 5f9cd12..88c861d 100644
--- a/rtl/ulx3s_top.sv
+++ b/rtl/ulx3s_top.sv
@@ -237,8 +237,11 @@ module ulx3s_top(
// 周辺機器との接続
//------------------------------------------------------------------
- // メモリマップ
- assign bram_en = (mem_addr < 8192) ? 1'b1 : 1'b0;
+ // アクセスしたアドレスに応じた周辺機器を有効にする
+ assign bram_en = (mem_addr < 262144) ? 1'b1 : 1'b0; // 0x0000_0000 ~ 0x0003_FFFF (256KB)
+ // assign bram_en = (mem_addr < 524288) ? 1'b1 : 1'b0; // 0x0000_0000 ~ 0x0007_FFFF(512KB)
+ // assign bram_en = (mem_addr < 131072) ? 1'b1 : 1'b0; // 0x0000_0000 ~ 0x0001_FFFF(128KB)
+ // assign bram_en = (mem_addr < 65536) ? 1'b1 : 1'b0; // 0x0000_0000 ~ 0x0000_FFFF(64KB)
assign sdram_en = ((mem_addr & 32'hf000_0000) == 32'h4000_0000) ? 1'b1 : 1'b0;
assign uart_data_en = (mem_addr == 32'hf0000000) ? 1'b1 : 1'b0;
assign uart_ctl_en = (mem_addr == 32'hf0000004) ? 1'b1 : 1'b0;
レイトレのバイナリサイズ
レイトレのバイナリ min-rt.min-caml のサイズは 224KB くらい
https://gyazo.com/28b5bd28d889b1a8056ab11f72ba223f
strip コマンドにかけたら、110KBに縮小した
https://gyazo.com/d596cd05a12be0a22651235a236ea509
レイトレのプログラムが200KB程度ということは、256KBのブロックRAMがあれば収まりそう。
まとめ
256KBのブロックRAMが確保できるので、レイトレのプログラムはブロックRAMに収まりそう
ヒープやスタックには4MB必要なので、ブロックRAMには収まらない
プログラムが格納されるTEXT領域はブロックRAMへ
ヒープやスタックのデータ領域はSDRAMへ