blob: 487d608dfb3045cc0e559ccf752bc3e5b29b3139 [file] [log] [blame] [edit]
#!/usr/bin/env python3
# Copyright 2020 The Skywater PDK Authors
#
# 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
#
# https://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 json
import os
import re
import sys
from collections import defaultdict
from common import lib_extract_from_name, lib_extract_from_path
from pathlib import Path
debug = True
debug_print = lambda x: print(x) if debug else 0
sourcetodests = defaultdict(list)
Copyright_header = ('# Copyright 2020 The Skywater PDK Authors\n'
'#\n'
'# Licensed under the Apache License, Version 2.0 (the "License");\n'
'# you may not use this file except in compliance with the License.\n'
'# You may obtain a copy of the License at\n'
'#\n'
'# https://www.apache.org/licenses/LICENSE-2.0\n'
'#\n'
'# Unless required by applicable law or agreed to in writing, software\n'
'# distributed under the License is distributed on an "AS IS" BASIS,\n'
'# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n'
'# See the License for the specific language governing permissions and\n'
'# limitations under the License.\n'
'\n')
def create_file(module, header , main_cell_dir, lib_name):
"""
>>> create_file('MACRO sky130_fd_io__smth END sky130_fd_io__smth', '', 'output/skywater-pdk/libraries/sky130_fd_io/V0.1.0/cells', 'sky130_fd_io')
'output/skywater-pdk/libraries/sky130_fd_io/V0.1.0/cells/smth/sky130_fd_io__smth.lef'
"""
global debug
re_modname = re.compile(rf'{lib_name}\w*')
full_name = re_modname.search(module)[0]
module = module.replace(Copyright_header, '')
header = header.replace(Copyright_header, '')
module = Copyright_header + header + module + '[\n]END LIBRARY'
mod_name = full_name.replace(lib_name + '__', '')
# remove strenght spec from mod
mod_name = re.sub(r'_[0-9][0-9]?$', '', mod_name)
path = main_cell_dir + '/' + mod_name
# write file
file_path = path + '/' + full_name + '.lef'
if debug:
pass
else:
if not os.path.isdir(path):
os.makedirs(path)
with open(file_path, 'w') as f_out:
f_out.write(module)
return file_path
def main(input_file):
global sourcetodests
with open(input_file, 'r') as in_f:
contents = in_f.read()
main_cell_dir = "/".join(input_file.split("/")[:-1])+ "/cells"
lib = lib_extract_from_path(input_file)
header_end_index = contents.find('MACRO')
header = contents[:header_end_index]
cell_search = re.findall(rf'(?s)MACRO {lib}\w*?[\n].*?END {lib}\w*', contents)
if cell_search is not None:
for cell in cell_search:
out_f = create_file(cell, header, main_cell_dir, lib)
print('\t' + out_f)
sourcetodests[f].append(out_f)
else:
sys.exit(f"Cannot find a single module deifinition in file {input_file}.")
#remove source file
os.remove(input_file)
if __name__ == "__main__":
import doctest
fails, _ = doctest.testmod()
if fails != 0:
exit()
else:
print("Tests Passed")
parser = argparse.ArgumentParser()
parser.add_argument(
"input",
help="The path to the source directory",
type=Path)
parser.add_argument(
"sourcetodests",
help="Output file mapping input to output",
type=Path)
debug = False
args = parser.parse_args()
files = sorted(args.input.rglob('sky130_fd_sc_*.lef'))
for f in files:
f = str(f)
print(f)
main(f)
with open(args.sourcetodests, 'w') as srctodest:
json.dump(sourcetodests, srctodest, indent=2)