/
run_lvs.py
132 lines (100 loc) · 6.42 KB
/
run_lvs.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# Copyright 2022 GlobalFoundries 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
#
# 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.
"""Run GlobalFoundries 180nm MCU LVS.
Usage:
run_lvs.py (--help| -h)
run_lvs.py (--design=<layout_path>) (--net=<netlist_path>) (--gf180mcu=<combined_options>) [--thr=<thr>] [--run_mode=<run_mode>] [--lvs_sub=<sub_name>] [--no_net_names] [--set_spice_comments] [--set_scale] [--set_verbose] [--set_schematic_simplify] [--set_net_only] [--set_top_lvl_pins] [--set_combine] [--set_purge] [--set_purge_nets]
Options:
--help -h Print this help message.
--design=<layout_path> The input GDS file path.
--net=<netlist_path> The input netlist file path.
--gf180mcu=<combined_options> Select combined options of metal_top, mim_option, and metal_level. Allowed values (A, B, C).
gf180mcu=A: Select metal_top=30K mim_option=A metal_level=3LM poly_res=1K, and mim_cap=2
gf180mcu=B: Select metal_top=11K mim_option=B metal_level=4LM poly_res=1K, and mim_cap=2
gf180mcu=C: Select metal_top=9K mim_option=B metal_level=5LM poly_res=1K, and mim_cap=2
--thr=<thr> Number of cores to be used by LVS checker
--run_mode=<run_mode> Select klayout mode Allowed modes (flat , deep, tiling). [default: deep]
--lvs_sub=<sub_name> Assign the substrate name used in design.
--no_net_names Discard net names in extracted netlist.
--set_spice_comments Set netlist comments in extracted netlist.
--set_scale Set scale of 1e6 in extracted netlist.
--set_verbose Set verbose mode.
--set_schematic_simplify Set schematic simplification in input netlist.
--set_net_only Set netlist object creation only in extracted netlist.
--set_top_lvl_pins Set top level pins only in extracted netlist.
--set_combine Set netlist combine only in extracted netlist.
--set_purge Set netlist purge all only in extracted netlist.
--set_purge_nets Set netlist purge nets only in extracted netlist.
"""
from docopt import docopt
import os
import logging
def main():
# Switches used in run
switches = ''
if args["--run_mode"] in ["flat" , "deep", "tiling"]:
switches = switches + f'-rd run_mode={args["--run_mode"]} '
else:
logging.error("Allowed klayout modes are (flat , deep , tiling) only")
exit()
if args["--gf180mcu"] == "A":
switches = switches + f'-rd metal_top=30K -rd mim_option=A -rd metal_level=3LM -rd poly_res=1K -rd mim_cap=2 '
elif args["--gf180mcu"] == "B":
switches = switches + f'-rd metal_top=11K -rd mim_option=B -rd metal_level=4LM -rd poly_res=1K -rd mim_cap=2 '
elif args["--gf180mcu"] == "C":
switches = switches + f'-rd metal_top=9K -rd mim_option=B -rd metal_level=5LM -rd poly_res=1K -rd mim_cap=2 '
else:
print("gf180mcu switch allowed values are (A , B, C) only")
exit()
switches = switches + '-rd spice_net_names=false ' if args["--no_net_names"] else switches + '-rd spice_net_names=true '
switches = switches + '-rd spice_comments=true ' if args["--set_spice_comments"] else switches + '-rd spice_comments=false '
switches = switches + '-rd scale=true ' if args["--set_scale"] else switches + '-rd scale=false '
switches = switches + '-rd verbose=true ' if args["--set_verbose"] else switches + '-rd verbose=false '
switches = switches + '-rd schematic_simplify=true ' if args["--set_schematic_simplify"] else switches + '-rd schematic_simplify=false '
switches = switches + '-rd net_only=true ' if args["--set_net_only"] else switches + '-rd net_only=false '
switches = switches + '-rd top_lvl_pins=true ' if args["--set_top_lvl_pins"] else switches + '-rd top_lvl_pins=false '
switches = switches + '-rd combine=true ' if args["--set_combine"] else switches + '-rd combine=false '
switches = switches + '-rd purge=true ' if args["--set_purge"] else switches + '-rd purge=false '
switches = switches + '-rd purge_nets=true ' if args["--set_purge_nets"] else switches + '-rd purge_nets=false '
switches = switches + f'-rd lvs_sub={args["--lvs_sub"]} ' if args["--lvs_sub"] else switches
# Generate databases
if args["--design"]:
path = args["--design"]
if args["--design"]:
file_name = args["--net"].split('.')
else:
print("The script must be given a netlist file or a path to be able to run LVS")
exit()
os.system(f"klayout -b -r gf180mcu.lvs -rd input={path} -rd report={file_name[0]}.lyrdb -rd schematic={args['--net']} -rd target_netlist=extracted_netlist_{file_name[0]}.cir -rd thr={workers_count} {switches}")
else:
print("The script must be given a layout file or a path to be able to run LVS")
exit()
if __name__ == "__main__":
logging.basicConfig(level=logging.DEBUG, format=f"%(asctime)s | %(levelname)-7s | %(message)s", datefmt='%d-%b-%Y %H:%M:%S')
# Args
args = docopt(__doc__, version='LVS Checker: 0.1')
workers_count = os.cpu_count()*2 if args["--thr"] == None else int(args["--thr"])
# Env. variables
pdk_root = os.environ['PDK_ROOT']
pdk = os.environ['PDK']
# ========= Checking Klayout version =========
klayout_v_ = os.popen("klayout -v").read()
klayout_v_ = klayout_v_.split("\n")[0]
klayout_v = int (klayout_v_.split(".") [-1])
if klayout_v < 8:
logging.warning("Using this klayout version has not been assesed in this development. Limits are unknown")
logging.info(f"Your version is: {klayout_v_}" )
logging.info(f"Prerequisites at a minimum: KLayout 0.27.8")
# Calling main function
main()