From e1ab3d938bd5b20f7fc3b7e3f4d11fa2da873c4f Mon Sep 17 00:00:00 2001 From: zart Date: Tue, 16 Apr 2024 17:21:43 +0800 Subject: [PATCH] Initial commit --- .gitignore | 4 + cpu_data.py | 132 +++++ execute_instruction.py | 1134 ++++++++++++++++++++++++++++++++++++++++ gui.py | 944 +++++++++++++++++++++++++++++++++ 4 files changed, 2214 insertions(+) create mode 100644 .gitignore create mode 100644 cpu_data.py create mode 100644 execute_instruction.py create mode 100644 gui.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..53ec7eb --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ + +.idea/ + +__pycache__/ \ No newline at end of file diff --git a/cpu_data.py b/cpu_data.py new file mode 100644 index 0000000..78d2548 --- /dev/null +++ b/cpu_data.py @@ -0,0 +1,132 @@ +def alu_op(): + ALUop = dict() + for i in '+-x÷': + ALUop[i] = False + return ALUop + + +def alu_io(): + ALUio = dict() + Register = ["R1", "R2", "R3", "R4"] + for reg in Register: + ALUio[f"{reg}_ALU_1"] = False + ALUio[f"{reg}_ALU_2"] = False + ALUio[f"ALU_{reg}"] = False + return ALUio + + +def clock_step(): + ClockStep = dict() + for i in range(6): + ClockStep[str(i + 1)] = False + return ClockStep + + +def sig_obj(): + SigObj = dict() + Register = ["R1", "R2", "R3", "R4", "IR"] + ctrl = ["ALU","ALU_1", "ALU_2", "PC+1", "Memory"] + for r in Register: + SigObj[f"Mcontent->{r}"] = [f"Mcontent->{r}", False, "DataSig"] + SigObj[f"->{r}"] = [f"->{r}", False, "CtrlSig"] + for ct in ctrl: + SigObj[f"->{ct}"] = [f"->{ct}", False, "CtrlSig"] + SigObj["IR->SigCtrl"] = ["IR->SigCtrl", False, "CtrlSig"] + SigObj["PC->Maddr"] = ["PC->Maddr", False, "DataSig"] + SigObj["IR->Maddr"] = ["IR->Maddr", False, "DataSig"] + SigObj["Memory->Mcontent"] = ["Memory->Mcontent", False, "DataSig"] + SigObj["Mcontent->PC"] = ["Mcontent->PC", False, "DataSig"] + SigObj["Mcontent->Memory"] = ["Mcontent->Memory", False, "DataSig"] + return SigObj + + +def sim_mem(): + sim_mem_ls = [] + for i in range(20): + sim_mem_ls.append(f"{0:016b}") + return sim_mem_ls + + +def bin_to_dec(binary_string, bit_width=16): + """ + 将补码二进制字符串转换为有符号数10进制,处理溢出。 + + 参数: + binary_string (str): 补码二进制字符串,例如 "1101100101101110"。 + bit_width (int): 位宽,默认为16位。 + + 返回: + int: 转换后的有符号数10进制。 + """ + if len(binary_string) > bit_width: + # 如果二进制字符串长度超出位宽,截断超出部分 + binary_string = binary_string[-bit_width:] + + # 如果最高位为1,说明是负数,先取反再加1得到绝对值的原码 + if binary_string[0] == '1': + inverted_string = ''.join('1' if bit == '0' else '0' for bit in binary_string) + absolute_value = -(int(inverted_string, 2) + 1) + else: + # 如果最高位是0,则直接转换为正数 + absolute_value = int(binary_string, 2) + + return absolute_value + + +def dec_to_bin(decimal_value, bit_width=16): + """ + 将有符号数10进制转换为补码二进制字符串,处理溢出。 + + 参数: + decimal_value (int): 有符号数10进制。 + bit_width (int): 位宽,默认为16位。 + + 返回: + str: 转换后的补码二进制字符串。 + """ + # 如果输入数据超出位宽,截断超出部分 + decimal_value = decimal_value & ((1 << bit_width) - 1) + + # 如果是负数,获取其绝对值的原码 + if decimal_value < 0: + absolute_value_binary = bin(abs(decimal_value))[2:] + + # 如果位数不足,需要在左侧补0 + if len(absolute_value_binary) < bit_width: + absolute_value_binary = '0' * (bit_width - len(absolute_value_binary)) + absolute_value_binary + + # 对绝对值的原码进行按位取反 + inverted_representation = ''.join('1' if bit == '0' else '0' for bit in absolute_value_binary) + + # 将取反后的二进制表示加上1,得到补码表示 + binary_representation = format(int(inverted_representation, 2) + 1, f'0{bit_width}b') + else: + # 如果是正数,直接转换为二进制 + binary_representation = bin(decimal_value)[2:] + + # 如果位数不足,需要在左侧补0 + if len(binary_representation) < bit_width: + binary_representation = '0' * (bit_width - len(binary_representation)) + binary_representation + + return binary_representation + + +ALUio = alu_io() +ALUop = alu_op() +ClockStep = clock_step() +SigObj = sig_obj() +SimMem = sim_mem() + +if __name__ == '__main__': + ALUio = alu_io() + print(ALUio) + ALUop = alu_op() + print(ALUop) + ClockStep = clock_step() + print(ClockStep) + SigObj = sig_obj() + print(SigObj) + SimMem = sim_mem() + print(SimMem) + + diff --git a/execute_instruction.py b/execute_instruction.py new file mode 100644 index 0000000..fa1ae72 --- /dev/null +++ b/execute_instruction.py @@ -0,0 +1,1134 @@ +# -*- encoding: utf-8 -*- +""" +@File : execute_instruction.py +@License : (C)Copyright 2021-2023 + +@Modify Time @Author @Version @Description +------------ ------- -------- ----------- +2023/11/10 17:14 zart20 1.0 None +""" +import re +import time +from tkinter import filedialog +from gui import * + +inscode_map = { + '取数': '000001', '存数': '000010', '加法': '000011', '减法': '000111', + '乘法': '000100', '除法': '001000', '打印': '000101', '停机': '000110', + '跳转': '001001' +} + + +class ExecInstructWithText: + def __init__(self): + self.wait_time = 0.1 # 节拍计时 + self.gui = GUISim() # 主界面显示 + self.alu = self.gui.alu # alu实例化 + self.memo = self.gui.memo # memo 实例化 + self.sing = self.gui.sigctrl # 信号实例化 + self.textbox = self.gui.textbox # 信息输入框实例化 + self.regs = {"R1": self.alu.r1, "R2": self.alu.r2, "R3": self.alu.r3, "R4": self.alu.r4} # 寄存器值槽 + self.sing_times1 = 0 # 取数指令的节拍计数变量 + self.sing_times2 = 0 # 存数指令的节拍 + self.menu_test() + self.show_msg() # 显示消息框 + self.manual_opera_step = 0 + self.entry_replace(self.sing.pc_reg, f"{0:016b}") + self.ctrl_stop = False + + self.register_mapping = { + "01": (self.alu.r2, "mco-r2"), + "10": (self.alu.r3, "mco-r3"), + "11": (self.alu.r4, "mco-r4"), + "00": (self.alu.r1, "mco-r1"), + } + + # self.textbox.msg_box("kkxs") + + def reset(self): + self.__init__() + self.textbox.clear() + + def stop_exec(self): + if self.ctrl_stop == True: + self.ctrl_stop = False + self.ctrl_exec.config(text="暂停执行") + self.exec_auto() + else: + self.ctrl_stop = True + self.ctrl_exec.config(text="继续执行") + + def show_msg(self): + """显示固定信息""" + self.textbox.reset_button.configure(command=self.reset) + self.textbox.canvas.delete("button") + self.textbox.main_msg_box("系统控制", 0, 0) + self.textbox.create_button("自动执行指令", x=1, y=0, command=self.exec_auto) + self.ctrl_exec = self.textbox.create_button("暂停执行", x=1, y=1, command=self.stop_exec) + self.prev_button = self.textbox.create_button("上一步", x=2, y=0, command=self.prev) + self.next_button = self.textbox.create_button("下一步", x=2, y=1, command=self.exec_next) + page2 = self.textbox.page2 + self.textbox.main_msg_box("运算器控制", 0, 0, page2) + self.textbox.create_button("更改运算", x=1, y=0, frame=page2, command=self.manual_opera_io) + self.textbox.create_button("更改输入输出", x=1, y=1, frame=page2, command=self.manual_opera_io) + self.textbox.create_button("更改R1-R4", x=3, y=1, frame=page2, command=self.manual_reg) + self.alu_reg = self.textbox.create_combobox(x=3, y=0, frame=page2, values=["R1", "R2", "R3", "R4"]) + self.alu_reg_value = self.textbox.create_entry(x=2, y=0, frame=page2) + page3 = self.textbox.page3 + self.textbox.main_msg_box("信号控制", 0, 0, page3) + self.textbox.create_button("自动连续执行", x=1, y=0, frame=page3, command=self.exec_auto) + self.textbox.create_button("单指令执行", x=2, y=0, frame=page3, command=self.one_instruct) + self.textbox.create_button("更改信号", x=3, y=0, frame=page3, command=self.modify_sing) + self.textbox.create_button("更改REG", x=1, y=1, frame=page3, command=self.modify_ctrl_reg) + sing_obj = ['->R1', '->R2', '->R3', '->R4', '->IR', '->ALU', '->PC+1', '->Memory'] + self.sing_single = self.textbox.create_combobox(x=3, y=1, frame=page3, values=list(sing_obj)) + sing_inscode = inscode_map.keys() # 获取指令 + self.sing_instruct = self.textbox.create_combobox(x=2, y=1, frame=page3, values=list(sing_inscode)) + page4 = self.textbox.page4 + self.textbox.main_msg_box("内存控制", 0, 0, page4) + self.textbox.create_button("更改内存REG", x=1, y=0, frame=page4, command=self.modify_memo_reg) + self.textbox.create_button("更改部分储存", x=1, y=1, frame=page4, command=self.manual_input) + self.textbox.create_button("装载一段程序", x=2, y=0, frame=page4, command=self.read_file) + self.textbox.create_button("装载一批数据", x=2, y=1, frame=page4, command=self.load_many_data) + def one_instruct(self): + inscode = self.sing_instruct.get() + inscode = inscode_map[inscode] + self.exe_one_instruct(inscode) + def modify_sing(self): + sing = self.sing_single.get() + cpu_data.SigObj[sing][1] = True + self.sing.show_singe() + print(sing) + def manual_reg(self): # 手动更改寄存器 + reg = self.alu_reg.get() + value = self.alu_reg_value.get() + self.entry_replace(self.regs[reg], value) + self.textbox.send_msg("更改成功") + def modify_memo_reg(self): # 更改控制器寄存器 + def n_mco_button(): + value = self.n_mco.get() + self.entry_replace(self.memo.mco, value) + self.textbox.send_msg("更改成功") + def n_mad_button(): + value = self.n_mad.get() + self.memo.show_maddr(value) + self.textbox.send_msg("更改成功") + top = tk.Toplevel() + top.title("内存寄存器修改") + # top.geometry(f"{460}x{200}") + tk.Label(top, text="新Mcontent值:", font=('微软雅黑', 16)).grid(row=0, column=0, padx=5, pady=5, sticky="e") + self.n_mco = tk.Entry(top, font=('微软雅黑', 12), width=16) + self.n_mco.grid(row=0, column=1, padx=5, pady=5) + tk.Button(top, text="确定", font=('微软雅黑', 12), width=10, bg="white", command=n_mco_button) \ + .grid(row=0, column=2, padx=5, pady=5) + + tk.Label(top, text="新Maddr值:", font=('微软雅黑', 16)).grid(row=1, column=0, padx=5, pady=5, sticky="e") + self.n_mad = tk.Entry(top, font=('微软雅黑', 12), width=16) + self.n_mad.grid(row=1, column=1, padx=5, pady=5) + tk.Button(top, text="确定", font=('微软雅黑', 12), width=10, bg="white", command=n_mad_button) \ + .grid(row=1, column=2, padx=5, pady=5) + def load_many_data(self): # 更改控制器寄存器 + def load_memo_finish(): + start = self.memo_addr.get() + start = int(start, 16) + data = self.memo_text.get("1.0", "end") + data = data.split("\n") + for index, line in enumerate(data): + line = line.replace("\n", "") + if index+start < 20 and re.match("^[01]{16}$", line): + self.memo.mem_save(index+start, line, load=True) + self.textbox.send_msg(f"【{index+start:02X}】数据装载完成") + else: + if index+start > 19: + break + elif line == "": + self.textbox.send_msg(f"【{index+start:02X}】数据异常请检查") + top = tk.Toplevel() + top.title("装载一批数据") + top.geometry(f"{245}x{330}") + tk.Label(top, text="起始地址:", font=('微软雅黑', 16)).grid(row=0, column=0, padx=5, pady=5, sticky="e") + self.memo_addr = ttk.Combobox(top, values=[f"{i:02X}" for i in range(20)], width=10, font=('微软雅黑', 12)) + self.memo_addr.grid(row=0, column=1, padx=5, pady=5) + self.memo_text = tk.Text(top, font=('微软雅黑', 12), width=16, height=10) + self.memo_text.grid(row=1, column=0, columnspan=2, padx=5, pady=5) + tk.Button(top, text="确定", font=('微软雅黑', 12), width=10, bg="white", command=load_memo_finish) \ + .grid(row=2, column=1, padx=5, pady=5) + def modify_ctrl_reg(self): # 更改控制器寄存器 + def n_pc_button(): + value = self.n_pc.get() + self.entry_replace(self.sing.pc_reg, value) + self.textbox.send_msg("更改成功") + def n_ir_button(): + value = self.n_ir.get() + self.entry_replace(self.sing.ir_reg, value) + self.sing.ir_reg_value() # 更新IR的值 + self.textbox.send_msg("更改成功") + + def n_clock_button(): + value = self.n_clock.get() + self.sing.clo_mark(int(value) - 1) + self.textbox.send_msg("更改成功") + + def n_inscode_button(): + value = self.n_inscode.get() + self.entry_replace(self.sing.ins, value) + self.textbox.send_msg("更改成功") + + top = tk.Toplevel() + top.title("控制器控制") + top.geometry(f"{450}x{200}") + tk.Label(top, text="新PC值:", font=('微软雅黑', 16)).grid(row=0, column=0, padx=5, pady=5, sticky="e") + self.n_pc = tk.Entry(top, font=('微软雅黑', 12), width=16) + self.n_pc.grid(row=0, column=1, padx=5, pady=5) + tk.Button(top, text="确定", font=('微软雅黑', 12), width=10, bg="white", command=n_pc_button) \ + .grid(row=0, column=2, padx=5, pady=5) + tk.Label(top, text="新IR值:", font=('微软雅黑', 16)).grid(row=1, column=0, padx=5, pady=5, sticky="e") + self.n_ir = tk.Entry(top, font=('微软雅黑', 12), width=16) + self.n_ir.grid(row=1, column=1, padx=5, pady=5) + tk.Button(top, text="确定", font=('微软雅黑', 12), width=10, bg="white", command=n_ir_button) \ + .grid(row=1, column=2, padx=5, pady=5) + tk.Label(top, text="新Clock值:", font=('微软雅黑', 16)).grid(row=2, column=0, padx=5, pady=5, sticky="e") + self.n_clock = tk.Entry(top, font=('微软雅黑', 12), width=16) + self.n_clock.grid(row=2, column=1, padx=5, pady=5) + tk.Button(top, text="确定", font=('微软雅黑', 12), width=10, bg="white", command=n_clock_button) \ + .grid(row=2, column=2, padx=5, pady=5) + tk.Label(top, text="新Inscode值:", font=('微软雅黑', 16)).grid(row=3, column=0, padx=5, pady=5, sticky="e") + self.n_inscode = tk.Entry(top, font=('微软雅黑', 12), width=16) + self.n_inscode.grid(row=3, column=1, padx=5, pady=5) + tk.Button(top, text="确定", font=('微软雅黑', 12), width=10, bg="white", command=n_inscode_button) \ + .grid(row=3, column=2, padx=5, pady=5) + + def manual_opera_io(self): # 手动更改运算 + values = list(cpu_data.ALUio.keys()) + + def ok(): + in1_val = self.in1.get() + in2_val = self.in2.get() + out_val = self.out.get() + opera_val = self.opera_op.get() + + for io in cpu_data.ALUio: + cpu_data.ALUio[io] = False # 重置所有输入输出 + cpu_data.ALUio[in1_val] = True + cpu_data.ALUio[in2_val] = True + cpu_data.ALUio[out_val] = True + self.alu.show_alu_line(cpu_data.ALUio) # 显示数据控制线 + + for op in cpu_data.ALUop: + cpu_data.ALUop[op] = False # 重置所有操作 + cpu_data.ALUop[opera_val] = True + self.alu.alu_operation() + + top = tk.Toplevel() + top.title("运算器控制") + top.geometry(f"{360}x{180}") + tk.Label(top, text="ALU输入", font=('微软雅黑', 16)).grid(row=0, column=0, padx=5, pady=5) + tk.Label(top, text="ALU输出", font=('微软雅黑', 16)).grid(row=1, column=0, padx=5, pady=5) + tk.Label(top, text="运算符", font=('微软雅黑', 16)).grid(row=2, column=0, padx=5, pady=5) + self.in1 = ttk.Combobox(top, values=values, width=10, font=('微软雅黑', 12)) + self.in1.set(values[0]) # 设置默认选项 + self.in1.grid(row=0, column=1, padx=5, pady=5) + self.in2 = ttk.Combobox(top, values=values, width=10, font=('微软雅黑', 12)) + self.in2.set(values[0]) # 设置默认选项 + self.in2.grid(row=0, column=2, padx=5, pady=5) + self.out = ttk.Combobox(top, values=values, width=10, font=('微软雅黑', 12)) + self.out.set(values[0]) # 设置默认选项 + self.out.grid(row=1, column=1, padx=5, pady=5) + self.opera_op = ttk.Combobox(top, values=["+", "-", "x", "÷"], width=10, font=('微软雅黑', 12)) + self.opera_op.set("+") # 设置默认选项 + self.opera_op.grid(row=2, column=1, padx=5, pady=5) + + tk.Button(top, text="确定", font=('微软雅黑', 12), width=10, bg="white", command=ok) \ + .grid(row=8, column=1, padx=5, pady=5) + + def menu_test(self): + menu_bar = tk.Menu(root) + root.config(menu=menu_bar) + + font = ("son", 12) + + lode_menu = tk.Menu(menu_bar, tearoff=0) + menu_bar.add_cascade(label="装载程序", menu=lode_menu, font=font) + lode_menu.add_command(label="从文件装载", command=self.read_file, font=font) + lode_menu.add_command(label="手动输入", command=self.manual_input, font=font) + + file_menu = tk.Menu(menu_bar, tearoff=0) + menu_bar.add_cascade(label="单指令执行", menu=file_menu) + + file_menu.add_command(label="取数", command=lambda: self.exe_one_instruct("000001")) + file_menu.add_command(label="存数", command=lambda: self.exe_one_instruct("000010")) + file_menu.add_command(label="加法", command=lambda: self.exe_one_instruct("000011")) + file_menu.add_command(label="减法", command=lambda: self.exe_one_instruct("000111")) + file_menu.add_command(label="乘法", command=lambda: self.exe_one_instruct("000100")) + file_menu.add_command(label="除法", command=lambda: self.exe_one_instruct("001000")) + file_menu.add_command(label="打印", command=lambda: self.exe_one_instruct("000101")) + file_menu.add_command(label="停机", command=lambda: self.exe_one_instruct("000110")) + file_menu.add_command(label="顺序执行", command=lambda: self.exec_auto()) + + def entry_replace(self, entry: tk.Entry, value): + entry.delete(0, tk.END) + entry.insert(0, value) + + def binary_addition(self, num1, num2): + result = bin_to_dec(num1) + bin_to_dec(num2) # 转为10进制的加 + result_binary = dec_to_bin(result) + return result_binary + + def binary_subtraction(self, num1, num2): + result = bin_to_dec(num1) - bin_to_dec(num2) # 转为10进制的减 + result_binary = dec_to_bin(result) + return result_binary + + def binary_multiplication(self, num1, num2): + result = bin_to_dec(num1) * bin_to_dec(num2) # 转为10进制的加 + result_binary = dec_to_bin(result) + return result_binary + + def binary_division(self, dividend, divisor): + quotient = bin_to_dec(dividend) // bin_to_dec(divisor) + result_binary = dec_to_bin(quotient) + return result_binary + # remainder = bin(int(dividend, 2) % int(divisor, 2))[2:] + + def reg_enhance_display(self, rx): + """强化显示R1-R4""" + self.alu.canvas.delete("reg") + for i in range(4): + if rx == f"R{i + 1}": + self.alu.canvas.create_line(365, 120 + i * 90, 513, 120 + i * 90, width=8, fill="#00FF00", tag="reg") + self.alu.canvas.create_line(365, 75 + i * 90, 513, 75 + i * 90, width=8, fill="#00FF00", tag="reg") + + def gen_opera(self, rx=None, ry=None, op=None, sing_num=None): # 一般计算规则 + """ + rx为小号寄存器,ry为大号寄存器 + 寄存器字母一定要填大写 + """ + for io in cpu_data.ALUio: + cpu_data.ALUio[io] = False # 清空ALU的数据线 + + if op is not None: + cpu_data.ALUop[op] = True # 设置ALU的操作 + + rt1, rt2 = None, None # 用于存储寄存器的实体框 + for reg, entry in self.regs.items(): # 遍历寄存器编号和寄存器实体框 + entry.config(bg=WHITE) # 寄存器恢复 + if reg == rx: + rt1 = entry + if sing_num == 4: + cpu_data.ALUio[f"{rx}_ALU_1"] = True + if reg == ry: + rt2 = entry + if sing_num == 4: + cpu_data.ALUio[f"{ry}_ALU_2"] = True + if rx is not None and ry is not None: + v1 = rt1.get() # 获取R1的值 + v2 = rt2.get() # 获取R2的值 + + if sing_num == 4: + self.alu.show_alu_line(cpu_data.ALUio) # 节拍5时显示寄存器到ALU的路线 + self.alu.alu_operation() # 显示符号 + rt1.config(bg=RED) + rt2.config(bg=RED) + if sing_num == 5: + if op == "+": + v = self.binary_addition(v1, v2) # 二进制加 + elif op == "-": + v = self.binary_subtraction(v1, v2) # 二进制减法 + elif op == "x": + v = self.binary_multiplication(v1, v2) # 二进制乘法 + elif op == "÷": + v = self.binary_division(v1, v2) # 二进制除法 + else: + v = None + # alu_line.append(f"ALU_{rx}") # 用于显示ALU的数据线 + cpu_data.ALUio[f"ALU_{rx}"] = True + + self.alu.alu_operation() # 显示符号 + self.alu.show_alu_line(cpu_data.ALUio) # 显示数据控制线 + self.entry_replace(rt1, f"{v}") # 替换R1中的值 + rt1.config(bg=RED) + + def pc_add_one(self, b16): + v = int(b16, 2) + return f"{v + 1:016b}" + + def reg_update(self): + self.sing.pc_reg.config(bg=WHITE) # 更新PC寄存器的背景显示 + self.sing.ins.config(bg=WHITE) # 更新ins背景 + self.sing.ir_reg.config(bg=WHITE) # 更新IR的颜色 + self.alu.r1.config(bg=WHITE) + self.alu.r2.config(bg=WHITE) + self.alu.r3.config(bg=WHITE) + self.alu.r4.config(bg=WHITE) + + # 储存寄存器在储存类中已经处理,这里不再重复处理 + + def read_file(self): + filename = filedialog.askopenfilename(title="选择文件", filetypes=[("TXT文件", "*.txt")]) + if filename: + with open(filename, "r", encoding="utf8") as f: + memo_line = f.readlines() # 按行读取文件信息 + for index, line in enumerate(memo_line): + line = line.replace("\n", "") # 去掉换行符 + if index < 20 and re.match("^[01]{16}$", line): + self.memo.mem_save(index, line, load=True) + else: + self.textbox.send_msg(f"【{index:02X}】数据异常请检查") + if index > 19: + break + self.textbox.send_msg("装载完成") + self.entry_replace(self.sing.pc_reg, f"{0:016b}") + + def on_inscode_select(self, event): + # 获取选择的值 + selected_value = self.inscode_input.get() + inscode = inscode_map.get(selected_value) + self.inscode_input.set(inscode) + print(selected_value) + + def load_finish(self): + self.child_window.destroy() + self.entry_replace(self.sing.pc_reg, f"{0:016b}") + self.textbox.send_msg("装载完成") + + def on_offset_select(self, event): + ox16 = self.o_value_input.get() + value = int(ox16, 16) + self.o_value_input.set(f"{value:010b}") + + def data_to_mome(self, offset_input): + data_input = self.d_value.get() + if offset_input and data_input: + offset = int(offset_input, 16) + if re.match("^-?[01]{16}$", data_input): + self.memo.mem_save(offset, data_input, load=True) + self.textbox.send_msg("数据装载完成\n" + f"{offset:02X}:{data_input}") + elif re.match("^-?\d+$", data_input) and len(data_input) < 7: # 如果是10进制数不可能多于7位 + # data_input = f"{int(data_input):016b}" + data_input = cpu_data.dec_to_bin(int(data_input)) + self.memo.mem_save(offset, data_input, load=True) + self.textbox.send_msg("数据装载完成\n" + f"{offset:02X}:{data_input}") + else: + if len(data_input) > 16: + self.textbox.send_msg(f"{data_input}不是16位数。") + else: + self.textbox.send_msg(f"{data_input}不是规范的二进制数。") + + def save_to_mome(self, offset): + inscode = self.inscode_input.get() + value = self.o_value_input.get() + if offset: + offset = int(offset, 16) + if inscode and value: + value = inscode + value + self.memo.mem_save(offset, value, load=True) + self.textbox.send_msg(f"指令装载完成\n{offset:02X}:{value}") + + def manual_input(self): + self.child_window = tk.Toplevel(root) + self.child_window.title("手动输入程序") + self.child_window.geometry("350x360") + fram_down = tk.Frame(self.child_window) + tk.Label(fram_down, text="指令输入", font=("微软雅黑", 16, "bold")).grid(row=0, column=0, columnspan=3) + fram_down.place(x=0, y=0, width=350, height=360) + offset_label = tk.Label(fram_down, text="地址", font=("微软雅黑", 16)) + offset_label.grid(row=1, column=0, sticky="nsew") + inscode_label = tk.Label(fram_down, text="指令", font=("微软雅黑", 16)) + inscode_label.grid(row=1, column=1, sticky="nsew") + o_value_label = tk.Label(fram_down, text="寻址地址", font=("微软雅黑", 16)) + o_value_label.grid(row=1, column=2, sticky="nsew") + hex_options = [f"{i:02X}" for i in range(20)] # 生成00-13的16进制选项 + offset_input = ttk.Combobox(fram_down, values=hex_options, font=("微软雅黑", 12), width=1) + offset_input.grid(row=2, column=0, sticky="nsew", padx=5) + inscode_options = list(inscode_map.keys()) + self.inscode_input = ttk.Combobox(fram_down, values=inscode_options, font=("微软雅黑", 12), width=6) + self.inscode_input.grid(row=2, column=1, sticky="nsew", padx=5) + self.inscode_input.bind("<>", self.on_inscode_select) + bin_options = [f"{i:02X}" for i in range(20)] # 生成00-13的16进制选项 + self.o_value_input = ttk.Combobox(fram_down, values=bin_options, font=("微软雅黑", 12), width=10) + self.o_value_input.grid(row=2, column=2, sticky="nsew", padx=5) + self.o_value_input.bind("<>", self.on_offset_select) + save_b = tk.Button(fram_down, text="确认", bg=RED, font=("微软雅黑", 12), + command=lambda: self.save_to_mome(offset_input.get())) + save_b.grid(row=3, column=0, columnspan=3, sticky="nsew", padx=10, pady=4) + tk.Label(fram_down, text="*" * 300, font=("微软雅黑", 16)).grid(row=4, column=0, columnspan=3) + tk.Label(fram_down, text="数据输入", font=("微软雅黑", 16, "bold")).grid(row=5, column=0, columnspan=3) + d_off = tk.Label(fram_down, text="地址", font=("微软雅黑", 16)) + d_off.grid(row=6, column=0, sticky="nsew") + d_value_lb = tk.Label(fram_down, text="数据", font=("微软雅黑", 16)) + d_value_lb.grid(row=6, column=1, columnspan=2, sticky="nsew") + hex_options = [f"{i:02X}" for i in range(20)] # 生成00-13的16进制选项 + d_off_in = ttk.Combobox(fram_down, values=hex_options, font=("微软雅黑", 12), width=1) + d_off_in.grid(row=7, column=0, sticky="nsew", padx=5) + self.d_value = tk.Entry(fram_down, font=("微软雅黑", 12)) + self.d_value.grid(row=7, column=1, columnspan=2, sticky="nsew") + self.d_value.insert(0, "支持10进制和16位进制") + d_save = tk.Button(fram_down, text="确认", bg=RED, font=("微软雅黑", 12), + command=lambda: self.data_to_mome(d_off_in.get())) + d_save.grid(row=8, column=0, columnspan=3, sticky="nsew", padx=10, pady=4) + # 配置列权重,使它们按比例占据整个宽度 + fram_down.columnconfigure(0, weight=2) + fram_down.columnconfigure(1, weight=6) + fram_down.columnconfigure(2, weight=10) + finish = tk.Button(fram_down, text="装载完成", bg=GOLD, font=("微软雅黑", 12), command=self.load_finish) + finish.grid(row=9, column=2, sticky="nsew", padx=10) + + def SimGet(self, sing_num, reg_code=None): + """取数指令""" + self.textbox.send_instr("取数") + if sing_num == 3: + self.textbox.send_msg(f"======Step{sing_num + 1}======") + self.reg_update() # 恢复寄存器 + self.sing.clo_mark(sing_num) # 显示节拍 + cpu_data.SigObj['->Memory'][1] = True + self.sing.show_singe() # 显示控制器信号 + self.gui.addr_line() # 更新地址线 + self.alu.show_alu_line() # 更新alu的数据线 + self.memo.mad_to_memo(1) # 更新mad-mome的地址线,参数为真则显示 + cpu_data.SigObj['Memory->Mcontent'][1] = True + self.gui.singe_ctrl_line() # 显示控制线 + + if reg_code in self.register_mapping: # 选择寄存器 + register, data_line = self.register_mapping[reg_code] + self.gui.data_line(data_line) + self.entry_replace(register, self.memo.mco.get()) + register.config(bg=RED) + canvas.update() + + def SimPut(self, sing_num, reg_code=None): + """存数指令""" + self.textbox.send_instr("存数") + if sing_num == 3: + self.textbox.send_msg(f"======Step{sing_num + 1}======") + if reg_code in self.register_mapping: # 选择寄存器 + register, data_line = self.register_mapping[reg_code] + mco, reg = data_line.split("-") + + self.reg_update() # 恢复寄存器 + self.sing.clo_mark(sing_num) + cpu_data.SigObj['->Memory'][1] = True + self.sing.show_singe() # 显示控制器信号 + cpu_data.SigObj['Mcontent->Memory'][1] = True + self.gui.singe_ctrl_line() + self.gui.addr_line() + # self.gui.data_line("r1-mco") + self.alu.show_alu_line() # 更新alu的数据线 + # self.memo.mad_to_memo() # 更新mad-mome的地址线,参数为真则显示 + self.memo.mco_to_memo() # 更新储存的显示显示 + + self.gui.data_line(f"{reg}-{mco}") # 重构参数 + self.entry_replace(self.memo.mco, register.get()) + register.config(bg=RED) + + self.memo.mco_to_memo() # 显示 + canvas.update() + + def SimAddr(self, sing_num, reg_code=None): + """加法指令""" + self.textbox.send_instr("加法") + + if sing_num == 3: + self.textbox.send_msg(f"======Step{sing_num + 1}======") + if reg_code in self.register_mapping: # 选择寄存器 + register, data_line = self.register_mapping[reg_code] + mco, reg = data_line.split("-") + reg = int(reg[-1]) + 1 + + self.reg_update() + self.sing.clo_mark(sing_num) # 显示节拍 + cpu_data.SigObj['->Memory'][1] = True + self.sing.show_singe() # 显示控制器信号 + cpu_data.SigObj[f'Mcontent->R{reg}'][1] = True + cpu_data.SigObj[f'->R{reg}'][1] = True + self.gui.singe_ctrl_line() # 显示控制线 + self.gui.addr_line() # 更新地址线 + self.memo.mad_to_memo(1) # 更新mad-mome的地址线,参数为真则显示 + self.gui.data_line(f"mco-r{reg}") # 更新数据线 + self.alu.show_alu_line() # 更新alu的数据线 + + # self.memo.mad_to_memo() # 显示memo动画 + self.entry_replace(eval(f'self.alu.r{reg}'), self.memo.mco.get()) # 更新显示R1中的值 + canvas.update() + + if sing_num == 4: + self.textbox.send_msg(f"======Step{sing_num + 1}======") + if reg_code in self.register_mapping: # 选择寄存器 + register, data_line = self.register_mapping[reg_code] + mco, reg = data_line.split("-") + reg = int(reg[-1]) + 1 + + self.reg_update() + self.sing.clo_mark(sing_num) # 显示节拍 + cpu_data.SigObj['->ALU'][1] = True + self.sing.show_singe() # 显示控制器信号 + cpu_data.SigObj['->ALU'][1] = True + self.gui.singe_ctrl_line() # 显示控制线 + self.gui.addr_line() # 更新地址线 + self.gui.data_line() # 更新数据线 + self.memo.mad_to_memo() # 更新mad-mome的地址线,参数为真则显示 + self.alu.show_alu_line() # 更新alu的数据线 + + self.gen_opera(f"R{reg - 1}", f"R{reg}", "+", sing_num) + canvas.update() + + if sing_num == 5: + self.textbox.send_msg(f"======Step{sing_num + 1}======") + if reg_code in self.register_mapping: # 查找寄存器 + register, data_line = self.register_mapping[reg_code] + mco, reg = data_line.split("-") + reg = int(reg[-1]) + 1 + + self.reg_update() + self.sing.clo_mark(sing_num) # 显示节拍 + self.sing.show_singe() # 显示控制器信号 + self.gui.singe_ctrl_line() # 显示控制线 + self.gui.addr_line() # 更新地址线 + self.gui.data_line() # 更新数据线 + self.memo.mad_to_memo() # 更新mad-mome的地址线,参数为真则显示 + self.alu.show_alu_line() # 更新alu的数据线 + + self.gen_opera(f"R{reg - 1}", f"R{reg}", "+", sing_num) + canvas.update() + + def SimMinus(self, sing_num, reg_code): + """减法指令""" + self.textbox.send_instr(f"减法") + + register, data_line = self.register_mapping[reg_code] + mco, reg = data_line.split("-") + reg = int(reg[-1]) + 1 + + if sing_num == 3: + self.textbox.send_msg(f"======Step{sing_num + 1}======") + self.reg_update() + self.sing.clo_mark(sing_num) # 显示节拍 + cpu_data.SigObj['->Memory'][1] = True + self.sing.show_singe() # 显示控制器信号 + cpu_data.SigObj[f'Mcontent->R{reg}'][1] = True + cpu_data.SigObj[f'->R{reg}'][1] = True + self.gui.singe_ctrl_line() # 显示控制线 + self.gui.addr_line() # 更新地址线 + self.memo.mad_to_memo(1) # 更新mad-mome的地址线,参数为真则显示 + self.gui.data_line(f"mco-r{reg}") # 更新数据线 + self.alu.show_alu_line() # 更新alu的数据线 + + self.entry_replace(eval(f"self.alu.r{reg}"), self.memo.mco.get()) # 更新显示R2中的值 + canvas.update() + + if sing_num == 4: + self.textbox.send_msg(f"======Step{sing_num + 1}======") + self.reg_update() + self.sing.clo_mark(sing_num) # 显示节拍 + cpu_data.SigObj['->ALU'][1] = True + self.sing.show_singe() # 显示控制器信号 + cpu_data.SigObj['->ALU'][1] = True + self.gui.singe_ctrl_line() # 显示控制线 + self.gui.addr_line() # 更新地址线 + self.gui.data_line() # 更新数据线 + self.memo.mad_to_memo() # 更新mad-mome的地址线,参数为真则显示 + self.alu.show_alu_line() # 更新alu的数据线 + + self.gen_opera(f"R{reg - 1}", f"R{reg}", "-", sing_num) + canvas.update() + + if sing_num == 5: + self.textbox.send_msg(f"======Step{sing_num + 1}======") + self.reg_update() + self.sing.clo_mark(sing_num) # 显示节拍 + self.sing.show_singe() # 显示控制器信号 + self.gui.singe_ctrl_line() # 显示控制线 + self.gui.addr_line() # 更新地址线 + self.gui.data_line() # 更新数据线 + self.memo.mad_to_memo() # 更新mad-mome的地址线,参数为真则显示 + self.alu.show_alu_line() # 更新alu的数据线 + + self.gen_opera(f"R{reg - 1}", f"R{reg}", "-", sing_num) + canvas.update() + + def SimProduct(self, sing_num, reg_code): + """乘法指令""" + self.textbox.send_instr(f"乘法") + + register, data_line = self.register_mapping[reg_code] + mco, reg = data_line.split("-") + reg = int(reg[-1]) + 1 + + if sing_num == 3: + self.textbox.send_msg(f"======Step{sing_num + 1}======") + self.reg_update() + self.sing.clo_mark(sing_num) # 显示节拍 + cpu_data.SigObj['->Memory'][1] = True + self.sing.show_singe() # 显示控制器信号 + cpu_data.SigObj[f'Mcontent->R{reg}'][1] = True + cpu_data.SigObj[f'->R{reg}'][1] = True + self.gui.singe_ctrl_line() # 显示控制线 + self.gui.addr_line() # 更新地址线 + self.memo.mad_to_memo(1) # 更新mad-mome的地址线,参数为真则显示 + self.gui.data_line(f"mco-r{reg}") # 更新数据线 + self.alu.show_alu_line() # 更新alu的数据线 + + self.entry_replace(eval(f"self.alu.r{reg}"), self.memo.mco.get()) # 更新显示R2中的值 + canvas.update() + + if sing_num == 4: + self.textbox.send_msg(f"======Step{sing_num + 1}======") + self.reg_update() + self.sing.clo_mark(sing_num) # 显示节拍 + cpu_data.SigObj['->ALU'][1] = True + self.sing.show_singe() # 显示控制器信号 + cpu_data.SigObj['->ALU'][1] = True + self.gui.singe_ctrl_line() # 显示控制线 + self.gui.addr_line() # 更新地址线 + self.gui.data_line() # 更新数据线 + self.memo.mad_to_memo() # 更新mad-mome的地址线,参数为真则显示 + self.alu.show_alu_line() # 更新alu的数据线 + + self.gen_opera(f"R{reg - 1}", f"R{reg}", "x", sing_num) + canvas.update() + + if sing_num == 5: + self.textbox.send_msg(f"======Step{sing_num + 1}======") + self.reg_update() + self.sing.clo_mark(sing_num) # 显示节拍 + self.sing.show_singe() # 显示控制器信号 + self.gui.singe_ctrl_line() # 显示控制线 + self.gui.addr_line() # 更新地址线 + self.gui.data_line() # 更新数据线 + self.memo.mad_to_memo() # 更新mad-mome的地址线,参数为真则显示 + self.alu.show_alu_line() # 更新alu的数据线 + + self.gen_opera(f"R{reg - 1}", f"R{reg}", "x", sing_num) + canvas.update() + + def SimDiv(self, sing_num, reg_code): + """除法指令""" + self.textbox.send_instr(f"除法") + + register, data_line = self.register_mapping[reg_code] + mco, reg = data_line.split("-") + reg = int(reg[-1]) + 1 + + if sing_num == 3: + self.textbox.send_msg(f"======Step{sing_num + 1}======") + self.reg_update() + self.sing.clo_mark(sing_num) # 显示节拍 + cpu_data.SigObj['->Memory'][1] = True + self.sing.show_singe() # 显示控制器信号 + cpu_data.SigObj[f'Mcontent->R{reg}'][1] = True + cpu_data.SigObj[f'->R{reg}'][1] = True + self.gui.singe_ctrl_line() # 显示控制线 + self.gui.addr_line() # 更新地址线 + self.memo.mad_to_memo(1) # 更新mad-mome的地址线,参数为真则显示 + self.gui.data_line(f"mco-r{reg}") # 更新数据线 + self.alu.show_alu_line() # 更新alu的数据线 + + self.entry_replace(eval(f"self.alu.r{reg}"), self.memo.mco.get()) # 更新显示R2中的值 + canvas.update() + + if sing_num == 4: + self.textbox.send_msg(f"======Step{sing_num + 1}======") + self.reg_update() + self.sing.clo_mark(sing_num) # 显示节拍 + cpu_data.SigObj['->ALU'][1] = True + self.sing.show_singe() # 显示控制器信号 + cpu_data.SigObj['->ALU'][1] = True + self.gui.singe_ctrl_line() # 显示控制线 + self.gui.addr_line() # 更新地址线 + self.gui.data_line() # 更新数据线 + self.memo.mad_to_memo() # 更新mad-mome的地址线,参数为真则显示 + self.alu.show_alu_line() # 更新alu的数据线 + + self.gen_opera(f"R{reg - 1}", f"R{reg}", "÷", sing_num) + canvas.update() + + if sing_num == 5: + self.textbox.send_msg(f"======Step{sing_num + 1}======") + self.reg_update() + self.sing.clo_mark(sing_num) # 显示节拍 + self.sing.show_singe() # 显示控制器信号 + self.gui.singe_ctrl_line() # 显示控制线 + self.gui.addr_line() # 更新地址线 + self.gui.data_line() # 更新数据线 + self.memo.mad_to_memo() # 更新mad-mome的地址线,参数为真则显示 + self.alu.show_alu_line() # 更新alu的数据线0. + + self.gen_opera(f"R{reg - 1}", f"R{reg}", "÷", sing_num) + canvas.update() + + def SimPrint(self, sing_num): + self.textbox.send_instr("打印") + + if sing_num == 3: + self.textbox.send_msg(f"======Step{sing_num + 1}======") + self.reg_update() + self.sing.clo_mark(sing_num) # 显示节拍 + cpu_data.SigObj['->Memory'][1] = True + self.sing.show_singe() # 显示控制器信号 + cpu_data.SigObj['->R1'][1] = True + cpu_data.SigObj['Mcontent->R1'][1] = True + self.gui.singe_ctrl_line() # 显示控制线 + self.gui.addr_line() # 更新地址线 + self.memo.mad_to_memo(1) # 更新mad-mome的地址线,参数为真则显示 + self.gui.data_line("mco-r1") # 更新数据线 + self.alu.show_alu_line() # 更新alu的数据线 + + self.entry_replace(self.alu.r1, self.memo.mco.get()) # 更新显示R2中的值 + canvas.update() + + if sing_num == 4: + self.textbox.send_msg(f"======Step{sing_num + 1}======") + self.reg_update() + self.sing.clo_mark(sing_num) # 显示节拍 + cpu_data.SigObj['->R1'][1] = True # 更新R1的值 + self.sing.show_singe() # 显示控制器信号 + cpu_data.SigObj['->R1'][1] = True # 更新R1的值 + self.gui.singe_ctrl_line() # 显示控制线 + self.gui.addr_line() # 更新地址线 + self.gui.data_line() # 更新数据线 + self.memo.mad_to_memo() # 更新mad-mome的地址线,参数为真则显示 + self.alu.show_alu_line() # 更新alu的数据线 + + val = self.alu.r1.get() + self.textbox.send_msg(f"打印输出:\n'{val}'") + binary_string = bin_to_dec(val) + self.textbox.send_msg(f"10进制转换:'{binary_string}'") + canvas.update() + + # print(self.alu.r1.get()) + + def SimStop(self, sing_num): + self.textbox.send_instr("停机") + if sing_num == 3: + self.textbox.send_msg(f"======Step{sing_num + 1}======") + self.reg_update() + self.sing.clo_mark(sing_num) # 显示节拍 + cpu_data.SigObj['->PC+1'][1] = True # 更新PC+1的值 + self.sing.show_singe() # 显示控制器信号 + cpu_data.SigObj['->PC+1'][1] = True # 更新PC+1的值 + self.gui.singe_ctrl_line() # 显示控制线 + + self.gui.addr_line() # 更新地址线 + self.gui.data_line() # 更新数据线 + self.memo.mad_to_memo() # 更新mad-mome的地址线,参数为真则显示 + self.alu.show_alu_line() # 更新alu的数据线 + + self.sing.pc_value = f"{0:016b}" # PC 置0 + self.sing.pc_reg_value() + self.textbox.send_msg("PC = 0") + self.sing.pc_reg.config(bg=RED) + self.sing.ins.config(bg=RED) + canvas.update() + + if sing_num == 4: + self.textbox.send_msg(f"======Step{sing_num + 1}======") + self.reg_update() + self.sing.clo_mark() # 显示节拍 + self.sing.show_singe() # 显示控制器信号 + self.gui.singe_ctrl_line() # 显示控制线 + self.gui.addr_line() # 更新地址线 + self.gui.data_line() # 更新数据线 + self.memo.mad_to_memo() # 更新mad-mome的地址线,参数为真则显示 + self.alu.show_alu_line() # 更新alu的数据线 + self.textbox.send_msg("系统停机") + canvas.update() + + def SimGoto(self, sing_num): + self.textbox.send_instr("跳转") + if sing_num == 3: + self.textbox.send_msg(f"======Step{sing_num + 1}======") + self.reg_update() + self.sing.clo_mark(sing_num) # 显示节拍 + cpu_data.SigObj['->Memory'][1] = True # 更新Memory的值 + self.sing.show_singe() # 显示控制器信号 + cpu_data.SigObj['PC->Maddr'][1] = True + cpu_data.SigObj['Mcontent->PC'][1] = True + cpu_data.SigObj["->PC+1"][1] = True + self.gui.singe_ctrl_line() # 显示控制线 + + self.gui.addr_line() # 更新地址线 + self.memo.mad_to_memo(1) # 更新mad-mome的地址线,参数为真则显示 + self.gui.data_line("mco-pc") # 更新数据线 + self.alu.show_alu_line() # 更新alu的数据线 + + mco_value = self.memo.mco.get() + self.entry_replace(self.sing.pc_reg, mco_value) + self.memo.mco.config(bg=RED) + self.sing.pc_reg.config(bg=RED) + canvas.update() + + def lw_(self, one_inscode=None, is_meter=None, step=None): + ''' + 取指令 + :param one_inscode: 执行模式,分单指令自动执行,和分节拍手动执行 + :param is_meter: 控制是否为分节拍模式 True则表示分节拍执行 + :param step: 节拍步骤 + :return: 停机指令 + ''' + self.alu.show_alu_line(None) # 更新ALU的数据线 + if step <= 2: # 前三节拍都更新取指令,后面的节拍更新其他指令 + self.textbox.send_instr("取指令") + + if step == 0: + self.textbox.send_msg(f"\n\n\n======Step{step + 1}======") + self.reg_update() # 更新各个寄存器颜色为白色 + self.sing.clo_mark(step) # 显示节拍 + + cpu_data.SigObj['->Memory'][1] = True # 更新Memory的值 + self.sing.show_singe() # 显示控制器信号 + + cpu_data.SigObj['PC->Maddr'][1] = True # 更新PC->Maddr的值 + self.gui.singe_ctrl_line() # 显示信号控制线 + + cpu_data.SigObj['PC->Maddr'][1] = True # 更新PC->Maddr的值 + self.gui.addr_line() # 显示地址线 + + self.gui.data_line() # 更新数据线 + self.memo.mad_to_memo() # 更新mad-mome的地址线 + + self.alu.alu_operation() # 更新alu的符号 + + canvas.update() # 刷新显示 + + maddr = self.sing.pc_reg.get() # 获取pc寄存器的值 + self.sing.pc_reg.config(bg=RED) # 更新PC寄存器的背景显示 + self.memo.show_maddr(maddr, 1) # 更新maddr的显示和值 + + self.alu.show_alu_line(None) # 显示ALU的数据线 + + if step == 1: + self.textbox.send_msg(f"======Step{step + 1}======") + self.reg_update() # 更新各个寄存器颜色为白色 + self.sing.clo_mark(step) # 显示节拍 + + cpu_data.SigObj['->IR'][1] = True + self.sing.show_singe() # 显示控制器信号 + + cpu_data.SigObj['->IR'][1] = True + self.gui.singe_ctrl_line() # 显示控制线 + self.gui.addr_line() # 更新显示地址线 + self.memo.mad_to_memo(1) # 更新mad-mome的地址线,参数为真则显示 + self.gui.data_line("mco-ir") # 更新数据线 + + data = self.memo.mco.get() # 取得mco中的值 + self.sing.ir_value = data # 更新 ir的值 + self.sing.ir_reg_value() # 显示IR + self.sing.ir_reg.config(bg=RED) # 更新IR的颜色 + + canvas.update() # 刷新显示 + + if step >= 2: + global inscode + if step == 2: + self.textbox.send_msg(f"======Step{step + 1}======") + self.reg_update() # 更新各个寄存器颜色为白色 + self.sing.clo_mark(step) # 显示节拍 + + cpu_data.SigObj['->PC+1'][1] = True # 更新PC+1的值 + cpu_data.SigObj['->IR'][1] = True # 更新IR的值 + self.sing.show_singe() # 显示控制器信号 + + cpu_data.SigObj['->PC+1'][1] = True # 更新PC+1的值 + cpu_data.SigObj['->IR'][1] = True # 更新IR的值 + self.gui.singe_ctrl_line() # 显示控制线 + + cpu_data.SigObj['IR->Maddr'][1] = True # 更新IR->Maddr的值 + self.gui.addr_line() # 更新地址线 + self.gui.data_line() # 更新数据线 + self.memo.mad_to_memo() # 更新mad-mome的地址线,参数为真则显示 + + self.sing.pc_value = self.sing.pc_reg.get() + self.sing.pc_value = self.pc_add_one(self.sing.pc_value) # pc+1 + self.sing.pc_reg_value() # 更新PC显示 + self.sing.pc_reg.config(bg=RED) # 更新PC背景 + + inscode, addr = self.sing.ir_value[:6], self.sing.ir_value[6:] # 拆分操作码和指令地址 + self.sing.ir_reg.config(bg=RED) # 更新IR背景 + self.entry_replace(self.sing.ins, inscode) # 更新 inscode值 + self.sing.ins.config(bg=RED) # 更新insCode背景 + self.memo.mad_value = f"{int(addr, 2):016b}" # 更新 maddr值 + self.memo.show_maddr(self.memo.mad_value, 1) # 显示maddr值 + + canvas.update() # 刷新显示 + if is_meter is None: + time.sleep(self.wait_time) + + if one_inscode is not None: # 如果有单指令,直接执行指令 + self.instruct(one_inscode) + else: # 如果没有单指令,执行读取到的指令 + if is_meter: # 如果是分节拍执行。 + stop_tag = self.instruct(inscode, step) # 加入步骤参数 + return stop_tag + else: # 不分节拍执行 + stop_tag = self.instruct(inscode) # 不加步骤参数 + if stop_tag == "stop": return "stop" + + if is_meter is None and step < 2: # 不分节拍执行时,增加等待时间 + time.sleep(self.wait_time) + + def instruct(self, inscode, step=None): + com_code = inscode[2:] + reg_code = inscode[:2] + + if com_code == '0001': # 取数指令 + if step is not None: # 当有手动指令时执行手动指令 + self.SimGet(step, reg_code) + if step >= 3: + return "end" + else: + for i in range(3, 4): + self.SimGet(i, reg_code) + time.sleep(self.wait_time) + + if com_code == "0010": # 存数指令 + if step is not None: + self.SimPut(step, reg_code) + if step >= 3: + return "end" + else: + for i in range(3, 4): + self.SimPut(i, reg_code) + time.sleep(self.wait_time) + + if com_code == "0011": + if reg_code != "11": # 加法指令 + if step is not None: + self.SimAddr(step, reg_code) + if step >= 5: + return "end" + else: + for i in range(3, 6): + self.SimAddr(i, reg_code) + time.sleep(self.wait_time) + else: + self.textbox.send_msg("寄存器超限!!!", fg="#FF0000") + + if com_code == "0111": # 减法指令 + if reg_code != "11": # 加法指令 + if step is not None: + self.SimMinus(step, reg_code) + if step >= 5: + return "end" + else: + for i in range(3, 6): + self.SimMinus(i, reg_code) + time.sleep(self.wait_time) + else: + self.textbox.send_msg("寄存器超限!!!", fg="#FF0000") + + if com_code == "0100": # 乘法指令 + if reg_code != "11": + if step is not None: + self.SimProduct(step, reg_code) + if step >= 5: + return "end" + else: + for i in range(3, 6): + self.SimProduct(i, reg_code) + time.sleep(self.wait_time) + else: + self.textbox.send_msg("寄存器超限!!!", fg="#FF0000") + + if com_code == "1000": # 除法指令 + if reg_code != "11": + if step is not None: + self.SimDiv(step, reg_code) + if step >= 5: + return "end" + else: + for i in range(3, 6): + self.SimDiv(i, reg_code) + time.sleep(self.wait_time) + else: + self.textbox.send_msg("寄存器超限!!!", fg="#FF0000") + + if com_code == "1001": # 跳转指令 + if step is not None: + self.SimGoto(step) + if step >= 3: + return "end" + else: + for i in range(3, 4): + self.SimGoto(i) + time.sleep(self.wait_time) + + if com_code == "0101": # 打印指令 + if step is not None: + self.SimPrint(step) + if step >= 4: + return "end" + else: + for i in range(3, 5): + self.SimPrint(i) + time.sleep(self.wait_time) + + if com_code == "0110": # 停机指令 + if step is not None: + self.SimStop(step) + if step >= 4: + return "stop" + else: + for i in range(3, 5): + self.SimStop(i) + time.sleep(self.wait_time) + if i >= 4: + return "stop" # 停机标志 + + def exe_one_instruct(self, inscode): + """单指令执行""" + for i in range(3): + self.lw_(inscode, step=i) + + def exec_auto(self): # 自动执行储存程序 + while True: + instr_stute = None # 指令状态为"stop"时退出循环。 + if self.ctrl_stop: + break + for i in range(3): + instr_stute = self.lw_(step=i) + if instr_stute == "stop": + break + + def exec_next(self): # 执行下一步 + statu = self.lw_(is_meter=True, step=self.manual_opera_step) # 执行指令 + self.manual_opera_step += 1 + if statu == "end" or self.manual_opera_step > 5: # 指令结束或者节拍序号大于5都将节拍重置鱼0 + self.manual_opera_step = 0 + elif statu == "stop": # 若上一条指令返回停机指令,则disable下一步按键 + self.next_button.config(state=tk.DISABLED) + + if self.manual_opera_step > 0: + self.prev_button.config(state=tk.NORMAL) + + def prev(self): # 执行上一步 + self.next_button.config(state=tk.NORMAL) + if self.manual_opera_step > 0: + self.manual_opera_step -= 1 + self.lw_(is_meter=True, step=self.manual_opera_step) + else: + self.prev_button.config(state=tk.DISABLED) + + def exec_manual_operation(self): + '''分节拍顺序执行''' + self.lw_(is_meter=True, step=self.manual_opera_step) + +def main(): + SimMem[0] = f"0000010000001010" # SimMem[10] => r1 + SimMem[1] = f"0000110000001011" # r1+SimMem[11] => r1 + SimMem[2] = f"0001000000001100" # r1*SimMem[12] => r1 + SimMem[3] = f"0010000000001101" # r1//SimMem[13] => r1 + SimMem[4] = f"0001110000001110" # r1-SimMem[14] => r1 + SimMem[5] = f"0000100000001111" # 存数到15地址 r1 => SimMem[15] + SimMem[6] = f"0001010000001111" # 打印 SimMem[15] + SimMem[7] = f"0001100000000000" # 停机 + + SimMem[10] = dec_to_bin(9) # 10 地址数据 + SimMem[11] = dec_to_bin(11) # 11 地址数据 + SimMem[12] = dec_to_bin(5) # 12 地址数据 + SimMem[13] = dec_to_bin(10) # 13 号位的值 + SimMem[14] = dec_to_bin(11) # 14 地址数据 + + exe = ExecInstructWithText() + root.mainloop() + +if __name__ == '__main__': + main() diff --git a/gui.py b/gui.py new file mode 100644 index 0000000..99ac018 --- /dev/null +++ b/gui.py @@ -0,0 +1,944 @@ +# -*- encoding: utf-8 -*- +""" +@File : gui.py +@License : (C)Copyright 2021-2023 + +@Modify Time @Author @Version @Description +------------ ------- -------- ----------- +2023/11/1 13:37 zart20 1.0 None +""" + +import tkinter as tk +from tkinter import scrolledtext, ttk + +import cpu_data +from cpu_data import * + +WORD = '#00f5ff' +BLACK = "#000000" +WHITE = "#F0F0F0" +DATALINE = "#0CB90C" +ADDRLINE = "#f35555" +RED = "#FFAAAA" +GREY = '#808080' +GOLD = '#FFD700' +GREEN = '#00FA9A' +BACK = '#0153d2' +ORANGE = '#d3b719' +MEMBACK = '#fba651' +width = 1000 # 设置窗口宽度 +height = 700 +root = tk.Tk() +root.title("16位简易CPU可视化") +root.geometry(f"{1300}x{700}") + +canvas = tk.Canvas(root, bg='white', bd=2, relief="sunken", width=width + 300, height=height, background=BLACK, + borderwidth=0, highlightthickness=0) +canvas.place(x=0, y=0, anchor=tk.NW, width=1300, height=700) + + +# root_right = tk.Frame(root, bg=WHITE, relief="groove", width=240, height=height - 40) +# root_right.place(x=width+25, y=15, anchor=tk.NW) # 右边栏 + + +def round_rectangle(x1, y1, x2, y2, r=25, **kwargs): + points = ( + x1 + r, y1, x1 + r, y1, x2 - r, y1, x2 - r, y1, x2, y1, x2, y1 + r, x2, y1 + r, x2, y2 - r, x2, y2 - r, x2, + y2, + x2 - r, y2, x2 - r, y2, x1 + r, y2, x1 + r, y2, x1, y2, x1, y2 - r, x1, y2 - r, x1, y1 + r, x1, y1 + r, x1, + y1) + return canvas.create_polygon(points, **kwargs, smooth=True) + +round_rectangle(width + 20, 15, width + 270, height - 25, r=25, fill=WHITE, width=0) +round_rectangle(20, 15, 970, height - 25, r=25, fill=WHITE, width=0) + + +class TextBox: + def __init__(self, canvas: canvas): + self.canvas = canvas + self.frame_low = tk.Frame(self.canvas, bg=WHITE, relief="groove", width=220, height=height - 50) # 底层框架 + self.frame_low.place(x=width + 25, y=15, anchor=tk.NW) # 右边栏 + + self.frame_msg = tk.Frame(self.frame_low, bg=WHITE, relief="groove") # 消息框 + self.frame_msg.grid(row=1, column=0) + # 创建一个样式对象 + style = ttk.Style() + # 定义选项卡标题的样式 + style.configure("Custom.TNotebook.Tab", font=("微软雅黑", 14)) + self.tab_control = ttk.Notebook(self.frame_low, style="Custom.TNotebook") # 创建一个Notebook组件 + self.tab_control.grid(row=0, column=0) + + self.page1 = self.creat_page(self.tab_control, "流程") # 创建两个分页 + self.page2 = self.creat_page(self.tab_control, "运算") # 创建两个分页 + self.page3 = self.creat_page(self.tab_control, "信号") # 创建两个分页 + self.page4 = self.creat_page(self.tab_control, "内存") # 创建两个分页 + + self.frame_midel = tk.Frame(self.frame_low, bg=WHITE, relief="groove") # 中间框架 + self.frame_midel.grid(row=0, column=0) + self.l_x = 1020 + self.r_x = 1027 + self.m_x = 1145 # 消息区X轴中线位置 + self.m_y = 265 # 消息区y轴分割位置 + tk.Label(self.frame_msg, text="系统消息", font=('微软雅黑', 16), bg=WHITE)\ + .grid(row=0, column=1, padx=5, pady=5) + tk.Button(self.frame_msg, text="X", font=('微软雅黑', 12), bg=WHITE, command=self.clear)\ + .grid(row=0, column=2, padx=5, pady=5, sticky="w") + self.reset_button = tk.Button(self.frame_msg, text="↺", font=('微软雅黑', 12), bg=WHITE) # 重置按钮 + self.reset_button.grid(row=0, column=0, padx=5, pady=5, sticky="e") # 重置按钮 + self.instr_label() # 显示指令 + self.create_text_box() # 显示消息框 + + def creat_page(self, tab_control, title): + """创建一个新的分页""" + page = ttk.Frame(tab_control) + tab_control.add(page, text=title) + return page + + def main_msg_box(self, msg: str, r,c, frame=None): + # 在Canvas上创建主要消息框 + if frame is None:frame = self.page1 + label1 = tk.Label(frame, text=msg, font=('微软雅黑', 20), bg=WHITE) + label1.grid(row=r, column=c, padx=5, pady=5,columnspan=2) + + def create_button(self, text: str, x: int, y: int, command: callable, frame=None) -> tk.Button: + # 创建文本按钮 + if frame is None:frame = self.page1 + button = tk.Button(frame, text=text, command=command, font=('微软雅黑', 12), width=10, bg=WHITE) + button.grid(row=x, column=y, padx=5, pady=5) + return button + + def create_combobox(self, x: int, y: int, values: list, frame=None) -> ttk.Combobox: + # 创建下拉框 + if frame is None:frame = self.page1 + combobox = ttk.Combobox(frame, values=values, width=10, font=('微软雅黑', 12)) + combobox.set(values[0]) # 设置默认选项 + combobox.grid(row=x, column=y, padx=5, pady=5) + return combobox + + # 创建当行输入框 + def create_entry(self, x: int, y: int, frame=None) -> tk.Entry: + if frame is None:frame = self.page1 + entry = tk.Entry(frame, font=('微软雅黑', 12), width=16) + entry.insert(0, "输入R(x)新值!") + entry.grid(row=x, column=y, padx=5, columnspan=2, pady=5) + return entry + + + # print(cpu_data.ALUio) + + def instr_label(self) -> None: + self.label = tk.Label(self.page1, font=('微软雅黑', 16), width=10) + self.label.grid(row=3, column=0, padx=5, pady=5,columnspan=2) + + def send_instr(self, text: str) -> None: + formatted_text = f"指令:{text}" + # 如果你想更新 Label 的文本,使用 configure 而不是再次创建 Label + self.label.config(text=formatted_text, bg=RED) + + def create_text_box(self): + """创建多行输入框""" + self.info_text = scrolledtext.ScrolledText(self.frame_low, wrap=tk.WORD, height=15, width=20) + # self.info_text.place(x=1025, y=290, anchor=tk.NW) + self.info_text.grid(row=2, column=0) + self.info_text.config(font=("微软雅黑", 14)) + + def send_msg(self, text: str) -> None: + '''向输入框发送系统消息''' + self.info_text.insert(tk.END, text + "\n") + self.info_text.see(tk.END) + + def clear(self) -> None: + '''清空系统消息框''' + if self.info_text.get("1.0", tk.END).strip() != "": # 检查文本框内容是否非空 + self.info_text.delete("1.0", tk.END) + + +textbox = TextBox(canvas) # 全局化消息框 + + +class GUISim: + def __init__(self): + self.canvas = canvas + self.canvas.bind("", self.on_left_click) + # root_right.bind("", self.on_left_click) + self.alu = ALU() + self.memo = MEMO() + self.sigctrl = SIGCtrl() + self.textbox = textbox # 为了让引用GUIsim类的对象来使用消息框 + self.singe_ctrl_line() + self.addr_line() + self.data_line() + self.line_explain() + # self.show_msg() + + def on_left_click(self, event): + print(event.x, ",", event.y) + + def singe_ctrl_line(self): # 控制线 + sings = [] + for sing in cpu_data.SigObj: # 遍历信号字典 + if cpu_data.SigObj[sing][1]: # 如果信号的值为True + sings.append(sing) # 将信号的名字添加到列表中 + # if sings is None: + # sings = [] + self.canvas.delete("ctrl_line") + # alu + line_points = [90, 575, 65, 575, 65, 235, 98, 235] + self.canvas.create_line(line_points, width=5, fill=GREY, arrow=tk.LAST, + tags="ctrl_line", dash=(10, 10)) + self.alu.draw_circle(103, 235, 5, fill=GREY, tags="ctrl_line") + + # maddr + line_points = [205, 630, 205, 660, 630, 660, 630, 545] + self.canvas.create_line(line_points, width=5, fill=GREY, arrow=tk.LAST, + tags="ctrl_line", dash=(10, 10)) + + # r1 + line_points = [135, 630, 135, 660, 45, 660, 45, 30, 560, 30, 560, 95, 515, 95] + self.canvas.create_line(line_points, width=5, fill=GREY, arrow=tk.LAST, + tags="ctrl_line", dash=(10, 10)) + + # r2 + line_points = [135, 630, 135, 660, 45, 660, 45, 30, 560, 30, 560, 189, 515, 189] + self.canvas.create_line(line_points, width=5, fill=GREY, arrow=tk.LAST, + tags="ctrl_line", dash=(10, 10)) + + # r3 + line_points = [135, 630, 135, 660, 45, 660, 45, 30, 560, 30, 560, 276, 515, 276] + self.canvas.create_line(line_points, width=5, fill=GREY, arrow=tk.LAST, + tags="ctrl_line", dash=(10, 10)) + + # r4 + line_points = [135, 630, 135, 660, 45, 660, 45, 30, 560, 30, 560, 368, 515, 368] + self.canvas.create_line(line_points, width=5, fill=GREY, arrow=tk.LAST, + tags="ctrl_line", dash=(10, 10)) + + # Mcontent + line_points = [135, 630, 135, 660, 45, 660, 45, 30, 560, 30, 885, 30, 885, 215] + self.canvas.create_line(line_points, width=5, fill=GREY, arrow=tk.LAST, + tags="ctrl_line", dash=(10, 10)) + + # pc + line_points = [280, 540, 350, 540, 350, 485] + self.canvas.create_line(line_points, width=5, fill=GREY, arrow=tk.LAST, + tags="ctrl_line", dash=(10, 10)) + + # IR + line_points = [225, 630, 225, 650, 350, 650, 350, 590] + self.canvas.create_line(line_points, width=5, fill=GREY, arrow=tk.LAST, + tags="ctrl_line", dash=(10, 10)) + + # IR -> inscode + line_points = [332, 575, 275, 575] + self.canvas.create_line(line_points, width=2, fill="black", arrow=tk.LAST, + tags="ctrl_line") + + # clock -> inscode + line_points = [200, 495, 200, 523] + self.canvas.create_line(line_points, width=2, fill="black", arrow=tk.LAST, + tags="ctrl_line") + + for sing in sings: + if sing == "->ALU": + # alu + line_points = [90, 575, 65, 575, 65, 235, 98, 235] + self.canvas.create_line(line_points, width=5, fill="red", arrow=tk.LAST, tags="ctrl_line", + dash=(10, 10)) + self.alu.draw_circle(103, 235, 5, fill=GREEN, tags="ctrl_line") + self.textbox.send_msg("Sig->ALU") + cpu_data.SigObj[sing][1] = False # 重置信号 + # if sing == "MAD": + if sing =="IR->Maddr" or sing == "PC->Maddr": + # maddr + line_points = [205, 630, 205, 660, 630, 660, 630, 545] + self.canvas.create_line(line_points, width=5, fill="red", arrow=tk.LAST, tags="ctrl_line", + dash=(10, 10)) + self.textbox.send_msg("Sig->MAD") + cpu_data.SigObj[sing][1] = False # 重置信号 + if sing == "->R1": + # r1 + line_points = [135, 630, 135, 660, 45, 660, 45, 30, 560, 30, 560, 95, 515, 95] + self.canvas.create_line(line_points, width=5, fill="red", arrow=tk.LAST, tags="ctrl_line", + dash=(10, 10)) + self.textbox.send_msg("Sig->R1") + cpu_data.SigObj[sing][1] = False # 重置信号 + if sing == "->R2": + # r2 + line_points = [135, 630, 135, 660, 45, 660, 45, 30, 560, 30, 560, 189, 515, 189] + self.canvas.create_line(line_points, width=5, fill="red", arrow=tk.LAST, tags="ctrl_line", + dash=(10, 10)) + self.textbox.send_msg("Sig->R2") + cpu_data.SigObj[sing][1] = False # 重置信号 + if sing == "->R3": + # r3 + line_points = [135, 630, 135, 660, 45, 660, 45, 30, 560, 30, 560, 276, 515, 276] + self.canvas.create_line(line_points, width=5, fill="red", arrow=tk.LAST, tags="ctrl_line", + dash=(10, 10)) + self.textbox.send_msg("Sig->R3") + cpu_data.SigObj[sing][1] = False # 重置信号 + if sing == "->R4": + # r4 + line_points = [135, 630, 135, 660, 45, 660, 45, 30, 560, 30, 560, 368, 515, 368] + self.canvas.create_line(line_points, width=5, fill="red", arrow=tk.LAST, tags="ctrl_line", + dash=(10, 10)) + self.textbox.send_msg("Sig->R4") + cpu_data.SigObj[sing][1] = False # 重置信号 + # if sing == "MCO": + # if sing == "Mcontent->PC" or sing == "Memory->Mcontent": + if sing.find("Mcontent") != -1: # 如果信号名字中包含Mcontent + # Mcontent + line_points = [135, 630, 135, 660, 45, 660, 45, 30, 560, 30, 885, 30, 885, 215] + self.canvas.create_line(line_points, width=5, fill="red", arrow=tk.LAST, tags="ctrl_line", + dash=(10, 10)) + self.textbox.send_msg("Sig->MCO") + cpu_data.SigObj[sing][1] = False # 重置信号 + if sing == "->PC+1": + # pc + line_points = [280, 540, 350, 540, 350, 485] + self.canvas.create_line(line_points, width=5, fill="red", arrow=tk.LAST, tags="ctrl_line", + dash=(10, 10)) + self.textbox.send_msg("Sig->PC+1") + cpu_data.SigObj[sing][1] = False # 重置信号 + if sing == "->IR": + # IR + line_points = [225, 630, 225, 650, 350, 650, 350, 590] + self.canvas.create_line(line_points, width=5, fill="red", arrow=tk.LAST, tags="ctrl_line", + dash=(10, 10)) + self.textbox.send_msg("Sig->IR") + cpu_data.SigObj[sing][1] = False # 重置信号 + + def addr_line(self): # 地址线 + sings = [] + for key, value in cpu_data.SigObj.items(): + if value[1]: + sings.append(value[0]) + + self.canvas.delete("addr_line") + # IR -> Maddr + line_points = [400, 560, 400, 515, 560, 515, 614, 515] + self.canvas.create_line(line_points, width=4, fill=GREY, arrow=tk.LAST, tags="addr_line") + + # pc -> Maddr + line_points = [485, 465, 615, 465] + self.canvas.create_line(line_points, width=4, fill=GREY, arrow=tk.LAST, tags="addr_line") + + for sing in sings: + if sing == "IR->Maddr": + # IR -> Maddr + line_points = [400, 560, 400, 515, 560, 515, 614, 515] + self.canvas.create_line(line_points, width=4, fill=ADDRLINE, arrow=tk.LAST, tags="addr_line") + self.textbox.send_msg("IR->MAD") + cpu_data.SigObj["IR->Maddr"][1] = False # 重置信号 + if sing == "PC->Maddr": + # pc -> Maddr + line_points = [485, 465, 615, 465] + self.canvas.create_line(line_points, width=4, fill=ADDRLINE, arrow=tk.LAST, tags="addr_line") + self.textbox.send_msg("PC->MAD") + cpu_data.SigObj["PC->Maddr"][1] = False # 重置信号 + + def data_line(self, singe=None): # 数据线 + self.canvas.delete("data_line") + # mco -> r1 + line_points = [765, 218, 765, 175, 570, 175, 570, 108, 518, 108] + self.canvas.create_line(line_points, width=5, fill=GREY, tags="data_line") + # r1 -> mco + line_points = [765, 218, 765, 175, 570, 175, 570, 108, 518, 108] + self.canvas.create_line(line_points, width=5, fill=GREY, tags="data_line") + # mco -> r2 + line_points = [765, 218, 765, 175, 570, 175, 570, 198, 518, 198] + self.canvas.create_line(line_points, width=5, fill=GREY, tags="data_line") + # r2 -> mco + line_points = [765, 218, 765, 175, 570, 175, 570, 198, 518, 198] + self.canvas.create_line(line_points, width=5, fill=GREY, tags="data_line") + # mco -> r3 + line_points = [765, 218, 765, 175, 570, 175, 570, 288, 518, 288] + self.canvas.create_line(line_points, width=5, fill=GREY, tags="data_line") + # r3 -> mco + line_points = [765, 218, 765, 175, 570, 175, 570, 288, 518, 288] + self.canvas.create_line(line_points, width=5, fill=GREY, tags="data_line") + # mco -> r4 + line_points = [765, 218, 765, 175, 570, 175, 570, 378, 518, 378] + self.canvas.create_line(line_points, width=5, fill=GREY, tags="data_line") + # r4 -> mco + line_points = [765, 218, 765, 175, 570, 175, 570, 378, 518, 378] + self.canvas.create_line(line_points, width=5, fill=GREY, tags="data_line") + # mco -> ir + line_points = [765, 218, 765, 175, 570, 175, 570, 575, 495, 575] + self.canvas.create_line(line_points, width=5, fill=GREY, tags="data_line") + # mco -> pc + line_points = [765, 218, 765, 175, 570, 175, 570, 475, 485, 475] + self.canvas.create_line(line_points, width=5, fill=GREY, tags="data_line") + # # memo -> mco + # line_points = [855, 245, 855, 275] + # self.canvas.create_line(line_points, width=5, fill=GREY, arrow=tk.LAST, tags="data_line") + # # mco -> memo + # line_points = [875, 245, 875, 275] + # self.canvas.create_line(line_points, width=5, fill=GREY, arrow=tk.FIRST, tags="data_line") + + # mco -> r1 + if singe == "mco-r1": + line_points = [765, 218, 765, 175, 570, 175, 570, 108, 518, 108] + self.canvas.create_line(line_points, width=5, fill=DATALINE, arrow=tk.LAST, tags="data_line") + self.textbox.send_msg("MCO->R1") + self.alu.r1.config(bg=RED) + # r1 -> mco + if singe == "r1-mco": + line_points = [765, 218, 765, 175, 570, 175, 570, 108, 518, 108] + self.canvas.create_line(line_points, width=5, fill=DATALINE, arrow=tk.FIRST, tags="data_line") + self.textbox.send_msg("R1->MCO") + self.memo.mco.config(bg=RED) + # mco -> r2 + if singe == "mco-r2": + line_points = [765, 218, 765, 175, 570, 175, 570, 198, 518, 198] + self.canvas.create_line(line_points, width=5, fill=DATALINE, arrow=tk.LAST, tags="data_line") + self.textbox.send_msg("MCO->R2") + self.alu.r2.config(bg=RED) + # r2 -> mco + if singe == "r2-mco": + line_points = [765, 218, 765, 175, 570, 175, 570, 198, 518, 198] + self.canvas.create_line(line_points, width=5, fill=DATALINE, arrow=tk.FIRST, tags="data_line") + self.textbox.send_msg("R2->MCO") + self.memo.mco.config(bg=RED) + # mco -> r3 + if singe == "mco-r3": + line_points = [765, 218, 765, 175, 570, 175, 570, 288, 518, 288] + self.canvas.create_line(line_points, width=5, fill=DATALINE, arrow=tk.LAST, tags="data_line") + self.textbox.send_msg("MCO->R3") + self.alu.r3.config(bg=RED) + # r3 -> mco + if singe == "r3-mco": + line_points = [765, 218, 765, 175, 570, 175, 570, 288, 518, 288] + self.canvas.create_line(line_points, width=5, fill=DATALINE, arrow=tk.FIRST, tags="data_line") + self.textbox.send_msg("R3->MCO") + self.memo.mco.config(bg=RED) + # mco -> r4 + if singe == "mco-r4": + line_points = [765, 218, 765, 175, 570, 175, 570, 378, 518, 378] + self.canvas.create_line(line_points, width=5, fill=DATALINE, arrow=tk.LAST, tags="data_line") + self.textbox.send_msg("MCO->R4") + self.alu.r4.config(bg=RED) + # r4 -> mco + if singe == "r4-mco": + line_points = [765, 218, 765, 175, 570, 175, 570, 378, 518, 378] + self.canvas.create_line(line_points, width=5, fill=DATALINE, arrow=tk.FIRST, tags="data_line") + self.textbox.send_msg("R4->MCO") + self.memo.mco.config(bg=RED) + # mco -> ir + if singe == "mco-ir": + line_points = [765, 218, 765, 175, 570, 175, 570, 575, 495, 575] + self.canvas.create_line(line_points, width=5, fill=DATALINE, arrow=tk.LAST, tags="data_line") + self.textbox.send_msg("MCO->IR") + self.sigctrl.ir_reg.config(bg=RED) + # mco -> pc + if singe == "mco-pc": + line_points = [765, 218, 765, 175, 570, 175, 570, 475, 485, 475] + self.canvas.create_line(line_points, width=5, fill=DATALINE, arrow=tk.LAST, tags="data_line") + self.textbox.send_msg("MCO->PC") + + def line_explain(self): + """线的类型标签""" + line_points = [640, 60, 705, 60] + self.canvas.create_line(line_points, width=3, fill="red", tags="line", dash=(10, 10)) + self.canvas.create_text(737, 60, text="控制线", anchor=tk.CENTER, font=('微软雅黑', 12)) + + line_points = [640, 90, 705, 90] + self.canvas.create_line(line_points, width=4, fill=ADDRLINE, tags="line", ) + self.canvas.create_text(737, 90, text="地址线", anchor=tk.CENTER, font=('微软雅黑', 12)) + + line_points = [640, 120, 705, 120] + self.canvas.create_line(line_points, width=5, fill=DATALINE, tags="line", ) + self.canvas.create_text(737, 120, text="数据线", anchor=tk.CENTER, font=('微软雅黑', 12)) + + +class ALU: + def __init__(self): + self.canvas = canvas + self.r1_entry() + self.r2_entry() + self.r3_entry() + self.r4_entry() + self.alu_draw() # alu 图样 + self.alu_line_init() # alu 的描述 + self.show_alu_line(None) # alu 数据线 + self.show_alu_reg() # alu r1-r4 + self.alu_operation() # alu 符号 + + def draw_circle(self, x, y, r, fill=None, tags=None): + """根据圆心坐标和半径画圆""" + # 圆外接矩形 + x1, y1, x2, y2 = x - r, y - r, x + r, y + r + self.canvas.create_oval(x1, y1, x2, y2, width=1, fill=fill, tags=tags) + + def alu_draw(self): + """画alu形状""" + # 定义倒梯形的顶点坐标 + round_rectangle(74, 48, 533, 415, fill="#226DDD", width=0, ) + Point = [90, 190, 120, 190, 130, 215, 205, 215, 215, 190, 245, 190, 220, 270, 115, 270] + self.canvas.create_polygon(Point, fill="black") # 绘制运算器 + self.draw_circle(103, 235, 5, fill=GREY, tags="alu_status") + + def alu_line_init(self): + """ALU模块命名""" + self.canvas.create_text(140, 183, text='ALU', font=('微软雅黑', 20), anchor=tk.NW, fill=WORD) + self.canvas.create_text(345, 95, text="R1", font=('微软雅黑', 18), fill=WORD) + self.canvas.create_text(345, 185, text="R2", font=('微软雅黑', 18), fill=WORD) + self.canvas.create_text(345, 275, text="R3", font=('微软雅黑', 18), fill=WORD) + self.canvas.create_text(345, 365, text="R4", font=('微软雅黑', 18), fill=WORD) + + def alu_operation(self): + """加减乘除""" + side = 30 + n = 0 + for i in "+-x÷": + if cpu_data.ALUop[i]: + cpu_data.ALUop[i] = False + self.canvas.create_text(115 + n * side, 240, text=f'{i}', font=('微软雅黑', 16), anchor=tk.NW, + fill="#FFFFCC") + textbox.send_msg(f"运算符: {i}") + else: + self.canvas.create_text(115 + n * side, 240, text=f'{i}', font=('微软雅黑', 16), anchor=tk.NW, + fill=GREY) + n += 1 + + def alu_r1(self, singed=None): + line_points = [170, 273, 170, 315, 270, 315, 270, 100, 330, 100, ] + if singed: + self.canvas.create_line(line_points, width=5, fill=DATALINE, arrow=tk.LAST, tags="alu_r_line") + else: + self.canvas.create_line(line_points, width=5, fill=GREY, arrow=tk.LAST, tags="alu_r_line") + + def alu_r2(self, singed=None): + line_points = [170, 273, 170, 315, 270, 315, 270, 180, 330, 180, ] + if singed: + self.canvas.create_line(line_points, width=5, fill=DATALINE, arrow=tk.LAST, tags="alu_r_line") + else: + self.canvas.create_line(line_points, width=5, fill=GREY, arrow=tk.LAST, tags="alu_r_line") + + def alu_r3(self, singed=None): + line_points = [170, 273, 170, 315, 270, 315, 270, 275, 330, 275, ] + if singed: + self.canvas.create_line(line_points, width=5, fill=DATALINE, arrow=tk.LAST, tags="alu_r_line") + else: + self.canvas.create_line(line_points, width=5, fill=GREY, arrow=tk.LAST, tags="alu_r_line") + + def alu_r4(self, singed=None): + line_points = [170, 273, 170, 315, 270, 315, 270, 355, 330, 355, ] + if singed: + self.canvas.create_line(line_points, width=5, fill=DATALINE, arrow=tk.LAST, tags="alu_r_line") + else: + self.canvas.create_line(line_points, width=5, fill=GREY, arrow=tk.LAST, tags="alu_r_line") + + def r1_alu1(self, singed=None): + line_points = [340, 80, 340, 65, 310, 65, 100, 65, 100, 190] + if singed: + self.canvas.create_line(line_points, width=5, fill=DATALINE, arrow=tk.LAST, tags="alu_r_line") + else: + self.canvas.create_line(line_points, width=5, fill=GREY, arrow=tk.LAST, tags="alu_r_line") + + def r2_alu1(self, singed=None): + line_points = [340, 165, 340, 155, 310, 155, 310, 65, 100, 65, 100, 190] + if singed: + self.canvas.create_line(line_points, width=5, fill=DATALINE, arrow=tk.LAST, tags="alu_r_line") + else: + self.canvas.create_line(line_points, width=5, fill=GREY, arrow=tk.LAST, tags="alu_r_line") + + def r3_alu1(self, singed=None): + line_points = [340, 245, 340, 235, 310, 235, 310, 65, 100, 65, 100, 190] + if singed: + self.canvas.create_line(line_points, width=5, fill=DATALINE, arrow=tk.LAST, tags="alu_r_line") + else: + self.canvas.create_line(line_points, width=5, fill=GREY, arrow=tk.LAST, tags="alu_r_line") + + def r4_alu1(self, singed=None): + line_points = [340, 335, 340, 325, 310, 325, 310, 65, 100, 65, 100, 190] + if singed: + self.canvas.create_line(line_points, width=5, fill=DATALINE, arrow=tk.LAST, tags="alu_r_line") + else: + self.canvas.create_line(line_points, width=5, fill=GREY, arrow=tk.LAST, tags="alu_r_line") + + def r1_alu2(self, singed=None): + line_points = [340, 110, 340, 130, 295, 130, 295, 240, 250, 240, 250, 160, 230, 160, 230, 190] + if singed: + self.canvas.create_line(line_points, width=5, fill=DATALINE, arrow=tk.LAST, tags="alu_r_line") + else: + self.canvas.create_line(line_points, width=5, fill=GREY, arrow=tk.LAST, tags="alu_r_line") + + def r2_alu2(self, singed=None): + line_points = [340, 200, 340, 220, 295, 220, 295, 240, 250, 240, 250, 160, 230, 160, 230, 190] + if singed: + self.canvas.create_line(line_points, width=5, fill=DATALINE, arrow=tk.LAST, tags="alu_r_line") + else: + self.canvas.create_line(line_points, width=5, fill=GREY, arrow=tk.LAST, tags="alu_r_line") + + def r3_alu2(self, singed=None): + line_points = [340, 290, 340, 310, 295, 310, 295, 240, 250, 240, 250, 160, 230, 160, 230, 190] + if singed: + self.canvas.create_line(line_points, width=5, fill=DATALINE, arrow=tk.LAST, tags="alu_r_line") + else: + self.canvas.create_line(line_points, width=5, fill=GREY, arrow=tk.LAST, tags="alu_r_line") + + def r4_alu2(self, singed=None): + line_points = [340, 380, 340, 395, 295, 395, 295, 240, 250, 240, 250, 160, 230, 160, 230, 190] + if singed: + self.canvas.create_line(line_points, width=5, fill=DATALINE, arrow=tk.LAST, tags="alu_r_line") + else: + self.canvas.create_line(line_points, width=5, fill=GREY, arrow=tk.LAST, tags="alu_r_line") + + def r1_entry(self, str=f"{0:016b}"): + self.r1 = tk.Entry(self.canvas) + self.r1.insert(0, str) + self.r1.config(width=16, font=('微软雅黑', 12)) + ent_win = self.canvas.create_window(365, 85, window=self.r1, anchor=tk.NW) + ent_win.conjugate() + + def r2_entry(self, str=f"{0:016b}"): + self.r2 = tk.Entry(self.canvas) + self.r2.insert(0, str) + self.r2.config(width=16, font=('微软雅黑', 12)) + ent_win = self.canvas.create_window(365, 175, window=self.r2, anchor=tk.NW) + ent_win.conjugate() + + def r3_entry(self, str=f"{0:016b}"): + self.r3 = tk.Entry(self.canvas) + self.r3.insert(0, str) + self.r3.config(width=16, font=('微软雅黑', 12)) + ent_win = self.canvas.create_window(365, 265, window=self.r3, anchor=tk.NW) + ent_win.conjugate() + + def r4_entry(self, str=f"{0:016b}"): + self.r4 = tk.Entry(self.canvas) + self.r4.insert(0, str) + self.r4.config(width=16, font=('微软雅黑', 12)) + ent_win = self.canvas.create_window(365, 355, window=self.r4, anchor=tk.NW) + ent_win.conjugate() + + def show_alu_line(self, ALUio=None): + singed = [] # 保存需要显示的数据线 + if ALUio is not None: + for io, torf in ALUio.items(): # 遍历数据线的字典 + if torf: # 如果数据线的值为True + singed.append(io) # 将数据线的名字添加到列表中 + self.canvas.delete("alu_r_line") + self.alu_r1() + self.alu_r2() + self.alu_r3() + self.alu_r4() + self.r1_alu1() + self.r2_alu1() + self.r3_alu1() + self.r4_alu1() + self.r1_alu2() + self.r2_alu2() + self.r3_alu2() + self.r4_alu2() + for singe in singed: + if singe == "ALU_R1": + self.alu_r1("ALU_R1") + textbox.send_msg("ALU->R1") + if singe == "ALU_R2": + self.alu_r2("ALU_R2") + textbox.send_msg("ALU->R2") + if singe == "ALU_R3": + self.alu_r3("ALU_R3") + textbox.send_msg("ALU->R3") + if singe == "ALU_R4": + self.alu_r4("ALU_R4") + textbox.send_msg("ALU->R4") + if singe == "R1_ALU_1": + self.r1_alu1("R1_ALU_1") + textbox.send_msg("R1->ALU1") + if singe == "R2_ALU_1": + self.r2_alu1("R2_ALU_1") + textbox.send_msg("R2->ALU1") + if singe == "R3_ALU_1": + self.r3_alu1("R3_ALU_1") + textbox.send_msg("R3->ALU1") + if singe == "R4_ALU_1": + self.r4_alu1("R4_ALU_1") + textbox.send_msg("R4->ALU1") + if singe == "R1_ALU_2": + self.r1_alu2("R1_ALU_2") + textbox.send_msg("R1->ALU2") + if singe == "R2_ALU_2": + self.r2_alu2("R2_ALU_2") + textbox.send_msg("R2->ALU2") + if singe == "R3_ALU_2": + self.r3_alu2("R3_ALU_2") + textbox.send_msg("R3->ALU2") + if singe == "R4_ALU_2": + self.r4_alu2("R4_ALU_2") + textbox.send_msg("R4->ALU2") + + def show_alu_reg(self, reg=None, str=None): + if reg == "r1": + self.r1.delete(0, tk.END);self.r1.insert(0, str) + elif reg == "r2": + self.r2.delete(0, tk.END);self.r2.insert(0, str) + elif reg == "r3": + self.r3.delete(0, tk.END);self.r3.insert(0, str) + elif reg == "r4": + self.r4.delete(0, tk.END);self.r4.insert(0, str) + + +class MEMO: + def __init__(self): + self.canvas = canvas + round_rectangle(597, 205, 928, 670, r=25, fill="#0153d2", width=0) + round_rectangle(675, 275, 910, 660, r=25, fill="black", width=0) + + self.canvas.create_rectangle(720, 281, 903, 654, fill=MEMBACK, width=0) + + self.mad_value = f"{0:016b}" # 初始化Maddr的值 + self.original_value = 9999 # 保存变量mad_value的原来值,用于检查值是否更新 + + self.show() + self.show_maddr(self.mad_value) # 显示Maddr的值 + self.show_mco() + self.show_offset(cpu_data.SimMem) # 显示地址 + self.load_memo_data(cpu_data.SimMem) # 显示内存数据 + + def draw_circle(self, x, y, r, fill=None, tags=None): + """根据圆心坐标和半径画圆""" + # 圆外接矩形 + x1, y1, x2, y2 = x - r, y - r, x + r, y + r + self.canvas.create_oval(x1, y1, x2, y2, width=1, fill=fill, tags=tags) + + def mad_to_memo(self, value=None): # value 用来控制地址线的显示 + """mad指向内存""" + self.show_maddr(self.mad_value) # 刷新Maddr的显示 + if value: + offset = int(self.mad_value, 2) # 转换为int + self.show_maddr(self.mad_value, 1) # 显示Maddr的变化 + else: + offset = None + self.mem_get(offset) # 从内存中获取响应地址的二进制值 + + def mco_to_memo(self): + """mco指向内存""" + offset = int(self.mad_value, 2) # int二进制转换 + value = self.mco.get() + self.mem_save(offset, value) + # textbox.send_msg("MCO->memo") + + def show(self): + self.canvas.create_text(670, 219, text='Mcontent', font=('微软雅黑', 12, 'bold'), anchor=tk.NW, fill=WORD) + self.canvas.create_text(611, 356, text='Maddr', font=('微软雅黑', 12, 'bold'), anchor=tk.NW, fill=WORD) + self.canvas.create_text(700, 260, text='地址', font=('time', 12,), anchor=tk.CENTER, fill='#ffd700') + self.canvas.create_text(790, 260, text='在选单元', font=('time', 12,), anchor=tk.CENTER, fill='#ffd700') + + def show_mco(self): # 显示mco + self.mco = tk.Entry(self.canvas) + self.mco.insert(0, f"{0:016b}") + self.mco.config(width=16, font=('微软雅黑', 12)) + ent_win = self.canvas.create_window(753, 218, window=self.mco, anchor=tk.NW) + ent_win.conjugate() + + def show_offset(self, SimMem): # 显示地址 + for i in range(len(SimMem)): # 显示存储器各个单元的地址 + self.canvas.create_text(688, 282 + 18.5 * i, text=f"{i:02X}", + font=('微软雅黑', 12), anchor=tk.NW, fill=GOLD) + + def load_memo_data(self, SimMem): # 程序单元 + self.canvas.delete("bin_code") + for i in range(20): + bin_str = SimMem[i] + bin_str_spa = " ".join([bin_str[i:i + 8] for i in range(0, len(bin_str), 8)]) + self.canvas.create_text(735, 282 + 18.5 * i, text=bin_str_spa, + font=('微软雅黑', 12), anchor=tk.NW, fill="black", tags="bin_code") + self.draw_circle(675, 293 + 18.5 * i, 5, fill=GREY, tags="bin_code") + + def mem_save(self, offset, value, SimMem=cpu_data.SimMem, load=None): + """保存value到offset地址""" + self.canvas.delete("bin_code") + SimMem[offset] = value + for i in range(20): + bin_str = SimMem[i] + bin_str_spa = " ".join([bin_str[i:i + 8] for i in range(0, len(bin_str), 8)]) + self.canvas.create_text(735, 282 + 18.5 * i, text=bin_str_spa, + font=('微软雅黑', 12), anchor=tk.NW, fill="black", tags="bin_code") + if i == offset: + y = 293 + 18.5 * i + self.draw_circle(675, y, 7, fill=GREEN, tags="bin_code") + # Maddr -> memo + line_points = [650, y, 669, y] + self.canvas.create_line(line_points, width=4, fill=ADDRLINE, arrow=tk.LAST, tags="bin_code") + if load is None: + textbox.send_msg(f"MAD->memo[{i:02X}]") + # moo -> memo + line_points = [855, 245, 855, 275] + self.canvas.create_line(line_points, width=5, fill=DATALINE, arrow=tk.LAST, tags="bin_code") + if load is None: + textbox.send_msg(f"MCO->memo[{i:02X}]") + else: + self.draw_circle(675, 293 + 18.5 * i, 5, fill=GREY, tags="bin_code") + + def mem_get(self, offset): + """获取offset地址的值""" + self.canvas.delete("bin_code") + # 更新内存显示值 + self.mco.config(bg=WHITE) + for i in range(20): + bin_str = SimMem[i] + bin_str_spa = " ".join([bin_str[i:i + 8] for i in range(0, len(bin_str), 8)]) + self.canvas.create_text(735, 282 + 18.5 * i, text=bin_str_spa, + font=('微软雅黑', 12), anchor=tk.NW, fill="black", tags="bin_code") + # 当传入地址时,显示数据线指示 + if i == offset: + y = 293 + 18.5 * i + self.draw_circle(675, y, 7, fill=RED, tags="bin_code") # 显示寻址单位激活态圆 + # Maddr -> memo + line_points = [650, y, 669, y] + self.canvas.create_line(line_points, width=4, fill=ADDRLINE, arrow=tk.LAST, tags="bin_code") + textbox.send_msg(f"MAD->memo[{offset:02X}]") + # memo -> Mco + line_points = [875, 245, 875, 275] + self.canvas.create_line(line_points, width=5, fill=DATALINE, arrow=tk.FIRST, tags="bin_code") + textbox.send_msg(f"memo[{offset:02X}]->MCO") + self.mco.delete(0, tk.END) # 更新mco的值 + self.mco.insert(0, SimMem[offset]) + self.mco.config(bg=RED) + else: + self.draw_circle(675, 293 + 18.5 * i, 5, fill=GREY, tags="bin_code") + + def show_maddr(self, get_pc, col_tag=None): + # 根据存储的数据显示当前Maddr的值 + self.mad_value = get_pc + self.canvas.delete("maddr") + if col_tag is not None: + self.canvas.create_rectangle(619, 383, 648, 541, fill=RED, width=0, tags="maddr") + else: + self.canvas.create_rectangle(619, 383, 648, 541, fill=WHITE, width=0, tags="maddr") + self.canvas.create_text(620, 390, text=self.mad_value, font=('微软雅黑', 12), anchor=tk.NE, fill=BLACK, + angle=90, tags="maddr") + + +class SIGCtrl: + def __init__(self): + self.canvas = canvas + round_rectangle(74, 434, 533, 642, r=25, fill=BACK, width=0) + round_rectangle(97, 525, 276, 627, r=25, fill=BLACK, width=0) + self.x0, self.y0, self.r = 113, 473, 15 # 时钟大小 + self.bx2, self.by2, self.dx, self.dy = 105, 558, 120, 16 # 设置sig_ctrl文字间隔 + self.ir_value = f"{0:016b}" + self.pc_value = f"{0:016b}" + self.clo_mark() + self.show_tags() + self.pc_reg_value() + self.ir_reg_value() + self.show_singe() + self.insCode() + + def draw_circle(self, x, y, r, fill=WHITE, tags=None): + """根据圆心坐标和半径画圆""" + # 圆外接矩形 + x1, y1, x2, y2 = x - r, y - r, x + r, y + r + self.canvas.create_oval(x1, y1, x2, y2, width=1, fill=fill, tags=tags) + + def clo_mark(self, time_series: int = None): # 依据时钟周期显示时钟周期 + self.canvas.delete("time") + round_rectangle(95, 455, 95 + 213, 455 + 37, fill=WHITE, width=0, tags="time") + + for i in range(6): # 遍历六个时钟刻,绘制各个时钟 + ClockStep[i] = True + x = i * 35 + self.x0 + self.draw_circle(x, self.y0, self.r, fill=WHITE, tags="time") + if i == time_series: + self.draw_circle(x, self.y0, self.r, fill=RED, tags="time") + self.canvas.create_text(x, self.y0, text=f"{i + 1}", font=('微软雅黑', 16, 'bold'), anchor=tk.CENTER, + fill=BLACK, tags='time') + + def show_tags(self): # 显示标签 + self.canvas.create_text(95, 434, text='Clock', font=('微软雅黑', 12, 'bold'), anchor=tk.NW, fill=WORD) + self.canvas.create_text(342, 434, text='PC', font=('微软雅黑', 12, 'bold'), anchor=tk.NW, fill=WORD) + self.canvas.create_text(104, 500, text='SigCtrl', font=('微软雅黑', 12, 'bold'), anchor=tk.NW, fill=WORD) + self.canvas.create_text(342, 540, text='IR', font=('微软雅黑', 12, 'bold'), anchor=tk.NW, fill=WORD) + + def pc_reg_value(self): + self.pc_reg = tk.Entry(self.canvas) # PC 寄存器 + self.pc_reg.config(width=16, font=('微软雅黑', 12)) + self.pc_reg.insert(0, self.pc_value) + self.canvas.create_window(335, 455, window=self.pc_reg, anchor=tk.NW) + + def ir_reg_value(self): + value = self.ir_value + self.canvas.delete("ir_reg") + self.ir_reg = tk.Entry(self.canvas) # IR 寄存器 + self.ir_reg.config(width=17, font=('微软雅黑', 12)) + self.ir_reg.insert(0, value[:6] + " " + value[6:]) + self.canvas.create_window(335, 565, window=self.ir_reg, anchor=tk.NW, tags="ir_reg") + + def insCode(self): + self.ins = tk.Entry(self.canvas) + self.ins.config(width=6, font=('微软雅黑', 12)) + self.ins.insert(0, f"{0:06b}") + self.canvas.create_window(203, 532, window=self.ins, anchor=tk.NW, tags="ins_code") + + def show_singe(self): + sings = [] + for sing in cpu_data.SigObj: # 遍历信号字典 + if cpu_data.SigObj[sing][1]: # 如果信号的值为True + sings.append(sing) # 将信号的名字添加到列表中 + + self.canvas.delete("sig_ctrl") + self.canvas.create_text(110, 535, text="insCode", + font=('微软雅黑', 12), fill=GOLD, anchor=tk.NW, tags="sig_ctrl") + self.canvas.create_text(self.bx2, self.by2, text='->ALU', + font=('微软雅黑', 10), anchor=tk.NW, tags="sig_ctrl", fill=GREY) + self.canvas.create_text(self.bx2, self.by2 + self.dy, text='->IR', + font=('微软雅黑', 10), anchor=tk.NW, tags="sig_ctrl", fill=GREY) + self.canvas.create_text(self.bx2, self.by2 + self.dy * 2, text='->PC + 1', + font=('微软雅黑', 10), anchor=tk.NW, tags="sig_ctrl", fill=GREY) + self.canvas.create_text(self.bx2, self.by2 + self.dy * 3, text='->MEMORY', + font=('微软雅黑', 10), anchor=tk.NW, tags="sig_ctrl", fill=GREY) + self.canvas.create_text(self.bx2 + self.dx, self.by2, text='->R1', + font=('微软雅黑', 10), anchor=tk.NW, tags="sig_ctrl", fill=GREY) + self.canvas.create_text(self.bx2 + self.dx, self.by2 + self.dy, text='->R2', + font=('微软雅黑', 10), anchor=tk.NW, tags="sig_ctrl", fill=GREY) + self.canvas.create_text(self.bx2 + self.dx, self.by2 + self.dy * 2, text='->R3', + font=('微软雅黑', 10), anchor=tk.NW, tags="sig_ctrl", fill=GREY) + self.canvas.create_text(self.bx2 + self.dx, self.by2 + self.dy * 3, text='->R4', + font=('微软雅黑', 10), anchor=tk.NW, tags="sig_ctrl", fill=GREY) + + for sing in sings: + if sing == "->ALU": + # if cpu_data.SigObj[sing][1]: + self.canvas.create_text(self.bx2, self.by2, text='->ALU', font=('微软雅黑', 10), anchor=tk.NW, + tags="sig_ctrl", fill=GOLD) + cpu_data.SigObj[sing][1] = False + if sing == "->IR": + self.canvas.create_text(self.bx2, self.by2 + self.dy, text='->IR', font=('微软雅黑', 10), anchor=tk.NW, + tags="sig_ctrl", fill=GOLD) + cpu_data.SigObj[sing][1] = False + if sing == "->PC+1": + self.canvas.create_text(self.bx2, self.by2 + self.dy * 2, text='->PC + 1', font=('微软雅黑', 10), + anchor=tk.NW, tags="sig_ctrl", fill=GOLD) + cpu_data.SigObj[sing][1] = False + if sing == "->Memory": + self.canvas.create_text(self.bx2, self.by2 + self.dy * 3, text='->MEMORY', font=('微软雅黑', 10), + anchor=tk.NW, tags="sig_ctrl", fill=GOLD) + cpu_data.SigObj[sing][1] = False + if sing == "->R1": + self.canvas.create_text(self.bx2 + self.dx, self.by2, text='->R1', font=('微软雅黑', 10), anchor=tk.NW, + tags="sig_ctrl", fill=GOLD) + cpu_data.SigObj[sing][1] = False + if sing == "->R2": + self.canvas.create_text(self.bx2 + self.dx, self.by2 + self.dy, text='->R2', font=('微软雅黑', 10), + anchor=tk.NW, tags="sig_ctrl", fill=GOLD) + cpu_data.SigObj[sing][1] = False + if sing == "->R3": + self.canvas.create_text(self.bx2 + self.dx, self.by2 + self.dy * 2, text='->R3', font=('微软雅黑', 10), + anchor=tk.NW, tags="sig_ctrl", fill=GOLD) + cpu_data.SigObj[sing][1] = False + if sing == "->R4": + self.canvas.create_text(self.bx2 + self.dx, self.by2 + self.dy * 3, text='->R4', font=('微软雅黑', 10), + anchor=tk.NW, tags="sig_ctrl", fill=GOLD) + cpu_data.SigObj[sing][1] = False + + +if __name__ == '__main__': + gui = GUISim() + alu = ALU() + memo = MEMO() + # memo.mem_get(12) + sig = SIGCtrl() + root.mainloop()