前回に引き続きここではシンプルな DRAM (Dynamic Random Access Memory)を扱っていきます。DRAM は1ビット 1 トランジスタのシンプルな構成のメモリです。
今回は DRAM のメモリセルの書き込みと読み出しの挙動を追っていきます。
Indexx
メモリはメモリセルの集合体
メモリは大量のメモリセルによって作られています。エクセルのセルと同じ格子状のものです。

このセルひとつひとつが1ビットを表現します。

前回は 2進数の表現が目的だったので 1 ビット 1 トランジスタで説明しましたが、
実際には 1 ビットは 1つのトランジスタと 1 つの キャパシタ(コンデンサーとも呼ばれます)で表現されます。
1つのトランジスタと 1 つのキャパシタの組み合わせが1つのセルを構成していて、1ビットを表現します。

トランジスタとキャパシタの組み合わせが 1 ビットを表現していて、この仕組みを格納しているのがメモリセルです。
トランジスタとキャパシタ
キャパシタは電荷を蓄積し、後で放出することができる受動的な電子部品です。短時間で電荷を蓄え、必要に応じて素早く放出することができます。
前回、2進数の 0 と 1 はトランジスタの ON / OFF ではなく電流が流れている状態と流れていない状態を表す、と記載しました。
もう少し具体的にいうと、DRAM においては電流が流れてキャパシタに電荷が蓄えられている状態を 1、蓄えられていない状態を 0 と表現しています。

下記の動画ではコンデンサと表記されていますが、ここでは英語でよく使われるキャパシタで記載していきます。
回路図
メモリセルの回路図は下記のようになっています。

これが 1 ビットを表現するしくみで、ひとつのセルを構成しています。

セル全体をみると下記のようになっています。

ワード線が行、ビット線が列に対応しています。
例えば Corsair の 32GB のメモリ の場合、32GB = 約274億 Bit なので、このメモリには 約274億個のセルが組み込まれており、 2 の 274億乗分のデータを記録できます。
回路図のポイントを順に追っていきます。
ワード線に電流を流すとトランジスタが ON になる

ワード線に電流を流すことを「アクティベーション」と呼びます。
セルへの読み書きはいずれもこのアクティベーションから始まります。
トランジスタが ON になると導体が繋がる

トランジスタが ON になるとトランジスタとキャパシタを繋いでいる導体に電流が流れる状態になります。トランジスタが OFF の場合は電流を流せません。
ビット線は電圧を調整できる
ビット線の電圧は調整できます。

ビット線の電圧の変化をセンスアンプが検知、増幅し、デジタル信号へ変換する
それぞれのビット線はセンスアンプと呼ばれるコンポーネントに接続されています。

センスアンプはビット線の微弱な電圧変化を検知します。
その電圧差を大幅に増幅させることで明確な 0 か 1 のデジタル信号へと変換し、CPU の中にあるメモリコントローラによってその他の IC へ送られます。
データの書き込み
では、メモリセルがどうやって 0 や 1 を表現するかを具体的に見ていきます。
C 言語のコードとしては
#include <stdio.h>
int main() {
int val = 1;
return 0;
}
あるいは
#include <stdio.h>
int main() {
int val = 0;
return 0;
}
このコードの「0」や「1」の値の末尾のビット値( 0 と 1)をメモリセルにどうやって書き込んでいるかについて見ていきます。
なお、ここでは書き込む手順のみを追っていきます。
どのセルに書き込むかについては別記事にします。(たぶん次の次の回かな)
データ「1」を書き込む

トランジスタが ON になると電流が流れ、その瞬間にキャパシタに電荷が蓄えられます。
これがデータ「1」をメモリに記憶させる、ということです。
この状態は下記のようにしてつくられます。

電流は高電圧から低電圧の場所へ流れるため、高電圧のビット線から低電圧のキャパシタへと電流が流れていきます。
キャパシタに電荷が溜まった後はワード線の電流を切ってトランジスタを OFF にします。

キャパシタに蓄積された電荷は時間とともに自然に減少します。電荷がなくなると「1」の状態を保持できなくなります。
これを防ぐため、DRAM では後述する定期的なリフレッシュを行っています。
データ「0」 を書き込む
0 の書き込みは下記のプロセスを経て行われています。

