blob: 8785502fcccaeec753603034ac49767a57c469eb [file] [log] [blame]
#!/usr/bin/env python3
# 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 re
import xml.etree.ElementTree as ET
import xml.dom.minidom as minidom
parser = argparse.ArgumentParser(
description='Converts a TritonRoute DRC Report to a KLayout database')
parser.add_argument('--input', '-i', required=True,
help='')
parser.add_argument('--design-name', '-name', required=True,
help='')
parser.add_argument('--output', '-o', required=True,
help='')
args = parser.parse_args()
input_file_name = args.input
design_name = args.design_name
output_file_name = args.output
RE_VIOLATION = re.compile(r'violation type: (?P<type>\S+)\s+'
r'srcs: (?P<src1>\S+)( (?P<src2>\S+))?\s+'
r'bbox = \( (?P<llx>\S+), (?P<lly>\S+) \)'
r' - '
r'\( (?P<urx>\S+), (?P<ury>\S+) \) '
r'on Layer (?P<layer>\S+)', re.M)
def prettify(elem):
"""
Return a pretty-printed XML string for the Element.
"""
rough_string = ET.tostring(elem, 'utf-8')
reparsed = minidom.parseString(rough_string)
return reparsed.toprettyxml(indent=" ",
newl="\n")
# encoding='utf-8')
with open(input_file_name, 'r') as f:
content = f.read()
cnt = 0
vio_dict = {}
for match in RE_VIOLATION.finditer(content):
cnt += 1
type_ = match.group('type')
src1 = match.group('src1')
src2 = match.group('src2')
llx = match.group('llx')
lly = match.group('lly')
urx = match.group('urx')
ury = match.group('ury')
layer = match.group('layer')
item = ET.Element('item')
ET.SubElement(item, 'category').text = type_
ET.SubElement(item, 'cell').text = design_name
ET.SubElement(item, 'visited').text = 'false'
ET.SubElement(item, 'multiplicity').text = '1'
values = ET.SubElement(item, 'values')
box = ET.SubElement(values, 'value')
box.text = f"box: ({llx},{lly};{urx},{ury})"
layer_msg = ET.SubElement(values, 'value')
layer_msg.text = f"text: 'On layer {layer}'"
srcs = ET.SubElement(values, 'value')
if src2:
srcs.text = f"text: 'Between {src1} {src2}'"
else:
srcs.text = f"text: 'Between {src1}'"
# create XML object
if type_ not in vio_dict:
vio_dict[type_] = []
vio_dict[type_].append(item)
print("Found", cnt, "violations")
report_database = ET.Element('report-database')
categories = ET.SubElement(report_database, 'categories')
for type_ in vio_dict.keys():
category = ET.SubElement(categories, 'category')
ET.SubElement(category, 'name').text = type_
cells = ET.SubElement(report_database, 'cells')
cell = ET.SubElement(cells, 'cell')
ET.SubElement(cell, 'name').text = design_name
items = ET.Element('items')
for _, vios in vio_dict.items():
for item in vios:
items.append(item)
report_database.append(items)
report_database_str = prettify(report_database)
with open(output_file_name, 'w') as f:
f.write(report_database_str)