💾
概念 #CODE #フリップフロップ #RAM #クロック #メモリ #論理回路 📚 CODEコンピュータのからくり

記憶と時計:フリップフロップ・クロック・RAM

「値を覚える」とはどういうことか。SR・DフリップフロップからRAMの構造まで。クロック信号がなぜ回路の同期に必要かも解説。CODE第2版 Ch.17-19。

「記憶する」とはどういうことか

前のdocまでの回路はすべて組み合わせ論理回路:入力が変われば出力が即座に変わる。

しかし計算機には「値を保持する」機能が必要。加算して得た結果を、次の計算に使うまで保存しておかなければならない。

「記憶」を実現するには、出力を入力にフィードバックする回路が必要。


SR フリップフロップ

Set-Reset フリップフロップ。最も基本的な1ビット記憶回路。

【SR フリップフロップ(NOR ゲート2個)】

        S ──┬──[NOR1]──┬── Q
            │          │
        R ──┼──[NOR2]──┼── Q̄(Qの反転)
            │          │
            └──────────┘
              (フィードバック)

動作:
  S=1, R=0 → Q=1, Q̄=0  (セット:1 を記憶)
  S=0, R=1 → Q=0, Q̄=1  (リセット:0 を記憶)
  S=0, R=0 → 現在の状態を保持  ← これが「記憶」
  S=1, R=1 → 禁止状態(Q=Q̄=0 になり不定)

真理値表:
  S  R │  Q(次の状態)
  0  0 │  Q(変化なし)
  0  1 │  0(リセット)
  1  0 │  1(セット)
  1  1 │  不定(禁止)

SR フリップフロップは「フィードバックループによって状態を保持する」という記憶の原理を最もシンプルに示している。


D フリップフロップ

SR の「禁止状態」をなくしたより実用的な回路。

【D フリップフロップ】

  D ──[NOT]──→  R
  D ───────→  S

  SR フリップフロップへ

  S = D、R = NOT D なので、S=R=1 が発生しない

  D=1 → S=1, R=0 → Q=1
  D=0 → S=0, R=1 → Q=0

  つまり「D の値をそのまま記憶する」

ただしこれだけでは「好きなタイミングで値をラッチ(保存)できない」。そこでクロック信号が登場する。


クロック付き D フリップフロップ(エッジトリガ型)

  D ──┐
      ├──[D-FF]──→ Q
  CLK─┘

  CLK が 0→1 に立ち上がる瞬間(立ち上がりエッジ)にだけ
  D の値を Q に記録する。それ以外の時間は Q を保持。

タイムチャート:
       ┌─┐ ┌─┐ ┌─┐ ┌─┐
CLK    │ │ │ │ │ │ │ │
     ──┘ └─┘ └─┘ └─┘ └─

D     ──┬──────────────┬──
        1              0

Q     ──────────┬──────────
                1(CLKの立ち上がりで D=1 をキャッチ)

「クロックの立ち上がりエッジで値を取り込む」という動作がすべての同期デジタル回路の基本。


クロック信号の役割

コンピュータ回路は複数のゲートが連鎖している。信号が全ゲートを通過するのに時間がかかる(伝播遅延)。

【伝播遅延の問題】

  入力 → [ゲート1] → [ゲート2] → [ゲート3] → 出力
            5ns         3ns         4ns
          ← 合計 12ns の遅延 →

  もし途中で入力が変わると、各ゲートの通過タイミングがずれて
  一瞬「中間的な誤った値」が出力に現れる(グリッチ)

【クロックによる解決】

  CLK の周期 > 最大伝播遅延 × 余裕

  周期が12nsより大きければ、クロックエッジが来る前に
  必ず全ゲートの出力が安定している

  → 安定した後の値だけを FF がキャプチャする
  → グリッチが無視される

クロック周波数 = 1秒間のエッジ回数。3GHzなら1秒に30億回の「スナップショット」を取る。


