You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cpu/ExecInstructWithText.py

430 lines
16 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# -*- encoding: utf-8 -*-
"""
@Author: packy945
@FileName: ExecInstructWithText.py
@DateTime: 2023/6/30 16:49
@SoftWare: PyCharm
"""
from RightPanel import *
from tkinter import scrolledtext
class ExecInstructWithText:
def __init__(self):
self.out = '' # 初始化综合输出框
self.play = 0 # 初始化程序运行状态
def SimDiv(self, n):
# 除法指令001000
self.clock(3) # 第三个节拍
self.SimIR_MAD() # 将地址从IR传到MAD并且SIG发出信号
self.clock(4) # 第四个节拍
self.get_mem(cpu.MAD_int) # 将MAD指定地址的内容取到MCO中
self.SimSIG_Rn(n + 2) # SIG通知R2接受数据
# 开始计算
self.clock(5) # 第五个节拍
self.SimR_ALU(n) # R1 R2 进入ALU中
self.clock(6) # 第六个节拍
ans = cpu.R_int[n] // cpu.R_int[n + 1] # 进行计算
self.SimANS_Rn(ans, n) # ALU将计算结果存到R[n]
self.out += '除法指令:' + '\n' # 输出信息到综合输出框
self.out += 'R' + str(n + 1) + ' / R' + str(n + 2) + ' -> R' + str(n + 1) + '\n' # 输出信息到综合输出框
def SimMinus(self, n):
# 减法指令000111
self.clock(3) # 第三个节拍
self.SimIR_MAD() # 将地址从IR传到MAD并且SIG发出信号
self.clock(4) # 第四个节拍
self.get_mem(cpu.MAD_int) # 将MAD指定地址的内容取到MCO中
self.SimSIG_Rn(n + 2) # SIG通知R2接受数据
# 开始计算
self.clock(5) # 第五个节拍
self.SimR_ALU(n) # R1 R2 进入ALU中
self.clock(6) # 第六个节拍
ans = cpu.R_int[n] - cpu.R_int[n + 1] # 进行计算
self.SimANS_Rn(ans, n) # ALU将计算结果存到R[n]
self.out += '减法指令:' + '\n' # 输出信息到综合输出框
self.out += 'R' + str(n + 1) + ' - R' + str(n + 2) + ' -> R' + str(n + 1) + '\n' # 输出信息到综合输出框
def SimStop(self):
# 停机指令000110
self.out += '停机指令:\n' + '停机\n' # 添加打印信息到综合输出框
cpu.__init__() # 重置cpu各项数据
init(cv) # 显示复位
self.play = 0 # 标记为未运行
self.auto_display() # 显示输出信息
def Simprint(self):
# 打印指令000101
self.clock(3) # 第三个节拍
self.SimIR_MAD() # 将地址从IR传到MAD并且SIG发出信号
self.clock(4) # 第四个节拍
self.get_mem(cpu.MAD_int) # 将MAD指定地址的内容取到MCO中
self.out += '打印指令:' + '\n' + cpu.MCO() + '\n' # 添加打印信息到综合输出框
self.auto_display() # 显示输出信息
def SimProduct(self, n):
# 乘法指令000100
self.clock(3) # 第三个节拍
self.SimIR_MAD() # 将地址从IR传到MAD并且SIG发出信号
self.clock(4) # 第四个节拍
self.get_mem(cpu.MAD_int) # 将MAD指定地址的内容取到MCO中
self.SimSIG_Rn(n + 2) # SIG通知R2接受数据
# 开始计算
self.clock(5) # 第五个节拍
self.SimR_ALU(n) # R1 R2 进入ALU中
self.clock(6) # 第六个节拍
ans = cpu.R_int[n] * cpu.R_int[n + 1] # 进行计算
self.SimANS_Rn(ans, n) # ALU将计算结果存到R[n]
self.out += '乘法指令:' + '\n' # 输出信息到综合输出框
self.out += 'R' + str(n + 1) + ' x R' + str(n + 2) + ' -> R' + str(n + 1) + '\n' # 输出信息到综合输出框
def SimAddr(self, n):
# 加法指令000011
self.clock(3) # 第三个节拍
self.SimIR_MAD() # 将地址从IR传到MAD并且SIG发出信号
self.clock(4) # 第四个节拍
self.get_mem(cpu.MAD_int) # 将MAD指定地址的内容取到MCO中
self.SimSIG_Rn(n + 2) # SIG通知Rn+1接受数据
# 开始计算
self.clock(5) # 第五个节拍
self.SimR_ALU(n) # R[n] R[n+1] 进入ALU中
self.clock(6) # 第六个节拍
# 记录计算结果到ans中
ans = cpu.R_int[n] + cpu.R_int[n + 1]
self.SimANS_Rn(ans, n) # ALU将计算结果存到Rn
self.out += '加法指令:' + '\n' # 输出信息到综合输出框
self.out += 'R' + str(n + 1) + ' + R' + str(n + 2) + ' -> R' + str(n + 1) + '\n' # 输出信息到综合输出框
def SimPut(self, n):
# 000010存数指令(R1)
# 010010存数指令(R2)
# 100010存数指令(R3)
# 110010存数指令(R4)
self.clock(3) # 第三个节拍
self.SimIR_MAD() # 将地址从IR传到MAD并且SIG发出信号
self.clock(4) # 第四个节拍
self.mark_MEM() # 标记MAD对应的存储单元
self.SinRn_MCO(n) # Rn->MCO
self.SimMCO_MEM() # MCO->对应的存储单元
self.out += '存数指令:' + '\n' # 输出信息到综合输出框
self.out += 'R' + str(n + 1) + ' -> SimMem[' + str(cpu.MAD_int) + ']' + '\n' # 输出信息到综合输出框
def SimGet(self, n):
# 000001取数指令(R1) n = 0
# 010001取数指令(R2) n = 1
# 100001取数指令(R3) n = 2
# 110001取数指令(R4) n = 3
self.clock(3) # 第三个节拍
self.SimIR_MAD() # 将地址从IR传到MAD并且SIG发出信号
self.clock(4) # 第四个节拍
self.get_mem(cpu.MAD_int) # 将MAD指定地址的内容取到MCO中
self.SimSIG_Rn(n + 1) # SIG通知R1接受数据
self.out += '取数指令:' + '\n' # 输出信息到综合输出框
self.out += 'SimMem[' + str(cpu.MAD_int) + '] -> R' + str(n + 1) + '\n' # 输出信息到综合输出框
def clock(self, n):
cpu.CLO(n - 1) # 更改cpu内时钟刻的信息
cl.clo_mark(cv) # 根据cpu显示时钟刻
time.sleep(cpu.time) # 定格一段时间
def print_mark(self, lines):
for l in lines: # 遍历要输出的线的信息
self.out += l.replace('_', '->') + '\n' # 将信息显示到综合输出框
self.auto_display() # 显示综合输出框
time.sleep(cpu.time) # 定格一段时间
def auto_display(self):
# 自动运行窗口
for w in root_right.winfo_children():
w.destroy()
# 清除右侧组件
# 右侧窗口标题
lab = tk.Label(root_right, text="执行指令(仅寄存器)", bg=WHITE, fg=BLACK, font=('微软雅黑', 18))
lab.place(relx=0, rely=0.02, width=250, height=30)
y0 = 0.1
# 开始运行程序按钮
start = tk.Button(root_right, text="自动运行程序", bg=WHITE, fg=BLACK, font=('微软雅黑', 12),
command=lambda: self.exec_instruct_with_text())
start.place(relx=0.1, rely=0.05 + y0, width=200, height=30)
if self.play == 1:
start['state'] = DISABLED
else:
start['state'] = NORMAL
# 显示当时正在进行的操作码(INSCODE)
lab = tk.Label(root_right, text="当前操作码:", bg=WHITE, fg=BLACK, font=('微软雅黑', 12), anchor=W)
lab.place(relx=0.1, rely=0.1 + y0, width=120, height=30)
lab2 = tk.Label(root_right, text=cpu.CODE(), bg=BLUE, fg=BLACK, font=('微软雅黑', 12))
lab2.place(relx=0.1, rely=0.15 + y0, width=200, height=30)
# 显示当时正在进行的操作名称
command = ['取指令', '取数指令', '存数指令', '加法指令', '乘法指令', '打印指令', '停机指令', '减法指令',
'除法指令', '跳转指令']
lab = tk.Label(root_right, text="正在执行指令:", bg=WHITE, fg=BLACK, font=('微软雅黑', 12), anchor=W)
lab.place(relx=0.1, rely=0.2 + y0, width=120, height=30)
lab2 = tk.Label(root_right, text=command[cpu.code % 16], bg=BLUE, fg=BLACK, font=('微软雅黑', 12))
lab2.place(relx=0.1, rely=0.25 + y0, width=200, height=30)
# 综合输出框,进行打印指令与停机指令的相应输出
lab = tk.Label(root_right, text="综合输出框:", bg=WHITE, fg=BLACK, font=('微软雅黑', 12), anchor=W)
lab.place(relx=0.1, rely=0.3 + y0, width=120, height=30)
scr = scrolledtext.ScrolledText(root_right, fg=BLACK, font=('微软雅黑', 12,))
scr.place(relx=0.1, rely=0.35 + y0, width=200, height=300)
scr.insert('end', self.out) # 末尾插入
scr.config(state=DISABLED) # 设置文本框为 “不能编辑”
scr.see(END) # 设置视图为最后一行
# lab2 = tk.Label(root_right, text=self.out, bg=BLUE, fg=BLACK, font=('微软雅黑', 12), anchor=N)
# lab2.place(relx=0.1, rely=0.35 + y0, width=200, height=150)
# 清空中和输出框按钮
B = tk.Button(root_right, text="清空", bg=WHITE, fg=BLACK, font=('微软雅黑', 12),
command=lambda: self.out_clear())
B.place(relx=0.5, rely=0.3 + y0, width=50, height=30)
def out_clear(self):
self.out = ''
self.auto_display()
# 执行一条指令
def exec_instruct_with_text(self):
while 1:
self.play = 1 # 更新系统状态为正在运行
self.auto_display() # 显示自动执行的输出框
self.get() # 执行取数指令时钟前2个节拍
code = cpu.code # 读取当前指令
self.auto_display() # 显示自动执行的输出框
if code % 16 == 1: # 000001取数指令(R1)
self.SimGet(code // 16)
elif code % 16 == 2: # 000010存数指令(R1)
self.SimPut(code // 16)
elif code % 16 == 3: # 000011加法指令 op = 0(R1)
self.SimAddr(code // 16)
elif code % 16 == 4: # 000100乘法指令 op = 2
self.SimProduct(code // 16)
elif code == 5: # 打印指令000101
self.Simprint()
elif code == 6: # 停机指令000110
self.SimStop()
break
elif code % 16 == 7: # 000111减法指令 op = 1
self.SimMinus(code // 16)
elif code % 16 == 8: # 001000除法指令 op = 3
self.SimDiv(code // 16)
else:
self.SimStop()
break
cpu.code = 0 # 更新指令为取数指令
si.init(cv, root)
def SimIR_MAD(self):
si.MEM(cv, 1)
self.print_mark(['IR_MAD', 'SIG_MEM'])
time.sleep(cpu.time)
si.MEM(cv, 0)
IR = cpu.IR()
sum = 0
for i in range(11):
if IR[i + 6] == ' ':
continue
sum *= 2
sum += int(IR[i + 6])
cpu.MAD_int = sum
mem.show(cv, root)
si.init(cv, root)
def SimMEM_MCO(self):
cpu.MCO_int = cpu.str_int(cpu.SimMem[cpu.MAD_int])
mem.show(cv, root)
def SimPC_SIG(self):
self.print_mark(['PC_SIG'])
PC = cpu.PC()
code = 0
for i in range(6):
code *= 2
code += int(PC[i])
cpu.code = code
si.init(cv, root)
def SimPC_MAD(self):
PC = cpu.PC()
sum = 0
for i in range(11):
if PC[i + 6] == ' ':
continue
sum *= 2
sum += int(PC[i + 6])
cpu.MAD_int = sum
mem.show(cv, root)
si.init(cv, root)
def SimMCO_IR(self):
time.sleep(cpu.time)
si.IR(cv, 1)
self.print_mark(['MCO_IR', 'SIG_IR'])
time.sleep(cpu.time)
si.IR(cv, 0)
cpu.IR_int = cpu.MCO_int
si.init(cv, root)
cl.init(cv, root)
def SimIR_SIG(self):
self.print_mark(['IR_SIG'])
time.sleep(cpu.time)
IR = cpu.IR()
code = 0
for i in range(6):
code *= 2
code += int(IR[i])
# print(code)
cpu.code = code
si.init(cv, root)
def PC_1(self):
si.PC(cv, 1)
time.sleep(cpu.time)
self.print_mark(['SIG_PC'])
time.sleep(cpu.time)
si.PC(cv, 0)
cpu.PC_int += 1
cl.init(cv, root)
def SimSIG_MAD(self):
si.MEM(cv, 1)
self.print_mark(['PC_MAD', 'SIG_MEM'])
time.sleep(cpu.time)
si.MEM(cv, 0)
def get(self): # 000000为取指令
self.clock(1) # 第一个节拍
self.SimPC_SIG() # PC->SIG
self.SimSIG_MAD() # 将地址传到MAD并且SIG发出信号
self.SimPC_MAD() # PC传参数给MAD
self.clock(2) # 第二个节拍
self.get_mem(cpu.MAD_int) # 将MAD指定地址的内容取到MCO中
self.SimMCO_IR() # mco把值传给IR
self.SimIR_SIG() # IR把CODE值传给SIG
self.clock(3) # 第三个节拍
self.PC_1() # PC+1
self.out += '取指令:' + '\n' + cpu.CODE() + '\n' # 添加打印信息到综合输出框
self.auto_display() # 显示输出信息
def SimSIG_Rn(self, n):
# SIG->R[n]
eval('si.R' + str(n) + '(cv, 1)')
eval("self.print_mark(['SIG_R" + str(n) + "', 'MCO_R" + str(n) + "'])")
time.sleep(cpu.time)
eval('si.R' + str(n) + '(cv, 0)')
si.init(cv, root)
# 将Mcontent中的数字存到R中
cpu.R_int[n - 1] = cpu.MCO_int
alu.init(cv, root)
def mark_MEM(self):
self.print_mark(["MAD_MEM"])
for j in range(20):
cpu.SimMARK[j] = False
cpu.SimMARK[cpu.MAD_int] = True
mem.mark(cv)
def SinRn_MCO(self, n):
eval('self.print_mark(["R' + str(n + 1) + '_MCO"])')
# self.print_mark(["R1_MCO"])
cpu.MCO_int = cpu.R_int[n]
mem.show(cv, root)
alu.init(cv, root)
time.sleep(cpu.time)
self.print_mark(["MCO_MEM"])
def SimMCO_MEM(self):
cpu.SimMem[cpu.MAD_int] = bin(cpu.MCO_int).replace('0b', '').zfill(16)
mem.show(cv, root)
time.sleep(cpu.time)
cpu.SimMARK[cpu.MAD_int] = False
mem.mark(cv)
def SimR_ALU(self, n):
# 高亮显示R1->ALU, R2->ALU
eval('self.print_mark(["R' + str(n + 1) + '_ALU1", "R' + str(n + 2) + '_ALU2"])')
time.sleep(cpu.time)
alu.init(cv, root)
time.sleep(cpu.time)
# SIG向ALU运算器发出指令
self.print_mark(["SIG_ALU"])
def SimANS_Rn(self, ans, n):
eval('self.print_mark(["ALU_R' + str(n + 1) + '"])')
time.sleep(cpu.time)
# 将运算结果存入R1中
cpu.R_int[n] = ans
alu.init(cv, root)
def get_mem(self, num):
# 将MAD指定地址的内容取到MCO中
self.print_mark(["MAD_MEM"])
for j in range(20):
cpu.SimMARK[j] = False
cpu.SimMARK[num] = True
mem.mark(cv)
self.print_mark(["MEM_MCO"])
self.SimMEM_MCO()
cpu.SimMARK[num] = False
mem.mark(cv)
def exec_test_program():
Program = [
'0000010000001000',
'0000110000001010',
'0001000000001001',
'0001000000001000',
'0000110000001011',
'0000100000001100',
'0001010000001100',
'0001100000000000',
'0000000000000101',
'0000000000001001',
'0000000000000110',
'0000000000001000'
] # 输入题目要求的程序
for i in range(len(Program)):
cpu.SimMem[i] = Program[i] # 将上述程序装载入仿真存储器中
cpu.PC_int = 0 # 设置PC值为“00000000 00000000”
init(cv) # 初始化cpu
run_text = ExecInstructWithText() # 实例化类
run_text.auto_display() # 开始执行完整一段程序
root.mainloop() # 执行可视化
if __name__ == "__main__":
cpu.time = 0.05
exec_test_program()