この記事では、DRAM の基本的な構成と、MIG とアプリケーション回路の間に設けるユーザインタフェースと呼ばれるモジュールについて解説していきます。前回の記事のように、説明では、Micron 社の DDR3 SDRAM MT41K128M16JT-125 という 256MB DRAM チップを搭載する Arty A7-35T FPGA ボードを想定します。
DRAM の基本的な構成
下図は DRAM ベースのメモリシステムの一般的な構成を示しています。
6つの階層があります。トップダウンで説明します.
- チャネル (Channel): 最上の階層。各チャネルは複数のモジュール (module) から構成されます。図1の例では、メモリシステムは2つのチャネルから構成され、各チャネルは2つのモジュールを持ちます。
- モジュール (Module): いくつかの種類がありますが、DIMM (Dual In-line Memory Module) が一般に使われています。コンピュータのマザーボードのメモリスロットに刺されるものはこれです。各 DIMM は表 (front) と裏 (back) の2つのランク (rank) から構成されます。
- ランク (Rank): 各ランクは複数のチップ (chip) から構成されます。図1の例では、各ランクは8個のチップを持ちます。
- チップ (Chip): 各チップは複数のバンク (bank) という2次元ストレージアレイから構成されます。図1の例では、各チップは8個のバンクを持ちます。
- バンク (Bank): 2次元ストレージアレイ。図1の例では、各バンクのサイズは 2n行 (row) ✕ 2m列 (column) です。
- 行/列 (Row/Column): 最下位の階層。
Arty A7-35T FPGA ボードが搭載する DRAM メモリは1個のチップ (MT41K128M16JT-125) だけなので、チャネル数、モジュール数、ランク数を1とみなすことができます。
次の図は DRAM チップ MT41K128M16JT-125 の内部の概要を示しています。
この DRAM チップは8つのバンクを持ちます。各バンクのサイズは 16,384 ✕ 1,024 です。バンクの各セルは 2-byte (16-bit) のデータを格納します。データアクセスの手順は以下の通りです。
- まず、バンクアドレス (bank address: 3-bit) でどのバンクにアクセスするかを決定します。
- 次に、行アドレス (row address: 14-bit) でアクセスの行を選択します。各行は 1-bit のイネーブル信号に関連付けられ、この信号が1にセットされたら、対応する行のデータ書き込み・読み出しが行われます。行アドレスからの全ての行のイネーブル信号を生成するために、バイナリデコーダが利用されます。
- 最後に、列アドレス (10-bit) で選択した行の対応するセルのデータアクセスを行います。
一般に、行アドレスと列アドレスは同一のピンを使って時分割されてDRAM チップに入力されます。MT41K128M16JT-125 の場合、行アドレスと列アドレスのビット幅はそれぞれ 14-bit と 10-bit なので、必要となるアドレスのピン数は 14 です (前回の記事の図2の ddr3_addr 信号に接続されるピン)。
MIG とアプリケーション回路の間のインタフェース
前回の記事で説明したように、MIG とのやり取りが複雑なため、アプリケーション回路 (user design) と MIG の間にユーザインタフェース (User Interface) と呼ばれるモジュールを設けます。以下では、MIG とユーザインタフェースの間のやり取りを説明します。
基本的な動作
次の図は MIG とユーザインタフェース (User Interface) の間のやり取りのための主要な信号を示しています。
ユーザインタフェースは MIG に対して「コマンド」でデータの書き込み・読み出しを行います。コマンドは app_cmd という3ビットの信号で指定されます。
- app_cmd = 3’b000 → 書き込みコマンド
- app_cmd = 3’b001 → 読み出しコマンド
ユーザインタフェースは、コマンドを発行するとき app_en をアサートします (1にセットします)。app_rdy がアサートされているときだけ、MIG はコマンドを受け付けることができます。
書き込み・読み出しのアドレスは app_addr 信号で指定されます。app_addr のビット幅はランク、バンク、行、列のアドレスのビット幅の合計です。MT41K128M16JT-125 DRAM チップの場合、ランク、バンク、行、列のアドレスのビット幅はそれぞれ 1-bit (ランク数=1のため), 3-bit, 14-bit, 10-bit なので、app_addr のビット幅は 28-bit になります。次回の記事で詳細な実装を説明しますが、app_addr でのランク、バンク、行、列のアドレスを次の図の順番にします。
データアクセスのバンド幅を向上するために、DRAM チップは一般に、バースト (burst) モードで動作します。これは、1つのコマンドで、複数の連続のセル (行・列アドレスによって決められたバンクの1個のセル)のデータのアクセスを行うことを意味します。
アクセスされる連続のセルの数はバースト長 (burst length) と呼ばれます。7-series (Arty A7-35T ボードに搭載する FPGA のファミリ) FPGA 用の MIG はバースト長=8しかサポートしません。
上記に説明したように MT41K128M16JT-125 DRAM チップのデータバスのビット幅は 16-bit ですが、バースト長=8なので、MIG とユーザインタフェースの間の書き込みデータ (app_wdf_data)、読み出しデータ (app_rd_data) のビット幅は 8*16-bit=128-bit です。
書き込み: app_rdy がアサートされるときに、MIG がコマンドを受け付けることができますが、書き込みの場合は、MIG の内部のバッファの状態により書き込みデータをすぐに受け付けないケースがあります。このとき、ユーザインタフェースは待たないといけません。app_wdf_rdy はそのための信号です。ユーザインタフェースは MIG に書き込みデータ app_wdf_data を送るとき、app_wdf_wren をアサートします。app_wdf_data のビット幅は 128-bit (16-byte) ですが、バイトの単位でマスクする (書き込みを行わない) ことができます。これを app_wdf_mask という16ビットの信号で指定します。例えば、app_wdf_mask[0] を1に設定すれば、app_wdf_data[7:0] が無視されます。
読み出し: MIG は DRAM から読み出されたデータを app_rd_data 信号でユーザインタフェースに転送します。app_rd_data_valid は app_rd_data が有効かどうかを示します。
バーストモードでのアドレスの指定方法
バーストモードの動作は JDEC 半導体技術協会の標準規格で規定されています。ユーザの観点からは、アドレスの指定方法が特に重要です。
上記に説明したように、Arty A7-35T ボードに搭載する FPGA 用の MIG はバースト長=8だけをサポートしているので、以下では、バースト長=8を想定します。他のバースト長の場合も同様です。
書き込み
指定された列アドレスの最下位の3ビット (図4では app_addr[2:0]) の値に関係なく、app_wdf_data はいつも以下のように DRAM に書き込まれます。
- app_wdf_data[15:0]: アドレス {app_addr[27:3], 3’b000} のセルに書き込み
- app_wdf_data[31:16]: アドレス {app_addr[27:3], 3’b001} のセルに書き込み
- app_wdf_data[47:32]: アドレス {app_addr[27:3], 3’b010} のセルに書き込み
- app_wdf_data[63:48]: アドレス {app_addr[27:3], 3’b011} のセルに書き込み
- app_wdf_data[79:64]: アドレス {app_addr[27:3], 3’b100} のセルに書き込み
- app_wdf_data[95:80]: アドレス {app_addr[27:3], 3’b101} のセルに書き込み
- app_wdf_data[111:96]: アドレス {app_addr[27:3], 3’b110} のセルに書き込み
- app_wdf_data[127:112]: アドレス {app_addr[27:3], 3’b111} のセルに書き込み
読み出し
指定された列アドレスの最下位の3ビット (図4では app_addr[2:0]) の値によって、DRAM から返されるデータ (app_rd_data) の対応するセルの順番が決められます。
ここでは説明を簡単にするために、アドレス {app_addr[27:3], 3’b000} のセルをセル0、アドレス {app_addr[27:3], 3’b001} のセルをセル1、…、アドレス {app_addr[27:3], 3’b111} のセルをセル7とします。app_addr[2:0]=k とすると、 app_rd_data の対応するセルの順番は k から始まり順次インクリメントしますが、次の赤色と青色で示すように4セルの単位で、3と7の後にラップアラウンドします (3の後が0, 7の後が4となります)。
例えば、app_addr[2:0]=3 (3’b011) のとき、DRAM から返されるデータは以下のようになります。
- app_rd_data[15:0]: アドレス {app_addr[27:3], 3’b011} のセル(セル3)のデータ
- app_rd_data[31:16]: アドレス {app_addr[27:3], 3’b000} のセル(セル0)のデータ
- app_rd_data[47:32]: アドレス {app_addr[27:3], 3’b001} のセル(セル1)のデータ
- app_rd_data[63:48]: アドレス {app_addr[27:3], 3’b010} のセル(セル2)のデータ
- app_rd_data[79:64]: アドレス {app_addr[27:3], 3’b111} のセル(セル7)のデータ
- app_rd_data[95:80]: アドレス {app_addr[27:3], 3’b100} のセル(セル4)のデータ
- app_rd_data[111:96]: アドレス {app_addr[27:3], 3’b101} のセル(セル5)のデータ
- app_rd_data[127:112]: アドレス {app_addr[27:3], 3’b110} のセル(セル6)のデータ
app_addr[2:0]=5 (3’b101) のとき、DRAM から返されるデータは以下のようになります。
- app_rd_data[15:0]: アドレス {app_addr[27:3], 3’b101} のセル(セル5)のデータ
- app_rd_data[31:16]: アドレス {app_addr[27:3], 3’b110} のセル(セル6)のデータ
- app_rd_data[47:32]: アドレス {app_addr[27:3], 3’b111} のセル(セル7)のデータ
- app_rd_data[63:48]: アドレス {app_addr[27:3], 3’b100} のセル(セル4)のデータ
- app_rd_data[79:64]: アドレス {app_addr[27:3], 3’b001} のセル(セル1)のデータ
- app_rd_data[95:80]: アドレス {app_addr[27:3], 3’b010} のセル(セル2)のデータ
- app_rd_data[111:96]: アドレス {app_addr[27:3], 3’b011} のセル(セル3)のデータ
- app_rd_data[127:112]: アドレス {app_addr[27:3], 3’b000} のセル(セル0)のデータ
結論
今回は、DRAM の基本的な構成と MIG とユーザインタフェースとの間のやり取りを説明しました。バーストモードでのアドレスの指定方法が特に重要であることに注意してください。
次回は、Vivado で MIG を生成する方法と DRAM コントローラ全体の Verilog HDL の実装を解説していきます。
東工大 Thiem Van Chu