2024-04-29 16:00:03 +08:00
|
|
|
|
import queue
|
|
|
|
|
from Memory import Memory
|
2024-04-29 22:03:14 +08:00
|
|
|
|
from error import *
|
2024-04-29 16:00:03 +08:00
|
|
|
|
import pathlib
|
|
|
|
|
import program
|
|
|
|
|
import importlib
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Core:
|
|
|
|
|
def __init__(self, id, registers: int, dtMemory: int, cmdMemory: int):
|
|
|
|
|
self.id = id
|
|
|
|
|
# 创建存储器
|
|
|
|
|
self.registers = Memory(registers)
|
|
|
|
|
self.dtMemory = Memory(dtMemory)
|
|
|
|
|
self.cmdMemory = Memory(cmdMemory)
|
|
|
|
|
|
|
|
|
|
# 设置存储器
|
|
|
|
|
self.registers.name = f"寄存器 - Core{id}"
|
|
|
|
|
self.dtMemory.name = f"数据内存 - Core{id}"
|
|
|
|
|
self.cmdMemory.name = f"程序内存 - Core{id}"
|
|
|
|
|
|
|
|
|
|
self.pc = 0 # 程序计数器
|
|
|
|
|
self.stack = queue.LifoQueue(maxsize=10 * self.registers.size) # 栈
|
|
|
|
|
|
|
|
|
|
self.ASMModule = []
|
|
|
|
|
self.ASMs = {}
|
|
|
|
|
|
|
|
|
|
for file in pathlib.Path("ASM").iterdir():
|
|
|
|
|
if file.is_dir():
|
|
|
|
|
continue
|
|
|
|
|
module = "ASM." + file.name.split(".")[0]
|
|
|
|
|
module = importlib.import_module(module)
|
|
|
|
|
for cmd in module.CMDs:
|
|
|
|
|
self.ASMs[cmd] = module
|
|
|
|
|
|
|
|
|
|
def loadProgram(self, code):
|
|
|
|
|
# 加载程序至cmdMemroy
|
|
|
|
|
self.cmdMemory[: len(code)] = code
|
|
|
|
|
|
|
|
|
|
def fetchInstruction(self):
|
|
|
|
|
# 取指令
|
|
|
|
|
if self.pc < len(self.cmdMemory):
|
|
|
|
|
instruction = self.cmdMemory[self.pc]
|
|
|
|
|
self.pc += 1
|
|
|
|
|
return instruction
|
|
|
|
|
else:
|
|
|
|
|
return None # 返回None表示程序已经执行完毕
|
|
|
|
|
|
|
|
|
|
def init(self):
|
|
|
|
|
# 初始化内存和寄存器
|
|
|
|
|
self.pc = 0
|
|
|
|
|
self.dtMemory.init()
|
|
|
|
|
self.registers.init()
|
|
|
|
|
|
|
|
|
|
def executeInstruction(self, instruction):
|
|
|
|
|
# 执行指令
|
|
|
|
|
if instruction is None:
|
|
|
|
|
return False # 程序已执行完毕,返回False
|
2024-04-29 22:03:14 +08:00
|
|
|
|
|
2024-04-29 16:00:03 +08:00
|
|
|
|
lists = instruction.split(" ")
|
|
|
|
|
|
|
|
|
|
# 解析指令
|
|
|
|
|
opcode = lists[0] # 操作码
|
2024-04-29 22:03:14 +08:00
|
|
|
|
operand = program.Operand(lists[1:], self) # 操作数
|
2024-04-29 16:00:03 +08:00
|
|
|
|
|
|
|
|
|
if opcode in self.ASMs:
|
|
|
|
|
ins = getattr(self.ASMs[opcode], opcode)
|
2024-04-29 22:03:14 +08:00
|
|
|
|
ret = ins(self, operand)
|
|
|
|
|
if ret is None:
|
|
|
|
|
return True
|
|
|
|
|
elif ret is False:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
|
|
raise InvalidInstruction()
|
2024-04-29 16:00:03 +08:00
|
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
|
# 开始执行
|
|
|
|
|
while True:
|
|
|
|
|
instruction = self.fetchInstruction()
|
|
|
|
|
if not self.executeInstruction(instruction):
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class MultiCoreCPU:
|
|
|
|
|
def __init__(self, num_cores, registers, dt_memory, cmd_memory_size=-1):
|
|
|
|
|
self.cores = []
|
|
|
|
|
|
|
|
|
|
self.programs = queue.Queue(maxsize=num_cores)
|
|
|
|
|
if cmd_memory_size <= 0:
|
|
|
|
|
cmd_memory_size = dt_memory.size
|
|
|
|
|
for i in range(num_cores):
|
|
|
|
|
cmdMem = Memory(cmd_memory_size)
|
|
|
|
|
core = Core(i, registers, dt_memory, cmdMem)
|
|
|
|
|
self.cores.append(core)
|
|
|
|
|
|
|
|
|
|
def load_program(self, program):
|
|
|
|
|
self.programs.put_nowait(program)
|
|
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
|
oldCore = -1
|
|
|
|
|
while not self.programs.empty():
|
|
|
|
|
oldCore += 1
|
|
|
|
|
self.cores[oldCore].loadProgram(self.programs.get())
|
|
|
|
|
|
|
|
|
|
def halt(self):
|
|
|
|
|
for core in self.cores:
|
|
|
|
|
core.is_running = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CPU(Core):
|
|
|
|
|
def __init__(self, registers, dtMemory, cmdMemory):
|
|
|
|
|
super().__init__(0, registers, dtMemory, cmdMemory)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
cpu = CPU(registers=64, dtMemory=1024, cmdMemory=1024)
|
|
|
|
|
program.Operand(["r0"], cpu)[0].set(2)
|
2024-04-29 22:03:14 +08:00
|
|
|
|
f = open('Example/加法器.txt')
|
|
|
|
|
code = f.read().split('\n')
|
|
|
|
|
cpu.loadProgram(code)
|
|
|
|
|
cpu.dtMemory.write_batch(0, [0, 1])
|
|
|
|
|
cpu.run()
|
|
|
|
|
# print(cpu.registers[0])
|