Skip to content

Commit

Permalink
Merge pull request #32 from yyan7223/master
Browse files Browse the repository at this point in the history
Add the function of sending the PyMTL3 RTL to Openroad and executing the RTL-GDSII flow.
  • Loading branch information
tancheng authored Oct 4, 2024
2 parents ab6254d + f09c687 commit 3689320
Showing 1 changed file with 104 additions and 66 deletions.
170 changes: 104 additions & 66 deletions launchUI.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ def window_size(window, width, height):

mapped_tile_color_list = ['#FFF113', '#75D561', '#F2CB67', '#FFAC73', '#F3993A', '#B3FF04', '#C2FFFF']

processOptions = tkinter.StringVar()
processOptions.set("asap7")

class ParamTile:
def __init__(s, ID, dimX, dimY, posX, posY, tileWidth, tileHeight):
s.ID = ID
Expand Down Expand Up @@ -2107,15 +2110,32 @@ def create_test_pannel(master):
reportSPMPowerLabel.grid(row=6, column=0, pady=5)
reportSPMPowerData.grid(row=6, column=1, pady=5)

"""
def create_layout_pannel(master):
# layoutPannel = tkinter.LabelFrame(master, text='Layout', bd=BORDER, relief='groove')
layoutPannel = customtkinter.CTkFrame(master)
layoutPannel.grid(row=0, column=3, rowspan=1, columnspan=1, padx=(5,0), pady=(5,0), sticky="nsew")
layoutPannelLabel = customtkinter.CTkLabel(layoutPannel, text='Layout ',
# width=100,
font=customtkinter.CTkFont(size=FRAME_LABEL_FONT_SIZE, weight="bold"))
layoutPannelLabel.pack(anchor="w", padx=(5,0))
layoutPannelLabel.grid(row=0, column=0, sticky="w")

# Adds the option menu to select process technology.
processNameLabel = customtkinter.CTkLabel(layoutPannel, text="Process:")
processNameLabel.grid(row=1, column=0, pady=(10,10))
tempOptions = [ "asap7", "nangate45", "sky130hd"]
processNameMenu = customtkinter.CTkOptionMenu(layoutPannel, variable=processOptions, values=tempOptions)
processNameMenu.grid(row=1, column=1, padx=(0,10), pady=(10,10))

# Adds the button to trigger RTL->GDSII flow.
openRoadButton = customtkinter.CTkButton(layoutPannel, text="RTL->GDSII", command=clickRTL2GDSII)
openRoadButton.grid(row=1, column=2, padx=(0,20), pady=(10,10))

# Adds a placeholder to show the layout image saved from OpenRoad.
global layoutLabel
layoutLabel = customtkinter.CTkLabel(layoutPannel, text='')
layoutLabel.grid(row=2, column=0, padx=(0,10), pady=(10,10), columnspan=3)

"""
canvas = customtkinter.CTkCanvas(layoutPannel, bg=CANVAS_BG_COLOR, bd=0, highlightthickness=0)
scrollbar = customtkinter.CTkScrollbar(layoutPannel, orientation="horizontal", command=canvas.xview)
scrollbar.pack(side="bottom", fill="x")
Expand All @@ -2126,79 +2146,97 @@ def create_layout_pannel(master):
showButton = customtkinter.CTkButton(layoutPannel, text="Display layout")
CreateToolTip(showButton, text="The layout demonstration is\nunder development.")
showButton.place(relx=0.5, rely=0.1, anchor="center")
# X = customtkinter.CTkLabel(layout_frame)
# X.pack()
"""

def create_layout_pannel(master, x, width, height):
layoutPannel = tkinter.LabelFrame(master, text='Layout', bd=BORDER, relief='groove')
layoutPannel.place(height=height, width=width, x=x, y=INTERVAL)
# Adds the showButton for the layout display
showButton = tkinter.Button(layoutPannel, text="Display layout", relief='raised',
command=clickDisplayLayout, highlightbackground="black", highlightthickness=1)
showButton.pack()
global layout_label
layout_label = tkinter.Label(layoutPannel, fg="black")
layout_label.pack()

def clickDisplayLayout():
# Hardcodes the related path, will fix later.
flow_basePath = os.path.dirname(os.path.abspath(__file__)) + "/tools/OpenROAD-flow-scripts/flow/"
layout_path = flow_basePath + "layout.png"
odb_path = flow_basePath + "results/nangate45/gcd/base/6_final.odb"
cmd_path = flow_basePath + "cmd.tcl"

# Checks if layout.png of default gcd example already exists.
# If yes, directly show.

def constructDependencyFiles(cgraflow_basepath, standard_module_name, test_platform_name, verilog_srcfile_path, mk_sdc_file_path, orfs_basePath):
# Finds the target RTL design and transforms the format.
files = os.listdir(cgraflow_basepath + "/build/verilog")
for f in files:
# Finds the generated verilog file.
if f == "design.v":
os.chdir(cgraflow_basepath + "/build/verilog")
# Manually copies design.v to design.sv to make sv2v work normally.
print("Renaming the system verilog file generated by PyMTL3.")
subprocess.run(["cp design.v design.sv"], shell=True, encoding="utf-8")
# Uses sv2v to convert system verilog to verilg.
print("Converting the system verilog file to verilog file.")
subprocess.run(["../../tools/sv2v/bin/sv2v --write=adjacent " + "design.sv"], shell=True, encoding="utf-8")
# Changes the top module name in design.v to standard_module_name.
print("Standardizing the top module name in verilog file.")
contents = ""
with open("design.v", "r", encoding="utf-8") as lines:
for line in lines:
if standard_module_name in line:
line = "module " + standard_module_name + " ("
contents += line
with open(standard_module_name + ".v", "w", encoding="utf-8") as newFile:
newFile.write(contents)
break

# Makes directories and copies CGRATemplateRTL.v, the pre-defined config.mk, and constraint.sdc to their respective directories.
os.chdir(orfs_basePath)
subprocess.run(["mkdir -p " + verilog_srcfile_path], shell=True, encoding="utf-8")
subprocess.run(["cp " + cgraflow_basepath + "/build/verilog/" + standard_module_name + ".v " + verilog_srcfile_path], shell=True, encoding="utf-8")
subprocess.run(["mkdir -p " + mk_sdc_file_path], shell=True, encoding="utf-8")
subprocess.run(["cp " + cgraflow_basepath + "/build/config.mk " + mk_sdc_file_path], shell=True, encoding="utf-8")
subprocess.run(["cp " + cgraflow_basepath + "/build/constraint.sdc " + mk_sdc_file_path], shell=True, encoding="utf-8")

# Updates process within the config.mk to the user selected one.
with open(mk_sdc_file_path + "config.mk", 'r') as file:
# Reads all lines within the file.
lines = file.readlines()
# Modifies the first line, replaces the PLATFORM with the user selected process technology.
lines[0] = "export PLATFORM = " + test_platform_name + "\n"
with open(mk_sdc_file_path + "config.mk", 'w') as file:
# Writes the updated content back to config.mk.
file.writelines(lines)

def runOpenRoad(mk_sdc_file_path, cmd_path, odb_path, layout_path):
# Runs the test module from RTL to GDSII.
subprocess.run(["make DESIGN_CONFIG=./" + mk_sdc_file_path + "config.mk"], shell=True, encoding="utf-8")
# Generates a cmd.tcl file for openroad
if os.path.exists(cmd_path):
os.remove(cmd_path)
with open(cmd_path, mode="a", encoding="utf-8") as file:
# Load the test module layout file.
file.write("read_db " + odb_path + "\n")
# Saves layout to image.
file.write("save_image " + layout_path + "\n")
file.write("exit")
# Runs openroad.
subprocess.run(["openroad", cmd_path], shell=False, encoding="utf-8")

def clickRTL2GDSII():
standard_module_name = "CGRATemplateRTL"
cgraflow_basepath = os.path.dirname(os.path.abspath(__file__))
test_platform_name = processOptions.get()
print("Test platform is %s" % (test_platform_name))
orfs_basePath = cgraflow_basepath + "/tools/OpenROAD-flow-scripts/flow/"
layout_path = orfs_basePath + "layout.png"
odb_path = orfs_basePath + "results/" + test_platform_name + "/" + standard_module_name + "/base/6_final.odb"
cmd_path = orfs_basePath + "cmd.tcl"
verilog_srcfile_path = "designs/src/" + standard_module_name + "/"
mk_sdc_file_path = "designs/" + test_platform_name + "/" + standard_module_name + "/"

# Checks if layout.png of target design already exists.
# If yes, directly shows.
if os.path.exists(layout_path):
display_layout_image(layout_path)
return
# If not, make the default gcd example and save layout.png then show.
# If not, runs the design from RTL to GDSII and saves layout.png, finally shows.
else:
os.chdir(flow_basePath)
# Runs default gcd example from RTL to GDSII.
subprocess.run(["make"], shell=True, encoding="utf-8")
# Generates a cmd.tcl file for openroad
if os.path.exists(cmd_path):
os.remove(cmd_path)
with open(cmd_path, mode="a", encoding="utf-8") as file:
# Load default gcd example layout file.
file.write("read_db " + odb_path + "\n")
# Saves layout to image.
file.write("save_image " + layout_path + "\n")
file.write("exit")
# Generates all dependency files for openroad.
constructDependencyFiles(cgraflow_basepath, standard_module_name, test_platform_name,
verilog_srcfile_path, mk_sdc_file_path, orfs_basePath)
# Runs openroad.
subprocess.run(["openroad", cmd_path], shell=False, encoding="utf-8")
runOpenRoad(mk_sdc_file_path, cmd_path, odb_path, layout_path)
# Shows the layout image on CGRA-Flow GUI.
display_layout_image(layout_path)

def display_layout_image(image_path):
try:
# Opens the image and resize it to fit the display.
img = Image.open(image_path)

# Logs the original image size before resizing.
print(f"Original image size: {img.size}")

# Resizes the image to fit within a 300x300 display area.
# Uses LANCZOS for high-quality downsampling.
img = img.resize((300, 300), Image.LANCZOS)
img = ImageTk.PhotoImage(img)

# Displays the image in the layout label.
if layout_label is not None:
layout_label.config(image=img)
layout_label.image = img
print(f"Displayed image from {image_path} successfully.")
else:
print("Error: layout_label is None. Ensure layout_label is initialized properly.")
tkinter.messagebox.showerror("Error", "Layout label is not initialized.")

except FileNotFoundError:
tkinter.messagebox.showerror("Error", f"Image file not found: {image_path}")
except Exception as e:
tkinter.messagebox.showerror("Error", f"Error displaying layout image: {str(e)}")

layoutImage = customtkinter.CTkImage(light_image=Image.open(image_path),
dark_image=Image.open(image_path),
size=(320, 320))
layoutLabel.configure(image=layoutImage)

def create_mapping_pannel(master):
# mappingPannel = tkinter.LabelFrame(master, text='Mapping', bd=BORDER, relief='groove')
Expand Down

0 comments on commit 3689320

Please sign in to comment.