-
Notifications
You must be signed in to change notification settings - Fork 23
/
lef_parser.py
134 lines (117 loc) · 4.09 KB
/
lef_parser.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
"""
Lef Parser
Author: Tri Cao
Email: [email protected]
Date: August 2016
"""
from lef_util import *
from util import *
SCALE = 2000
class LefParser:
"""
LefParser object will parse the LEF file and store information about the
cell library.
"""
def __init__(self, lef_file):
self.lef_path = lef_file
# dictionaries to map the definitions
self.macro_dict = {}
self.layer_dict = {}
self.via_dict = {}
# can make the stack to be an object if needed
self.stack = []
# store the statements info in a list
self.statements = []
self.cell_height = -1
def get_cell_height(self):
"""
Get the general cell height in the library
:return: void
"""
for macro in self.macro_dict:
self.cell_height = self.macro_dict[macro].info["SIZE"][1]
break
def parse(self):
# Now try using my data structure to parse
# open the file and start reading
print ("Start parsing LEF file...")
f = open(self.lef_path, "r")
# the program will run until the end of file f
for line in f:
info = str_to_list(line)
if len(info) != 0:
# if info is a blank line, then move to next line
# check if the program is processing a statement
#print (info)
if len(self.stack) != 0:
curState = self.stack[len(self.stack) - 1]
nextState = curState.parse_next(info)
else:
curState = Statement()
nextState = curState.parse_next(info)
# check the status return from parse_next function
if nextState == 0:
# continue as normal
pass
elif nextState == 1:
# remove the done statement from stack, and add it to the statements
# list
if len(self.stack) != 0:
# add the done statement to a dictionary
done_obj = self.stack.pop()
if isinstance(done_obj, Macro):
self.macro_dict[done_obj.name] = done_obj
elif isinstance(done_obj, Layer):
self.layer_dict[done_obj.name] = done_obj
elif isinstance(done_obj, Via):
self.via_dict[done_obj.name] = done_obj
self.statements.append(done_obj)
elif nextState == -1:
pass
else:
self.stack.append(nextState)
# print (nextState)
f.close()
# get the cell height of the library
self.get_cell_height()
print ("Parsing LEF file done.")
def draw_cells():
"""
code to draw cells based on LEF information.
:return: void
"""
to_draw = []
to_draw.append(input("Enter the first macro: "))
to_draw.append(input("Enter the second macro: "))
#to_draw = ["AND2X1", "AND2X2"]
plt.figure(figsize=(12, 9), dpi=80)
plt.axes()
num_plot = 1
for macro_name in to_draw:
# check user's input
if macro_name not in lef_parser.macro_dict:
print ("Error: This macro does not exist in the parsed library.")
quit()
macro = lef_parser.macro_dict[macro_name]
sub = plt.subplot(1, 2, num_plot)
# need to add title
sub.set_title(macro.name)
draw_macro(macro)
num_plot += 1
# scale the axis of the subplot
plt.axis('scaled')
# start drawing
print ("Start drawing...")
plt.show()
# Main Class
if __name__ == '__main__':
path = "./libraries/Nangate/NangateOpenCellLibrary.lef"
lef_parser = LefParser(path)
lef_parser.parse()
# test via_dict
via1_2 = lef_parser.via_dict["via1_2"]
print (via1_2.layers)
for each in via1_2.layers:
print (each.name)
for each_shape in each.shapes:
print (each_shape.type)