DeepLearning/FPGAなどを勉強する人

興味のあることを書く

Top

このブログはなんですか

Talk of tech innovation is bullsh*t. Shut up and get the work done – says Linus Torvalds

Deep Leaning 勉強用ブログ - DeepLearning/FPGAなどを勉強する人

備考

諸事情により8月中は更新なし

DDR3 SDRAM: Auto Self Refresh/Self Refresh Temperature

DDR3 SDRAMに関するメモ的なもの(特にDDR3L-1333)。

図は全て以下のMicronのドキュメントからの引用であり、このメモの内容もこれを参照する。
2Gb: x4, x8, x16 DDR3L SDRAM

以下も参照。
DDR3 SDRAMにおけるコマンドとオペレーション - Wikipedia

Auto Self Refresh/Self Refresh Temperature

通常のケース温度\rm T_Cの範囲は0 \sim 85 \ {}^\circ\mathrm{C}だが、拡張温度範囲85 \sim 95 \ {}^\circ\mathrm{C}まで利用するときにself refresh動作を保証するために必須な機能(ちなみにこの機能はオプショナル)。
設定方法に関してはモードレジスタのところでまとめる。

まず、拡張温度範囲でのDRAMは手動でdouble refresh(2倍のレートでのrefresh)を行う必要がある。 double refreshは通常の周期62msを32msにすれば良い。
しかし、self refreshモードにおいては、拡張温度範囲をサポートするためにASRかSRTのいずれかが必要になる。つまり、どちらかを有効にしなければ、拡張温度範囲でself refreshモードは使用できない。

Auto Self Refresh (ASR)

SRTが無効の状態で、ASRが無効の場合、self refreshモードのrefresh rateは常に通常の1x refresh rate(85 \ {}^\circ\mathrm{C}もの)が選択されることになり、ユーザはself refreshモード中は\rm T_C85 \ {}^\circ\mathrm{C}を超えないことを保証しなければならない。
ASRが有効であれば、\rm T_C85 \ {}^\circ\mathrm{C}を超えた時、(self refreshモード時の)refresh rateが自動的に1xから2xに切り替わる。これによって、DRAMは拡張温度範囲でのオペレーションが可能となる。

DRAMは1xから2xの切り替え時のデータ完全性(data integrity)は提供しているが、ASRはサポートされる温度範囲(0 \sim 95 \ {}^\circ\mathrm{C})内でのrefresh rateの自動調整を許していて、85 \ {}^\circ\mathrm{C}未満であっても切り替わりが起こる可能性がある。また、ちょうど85 \ {}^\circ\mathrm{C}の場合、常に1xから2xへ切り替わるとは限らない。

Self Refresh Temperature (SRT)

ASRと同様で、ASRが無効かつSRTも無効ならば、refresh rateは常に1xであり、self refreshモード中は\rm T_C85 \ {}^\circ\mathrm{C}を超えないことを保証しなければならない。
SRTが有効であれば、\rm T_Cに関わらず(self refreshモード時の)refresh rateは強制的に1xから2xに切り替わる。これによって、拡張温度範囲でのオペレーションが可能となる。

ASR vs. SRT

\rm T_C85 \ {}^\circ\mathrm{C}を超えないことを保証できるのであれば、どちらの機能も無効でよい。
しかし、拡張温度範囲でのオペレーションが必要ならば、self refreshモード時の正常なrefreshのためにASRかSRTのどちらか一方を有効にしなければならない(同時に有効にすることはできない)。

DDR3 SDRAM: Self Refresh

DDR3 SDRAMに関するメモ的なもの(特にDDR3L-1333)。

図は全て以下のMicronのドキュメントからの引用であり、このメモの内容もこれを参照する。
2Gb: x4, x8, x16 DDR3L SDRAM

以下も参照。
DDR3 SDRAMにおけるコマンドとオペレーション - Wikipedia

Self Refresh (SR)

Self Refresh Timing

Param. Symbol DDR3L-1333 Unit
Exit SR -> commands not requiring a locked DLL tXS \rm MIN=Greater(5CK, tRFC) CK
Exit SR -> commands requiring a locked DLL tXSDLL \rm MIN=tDLLK(MIN) CK
Min CKE low pulse width for SRE to SRX timing tCKESR \rm MIN=tCKE(MIN)+CK CK
Valid clocks after SRE or PDE tCKSRE \rm MIN=Greater(5CK,10ns) CK
Valid clocks before SRE,PDE,RE tCKSRX \rm MIN=Greater(5CK,10ns) CK

