|
|
# -*- 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()
|