gowin-init-ram-xx-bit-mapping

Gowin の INIT_RAM_XX のビット配置

Gowin 社の FPGA が持つ BSRAM には、初期値を指定するためのパラメタとして INIT_RAM_XX があります。ここに 8 ビット単位ではないビット幅の初期値を指定するときのビット表現を調べました。

例えば、次のように初期値を指定できます。

defparam sdpx9b_inst_0.INIT_RAM_00 = 288'h0003C000000000000000000000000001BEEF00000000000000000000000000072003DEAD;
defparam sdpx9b_inst_0.INIT_RAM_01 = 288'h0007C00000000000000000000000000000180005C0000000000000000000000000440010;
...
defparam sdpx9b_inst_0.INIT_RAM_0F = 288'h32BF80000000000000000000000000000000000000000000000000000000000000000000;

288 ビットの中のどこが、RAM のどのアドレスに対応するのか、ということを調べました。何故そんなことを調べたかというと、defparam の行を自動生成したかったからです。自動生成するために、どこにどんな値を書けばいいかを知る必要がありました。

指定する初期値

調査のために、Gowin EDA の IP Core Generator を用いて、1 ワードあたり 18 ビット、合計 256 ワードのセミ・デュアル・ポート(SDP)RAM を作ってみます。初期値として指定する Memory Initialization File に記述した内容は次の通りです。

ワードアドレス ワード値
00 3DEAD
01 1C800
...
08 1BEEF
...
0F 0000F
10 00010
11 00011
...
17 00017
18 00018
...
1F 0001F
...
FF 0CAFE

省略「...」したところに書かれている値はすべて 0 です。

生成された defparam

18 ビット×256 ワードですから、計 4608 ビットです。これを 288 ビット毎に分けると 16 行になります。だから defparam は 16 行生成されました。

defparam sdpx9b_inst_0.INIT_RAM_00 = 288'h0003C000000000000000000000000001BEEF00000000000000000000000000072003DEAD;
defparam sdpx9b_inst_0.INIT_RAM_01 = 288'h0007C00000000000000000000000000000180005C0000000000000000000000000440010;
defparam sdpx9b_inst_0.INIT_RAM_02 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000;
defparam sdpx9b_inst_0.INIT_RAM_03 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000;
defparam sdpx9b_inst_0.INIT_RAM_04 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000;
defparam sdpx9b_inst_0.INIT_RAM_05 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000;
defparam sdpx9b_inst_0.INIT_RAM_06 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000;
defparam sdpx9b_inst_0.INIT_RAM_07 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000;
defparam sdpx9b_inst_0.INIT_RAM_08 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000;
defparam sdpx9b_inst_0.INIT_RAM_09 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000;
defparam sdpx9b_inst_0.INIT_RAM_0A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000;
defparam sdpx9b_inst_0.INIT_RAM_0B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000;
defparam sdpx9b_inst_0.INIT_RAM_0C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000;
defparam sdpx9b_inst_0.INIT_RAM_0D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000;
defparam sdpx9b_inst_0.INIT_RAM_0E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000;
defparam sdpx9b_inst_0.INIT_RAM_0F = 288'h32BF80000000000000000000000000000000000000000000000000000000000000000000;

1 行目の解読

まず 1 行目 288'h0003C000000000000000000000000001BEEF00000000000000000000000000072003DEAD; に注目します。

最下位にある「3DEAD」は分かりやすいです。しかし、その次の「07200」は謎です。アドレス 1 には「1C800」があるはずなのに、「07200」って何でしょうか。

その謎を解くためにいったん 2 進数で表してみます。下 9 桁 72003DEAD を 2 進数で表すと 0111 0010 0000 0000 0011 1101 1110 1010 1101 となります。

これをちょうど半分に分けます。

  • ワード 1: 0111 0010 0000 0000 00
  • ワード 2: 11 1101 1110 1010 1101

ワード 1 のビットの区切りを修正すると 01 1100 1000 0000 0000 となります。つまり 1C800 です!

とまあこんな風に 2 ワード 9 桁をひとかたまりとして取り出し、整理すると、次のようになります。

ワード 16進値 下位ワード 上位ワード
0,1 72003DEAD 3DEAD 1C800
8,9 00001BEEF 1BEEF 00000
14,15 0003C0000 00000 0000F

ビット配置

ここまでの調査で答えが出ました。INIT_RAM_XX には、下位ビットから隙間無くデータが詰め込まれているようです。

2 進数で表せば、2 ワード分は bbbb bbbb bbbb bbbb bbaa aaaa aaaa aaaa aaaa と詰め込まれます。上位ワードを b、下位ワードを a で書いています。



この記事を参照しているブログ内記事はありません。

作成:2026-04-22 15:01:00

最終更新:2026-04-22 15:01:00