power-downモード中などでもDRAM内のデータを保持するためのモードで、SRモード中は外部クロックを必要としない。
このモードはDLLのenable/disable、クロック周波数の変更などに対しても便利なものとなっている。全ての電源、参照電圧はentry/exitとSRモード中は正当なレベルに保たれていなければならない。

SRモードへの突入と同時にDLLは自動的に無効となり、抜けるときに自動的にリセットされる。
SR entryのコマンドを発行する前に、DRAMはidle状態で全てのバンクはprechargeされた状態に(tRP経過していて、バーストが実行中でない)、また、ODTはoffにしておかなければならない。ただし、nominal ODT、dynamic ODTのどちらも無効であればODTはDon't Careでもいい。
SR entryコマンドが発行されたらCKEはLOWにしてSRモード中はLOWに保たなければならない。 
SRモードに入ると、CKEとRESET#以外の制御信号はDon't Careになる。DRAMはtCKE内(意味的にはSRモード中)で内部的に最小数のREFRESHコマンドを実行する。

SRモードのenter/exitに関する制約は、モード中のクロックの状態に依存する。
SRモード中、クロックが安定していて、周波数が変わらないならば、DRAMtCKESRを満たしたらSRモードから抜けることができる(この時、CKEはLOWとなったtCKESR後にHIGHにすることができる)。つまり、クロックが安定していて、周波数が変わっていないので、tCKSREとtCKSRXは要求されない。
一方で、クロックがSRモード中に変化する場合(offにするか、周波数が変わる場合)、tCKSREtCKSRXは満たさなければならない。SRモードに入るとき、クロックの周波数を変化させる前に、tCKSREはまず満たさなければならない。SRモードから抜けるtCKSRX前までに、クロックが安定してCKEがHIGHでなければならない。

SR exit中にCKEがHIGHになったら、tXSの間はNOP/DESコマンドを発行しなければならない。tXSは実行中の内部的なrefreshの完了のために必要で、DLLロックを必要としないコマンドが発行可能になる前に満たされなければならない。また、tXSはSRモードへのre-entry可能になる最小時間でもある。DLLロックが必要なコマンドの場合は、その前にZACLコマンドを発行しなくてはならず、tZQOperと、tXSDLLを満たさなければらない。また、tXSDLL中はODTのはoffでなければならない。
f:id:wanwannodao:20170907124008p:plain

DDR3 SDRAM: ZQ Calibration

DDR3 SDRAMに関するメモ的なもの(特にDDR3L-1333)。

図は全て以下のMicronのドキュメントからの引用であり、このメモの内容もこれを参照する。
2Gb: x4, x8, x16 DDR3L SDRAM

以下も参照。
DDR3 SDRAMにおけるコマンドとオペレーション - Wikipedia

ZQ Calibration

ZQはZero Quotientらしいが意味はわからない。

ZQ CalibrationはDRAM出力ドライバ\rm R_{ON}とODT値\rm R_{TT}の補正のための処理。
power-on時の初期化処理とself refreshから抜ける時における\rm R_{ON}\rm R_{TT}の補正には長い時間を、周期的な補正には比較的短い時間を要する。
ZQ Calibration LongZQ Calibration Shortが用意されている。

ZQ Calibration関連のタイミングは以下の通り。
Calibration Timing

Param. Symbol DDRL-1333 Unit
ZQCL:Power-up/RESET tZQinit 512 CK
ZQCL:normal operation tZQoper 256 CK
ZQCS tZQCS 64 CK

ZQ Calibration Long (ZQCL)

ZQCLはpower-up時の初期化中とリセット時における、初期補正のために使用されるが、システム環境によってコントローラからいつでも発行される可能性はある。
ZQCLはDRAM内部の補正回路(240Ω(\rm \pm 1\%)の外部抵抗がDRAMのZQ ballとV_{SSQ}に繋がっている)を起動し、補正が完了したら補正値を補正回路からDRAM I/Oへ転送され、更新後の\rm R_{ON}\rm R_{TT}として反映される。
初期化処理中にZQCLを発行する場合はtZQinitを、初期化後のZQCLコマンドはtZQoperを満たす必要がある。

ZQ Calibration Short (ZQCS)

ZQCSは、電圧と温度の細かい変化に対する周期的な補正に利用され、tZQCSで完了する。
ZQCSは最小で\rm 0.5 \% R_{ON}、R_{TT}インピーダンス誤差を64サイクルで効率的に修正可能。

ZQ Calibration Operation

