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?

CPUをPythonで

Posted at

import numpy as np
import matplotlib.pyplot as plt
import time

#---------------------------------------------
# ① 論理ゲート / Logic Gates
#---------------------------------------------
def AND(a, b): return a & b
def OR(a, b):  return a | b
def NOT(a):    return 1 - a
def XOR(a, b): return a ^ b
def NAND(a, b): return 1 - (a & b)

#---------------------------------------------
# ② 半加算器・全加算器 / Half & Full Adder
#---------------------------------------------
def half_adder(a, b):
    s = XOR(a, b)
    c = AND(a, b)
    return s, c

def full_adder(a, b, cin):
    s1, c1 = half_adder(a, b)
    s2, c2 = half_adder(s1, cin)
    cout = OR(c1, c2)
    return s2, cout

#---------------------------------------------
# ③ 8ビット加算器 / 8-bit Ripple Carry Adder
#---------------------------------------------
def adder8(A, B):
    result = 0
    carry = 0
    for i in range(8):
        a_bit = (A >> i) & 1
        b_bit = (B >> i) & 1
        s, carry = full_adder(a_bit, b_bit, carry)
        result |= (s << i)
    return result & 0xFF, carry

#---------------------------------------------
# ④ ALU (Arithmetic Logic Unit)
#---------------------------------------------
def ALU(A, B, opcode):
    """
    opcode:
      00 = ADD
      01 = AND
      10 = OR
      11 = XOR
    """
    if opcode == 0b00:
        out, c = adder8(A, B)
    elif opcode == 0b01:
        out, c = A & B, 0
    elif opcode == 0b10:
        out, c = A | B, 0
    elif opcode == 0b11:
        out, c = A ^ B, 0
    return out, c

#---------------------------------------------
# ⑤ CPUレジスタとメモリ / Registers & Memory
#---------------------------------------------
MEM = np.zeros(32, dtype=int)  # 32 bytes of memory
PC = 0                         # Program Counter
ACC = 0                        # Accumulator
FLAG_Z = 0                     # Zero flag
CLOCK = []                     # Clock waveform record

#---------------------------------------------
# ⑥ 命令セット / Instruction Set
#---------------------------------------------
# opcode definition
# 0=LOAD, 1=ADD, 2=STORE, 3=JMP, 4=CMP, 5=SHL, 6=SHR, 7=HALT
PROGRAM = [
    [0, 1],   # LOAD MEM[1]
    [1, 2],   # ADD MEM[2]
    [4, 3],   # CMP MEM[3]
    [3, 5],   # JMP to addr 5 if Z=0
    [5, 0],   # SHL ACC
    [6, 0],   # SHR ACC
    [2, 4],   # STORE MEM[4]
    [7, 0],   # HALT
]

# メモリ初期化 / Memory initialization
MEM[1] = 10
MEM[2] = 20
MEM[3] = 30

#---------------------------------------------
# ⑦ クロックシミュレーション / Clock Simulation
#---------------------------------------------
def clock_pulse(n=20):
    t = np.arange(n)
    clk = np.array([(i % 2) for i in range(n)])
    plt.figure(figsize=(6, 1.5))
    plt.step(t, clk, where="mid")
    plt.ylim(-0.5, 1.5)
    plt.title("Clock Signal")
    plt.xlabel("Time Step")
    plt.ylabel("CLK")
    plt.show()

#---------------------------------------------
# ⑧ 命令実行ループ / Execution Loop
#---------------------------------------------
cycle = 0
while True:
    opcode, addr = PROGRAM[PC]
    print(f"CYCLE={cycle:02d} PC={PC:02d} OPCODE={opcode} ADDR={addr} ACC={ACC} Z={FLAG_Z}")

    if opcode == 0:       # LOAD
        ACC = MEM[addr]
    elif opcode == 1:     # ADD
        ACC, _ = adder8(ACC, MEM[addr])
        FLAG_Z = int(ACC == 0)
    elif opcode == 2:     # STORE
        MEM[addr] = ACC
    elif opcode == 3:     # JMP (conditional)
        if FLAG_Z == 0:
            PC = addr
            cycle += 1
            CLOCK.append(1)
            continue
    elif opcode == 4:     # CMP (compare)
        diff, _ = adder8(ACC, (256 - MEM[addr]))  # subtract via two’s complement
        FLAG_Z = int(diff == 0)
    elif opcode == 5:     # SHL (logical shift left)
        ACC = (ACC << 1) & 0xFF
        FLAG_Z = int(ACC == 0)
    elif opcode == 6:     # SHR (logical shift right)
        ACC = (ACC >> 1) & 0xFF
        FLAG_Z = int(ACC == 0)
    elif opcode == 7:     # HALT
        break

    CLOCK.append(1)
    PC += 1
    cycle += 1
    time.sleep(0.1)

print("\nFinal State:")
print(f"ACC = {ACC}")
print(f"MEM = {MEM[:8]}")
print(f"Zero Flag = {FLAG_Z}")
print(f"Cycles = {cycle}")

#---------------------------------------------
# ⑨ クロック波形の可視化 / Clock waveform plot
#---------------------------------------------
clock_pulse(len(CLOCK))

【解説】

要素 説明
JMP FLAG_Z==0 のときにPCを指定番地へジャンプ
CMP ACCとメモリ値を比較。等しければZ=1
SHL/SHR 論理シフト命令。ビット演算で再現
CLOCK 各命令実行ごとにクロック1パルスを記録し、matplotlibで波形表示

【結果例】

CYCLE=00 PC=00 OPCODE=0 ADDR=1 ACC=0 Z=0
CYCLE=01 PC=01 OPCODE=1 ADDR=2 ACC=10 Z=0
CYCLE=02 PC=02 OPCODE=4 ADDR=3 ACC=30 Z=1
CYCLE=03 PC=03 OPCODE=3 ADDR=5 ACC=30 Z=1
CYCLE=04 PC=04 OPCODE=5 ADDR=0 ACC=30 Z=0
CYCLE=05 PC=05 OPCODE=6 ADDR=0 ACC=60 Z=0
CYCLE=06 PC=06 OPCODE=2 ADDR=4 ACC=30 Z=0
CYCLE=07 PC=07 OPCODE=7 ADDR=0 ACC=30 Z=0

Final State:
ACC = 30
MEM = [0 10 20 30 30 0 0 0]
Zero Flag = 0
Cycles = 8

このプログラムは、
「命令の読み出し → 実行 → 書き戻し」+ 分岐・比較・シフト・クロック表示
をすべて含む、教育用の最小構成8ビットCPUシミュレーターです。

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?