FPGAのBRAM(Block RAM)完全ガイド:構造・動作モード・ベンダ比較と設計ベストプラクティス
BRAMとは — FPGAにおける組み込みメモリの基礎と活用
BRAM(Block RAM)は、主にFPGA(Field-Programmable Gate Array)内部に配置されたブロック単位の静的RAM(SRAM)リソースを指します。FPGAが持つメモリリソースの一種で、低レイテンシ/高スループットのオンチップ一時記憶領域として、FIFO、バッファ、ルックアップテーブル保存、ディープパイプラインやデータストリーミング処理など幅広い用途に使われます。以下ではBRAMの構造、動作モード、設計上の留意点、各ベンダ実装の違い、設計テクニックなどを詳しく解説します。
BRAMの基本構造と特徴
- ブロック単位のメモリ:BRAMはFPGA上に配置された固定サイズのメモリブロックとして実装されます。代表的な例として、Xilinxの7シリーズでは18Kb(BRAM18)/36Kb(BRAM36)単位で構成されます(BRAM36は2つのBRAM18を結合した論理単位)。Intel(旧Altera)でも世代によりM9K、M10K、M20Kなどのブロック容量が存在します。
- 同期動作:多くのBRAMはクロック同期で動作し、読み書きはクロックエッジに同期して行われます。そのためタイミング設計が容易で、FPGAロジックと密に結合できます。
- マルチポート:一般的に「デュアルポート」(あるいは真のデュアルポート)を持ち、2つの独立したポートで同時にアクセス(読み書き)できます。ポートは同一クロックまたは異クロックで動かせるものもありますが、クロック境界や書き込み競合のルールに注意が必要です。
- 可変幅/深さ:ツール/プリミティブが内部でブロックを組み合わせて、読み出し幅(例:8/16/32/64ビット)と深さを調整します。幅と深さを変えることで論理的なメモリ構造を柔軟に作成できますが、細かい幅での利用はブロックの断片化(内部分割の無駄)を招くことがあります。
BRAMの動作モード/機能
- 読書きポリシー(Write Mode):BRAMには一般的に「WRITE_FIRST(write-through)」「READ_FIRST」「NO_CHANGE」といった書き込み時のデータ出力挙動モードがあります。これは同じサイクルに同一アドレスで書き込みと読み出しが発生した場合に、出力に何が反映されるかを制御します。
- ポートタイプ:シングルポート、シンプルデュアルポート(別アドレスでの読み書きだが書き込みの制約あり)、トゥルーデュアルポート(両方で独立して読み書き可能)などがあります。真のデュアルポートは同じアドレスでの同時書き込み・読み出しの解釈ルールを持ちます。
- バイトイネーブル/部分書き込み:ワード幅が大きいBRAMでは、バイト単位での書き込み有効化(byte enable)をサポートし、局所的な更新が可能です。
- 初期化とコンテンツロード:FPGAビットストリームにBRAM初期値を埋め込める機能があり、COEファイル(Xilinx)などでROM的に初期化することが可能です。また、起動時に外部からロードする手法もあります。
- エラー検出・訂正(ECC/パリティ):一部のFPGA世代ではBRAMに対してパリティやECCをサポートしており、信頼性向上に寄与します(対応有無はデバイス世代に依存)。
代表的ベンダ実装(概略)
- Xilinx:7シリーズではBRAM18(18Kb)、BRAM36(36Kb)が基本。Vivadoはこれらを組み合わせて希望の幅/深さでBRAMを「推論(inference)」します。UltraScale/UltraScale+世代にはBRAMに加えて、より大容量のURAM(UltraRAM)といった大容量オンチップメモリも存在します。
- Intel(旧Altera):デバイス世代によりM4K、M9K、M10K、M20Kなどのブロックがあり、それぞれ容量・機能が異なります。Quartusの合成は記述に応じてブロックを自動的に割り当てます。
設計上の注意点とベストプラクティス
- 推論と無駄な断片化を避ける:小さな配列を大量に定義すると論理的にはBRAMでなくLUT-RAM(ロジックに実装される小容量RAM)に割り当てられたり、BRAMを細切れに使ってしまい効率が悪くなります。必要な幅と深さを検討し、ツールのレポートで割り当てを確認してください。
- 読み出しレイテンシの把握:BRAMはクロック同期なので、読み出しの結果が出力に現れるまでサイクル遅延があります(1サイクル以上)。タイミング設計やパイプライン挿入時にこのレイテンシを考慮する必要があります。
- クロック境界(CDC):デュアルポートBRAMを異なるクロックで使う場合、クロックドメイン間の同時アクセスや競合の取り扱いに注意が必要です。多くのBRAMは異クロック動作をサポートしますが、メモリの一貫性ルールを設計で保証することが重要です。
- 同時書き込み競合対策:同一アドレスへの同一サイクル書き込みはルールがベンダ/モードに依存します。意図しないデータ破壊を回避するため競合が起きないアーキテクチャにするか、明示的に仲裁を入れてください。
- 大容量要求時はURAMや外部DDRを検討:BRAMはオンチップで高速ですが容量は限られます。数メガビット以上のストレージが必要ならUltraRAM(Xilinx)や外付けDDR/DRAMを用いるのが一般的です。
よくある用途
- FIFO(ポインタ制御+メモリ保存)
- バッファリング(ビデオラインバッファ等)
- ルックアップテーブル(大容量ROM的利用)
- データ共有用の低レイテンシバッファ(複数演算ユニット間)
- アルゴリズム中間データの保持(畳み込みバッファ、DSPとの連携)
BRAMの推論(inference)とHDL記述
通常、Verilog/VHDLで同期配列(reg/array)を記述すると、合成ツールが可能な場合BRAMへ自動割当します。ただし推論されるかどうかは記述方法(読み出し/書き込みの同期性、アドレス幅、初期化方法)に左右されます。推論が期待通りでないときはベンダのBRAMプリミティブ(Xilinxのblock RAM primitives)を直接使ったり、IPカタログのメモリコアを用いることで確実な制御が可能です。
パフォーマンスと消費電力
BRAMは外付けDRAMに比べレイテンシが低く、消費電力も一般的に低めですが、アクセス密度が高い場合は電力が増加します。クロックの有無やリード/ライトの比率で消費電力は変わるため、低消費電力設計では必要なアクセスだけを行う工夫(クロックゲーティングやバンク分割)が有効です。
まとめ
BRAMはFPGA設計における重要な資源で、高速で信頼性の高いオンチップメモリを提供します。設計時はブロック容量、ポート構成、同期特性、推論のされ方、クロック境界、同時アクセスのルールなどを理解し、ツールのレポートやデバイスデータシートを基に最適化することが重要です。大容量要件や高信頼性が求められる用途ではURAMや外部メモリ、ECC機能の活用も検討してください。
参考文献
- Xilinx — 7 Series FPGAs Memory Resources (UG473)
- Xilinx — Memory and Storage on FPGA
- Intel FPGA — Embedded Memory Resources
- Wikipedia — Field-programmable gate array
- Digilent — Using Block RAM (tutorial)