ZQCLとZQCSを発行するには、全てのバンクがprechargeされていてtRP経過していなければならない。コントローラはtZQinit/tZQoper中はDRAMチャネルに対していかなる行動もしてはいけない。
この静止時間は補正精度を高めるために必要となっている。補正が完了したら、DRAMは電力削減のために補正回路の電流消費を無効にする。
ZQCL/ZQCSはDLL RESETコマンド、DLLのロック中と並行して発行することができる。self refreshから抜けるときは、ZQ Calibrationが必要であれば明示的なZQCLが必要。
ZQ抵抗(上記の外部抵抗)を共有しているようなデュアルランク構成の場合、コントローラはtZQinit、tZQoper、tZQCSをランク間でオーバーラップさせないようにしなければならない。
また、補正処理中は以下のことに気をつける。

  • CKEはHIGHに保たなければならない。
  • ODTは無効にしなければならない。
  • DQバスに繋がっている全てのデバイスをHigh-Zにしなければならない。

f:id:wanwannodao:20170907103545p:plain

DDR3 SDRAM: On-Die Termination

DDR3 SDRAMに関するメモ的なもの(特にDDR3L-1333)。

図は全て以下のMicronのドキュメントからの引用であり、このメモの内容もこれを参照する。
2Gb: x4, x8, x16 DDR3L SDRAM

以下も参照。
DDR3 SDRAMにおけるコマンドとオペレーション - Wikipedia
The Secrets of PC Memory: Part 3 | bit-tech.net

信号の反射

一般にメモリコントローラとメモリモジュールを繋ぐために利用されるスタブバス(stub bus)では、メインデータラインを各メモリモジュールのコネクタで分岐することで共有している。なぜスタブバスが利用されているかというと、設計を簡素化できるという利点があるため。
DDR1のスピードを超えると、それまでのマザーボード終端では信号の反射が深刻な問題となっていた。つまり、チップ端で発生した反射波が分岐を通してメインデータラインに達して波形品質を悪化させてしまう。メモリバスが高周波になると信号の異常を回復する余裕がなくなってしまうし、更により低電圧な圧縮された信号になると、基本的に弱く全てのジッタを取り除けなくなる。こうしたことから、スタブバスは高速データ転送には不向きとされていた。
その対策の一つとして、終端抵抗をデバイスの直近に置いて反射波を軽減するということが挙げられる。そこでDDR2からOn-Die Termination(ODT)というオンダイの動的な終端抵抗をチップ内部に置くことで、波形品質を確保している。

http://images.bit-tech.net/content_images/2008/02/the_secrets_of_pc_memory_part_3/odt-signal.png

ただし、この終端が効き過ぎてしまうと、メモリタイミングが不正確なときに(例えばオーバークロッキングした場合など??よくわからない)、データ信号自体が吸収されてしまう可能性がある。マザーボードによってはBIOS経由でODTの値を調整できるらしい。

On-Die Termination (ODT)

DDR3 SDRAMのODTは、x4/x8ならばDQDQS,DQS#、DMの、x16ならばDQ,UDQS,UDQS#、LDQS、LDQS#、UDM、LDMの終端抵抗のon/off制御を可能にさせるための機能である。目的としては、DRAMコントローラが各DRAMの内部終端抵抗を独立にon/offできるようにすることで、メモリチャネルのデジタル信号品質(signal integrity)を向上させるという事となる。(※DLLがdisbaleの環境では使用できない)
内部のODTコントロールロジックによって下図のようなスイッチが制御される。

f:id:wanwannodao:20170907035017p:plain

self refreshモード時、disable時はこの部分は無視される。
以下用いる記号の説明。

Symbol Description
\rm R_{TT} ODT termination resistance value
\rm R_{TT,nom} nominal ODT value
\rm R_{TT(WR)} dynamic ODT value
\rm R_{TT(EFF)} The actual effective termination

\rm R_{TT}はモードレジスタ経由で設定される。


ODTはnominal ODTdynamic ODTによって構成されていて、それぞれ同期非同期モードがある。非同期はprecharge power-down中にDLLがoffの場合や、DLLが同期中の時に起きる。また、nominal ODTは基本となる終端で、dynamic ODTはWRITE中のみ適用されるもので、\rm no \ R_{TT}または\rm R_{TT,nom}から\rm R_{TT(WR)}へのスイッチングを行う。
非線形な終端なので、\rm R_{TT(EFF)}\rm R_{TT}と同じになるとは限らない。


使用するタイミングは以下の通り。
ODT Timing

Param Symbol DDR3L-1333 Unit
\rm R_{TT,nom} synchronous turn-on delay ODTLon \rm CWL+AL-2CK CK
\rm R_{TT,nom} synchronous turn-off delay ODTLoff \rm CWL+AL-2CK CK
\rm R_{TT} turn-on from ODTLon tAON \rm MIN=-250;MAX=250 ps
\rm R_{TT} turn-off from ODTLoff tAOF \rm MIN=0.3;MAX=0.7 CK
ODT=HIGH time (BL8) ODTH8 \rm MIN=6 CK
ODT=HIGH time (BC4/without WRITE) ODTH4 \rm MIN=4 CK

