blob: 254236641d074614cd9942a2750c5da0079f81c1 [file] [log] [blame]
# Copyright 2020 Efabless Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import argparse
import subprocess
import utils.utils as utils
parser = argparse.ArgumentParser(
description="update configuration of design(s) per given PDK"
)
parser.add_argument(
"--root",
"-r",
action="store",
default="./",
help="The root directory. assuming root/designs, root/scripts root/logs",
)
parser.add_argument(
"--pdk", "-p", action="store", required=True, help="The name of the PDK"
)
parser.add_argument(
"--std-cell-library",
"-scl",
action="store",
required=True,
help="The name of the standard cell library",
)
parser.add_argument("--designs", "-d", nargs="+", default=[], help="designs to update ")
parser.add_argument(
"--best_results",
"-b",
action="store",
required=True,
help="name of the log file from which to extract the name of the best configs",
)
parser.add_argument(
"--clean",
"-cl",
action="store_true",
default=False,
help="deletes the config file that the data was extracted from",
)
parser.add_argument(
"--update_clock_period",
"-ucp",
action="store_true",
default=False,
help="Updates the CLOCK_PERIOD of the design based on the suggested_clock_period parameter",
)
args = parser.parse_args()
root = args.root
pdk = args.pdk
std_cell_library = args.std_cell_library
designs = list(dict.fromkeys(args.designs))
best_results = args.best_results
clean = args.clean
update_clock_period = args.update_clock_period
logFileOpener = open(root + "/regression_results/" + best_results, "r")
logFileData = logFileOpener.read().split("\n")
logFileOpener.close()
headerInfo = logFileData[0].split(",")
configIdx = 0
designIdx = 0
flow_statusIdx = 0
clkPeriodIdx = -1
for i in range(len(headerInfo)):
if headerInfo[i] == "config":
configIdx = i
continue
if headerInfo[i] == "design":
designIdx = i
continue
if headerInfo[i] == "flow_status":
flow_statusIdx = i
continue
if headerInfo[i] == "suggested_clock_period":
clkPeriodIdx = i
designConfigDict = dict()
designFailDict = dict()
designClockDict = dict()
logFileData = logFileData[1:]
for line in logFileData:
if line != "":
splitLine = line.split(",")
designConfigDict[str(splitLine[designIdx])] = str(splitLine[configIdx])
designFailDict[str(splitLine[designIdx])] = (
str(splitLine[flow_statusIdx]) == "flow_completed"
)
if clkPeriodIdx != -1:
designClockDict[str(splitLine[designIdx])] = str(splitLine[clkPeriodIdx])
if len(designs) == 0:
designs = [key for key in designConfigDict]
for design in designs:
if design not in designConfigDict.keys():
print(f"{design} not found in sheet. Skipping...")
if not designFailDict[design]:
print(f"Skipping {design} ...")
continue
print(f"Updating {design} config...")
base_path = utils.get_design_path(design=design)
configFileToUpdate = (
str(base_path) + "/" + str(pdk) + "_" + str(std_cell_library) + "_config.tcl"
)
configFileBest = str(base_path) + "/" + str(designConfigDict[design]) + ".tcl"
configFileBestOpener = open(configFileBest, "r")
configFileBestData = configFileBestOpener.read().split("\n")
configFileBestOpener.close()
newData = ""
copyFrom = False
for line in configFileBestData:
if line == "# Regression":
copyFrom = True
if copyFrom:
newData += line + "\n"
configFileToUpdateOpener = open(configFileToUpdate, "a+")
configFileToUpdateOpener.write(newData)
if update_clock_period:
if design in designClockDict and float(designClockDict[design]) > 0:
clockLine = (
'\n# Suggested Clock Period:\nset ::env(CLOCK_PERIOD) "'
+ str(round(float(designClockDict[design]), 2))
+ '"\n'
)
configFileToUpdateOpener.write(clockLine)
configFileToUpdateOpener.close()
if clean:
clean_cmd = f"rm -f {configFileBest}"
subprocess.check_output(clean_cmd.split())
# clean config file