FPGAのスペックや設計ツールを使っていると、「BRAM」や「Block RAM」という言葉を頻繁に目にします。しかし、"BRAMってただのRAMでしょ?"と思っていると、実装時に思わぬリソース消費や合成エラーに悩むことになります。本記事では、FPGAにおけるBRAMの基本概念から、HDLでの使い方、さらにはリソース管理の視点まで、初学者向けに解説します。
BRAM(Block RAM)とは何か?
BRAMとは、FPGAチップ内にあらかじめ組み込まれている専用の固定サイズのメモリブロックです。
- "Block"とは、1つのRAMが物理的にまとまった単位で存在するという意味です。
- FPGAではこのRAMをユーザーが自由に回路内で利用できます。
例:Zynq-7020には36KbのBRAMブロックが最大140個搭載されており、合計約630KBの内部RAMとして使えます。
なぜBRAMがあるのか?
論理回路の記述でもRAMは作れますが、それにはLUT(ルックアップテーブル)を消費します。小規模なRAMならそれで十分ですが、大容量のメモリを実装するには非効率です。
こうしたLUTベースのRAMは、一般に"分散RAM(Distributed RAM)"と呼ばれることもありますが、厳密な規格名ではなく、文脈によって呼び方が変わるため、本記事では"小規模RAM"と表現します。
BRAMは、高速で安定したアクセスを可能にしつつ、専用構造により回路リソースを圧迫しません。
比較対象 | 小規模RAM | Block RAM (BRAM) |
---|---|---|
容量 | 小さい(数Kb未満) | 大きい(36Kb/ブロック) |
消費資源 | 論理素子(LUT) | 専用のRAMセル |
用途 | 小規模なFIFO/バッファなど | 大容量メモリ、画像/音声バッファなど |
HDLでのBRAM利用:コードとその意味
Vivadoなどのツールでは、HDLコードから自動的に"これはRAMだ"と推論してBRAMに割り当ててくれます。以下に例を示します:
(* ram_style = "block" *)
reg [11:0] memory_array [0:(1<<ADDR_WIDTH)-1]; // ADDR_WIDTH = 14 の場合、12bit x 16384 = 約192Kb
このコードは、12ビット幅、16KエントリのRAMを定義しています(ADDR_WIDTH
= 14 の場合)。
- 必要容量:12bit × 16384 = 196,608bit(192Kb)
- 36KbのBRAMで割ると → ceil(196608 / 36864) = 6ブロック消費
- 属性
ram_style = "block"
によって、ツールに明示的にBRAM利用を促しています
つまり、コード上は1行でも、物理的には6個のBRAMブロックを消費する大規模リソースということになります。
リソース管理の観点:容量とブロック単位
重要なのは、BRAMはブロック単位でしか使えないという点です。
- たとえば36Kbのうち20Kbしか使わないRAMでも、1ブロックをまるごと専有します。
- ブロック内で複数のRAMを共有することは基本的にできません(設計次第で分割的使用は可能)。
そのため、以下のようなことを意識する必要があります:
- RAMの深さ(アドレス数)と幅(データ幅)を調整して、BRAM使用効率を最適化する
- 実際に何ブロック消費するのかは合成レポートで確認する
- 小規模なRAMはLUT RAMで済ませ、大容量だけBRAMを使うように意識する
まとめ
- BRAMは、FPGAに物理的に搭載されている大容量メモリブロック
- HDLでRAM構造を書くと、ツールが自動的にBRAMに割り当てる(場合による)
ram_style = "block"
を使うことで意図的にBRAMを使わせることができる- 容量≠リソース消費量:たとえば1ブロック36Kbの場合は192KbのRAMでも実際は216Kb分(6ブロック)使う
- 効率的な使い方にはビット数の見積もりと構成設計が不可欠
BRAMの使い方と意義を理解することは、FPGA設計者にとって非常に重要です。回路の性能と規模のバランスを取るためにも、単に「RAMを使う」以上に、どう使うか、どれだけ使うかを考える視点が求められます。