CWL:CAS Write Latency, AL:Active Latency

Nominal ODT

\rm R_{TT,nom}が前述した出力ピンに適用される。DDR3 SDRAMでは\rm RZQ/nという形式で複数の抵抗値を選択することができる。ここで、n=2,4,6,8,12\rm RZQ=240Ω
\rm R_{TT,nom}での終端は、DARMが初期化され、補正された後で、リードアクセスを実行しておらず、self refreshモードでなければいつでも適用可能である。
dynamic ODTが有効でない場合、ライトアクセス時にも\rm R_{TT,nom}を利用するが、n=2,4,6に制限される。

Dynamic ODT

終端の強度をMRSコマンドを経由することなく、ODT終端をon-the-flyで変化させられることは、データバスの更なるデジタル信号品質の向上のためにも望ましい。
dynamic ODT \rm R_{TT(WR)}を有効にすることで、DRAMはWRITEバースト開始時に、\rm R_{TT,nom}から\rm R_{TT(WR)}にスイッチさせ、WRITEバーストが終わったら\rm R_{TT,nom}に再びスイッチさせることができる。

各スイッチにかかる時間は以下の通り。tADCの間は\rm R_{TT}の値は未定義。
dynamic ODT Timing

Param Symbol DDR3L-1333 Unit
\rm R_{TT,nom}-to-\rm R_{TT(WR)} change skew ODTLcnw \rm WL-2CK CK
\rm R_{TT(WR)}-to-\rm R_{TT,nom} change skew(BC4) ODTLcnw4 \rm 4CK+ODTLoff CK
\rm R_{TT(WR)}-to-\rm R_{TT,nom} change skew(BL8) ODTLcnw8 \rm 6CK+ODTLoff CK
\rm R_{TT} dynamic change skew tADC \rm MIN=0.3;MAX=0.7 CK

WL:Write Latency

特殊な仕様事例(DDR3がシングルランクの場合)

micronのドキュメントに書いてあるが、よく分かっていないので、とりあえず省略。

Synchronous ODT Mode

同期ODTとは、ODTピンの入力からAL分遅延して\rm R_{TT}のon/offが同期するODTのことを指す。DLLがonでロックされている状態で、\rm R_{TT,nom}\rm R_{TT(WR)}が有効であればいつでも同期ODTになる。つまり以下の場合が該当する。

  • CKEがHIGHで、全てのバンクがactive
  • CKEがHIGHで、refreshモード
  • CKEがHIGHで、idleモード
  • active power-down モード
  • DLLが有効なprecharge power-down モード

同期ODTでは、\rm R_{TT}はクロックの立ち上がりで、ODTがHIGHであるとサンプルされてからODTLonサイクル後にonとなり、ODTがLOWであるとサンプルされてからODTLoffサイクル後にoffとなる。実際にon/offになるタイミングはtAON/tAOFだけずれる。tAONとtAOFが分かりにくいが、つまりtAON(MIN)(minimum \rm R_{TT} turn-on time)とは、ODTLonから、実際にデバイスがHigh-Z状態から\rm R_{TT}をonに切り替え始めるタイミングで、tAON(MAX)(maximum \rm R_{TT} turn-on time)とはODTLonからODT抵抗を完全にonにしたタイミングのこと(tAOFも同様)。

ODTレイテンシ(ODTLon/ODTLoff)はWL(Wirte Latency)と結びついていて、WLはCWT(CAS WRITE Latency)とAL(Additive Latency)から成るので、モードレジスタで設定したALがODT信号にも適用される。つまり、内部のODT信号は外部のODT信号からAL分遅延する。

ODTがアサートされたら、ODTH4の間はHIGHに保たなければならない。WRITEコマンドの場合はODTH4(BC4)、ODTH8(BL8)の間HIGHに保たなければならない。
f:id:wanwannodao:20170907073651p:plain

READ中のODT Off

バイスが終端と出力を同時に行えないので、READプリアンブルの少なくとも半クロックサイクル前に\rm R_{TT}を無効にしておかなければならない。また、\rm R_{TT}はポストプリアンブルが終わってからでないと有効にならない。
f:id:wanwannodao:20170907073659p:plain

Asynchronous ODT Mode

常にfast exitを使うならここからの話は全く気にしなくて良い。
正直このあたりからかなり複雑過ぎてつらい...のでほぼ適当
Asynchronous ODT Timing