レジスタ:複数ビットを保持

D-FF を並べると複数ビットを同時に保持できる。

【8ビットレジスタ(D-FF × 8個)】

  D7 D6 D5 D4 D3 D2 D1 D0  ← 8本のデータ入力
   │  │  │  │  │  │  │  │
  [FF][FF][FF][FF][FF][FF][FF][FF]
   │  │  │  │  │  │  │  │
  Q7 Q6 Q5 Q4 Q3 Q2 Q1 Q0  ← 8本の出力

  CLK ── (全FFに共通接続)

CLK エッジのたびに 8 ビット全部を同時にキャプチャ

CPUのレジスタ(AX, BX, R0, R1 など)はこの構造。Intel 8080は8本の8ビットレジスタを持つ。


RAM(Random Access Memory)

大量のビットをアドレスで管理するメモリ。

【RAM の基本構造】

  アドレスバス(A0〜An):「どこを読み書きするか」
  データバス(D0〜Dm)  :「何を読み書きするか」
  制御信号(WE, OE)   :「読むか書くか」

  WE(Write Enable)= 1 → 書き込みモード
  OE(Output Enable)= 1 → 読み出しモード

n本のアドレスバス = 2^n 個のセルにアクセス可能

  8ビットアドレス  → 256アドレス
  16ビットアドレス → 65,536(64KB)
  32ビットアドレス → 4,294,967,296(4GB)
  64ビットアドレス → 約1.8エクサバイト(理論値)

RAM の内部構造(簡略)

                 アドレスデコーダ

  A0 A1 A2 ──→ [3-to-8 デコーダ] ──→ 8本のワード選択線

          データ線(D0〜D7)               │
          ──────────────────────── × 8本

          [FF FF FF FF FF FF FF FF] ← 行0  ← ワード0
          [FF FF FF FF FF FF FF FF] ← 行1  ← ワード1
          ...(8行 × 8ビット = 64ビット)

選択されたアドレスの行に書き込み、または読み出し

RAM の種類

SRAM(Static RAM):
  フリップフロップで実装
  速いが消費電力大・高コスト・面積大
  用途:CPUキャッシュ(L1/L2/L3)

DRAM(Dynamic RAM):
  コンデンサで実装(電荷を蓄える)
  遅いが低コスト・高密度
  電荷が放電するため定期的な「リフレッシュ」が必要
  用途:メインメモリ(DDR SDRAM)

ROM(Read-Only Memory):
  書き込み不可(製造時に書き込まれる)
  電源を切っても保持
  用途:BIOS/ファームウェア

メモリマップ

CPUはアドレスに対して一様にアクセスする。アドレス空間の「どこに何があるか」がメモリマップ。

【Intel 8080の16ビットアドレス空間(例)】

  0x0000 ─── ROM(プログラム格納)

  0x1FFF ─── ROM 終端
  0x2000 ─── RAM(データ・スタック)

  0x3FFF ─── RAM 終端
  0x4000 ─── I/Oマップ(周辺機器)

  0xFFFF ─── アドレス空間の終端

実際のPCでも同じ構造(より複雑だが):
  0x00000000 ─── 低アドレス(BIOS, レガシーデバイス)
  0x00100000 ─── 1MB以降(OS + アプリのメモリ)
  ...
  0xFFFFFFFF ─── 4GBの終端(32ビットアドレス空間)

まとめ:記憶の階層

フリップフロップ(1ビット)
  ↓ 8個並べる
レジスタ(8ビット)
  ↓ デコーダで選択できるようにする
RAM(アドレス指定可能な多数のレジスタ)
  ↓ 容量を増やす
キャッシュ(SRAM)/ メインメモリ(DRAM)/ ストレージ(フラッシュ)

速い ←────────────────────────────→ 遅い
高価 ←────────────────────────────→ 安価
容量小 ←──────────────────────────→ 容量大

出典: https://www.amazon.co.jp/dp/4296080245