blob: ac1d23b121bfdf185fa0200219f6ad86b359cce0 [file] [log] [blame]
import os
import io
import re
def CollateErrors(sourceLocation:str, outputLocation:str):
macrosPaths = [ f.path for f in os.scandir(sourceLocation) if f.is_dir() ]
for macroPath in macrosPaths:
CheckMacro(macroPath, outputLocation)
def CheckMacro(macroPath:str, outputLocation:str):
outputDirNames = ["logs", "reports"]
macroName = os.path.basename(macroPath)
print(f"Checking macro '{macroName}': ", end="")
buildPath = os.path.join(macroPath, "runs", macroName)
macroOutputPath = os.path.join(outputLocation, macroName)
if not os.path.exists(macroOutputPath):
os.mkdir(macroOutputPath)
errorOutputFilePath = os.path.join(macroOutputPath, "errors.log")
if os.path.exists(errorOutputFilePath):
os.remove(errorOutputFilePath)
warningOutputFilePath = os.path.join(macroOutputPath, "warnings.log")
if os.path.exists(warningOutputFilePath):
os.remove(warningOutputFilePath)
errorCount = 0
warningCount = 0
violationCount = 0
errorOutputFile = None
warningOutputFile = None
try:
errorOutputFile = open(errorOutputFilePath, "a")
warningOutputFile = open(warningOutputFilePath, "a")
if os.path.exists(buildPath):
# Copy errors from file
errorFilePath = os.path.join(buildPath, "errors.log")
if os.path.exists(errorFilePath):
with open(errorFilePath, "r") as f:
lines = f.readlines()
errorOutputFile.writelines(lines)
errorCount += len(lines)
# Copy warnings from file
warningFilePath = os.path.join(buildPath, "warnings.log")
if os.path.exists(warningFilePath):
with open(warningFilePath, "r") as f:
lines = f.readlines()
warningOutputFile.writelines(lines)
warningCount += len(lines)
# Check for synthesis problems
for dir in outputDirNames:
synthesisFilesPath = os.path.join(buildPath, dir, "synthesis")
synthesisFiles = [ f.path for f in os.scandir(synthesisFilesPath) if f.is_file() and f.path.endswith(".log") ]
for file in synthesisFiles:
e, w, v = CheckFile(file, errorOutputFile, warningOutputFile)
errorCount += e
warningCount += w
violationCount += v
# Check for routing violations
for dir in outputDirNames:
routingFilesPath = os.path.join(buildPath, dir, "routing")
routingFiles = [ f.path for f in os.scandir(routingFilesPath) if f.is_file() and f.path.endswith(".rpt") ]
for file in routingFiles:
e, w, v = CheckFile(file, errorOutputFile, warningOutputFile)
errorCount += e
warningCount += w
violationCount += v
finally:
if errorOutputFile != None:
errorOutputFile.close()
if warningOutputFile != None:
warningOutputFile.close()
if errorCount == 0 and violationCount == 0 and warningCount == 0:
print("Ok")
else:
print("Found issues")
if errorCount != 0:
print(f" \033[91mErrors: {errorCount}\033[0m")
if violationCount != 0:
print(f" \033[91mViolations: {violationCount}\033[0m")
if warningCount != 0:
print(f" \033[93mWarnings: {warningCount}\033[0m")
def CheckFile(fileName:str, errorFile:io.TextIOWrapper, warningFile:io.TextIOWrapper) -> tuple[int, int, int]:
if not os.path.exists(fileName):
return 0, 0, 0
errorCount = 0
warningCount = 0
violationCount = 0
with open(fileName, "r") as f:
lines = f.readlines()
text = "".join(lines)
# errors = re.findall(".*(?<![_\\-.\\w])error(?![_\\-.\\w]).*", text, re.IGNORECASE)
# if len(errors) > 0:
# errorFile.writelines(errors)
# errorCount += len(errors)
# violations = re.findall(".*(?<![_\\-.\\w])violated(?![_\\-.\\w]).*", text, re.IGNORECASE)
# if len(violations) > 0:
# errorFile.writelines(violations)
# violationCount += len(violations)
# warnings = re.findall(".*(?<![_\\-.\\w])warning(?![_\\-.\\w]).*", text, re.IGNORECASE)
# warnings = [line for line in warnings if "has no liberty cell." not in line]
# if len(warnings) > 0:
# warningFile.writelines(warnings)
# warningCount += len(warnings)
for i in range(len(lines)):
lowerCaseLine = lines[i].lower()
if " error " in lowerCaseLine or "[error]" in lowerCaseLine:
errorFile.write(f"{fileName}[{i}]: {lines[i].strip()}\n")
errorCount += 1
elif "violated" in lowerCaseLine:
errorFile.write(f"{fileName}[{i}]: {lines[i].strip()}\n")
violationCount += 1
elif "warning" in lowerCaseLine and "has no liberty cell." not in lines[i]:
warningFile.write(f"{fileName}[{i}]: {lines[i].strip()}\n")
warningCount += 1
return errorCount, warningCount, violationCount
if __name__ == "__main__":
CollateErrors("openlane/", "docs/Logs/")