Param Symbol DDR3L-1333 Unit
Async. \rm R_{TT} turn-on delay tAONPD \rm MIN=2;MAX=8.5 ns
Async. \rm R_{TT} turn-off delay tAOFPD \rm MIN=2;MAX=8.5 ns

DLLがonであり、\rm R_{TT,nom}\rm R_{TT(WR)}が有効である状態で、precharge power-down中にDLLがoffになる場合に非同期ODTモードになる。または、リセットの後にDLLが同期中である場合にも非同期ODTになる。また、非同期ODTでは、ALによる遅延は発生しない。

tAONPD(MIN)(minimum \rm R_{TT} turn-on time),tAONPD(MAX)(maximum \rm R_{TT} turn-on time)の定義は同期ODTとほぼ同様だが、計測の基点がODTがHIGHとサンプルされた時点からとなっている(tAOFPDも同様)。
f:id:wanwannodao:20170907073708p:plain

Sync. to Async.

ここからはslow exitのprecharge power-downモードの時の同期ODTと非同期ODT間の遷移に関する事。

Power-Down Timing

Param Symbol DDR3L-1333 Unit
Begin power-down period prior to CKE registered HIGH tANPD \rm WL-1CK(Greater(ODTLoff+1,ODTLon+1)) CK
Power-down entry period:ODT(sync./async.) PDE \rm Greater(tANPD, tRFC-(REFRESH->CKE=LOW \ time)) CK
Power-down exit period:ODT(sync./async.) PDX \rm tANPD+tXPDLL CK

PDE周辺でODTはsync./async.どちらの振る舞いにもなりうる。これは、precharge power-downモードでDLLがoffの時に発生する。power-down entryはCKEが最初にLOWとなるtANPD前に始まり、最初にLOWとなった時に終わる。ここで、tANPDはODTLoff+1かODTLon+1の大きい方に等しい。一方、REFRESHコマンドが発行されていて、CKEがLOWになる時に実行中の場合、power-down entryは、(最初にCKEがLOWになった時ではなく)REFRESHコマンドのtRFC後に終わる。したがって、PDEは表の通りになる。
この時、power-down entry中のODTのアサーションとデアサーション\rm R_{TT}の変化は以下のようになる。

