|
|
# -*- 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("<Button-1>", self.on_left_click)
|
|
|
# root_right.bind("<Button-1>", 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()
|