blob: 4e619c5f4462a208ae3660fb6b8b517e75250e0c [file] [log] [blame]
#!/usr/bin/env python3
# From: https://github.com/The-OpenROAD-Project/OpenROAD-flow/blob/master/flow/util/mergeLef.py
# Copyright 2020 The OpenROAD Project
#
# 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 re
import os
import argparse # argument parsing
# WARNING: this script expects the tech lef first
# Parse and validate arguments
# ==============================================================================
parser = argparse.ArgumentParser(description="Merges lefs together")
parser.add_argument("--inputLef", "-i", required=True, help="Input Lef", nargs="+")
parser.add_argument("--outputLef", "-o", required=True, help="Output Lef")
args = parser.parse_args()
def get_delimited_blocks(data):
# MACRO and SITE blocks
# assumes correctly indented LEF; otherwise, assertions should fail
blocks = []
current_block_name = None
block_content = []
for line in data.splitlines():
if line.startswith("MACRO") or line.startswith("SITE"):
assert current_block_name is None, (current_block_name, line)
assert not block_content, block_content
tokens = line.split()
assert len(tokens) == 2, line
current_block_name = tokens[1]
block_content.append(line)
elif current_block_name is not None:
block_content.append(line)
if line.startswith("END"):
assert line != "END LIBRARY", current_block_name
tokens = line.split()
assert len(tokens) == 2, line
assert tokens[1] == current_block_name, (line, current_block_name)
blocks.append("\n".join(block_content))
current_block_name = None
block_content = []
assert not current_block_name, current_block_name
assert not block_content, block_content
return blocks
print(os.path.basename(__file__), ": Merging LEFs")
f = open(args.inputLef[0])
content = f.read()
f.close()
# Remove Last line ending the library
content = re.sub("END LIBRARY", "", content)
content = content.splitlines()
lefs = args.inputLef[1:]
if len(lefs) == 1:
lefs = lefs[0].split()
# Iterate through additional lefs
for lefFile in lefs:
f = open(lefFile)
snippet = f.read()
f.close()
snippet = snippet.replace("END LIBRARY", "")
blocks = get_delimited_blocks(snippet)
site_cnt = 0
macro_cnt = 0
for block in blocks:
if block.startswith("MACRO"):
macro_cnt += 1
else:
assert block.startswith("SITE"), block
site_cnt += 1
print(os.path.basename(lefFile) + ": SITEs matched found:", site_cnt)
print(os.path.basename(lefFile) + ": MACROs matched found:", macro_cnt)
content.extend(blocks)
content.append("END LIBRARY")
f = open(args.outputLef, "w")
f.write("\n".join(content))
f.close()
print(os.path.basename(__file__), ": Merging LEFs complete")