Description Min Max
ODT -> \rm R_{TT} turn-on delay \rm Lesser(tAONPD(MIN),ODTLon \times tCK + tAON(MIN)) \rm Greater(tAONPD(MAX),ODTLon \times tCK + tAON(MAX)

さて、ここでODTの振る舞いについて以下の3ケースが考えられる。

  • tANPD前の同期的な動作
  • PDE中の動作:上の表でLesser, Greaterで右側が選ばれる時
  • PDE後の非同期的な動作

f:id:wanwannodao:20170907084302p:plain

Async. to Sync.

Sync. to Async.の逆でpower-down exitで起きる事。大体同じ話なのでODTと\rm R_{TT}の変化だけ。

Description Min Max
ODT -> \rm R_{TT} turn-off delay \rm Lesser(tAOFPD(MIN),ODTLoff \times tCK + tAOF(MIN)) \rm Greater(tAOFPD(MAX),ODTLoff \times tCK + tAOF(MAX)
Short CKE Pulse

precharge power-downもしくはidleステートの時間が非常に短い場合(CKE LOWパルスが短い場合)、power-down entryとpower-down exitの遷移がオーバーラップする。
idleステートの時間が非常に短い場合(CKE HIGHパルスが短い場合)、power-down exitとpower-down entryの遷移がオーバーラップする。

これらの場合に関する\rm R_{TT}の変化に関することだが、力尽きたので気が向いた時に加筆する。

DDR3 SDRAM: Power-Down Mode

DDR3 SDRAMに関するメモ的なもの(特にDDR3L-1333)。

図は全て以下のMicronのドキュメントからの引用であり、このメモの内容もこれを参照する。
2Gb: x4, x8, x16 DDR3L SDRAM

wikiの記述も参照。
DDR3 SDRAMにおけるコマンドとオペレーション - Wikipedia

Power-Down Mode

power-downに関するタイミングのシンボルは以下の通り。

Power-Down Timing

Param. Symbol DDR3L-1333 Unit
CKE MIN pulse width tCKE(MIN) \rm Greater(3CK,5.625ns) CK
Command pass disable delay tCPDED \rm MIN=1 CK
Power-down entry -> power-down exit tPD \rm MIN=tCKE(MIN); \ MAX=9 \times tREFI CK

Power-Down Exit Timing

Param. Symbol DDR3L-1333 Unit
DLL on/any valid command/DLL off -> commands not requiring a locked DLL tXP  \rm MIN=Greater(3CK,6ns) CK
Precharge power-down(DLL off) -> commands requiring a locked DLL tXPDLL  \rm MIN=Greater(10CK,24ns) CK

NOP/DESコマンドと同時にCKEをLOWに落とすことで同期的にpower-downモードに突入する。ただし、MRS/MPR/ZQCAL/READ/WRITE中にCKEをLOWに落としてはならない(他のオペレーション中ならば可能だが、power-down中の電流量になるのは実行中のオペレーションが完了してからとなる)。この時、DRAMのステートと最後に発行されたコマンドによって、power-downモードに突入するまでの時間がそれぞれ異なる(詳細はMicronのドキュメント参照)。
power-downモードに入ると、CK,CK#,ODT,CKE,RESET#を除く入出力バッファは無効になる。また、tCPDEDが満たされるまでは、コマンドはNOP/DESでなければならない。
exitの関しては、fast exitの場合、power-down中DLLはロックされている必要があり、slow exitの場合は抜けた時にDLLをリセットする必要がある。

power-downには2つの種類がある。 バンクが開いたままだとactive power-downモードに入り、全てのバンクが閉じた状態だと、precharge power-downモードに入る。
precharge power-downモードの場合、slow exitかfast exitのどちらか選ぶ必要がある。precharge power-downモード突入時に、slow exitの時はDLLはoffにされ、fast exitの時は維持される。
active power-downの場合、DLLはonのまま。 slow exit modeのprecharge power-downの場合、ODTのタイミング制約が少し異なるので注意(非同期ODT)。

どちらのタイプのpower-downモードであっても、power-down中はCKEはLOWで、RESET#はHIGHで、安定したクロックを維持しなければならない。
また、ODTは正当な状態でなければならないが、他の入力信号はDon't Careとなる。
power-down中にRESET#がLOWになった場合、DRAMはpower-downからresetステートへスイッチする。
CKEがLOWになってからは、CKEはtPD(MIN)の間LOWである必要があり、最大で許可されるpower-down時間はtPD(MAX) (9xtREFI)となっている。

(コマンドはNOP/DESで)CKEがHIGHになったら同期的にpower-downモードから抜ける。この時、CKEはtCKEの間HIGHに維持しなければならない。また、正当で実行可能なコマンドはtXP(power-down exit latency)/tXPDLLを満たした後に適用可能となる。

まとめると以下の表の通りである。

DRAM State MR0[12] DLL State Power-Down Exit Relevant Param.
Active X On Fast tXP -> valid command
Precharged 1 On Fast tXP -> valid command
Precharged 0 Off Slow tXPDLL -> commands requiring a locked DLL/tXP -> others

power-down exit -> refresh -> power-down entry というようなCKE-intensive(多分CKEの上げ下げが集中するようなということ)なオペレーションでは、power-down exitとpower-down entry間のサイクル数だけではDLLの適切な更新には不十分である可能性がある。
なので、REFRESHコマンドをpower-down exitとpower-down entryの間に使用するときは、tPDに加えて2つの条件を満たす必要がある。
まず、REFRESHを発行する前にtXPを満たす必要がある。次に、後続のpower-down entryの前にtXPDLLを満たす必要がある。


主要なタイミングチャートは以下の通り。
f:id:wanwannodao:20170907031145p:plain
f:id:wanwannodao:20170907031211p:plain
f:id:wanwannodao:20170907031156p:plain
f:id:wanwannodao:20170907031203p:plain

Pointer Networks

[1506.03134] Pointer Networks

論文まとめ

入力系列上のインデックスに対応した要素から成る出力系列の条件付き確率分布を学習するアーキテクチャ.
この種の問題は、出力の各ステップでのターゲットクラスの数が、可変である入力長にいぞんしているので、Seq2SeqやNeural Turing Machineでは解くのは難しい.
(例えば、可変長のソート問題や種々の組み合わせ最適化問題など.)

既存のAttention

  • デコーダの各ステップで、エンコーダの隠れユニットをコンテキストに混ぜる

今回のAttention

  • 出力として、入力系列中の要素を指すポインタ(つまりインデックス)として利用する

Sequence-to-Sequence

\mathcal P = \{ P_1, ..., P_n \} : 入力系列
\mathcal C^{\mathcal P} = \{C_1, ..., C_{m( \mathcal P )} \},  m( \mathcal P ) \in [1, n ] : 出力系列(各出力は入力系列上のインデックス)

トレーニングデータのペア(\mathcal P, \mathcal C^{\mathcal P})が与えられた時、次の条件付き確率を、RNN (LSTM)によるパラメトリックモデルで推定するというもの.
{\displaystyle
p(\mathcal C^{\mathcal P} | \mathcal P ; \theta) = \prod_{i=1}^{m(\mathcal P)} p_{\theta} (C_i | C1, ..., C_{i-1}, \mathcal P; \theta)
}
以下のように、トレーニングセットの条件付き確率を最大化するように学習する.
{\displaystyle
\newcommand{\argmax}{\mathop{\rm arg~max}\limits}

\theta^* = \argmax_{\theta} \sum_{\mathcal P,  \mathcal C^{\mathcal P}} \log {p(\mathcal C^{\mathcal P} | \mathcal P ; \theta) }
}

統計的な独立性は仮定はせずに、RNNは各時刻iにおいて、P_iを入力系列の終わり(\Rightarrow)まで受け取り、出力系列の終わり(\Leftarrow)まで出力記号C_jを生成する.

推定時には、入力系列\mathcal Pが与えられ、学習済みパラメータ\theta^*を用いて、条件付き確率を最大化する列、つまり\newcommand{\argmax}{\mathop{\rm arg~max}\limits} \hat{\mathcal C}^{\mathcal P} = \argmax_{\mathcal C ^ {\mathcal P}} p ( \mathcal C ^ {\mathcal P} | \mathcal P; \theta^*) となる\hat{\mathcal C}^{\mathcal P}を選択する.

最適な系列\hat {\mathcal C}を見つけるには、計算量的に困難なので、ビームサーチを行ったりする.

このsequence-to-sequenceにおいては、出力は入力系列上のインデックスから選択されるのであるから、すべての記号C_iの数は入力列長であるnに固定されている.
つまり異なるnごとに学習しなくてはならない. 

ちなみに、出力の数がO(n)だとしたら、計算量はO(n)となる.

Content Based Input Attention

attentionというものを考えて、seq2seqでは固定的であったdecoderのステートに対してより多くの情報を付加する.

(e_1, ..., e_n): encoder hidden states
(d_1, ..., d_{m(\mathcal P)}): decoder hidden states
としたとき、attentionを以下のように定義する.

{ \displaystyle
\begin{eqnarray}
u_j^i & = &v^T \tanh(W_1e_j + W_2d_i) & j \in (1, ..., n) \\
a_j^i & = &{\rm softmax}(u_j^i) & j \in (1, ..., n) \\
d_i^{'} & = & \sum_{j=1}^n a_j^i e_j  \\
{\rm hidden \ states} & = & {\rm concat}(d_i^{'}, d_i)
\end{eqnarray}
}

 v, W_1, W_2は学習パラメータで、 {\rm softmax}{\bf u}^iを正規化してattention maskを生成する.
計算量的には推定時に、各出力でn命令処理するので、O(n^2)となる.

Seq2Seqより性能は良いが、やはり出力の辞書サイズが入力に依存するような問題には適用できない.

Ptr-Net

Seq2Seqでは、条件付き確率p(C_i | C_1, ..., C_{i-1}, \mathcal P)を計算するために、固定サイズの入力の辞書(系列上のインデックス)における{\rm softmax}の分布を使用する形になる.
したがって、出力が入力の辞書サイズに依存するような場合には適用できなかった. これに対して、以下のように、attentionを用いて条件付き確率p(C_i | C1, ..., C_{i-1}, \mathcal P)モデリングする.

{\displaystyle
\begin {eqnarray}
u_j^i & = & v^T \tanh(W_1e_j + W_2d_i) & \ j \in (1, ..., n) \\
p(C_i | C_1, ..., C_{i-1}, \mathcal P) & = & {\rm softmax}(u^i)
\end {eqnarray}
}

 v, W_1, W_2は学習パラメータで、 {\rm softmax}{\bf u}^iを正規化して、入力の辞書上(インデックス)の確率分布を生成する.
通常のattentionのように、「より多くの情報を伝播させるために、encoderのステートe_jを混ぜる」というようなことはせずに、u_j^iを入力要素へのポインタとして使う.
また、 C_{i-1}で条件付けするために、対応するP_{C_{i-1}}を入力としてコピーする.

図的には以下のような感じ
f:id:wanwannodao:20170612195610p:plain
(論文より引用)

データセット

Convex Hull (凸包)

定義
凸包 - Wikipedia


こんな感じのデータ

0.12597930 0.57132358 0.77404416 0.01266053 0.69612552 0.98888917 0.56750540 0.30860638 0.25714026 0.99675915 0.41245506 0.03328769 0.99328556 0.97091931 0.82174988 0.08516088 0.63969443 0.51914056 0.45612945 0.54733761 0.32766033 0.43352998 0.49206557 0.89107185 0.13685374 0.00708945 0.61040137 0.43254429 0.88256464 0.81985257 0.07880500 0.53008275 0.42095766 0.92055700 0.02109736 0.33024543 0.76352942 0.73969747 0.08505665 0.51877561 0.62335861 0.39605697 0.86642364 0.09540971 0.89609816 0.87439433 0.57799306 0.40433588 0.01053175 0.77368518 0.49862115 0.26769698 0.94832038 0.56638474 0.03807545 0.71314326 0.97767538 0.72042601 0.82861561 0.41455754 0.56748456 0.32859033 0.87639463 0.93457765 0.28872692 0.14781993 0.18529194 0.06272494 0.32126462 0.56453709 0.81442383 0.01964365 0.56290155 0.64332693 0.93979231 0.16170123 0.36700478 0.97992791 0.26060579 0.12514376 0.33918180 0.76817253 0.41583231 0.49321529 0.41187788 0.27050384 0.19393678 0.46065066 0.29478536 0.77983912 0.54389681 0.26205415 0.20471867 0.04153719 0.95478980 0.33200250 0.04618655 0.56410345 0.99342056 0.87685348 output 2 36 38 48 50 7 3 5 25 18 13 2

可視化するとこのような感じ

https://github.com/Wanwannodao/DeepLearning/blob/master/RNN/PtrNet/data.png?raw=true

実装

github.com

Decoder

dec_cell_in = utils.fc(dec_inputs, dec_inputs.get_shape()[-1],
    lstm_width, init_w=initializer, a_fn=tf.nn.elu)

(dec_cell_out, dec_state) = dec_cell(dec_cell_in, dec_state)

# W1, W2 are square matrixes (SxS)
# where S is the size of hidden states
W1 = tf.get_variable("W1", [lstm_width, lstm_width], dtype=tf.float32, initializer=initializer)
W2 = tf.get_variable("W2", [lstm_width, lstm_width], dtype=tf.float32, initializer=initializer)
# v is a vector (S)
v  = tf.get_variable("v", [lstm_width], dtype=tf.float32, initializer=initializer)

# W2 (SxS) d_i (S) = W2d (S)
W2d = tf.matmul(dec_state.h, W2)
# u_i (n)
u_i = []
                
for j in range(num_steps):
  # W1 (SxS) e_j (S) = W1e (S)
  # t = tanh(W1e + W2d) (S)
  t    = tf.tanh( tf.matmul(enc_states[j].h, W1) + W2d )
  # v^T (S) t (S) = U_ij (1)  
  u_ij = tf.reduce_sum(v*t, axis=1) # cuz t is acutually BxS

  u_i.append(u_ij)

u_i   = tf.stack(u_i, axis=1) # asarray
probs = tf.nn.softmax(u_i)

Loss

L2 Loss

self.loss = tf.nn.l2_loss(targets - self.C_prob)

入力データ

上の方で貼った図に倣い、入力の先頭(index 0)を終了記号に対応させるようにした.
具体的にどのような値を設定するべきなのかわからなかったので入力系列のインデックス0には[-1.0, -1.0]を対応させた.

トレーニングデータの出力系列はzero-padidngした。

enc.insert(0, '-1.0')
enc.insert(0, '-1.0')

while len(dec) != len(enc) // 2:
  dec = np.append(dec, _STOP)

結果

https://github.com/Wanwannodao/DeepLearning/blob/master/RNN/PtrNet/loss.png?raw=true

ある程度それっぽい出力をしている例
https://github.com/Wanwannodao/DeepLearning/blob/master/RNN/PtrNet/eval_6.png?raw=true
[ 2 11 21 21 39 28 40 50 47 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
https://github.com/Wanwannodao/DeepLearning/blob/master/RNN/PtrNet/eval_8.png?raw=true
[ 1 18 42 42 31 25 25 49 26 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
https://github.com/Wanwannodao/DeepLearning/blob/master/RNN/PtrNet/eval_18.png?raw=true
[ 2 2 44 12 30 36 36 21 29 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]

https://github.com/Wanwannodao/DeepLearning/blob/master/RNN/PtrNet/eval_63.png?raw=true
[ 2 2 7 26 6 6 44 4 27 27 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
https://github.com/Wanwannodao/DeepLearning/blob/master/RNN/PtrNet/eval_75.png?raw=true
[ 5 34 34 32 8 43 43 45 18 25 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
https://github.com/Wanwannodao/DeepLearning/blob/master/RNN/PtrNet/eval_84.png?raw=true
[ 6 31 28 41 41 48 39 9 9 13 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]

微妙なものも多くあったので、実装に不備があるのかもしれない...