forked from The-OpenROAD-Project-Attic/Resizer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Resizer.tcl
276 lines (239 loc) · 8.58 KB
/
Resizer.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
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
# Resizer, LEF/DEF gate resizer
# Copyright (c) 2019, 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/>.
namespace eval sta {
proc show_resizer_splash {} {
puts "Resizer [sta::resizer_version] [string range [sta::resizer_git_sha1] 0 9] Copyright (c) 2019, Parallax Software, Inc.
License GPLv3: GNU GPL version 3 <http://gnu.org/licenses/gpl.html>
This is free software, and you are free to change and redistribute it
under certain conditions; type `show_copying' for details.
This program comes with ABSOLUTELY NO WARRANTY; for details type `show_warranty'."
}
# Defined by SWIG interface Resizer.i.
define_cmd_args "set_dont_use" {cell dont_use}
# Defined by SWIG interface Resizer.i
define_cmd_args "read_lef" {filename}
define_cmd_args "read_def" {filename}
define_cmd_args "set_design_size" {[-die {lx ly ux uy}]\
[-core {lx ly ux uy}]}
proc set_design_size { args } {
parse_key_args "set_design_size" args keys {-die -core} flags {}
set die_lx 0
set die_ly 0
set die_ux 0
set die_uy 0
if [info exists keys(-die)] {
set die $keys(-die)
if { [llength $die] != 4 } {
sta_error "-die_area is a list of 4 coordinates."
}
lassign $die die_lx die_ly die_ux die_uy
check_positive_float "-die" $die_lx
check_positive_float "-die" $die_ly
check_positive_float "-die" $die_ux
check_positive_float "-die" $die_uy
set_die_size_cmd \
[distance_ui_sta $die_lx] [distance_ui_sta $die_ly] \
[distance_ui_sta $die_ux] [distance_ui_sta $die_uy]
}
if [info exists keys(-core)] {
set core $keys(-core)
if { [llength $core] != 4 } {
sta_error "-core_area is a list of 4 coordinates."
}
lassign $core core_lx core_ly core_ux core_uy
check_positive_float "-core" $core_lx
check_positive_float "-core" $core_ly
check_positive_float "-core" $core_ux
check_positive_float "-core" $core_uy
set_core_size_cmd \
[distance_ui_sta $core_lx] [distance_ui_sta $core_ly] \
[distance_ui_sta $core_ux] [distance_ui_sta $core_uy]
}
}
define_cmd_args "write_def" {-units def_units\
[-die_area {lx ly ux uy}]\
[-core_area {lx ly ux uy}]\
[-site site_name]\
[-tracks tracks_file]\
[-auto_place_pins]\
[-sort]\
filename}
proc write_def { args } {
parse_key_args "write_def" args \
keys {-units -die_area -core_area -site -tracks} \
flags {-auto_place_pins -sort}
set units 1000
if [info exists keys(-units)] {
set units $keys(-units)
check_positive_integer "-units" $units
}
if [info exists keys(-die_area)] {
sta_warn "Warning: write_def -die_area deprecated. Use the set_design_size command."
set die_area $keys(-die_area)
if { [llength $die_area] != 4 } {
sta_error "-die_area is a list of 4 coordinates."
}
lassign $die_area die_lx die_ly die_ux die_uy
check_positive_float "-die_area" $die_lx
check_positive_float "-die_area" $die_ly
check_positive_float "-die_area" $die_ux
check_positive_float "-die_area" $die_uy
set_design_die_size_cmd \
[distance_ui_sta $die_lx] [distance_ui_sta $die_ly] \
[distance_ui_sta $die_ux] [distance_ui_sta $die_uy]
}
if [info exists keys(-core_area)] {
sta_warn "Warning: write_def -core_area deprecated. Use the set_design_size command."
set core_area $keys(-core_area)
if { [llength $core_area] != 4 } {
sta_error "-core_area is a list of 4 coordinates."
}
lassign $core_area core_lx core_ly core_ux core_uy
check_positive_float "-core_area" $core_lx
check_positive_float "-core_area" $core_ly
check_positive_float "-core_area" $core_ux
check_positive_float "-core_area" $core_uy
set_design_core_size_cmd \
[distance_ui_sta $core_lx] [distance_ui_sta $core_ly] \
[distance_ui_sta $core_ux] [distance_ui_sta $core_uy]
}
set site_name ""
if [info exists keys(-site)] {
set site_name $keys(-site)
}
set tracks_file ""
if { [info exists keys(-tracks)] } {
set tracks_file $keys(-tracks)
}
set auto_place_pins [info exists flags(-auto_place_pins)]
set sort [info exists flags(-sort)]
check_argc_eq1 "write_def" $args
set filename $args
# convert die coordinates to meters.
write_def_cmd $filename $units \
$site_name $tracks_file $auto_place_pins $sort
}
define_cmd_args "set_wire_rc" {[-resistance res ][-capacitance cap]\
[-corner corner_name]}
proc set_wire_rc { args } {
parse_key_args "set_wire_rc" args \
keys {-resistance -capacitance -corner} flags {}
set wire_res 0.0
if [info exists keys(-resistance)] {
set res $keys(-resistance)
check_positive_float "-resistance" $res
}
set wire_cap 0.0
if [info exists keys(-capacitance)] {
set cap $keys(-capacitance)
check_positive_float "-capacitance" $cap
}
set corner [parse_corner keys]
check_argc_eq0 "set_wire_rc" $args
set r [expr [resistance_ui_sta $res] / [distance_ui_sta 1.0]]
set c [expr [capacitance_ui_sta $cap] / [distance_ui_sta 1.0]]
set_wire_rc_cmd $r $c $corner
}
define_cmd_args "resize" {[-buffer_inputs]\
[-buffer_outputs]\
[-resize]\
[-repair_max_cap]\
[-repair_max_slew]\
[-resize_libraries resize_libs]\
[-buffer_cell buffer_cell]\
[-dont_use lib_cells]}
proc resize { args } {
parse_key_args "resize" args \
keys {-buffer_cell -resize_libraries -dont_use -max_utilization} \
flags {-buffer_inputs -buffer_outputs -resize -repair_max_cap -repair_max_slew}
set buffer_inputs [info exists flags(-buffer_inputs)]
set buffer_outputs [info exists flags(-buffer_outputs)]
set resize [info exists flags(-resize)]
set repair_max_cap [info exists flags(-repair_max_cap)]
set repair_max_slew [info exists flags(-repair_max_slew)]
# With no options you get the whole salmai.
if { !($buffer_inputs || $buffer_outputs || $resize \
|| $repair_max_cap || $repair_max_slew) } {
set buffer_inputs 1
set buffer_outputs 1
set resize 1
set repair_max_cap 1
set repair_max_slew 1
}
set buffer_cell "NULL"
if { [info exists keys(-buffer_cell)] } {
set buffer_cell_name $keys(-buffer_cell)
# check for -buffer_cell [get_lib_cell arg] return ""
if { $buffer_cell_name != "" } {
set buffer_cell [get_lib_cell_error "-buffer_cell" $buffer_cell_name]
if { $buffer_cell != "NULL" } {
if { ![get_property $buffer_cell is_buffer] } {
sta_error "Error: [get_name $buffer_cell] is not a buffer."
}
}
}
}
if { $buffer_cell == "NULL" && ($buffer_inputs || $buffer_outputs \
|| $repair_max_cap || $repair_max_slew) } {
sta_error "Error: resize -buffer_cell required for buffer insertion."
}
if { [info exists keys(-resize_libraries)] } {
set resize_libs [get_liberty_error "-resize_libraries" $keys(-resize_libraries)]
} else {
set resize_libs [get_libs *]
}
set dont_use {}
if { [info exists keys(-dont_use)] } {
set dont_use [get_lib_cells -quiet $keys(-dont_use)]
}
set max_util 0.0
if { [info exists keys(-max_utilization)] } {
set max_util $keys(-max_utilization)
if {!([string is double $max_util] && $max_util >= 0.0 && $max_util <= 100)} {
sta_error "-max_utilization must be between 0 and 100%."
}
set max_util [expr $max_util / 100.0]
}
check_argc_eq0 "resize" $args
resizer_preamble $resize_libs
set_dont_use $dont_use
set_max_utilization $max_util
if { $buffer_inputs } {
buffer_inputs $buffer_cell
}
if { $buffer_outputs } {
buffer_outputs $buffer_cell
}
if { $resize } {
resize_to_target_slew
}
if { $repair_max_cap || $repair_max_slew } {
rebuffer_nets $repair_max_cap $repair_max_slew $buffer_cell
}
}
define_cmd_args "get_pin_net" {pin_name}
proc get_pin_net { pin_name } {
set pin [get_pin_error "pin_name" $pin_name]
return [$pin net]
}
define_cmd_args "report_design_area" {}
proc report_design_area {} {
set util [format %.0f [expr [utilization] * 100]]
set area [format_area [design_area] 0]
puts "Design area ${area} u^2 ${util}% utilization."
}
# sta namespace end
}