forked from ICBench/OpenSTA
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNetworkEdit.tcl
241 lines (223 loc) · 6.2 KB
/
NetworkEdit.tcl
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# OpenSTA, Static Timing Analyzer
# Copyright (c) 2018, Parallax Software, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# Network editing commands.
namespace eval sta {
proc connect_pins { net pins } {
# Visit the pins to make sure command will succeed.
set insts_ports [parse_connect_pins $pins]
if { $insts_ports == 0 } {
return 0
}
set net [get_net_warn "net" $net]
if { $net == "NULL" } {
return 0
}
foreach {inst port} $insts_ports {
connect_pin_cmd $inst $port $net
}
return 1
}
proc parse_connect_pins { arg } {
set path_regexp [path_regexp]
set insts_ports {}
# Copy backslashes that will be removed by foreach.
set arg [string map {\\ \\\\} $arg]
foreach obj $arg {
if { [is_object $obj] } {
set object_type [object_type $obj]
if { $object_type == "Pin" } {
set pin $obj
set inst [$pin instance]
set port [$pin port]
} elseif { $object_type == "Port" } {
# Explicit port arg - convert to pin.
set pin [find_pin [$obj name]]
set inst [$pin instance]
set port [$pin port]
} else {
sta_error "unsupported object type $object_type."
}
} else {
if {[regexp $path_regexp $obj ignore path_name port_name]} {
set inst [find_instance $path_name]
if { $inst == "NULL" } {
return 0
}
} else {
set inst [top_instance]
set port_name $obj
}
set cell [$inst cell]
set port [$cell find_port $port_name]
if { $port == "NULL" } {
return 0
}
set pin [$inst find_pin $port_name]
}
# Make sure the pin is not currently connected to a net.
if { $pin != "NULL" \
&& ![$pin is_hierarchical] \
&& [$pin net] != "NULL" } {
return 0
}
lappend insts_ports $inst $port
}
return $insts_ports
}
################################################################
proc delete_instance { instances } {
# Copy backslashes that will be removed by foreach.
set instances1 [string map {\\ \\\\} $instances]
foreach obj $instances1 {
if { [is_object $obj] } {
set object_type [object_type $obj]
if { $object_type == "Instance" } {
set inst $obj
} else {
sta_error "unsupported object type $object_type."
}
} else {
set inst [find_instance $obj]
}
if { $inst != "NULL" } {
delete_instance_cmd $inst
}
}
}
################################################################
proc delete_net { net_list } {
# Copy backslashes that will be removed by foreach.
set net_list [string map {\\ \\\\} $net_list]
foreach obj $net_list {
if { [is_object $obj] } {
set object_type [object_type $obj]
if { $object_type == "Net" } {
set net $obj
} else {
sta_error "unsupported object type $object_type."
}
} else {
set net [find_net $obj]
}
if { $net != "NULL" } {
delete_net_cmd $net
}
}
}
################################################################
proc disconnect_pins { net pins } {
set net [get_net_warn "net" $net]
if { $net == "NULL" } {
return 0
}
if { $pins == "-all" } {
set iter [$net connected_pin_iterator]
while {[$iter has_next]} {
set pin [$iter next]
disconnect_pin_cmd $pin
}
$iter finish
return 1
} else {
# Copy backslashes that will be removed by foreach.
set pins [string map {\\ \\\\} $pins]
# Visit the pins to make sure command will succeed.
foreach pin $pins {
set pin1 [get_port_pin_warn "pin" $pin]
if { $pin1 == "NULL" } {
return 0
}
}
foreach pin $pins {
set pin1 [get_port_pin_warn "pin" $pin]
disconnect_pin_cmd $pin1
}
return 1
}
}
################################################################
proc make_instance { inst_names lib_cell } {
set lib_cell [get_lib_cell_warn "lib_cell" $lib_cell]
if { $lib_cell != "NULL" } {
set path_regexp [path_regexp]
foreach inst_path $inst_names {
if {[regexp $path_regexp $inst_path ignore path_name inst_name]} {
set parent [find_instance $path_name]
if { $parent == "NULL" } {
# Parent instance not found. This could be a typo, but since
# SDC does not escape hierarchy dividers it can also be
# an escaped name.
set inst_name $inst_path
set parent [top_instance]
}
} else {
set inst_name $inst_path
set parent [top_instance]
}
make_instance_cmd $inst_name $lib_cell $parent
}
return 1
} else {
return 0
}
}
################################################################
proc make_net { net_list } {
# Visit the net names to make sure command will succeed.
set path_regexp [path_regexp]
foreach net $net_list {
if {[regexp $path_regexp $net ignore path_name net_name]} {
set parent [find_instance $path_name]
if { $parent == "NULL" } {
return 0
}
}
}
# Copy backslashes that will be removed by foreach.
set net_list [string map {\\ \\\\} $net_list]
foreach net $net_list {
if {[regexp $path_regexp $net ignore path_name net_name]} {
set parent [find_instance $path_name]
} else {
set net_name $net
set parent [top_instance]
}
make_net_cmd $net_name $parent
}
return 1
}
################################################################
proc replace_cell { instances lib_cell } {
set cell [get_lib_cell_warn "lib_cell" $lib_cell]
if { $cell != "NULL" } {
set insts [get_instances_error "instances" $instances]
foreach inst $insts {
set inst_cell [$inst liberty_cell]
if { $inst_cell != "NULL" \
&& ![cells_equiv_ports $inst_cell $cell] } {
return 0
}
}
foreach inst $insts {
replace_cell_cmd $inst $cell
}
return 1
} else {
return 0
}
}
# sta namespace end.
}