HN 日本語サマリー

← 一覧へ戻る
プログラミング

DRAMインターフェースとPHY(DDR3+インターフェースが起動時にチューニングされる理由)

The DRAM interface and the PHY (why a DDR3+ interface must be tuned at boot) (github.com)

9 pointsby peter_d_sherman0 コメント

要約

この記事は、FPGAとDRAM間の配線で何が起こるのか、そしてDRAMインターフェースが起動時にチューニングされる必要がある理由を解説します。信号、ストローブ、ボードトポロジー、レベリング手順、終端、基準電圧、そしてコントローラとPHY間のクロックとDFIインターフェースを網羅しています。各セクションでは、LiteDRAMにおける対応する実装部分も紹介しています。

全文翻訳

03_dram_interface.md

DRAMインターフェースとPHY {#dram-interface}

この章では、FPGAとDRAM間の配線で何が起こるのか、そしてDRAMインターフェースが起動時にチューニングされる必要がある理由を説明します。信号、ストローブ、ボードトポロジー、レベリング手順、終端、基準電圧、そしてコントローラとPHY間のクロックとDFIインターフェースを網羅します。

各セクションの最後には、LiteDRAMでそのメカニズムを実装している部分が示されています。前の章であるDRAMの概要ではコマンドとタイミングについて説明し、初期化とキャリブレーションではBIOSが実行する正確な手順を示しています。

信号 {#iface-signals}

DRAMインターフェースは2つの部分からなります。「コマンドとアドレス」の部分はコントローラからDRAMへ一方向で、ランク内のすべてのチップで共有されます。「データ」の部分は双方向で、「バイトレーン」に分割され、それぞれに独自のストローブがあります。以下の図に信号を示します。

[画像: FPGAとDRAM間の信号。PHYはクロック、コマンド、制御ピンを送信します。データ(DQ、DM)とストローブ(DQS)は両方向で、バイトレーンごとに1つのストローブがあります。]

信号方向役割
CK, CK#DRAMへ差動クロック; コマンドはその立ち上がりエッジでサンプリングされる
CS#, RAS#, CAS#, WE#DRAMへコマンドエンコーディング; ACT_nはDDR4で追加される
A, BA, BGDRAMへ行または列アドレス、バンク、バンクグループ(DDR4)
CKEDRAMへクロックイネーブル; 電源オフおよびセルフリフレッシュ時はロー
ODTDRAMへDRAMのデータピンの終端をオンにする
RESET#DRAMへリセット(DDR3以降)
DQ両方向データ、チップあたり4、8、または16
DQS, DQS#両方向データストローブ、バイトレーンあたり1つの差動ペア(x4チップではニブルあたり)
DMDRAMへデータマスク、バイトレーンあたり1つ:書き込み中にバイトをマスクする

バイトレーンは8つのDQ、それらのDQSペア、およびDMで構成されます。各レーンは独自にルーティングされるため、それぞれがわずかに異なる時間に到着する可能性があり、それぞれが個別にチューニングされます。

LiteDRAMでは、DRAMのパッドはプラットフォームファイルからのレコードであり、これらの信号(dq、dqs_p、a、ba、cs_n)にちなんで名付けられたフィールドがあります。PHYはそこからレーンを数えます。litedram/common.pyの2つのヘルパーがパッドを整形します。PHYPadsReducerは一部のレーンのみを保持し、PHYPadsCombinerは個別のコマンドバスを持つチップを1つのコントローラにマージします。

ダブルデータレートとストローブ {#iface-dqs}

SDRメモリはクロックごとに1ワードを転送し、コントローラが送信するクロックの立ち上がりエッジでサンプリングします。DDRメモリはクロックごとに2つのワードを転送し、各エッジで1つずつ転送します。このレートでは、コントローラからのクロックはデータのサンプリングを信頼できません。ボードとチップの遅延が大きすぎるためです。

したがって、データは独自のクロックであるストローブDQSと共に転送されます。データを送信する側がDQSも送信し、受信側はDQSでDQをサンプリングします。これはソース同期インターフェースです。両者は同じパスを移動するため、遅延は相殺されます。以下の図は、DQSがDQとどのように整列されるかを示しています。

[画像: DQS対DQ。DQSエッジから下の点線に沿って追ってください:書き込み時(左)は各エッジがデータビットの中央に落ち、DRAMがサンプリングする準備ができています。読み出し時(右)は各エッジがビット遷移に落ち、受信側はサンプリング前にDQSをクロックの1/4だけ遅延させる必要があります。]

書き込み時、コントローラはDQSをDQに対して中央揃えで送信し、そのエッジは各ビットの中央にあります。読み出し時、DRAMはDQSをエッジ揃えでビット遷移上に送信し、受信側はそれを1/4クロック遅延させてサンプリングします。バーストの前には、DQSはプリアンブルのために駆動され、後にはデータを持たないポストアンブルのために駆動されます。

LiteDRAMでは、DDR PHYはFPGAの手段を用いて、書き込みDQSをDQから1/4クロックシフトします。

  • Artix-7 PHYは、ターゲットが構築する(bench/arty.py)クロックsys4x_dqsから90度シフトされたクロックでDQSシリアライザをクロックします。
  • 出力遅延を持つPHY(Kintex-7およびVirtex-7 HPバンク、UltraScale)は、DQSを1/4クロック遅延させます。
  • LatticeおよびGowin PHYは、FPGAのDQSブロックのシフトされた書き込みクロックを使用します。

読み出し時、PHYは異なります。

  • Xilinx PHYはDQSを使用しません。それらは、読み出しレベリングがレーンごとにチューニングする入力遅延を通じて、独自の高速クロックでDQをサンプリングします。
  • LatticeおよびGowin PHYは、FPGAのDQSブロックを使用します。これはDQSを90度遅延させ、それを使用してDQをキャプチャし、バーストを見たときに報告します(バースト検出)。

フライバイ・トポロジーとライトレベリング {#iface-flyby}

DDR3およびDDR4は、クロック、コマンド、アドレスピンを、各チップを順番に通過し終端で終わる1つのバスとしてルーティングします。これはフライバイトポロジーです。これにより、高レートでもこれらの負荷の高い信号をクリーンに保てますが、各チップは前のチップよりもわずかに遅れてクロックを受信します。以下の図にそれを示します。

[画像: フライバイ・トポロジー。クロック、コマンド、アドレスはチップを次々と通過し、終端(VTT)で終わります。データレーンはポイント・ツー・ポイントです。各チップは前のチップよりも遅れてクロックを受け取りますが、データレーンは独自の長さを持っています。]

データレーンはポイント・ツー・ポイントであるため、その遅延はクロックに従いません。チップはDQSが自身のCKエッジ(tDQSS)の近くに到着する必要があります。フライバイ・ルーティングでは、最初と最後のチップ間のスキューはクロック期間を超える可能性があるため、各レーンは独自のDQS遅延を必要とします。

ライトレベリングはその遅延を測定します。コントローラはモードレジスタビット(DDR3およびDDR4のMR1ビットA7)でDRAMをライトレベリングモードに設定し、次にDQSパルスを送信します。DRAMは各DQS立ち上がりエッジでCKをサンプリングし、サンプリングされた値をDQで返します。コントローラはDQが0から1に変わるまでDQSをステップごとに遅延させます。これにより、そのチップでのDQSがCKと整列されます。

LiteDRAMでは、PHYはレジスタを通じてライトレベリングを公開します。wlevel_enはモードを有効にし、wlevel_strobeは1つのDQSパルスを送信し、レーンごとの出力遅延はDQSとDQを移動させます。BIOSはスキャンを実行します(liblitedram内のsdram_write_leveling)。

ライトレベリングには出力遅延が必要です。Kintex-7およびVirtex-7のHPバンクのPHYとUltraScale PHYにはそれがあります。Artix-7にはありません。1つの静的なDQSフェーズでは、フライバイメモリのレーンの一部のみがtDQSSを満たします。オプションのCKフェーズシフトモード(DDR3で1:4)は、CKをすべてのレーンに対して移動させます(CKフェーズシフト)。

書き込みレイテンシとDQ-DQSトレーニング {#iface-write-latency}

ライトレベリングは、DQSを1クロック期間内でCKに整列させますが、レーンは丸1クロック早くまたは遅れる可能性があります。その場合、DRAMはバーストを数ワードずらして書き込みます。書き込みレイテンシキャリブレーションは、既知のパターンを書き込み、それを読み戻し、パターンが正しくなるまで各レーンをクロック単位で移動させます。

DQ-DQSトレーニングは、書き込み時にDQをDQSに対して中央揃えにします。各レーンのDQピンの出力遅延をスイープし、各ステップでパターンを書き込み・読み戻し、通過範囲の中央を保持します。これは、読み出し側の動作に依存し、その後読み出しレベリングによってさらに調整されます。

LiteDRAMでは、書き込みレイテンシは書き込みビットスリップ(wdly_dq_bitslip)によって移動され、DQは出力遅延(wdly_dq)によって移動されます。各PHYは、サポートするキャリブレーションをその設定(write_leveling、write_latency_calibration、write_dq_dqs_training、read_leveling)で宣言します。BIOSはそれらのみを実行します。

読み出しレベリング {#iface-read-leveling}

読み出し時、コントローラはデータがいつ到着するかを知りません。DRAMはRDのCLクロック後に応答しますが、ボードとI/Oはレーンごとに異なる遅延を追加します。各レーンには2つの設定を見つける必要があります。1つ目は、高速クロックサイクルで最初のワードを保持する粗い設定、2つ目はビットのどこでサンプリングするかを決定する細かい設定です。

粗い設定はビットスリップです。デシリアライザの出力は、ワードが整列されるまでビット単位でシフトされます。細かい設定は入力遅延で、FPGAによって異なりますが、数百ピコ秒から約100ピコ秒まで(7シリーズで200 MHz基準の場合、78 ps)です。読み出しレベリングはパターンを書き込み、次に各ビットスリップに対して遅延をスイープし、パターンを読み戻します。以下の図は、そのようなスキャンを示しています。

[画像: 読み出しレベリングスキャン、1レーンの例。各ビットスリップに対して遅延タップがスイープされ、各読み出しがチェックされます:シアンのタップは正しいデータを返しました。BIOSは最も広い通過ウィンドウを持つビットスリップを保持し、その中央に遅延を設定します(緑)。]

ウィンドウは、遅延ラインを通して見えるデータアイです。広いウィンドウは堅牢なインターフェースを意味し、狭いウィンドウは信号整合性またはクロッキングの問題を示唆します。DDR3およびDDR4は、MPR(多目的レジスタ)から固定パターンを返すこともできるため、読み出し側は何も書き込まれる前にチューニングできます。

DQSでキャプチャするPHYは、もう1つの問題を抱えています。DQSはバースト間では駆動されないため、受信側は読み出し中のみそれに注意を払う必要があります。FPGAのDQSブロックは、このゲートを開き、バースト検出を報告します。これは読み出しレベリングが読み出しウィンドウが正しいことを確認するために使用します。

LiteDRAMでは、各PHYは遅延タップ数とビットスリップ数をその設定(delays、bitslips)で宣言し、レジスタ(LatticeおよびGowin PHYではrdly_dq_inc、rdly_dq_bitslip、burstdet_seen)を通じて公開します。BIOSはスキャンを実行し、レーンとビットスリップごとに1行印刷します。DDR4では、登録済みDIMMとクラムシェルレイアウトを除き、MPRパターンを読み取ります。

終端とドライブ強度 {#iface-odt}

DRAMレートでは、終端されていないラインの終端で信号が反射します。したがって、DRAMはオンダイ終端(ODT)で自身のデータピンを終端します。これは、ODTピンが高のときにオンになる抵抗です。FPGAは、読み出しデータを受信するときに同様の方法で入力終端を行います。

DDR3およびDDR4には2つの終端値があります。RTT_NOMはチップがアイドル状態の場合や別のランクが書き込まれる場合に使用され、RTT_WRはチップ自体が書き込まれている間(ダイナミックODT)に使用されます。DRAMのドライバ強度であるRONは、読み出しデータをどれだけ強く駆動するかを設定します。これら3つすべてがモードレジスタで設定されます。

設定DDR3デフォルトDDR4デフォルトモードレジスタ
RTT_NOM60オーム40オームMR1
RTT_WR60オーム120オームMR2
RON34オーム34オームMR1

LiteDRAMでは、テーブルのデフォルト値はlitedram/init.pyで設定されます。PHYはそれをオーバーライドできます(設定内のrtt_nom、rtt_wr、ron)。DRAM DLLオフ、低クロックレート用のDDR3モード(GW5A PHYが提供するdll_off)では、両方の終端が無効になります。

ODTピンはデフォルトで静的に駆動されます。with_dynamic_odt(DDR3、シングルランク)を使用すると、コントローラは書き込みの周りのみODTを上げます。そのため、読み出し中はDRAM終端はオフになります(ダイナミックODT)。FPGA側の終端は、LiteDRAMではなく、プラットフォームファイルのI/O標準の一部です。

ZQキャリブレーション {#iface-zq}

チップのドライバと終端の抵抗は、プロセス、電圧、温度によって変動します。DDR3以降のチップは、ZQピンにある240オームの抵抗に対してこれらをキャリブレーションします。ZQCL(ロングキャリブレーション)は初期化時に一度実行されます。ZQCS(ショートキャリブレーション)は、動作中に時々ドリフトを補正します。

LiteDRAMでは、初期化シーケンスはZQCLで終了し(モードレジスタと電源投入)、リフレッシャはデフォルトで1秒に1回ZQCSを送信します(リフレッシュ)。LPDDR4にはZQCSがありません。初期化時のみLiteDRAMが送信する2つの多目的コマンド(MPC)、スタートとラッチでキャリブレーションします。

基準電圧 {#iface-vref}

データ受信機は、各入力を、ハイレベルとローレベルの中間にある基準電圧VREFと比較します。DDR3では、ボードが専用ピンでVREFを提供します。DDR4はデータピンを電源(疑似オープンドレイン)に終端するため、データスイングは電源の上部に近く、正しい基準は中間ではありません。DRAMはMR6でプログラムされた内部でデータVREFを生成します。

FPGA側では、読み出しデータの受信機にもVREFが必要です。一部のFPGA I/Oバンクは、VREFピンを使用する代わりに、内部で段階的に設定できます。

LiteDRAMでは、DDR4初期化はtCCD_LのみでMR6を書き込み、VREFフィールドをゼロ(範囲1の最初の値、VDDQの60%)のままにします。DRAMデータVREFはトレーニングされません。

UltraScale+ PHYは、HP I/OバンクのFPGA読み出しVREFを設定できます(with_hpio_vref、レジスタrd_vref、コード0から72)。BIOSはそれをスキャンしません。ソフトウェアが書き込まない限り、レジスタはビルド時の値(hpio_vref_tune)を保持します。LiteX issue 2769は、不足しているBIOSスキャンを追跡しています。

クロックと周波数比 {#iface-clocking}

FPGAファブリックはDRAMクロックで実行できません。800 MT/sのDDR3は400 MHzクロックを持ち、ピンあたり800 Mbpsでデータを移動します。したがって、PHYはFPGA I/Oのシリアライザとデシリアライザを使用します。コントローラはDRAMクロックの分数で実行され、サイクルあたり数クロック分のコマンドとデータを移動します。

この分数が周波数比です。1:4の場合、コントローラはDRAMクロックの1/4で実行されます。Arty A7ベンチターゲットは、コントローラを125 MHz、DRAMクロックを500 MHz、DDR3を1000 MT/sで実行します。DDRメモリの場合、データレートはDRAMクロックの2倍です。1:4では、コントローラクロックの8倍になります。

Artix-7 DDR3ターゲットは、ボードのクロックモジュールのPLL(bench/arty.py)によって生成される4つのクロックを必要とします。Kintex-7およびVirtex-7ターゲットはsys4x_dqsを必要としません。それらの出力遅延は代わりにDQSをシフトします。

クロック周波数使用目的
sysコントローラクロックコントローラ、DFI、シリアライザの並列側
sys4xsysの4倍シリアライザのシリアル側:CK、コマンド、DQ
sys4x_dqssysの4倍、90度DQSシリアライザのシリアル側(Artix-7)
clk200200 MHz入出力遅延の基準(IDELAYCTRL)

他のファミリーは独自のクロッキングを使用します。ECP5 PHYは、I/Oゲーティングのために2倍クロック、1:4で4倍クロックを使用し、Gowin GW5A PHYはフェーズ数で1:2または1:4を選択します。DDR PHYsは、各ファミリーのクロックを示しています。

DFI、コントローラとPHY間のインターフェース {#iface-dfi}

コントローラとPHYは、DDR PHY Interface仕様にちなんで名付けられたDFIインターフェースで接続されます。これは、コントローラサイクルの各DRAMクロックに対して、1つのコマンドスロットと、そのクロックのデータを運びます。これらのスロットのそれぞれがDFIフェーズです。以下の図は、1:4比率でのフェーズを示しています。

[画像: 1:4でのDFIフェーズ。図を列ごとに読みます:1つのコントローラクロック(sys)は4つのDRAMクロックにまたがり、DFIフェーズNはDRAMクロックNのコマンドスロットと2つのデータビートを運びます。8のバーストは1つのコントローラクロックを占有します。コマンドのデータは、読み書きレイテンシの後、後続のコントローラクロックで移動します。]

DFI信号方向内容
address, bankPHYへ行または列アドレス、バンク(DDR4ではバンクグループも)
ras_n, cas_n, we_n, cs_n, act_nPHYへコマンドエンコーディング
cke, odt, reset_nPHYへ制御ピン
wrdata, wrdata_maskPHYへ書き込みデータとバイトマスク、フェーズあたり2ビート
wrdata_enPHYへ書き込みデータ有効、書き込みレイテンシと共に送信される
rddata_enPHYへこのフェーズで読み出しが発行された
rddata, rddata_validコントローラへ読み出しデータとその有効フラグ

2つのレイテンシがコマンドをデータに結び付けます。書き込みレイテンシは、WRとコントローラが書き込みデータを提示するサイクルとの間のコントローラサイクルの数です。読み出しレイテンシは、RDと読み出しデータが有効になって戻ってくるサイクルとの間のサイクル数です。どちらもCL、CWL、およびPHYのパイプラインから導き出されます。

コマンドは常にフェーズ0で開始されるわけではありません。PHYは、読み書きを発行するフェーズをコントローラに通知します(rdphase、wrphase)。これにより、バーストのデータが完全なコントローラサイクルを埋めるようになります。

LiteDRAMでは、DFIインターフェースはlitedram/phy/dfi.pyのInterfaceです。DFI仕様の構造、フェーズ、信号名に従いますが、そのバージョンを主張するものではありません。

各PHYは、フェーズ数、コントローラサイクルでのレイテンシ、DRAMクロックでのCLとCWL、およびキャリブレーション機能を備えたPhySettingsを埋めます。DFIRateConverterは、より多くのフェーズとフェーズあたりの狭いデータ幅で比率を上げるためにPHYをラップします。コアアーキテクチャを参照してください。

各FPGAファミリーが提供するもの {#iface-fpga}

各PHYは、FPGAファミリーのI/Oプリミティブから構築されます。以下の表は、LiteDRAM PHYが使用するものをまとめたものです。DDR PHYsは、各ファミリーについて説明しています。

ファミリーシリアライザ遅延タップビットスリップ読み出しキャプチャ
Xilinx 7-SeriesOSERDESE2, ISERDESE2328高速クロック、DQごとの入力遅延
Xilinx UltraScale(+)OSERDESE3, ISERDESE35128高速クロック、DQごとの入力遅延
Lattice ECP5ODDRX2DQA, IDDRX2DQA84DQSBUFM, バースト検出
Lattice NexusODDRX2DQ, IDDRX2DQ164DQSBUF, バースト検出
Gowin GW2AOSER4_MEM, IDES4_MEM2564DQSブロック, バースト検出
Gowin GW5AOSER4_MEM, IDES4_MEM (1:2), OSER8_MEM, IDES8_MEM (1:4)2564 または 8DQSブロック, バースト検出

7シリーズの入出力遅延は、200 MHzまたは300 MHz、あるいはより高速なスピードグレードでは400 MHzの基準クロックを必要とします。出力遅延はKintex-7およびVirtex-7のHPバンクにのみ存在します。UltraScaleの遅延は時間単位で設定され、en_vtcが設定されている間、FPGAは電圧と温度に対してそれらを補償します。

次へ:BIOS手順については初期化とキャリブレーション、各ファミリーについてはDDR PHYs、スキャンでウィンドウが表示されない場合のデバッグについてはデバッグを参照してください。