0 を書き込む場合に問題になるのは放電です。
最初から電荷が蓄積されていない状態であれば特になにもせずそのまま 0 の状態です。
ただ、既に電荷が蓄積されている状態、つまり1 を表現している状態を 0 にする場合には
蓄積されている電荷をリセットするために放電を行う必要があります。
コードだと下記のような場合です。
#include <stdio.h>
int main() {
int val = 1;
val = 0;
return 0;
}
この場合変数 val の末尾のビットは 1 のため、末尾のビットを表現しているセルのキャパシタには電荷が蓄積されている状態です。
このセルで 0 を表現するには放電が必要になります。
放電は次のように行われます。

重要なのはビット線がグラウンドへ接続され、低電圧の状態を保っていることです。
電流は高電位から低電位の場所に向かって流れるため、キャパシタの放電が行われます。
放電が完了したタイミングでワード線の電流を止め、キャパシタの電荷がない状態を保ちます。

リフレッシュ
キャパシタに貯めた電荷は時間とともに徐々に減少していきます。
これを防ぐために DRAM はリフレッシュと呼ばれる工程でキャパシタの電荷を再度充電します。
リフレッシュの頻度は一般的な DRAM で 64ミリ秒の周期で行われています。

「0」を表しているセルは時間経過の影響を受けないため、何もしません。
64ミリ秒の周期でリフレッシュが行われるとはいえ、リフレッシュ後に徐々に電荷が下がるため、すぐに満充電の状態ではなくなります。リフレッシュの間に読み出しを行ったとしても「1」として扱えるように閾値が設けられています。
データの読み出し
セルが 0 を表しているか 1 を表しているかを調べるにはキャパシタの状態を調べることになります。
キャパシタに電荷が蓄積されていれば 1 、放電状態であれば 0 を読み出します。
コードで言うと下記のコードの末尾2桁のビット(1 と 0)を読みます。
#include <stdio.h>
int main() {
int val = 1;
printf("%d", val);
return 0;
}
このプロセスはビット線を中電圧にした状態でワード線に電流を流すことで行われます。
ビット線を中電圧にすることを「プリチャージ」と呼びます。

データ「1」の読み出し

トランジスタを ON にした際に電流がキャパシタからビット線へ向かって流れ、ビット線の電圧が上がります。この電圧の上昇をセンスアンプが検出します。

センスアンプが電圧の上昇を確認した時点で⑤ を行って電流を止めます。
ただし、既に電流が流れた後のため、若干の電荷が移動しています。このときのキャパシタは満充電ではなくなっています。
データ「0」の読み出し

「1」のときとは逆で、ビット線の電圧が下がります。ビット線の電圧の低下をセンスアンプが検出します。

「1」のとき同様検出と同時にワード線の電流を止めます。ですが、わずかにキャパシタへ電流が流れたため、キャパシタに電荷が蓄積されています。
電圧差を増幅してデジタル信号に変換、送信
センスアンプは検出した電圧の差を増幅させます。

④で検出した電圧の差はかなり微弱のため、0 か 1 の明確な判別ができません。
センスアンプは検出した電圧の差を大幅に増幅させて明確にします。これが「o」または「1」のデジタル信号です。
これをメモリコントローラが CPU などのその他の IC に送っています。
リフレッシュ(データの書き戻し)
DRAM の読み出しは破壊的です。
電荷の再分配を行ってビット線の電圧が変化するという事は、そのタイミングでキャパシタの電荷量が変化しています。
そのため読み出しを行うたびにキャパシタの電荷量が変化していき、データが狂っていきます。

例えば下記のようなコードを書いた際、ループするたびに中電圧に近づいていってしまします。
#include <stdio.h>
int main() {
int val = 1;
int i;
for (i = 0; i < 100; i++) {
printf("%d", val);
}
return 0;
}
これを防ぐために DRAM では読み出しをする度にリフレッシュを行ってキャパシタの電荷を元に戻します。


まとめ
今回はメモリセルの中身の挙動について見てきました。
挙動としては、ワード線とビット線の電力調整のみです。この電力を調整するだけでトランジスタとキャパシタが動作し、センスアンプが 0 か 1 の電気信号へと変換します。
ワード線とビット線の電力調整はメモリコントローラが行います。
次回はメモリコントローラがセル全体をどのように扱ってメモリを操作しているかを見ていきます。
参考サイト:

LEAVE A REPLY