0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

NANDとCPU

Last updated at Posted at 2025-10-12

【1. NANDは「完全論理系」:全ての論理を作れる基本素子】

NANDは「完全論理系(functionally complete)」であり、
この1種類のゲートだけで全ての論理回路を構成可能です。

論理式:

NAND(A, B) = ¬(A ⋅ B)

【2. 基本論理回路のNAND構成式】

NANDのみで実現できる基本ゲート:

論理回路 NANDによる構成式 構成ゲート数
NOT NAND(A, A) 1
AND NAND(NAND(A,B), NAND(A,B)) 2
OR NAND(NAND(A,A), NAND(B,B)) 3
XOR NAND(NAND(A, NAND(A,B)), NAND(B, NAND(A,B))) 4

【3. 組み合わせ回路(Combinational Circuits)】

これらの基本ゲートを組み合わせることで、
加算器(adder)や多重器(multiplexer)などの機能ブロックを構成します。

(1) 半加算器(Half Adder)

Sum  = A ⊕ B
Carry = A ⋅ B

NANDだけで実現:

  • XOR → 4 NAND
  • AND → 2 NAND
    合計6 NAND

(2) 全加算器(Full Adder)

Sum  = A ⊕ B ⊕ Cin
Cout = (A ⋅ B) + (Cin ⋅ (A ⊕ B))

構成:半加算器2段+OR1段
→ 約14 NANDで構成可能


【4. 順序回路(Sequential Circuits)】

CPUには**記憶素子(フリップフロップ)**が必要です。
NANDで構成できる代表的な順序回路は以下の通り。

(1) SRラッチ(基本メモリ)

Q  = NAND(S, Q̅)
Q̅ = NAND(R, Q)

→ 2 NAND構成

(2) Dラッチ

Dラッチ = SRラッチ + 入力制御NAND ×2

→ 合計4 NAND

(3) Dフリップフロップ(クロック同期)

D-FF = Dラッチ × 2(Master-Slave構成)

→ 約8 NAND


【5. ALU(Arithmetic Logic Unit)】

ALUはCPUの中核であり、加算器・論理演算器・比較器を含みます。
全てNAND論理で実現可能。

例:4ビットALU構成

  • 1ビット全加算器 ×4 → 56 NAND
  • AND/OR/XOR選択用MUX → 各演算器にNAND 追加
  • 制御入力(OPCODE)で動作を選択

【6. 制御回路(Control Unit)】

制御部は**状態機械(Finite State Machine, FSM)**として設計します。

  • 入力:命令(opcode)
  • 出力:制御信号(ALU操作、レジスタ選択、メモリアクセス)

設計手順:

  1. 状態遷移表(State Transition Table)を定義
  2. 各状態をNANDベースの論理式で表現
  3. クロック同期で次状態を決定(D-FFで保持)

【7. メモリブロック】

SRラッチ → D-FF → レジスタ → レジスタファイル
全てNANDで構成できる。

1ビットメモリ:

SR latch → 2 NAND

8ビットレジスタ:

D-FF × 8 → 64 NAND

【8. CPUトップレベル構成】

CPU = ALU + レジスタ + 制御部 + メモリ + クロック

構造イメージ(NAND階層設計):

[NAND]
  ↓
[AND, OR, NOT, XOR]
  ↓
[Adder, MUX, FF]
  ↓
[ALU, Register, Control]
  ↓
[CPU Core]

【9. 動作の一次遅れモデル(RC遅延式)】

各ゲートは一次遅れで近似可能:

τ_gate = R_eq × C_L
t_pd ≈ 0.69 × τ_gate

CPU動作周波数は:

f_max ≈ 1 / (N_stage × t_pd)

(N_stage:ゲート段数)



#---------------------------------------------
# 必要ライブラリのインストール / Install required libraries
#---------------------------------------------
!pip install numpy matplotlib

#---------------------------------------------
# ライブラリのインポート / Import libraries
#---------------------------------------------
import numpy as np
import matplotlib.pyplot as plt

#---------------------------------------------
# パラメータ設定 / Parameter definitions
#---------------------------------------------
# トランジスタ等価抵抗 [Ω]
R_N = 10e3      # NMOS等価抵抗
R_P = 5e3       # PMOS等価抵抗
# 負荷容量 [F]
C_L = 1e-12
# 入力信号の立ち上がり時間 [s]
t_rise = 5e-9
# 総シミュレーション時間 [s]
t_end = 50e-9
# ゲイン(反転を含む) / Gain
K = -1

#---------------------------------------------
# 時定数の定義 / Define time constants
#---------------------------------------------
tau_HL = 2 * R_N * C_L      # High→Low 遷移(NMOS直列)
tau_LH = (R_P / 2) * C_L    # Low→High 遷移(PMOS並列)

#---------------------------------------------
# 入力信号の生成 / Generate input waveforms
#---------------------------------------------
t = np.linspace(0, t_end, 1000)
# A, B は矩形波入力
A = np.where(t < t_end/2, 0, 1)
B = np.where(t < t_end/3, 0, 1)

#---------------------------------------------
# NAND論理の理想出力 / Ideal logical output
#---------------------------------------------
ideal_out = 1 - (A * B)

#---------------------------------------------
# 一次遅れ系応答の計算 / First-order response calculation
#---------------------------------------------
# vout[0] 初期値 / Initial condition
vout = np.zeros_like(t)
vout[0] = 1

# 数値積分による一次遅れ系応答(オイラー法)/ Euler integration
for i in range(1, len(t)):
    dt = t[i] - t[i-1]
    # τ_eff 切替え(入力条件による) / Select time constant depending on inputs
    if A[i] == 1 and B[i] == 1:
        tau_eff = tau_HL
        target = 0   # 放電方向
    else:
        tau_eff = tau_LH
        target = 1   # 充電方向
    # 一次遅れ微分方程式 dv/dt = (target - v)/τ
    vout[i] = vout[i-1] + (target - vout[i-1]) * (dt / tau_eff)

#---------------------------------------------
# プロット / Plot results
#---------------------------------------------
plt.figure(figsize=(8,5))
plt.plot(t*1e9, A, label="Input A")
plt.plot(t*1e9, B, label="Input B")
plt.plot(t*1e9, vout, label="Vout (1st-order response)")
plt.title("2-input NAND Gate First-Order Response")
plt.xlabel("Time [ns]")
plt.ylabel("Voltage (normalized)")
plt.legend()
plt.grid(True)
plt.show()

#---------------------------------------------
# 日本語補足 / Japanese explanation
#---------------------------------------------
# このスクリプトは2入力NANDゲートの動的応答を一次遅れ系で近似し,
# 入力A,Bの変化に応じて時定数τを切り替えながら出力Voutを計算します。
# 出力の放電時はNMOS直列のため遅く,充電時はPMOS並列のため速く変化します。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?