blob: d868da7abfbd2b3f505c9297df7fdb629b761e1f [file] [log] [blame]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001###
2### Source file sky130.tcl
3### Process this file with the preprocessor script
4###
5#-----------------------------------------------------
6# Magic/TCL design kit for SKYWATER TECHNAME
7#-----------------------------------------------------
8# Tim Edwards
Tim Edwardsd7289eb2020-09-10 21:48:31 -04009# Revision 1 ALPHA 9/10/2020
Tim Edwards55f4d0e2020-07-05 15:41:02 -040010#-----------------------------------------------------
11
12set TECHPATH STAGING_PATH
13if [catch {set PDKPATH}] {set PDKPATH ${TECHPATH}/TECHNAME}
14set PDKNAME TECHNAME
15# "sky130" is the namespace used for all devices
16set PDKNAMESPACE sky130
17puts stdout "Loading TECHNAME Device Generator Menu ..."
18
19# Initialize toolkit menus to the wrapper window
20
21global Opts
22namespace eval sky130 {}
23
24# Set the window callback
25if [catch {set Opts(callback)}] {set Opts(callback) ""}
26set Opts(callback) [subst {sky130::addtechmenu \$framename; $Opts(callback)}]
27
28# if {![info exists Opts(cmdentry)]} {set Opts(cmdentry) 1}
29
30# Set options specific to this PDK
31set Opts(hidelocked) 1
32set Opts(hidespecial) 1
33
34# Create new "tool" proc that doesn't have the netlist tool.
35proc magic::nexttool {} {
36 global Opts
37
38 # Don't attempt to switch tools while a selection drag is active
39 if {$Opts(motion) == {}} {
40 switch $Opts(tool) {
41 box { magic::tool wiring }
42 wiring { magic::tool pick }
43 default { magic::tool box }
44 }
45 }
46}
47
48# This shoule be part of sitedef. . .
49macro space magic::nexttool
50
51# Wrap the closewrapper procedure so that closing the last
52# window is equivalent to quitting.
53if {[info commands closewrapper] == "closewrapper"} {
54 rename closewrapper closewrapperonly
55 proc closewrapper { framename } {
56 if {[llength [windownames all]] <= 1} {
57 magic::quit
58 } else {
59 closewrapperonly $framename
60 }
61 }
62}
63
64# Remove maze router layers from the toolbar by locking them
65tech lock fence,magnet,rotate
66
67namespace eval sky130 {
68 namespace path {::tcl::mathop ::tcl::mathfunc}
69
70 set ruleset [dict create]
71
72 # Process DRC rules (magic style)
73
74 dict set ruleset poly_surround 0.08 ;# Poly surrounds contact
75 dict set ruleset diff_surround 0.06 ;# Diffusion surrounds contact
76 dict set ruleset gate_to_diffcont 0.145 ;# Gate to diffusion contact center
77 dict set ruleset gate_to_polycont 0.275 ;# Gate to poly contact center
78 dict set ruleset gate_extension 0.13 ;# Poly extension beyond gate
79 dict set ruleset diff_extension 0.29 ;# Diffusion extension beyond gate
80 dict set ruleset contact_size 0.17 ;# Minimum contact size
81 dict set ruleset via_size 0.17 ;# Minimum via size
82 dict set ruleset metal_surround 0.08 ;# Local interconnect overlaps contact
83 dict set ruleset sub_surround 0.18 ;# Sub/well surrounds diffusion
84 dict set ruleset diff_spacing 0.28 ;# Diffusion spacing rule
85 dict set ruleset poly_spacing 0.21 ;# Poly spacing rule
86 dict set ruleset diff_poly_space 0.075 ;# Diffusion to poly spacing rule
87 dict set ruleset diff_gate_space 0.20 ;# Diffusion to gate poly spacing rule
88 dict set ruleset metal_spacing 0.23 ;# Local interconnect spacing rule
89 dict set ruleset mmetal_spacing 0.14 ;# Metal spacing rule (above local interconnect)
90 dict set ruleset res_to_cont 0.20 ;# resistor to contact center
91 dict set ruleset res_diff_space 0.20 ;# resistor to guard ring
92}
93
94#-----------------------------------------------------
95# magic::addtechmenu
96#-----------------------------------------------------
97
98proc sky130::addtechmenu {framename} {
99 global Winopts Opts
100
101 # Check for difference between magic 8.1.125 and earlier, and 8.1.126 and later
102 if {[catch {${framename}.titlebar cget -height}]} {
103 set layoutframe ${framename}.pane.top
104 } else {
105 set layoutframe ${framename}
106 }
107
108 # List of devices is long. Divide into two sections for active and passive deivces
109 magic::add_toolkit_menu $layoutframe "Devices 1" pdk1
110
111 magic::add_toolkit_command $layoutframe "nmos (MOSFET)" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400112 "magic::gencell sky130::sky130_fd_pr__nfet_01v8" pdk1
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400113 magic::add_toolkit_command $layoutframe "pmos (MOSFET)" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400114 "magic::gencell sky130::sky130_fd_pr__pfet_01v8" pdk1
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400115
116 magic::add_toolkit_separator $layoutframe pdk1
117 magic::add_toolkit_command $layoutframe "n-diode" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400118 "magic::gencell sky130::sky130_fd_pr__diode_pw2nd_05v5" pdk1
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400119 magic::add_toolkit_command $layoutframe "p-diode" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400120 "magic::gencell sky130::sky130_fd_pr__diode_pd2nw_05v5" pdk1
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400121
122 magic::add_toolkit_separator $layoutframe pdk1
123 magic::add_toolkit_command $layoutframe "MOS varactor" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400124 "magic::gencell sky130::sky130_fd_pr__cap_var_lvt" pdk1
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400125 magic::add_toolkit_separator $layoutframe pdk1
126
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400127 magic::add_toolkit_command $layoutframe "NPN 1.0 x 1.0" \
128 "magic::gencell sky130::sky130_fd_pr__npn_05v5_W1p00L1p00" pdk1
129 magic::add_toolkit_command $layoutframe "NPN 1.0 x 2.0" \
130 "magic::gencell sky130::sky130_fd_pr__npn_05v5_W1p00L2p00" pdk1
131 magic::add_toolkit_command $layoutframe "PNP 0.68 x 0.68" \
132 "magic::gencell sky130::sky130_fd_pr__pnp_05v5_W0p68L0p68" pdk1
133 magic::add_toolkit_command $layoutframe "PNP 3.4 x 3.4" \
134 "magic::gencell sky130::sky130_fd_pr__pnp_05v5_W3p40L3p40" pdk1
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400135
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400136#ifdef REDISTRIBUTION
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400137 magic::add_toolkit_separator $layoutframe pdk1
138
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400139 magic::add_toolkit_command $layoutframe "inductor 01x04" \
140 "magic::gencell sky130::sky130_fd_pr__ind_01_04" pdk1
141 magic::add_toolkit_command $layoutframe "inductor 02x04" \
142 "magic::gencell sky130::sky130_fd_pr__ind_02_04" pdk1
143#endif (REDISTRIBUTION)
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400144
145 magic::add_toolkit_separator $layoutframe pdk1
146
147 magic::add_toolkit_command $layoutframe "substrate contact (1.8V)" \
148 "sky130::subconn_draw" pdk1
149 magic::add_toolkit_command $layoutframe "substrate contact (5.0V)" \
150 "sky130::mvsubconn_draw" pdk1
151 magic::add_toolkit_command $layoutframe "deep n-well region" \
152 "sky130::deep_nwell_draw" pdk1
153 magic::add_toolkit_command $layoutframe "mcon" \
154 "sky130::mcon_draw" pdk1
155 magic::add_toolkit_command $layoutframe "via1" \
156 "sky130::via1_draw" pdk1
157 magic::add_toolkit_command $layoutframe "via2" \
158 "sky130::via2_draw" pdk1
159#ifdef METAL5
160 magic::add_toolkit_command $layoutframe "via3" \
161 "sky130::via3_draw" pdk1
162 magic::add_toolkit_command $layoutframe "via4" \
163 "sky130::via4_draw" pdk1
164#endif (METAL5)
165
166
167 magic::add_toolkit_menu $layoutframe "Devices 2" pdk2
168
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400169 magic::add_toolkit_command $layoutframe "n-diff resistor (1.8V) - 120 Ohm/sq" \
170 "magic::gencell sky130::sky130_fd_pr__res_generic_nd" pdk2
171 magic::add_toolkit_command $layoutframe "p-diff resistor (1.8V) - 197 Ohm/sq" \
172 "magic::gencell sky130::sky130_fd_pr__res_generic_pd" pdk2
173 magic::add_toolkit_command $layoutframe "n-diff resistor (5.0V) - 114 Ohm/sq" \
174 "magic::gencell sky130::sky130_fd_pr__mrdn_hv" pdk2
175 magic::add_toolkit_command $layoutframe "p-diff resistor (5.0V) - 191 Ohm/sq" \
176 "magic::gencell sky130::sky130_fd_pr__mrdp_hv" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400177
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400178 magic::add_toolkit_command $layoutframe "poly resistor - 48.2 Ohm/sq" \
179 "magic::gencell sky130::sky130_fd_pr__res_generic_po" pdk2
180 magic::add_toolkit_command $layoutframe "poly resistor - 319.8 Ohm/sq" \
181 "magic::gencell sky130::sky130_fd_pr__res_high_po_0p35" pdk2
182 magic::add_toolkit_command $layoutframe "poly resistor - 2000 Ohm/sq" \
183 "magic::gencell sky130::sky130_fd_pr__res_xhigh_po_0p35" pdk2
184 magic::add_toolkit_command $layoutframe "p-well resistor - 3050 Ohm/sq" \
185 "magic::gencell sky130::sky130_fd_pr__res_iso_pw" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400186 magic::add_toolkit_separator $layoutframe pdk2
187
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400188 magic::add_toolkit_command $layoutframe "l1 metal resistor - 12.2 Ohm/sq" \
189 "magic::gencell sky130::sky130_fd_pr__res_generic_l1" pdk2
190 magic::add_toolkit_command $layoutframe "m1 metal resistor - 125 mOhm/sq" \
191 "magic::gencell sky130::sky130_fd_pr__res_generic_m1" pdk2
192 magic::add_toolkit_command $layoutframe "m2 metal resistor - 125 mOhm/sq" \
193 "magic::gencell sky130::sky130_fd_pr__res_generic_m2" pdk2
194 magic::add_toolkit_command $layoutframe "m3 metal resistor - 47 mOhm/sq" \
195 "magic::gencell sky130::sky130_fd_pr__res_generic_m3" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400196#ifdef METAL5
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400197 magic::add_toolkit_command $layoutframe "m4 metal resistor - 47 mOhm/sq" \
198 "magic::gencell sky130::sky130_fd_pr__res_generic_m4" pdk2
199 magic::add_toolkit_command $layoutframe "m5 metal resistor - 29 mOhm/sq" \
200 "magic::gencell sky130::sky130_fd_pr__res_generic_m5" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400201#endif (METAL5)
202
203#ifdef MIM
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400204 magic::add_toolkit_command $layoutframe "MiM cap - 1fF/um^2 (metal3)" \
205 "magic::gencell sky130::sky130_fd_pr__cap_mim_m3_1" pdk2
206 magic::add_toolkit_command $layoutframe "MiM cap - 1fF/um^2 (metal4)" \
207 "magic::gencell sky130::sky130_fd_pr__cap_mim_m3_2" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400208#endif (MIM)
209 magic::add_toolkit_separator $layoutframe pdk2
210
211 magic::add_toolkit_command $layoutframe "vpp 11.5x11.7 li/m5 shield" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400212 "magic::gencell sky130::sky130_fd_pr__cap_vpp_11p5x11p7_lim5_shield" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400213 magic::add_toolkit_command $layoutframe "vpp 11.5x11.7 li/m3/m5 shield" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400214 "magic::gencell sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m3_lim5_shield" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400215 magic::add_toolkit_command $layoutframe "vpp 11.5x11.7 m4 shield" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400216 "magic::gencell sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m4_shield" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400217 magic::add_toolkit_command $layoutframe "vpp 11.5x11.7 p/m4 shield" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400218 "magic::gencell sky130::sky130_fd_pr__cap_vpp_11p5x11p7_pom4_shield" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400219 # magic::add_toolkit_command $layoutframe "vpp 11.5x11.7 p/m5 shield" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400220 "magic::gencell sky130::sky130_fd_pr__cap_vpp_4p4x4p6_m3_lim5_shield" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400221 magic::add_toolkit_command $layoutframe "vpp 6.8x6.1 li/m4 shield" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400222 "magic::gencell sky130::sky130_fd_pr__cap_vpp_6p8x6p1_lim4_shield" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400223 magic::add_toolkit_command $layoutframe "vpp 6.8x6.1 p/m4 shield" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400224 "magic::gencell sky130::sky130_fd_pr__cap_vpp_6p8x6p1_pom4_shield" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400225 magic::add_toolkit_command $layoutframe "vpp 8.6x7.9 li/m3/m5 shield" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400226 "magic::gencell sky130::sky130_fd_pr__cap_vpp_8p6x7p9_m3_lim5_shield" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400227 magic::add_toolkit_command $layoutframe "vpp 11.5x11.7 li/m3 shield" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400228 "magic::gencell sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m3_li_shield" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400229 magic::add_toolkit_command $layoutframe "vpp 11.5x11.7 m3 shield" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400230 "magic::gencell sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m3_shield" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400231 # magic::add_toolkit_command $layoutframe "vpp 1.8x1.8 li shield" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400232 # "magic::gencell sky130::sky130_fd_pr__cap_vpp_1p8x1p8_li_shield" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400233 # magic::add_toolkit_command $layoutframe "vpp 1.8x1.8 m3 shield" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400234 # "magic::gencell sky130::sky130_fd_pr__cap_vpp_1p8x1p8_m3_shield" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400235 magic::add_toolkit_command $layoutframe "vpp 4.4x4.6 li/m3 shield" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400236 "magic::gencell sky130::sky130_fd_pr__cap_vpp_4p4x4p6_m3_li_shield" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400237 magic::add_toolkit_command $layoutframe "vpp 4.4x4.6 m3 shield" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400238 "magic::gencell sky130::sky130_fd_pr__cap_vpp_4p4x4p6_m3_shield" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400239 magic::add_toolkit_command $layoutframe "vpp 8.6x7.9 li/m3 shield" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400240 "magic::gencell sky130::sky130_fd_pr__cap_vpp_8p6x7p9_m3_li_shield" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400241 magic::add_toolkit_command $layoutframe "vpp 8.6x7.9 m3 shield" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400242 "magic::gencell sky130::sky130_fd_pr__cap_vpp_8p6x7p9_m3_shield" pdk2
243 magic::add_toolkit_command $layoutframe "vpp 4.4x4.6" \
244 "magic::gencell sky130::sky130_fd_pr__cap_vpp_04p4x04p6_l1m1m2_noshield" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400245
246 ${layoutframe}.titlebar.mbuttons.drc.toolmenu add command -label "DRC Routing" -command {drc style drc(routing)}
247
248 # Add command entry window by default if enabled
249 if {[info exists Opts(cmdentry)]} {
250 set Winopts(${framename},cmdentry) $Opts(cmdentry)
251 } else {
252 set Winopts(${framename},cmdentry) 0
253 }
254 if {$Winopts(${framename},cmdentry) == 1} {
255 addcommandentry $framename
256 }
257}
258
259#----------------------------------------------------------------
260
261proc sky130::mcon_draw {} {
262 set w [magic::i2u [box width]]
263 set h [magic::i2u [box height]]
264 if {$w < 0.17} {
265 puts stderr "Mcon width must be at least 0.17um"
266 return
267 }
268 if {$h < 0.17} {
269 puts stderr "Mcon height must be at least 0.17um"
270 return
271 }
272 paint lic
273 box grow n 0.05um
274 box grow s 0.05um
275 paint m1
276 box grow n -0.05um
277 box grow s -0.05um
278 box grow e 0.05um
279 box grow w 0.05um
280 paint li
281 box grow e -0.05um
282 box grow w -0.05um
283}
284
285proc sky130::via1_draw {} {
286 set w [magic::i2u [box width]]
287 set h [magic::i2u [box height]]
288 if {$w < 0.26} {
289 puts stderr "Via1 width must be at least 0.26um"
290 return
291 }
292 if {$h < 0.26} {
293 puts stderr "Via1 height must be at least 0.26um"
294 return
295 }
296 paint via1
297 box grow n 0.05um
298 box grow s 0.05um
299 paint m2
300 box grow n -0.05um
301 box grow s -0.05um
302 box grow e 0.05um
303 box grow w 0.05um
304 paint m1
305 box grow e -0.05um
306 box grow w -0.05um
307}
308
309proc sky130::via2_draw {} {
310 set w [magic::i2u [box width]]
311 set h [magic::i2u [box height]]
312 if {$w < 0.28} {
313 puts stderr "Via2 width must be at least 0.28um"
314 return
315 }
316 if {$h < 0.28} {
317 puts stderr "Via2 height must be at least 0.28um"
318 return
319 }
320 paint via2
321 box grow n 0.05um
322 box grow s 0.05um
323 paint m2
324 box grow n -0.05um
325 box grow s -0.05um
326 box grow e 0.05um
327 box grow w 0.05um
328 paint m3
329 box grow e -0.05um
330 box grow w -0.05um
331}
332
333#ifdef METAL5
334proc sky130::via3_draw {} {
335 set w [magic::i2u [box width]]
336 set h [magic::i2u [box height]]
337 if {$w < 0.32} {
338 puts stderr "Via3 width must be at least 0.32um"
339 return
340 }
341 if {$h < 0.32} {
342 puts stderr "Via3 height must be at least 0.32um"
343 return
344 }
345 paint via3
346 box grow n 0.05um
347 box grow s 0.05um
348 paint m4
349 box grow n -0.05um
350 box grow s -0.05um
351 box grow e 0.05um
352 box grow w 0.05um
353 paint m3
354 box grow e -0.05um
355 box grow w -0.05um
356}
357
358proc sky130::via4_draw {} {
359 set w [magic::i2u [box width]]
360 set h [magic::i2u [box height]]
361 if {$w < 1.18} {
362 puts stderr "Via3 width must be at least 1.18um"
363 return
364 }
365 if {$h < 1.18} {
366 puts stderr "Via3 height must be at least 1.18um"
367 return
368 }
369 paint via4
370 box grow n 0.05um
371 box grow s 0.05um
372 paint m5
373 box grow n -0.05um
374 box grow s -0.05um
375 box grow e 0.05um
376 box grow w 0.05um
377 paint m4
378 box grow e -0.05um
379 box grow w -0.05um
380}
381#endif (METAL5)
382
383proc sky130::subconn_draw {} {
384 set w [magic::i2u [box width]]
385 set h [magic::i2u [box height]]
386 if {$w < 0.17} {
387 puts stderr "Substrate tap width must be at least 0.17um"
388 return
389 }
390 if {$h < 0.17} {
391 puts stderr "Substrate tap height must be at least 0.17um"
392 return
393 }
394 paint nsc
395 box grow c 0.1um
396 paint nsd
397 box grow c -0.1um
398}
399
400#----------------------------------------------------------------
401
402proc sky130::mvsubconn_draw {} {
403 set w [magic::i2u [box width]]
404 set h [magic::i2u [box height]]
405 if {$w < 0.17} {
406 puts stderr "Substrate tap width must be at least 0.17um"
407 return
408 }
409 if {$h < 0.17} {
410 puts stderr "Substrate tap height must be at least 0.17um"
411 return
412 }
413 paint mvnsc
414 box grow c 0.1um
415 paint mvnsd
416 box grow c -0.1um
417}
418
419#----------------------------------------------------------------
420
421proc sky130::deep_nwell_draw {} {
422 set w [magic::i2u [box width]]
423 set h [magic::i2u [box height]]
424 if {$w < 3.0} {
425 puts stderr "Deep-nwell region width must be at least 3.0um"
426 return
427 }
428 if {$h < 3.0} {
429 puts stderr "Deep-nwell region height must be at least 3.0um"
430 return
431 }
432 suspendall
433 tech unlock *
434 paint dnwell
435 pushbox
436 pushbox
437 box grow c 0.4um
438 paint nwell
439 box grow c -1.43um
440 erase nwell
441 popbox
442 box grow c 0.03um
443
444 pushbox
445 box width 0
446 box grow c 0.085um
447 paint li
448 pushbox
449 box grow n -0.3um
450 box grow s -0.3um
451 paint nsc
452 popbox
453 box grow c 0.1um
454 paint nsd
455 popbox
456
457 pushbox
458 box height 0
459 box grow c 0.085um
460 paint li
461 pushbox
462 box grow e -0.3um
463 box grow w -0.3um
464 paint nsc
465 popbox
466 box grow c 0.1um
467 paint nsd
468 popbox
469
470 pushbox
471 box move n [box height]i
472 box height 0
473 box grow c 0.085um
474 paint li
475 pushbox
476 box grow e -0.3um
477 box grow w -0.3um
478 paint nsc
479 popbox
480 box grow c 0.1um
481 paint nsd
482 popbox
483
484 pushbox
485 box move e [box width]i
486 box width 0
487 box grow c 0.085um
488 paint li
489 pushbox
490 box grow n -0.3um
491 box grow s -0.3um
492 paint nsc
493 box grow c 0.1um
494 paint nsd
495 popbox
496
497 popbox
498 tech revert
499 resumeall
500}
501
502#----------------------------------------------------------------
503
504proc sky130::res_recalc {field parameters} {
505 set snake 0
506 set sterm 0.0
507 set caplen 0
508 # Set a local variable for each parameter (e.g., $l, $w, etc.)
509 foreach key [dict keys $parameters] {
510 set $key [dict get $parameters $key]
511 }
512 set val [magic::spice2float $val]
513 set l [magic::spice2float $l]
514 set w [magic::spice2float $w]
515
516 if {$snake == 0} {
517 # Straight resistor calculation
518 switch $field {
519 val { set l [expr ($val * ($w - $dw) - (2 * $term)) / $rho]
520 set w [expr ((2 * $term + $l * $rho) / $val) + $dw]
521 }
522 w { set val [expr (2 * $term + $l * $rho) / ($w - $dw)]
523 set l [expr ($val * ($w - $dw) - (2 * $term)) / $rho]
524 }
525 l { set val [expr (2 * $term + $l * $rho) / ($w - $dw)]
526 set w [expr ((2 * $term + $l * $rho) / $val) + $dw]
527 }
528 }
529 } else {
530 set term [expr $term + $sterm]
531 # Snake resistor calculation
532 switch $field {
533 val { set l [expr (($val - $rho * ($nx - 1)) * ($w - $dw) \
534 - (2 * $term) - ($rho * $caplen * ($nx - 1))) \
535 / ($rho * $nx)]
536
537 set w [expr ((2 * $term + $l * $rho * $nx \
538 + $caplen * $rho * ($nx - 1)) \
539 / ($val - $rho * ($nx - 1))) + $dw]
540 }
541 w { set val [expr $rho * ($nx - 1) + ((2 * $term) \
542 + ($rho * $l * $nx) + ($rho * $caplen * ($nx - 1))) \
543 / ($w - $dw)]
544
545 set l [expr (($val - $rho * ($nx - 1)) * ($w - $dw) \
546 - (2 * $term) - ($rho * $caplen * ($nx - 1))) \
547 / ($rho * $nx)]
548 }
549 l { set val [expr $rho * ($nx - 1) + ((2 * $term) \
550 + ($rho * $l * $nx) + ($rho * $caplen * ($nx - 1))) \
551 / ($w - $dw)]
552
553 set w [expr ((2 * $term + $l * $rho * $nx \
554 + $caplen * $rho * ($nx - 1)) \
555 / ($val - $rho * ($nx - 1))) + $dw]
556 }
557 }
558 }
559
560 set val [magic::3digitpastdecimal $val]
561 set w [magic::3digitpastdecimal $w]
562 set l [magic::3digitpastdecimal $l]
563
564 dict set parameters val $val
565 dict set parameters w $w
566 dict set parameters l $l
567
568 return $parameters
569}
570
571#----------------------------------------------------------------
572# Drawn diode routines
573#----------------------------------------------------------------
574
575proc sky130::diode_recalc {field parameters} {
576 # Set a local variable for each parameter (e.g., $l, $w, etc.)
577 foreach key [dict keys $parameters] {
578 set $key [dict get $parameters $key]
579 }
580 switch $field {
581 area { puts stdout "area changed" }
582 peri { puts stdout "perimeter changed" }
583 w { puts stdout "width changed" }
584 l { puts stdout "length changed" }
585 }
586 dict set parameters area $area
587 dict set parameters peri $peri
588 dict set parameters w $w
589 dict set parameters l $l
590}
591
592#----------------------------------------------------------------
593# diode: Conversion from SPICE netlist parameters to toolkit
594#----------------------------------------------------------------
595
596proc sky130::diode_convert {parameters} {
597 set pdkparams [dict create]
598 dict for {key value} $parameters {
599 switch -nocase $key {
600 l -
601 w -
602 peri {
603 # Length, width, and perimeter are converted to units of microns
604 set value [magic::spice2float $value]
605 # set value [expr $value * 1e6]
606 set value [magic::3digitpastdecimal $value]
607 dict set pdkparams [string tolower $key] $value
608 }
609 area {
610 # area also converted to units of microns
611 set value [magic::spice2float $value]
612 # set value [expr $value * 1e12]
613 set value [magic::3digitpastdecimal $value]
614 dict set pdkparams [string tolower $key] $value
615 }
616 m {
617 # Convert m to ny
618 dict set pdkparams ny $value
619 }
620 }
621 }
622 return $pdkparams
623}
624
625#----------------------------------------------------------------
626# diode: Interactively specifies the fixed layout parameters
627#----------------------------------------------------------------
628
629proc sky130::diode_dialog {device parameters} {
630 # Editable fields: w, l, area, perim, nx, ny
631
632 magic::add_entry area "Area (um^2)" $parameters
633 magic::add_entry peri "Perimeter (um)" $parameters
634 sky130::compute_aptot $parameters
635 magic::add_message atot "Total area (um^2)" $parameters
636 magic::add_message ptot "Total perimeter (um)" $parameters
637 magic::add_entry l "Length (um)" $parameters
638 magic::add_entry w "Width (um)" $parameters
639 magic::add_entry nx "X Repeat" $parameters
640 magic::add_entry ny "Y Repeat" $parameters
641
642 if {[dict exists $parameters compatible]} {
643 set sellist [dict get $parameters compatible]
644 magic::add_selectlist gencell "Device type" $sellist $parameters $device
645 }
646
647 if {[dict exists $parameters doverlap]} {
648 magic::add_checkbox doverlap "Overlap at end contact" $parameters
649 }
650 if {[dict exists $parameters elc]} {
651 magic::add_checkbox elc "Add left end contact" $parameters
652 }
653 if {[dict exists $parameters erc]} {
654 magic::add_checkbox erc "Add right end contact" $parameters
655 }
656 if {[dict exists $parameters etc]} {
657 magic::add_checkbox etc "Add top end contact" $parameters
658 }
659 if {[dict exists $parameters ebc]} {
660 magic::add_checkbox ebc "Add bottom end contact" $parameters
661 }
662
663 if {[dict exists $parameters guard]} {
664 magic::add_checkbox full_metal "Full metal guard ring" $parameters
665 }
666 if {[dict exists $parameters glc]} {
667 magic::add_checkbox glc "Add left guard ring contact" $parameters
668 }
669 if {[dict exists $parameters grc]} {
670 magic::add_checkbox grc "Add right guard ring contact" $parameters
671 }
672 if {[dict exists $parameters gtc]} {
673 magic::add_checkbox gtc "Add top guard ring contact" $parameters
674 }
675 if {[dict exists $parameters gbc]} {
676 magic::add_checkbox gbc "Add bottom guard ring contact" $parameters
677 }
678
679 magic::add_dependency sky130::diode_recalc $device sky130 l w area peri
680
681 # magic::add_checkbox dummy "Add dummy" $parameters
682}
683
684#----------------------------------------------------------------
685# Diode total area and perimeter computation
686#----------------------------------------------------------------
687
688proc sky130::compute_aptot {parameters} {
689 foreach key [dict keys $parameters] {
690 set $key [dict get $parameters $key]
691 }
692 set area [magic::spice2float $area]
693 set area [magic::3digitpastdecimal $area]
694 set peri [magic::spice2float $peri]
695 set peri [magic::3digitpastdecimal $peri]
696
697 # Compute total area
698 catch {set magic::atot_val [expr ($area * $nx * $ny)]}
699 # Compute total perimeter
700 catch {set magic::ptot_val [expr ($peri * $nx * $ny)]}
701}
702
703#----------------------------------------------------------------
704# diode: Check device parameters for out-of-bounds values
705#----------------------------------------------------------------
706
707proc sky130::diode_check {parameters} {
708
709 # Set a local variable for each parameter (e.g., $l, $w, etc.)
710 foreach key [dict keys $parameters] {
711 set $key [dict get $parameters $key]
712 }
713
714 # Normalize distance units to microns
715 set l [magic::spice2float $l]
716 set l [magic::3digitpastdecimal $l]
717 set w [magic::spice2float $w]
718 set w [magic::3digitpastdecimal $w]
719
720 set area [magic::spice2float $area]
721 set area [magic::3digitpastdecimal $area]
722 set peri [magic::spice2float $peri]
723 set peri [magic::3digitpastdecimal $peri]
724
725 if {$l == 0} {
726 # Calculate L from W and area
727 set l [expr ($area / $w)]
728 dict set parameters l [magic::float2spice $l]
729 } elseif {$w == 0} {
730 # Calculate W from L and area
731 set w [expr ($area / $l)]
732 dict set parameters w [magic::float2spice $w]
733 }
734 if {$w < $wmin} {
735 puts stderr "Diode width must be >= $wmin"
736 dict set parameters w $wmin
737 }
738 if {$l < $lmin} {
739 puts stderr "Diode length must be >= $lmin"
740 dict set parameters l $lmin
741 }
742 # Calculate area and perimeter from L and W
743 set area [expr ($l * $w)]
744 dict set parameters area [magic::float2spice $area]
745 set peri [expr (2 * ($l + $w))]
746 dict set parameters peri [magic::float2spice $peri]
747 sky130::compute_aptot $parameters
748
749 return $parameters
750}
751
752#------------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400753# NOTE: sky130_fd_pr__diode_pw2nd_05v5_lvt,
754# sky130_fd_pr__diode_pw2nd_05v5_nvt, sky130_fd_pr__pd2nw_05v5_lvt,
755# and sky130_fd_pr__pd2nw_11v0 are all considered parasitic diodes.
756# They may be generated by invoking the build procedure on the
757# command line. To enable them in the PDK, add them to the
758# appropriate compatible {} list.
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400759#------------------------------------------------------------------
760
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400761proc sky130::sky130_fd_pr__diode_pw2nd_05v5_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400762 return {w 0.45 l 0.45 area 0.2025 peri 1.8 \
763 nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
764 elc 1 erc 1 etc 1 ebc 1 doverlap 0 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400765 compatible {ndiode sky130_fd_pr__diode_pw2nd_11v0} full_metal 1}
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400766}
767
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400768proc sky130::sky130_fd_pr__diode_pw2nd_05v5_lvt_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400769 return {w 0.45 l 0.45 area 0.2025 peri 1.8 \
770 nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
771 elc 1 erc 1 etc 1 ebc 1 doverlap 0 \
772 full_metal 1}
773}
774
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400775proc sky130::sky130_fd_pr__pd2nw_05v5_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400776 return {w 0.45 l 0.45 area 0.2025 peri 1.8 \
777 nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
778 elc 1 erc 1 etc 1 ebc 1 \
779 glc 1 grc 1 gtc 1 gbc 1 doverlap 0 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400780 compatible {pdiode sky130_fd_pr__pd2nw_11v0} full_metal 1}
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400781}
782
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400783proc sky130::sky130_fd_pr__pd2nw_05v5_lvt_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400784 return {w 0.45 l 0.45 area 0.2025 peri 1.8 \
785 nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
786 elc 1 erc 1 etc 1 ebc 1 \
787 glc 1 grc 1 gtc 1 gbc 1 doverlap 0 \
788 full_metal 1}
789}
790
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400791proc sky130::sky130_fd_pr__pd2nw_11v0_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400792 return {w 0.45 l 0.45 area 0.2025 peri 1.8 \
793 nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
794 elc 1 erc 1 etc 1 ebc 1 \
795 glc 1 grc 1 gtc 1 gbc 1 doverlap 0 \
796 full_metal 1}
797}
798
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400799proc sky130::sky130_fd_pr__diode_pw2nd_11v0_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400800 return {w 0.45 l 0.45 area 0.2024 peri 1.8 \
801 nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
802 elc 1 erc 1 etc 1 ebc 1 doverlap 0 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400803 compatible {ndiode sky130_fd_pr__diode_pw2nd_11v0} full_metal 1}
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400804}
805
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400806proc sky130::sky130_fd_pr__diode_pw2nd_05v5_nvt_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400807 return {w 0.45 l 0.45 area 0.2024 peri 1.8 \
808 nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
809 elc 1 erc 1 etc 1 ebc 1 doverlap 0 \
810 full_metal 1}
811}
812
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400813proc sky130::sky130_fd_pr__pd2nw_11v0_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400814 return {w 0.45 l 0.45 area 0.2024 peri 1.8 \
815 nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
816 elc 1 erc 1 etc 1 ebc 1 \
817 glc 1 grc 1 gtc 1 gbc 1 doverlap 0 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400818 compatible {pdiode sky130_fd_pr__pd2nw_11v0} full_metal 1}
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400819}
820
821#----------------------------------------------------------------
822
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400823proc sky130::sky130_fd_pr__diode_pw2nd_05v5_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400824 return [sky130::diode_convert $parameters]
825}
826
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400827proc sky130::sky130_fd_pr__diode_pw2nd_05v5_lvt_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400828 return [sky130::diode_convert $parameters]
829}
830
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400831proc sky130::sky130_fd_pr__pd2nw_05v5_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400832 return [sky130::diode_convert $parameters]
833}
834
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400835proc sky130::sky130_fd_pr__pd2nw_05v5_lvt_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400836 return [sky130::diode_convert $parameters]
837}
838
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400839proc sky130::sky130_fd_pr__pd2nw_11v0_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400840 return [sky130::diode_convert $parameters]
841}
842
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400843proc sky130::sky130_fd_pr__diode_pw2nd_11v0_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400844 return [sky130::diode_convert $parameters]
845}
846
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400847proc sky130::sky130_fd_pr__diode_pw2nd_05v5_nvt_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400848 return [sky130::diode_convert $parameters]
849}
850
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400851proc sky130::sky130_fd_pr__pd2nw_11v0_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400852 return [sky130::diode_convert $parameters]
853}
854
855#----------------------------------------------------------------
856
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400857proc sky130::sky130_fd_pr__diode_pw2nd_05v5_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400858 sky130::diode_dialog ndiode $parameters
859}
860
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400861proc sky130::sky130_fd_pr__diode_pw2nd_05v5_lvt_dialog {parameters} {
862 sky130::diode_dialog sky130_fd_pr__diode_pw2nd_05v5_lvt $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400863}
864
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400865proc sky130::sky130_fd_pr__pd2nw_05v5_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400866 sky130::diode_dialog pdiode $parameters
867}
868
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400869proc sky130::sky130_fd_pr__pd2nw_05v5_lvt_dialog {parameters} {
870 sky130::diode_dialog sky130_fd_pr__pd2nw_05v5_lvt $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400871}
872
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400873proc sky130::sky130_fd_pr__pd2nw_11v0_dialog {parameters} {
874 sky130::diode_dialog sky130_fd_pr__pd2nw_11v0 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400875}
876
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400877proc sky130::sky130_fd_pr__diode_pw2nd_11v0_dialog {parameters} {
878 sky130::diode_dialog sky130_fd_pr__diode_pw2nd_11v0 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400879}
880
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400881proc sky130::sky130_fd_pr__diode_pw2nd_05v5_nvt_dialog {parameters} {
882 sky130::diode_dialog sky130_fd_pr__diode_pw2nd_05v5_nvt $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400883}
884
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400885proc sky130::sky130_fd_pr__pd2nw_11v0_dialog {parameters} {
886 sky130::diode_dialog sky130_fd_pr__pd2nw_11v0 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400887}
888
889#----------------------------------------------------------------
890
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400891proc sky130::sky130_fd_pr__diode_pw2nd_05v5_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400892 sky130::diode_check $parameters
893}
894
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400895proc sky130::sky130_fd_pr__diode_pw2nd_05v5_lvt_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400896 sky130::diode_check $parameters
897}
898
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400899proc sky130::sky130_fd_pr__pd2nw_05v5_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400900 sky130::diode_check $parameters
901}
902
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400903proc sky130::sky130_fd_pr__pd2nw_05v5_lvt_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400904 sky130::diode_check $parameters
905}
906
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400907proc sky130::sky130_fd_pr__pd2nw_11v0_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400908 sky130::diode_check $parameters
909}
910
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400911proc sky130::sky130_fd_pr__diode_pw2nd_11v0_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400912 sky130::diode_check $parameters
913}
914
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400915proc sky130::sky130_fd_pr__diode_pw2nd_05v5_nvt_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400916 sky130::diode_check $parameters
917}
918
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400919proc sky130::sky130_fd_pr__pd2nw_11v0_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400920 sky130::diode_check $parameters
921}
922
923#----------------------------------------------------------------
924# Diode: Draw a single device
925#----------------------------------------------------------------
926
927proc sky130::diode_device {parameters} {
928 # Epsilon for avoiding round-off errors
929 set eps 0.0005
930
931 # Set local default values if they are not in parameters
932 set dev_surround 0
933 set dev_sub_type ""
934
935 # Set a local variable for each parameter (e.g., $l, $w, etc.)
936 foreach key [dict keys $parameters] {
937 set $key [dict get $parameters $key]
938 }
939
940 # If there is no end_sub_surround, set it to sub_surround
941 if {![dict exists $parameters end_sub_surround]} {
942 set end_sub_surround $sub_surround
943 }
944
945 # Draw the device
946 pushbox
947 box size 0 0
948
949 set hw [/ $w 2.0]
950 set hl [/ $l 2.0]
951
952 # Calculate ring size (measured to contact center)
953 set gx [+ $w [* 2.0 [+ $dev_spacing $dev_surround]] $contact_size]
954 set gy [+ $l [* 2.0 [+ $dev_spacing $dev_surround]] $contact_size]
955
956 # Draw the ring first, because diode may occupy well/substrate plane
957 set guardparams $parameters
958 dict set guardparams plus_diff_type $end_type
959 dict set guardparams plus_contact_type $end_contact_type
960 dict set guardparams diff_surround $end_surround
961 dict set guardparams sub_type $end_sub_type
962 dict set guardparams sub_surround $sub_surround
963 dict set guardparams guard_sub_surround $end_sub_surround
964 dict set guardparams glc $elc
965 dict set guardparams grc $erc
966 dict set guardparams gtc $etc
967 dict set guardparams gbc $ebc
968 set cext [sky130::guard_ring $gx $gy $guardparams]
969
970 pushbox
971 box grow n ${hl}um
972 box grow s ${hl}um
973 box grow e ${hw}um
974 box grow w ${hw}um
975 paint ${dev_type}
976 set cext [sky130::unionbox $cext [sky130::getbox]]
977
978 if {$dev_sub_type != ""} {
979 box grow n ${sub_surround}um
980 box grow s ${sub_surround}um
981 box grow e ${sub_surround}um
982 box grow w ${sub_surround}um
983 paint ${dev_sub_type}
984 }
985 popbox
986
987 if {${w} < ${l}} {
988 set orient vert
989 } else {
990 set orient horz
991 }
992
993 # Reduce width by surround amount
994 set w [- $w [* ${dev_surround} 2.0]]
995 set l [- $l [* ${dev_surround} 2.0]]
996
997 set cext [sky130::unionbox $cext [sky130::draw_contact ${w} ${l} \
998 ${dev_surround} ${metal_surround} ${contact_size} \
999 ${dev_type} ${dev_contact_type} li ${orient}]]
1000
1001 popbox
1002 return $cext
1003}
1004
1005#----------------------------------------------------------------
1006# Diode: Draw the tiled device
1007#----------------------------------------------------------------
1008
1009proc sky130::diode_draw {parameters} {
1010 tech unlock *
1011
1012 # Set defaults if they are not in parameters
1013 set doverlap 0 ;# overlap diodes at contacts
1014 set guard 0 ;# draw a guard ring
1015 set prohibit_overlap false ;# don't prohibit overlaps
1016
1017 # Set a local variable for each parameter (e.g., $l, $w, etc.)
1018 foreach key [dict keys $parameters] {
1019 set $key [dict get $parameters $key]
1020 }
1021
1022 # Normalize distance units to microns
1023 set w [magic::spice2float $w]
1024 set l [magic::spice2float $l]
1025
1026 pushbox
1027 box values 0 0 0 0
1028
1029 # Determine the base device dimensions by drawing one device
1030 # while all layers are locked (nothing drawn). This allows the
1031 # base drawing routine to do complicated geometry without having
1032 # to duplicate it here with calculations.
1033
1034 tech lock *
1035 set bbox [sky130::diode_device $parameters]
1036 # puts stdout "Diagnostic: Device bounding box e $bbox (um)"
1037 tech unlock *
1038
1039 set fw [- [lindex $bbox 2] [lindex $bbox 0]]
1040 set fh [- [lindex $bbox 3] [lindex $bbox 1]]
1041 set lw [+ [lindex $bbox 2] [lindex $bbox 0]]
1042 set lh [+ [lindex $bbox 3] [lindex $bbox 1]]
1043
1044 # If prohibit_overlap is true, then end overlapping is prohibited when
1045 # nx or ny is > 1 to prevent DRC errors (typically from well spacing rule)
1046 if {$prohibit_overlap == true} {
1047 if {($nx > 1) || ($ny > 1)} {
1048 set doverlap 0
1049 }
1050 }
1051
1052 # Determine tile width and height (depends on overlap)
1053
1054 if {$doverlap == 0} {
1055 set dx [+ $fw $end_spacing]
1056 set dy [+ $fh $end_spacing]
1057 } else {
1058 # overlap contact
1059 set dx [- $fw [+ [* 2.0 $sub_surround] [* 2.0 $end_surround] $contact_size]]
1060 set dy [- $fh [+ [* 2.0 $sub_surround] [* 2.0 $end_surround] $contact_size]]
1061 }
1062
1063 # Determine core width and height
1064 set corex [+ [* [- $nx 1] $dx] $fw]
1065 set corey [+ [* [- $ny 1] $dy] $fh]
1066 set corellx [/ [+ [- $corex $fw] $lw] 2.0]
1067 set corelly [/ [+ [- $corey $fh] $lh] 2.0]
1068
1069 if {$guard != 0} {
1070 # Calculate guard ring size (measured to contact center)
1071 set gx [+ $corex [* 2.0 [+ $diff_spacing $diff_surround]] $contact_size]
1072 set gy [+ $corey [* 2.0 [+ $diff_spacing $diff_surround]] $contact_size]
1073
1074 # Draw the guard ring first, because diode may occupy well/substrate plane
1075 sky130::guard_ring $gx $gy $parameters
1076 }
1077
1078 pushbox
1079 box move w ${corellx}um
1080 box move s ${corelly}um
1081 if {($nx > 1) || ($ny > 1)} {
1082 pushbox
1083 set hfw [/ $fw 2.0]
1084 set hfh [/ $fh 2.0]
1085 box move w ${hfw}um
1086 box move s ${hfh}um
1087 box size ${corex}um ${corey}um
1088 paint $end_sub_type
1089 popbox
1090 }
1091 for {set xp 0} {$xp < $nx} {incr xp} {
1092 pushbox
1093 for {set yp 0} {$yp < $ny} {incr yp} {
1094 sky130::diode_device $parameters
1095 box move n ${dy}um
1096 }
1097 popbox
1098 box move e ${dx}um
1099 }
1100 popbox
1101 popbox
1102
1103 tech revert
1104}
1105
1106#----------------------------------------------------------------
1107
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001108proc sky130::sky130_fd_pr__diode_pw2nd_05v5_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001109
1110 # Set a local variable for each rule in ruleset
1111 foreach key [dict keys $sky130::ruleset] {
1112 set $key [dict get $sky130::ruleset $key]
1113 }
1114
1115 set newdict [dict create \
1116 dev_type ndiode \
1117 dev_contact_type ndic \
1118 end_type psd \
1119 end_contact_type psc \
1120 end_sub_type psub \
1121 dev_spacing ${diff_spacing} \
1122 dev_surround ${diff_surround} \
1123 end_spacing ${diff_spacing} \
1124 end_surround 0 \
1125 ]
1126 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1127 return [sky130::diode_draw $drawdict]
1128}
1129
1130#----------------------------------------------------------------
1131# NOTE: Use ppd instead of psd so that there is additional
1132# diffusion around the contact, allowing more space for the
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001133# implant (likewise sky130_fd_pr__pd2nw_05v5_lvt and sky130_fd_pr__pd2nw_11v0).
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001134
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001135proc sky130::sky130_fd_pr__diode_pw2nd_05v5_lvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001136
1137 # Set a local variable for each rule in ruleset
1138 foreach key [dict keys $sky130::ruleset] {
1139 set $key [dict get $sky130::ruleset $key]
1140 }
1141
1142 set newdict [dict create \
1143 dev_type ndiodelvt \
1144 dev_contact_type ndilvtc \
1145 end_type ppd \
1146 end_contact_type psc \
1147 end_sub_type psub \
1148 dev_spacing ${diff_spacing} \
1149 dev_surround ${diff_surround} \
1150 end_spacing ${diff_spacing} \
1151 end_surround ${diff_surround} \
1152 ]
1153 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1154 return [sky130::diode_draw $drawdict]
1155}
1156
1157#----------------------------------------------------------------
1158
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001159proc sky130::sky130_fd_pr__pd2nw_05v5_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001160
1161 # Set a local variable for each rule in ruleset
1162 foreach key [dict keys $sky130::ruleset] {
1163 set $key [dict get $sky130::ruleset $key]
1164 }
1165
1166 set newdict [dict create \
1167 dev_type pdiode \
1168 guard 1 \
1169 dev_contact_type pdic \
1170 end_type nsd \
1171 end_contact_type nsc \
1172 end_sub_type nwell \
1173 plus_diff_type psd \
1174 plus_contact_type psc \
1175 sub_type psub \
1176 dev_spacing ${diff_spacing} \
1177 dev_surround ${diff_surround} \
1178 end_spacing ${diff_spacing} \
1179 end_surround 0 \
1180 ]
1181 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1182 return [sky130::diode_draw $drawdict]
1183}
1184
1185#----------------------------------------------------------------
1186
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001187proc sky130::sky130_fd_pr__pd2nw_05v5_lvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001188
1189 # Set a local variable for each rule in ruleset
1190 foreach key [dict keys $sky130::ruleset] {
1191 set $key [dict get $sky130::ruleset $key]
1192 }
1193
1194 set newdict [dict create \
1195 dev_type pdiodelvt \
1196 guard 1 \
1197 dev_contact_type pdilvtc \
1198 end_type nnd \
1199 end_contact_type nsc \
1200 end_sub_type nwell \
1201 plus_diff_type psd \
1202 plus_contact_type psc \
1203 sub_type psub \
1204 dev_spacing ${diff_spacing} \
1205 dev_surround ${diff_surround} \
1206 end_spacing ${diff_spacing} \
1207 end_surround ${diff_surround} \
1208 ]
1209 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1210 return [sky130::diode_draw $drawdict]
1211}
1212
1213#----------------------------------------------------------------
1214
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001215proc sky130::sky130_fd_pr__pd2nw_11v0_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001216
1217 # Set a local variable for each rule in ruleset
1218 foreach key [dict keys $sky130::ruleset] {
1219 set $key [dict get $sky130::ruleset $key]
1220 }
1221
1222 set newdict [dict create \
1223 dev_type pdiodehvt \
1224 guard 1 \
1225 dev_contact_type pdihvtc \
1226 end_type nnd \
1227 end_contact_type nsc \
1228 end_sub_type nwell \
1229 plus_diff_type psd \
1230 plus_contact_type psc \
1231 sub_type psub \
1232 dev_spacing ${diff_spacing} \
1233 dev_surround ${diff_surround} \
1234 end_spacing ${diff_spacing} \
1235 end_surround ${diff_surround} \
1236 ]
1237 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1238 return [sky130::diode_draw $drawdict]
1239}
1240
1241#----------------------------------------------------------------
1242
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001243proc sky130::sky130_fd_pr__diode_pw2nd_11v0_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001244
1245 # Set a local variable for each rule in ruleset
1246 foreach key [dict keys $sky130::ruleset] {
1247 set $key [dict get $sky130::ruleset $key]
1248 }
1249
1250 set newdict [dict create \
1251 dev_type mvndiode \
1252 dev_contact_type mvndic \
1253 end_type mvpsd \
1254 end_contact_type mvpsc \
1255 end_sub_type psub \
1256 diff_spacing 0.37 \
1257 dev_spacing 0.39 \
1258 dev_surround ${diff_surround} \
1259 end_spacing 0.36 \
1260 end_surround ${diff_surround} \
1261 ]
1262 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1263 return [sky130::diode_draw $drawdict]
1264}
1265
1266
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001267proc sky130::sky130_fd_pr__diode_pw2nd_05v5_nvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001268
1269 # Set a local variable for each rule in ruleset
1270 foreach key [dict keys $sky130::ruleset] {
1271 set $key [dict get $sky130::ruleset $key]
1272 }
1273
1274 set newdict [dict create \
1275 dev_type nndiode \
1276 dev_contact_type nndic \
1277 end_type mvpsd \
1278 end_contact_type mvpsc \
1279 end_sub_type psub \
1280 dev_spacing 0.37 \
1281 dev_surround ${diff_surround} \
1282 end_spacing 0.30 \
1283 end_surround ${diff_surround} \
1284 ]
1285 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1286 return [sky130::diode_draw $drawdict]
1287}
1288
1289
1290#----------------------------------------------------------------
1291
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001292proc sky130::sky130_fd_pr__pd2nw_11v0_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001293
1294 # Set a local variable for each rule in ruleset
1295 foreach key [dict keys $sky130::ruleset] {
1296 set $key [dict get $sky130::ruleset $key]
1297 }
1298
1299 set newdict [dict create \
1300 guard 1 \
1301 dev_type mvpdiode \
1302 dev_contact_type mvpdic \
1303 end_type mvnsd \
1304 end_contact_type mvnsc \
1305 end_sub_type nwell \
1306 plus_diff_type mvpsd \
1307 plus_contact_type mvpsc \
1308 sub_type psub \
1309 diff_spacing 0.58 \
1310 dev_spacing 0.37 \
1311 dev_surround ${diff_surround} \
1312 end_spacing 0.30 \
1313 end_sub_surround 0.33 \
1314 end_surround ${diff_surround} \
1315 ]
1316 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1317 return [sky130::diode_draw $drawdict]
1318}
1319
1320#----------------------------------------------------------------
1321# Drawn capactitor routines
1322# NOTE: Work in progress. These values need to be corrected.
1323#----------------------------------------------------------------
1324
1325#ifdef MIM
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001326proc sky130::sky130_fd_pr__cap_mim_m3_1_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001327 return {w 2.00 l 2.00 val 4.0 carea 1.00 cperi 0.17 \
1328 nx 1 ny 1 dummy 0 square 0 lmin 2.00 wmin 2.00 \
1329 lmax 30.0 wmax 30.0 dc 0 bconnect 1 tconnect 1}
1330}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001331proc sky130::sky130_fd_pr__cap_mim_m3_2_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001332 return {w 2.00 l 2.00 val 4.0 carea 1.00 cperi 0.17 \
1333 nx 1 ny 1 dummy 0 square 0 lmin 2.00 wmin 2.00 \
1334 lmax 30.0 wmax 30.0 dc 0 bconnect 1 tconnect 1}
1335}
1336#endif (MIM)
1337
1338
1339#----------------------------------------------------------------
1340# Recalculate capacitor values from GUI entries.
1341# Recomputes W/L and Value as long as 2 of them are present
1342# (To be completed)
1343#----------------------------------------------------------------
1344
1345proc sky130::cap_recalc {field parameters} {
1346 # Set a local variable for each parameter (e.g., $l, $w, etc.)
1347 foreach key [dict keys $parameters] {
1348 set $key [dict get $parameters $key]
1349 }
1350 switch $field {
1351 val { puts stdout "value changed" }
1352 w { puts stdout "width changed" }
1353 l { puts stdout "length changed" }
1354 }
1355 dict set parameters val $val
1356 dict set parameters w $w
1357 dict set parameters l $l
1358}
1359
1360#----------------------------------------------------------------
1361# Capacitor defaults:
1362#----------------------------------------------------------------
1363# w Width of drawn cap
1364# l Length of drawn cap
1365# nx Number of devices in X
1366# ny Number of devices in Y
1367# val Default cap value
1368# carea Area
1369# cperi Perimeter
1370# dummy Add dummy cap
1371# square Make square capacitor
1372#
1373# (not user-editable)
1374#
1375# wmin Minimum allowed width
1376# lmin Minimum allowed length
1377# dc Area to remove to calculated area
1378#----------------------------------------------------------------
1379
1380#----------------------------------------------------------------
1381# capacitor: Conversion from SPICE netlist parameters to toolkit
1382#----------------------------------------------------------------
1383
1384proc sky130::cap_convert {parameters} {
1385 set pdkparams [dict create]
1386 dict for {key value} $parameters {
1387 switch -nocase $key {
1388 l -
1389 w {
1390 # Length and width are converted to units of microns
1391 set value [magic::spice2float $value]
1392 # set value [expr $value * 1e6]
1393 set value [magic::3digitpastdecimal $value]
1394 dict set pdkparams [string tolower $key] $value
1395 }
1396 m {
1397 # Convert m to ny
1398 dict set pdkparams ny $value
1399 }
1400 }
1401 }
1402 return $pdkparams
1403}
1404
1405#ifdef MIM
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001406proc sky130::sky130_fd_pr__cap_mim_m3_1_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001407 return [cap_convert $parameters]
1408}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001409proc sky130::sky130_fd_pr__cap_mim_m3_2_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001410 return [cap_convert $parameters]
1411}
1412#endif (MIM)
1413
1414#----------------------------------------------------------------
1415# capacitor: Interactively specifies the fixed layout parameters
1416#----------------------------------------------------------------
1417
1418proc sky130::cap_dialog {device parameters} {
1419 # Editable fields: w, l, nx, ny, val
1420 # Checked fields: square, dummy
1421
1422 magic::add_entry val "Value (fF)" $parameters
1423 sky130::compute_ctot $parameters
1424 magic::add_message ctot "Total capacitance (pF)" $parameters
1425 magic::add_entry l "Length (um)" $parameters
1426 magic::add_entry w "Width (um)" $parameters
1427 magic::add_entry nx "X Repeat" $parameters
1428 magic::add_entry ny "Y Repeat" $parameters
1429
1430 if {[dict exists $parameters square]} {
1431 magic::add_checkbox square "Square capacitor" $parameters
1432 }
1433 if {[dict exists $parameters bconnect]} {
1434 magic::add_checkbox bconnect "Connect bottom plates in array" $parameters
1435 }
1436 if {[dict exists $parameters tconnect]} {
1437 magic::add_checkbox tconnect "Connect top plates in array" $parameters
1438 }
1439 if {[dict exists $parameters guard]} {
1440 magic::add_checkbox guard "Add guard ring" $parameters
1441 }
1442
1443 magic::add_dependency sky130::cap_recalc $device sky130 l w val
1444
1445 # magic::add_checkbox dummy "Add dummy" $parameters
1446}
1447
1448#ifdef MIM
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001449proc sky130::sky130_fd_pr__cap_mim_m3_1_dialog {parameters} {
1450 sky130::cap_dialog sky130_fd_pr__cap_mim_m3_1 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001451}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001452proc sky130::sky130_fd_pr__cap_mim_m3_2_dialog {parameters} {
1453 sky130::cap_dialog sky130_fd_pr__cap_mim_m3_2 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001454}
1455#endif (MIM)
1456
1457#----------------------------------------------------------------
1458# Capacitor total capacitance computation
1459#----------------------------------------------------------------
1460
1461proc sky130::compute_ctot {parameters} {
1462 foreach key [dict keys $parameters] {
1463 set $key [dict get $parameters $key]
1464 }
1465 set val [magic::spice2float $val]
1466 set val [magic::3digitpastdecimal $val]
1467
1468 # Compute total capacitance (and convert fF to pF)
1469 catch {set magic::ctot_val [expr (0.001 * $val * $nx * $ny)]}
1470}
1471
1472#----------------------------------------------------------------
1473# Capacitor: Draw a single device
1474#----------------------------------------------------------------
1475
1476proc sky130::cap_device {parameters} {
1477 # Epsilon for avoiding round-off errors
1478 set eps 0.0005
1479
1480 # Set local default values if they are not in parameters
1481 set cap_surround 0
1482 set bot_surround 0
1483 set top_surround 0
1484 set bconnect 0 ;# bottom plates are connected in array
1485 set cap_spacing 0 ;# cap spacing in array
1486 set top_metal_space 0 ;# top metal spacing (if larger than cap spacing)
1487
1488 # Set a local variable for each parameter (e.g., $l, $w, etc.)
1489 foreach key [dict keys $parameters] {
1490 set $key [dict get $parameters $key]
1491 }
1492
1493 if {![dict exists $parameters top_metal_space]} {
1494 set top_metal_space $metal_spacing
1495 }
1496
1497 # Draw the device
1498 pushbox
1499 box size 0 0
1500
1501 pushbox
1502 set hw [/ $w 2.0]
1503 set hl [/ $l 2.0]
1504 box grow e ${hw}um
1505 box grow w ${hw}um
1506 box grow n ${hl}um
1507 box grow s ${hl}um
1508 paint ${cap_type}
1509 pushbox
1510 box grow n -${cap_surround}um
1511 box grow s -${cap_surround}um
1512 box grow e -${cap_surround}um
1513 box grow w -${cap_surround}um
1514 paint ${cap_contact_type}
1515 pushbox
1516 box grow n ${top_surround}um
1517 box grow s ${top_surround}um
1518 box grow e ${top_surround}um
1519 box grow w ${top_surround}um
1520 paint ${top_type}
1521 set cext [sky130::getbox]
1522 popbox
1523 popbox
1524 pushbox
1525 box grow n ${bot_surround}um
1526 box grow s ${bot_surround}um
1527 box grow e ${bot_surround}um
1528 box grow w ${bot_surround}um
1529
1530 paint ${bot_type}
1531 # Create boundary using properties
1532 property FIXED_BBOX [box values]
1533 set cext [sky130::unionbox $cext [sky130::getbox]]
1534
1535 # Extend bottom metal under contact to right
1536 box grow e ${end_spacing}um
1537 set chw [/ ${contact_size} 2.0]
1538 box grow e ${chw}um
1539 box grow e ${end_surround}um
1540 paint ${bot_type}
1541
1542 popbox
1543 popbox
1544
1545 # Draw contact to right. Reduce contact extent if devices are not
1546 # wired together and the top metal spacing rule limits the distance
1547 set lcont $l
1548 if {($bconnect == 0) && ($ny > 1)} {
1549 if {$cap_spacing < $top_metal_space} {
1550 set cspace [- $top_metal_space $cap_spacing]
1551 set lcont [- $l $cspace]
1552 }
1553 }
1554
1555 pushbox
1556 box move e ${hw}um
1557 box move e ${bot_surround}um
1558 box move e ${end_spacing}um
1559 set cl [- [+ ${lcont} [* ${bot_surround} 2.0]] [* ${end_surround} 2.0]]
1560 set cl [- ${cl} ${metal_surround}] ;# see below
1561 set cext [sky130::unionbox $cext [sky130::draw_contact 0 ${cl} \
1562 ${end_surround} ${metal_surround} ${contact_size} \
1563 ${bot_type} ${top_contact_type} ${top_type} full]]
1564 popbox
1565 popbox
1566
1567 return $cext
1568
1569 # cl shrinks top and bottom to accomodate larger bottom metal
1570 # surround rule for contacts near a MiM cap. This should be its
1571 # own variable, but metal_surround is sufficient.
1572}
1573
1574#----------------------------------------------------------------
1575# Metal plate sandwich capacitor: Draw a single device
1576#----------------------------------------------------------------
1577
1578proc sky130::sandwich_cap_device {parameters} {
1579
1580 # Set a local variable for each parameter (e.g., $l, $w, etc.)
1581 foreach key [dict keys $parameters] {
1582 set $key [dict get $parameters $key]
1583 }
1584
1585 pushbox
1586 box size 0 0
1587
1588 set hw [/ $w 2.0]
1589 set hl [/ $l 2.0]
1590
1591 set cw [- [* $hw [/ 2.0 3]] [* $cont_surround 2.0]]
1592 set cl [- [* $hl [/ 2.0 3]] [* $cont_surround 2.0]]
1593
1594 # plate capacitor defines layers p0, p1, etc.
1595 for {set i 0} {$i < 20} {incr i} {
1596 if {[catch {set layer [subst \$p${i}_type]}]} {break} ;# no more layers defined
1597 pushbox
1598 box grow e ${hw}um
1599 box grow w ${hw}um
1600 box grow n ${hl}um
1601 box grow s ${hl}um
1602 if {![catch {set shrink [subst \$p${i}_shrink]}]} {
1603 box grow e -${shrink}um
1604 box grow w -${shrink}um
1605 box grow n -${shrink}um
1606 box grow s -${shrink}um
1607 set cutout_spacing [+ [* ${shrink} 2.0] [/ $via_size 2.0] $cont_surround]
1608 } else {
1609 set cutout_spacing 0
1610 }
1611
1612 paint ${layer}
1613
1614 if {$i == 1} {
1615 # Note that cap_type geometry is coincident with p1_type.
1616 # Typically, this will define a layer that outputs as both
1617 # poly and a capacitor definition layer.
1618 if {[dict exists $parameters cap_type]} {
1619 paint $cap_type
1620 }
1621 }
1622 popbox
1623
1624 # Even layers connect at corners, odd layers connect at sides.
1625 # Even layers cut out the sides, odd layers cut out the corners.
1626 # Layer zero has no side contacts or cutout.
1627
1628 if {[% $i 2] == 0} {
1629 set cornercmd paint
1630 set cornersize $cutout_spacing
1631 set sidecmd erase
1632 set nssidelong [+ $cutout_spacing [/ $hw 3.0]]
1633 set ewsidelong [+ $cutout_spacing [/ $hl 3.0]]
1634 set sideshort $cutout_spacing
1635 } else {
1636 set cornercmd erase
1637 set cornersize $cutout_spacing
1638 set sidecmd paint
1639 set nssidelong [/ $hw 3.0]
1640 set ewsidelong [/ $hl 3.0]
1641 set sideshort $cutout_spacing
1642 }
1643
1644 if {$i > 0} {
1645 pushbox
1646 box move e ${hw}um
1647 box grow n ${ewsidelong}um
1648 box grow s ${ewsidelong}um
1649 box grow w ${sideshort}um
1650 ${sidecmd} ${layer}
1651 popbox
1652 pushbox
1653 box move n ${hl}um
1654 box grow e ${nssidelong}um
1655 box grow w ${nssidelong}um
1656 box grow s ${sideshort}um
1657 ${sidecmd} ${layer}
1658 popbox
1659 pushbox
1660 box move w ${hw}um
1661 box grow n ${ewsidelong}um
1662 box grow s ${ewsidelong}um
1663 box grow e ${sideshort}um
1664 ${sidecmd} ${layer}
1665 popbox
1666 pushbox
1667 box move s ${hl}um
1668 box grow e ${nssidelong}um
1669 box grow w ${nssidelong}um
1670 box grow n ${sideshort}um
1671 ${sidecmd} ${layer}
1672 popbox
1673
1674 pushbox
1675 box move n ${hl}um
1676 box move e ${hw}um
1677 box grow s ${cornersize}um
1678 box grow w ${cornersize}um
1679 ${cornercmd} ${layer}
1680 popbox
1681 pushbox
1682 box move n ${hl}um
1683 box move w ${hw}um
1684 box grow s ${cornersize}um
1685 box grow e ${cornersize}um
1686 ${cornercmd} ${layer}
1687 popbox
1688 pushbox
1689 box move s ${hl}um
1690 box move e ${hw}um
1691 box grow n ${cornersize}um
1692 box grow w ${cornersize}um
1693 ${cornercmd} ${layer}
1694 popbox
1695 pushbox
1696 box move s ${hl}um
1697 box move w ${hw}um
1698 box grow n ${cornersize}um
1699 box grow e ${cornersize}um
1700 ${cornercmd} ${layer}
1701 popbox
1702 }
1703 }
1704
1705 # Draw contacts after all layers have been drawn, so that erasing
1706 # layers does not affect the contacts.
1707
1708 for {set i 0} {$i < 20} {incr i} {
1709 if {![catch {set contact [subst \$p${i}_contact_type]}]} {
1710 set layer [subst \$p${i}_type]
1711 set j [+ $i 1]
1712 set toplayer [subst \$p${j}_type]
1713
1714 # Draw corner contacts
1715 pushbox
1716 box move e ${hw}um
1717 box move n ${hl}um
1718 sky130::draw_contact 0 0 \
1719 ${cont_surround} ${cont_surround} ${via_size} \
1720 ${layer} ${contact} ${toplayer} full
1721 popbox
1722 pushbox
1723 box move w ${hw}um
1724 box move n ${hl}um
1725 sky130::draw_contact 0 0 \
1726 ${cont_surround} ${cont_surround} ${via_size} \
1727 ${layer} ${contact} ${toplayer} full
1728 popbox
1729 pushbox
1730 box move e ${hw}um
1731 box move s ${hl}um
1732 sky130::draw_contact 0 0 \
1733 ${cont_surround} ${cont_surround} ${via_size} \
1734 ${layer} ${contact} ${toplayer} full
1735 popbox
1736 pushbox
1737 box move w ${hw}um
1738 box move s ${hl}um
1739 sky130::draw_contact 0 0 \
1740 ${cont_surround} ${cont_surround} ${via_size} \
1741 ${layer} ${contact} ${toplayer} full
1742 popbox
1743
1744 # Draw side contacts (except on poly)
1745 if {$i > 0} {
1746 pushbox
1747 box move w ${hw}um
1748 sky130::draw_contact 0 ${cl} \
1749 ${cont_surround} ${cont_surround} ${via_size} \
1750 ${layer} ${contact} ${toplayer} full
1751 popbox
1752 pushbox
1753 box move e ${hw}um
1754 sky130::draw_contact 0 ${cl} \
1755 ${cont_surround} ${cont_surround} ${via_size} \
1756 ${layer} ${contact} ${toplayer} full
1757 popbox
1758 pushbox
1759 box move n ${hl}um
1760 sky130::draw_contact ${cw} 0 \
1761 ${cont_surround} ${cont_surround} ${via_size} \
1762 ${layer} ${contact} ${toplayer} full
1763 popbox
1764 pushbox
1765 box move s ${hl}um
1766 sky130::draw_contact ${cw} 0 \
1767 ${cont_surround} ${cont_surround} ${via_size} \
1768 ${layer} ${contact} ${toplayer} full
1769 popbox
1770 }
1771 } else {
1772 break
1773 }
1774 }
1775
1776 popbox
1777 # Bounding box is the same as the device length and width
1778 set cext [list -$hw -$hl $hw $hl]
1779 return $cext
1780}
1781
1782#----------------------------------------------------------------
1783# Capacitor: Draw the tiled device
1784#----------------------------------------------------------------
1785
1786proc sky130::cap_draw {parameters} {
1787 tech unlock *
1788 set savesnap [snap]
1789 snap internal
1790
1791 # Set defaults if they are not in parameters
1792 set coverlap 0 ;# overlap capacitors at contacts
1793 set guard 0 ;# draw a guard ring
1794 set sandwich 0 ;# this is not a plate sandwich capacitor
1795 set cap_spacing 0 ;# abutted caps if spacing is zero
1796 set cap_diff_spacing 0
1797 set wide_cap_spacing 0 ;# additional spacing for wide metal rule
1798 set wide_cap_width 0
1799 set end_spacing 0
1800 set end_surround 0
1801 set bot_surround 0
1802 set top_metal_width 0
1803 set bconnect 0 ;# connect bottom plates in array
1804 set tconnect 0 ;# connect top plates in array
1805 set top_type ""
1806
1807 # Set a local variable for each parameter (e.g., $l, $w, etc.)
1808 foreach key [dict keys $parameters] {
1809 set $key [dict get $parameters $key]
1810 }
1811
1812 # Normalize distance units to microns
1813 set w [magic::spice2float $w]
1814 set l [magic::spice2float $l]
1815
1816 pushbox
1817 box values 0 0 0 0
1818
1819 # Determine the base device dimensions by drawing one device
1820 # while all layers are locked (nothing drawn). This allows the
1821 # base drawing routine to do complicated geometry without having
1822 # to duplicate it here with calculations.
1823
1824 tech lock *
1825 if {$sandwich == 1} {
1826 set bbox [sky130::sandwich_cap_device $parameters]
1827 } else {
1828 set bbox [sky130::cap_device $parameters]
1829 }
1830 # puts stdout "Diagnostic: Device bounding box e $bbox (um)"
1831 tech unlock *
1832
1833 set fw [- [lindex $bbox 2] [lindex $bbox 0]]
1834 set fh [- [lindex $bbox 3] [lindex $bbox 1]]
1835 set lw [+ [lindex $bbox 2] [lindex $bbox 0]]
1836 set lh [+ [lindex $bbox 3] [lindex $bbox 1]]
1837
1838 set dwide 0
1839 if {($fw >= $wide_cap_width) && ($fh >= $wide_cap_width)} {
1840 set dwide $wide_cap_spacing
1841 }
1842
1843 # Determine tile width and height (depends on overlap)
1844 if {$coverlap == 0} {
1845 set dy [+ $fh $cap_spacing $dwide]
1846 } else {
1847 # overlap at end contact
1848 set dy [- $fh [+ $end_surround $end_surround $contact_size]]
1849 }
1850 # Contact is placed on right so spacing is determined by end_spacing.
1851 set dx [+ $fw $end_spacing $dwide]
1852
1853 # Determine core width and height
1854 set corex [+ [* [- $nx 1] $dx] $fw]
1855 set corey [+ [* [- $ny 1] $dy] $fh]
1856 set corellx [/ [+ [- $corex $fw] $lw] 2.0]
1857 set corelly [/ [+ [- $corey $fh] $lh] 2.0]
1858
1859 if {$guard != 0} {
1860 # Calculate guard ring size (measured to contact center)
1861 set gx [+ $corex [* 2.0 [+ $cap_diff_spacing $diff_surround]] $contact_size]
1862 set gy [+ $corey [* 2.0 [+ $end_spacing $diff_surround]] $contact_size]
1863
1864 # Draw the guard ring first.
1865 sky130::guard_ring $gx $gy $parameters
1866 }
1867
1868 set twidth [+ ${contact_size} ${end_surround} ${end_surround}]
1869 if {${twidth} < ${top_metal_width}} {
1870 set twidth ${top_metal_width}
1871 }
1872 set hmw [/ $twidth 2.0]
1873 set hdy [/ $dy 2.0]
1874 set cdx [+ [/ ${w} 2.0] ${bot_surround} ${end_spacing}]
1875
1876 pushbox
1877 box move w ${corellx}um
1878 box move s ${corelly}um
1879 for {set xp 0} {$xp < $nx} {incr xp} {
1880 pushbox
1881 for {set yp 0} {$yp < $ny} {incr yp} {
1882 if {$sandwich == 1} {
1883 sky130::sandwich_cap_device $parameters
1884 } else {
1885 sky130::cap_device $parameters
1886 }
1887 if {$ny > 1} {
1888 pushbox
1889 box grow e ${hmw}um
1890 box grow w ${hmw}um
1891 box grow n ${hdy}um
1892 box grow s ${hdy}um
1893 if {($top_type != "") && ($tconnect == 1)} {
1894 paint ${top_type}
1895 }
1896 if {($top_type != "") && ($bconnect == 1)} {
1897 box move e ${cdx}um
1898 paint ${top_type}
1899 }
1900 popbox
1901 }
1902 box move n ${dy}um
1903 }
1904 popbox
1905 box move e ${dx}um
1906 }
1907 popbox
1908 popbox
1909
1910 snap $savesnap
1911 tech revert
1912}
1913
1914#----------------------------------------------------------------
1915
1916#ifdef MIM
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001917proc sky130::sky130_fd_pr__cap_mim_m3_1_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001918 set newdict [dict create \
1919 top_type m4 \
1920 top_contact_type via3 \
1921 cap_type mimcap \
1922 cap_contact_type mimcc \
1923 bot_type m3 \
1924 bot_surround 0.5 \
1925 cap_spacing 0.5 \
1926 cap_surround 0.2 \
1927 top_surround 0.005 \
1928 end_surround 0.1 \
1929 end_spacing 0.60 \
1930 contact_size 0.32 \
1931 metal_surround 0.08 \
1932 ]
1933 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1934 return [sky130::cap_draw $drawdict]
1935}
1936
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001937proc sky130::sky130_fd_pr__cap_mim_m3_2_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001938 set newdict [dict create \
1939 top_type m5 \
1940 top_contact_type via4 \
1941 cap_type mimcap2 \
1942 cap_contact_type mim2cc \
1943 bot_type m4 \
1944 bot_surround 0.5 \
1945 cap_spacing 0.5 \
1946 cap_surround 0.2 \
1947 top_surround 0.12 \
1948 end_surround 0.1 \
1949 end_spacing 2.10 \
1950 contact_size 1.18 \
1951 metal_surround 0.21 \
1952 top_metal_width 1.6 \
1953 top_metal_space 1.7 \
1954 ]
1955 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1956 return [sky130::cap_draw $drawdict]
1957}
1958
1959#endif (MIM)
1960
1961#----------------------------------------------------------------
1962# capacitor: Check device parameters for out-of-bounds values
1963#----------------------------------------------------------------
1964
1965proc sky130::cap_check {parameters} {
1966 # In case wmax and/or lmax are undefined
1967 set lmax 0
1968 set wmax 0
1969
1970 # Set a local variable for each parameter (e.g., $l, $w, etc.)
1971 foreach key [dict keys $parameters] {
1972 set $key [dict get $parameters $key]
1973 }
1974
1975 # Normalize distance units to microns
1976 set l [magic::spice2float $l]
1977 set l [magic::3digitpastdecimal $l]
1978 set w [magic::spice2float $w]
1979 set w [magic::3digitpastdecimal $w]
1980
1981 set val [magic::spice2float $val]
1982 set carea [magic::spice2float $carea]
1983 set cperi [magic::spice2float $cperi]
1984 set dc [magic::spice2float $dc]
1985
1986 if {$square == 1} {
1987 # Calculate L and W from value
1988 set a $carea
1989 set b [expr $cperi * 4]
1990 set c [expr -4 * $dc - $val]
1991 set l [expr ((-$b + sqrt($b * $b - (4 * $a * $c))) / (2 * $a))]
1992 dict set parameters l [magic::float2spice $l]
1993 set w $l
1994 dict set parameters w [magic::float2spice $w]
1995 } elseif {$l == 0} {
1996 # Calculate L from W and value
1997 set l [expr (($val + 4 * $dc - 2 * $w * $cperi) / ($w * $carea + 2 * $cperi))]
1998 dict set parameters l [magic::float2spice $l]
1999 } elseif {$w == 0} {
2000 # Calculate W from L and value
2001 set w [expr (($val + 4 * $dc - 2 * $l * $cperi) / ($l * $carea + 2 * $cperi))]
2002 dict set parameters w [magic::float2spice $w]
2003 }
2004 if {$w < $wmin} {
2005 puts stderr "Capacitor width must be >= $wmin"
2006 dict set parameters w $wmin
2007 set w $wmin
2008 }
2009 if {$l < $lmin} {
2010 puts stderr "Capacitor length must be >= $lmin"
2011 dict set parameters l $lmin
2012 set l $lmin
2013 }
2014 if {($wmax > 0) && ($w > $wmax)} {
2015 puts stderr "Capacitor width must be <= $wmax"
2016 dict set parameters w $wmax
2017 set w $wmax
2018 }
2019 if {($lmax > 0) && ($l > $lmax)} {
2020 puts stderr "Capacitor length must be <= $lmax"
2021 dict set parameters l $lmax
2022 set l $lmax
2023 }
2024 # Calculate value from L and W
2025 set cval [expr ($l * $w * $carea + 2 * ($l + $w) * $cperi - 4 * $dc)]
2026 dict set parameters val [magic::float2spice $cval]
2027 sky130::compute_ctot $parameters
2028
2029 return $parameters
2030}
2031
2032#ifdef MIM
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002033proc sky130::sky130_fd_pr__cap_mim_m3_1_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002034 return [sky130::cap_check $parameters]
2035}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002036proc sky130::sky130_fd_pr__cap_mim_m3_2_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002037 return [sky130::cap_check $parameters]
2038}
2039#endif (MIM)
2040
2041#----------------------------------------------------------------
2042# Drawn resistors
2043#----------------------------------------------------------------
2044
2045#----------------------------------------------------------------
2046# Resistor defaults:
2047#----------------------------------------------------------------
2048# User editable values:
2049#
2050# val Resistor value in ohms
2051# w Width
2052# l Length
2053# t Number of turns
2054# m Number devices in Y
2055# nx Number devices in X
2056# snake Use snake geometry (if not present, snake geometry not allowed)
2057# dummy Flag to mark addition of dummy resistor
2058#
2059# Non-user editable values:
2060#
2061# wmin Minimum allowed width
2062# lmin Minimum allowed length
2063# rho Resistance in ohms per square
2064# dw Delta width
2065# term Resistance per terminal
2066# sterm Additional resistance per terminal for snake geometry
2067#----------------------------------------------------------------
2068
2069#----------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002070# sky130_fd_pr__res_iso_pw: Specify all user-editable default values and those
2071# needed by sky130_fd_pr__res_iso_pw_check
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002072# NOTE: Work in progress. These values need to be corrected.
2073#----------------------------------------------------------------
2074
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002075proc sky130::sky130_fd_pr__res_iso_pw_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002076 return {w 2.650 l 26.50 m 1 nx 1 wmin 2.650 lmin 26.50 \
2077 rho 975 val 4875 dummy 0 dw 0.25 term 1.0 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002078 guard 1 endcov 100 full_metal 1}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002079}
2080
2081#----------------------------------------------------------------
2082# rpp1: Specify all user-editable default values and those
2083# needed by rp1_check
2084#----------------------------------------------------------------
2085
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002086proc sky130::sky130_fd_pr__res_generic_po_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002087 return {w 0.330 l 1.650 m 1 nx 1 wmin 0.330 lmin 1.650 \
2088 rho 48.2 val 241 dummy 0 dw 0.0 term 0.0 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002089 sterm 0.0 caplen 0.4 snake 0 guard 1 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002090 glc 1 grc 1 gtc 1 gbc 1 roverlap 0 endcov 100 \
2091 full_metal 1}
2092}
2093
2094# "term" is rho * 0.06, the distance between xpc edge and CONT.
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002095proc sky130::sky130_fd_pr__res_high_po_0p35_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002096 return {w 0.350 l 0.50 m 1 nx 1 wmin 0.350 lmin 0.50 \
2097 rho 319.8 val 456.857 dummy 0 dw 0.0 term 19.188 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002098 sterm 0.0 caplen 0 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002099 compatible {sky130_fd_pr__res_high_po_0p35 \
2100 sky130_fd_pr__res_high_po_0p69 sky130_fd_pr__res_high_po_1p41 \
2101 sky130_fd_pr__res_high_po_2p85 sky130_fd_pr__res_high_po_5p73} \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002102 full_metal 1 wmax 0.350}
2103}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002104proc sky130::sky130_fd_pr__res_high_po_0p69_defaults {} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002105 return {w 0.690 l 1.00 m 1 nx 1 wmin 0.690 lmin 0.50 \
2106 rho 319.8 val 463.480 dummy 0 dw 0.0 term 19.188 \
2107 sterm 0.0 caplen 0 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002108 compatible {sky130_fd_pr__res_high_po_0p35 \
2109 sky130_fd_pr__res_high_po_0p69 sky130_fd_pr__res_high_po_1p41 \
2110 sky130_fd_pr__res_high_po_2p85 sky130_fd_pr__res_high_po_5p73} \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002111 full_metal 1 wmax 0.690}
2112}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002113proc sky130::sky130_fd_pr__res_high_po_1p41_defaults {} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002114 return {w 1.410 l 2.00 m 1 nx 1 wmin 1.410 lmin 0.50 \
2115 rho 319.8 val 453.620 dummy 0 dw 0.0 term 19.188 \
2116 sterm 0.0 caplen 0 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002117 compatible {sky130_fd_pr__res_high_po_0p35 \
2118 sky130_fd_pr__res_high_po_0p69 sky130_fd_pr__res_high_po_1p41 \
2119 sky130_fd_pr__res_high_po_2p85 sky130_fd_pr__res_high_po_5p73} \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002120 full_metal 1 wmax 1.410}
2121}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002122proc sky130::sky130_fd_pr__res_high_po_2p85_defaults {} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002123 return {w 2.850 l 3.00 m 1 nx 1 wmin 2.850 lmin 0.50 \
2124 rho 319.8 val 336.630 dummy 0 dw 0.0 term 19.188 \
2125 sterm 0.0 caplen 0 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002126 compatible {sky130_fd_pr__res_high_po_0p35 \
2127 sky130_fd_pr__res_high_po_0p69 sky130_fd_pr__res_high_po_1p41 \
2128 sky130_fd_pr__res_high_po_2p85 sky130_fd_pr__res_high_po_5p73} \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002129 full_metal 1 wmax 2.850}
2130}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002131proc sky130::sky130_fd_pr__res_high_po_5p73_defaults {} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002132 return {w 5.730 l 6.00 m 1 nx 1 wmin 5.730 lmin 0.50 \
2133 rho 319.8 val 334.870 dummy 0 dw 0.0 term 19.188 \
2134 sterm 0.0 caplen 0 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002135 compatible {sky130_fd_pr__res_high_po_0p35 \
2136 sky130_fd_pr__res_high_po_0p69 sky130_fd_pr__res_high_po_1p41 \
2137 sky130_fd_pr__res_high_po_2p85 sky130_fd_pr__res_high_po_5p73} \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002138 full_metal 1 wmax 5.730}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002139}
2140
2141# "term" is rho * 0.06, the distance between xpc edge and CONT.
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002142proc sky130::sky130_fd_pr__res_xhigh_po_0p35_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002143 return {w 0.350 l 0.50 m 1 nx 1 wmin 0.350 lmin 0.50 \
2144 rho 2000 val 2875.143 dummy 0 dw 0.0 term 120 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002145 sterm 0.0 caplen 0 wmax 0.350 \
2146 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002147 compatible {sky130_fd_pr__res_xhigh_po_0p35 \
2148 sky130_fd_pr__res_xhigh_po_0p69 sky130_fd_pr__res_xhigh_po_1p41 \
2149 sky130_fd_pr__res_xhigh_po_2p85 sky130_fd_pr__res_xhigh_po_5p73} \
2150 full_metal 1}
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002151}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002152proc sky130::sky130_fd_pr__res_xhigh_po_0p69_defaults {} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002153 return {w 0.690 l 1.00 m 1 nx 1 wmin 0.690 lmin 0.50 \
2154 rho 2000 val 2898.600 dummy 0 dw 0.0 term 120 \
2155 sterm 0.0 caplen 0 wmax 0.690 \
2156 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002157 compatible {sky130_fd_pr__res_xhigh_po_0p35 \
2158 sky130_fd_pr__res_xhigh_po_0p69 sky130_fd_pr__res_xhigh_po_1p41 \
2159 sky130_fd_pr__res_xhigh_po_2p85 sky130_fd_pr__res_xhigh_po_5p73} \
2160 full_metal 1}
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002161}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002162proc sky130::sky130_fd_pr__res_xhigh_po_1p41_defaults {} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002163 return {w 1.410 l 2.00 m 1 nx 1 wmin 1.410 lmin 0.50 \
2164 rho 2000 val 2836.900 dummy 0 dw 0.0 term 120 \
2165 sterm 0.0 caplen 0 wmax 1.410 \
2166 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002167 compatible {sky130_fd_pr__res_xhigh_po_0p35 \
2168 sky130_fd_pr__res_xhigh_po_0p69 sky130_fd_pr__res_xhigh_po_1p41 \
2169 sky130_fd_pr__res_xhigh_po_2p85 sky130_fd_pr__res_xhigh_po_5p73} \
2170 full_metal 1}
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002171}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002172proc sky130::sky130_fd_pr__res_xhigh_po_2p85_defaults {} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002173 return {w 2.850 l 3.00 m 1 nx 1 wmin 2.850 lmin 0.50 \
2174 rho 2000 val 2105.300 dummy 0 dw 0.0 term 120 \
2175 sterm 0.0 caplen 0 wmax 2.850 \
2176 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002177 compatible {sky130_fd_pr__res_xhigh_po_0p35 \
2178 sky130_fd_pr__res_xhigh_po_0p69 sky130_fd_pr__res_xhigh_po_1p41 \
2179 sky130_fd_pr__res_xhigh_po_2p85 sky130_fd_pr__res_xhigh_po_5p73} \
2180 full_metal 1}
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002181}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002182proc sky130::sky130_fd_pr__res_xhigh_po_5p73_defaults {} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002183 return {w 5.730 l 6.00 m 1 nx 1 wmin 5.730 lmin 0.50 \
2184 rho 2000 val 2094.200 dummy 0 dw 0.0 term 120 \
2185 sterm 0.0 caplen 0 wmax 5.730 \
2186 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002187 compatible {sky130_fd_pr__res_xhigh_po_0p35 \
2188 sky130_fd_pr__res_xhigh_po_0p69 sky130_fd_pr__res_xhigh_po_1p41 \
2189 sky130_fd_pr__res_xhigh_po_2p85 sky130_fd_pr__res_xhigh_po_5p73} \
2190 full_metal 1}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002191}
2192
2193#----------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002194# sky130_fd_pr__res_generic_nd: Specify all user-editable default values and those
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002195# needed by rdn_check
2196#----------------------------------------------------------------
2197
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002198proc sky130::sky130_fd_pr__res_generic_nd_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002199 return {w 0.420 l 2.100 m 1 nx 1 wmin 0.42 lmin 2.10 \
2200 rho 120 val 600.0 dummy 0 dw 0.05 term 0.0 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002201 sterm 0.0 caplen 0.4 snake 0 guard 1 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002202 glc 1 grc 1 gtc 1 gbc 1 roverlap 0 endcov 100 \
2203 full_metal 1}
2204}
2205
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002206proc sky130::sky130_fd_pr__mrdn_hv_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002207 return {w 0.420 l 2.100 m 1 nx 1 wmin 0.42 lmin 2.10 \
2208 rho 120 val 600.0 dummy 0 dw 0.02 term 0.0 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002209 sterm 0.0 caplen 0.4 snake 0 guard 1 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002210 glc 1 grc 1 gtc 1 gbc 1 roverlap 0 endcov 100 \
2211 full_metal 1}
2212}
2213
2214#----------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002215# sky130_fd_pr__res_generic_pd: Specify all user-editable default values and those
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002216# needed by rdp_check
2217#----------------------------------------------------------------
2218
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002219proc sky130::sky130_fd_pr__res_generic_pd_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002220 return {w 0.420 l 2.100 m 1 nx 1 wmin 0.42 lmin 2.10 \
2221 rho 197 val 985.0 dummy 0 dw 0.02 term 0.0 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002222 sterm 0.0 caplen 0.60 snake 0 guard 1 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002223 glc 1 grc 1 gtc 1 gbc 1 roverlap 0 endcov 100 \
2224 full_metal 1}
2225}
2226
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002227proc sky130::sky130_fd_pr__mrdp_hv_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002228 return {w 0.420 l 2.100 m 1 nx 1 wmin 0.42 lmin 2.10 \
2229 rho 197 val 985.0 dummy 0 dw 0.02 term 0.0 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002230 sterm 0.0 caplen 0.60 snake 0 guard 1 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002231 glc 1 grc 1 gtc 1 gbc 1 roverlap 0 endcov 100 \
2232 full_metal 1}
2233}
2234
2235#----------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002236# sky130_fd_pr__res_generic_l1: Specify all user-editable default values and those needed
2237# by sky130_fd_pr__res_generic_l1_check
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002238#----------------------------------------------------------------
2239
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002240proc sky130::sky130_fd_pr__res_generic_l1_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002241 return {w 0.170 l 0.170 m 1 nx 1 wmin 0.17 lmin 0.17 \
2242 rho 12.8 val 12.8 dummy 0 dw 0.0 term 0.0 snake 0 \
2243 roverlap 0}
2244}
2245
2246#----------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002247# sky130_fd_pr__res_generic_m1: Specify all user-editable default values and those needed
2248# by sky130_fd_pr__res_generic_m1_check
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002249#----------------------------------------------------------------
2250
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002251proc sky130::sky130_fd_pr__res_generic_m1_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002252 return {w 0.140 l 0.140 m 1 nx 1 wmin 0.14 lmin 0.14 \
2253 rho 0.125 val 0.125 dummy 0 dw 0.0 term 0.0 \
2254 roverlap 0}
2255}
2256
2257#----------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002258# sky130_fd_pr__res_generic_m2: Specify all user-editable default values and those needed
2259# by sky130_fd_pr__res_generic_m2_check
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002260#----------------------------------------------------------------
2261
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002262proc sky130::sky130_fd_pr__res_generic_m2_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002263 return {w 0.140 l 0.140 m 1 nx 1 wmin 0.14 lmin 0.14 \
2264 rho 0.125 val 0.125 dummy 0 dw 0.0 term 0.0 \
2265 roverlap 0}
2266}
2267
2268#----------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002269# sky130_fd_pr__res_generic_m3: Specify all user-editable default values and those needed
2270# by sky130_fd_pr__res_generic_m3_check
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002271#----------------------------------------------------------------
2272
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002273proc sky130::sky130_fd_pr__res_generic_m3_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002274 return {w 0.300 l 0.300 m 1 nx 1 wmin 0.30 lmin 0.30 \
2275 rho 0.047 val 0.047 dummy 0 dw 0.0 term 0.0 \
2276 roverlap 0}
2277}
2278
2279#----------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002280# Additional entries for sky130_fd_pr__res_generic_m4 and sky130_fd_pr__res_generic_m5, depending on the
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002281# back-end metal stack.
2282#----------------------------------------------------------------
2283
2284#ifdef METAL5
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002285proc sky130::sky130_fd_pr__res_generic_m4_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002286 return {w 0.300 l 0.300 m 1 nx 1 wmin 0.30 lmin 0.30 \
2287 rho 0.047 val 0.047 dummy 0 dw 0.0 term 0.0 \
2288 roverlap 0}
2289}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002290proc sky130::sky130_fd_pr__res_generic_m5_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002291 return {w 1.600 l 1.600 m 1 nx 1 wmin 1.60 lmin 1.60 \
2292 rho 0.029 val 0.029 dummy 0 dw 0.0 term 0.0 \
2293 roverlap 0}
2294}
2295#endif (METAL5)
2296
2297#----------------------------------------------------------------
2298# resistor: Conversion from SPICE netlist parameters to toolkit
2299#----------------------------------------------------------------
2300
2301proc sky130::res_convert {parameters} {
2302 set pdkparams [dict create]
2303 dict for {key value} $parameters {
2304 switch -nocase $key {
2305 l -
2306 w {
2307 # Length and width are converted to units of microns
2308 set value [magic::spice2float $value]
2309 # set value [expr $value * 1e6]
2310 set value [magic::3digitpastdecimal $value]
2311 dict set pdkparams [string tolower $key] $value
2312 }
2313 }
2314 }
2315 return $pdkparams
2316}
2317
2318#----------------------------------------------------------------
2319
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002320proc sky130::sky130_fd_pr__res_iso_pw_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002321 return [sky130::res_convert $parameters]
2322}
2323
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002324proc sky130::sky130_fd_pr__res_generic_po_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002325 return [sky130::res_convert $parameters]
2326}
2327
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002328proc sky130::sky130_fd_pr__res_high_po_0p35_convert {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002329 return [sky130::res_convert $parameters]
2330}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002331proc sky130::sky130_fd_pr__res_high_po_0p69_convert {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002332 return [sky130::res_convert $parameters]
2333}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002334proc sky130::sky130_fd_pr__res_high_po_1p41_convert {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002335 return [sky130::res_convert $parameters]
2336}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002337proc sky130::sky130_fd_pr__res_high_po_2p85_convert {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002338 return [sky130::res_convert $parameters]
2339}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002340proc sky130::sky130_fd_pr__res_high_po_5p73_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002341 return [sky130::res_convert $parameters]
2342}
2343
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002344proc sky130::sky130_fd_pr__res_xhigh_po_0p35_convert {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002345 return [sky130::res_convert $parameters]
2346}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002347proc sky130::sky130_fd_pr__res_xhigh_po_0p69_convert {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002348 return [sky130::res_convert $parameters]
2349}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002350proc sky130::sky130_fd_pr__res_xhigh_po_1p41_convert {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002351 return [sky130::res_convert $parameters]
2352}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002353proc sky130::sky130_fd_pr__res_xhigh_po_2p85_convert {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002354 return [sky130::res_convert $parameters]
2355}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002356proc sky130::sky130_fd_pr__res_xhigh_po_5p73_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002357 return [sky130::res_convert $parameters]
2358}
2359
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002360proc sky130::sky130_fd_pr__res_generic_nd_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002361 return [sky130::res_convert $parameters]
2362}
2363
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002364proc sky130::sky130_fd_pr__res_generic_pd_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002365 return [sky130::res_convert $parameters]
2366}
2367
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002368proc sky130::sky130_fd_pr__mrdn_hv_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002369 return [sky130::res_convert $parameters]
2370}
2371
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002372proc sky130::sky130_fd_pr__mrdp_hv_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002373 return [sky130::res_convert $parameters]
2374}
2375
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002376proc sky130::sky130_fd_pr__res_generic_l1_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002377 return [sky130::res_convert $parameters]
2378}
2379
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002380proc sky130::sky130_fd_pr__res_generic_m1_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002381 return [sky130::res_convert $parameters]
2382}
2383
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002384proc sky130::sky130_fd_pr__res_generic_m2_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002385 return [sky130::res_convert $parameters]
2386}
2387
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002388proc sky130::sky130_fd_pr__res_generic_m3_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002389 return [sky130::res_convert $parameters]
2390}
2391
2392#ifdef METAL5
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002393proc sky130::sky130_fd_pr__res_generic_m4_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002394 return [sky130::res_convert $parameters]
2395}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002396proc sky130::sky130_fd_pr__res_generic_m5_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002397 return [sky130::res_convert $parameters]
2398}
2399#endif (METAL5)
2400
2401#----------------------------------------------------------------
2402# resistor: Interactively specifies the fixed layout parameters
2403#----------------------------------------------------------------
2404
2405proc sky130::res_dialog {device parameters} {
2406 # Editable fields: w, l, t, nx, m, val
2407 # Checked fields:
2408
2409 magic::add_entry val "Value (ohms)" $parameters
2410 if {[dict exists $parameters snake]} {
2411 sky130::compute_ltot $parameters
2412 magic::add_message ltot "Total length (um)" $parameters
2413 }
2414 magic::add_entry l "Length (um)" $parameters
2415 magic::add_entry w "Width (um)" $parameters
2416 magic::add_entry nx "X Repeat" $parameters
2417 magic::add_entry m "Y Repeat" $parameters
2418 if {[dict exists $parameters endcov]} {
2419 magic::add_entry endcov "End contact coverage (%)" $parameters
2420 }
2421
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002422 if {[dict exists $parameters compatible]} {
2423 set sellist [dict get $parameters compatible]
2424 magic::add_selectlist gencell "Device type" $sellist $parameters $device
2425 }
2426
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002427 # magic::add_checkbox dummy "Add dummy" $parameters
2428
2429 if {[dict exists $parameters snake]} {
2430 magic::add_checkbox snake "Use snake geometry" $parameters
2431 }
2432 if {[dict exists $parameters roverlap]} {
2433 if {[dict exists $parameters endcov]} {
2434 magic::add_checkbox roverlap "Overlap at end contact" $parameters
2435 } else {
2436 magic::add_checkbox roverlap "Overlap at ends" $parameters
2437 }
2438 }
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002439 if {[dict exists $parameters guard]} {
2440 magic::add_checkbox guard "Add guard ring" $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002441
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002442 if {[dict exists $parameters full_metal]} {
2443 magic::add_checkbox full_metal "Full metal guard ring" $parameters
2444 }
2445 if {[dict exists $parameters glc]} {
2446 magic::add_checkbox glc "Add left guard ring contact" $parameters
2447 }
2448 if {[dict exists $parameters grc]} {
2449 magic::add_checkbox grc "Add right guard ring contact" $parameters
2450 }
2451 if {[dict exists $parameters gtc]} {
2452 magic::add_checkbox gtc "Add top guard ring contact" $parameters
2453 }
2454 if {[dict exists $parameters gbc]} {
2455 magic::add_checkbox gbc "Add bottom guard ring contact" $parameters
2456 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002457 }
2458
2459 if {[dict exists $parameters snake]} {
2460 magic::add_dependency sky130::res_recalc $device sky130 l w val nx snake
2461 } else {
2462 magic::add_dependency sky130::res_recalc $device sky130 l w val nx
2463 }
2464}
2465
2466#----------------------------------------------------------------
2467
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002468proc sky130::sky130_fd_pr__res_iso_pw_dialog {parameters} {
2469 sky130::res_dialog sky130_fd_pr__res_iso_pw $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002470}
2471
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002472proc sky130::sky130_fd_pr__res_generic_po_dialog {parameters} {
2473 sky130::res_dialog sky130_fd_pr__res_generic_po $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002474}
2475
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002476proc sky130::sky130_fd_pr__res_high_po_0p35_dialog {parameters} {
2477 sky130::res_dialog sky130_fd_pr__res_high_po_0p35 $parameters
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002478}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002479proc sky130::sky130_fd_pr__res_high_po_0p69_dialog {parameters} {
2480 sky130::res_dialog sky130_fd_pr__res_high_po_0p69 $parameters
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002481}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002482proc sky130::sky130_fd_pr__res_high_po_1p41_dialog {parameters} {
2483 sky130::res_dialog sky130_fd_pr__res_high_po_1p41 $parameters
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002484}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002485proc sky130::sky130_fd_pr__res_high_po_2p85_dialog {parameters} {
2486 sky130::res_dialog sky130_fd_pr__res_high_po_2p85 $parameters
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002487}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002488proc sky130::sky130_fd_pr__res_high_po_5p73_dialog {parameters} {
2489 sky130::res_dialog sky130_fd_pr__res_high_po_5p73 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002490}
2491
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002492proc sky130::sky130_fd_pr__res_xhigh_po_0p35_dialog {parameters} {
2493 sky130::res_dialog sky130_fd_pr__res_xhigh_po_0p35 $parameters
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002494}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002495proc sky130::sky130_fd_pr__res_xhigh_po_0p69_dialog {parameters} {
2496 sky130::res_dialog sky130_fd_pr__res_xhigh_po_0p69 $parameters
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002497}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002498proc sky130::sky130_fd_pr__res_xhigh_po_1p41_dialog {parameters} {
2499 sky130::res_dialog sky130_fd_pr__res_xhigh_po_1p41 $parameters
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002500}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002501proc sky130::sky130_fd_pr__res_xhigh_po_2p85_dialog {parameters} {
2502 sky130::res_dialog sky130_fd_pr__res_xhigh_po_2p85 $parameters
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002503}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002504proc sky130::sky130_fd_pr__res_xhigh_po_5p73_dialog {parameters} {
2505 sky130::res_dialog sky130_fd_pr__res_xhigh_po_5p73 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002506}
2507
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002508proc sky130::sky130_fd_pr__res_generic_nd_dialog {parameters} {
2509 sky130::res_dialog sky130_fd_pr__res_generic_nd $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002510}
2511
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002512proc sky130::sky130_fd_pr__res_generic_pd_dialog {parameters} {
2513 sky130::res_dialog sky130_fd_pr__res_generic_pd $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002514}
2515
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002516proc sky130::sky130_fd_pr__mrdn_hv_dialog {parameters} {
2517 sky130::res_dialog sky130_fd_pr__mrdn_hv $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002518}
2519
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002520proc sky130::sky130_fd_pr__mrdp_hv_dialog {parameters} {
2521 sky130::res_dialog sky130_fd_pr__mrdp_hv $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002522}
2523
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002524proc sky130::sky130_fd_pr__res_generic_l1_dialog {parameters} {
2525 sky130::res_dialog sky130_fd_pr__res_generic_l1 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002526}
2527
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002528proc sky130::sky130_fd_pr__res_generic_m1_dialog {parameters} {
2529 sky130::res_dialog sky130_fd_pr__res_generic_m1 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002530}
2531
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002532proc sky130::sky130_fd_pr__res_generic_m2_dialog {parameters} {
2533 sky130::res_dialog sky130_fd_pr__res_generic_m2 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002534}
2535
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002536proc sky130::sky130_fd_pr__res_generic_m3_dialog {parameters} {
2537 sky130::res_dialog sky130_fd_pr__res_generic_m3 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002538}
2539
2540#ifdef METAL5
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002541proc sky130::sky130_fd_pr__res_generic_m4_dialog {parameters} {
2542 sky130::res_dialog sky130_fd_pr__res_generic_m4 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002543}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002544proc sky130::sky130_fd_pr__res_generic_m5_dialog {parameters} {
2545 sky130::res_dialog sky130_fd_pr__res_generic_m5 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002546}
2547#endif (METAL5)
2548
2549#----------------------------------------------------------------
2550# Resistor: Draw a single device in straight geometry
2551#----------------------------------------------------------------
2552
2553proc sky130::res_device {parameters} {
2554 # Epsilon for avoiding round-off errors
2555 set eps 0.0005
2556
2557 # Set local default values if they are not in parameters
2558 set endcov 0 ;# percent coverage of end contacts
2559 set roverlap 0 ;# overlap resistors at end contacts
2560 set well_res_overlap 0 ;# not a well resistor
2561 set end_contact_type "" ;# no contacts for metal resistors
2562 set end_overlap_cont 0 ;# additional end overlap on sides
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002563 set res_idtype none
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002564
2565 # Set a local variable for each parameter (e.g., $l, $w, etc.)
2566 foreach key [dict keys $parameters] {
2567 set $key [dict get $parameters $key]
2568 }
2569
2570 if {![dict exists $parameters end_contact_size]} {
2571 set end_contact_size $contact_size
2572 }
2573
2574 # Draw the resistor and endcaps
2575 pushbox
2576 box size 0 0
2577 pushbox
2578 set hw [/ $w 2.0]
2579 set hl [/ $l 2.0]
2580 box grow n ${hl}um
2581 box grow s ${hl}um
2582 box grow e ${hw}um
2583 box grow w ${hw}um
2584
2585 pushbox
2586 box grow n ${res_to_endcont}um
2587 box grow s ${res_to_endcont}um
2588 if {$well_res_overlap > 0} {
2589 set well_extend [+ ${well_res_overlap} [/ ${end_contact_size} 2.0] ${end_surround}]
2590 box grow n ${well_extend}um
2591 box grow s ${well_extend}um
2592 paint ${well_res_type}
2593 } else {
2594 paint ${end_type}
2595 }
2596 set cext [sky130::getbox]
2597 popbox
2598
2599 if {$well_res_overlap > 0} {
2600 erase ${well_res_type}
2601 } else {
2602 erase ${end_type}
2603 }
2604 paint ${res_type}
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002605 if {"$res_idtype" != "none"} {
2606 box grow c 2
2607 paint ${res_idtype}
2608 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002609 popbox
2610
2611 # Reduce contact sizes by (end type) surround so that
2612 # the contact area edges match the device type width.
2613 # (Minimum dimensions will be enforced by the contact drawing routine)
2614 set epl [- ${w} [* ${end_surround} 2]] ;# end contact width
2615
2616 # Reduce end material size for well resistor types
2617 if {$well_res_overlap > 0} {
2618 set epl [- ${epl} [* ${well_res_overlap} 2]]
2619 }
2620
2621 # Reduce by coverage percentage unless overlapping at contacts
2622 if {(${roverlap} == 0) && (${endcov} > 0)} {
2623 set cpl [* ${epl} [/ ${endcov} 100.0]]
2624 } else {
2625 set cpl $epl
2626 }
2627
2628 # Ensure additional overlap of diffusion contact if required
2629 set dov [* ${end_overlap_cont} 2]
2630 if {[- ${epl} ${cpl}] < $dov} {
2631 set cpl [- ${epl} $dov] ;# additional end contact width
2632 }
2633
2634 set hepl [+ [/ ${epl} 2.0] ${end_surround}]
2635 set hesz [/ ${end_contact_size} 2.0]
2636
2637 # LV substrate diffusion types have a different surround requirement
2638 set lv_sub_types {"psd" "nsd"}
2639 if {[lsearch $lv_sub_types $end_type] < 0} {
2640 set hesz [+ ${hesz} ${end_surround}]
2641 }
2642
2643 # Top end material & contact
2644 pushbox
2645 box move n ${hl}um
2646 box move n ${res_to_endcont}um
2647
2648 pushbox
2649 box size 0 0
2650 box grow n ${hesz}um
2651 box grow s ${hesz}um
2652 box grow e ${hepl}um
2653 box grow w ${hepl}um
2654 paint ${end_type}
2655 set cext [sky130::unionbox $cext [sky130::getbox]]
2656 popbox
2657
2658 if {${end_contact_type} != ""} {
2659 set cext [sky130::unionbox $cext [sky130::draw_contact ${cpl} 0 \
2660 ${end_surround} ${metal_surround} ${end_contact_size} \
2661 ${end_type} ${end_contact_type} li horz]]
2662 }
2663 popbox
2664
2665 # Bottom end material & contact
2666 pushbox
2667 box move s ${hl}um
2668 box move s ${res_to_endcont}um
2669
2670 pushbox
2671 box size 0 0
2672 box grow n ${hesz}um
2673 box grow s ${hesz}um
2674 box grow e ${hepl}um
2675 box grow w ${hepl}um
2676 paint ${end_type}
2677 set cext [sky130::unionbox $cext [sky130::getbox]]
2678 popbox
2679
2680 if {${end_contact_type} != ""} {
2681 set cext [sky130::unionbox $cext [sky130::draw_contact ${cpl} 0 \
2682 ${end_surround} ${metal_surround} ${end_contact_size} \
2683 ${end_type} ${end_contact_type} li horz]]
2684 }
2685 popbox
2686
2687 popbox
2688 return $cext
2689}
2690
2691#----------------------------------------------------------------
2692# Resistor: Draw a single device in snake geometry
2693#----------------------------------------------------------------
2694
2695proc sky130::res_snake_device {nf parameters} {
2696 # nf is the number of fingers of the snake geometry
2697
2698 # Epsilon for avoiding round-off errors
2699 set eps 0.0005
2700
2701 # Set local default values if they are not in parameters
2702 set endcov 100 ;# percent coverage of end contacts
2703 set well_res_overlap 0 ;# not a well resistor
2704 set end_contact_type "" ;# no contacts for metal resistors
2705 set mask_clearance 0 ;# additional length to clear mask
2706
2707 # Set a local variable for each parameter (e.g., $l, $w, etc.)
2708 foreach key [dict keys $parameters] {
2709 set $key [dict get $parameters $key]
2710 }
2711
2712 if {![dict exists $parameters end_contact_size]} {
2713 set end_contact_size $contact_size
2714 }
2715
2716 # Compute half width and length
2717 set hw [/ $w 2.0]
2718 set hl [/ $l 2.0]
2719
2720 # Reduce contact sizes by (end type) surround so that
2721 # the contact area edges match the device type width.
2722 # (Minimum dimensions will be enforced by the contact drawing routine)
2723 set epl [- ${w} [* ${end_surround} 2]] ;# end contact width
2724
2725 # Reduce contact size for well resistor types
2726 if {$well_res_overlap > 0} {
2727 set epl [- ${epl} [* ${well_res_overlap} 2]]
2728 }
2729
2730 # Reduce contact part of end by coverage percentage
2731 if {${endcov} > 0} {
2732 set cpl [* ${epl} [/ ${endcov} 100.0]]
2733 } else {
2734 set cpl $epl
2735 }
2736
2737 set hepl [+ [/ ${epl} 2.0] ${end_surround}]
2738 set hesz [+ [/ ${end_contact_size} 2.0] ${end_surround}]
2739
2740 pushbox
2741 box size 0 0 ;# Position is taken from caller
2742
2743 # Front end contact (always bottom)
2744 pushbox
2745 box move s ${hl}um
2746 pushbox
2747 box move s ${mask_clearance}um
2748 box move s ${res_to_endcont}um
2749
2750 pushbox
2751 box size 0 0
2752 box grow n ${hesz}um
2753 box grow s ${hesz}um
2754 box grow e ${hepl}um
2755 box grow w ${hepl}um
2756 paint ${end_type}
2757 set cext [sky130::getbox]
2758 popbox
2759
2760 if {${end_contact_type} != ""} {
2761 set cext [sky130::draw_contact ${cpl} 0 \
2762 ${end_surround} ${metal_surround} ${end_contact_size} \
2763 ${end_type} ${end_contact_type} li horz]
2764 }
2765 popbox
2766
2767 # Draw portion between resistor end and contact.
2768 box grow e ${hw}um
2769 box grow w ${hw}um
2770 pushbox
2771 box grow s ${mask_clearance}um
2772 paint ${res_type}
2773 popbox
2774 box move s ${mask_clearance}um
2775 box grow s ${res_to_endcont}um
2776 if {$well_res_overlap > 0} {
2777 set well_extend [+ ${well_res_overlap} [/ ${end_contact_size} 2.0] ${end_surround}]
2778 box grow s ${well_extend}um
2779 paint ${well_res_type}
2780 } else {
2781 paint ${end_type}
2782 }
2783 set cext [sky130::unionbox $cext [sky130::getbox]]
2784 popbox
2785
2786 # Draw the resistor and endcaps
2787 pushbox
2788 box grow n ${hl}um
2789 box grow s ${hl}um
2790 box grow e ${hw}um
2791 box grow w ${hw}um
2792
2793 # Capture these extents in the bounding box in case both contacts
2794 # are on one side.
2795 set cext [sky130::unionbox $cext [sky130::getbox]]
2796
2797 set deltax [+ ${res_spacing} ${w}]
2798 set deltay [- ${l} ${w}]
2799 for {set i 0} {$i < [- $nf 1]} {incr i} {
2800 paint ${res_type}
2801 pushbox
2802 if {[% $i 2] == 0} {
2803 box move n ${deltay}um
2804 }
2805 box height ${w}um
2806 box width ${deltax}um
2807 paint ${res_type}
2808 popbox
2809 box move e ${deltax}um
2810 }
2811 paint ${res_type}
2812 # Capture these extents in the bounding box
2813 set cext [sky130::unionbox $cext [sky130::getbox]]
2814 popbox
2815
2816 # Move box to last finger
2817 set lastf [* [- $nf 1] $deltax]
2818 box move e ${lastf}um
2819
2820 # Back-end contact (top or bottom, depending if odd or even turns)
2821 pushbox
2822
2823 if {[% $nf 2] == 1} {
2824 set dir n
2825 } else {
2826 set dir s
2827 }
2828 box move $dir ${hl}um
2829 pushbox
2830 box move $dir ${mask_clearance}um
2831 box move $dir ${res_to_endcont}um
2832
2833 pushbox
2834 box size 0 0
2835 box grow n ${hesz}um
2836 box grow s ${hesz}um
2837 box grow e ${hepl}um
2838 box grow w ${hepl}um
2839 paint ${end_type}
2840 set cext [sky130::unionbox $cext [sky130::getbox]]
2841 popbox
2842
2843 if {${end_contact_type} != ""} {
2844 set cext [sky130::unionbox $cext [sky130::draw_contact ${cpl} 0 \
2845 ${end_surround} ${metal_surround} ${end_contact_size} \
2846 ${end_type} ${end_contact_type} li horz]]
2847 }
2848 popbox
2849 # Draw portion between resistor end and contact.
2850 box grow e ${hw}um
2851 box grow w ${hw}um
2852 pushbox
2853 box grow $dir ${mask_clearance}um
2854 paint ${res_type}
2855 popbox
2856 box move $dir ${mask_clearance}um
2857 box grow $dir ${res_to_endcont}um
2858
2859 if {$well_res_overlap > 0} {
2860 set well_extend [+ ${well_res_overlap} [/ ${end_contact_size} 2.0] ${end_surround}]
2861 box grow $dir ${well_extend}um
2862 paint ${well_res_type}
2863 } else {
2864 paint ${end_type}
2865 }
2866 popbox
2867
2868 popbox
2869 return $cext
2870}
2871
2872#----------------------------------------------------------------
2873# Resistor: Draw the tiled device
2874#----------------------------------------------------------------
2875
2876proc sky130::res_draw {parameters} {
2877 tech unlock *
2878 set savesnap [snap]
2879 snap internal
2880
2881 # Set defaults if they are not in parameters
2882 set snake 0 ;# some resistors don't allow snake geometry
2883 set roverlap 0 ;# overlap resistors at contacts
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002884 set guard 0 ;# draw a guard ring
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002885 set plus_diff_type nsd ;# guard ring diffusion type
2886 set overlap_compress 0 ;# special Y distance compression
2887 set well_res_overlap 0 ;# additional well extension behind contact
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002888 set res_diff_spacing 0 ;# spacing from resistor to diffusion
2889 set res_idtype none
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002890
2891 # Set a local variable for each parameter (e.g., $l, $w, etc.)
2892 foreach key [dict keys $parameters] {
2893 set $key [dict get $parameters $key]
2894 }
2895
2896 # For devices where inter-device space is smaller than device-to-guard ring
2897 if {![dict exists $parameters end_to_end_space]} {
2898 set end_to_end_space $end_spacing
2899 }
2900
2901 if {![dict exists $parameters end_contact_size]} {
2902 set end_contact_size $contact_size
2903 }
2904
2905 # Normalize distance units to microns
2906 set w [magic::spice2float $w]
2907 set l [magic::spice2float $l]
2908
2909 pushbox
2910 box values 0 0 0 0
2911
2912 # Determine the base device dimensions by drawing one device
2913 # while all layers are locked (nothing drawn). This allows the
2914 # base drawing routine to do complicated geometry without having
2915 # to duplicate it here with calculations.
2916
2917 tech lock *
2918 set nf $nx
2919 if {($snake == 1) && ($nx == 1)} {set snake 0}
2920 if {$snake == 1} {
2921 set bbox [sky130::res_snake_device $nf $parameters]
2922 set nx 1
2923 } else {
2924 set bbox [sky130::res_device $parameters]
2925 }
2926 # puts stdout "Diagnostic: Device bounding box e $bbox (um)"
2927 tech unlock *
2928
2929 set fw [- [lindex $bbox 2] [lindex $bbox 0]]
2930 set fh [- [lindex $bbox 3] [lindex $bbox 1]]
2931 set lw [+ [lindex $bbox 2] [lindex $bbox 0]]
2932 set lh [+ [lindex $bbox 3] [lindex $bbox 1]]
2933
2934 # Determine tile width and height (depends on overlap)
2935 # Snake resistors cannot overlap.
2936 # However, snake resistors with an odd number of fingers can
2937 # compress the space if overlap_compress is defined
2938
2939 if {($roverlap == 1) && ($snake == 1) && ([% $nf 2] == 1) && ($m > 1)} {
2940 set dy [- $fh $overlap_compress]
2941 } elseif {($roverlap == 0) || ($snake == 1)} {
2942 set dy [+ $fh $end_to_end_space]
2943 } else {
2944 # overlap poly
2945 set dy [- $fh [+ [* [+ $end_surround $well_res_overlap] 2.0] $end_contact_size]]
2946 }
2947 set dx [+ $fw $res_spacing]
2948
2949 # Determine core width and height
2950 set corex [+ [* [- $nx 1] $dx] $fw]
2951 set corey [+ [* [- $m 1] $dy] $fh]
2952 set corellx [/ [+ [- $corex $fw] $lw] 2.0]
2953 set corelly [/ [+ [- $corey $fh] $lh] 2.0]
2954
2955 set lv_sub_types {"psd" "nsd"}
2956 if {[lsearch $lv_sub_types $plus_diff_type] >= 0} {
2957 set guard_diff_surround 0
2958 } else {
2959 set guard_diff_surround ${diff_surround}
2960 }
2961
2962 if {$guard != 0} {
2963 # Calculate guard ring size (measured to contact center)
2964 set gx [+ $corex [* 2.0 [+ $res_diff_spacing $guard_diff_surround]] $contact_size]
2965 set gy [+ $corey [* 2.0 [+ $end_spacing $guard_diff_surround]] $contact_size]
2966
2967 # Draw the guard ring first, because well resistors are on the substrate plane
2968 sky130::guard_ring $gx $gy $parameters
2969 }
2970
2971 pushbox
2972 box move w ${corellx}um
2973 box move s ${corelly}um
2974 # puts "Device position at = [sky130::getbox]"
2975 for {set xp 0} {$xp < $nx} {incr xp} {
2976 pushbox
2977 for {set yp 0} {$yp < $m} {incr yp} {
2978 if {$snake == 1} {
2979 sky130::res_snake_device $nf $parameters
2980 } else {
2981 sky130::res_device $parameters
2982 }
2983 box move n ${dy}um
2984 }
2985 popbox
2986 box move e ${dx}um
2987 }
2988 popbox
2989 popbox
2990
2991 snap $savesnap
2992 tech revert
2993}
2994
2995#----------------------------------------------------------------
2996
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002997proc sky130::sky130_fd_pr__res_generic_po_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002998
2999 # Set a local variable for each rule in ruleset
3000 foreach key [dict keys $sky130::ruleset] {
3001 set $key [dict get $sky130::ruleset $key]
3002 }
3003
3004 set newdict [dict create \
3005 res_type npres \
3006 end_type poly \
3007 end_contact_type pc \
3008 plus_diff_type nsd \
3009 plus_contact_type nsc \
3010 sub_type nwell \
3011 end_surround $poly_surround \
3012 end_spacing 0.48 \
3013 end_to_end_space 0.52 \
3014 res_to_endcont $res_to_cont \
3015 res_spacing $poly_spacing \
3016 res_diff_spacing 0.48 \
3017 mask_clearance 0.52 \
3018 overlap_compress 0.36 \
3019 ]
3020 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3021 return [sky130::res_draw $drawdict]
3022}
3023
3024#----------------------------------------------------------------
3025
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003026proc sky130::sky130_fd_pr__res_high_po_0p35_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003027
3028 # Set a local variable for each rule in ruleset
3029 foreach key [dict keys $sky130::ruleset] {
3030 set $key [dict get $sky130::ruleset $key]
3031 }
3032
3033 set newdict [dict create \
3034 res_type ppres \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003035 res_idtype res0p35 \
3036 end_type xpc \
3037 end_contact_type xpc \
3038 end_contact_size 0 \
3039 plus_diff_type psd \
3040 plus_contact_type psc \
3041 sub_type psub \
3042 end_surround $poly_surround \
3043 end_spacing 0.48 \
3044 end_to_end_space 0.52 \
3045 end_contact_size 0.19 \
3046 res_to_endcont 1.985 \
3047 res_spacing 1.24 \
3048 res_diff_spacing 0.48 \
3049 mask_clearance 0.52 \
3050 overlap_compress 0.36 \
3051 ]
3052 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3053 return [sky130::res_draw $drawdict]
3054}
3055
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003056proc sky130::sky130_fd_pr__res_high_po_0p69_draw {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003057
3058 # Set a local variable for each rule in ruleset
3059 foreach key [dict keys $sky130::ruleset] {
3060 set $key [dict get $sky130::ruleset $key]
3061 }
3062
3063 set newdict [dict create \
3064 res_type ppres \
3065 res_idtype res0p69 \
3066 end_type xpc \
3067 end_contact_type xpc \
3068 end_contact_size 0 \
3069 plus_diff_type psd \
3070 plus_contact_type psc \
3071 sub_type psub \
3072 end_surround $poly_surround \
3073 end_spacing 0.48 \
3074 end_to_end_space 0.52 \
3075 end_contact_size 0.19 \
3076 res_to_endcont 1.985 \
3077 res_spacing 1.24 \
3078 res_diff_spacing 0.48 \
3079 mask_clearance 0.52 \
3080 overlap_compress 0.36 \
3081 ]
3082 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3083 return [sky130::res_draw $drawdict]
3084}
3085
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003086proc sky130::sky130_fd_pr__res_high_po_1p41_draw {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003087
3088 # Set a local variable for each rule in ruleset
3089 foreach key [dict keys $sky130::ruleset] {
3090 set $key [dict get $sky130::ruleset $key]
3091 }
3092
3093 set newdict [dict create \
3094 res_type ppres \
3095 res_idtype res1p41 \
3096 end_type xpc \
3097 end_contact_type xpc \
3098 end_contact_size 0 \
3099 plus_diff_type psd \
3100 plus_contact_type psc \
3101 sub_type psub \
3102 end_surround $poly_surround \
3103 end_spacing 0.48 \
3104 end_to_end_space 0.52 \
3105 end_contact_size 0.19 \
3106 res_to_endcont 1.985 \
3107 res_spacing 1.24 \
3108 res_diff_spacing 0.48 \
3109 mask_clearance 0.52 \
3110 overlap_compress 0.36 \
3111 ]
3112 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3113 return [sky130::res_draw $drawdict]
3114}
3115
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003116proc sky130::sky130_fd_pr__res_high_po_2p85_draw {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003117
3118 # Set a local variable for each rule in ruleset
3119 foreach key [dict keys $sky130::ruleset] {
3120 set $key [dict get $sky130::ruleset $key]
3121 }
3122
3123 set newdict [dict create \
3124 res_type ppres \
3125 res_idtype res2p85 \
3126 end_type xpc \
3127 end_contact_type xpc \
3128 end_contact_size 0 \
3129 plus_diff_type psd \
3130 plus_contact_type psc \
3131 sub_type psub \
3132 end_surround $poly_surround \
3133 end_spacing 0.48 \
3134 end_to_end_space 0.52 \
3135 end_contact_size 0.19 \
3136 res_to_endcont 1.985 \
3137 res_spacing 1.24 \
3138 res_diff_spacing 0.48 \
3139 mask_clearance 0.52 \
3140 overlap_compress 0.36 \
3141 ]
3142 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3143 return [sky130::res_draw $drawdict]
3144}
3145
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003146proc sky130::sky130_fd_pr__res_high_po_5p73_draw {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003147
3148 # Set a local variable for each rule in ruleset
3149 foreach key [dict keys $sky130::ruleset] {
3150 set $key [dict get $sky130::ruleset $key]
3151 }
3152
3153 set newdict [dict create \
3154 res_type ppres \
3155 res_idtype res5p73 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003156 end_type xpc \
3157 end_contact_type xpc \
3158 end_contact_size 0 \
3159 plus_diff_type psd \
3160 plus_contact_type psc \
3161 sub_type psub \
3162 end_surround $poly_surround \
3163 end_spacing 0.48 \
3164 end_to_end_space 0.52 \
3165 end_contact_size 0.19 \
3166 res_to_endcont 1.985 \
3167 res_spacing 1.24 \
3168 res_diff_spacing 0.48 \
3169 mask_clearance 0.52 \
3170 overlap_compress 0.36 \
3171 ]
3172 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3173 return [sky130::res_draw $drawdict]
3174}
3175
3176#----------------------------------------------------------------
3177
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003178proc sky130::sky130_fd_pr__res_xhigh_po_0p35_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003179
3180 # Set a local variable for each rule in ruleset
3181 foreach key [dict keys $sky130::ruleset] {
3182 set $key [dict get $sky130::ruleset $key]
3183 }
3184
3185 set newdict [dict create \
3186 res_type xpres \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003187 res_idtype res0p35 \
3188 end_type xpc \
3189 end_contact_type xpc \
3190 end_contact_size 0 \
3191 plus_diff_type psd \
3192 plus_contact_type psc \
3193 sub_type psub \
3194 end_surround $poly_surround \
3195 end_spacing 0.48 \
3196 end_to_end_space 0.52 \
3197 end_contact_size 0.19 \
3198 res_to_endcont 1.985 \
3199 res_spacing 1.24 \
3200 res_diff_spacing 0.48 \
3201 mask_clearance 0.52 \
3202 overlap_compress 0.36 \
3203 ]
3204 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3205 return [sky130::res_draw $drawdict]
3206}
3207
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003208proc sky130::sky130_fd_pr__res_xhigh_po_0p69_draw {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003209
3210 # Set a local variable for each rule in ruleset
3211 foreach key [dict keys $sky130::ruleset] {
3212 set $key [dict get $sky130::ruleset $key]
3213 }
3214
3215 set newdict [dict create \
3216 res_type xpres \
3217 res_idtype res0p69 \
3218 end_type xpc \
3219 end_contact_type xpc \
3220 end_contact_size 0 \
3221 plus_diff_type psd \
3222 plus_contact_type psc \
3223 sub_type psub \
3224 end_surround $poly_surround \
3225 end_spacing 0.48 \
3226 end_to_end_space 0.52 \
3227 end_contact_size 0.19 \
3228 res_to_endcont 1.985 \
3229 res_spacing 1.24 \
3230 res_diff_spacing 0.48 \
3231 mask_clearance 0.52 \
3232 overlap_compress 0.36 \
3233 ]
3234 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3235 return [sky130::res_draw $drawdict]
3236}
3237
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003238proc sky130::sky130_fd_pr__res_xhigh_po_1p41_draw {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003239
3240 # Set a local variable for each rule in ruleset
3241 foreach key [dict keys $sky130::ruleset] {
3242 set $key [dict get $sky130::ruleset $key]
3243 }
3244
3245 set newdict [dict create \
3246 res_type xpres \
3247 res_idtype res1p41 \
3248 end_type xpc \
3249 end_contact_type xpc \
3250 end_contact_size 0 \
3251 plus_diff_type psd \
3252 plus_contact_type psc \
3253 sub_type psub \
3254 end_surround $poly_surround \
3255 end_spacing 0.48 \
3256 end_to_end_space 0.52 \
3257 end_contact_size 0.19 \
3258 res_to_endcont 1.985 \
3259 res_spacing 1.24 \
3260 res_diff_spacing 0.48 \
3261 mask_clearance 0.52 \
3262 overlap_compress 0.36 \
3263 ]
3264 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3265 return [sky130::res_draw $drawdict]
3266}
3267
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003268proc sky130::sky130_fd_pr__res_xhigh_po_2p85_draw {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003269
3270 # Set a local variable for each rule in ruleset
3271 foreach key [dict keys $sky130::ruleset] {
3272 set $key [dict get $sky130::ruleset $key]
3273 }
3274
3275 set newdict [dict create \
3276 res_type xpres \
3277 res_idtype res2p85 \
3278 end_type xpc \
3279 end_contact_type xpc \
3280 end_contact_size 0 \
3281 plus_diff_type psd \
3282 plus_contact_type psc \
3283 sub_type psub \
3284 end_surround $poly_surround \
3285 end_spacing 0.48 \
3286 end_to_end_space 0.52 \
3287 end_contact_size 0.19 \
3288 res_to_endcont 1.985 \
3289 res_spacing 1.24 \
3290 res_diff_spacing 0.48 \
3291 mask_clearance 0.52 \
3292 overlap_compress 0.36 \
3293 ]
3294 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3295 return [sky130::res_draw $drawdict]
3296}
3297
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003298proc sky130::sky130_fd_pr__res_xhigh_po_5p73_draw {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003299
3300 # Set a local variable for each rule in ruleset
3301 foreach key [dict keys $sky130::ruleset] {
3302 set $key [dict get $sky130::ruleset $key]
3303 }
3304
3305 set newdict [dict create \
3306 res_type xpres \
3307 res_idtype res5p73 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003308 end_type xpc \
3309 end_contact_type xpc \
3310 end_contact_size 0 \
3311 plus_diff_type psd \
3312 plus_contact_type psc \
3313 sub_type psub \
3314 end_surround $poly_surround \
3315 end_spacing 0.48 \
3316 end_to_end_space 0.52 \
3317 end_contact_size 0.19 \
3318 res_to_endcont 1.985 \
3319 res_spacing 1.24 \
3320 res_diff_spacing 0.48 \
3321 mask_clearance 0.52 \
3322 overlap_compress 0.36 \
3323 ]
3324 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3325 return [sky130::res_draw $drawdict]
3326}
3327
3328#----------------------------------------------------------------
3329
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003330proc sky130::sky130_fd_pr__res_generic_nd_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003331
3332 # Set a local variable for each rule in ruleset
3333 foreach key [dict keys $sky130::ruleset] {
3334 set $key [dict get $sky130::ruleset $key]
3335 }
3336
3337 set newdict [dict create \
3338 res_type rdn \
3339 end_type ndiff \
3340 end_contact_type ndc \
3341 plus_diff_type psd \
3342 plus_contact_type psc \
3343 sub_type psub \
3344 end_surround $diff_surround \
3345 end_spacing 0.44 \
3346 res_to_endcont 0.37 \
3347 res_spacing 0.30 \
3348 res_diff_spacing 0.44 \
3349 mask_clearance 0.22 \
3350 overlap_compress 0.36 \
3351 ]
3352 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3353 return [sky130::res_draw $drawdict]
3354}
3355
3356#----------------------------------------------------------------
3357
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003358proc sky130::sky130_fd_pr__mrdn_hv_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003359
3360 # Set a local variable for each rule in ruleset
3361 foreach key [dict keys $sky130::ruleset] {
3362 set $key [dict get $sky130::ruleset $key]
3363 }
3364
3365 set newdict [dict create \
3366 res_type mvrdn \
3367 end_type mvndiff \
3368 end_contact_type mvndc \
3369 plus_diff_type mvpsd \
3370 plus_contact_type mvpsc \
3371 sub_type psub \
3372 end_surround $diff_surround \
3373 end_spacing 0.44 \
3374 res_to_endcont 0.37 \
3375 res_spacing 0.30 \
3376 res_diff_spacing 0.44 \
3377 mask_clearance 0.22 \
3378 overlap_compress 0.36 \
3379 ]
3380 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3381 return [sky130::res_draw $drawdict]
3382}
3383
3384#----------------------------------------------------------------
3385
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003386proc sky130::sky130_fd_pr__res_generic_pd_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003387
3388 # Set a local variable for each rule in ruleset
3389 foreach key [dict keys $sky130::ruleset] {
3390 set $key [dict get $sky130::ruleset $key]
3391 }
3392
3393 set newdict [dict create \
3394 res_type rdp \
3395 end_type pdiff \
3396 end_contact_type pdc \
3397 plus_diff_type nsd \
3398 plus_contact_type nsc \
3399 sub_type nwell \
3400 end_surround $diff_surround \
3401 end_spacing 0.44 \
3402 res_to_endcont 0.37 \
3403 res_spacing $diff_spacing \
3404 res_diff_spacing 0.44 \
3405 mask_clearance 0.22 \
3406 overlap_compress 0.36 \
3407 ]
3408 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3409 return [sky130::res_draw $drawdict]
3410}
3411
3412#----------------------------------------------------------------
3413
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003414proc sky130::sky130_fd_pr__mrdp_hv_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003415
3416 # Set a local variable for each rule in ruleset
3417 foreach key [dict keys $sky130::ruleset] {
3418 set $key [dict get $sky130::ruleset $key]
3419 }
3420
3421 set newdict [dict create \
3422 res_type mvrdp \
3423 end_type mvpdiff \
3424 end_contact_type mvpdc \
3425 plus_diff_type mvnsd \
3426 plus_contact_type mvnsc \
3427 sub_type nwell \
3428 end_surround $diff_surround \
3429 guard_sub_surround 0.33 \
3430 end_spacing 0.44 \
3431 res_to_endcont 0.37 \
3432 res_spacing 0.30 \
3433 res_diff_spacing 0.44 \
3434 mask_clearance 0.22 \
3435 overlap_compress 0.36 \
3436 ]
3437 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3438 return [sky130::res_draw $drawdict]
3439}
3440
3441#----------------------------------------------------------------
3442
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003443proc sky130::sky130_fd_pr__res_iso_pw_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003444
3445 # Set a local variable for each rule in ruleset
3446 foreach key [dict keys $sky130::ruleset] {
3447 set $key [dict get $sky130::ruleset $key]
3448 }
3449
3450 set newdict [dict create \
3451 well_res_type pwell \
3452 res_type rpw \
3453 end_type psd \
3454 end_contact_type psc \
3455 plus_diff_type nsd \
3456 plus_contact_type nsc \
3457 sub_type dnwell \
3458 sub_surround 0.23 \
3459 guard_sub_type nwell \
3460 guard_sub_surround 0.63 \
3461 end_surround $diff_surround \
3462 end_spacing 0.63 \
3463 end_to_end_space 1.15 \
3464 end_overlap_cont 0.06 \
3465 end_contact_size 0.53 \
3466 overlap_compress -0.17 \
3467 res_to_endcont 0.265 \
3468 res_spacing 1.4 \
3469 res_diff_spacing 0.63 \
3470 well_res_overlap 0.2 \
3471 ]
3472 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3473 return [sky130::res_draw $drawdict]
3474}
3475
3476#----------------------------------------------------------------
3477
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003478proc sky130::sky130_fd_pr__res_generic_l1_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003479
3480 # Set a local variable for each rule in ruleset
3481 foreach key [dict keys $sky130::ruleset] {
3482 set $key [dict get $sky130::ruleset $key]
3483 }
3484
3485 set newdict [dict create \
3486 guard 0 \
3487 res_type rli \
3488 end_type li \
3489 end_surround 0.0 \
3490 end_spacing 0.0 \
3491 res_to_endcont 0.2 \
3492 end_to_end_space 0.23 \
3493 res_spacing $metal_spacing \
3494 ]
3495 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3496 return [sky130::res_draw $drawdict]
3497}
3498
3499#----------------------------------------------------------------
3500
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003501proc sky130::sky130_fd_pr__res_generic_m1_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003502
3503 # Set a local variable for each rule in ruleset
3504 foreach key [dict keys $sky130::ruleset] {
3505 set $key [dict get $sky130::ruleset $key]
3506 }
3507
3508 set newdict [dict create \
3509 guard 0 \
3510 res_type rm1 \
3511 end_type m1 \
3512 end_surround 0.0 \
3513 end_spacing 0.0 \
3514 end_to_end_space 0.28 \
3515 res_to_endcont 0.2 \
3516 res_spacing $mmetal_spacing \
3517 ]
3518 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3519 return [sky130::res_draw $drawdict]
3520}
3521
3522#----------------------------------------------------------------
3523
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003524proc sky130::sky130_fd_pr__res_generic_m2_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003525
3526 # Set a local variable for each rule in ruleset
3527 foreach key [dict keys $sky130::ruleset] {
3528 set $key [dict get $sky130::ruleset $key]
3529 }
3530
3531 set newdict [dict create \
3532 guard 0 \
3533 res_type rm2 \
3534 end_type m2 \
3535 end_surround 0.0 \
3536 end_spacing 0.0 \
3537 end_to_end_space 0.28 \
3538 res_to_endcont 0.2 \
3539 res_spacing $mmetal_spacing \
3540 ]
3541 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3542 return [sky130::res_draw $drawdict]
3543}
3544
3545#----------------------------------------------------------------
3546
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003547proc sky130::sky130_fd_pr__res_generic_m3_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003548
3549 # Set a local variable for each rule in ruleset
3550 foreach key [dict keys $sky130::ruleset] {
3551 set $key [dict get $sky130::ruleset $key]
3552 }
3553
3554 set newdict [dict create \
3555 guard 0 \
3556 res_type rm3 \
3557 end_type m3 \
3558 end_surround 0.0 \
3559 end_spacing 0.0 \
3560 end_to_end_space 0.28 \
3561 res_to_endcont 0.2 \
3562 res_spacing $mmetal_spacing \
3563 ]
3564 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3565 return [sky130::res_draw $drawdict]
3566}
3567
3568#----------------------------------------------------------------
3569
3570#ifdef METAL5
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003571proc sky130::sky130_fd_pr__res_generic_m4_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003572
3573 # Set a local variable for each rule in ruleset
3574 foreach key [dict keys $sky130::ruleset] {
3575 set $key [dict get $sky130::ruleset $key]
3576 }
3577
3578 set newdict [dict create \
3579 guard 0 \
3580 res_type rm4 \
3581 end_type m4 \
3582 end_surround 0.0 \
3583 end_spacing 0.0 \
3584 end_to_end_space 0.28 \
3585 res_to_endcont 0.2 \
3586 res_spacing $mmetal_spacing \
3587 ]
3588 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3589 return [sky130::res_draw $drawdict]
3590}
3591
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003592proc sky130::sky130_fd_pr__res_generic_m5_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003593 # Set a local variable for each rule in ruleset
3594 foreach key [dict keys $sky130::ruleset] {
3595 set $key [dict get $sky130::ruleset $key]
3596 }
3597
3598 set newdict [dict create \
3599 guard 0 \
3600 res_type rm5 \
3601 end_type m5 \
3602 end_surround 0.0 \
3603 end_spacing 0.0 \
3604 end_to_end_space 1.6 \
3605 res_to_endcont 0.2 \
3606 res_spacing $mmetal_spacing \
3607 ]
3608 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3609 return [sky130::res_draw $drawdict]
3610}
3611#endif (METAL5)
3612
3613#----------------------------------------------------------------
3614# Resistor total length computation
3615#----------------------------------------------------------------
3616
3617proc sky130::compute_ltot {parameters} {
3618 # In case snake not defined
3619 set snake 0
3620 set caplen 0
3621
3622 foreach key [dict keys $parameters] {
3623 set $key [dict get $parameters $key]
3624 }
3625
3626 set l [magic::spice2float $l]
3627 set l [magic::3digitpastdecimal $l]
3628
3629 # Compute total length. Use catch to prevent error in batch/scripted mode.
3630 if {$snake == 1} {
3631 catch {set magic::ltot_val [expr ($caplen * ($nx - 1)) + ($l * $nx) + ($nx - 1)]}
3632 } else {
3633 catch {set magic::ltot_val $l}
3634 }
3635}
3636
3637#----------------------------------------------------------------
3638# resistor: Check device parameters for out-of-bounds values
3639#----------------------------------------------------------------
3640
3641proc sky130::res_check {device parameters} {
3642
3643 # Set a local variable for each parameter (e.g., $l, $w, etc.)
3644 set snake 0
3645 set sterm 0.0
3646 set caplen 0
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003647 set wmax 0
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003648
3649 foreach key [dict keys $parameters] {
3650 set $key [dict get $parameters $key]
3651 }
3652
3653 # Normalize distance units to microns
3654 set w [magic::spice2float $w]
3655 set w [magic::3digitpastdecimal $w]
3656 set l [magic::spice2float $l]
3657 set l [magic::3digitpastdecimal $l]
3658
3659 set val [magic::spice2float $val]
3660 set rho [magic::spice2float $rho]
3661
3662 # nf, m must be integer
3663 if {![string is int $nx]} {
3664 puts stderr "X repeat must be an integer!"
3665 dict set parameters nx 1
3666 }
3667 if {![string is int $m]} {
3668 puts stderr "Y repeat must be an integer!"
3669 dict set parameters m 1
3670 }
3671
3672 # Width always needs to be specified
3673 if {$w < $wmin} {
3674 puts stderr "Resistor width must be >= $wmin um"
3675 dict set parameters w $wmin
3676 }
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003677 if {$wmax > 0 && $w > $wmax} {
3678 puts stderr "Resistor width must be <= $wmax um"
3679 dict set parameters w $wmax
3680 }
3681
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003682 # Val and W specified - no L
3683 if {$l == 0} {
3684 set l [expr ($w - $dw) * $val / $rho]
3685 set l [magic::3digitpastdecimal $l]
3686 set stringval [magic::float2spice $val]
3687 dict set parameters l [magic::float2spice [expr $l * 1e-6]]
3688 # L and W specified - ignore Val if specified
3689 } else {
3690 if {$snake == 0} {
3691 set val [expr (2 * $term + $l * $rho) / ($w - $dw)]
3692 } else {
3693 set val [expr $rho * ($nx - 1) + ((2 * ($term + $sterm)) \
3694 + ($rho * $l * $nx) + ($rho * $caplen * ($nx - 1))) \
3695 / ($w - $dw)]
3696 }
3697 set val [magic::float2spice $val]
3698 dict set parameters val $val
3699 }
3700 if {$l < $lmin} {
3701 puts stderr "Resistor length must be >= $lmin um"
3702 dict set parameters l $lmin
3703 }
3704 if {$nx < 1} {
3705 puts stderr "X repeat must be >= 1"
3706 dict set parameters nx 1
3707 }
3708 if {$m < 1} {
3709 puts stderr "Y repeat must be >= 1"
3710 dict set parameters m 1
3711 }
3712
3713 # Snake resistors cannot have width greater than length
3714 if {$snake == 1} {
3715 if {$w > $l} {
3716 puts stderr "Snake resistor width must be < length"
3717 dict set parameters w $l
3718 }
3719 }
3720
3721 # Diffusion resistors must satisfy diffusion-to-tap spacing of 20um.
3722 # Therefore the maximum of guard ring width or height cannot exceed 40um.
3723 # If in violation, reduce counts first, as these are easiest to recover
3724 # by duplicating the device and overlapping the wells.
3725 if {$device == "rdn" || $device == "rdp"} {
3726 set origm $m
3727 set orignx $nx
3728 while true {
3729 set xext [expr ($w + 0.8) * $nx + 1.0]
3730 set yext [expr ($l + 1.7) * $m + 1.7]
3731 if {[expr min($xext, $yext)] > 40.0} {
3732 if {$yext > 40.0 && $m > 1} {
3733 incr m -1
3734 } elseif {$xext > 40.0 && $nx > 1} {
3735 incr nx -1
3736 } elseif {$yext > 40.0} {
3737 set l 36.6
3738 puts -nonewline stderr "Diffusion resistor length must be < 36.6 um"
3739 puts stderr " to avoid tap spacing violation."
3740 dict set parameters l $l
3741 } elseif {$xext > 40.0} {
3742 set w 38.2
3743 puts -nonewline stderr "Diffusion resistor width must be < 38.2 um"
3744 puts stderr " to avoid tap spacing violation."
3745 dict set parameters w $w
3746 }
3747 } else {
3748 break
3749 }
3750 }
3751 if {$m != $origm} {
3752 puts stderr "Y repeat reduced to prevent tap distance violation"
3753 dict set parameters m $m
3754 }
3755 if {$nx != $orignx} {
3756 puts stderr "X repeat reduced to prevent tap distance violation"
3757 dict set parameters nx $nx
3758 }
3759 }
3760 sky130::compute_ltot $parameters
3761 return $parameters
3762}
3763
3764#----------------------------------------------------------------
3765
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003766proc sky130::sky130_fd_pr__res_iso_pw_check {parameters} {
3767 return [sky130::res_check sky130_fd_pr__res_iso_pw $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003768}
3769
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003770proc sky130::sky130_fd_pr__res_generic_po_check {parameters} {
3771 return [sky130::res_check sky130_fd_pr__res_generic_po $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003772}
3773
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003774proc sky130::sky130_fd_pr__res_high_po_0p35_check {parameters} {
3775 return [sky130::res_check sky130_fd_pr__res_high_po_0p35 $parameters]
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003776}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003777proc sky130::sky130_fd_pr__res_high_po_0p69_check {parameters} {
3778 return [sky130::res_check sky130_fd_pr__res_high_po_0p69 $parameters]
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003779}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003780proc sky130::sky130_fd_pr__res_high_po_1p41_check {parameters} {
3781 return [sky130::res_check sky130_fd_pr__res_high_po_1p41 $parameters]
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003782}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003783proc sky130::sky130_fd_pr__res_high_po_2p85_check {parameters} {
3784 return [sky130::res_check sky130_fd_pr__res_high_po_2p85 $parameters]
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003785}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003786proc sky130::sky130_fd_pr__res_high_po_5p73_check {parameters} {
3787 return [sky130::res_check sky130_fd_pr__res_high_po_5p73 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003788}
3789
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003790proc sky130::sky130_fd_pr__res_xhigh_po_0p35_check {parameters} {
3791 return [sky130::res_check sky130_fd_pr__res_xhigh_po_0p35 $parameters]
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003792}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003793proc sky130::sky130_fd_pr__res_xhigh_po_0p69_check {parameters} {
3794 return [sky130::res_check sky130_fd_pr__res_xhigh_po_0p69 $parameters]
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003795}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003796proc sky130::sky130_fd_pr__res_xhigh_po_1p41_check {parameters} {
3797 return [sky130::res_check sky130_fd_pr__res_xhigh_po_1p41 $parameters]
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003798}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003799proc sky130::sky130_fd_pr__res_xhigh_po_2p85_check {parameters} {
3800 return [sky130::res_check sky130_fd_pr__res_xhigh_po_2p85 $parameters]
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003801}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003802proc sky130::sky130_fd_pr__res_xhigh_po_5p73_check {parameters} {
3803 return [sky130::res_check sky130_fd_pr__res_xhigh_po_5p73 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003804}
3805
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003806proc sky130::sky130_fd_pr__res_generic_nd_check {parameters} {
3807 return [sky130::res_check sky130_fd_pr__res_generic_nd $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003808}
3809
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003810proc sky130::sky130_fd_pr__res_generic_pd_check {parameters} {
3811 return [sky130::res_check sky130_fd_pr__res_generic_pd $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003812}
3813
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003814proc sky130::sky130_fd_pr__mrdn_hv_check {parameters} {
3815 return [sky130::res_check sky130_fd_pr__mrdn_hv $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003816}
3817
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003818proc sky130::sky130_fd_pr__mrdp_hv_check {parameters} {
3819 return [sky130::res_check sky130_fd_pr__mrdp_hv $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003820}
3821
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003822proc sky130::sky130_fd_pr__res_generic_l1_check {parameters} {
3823 return [sky130::res_check sky130_fd_pr__res_generic_l1 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003824}
3825
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003826proc sky130::sky130_fd_pr__res_generic_m1_check {parameters} {
3827 return [sky130::res_check sky130_fd_pr__res_generic_m1 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003828}
3829
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003830proc sky130::sky130_fd_pr__res_generic_m2_check {parameters} {
3831 return [sky130::res_check sky130_fd_pr__res_generic_m2 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003832}
3833
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003834proc sky130::sky130_fd_pr__res_generic_m3_check {parameters} {
3835 return [sky130::res_check sky130_fd_pr__res_generic_m3 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003836}
3837
3838#ifdef METAL5
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003839proc sky130::sky130_fd_pr__res_generic_m4_check {parameters} {
3840 return [sky130::res_check sky130_fd_pr__res_generic_m4 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003841}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003842proc sky130::sky130_fd_pr__res_generic_m5_check {parameters} {
3843 return [sky130::res_check sky130_fd_pr__res_generic_m5 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003844}
3845#endif (METAL5)
3846
3847#----------------------------------------------------------------
3848# MOS defaults:
3849#----------------------------------------------------------------
3850# w = Gate width
3851# l = Gate length
3852# m = Multiplier
3853# nf = Number of fingers
3854# diffcov = Diffusion contact coverage
3855# polycov = Poly contact coverage
3856# topc = Top gate contact
3857# botc = Bottom gate contact
3858# guard = Guard ring
3859#
3860# (not user-editable)
3861#
3862# lmin = Gate minimum length
3863# wmin = Gate minimum width
3864#----------------------------------------------------------------
3865
3866#----------------------------------------------------------------
3867# pmos: Specify all user-editable default values and those
3868# needed by mos_check
3869#----------------------------------------------------------------
3870
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003871proc sky130::sky130_fd_pr__pfet_01v8_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003872 return {w 0.42 l 0.15 m 1 nf 1 diffcov 100 polycov 100 \
3873 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
3874 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.15 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003875 compatible {sky130_fd_pr__pfet_01v8 \
3876 sky130_fd_pr__pfet_01v8_lvt sky130_fd_pr__pfet_01v8_hvt \
3877 sky130_fd_pr__pfet_g5v0d10v5} full_metal 1}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003878}
3879
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003880proc sky130::sky130_fd_pr__pfet_01v8_lvt_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003881 return {w 0.42 l 0.35 m 1 nf 1 diffcov 100 polycov 100 \
3882 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
3883 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.35 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003884 compatible {sky130_fd_pr__pfet_01v8 \
3885 sky130_fd_pr__pfet_01v8_lvt sky130_fd_pr__pfet_01v8_hvt \
3886 sky130_fd_pr__pfet_g5v0d10v5} full_metal 1}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003887}
3888
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003889proc sky130::sky130_fd_pr__pfet_01v8_hvt_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003890 return {w 0.42 l 0.15 m 1 nf 1 diffcov 100 polycov 100 \
3891 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
3892 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.15 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003893 compatible {sky130_fd_pr__pfet_01v8 \
3894 sky130_fd_pr__pfet_01v8_lvt sky130_fd_pr__pfet_01v8_hvt \
3895 sky130_fd_pr__pfet_g5v0d10v5} full_metal 1}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003896}
3897
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003898proc sky130::sky130_fd_pr__pfet_g5v0d10v5_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003899 return {w 0.42 l 0.50 m 1 nf 1 diffcov 100 polycov 100 \
3900 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
3901 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.50 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003902 compatible {sky130_fd_pr__pfet_01v8 \
3903 sky130_fd_pr__pfet_01v8_lvt sky130_fd_pr__pfet_01v8_hvt \
3904 sky130_fd_pr__pfet_g5v0d10v5} full_metal 1}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003905}
3906
3907#----------------------------------------------------------------
3908# nmos: Specify all user-editable default values and those
3909# needed by mos_check
3910#----------------------------------------------------------------
3911
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003912proc sky130::sky130_fd_pr__nfet_01v8_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003913 return {w 0.420 l 0.150 m 1 nf 1 diffcov 100 polycov 100 \
3914 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
3915 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.15 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003916 compatible {sky130_fd_pr__nfet_01v8 sky130_fd_pr__nfet_01v8_lvt \
3917 sky130_fd_bs_flash__special_sonosfet_star \
3918 sky130_fd_pr__nfet_g5v0d10v5 sky130_fd_pr__nfet_05v0_nvt} full_metal 1}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003919}
3920
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003921proc sky130::sky130_fd_pr__nfet_01v8_lvt_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003922 return {w 0.420 l 0.150 m 1 nf 1 diffcov 100 polycov 100 \
3923 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
3924 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.15 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003925 compatible {sky130_fd_pr__nfet_01v8 sky130_fd_pr__nfet_01v8_lvt \
3926 sky130_fd_bs_flash__special_sonosfet_star \
3927 sky130_fd_pr__nfet_g5v0d10v5 sky130_fd_pr__nfet_05v0_nvt} full_metal 1}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003928}
3929
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003930proc sky130::sky130_fd_bs_flash__special_sonosfet_star_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003931 return {w 0.420 l 0.150 m 1 nf 1 diffcov 100 polycov 100 \
3932 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
3933 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.15 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003934 compatible {sky130_fd_pr__nfet_01v8 sky130_fd_pr__nfet_01v8_lvt \
3935 sky130_fd_bs_flash__special_sonosfet_star \
3936 sky130_fd_pr__nfet_g5v0d10v5 sky130_fd_pr__nfet_05v0_nvt} full_metal 1}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003937}
3938
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003939proc sky130::sky130_fd_pr__nfet_g5v0d10v5_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003940 return {w 0.42 l 0.50 m 1 nf 1 diffcov 100 polycov 100 \
3941 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
3942 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.50 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003943 compatible {sky130_fd_pr__nfet_01v8 sky130_fd_pr__nfet_01v8_lvt \
3944 sky130_fd_bs_flash__special_sonosfet_star \
3945 sky130_fd_pr__nfet_g5v0d10v5 sky130_fd_pr__nfet_05v0_nvt} full_metal 1}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003946}
3947
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003948proc sky130::sky130_fd_pr__nfet_05v0_nvt_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003949 return {w 0.42 l 0.50 m 1 nf 1 diffcov 100 polycov 100 \
3950 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
3951 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.50 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003952 compatible {sky130_fd_pr__nfet_01v8 sky130_fd_pr__nfet_01v8_lvt \
3953 sky130_fd_bs_flash__special_sonosfet_star \
3954 sky130_fd_pr__nfet_g5v0d10v5 sky130_fd_pr__nfet_05v0_nvt} full_metal 1}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003955}
3956
3957#----------------------------------------------------------------
3958# mos varactor: Specify all user-editable default values and those
3959# needed by mosvc_check
3960#----------------------------------------------------------------
3961
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003962proc sky130::sky130_fd_pr__cap_var_lvt_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003963 return {w 1.0 l 0.18 m 1 nf 1 diffcov 100 polycov 100 \
3964 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
3965 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.18 wmin 1.0 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003966 compatible {sky130_fd_pr__cap_var_lvt \
3967 sky130_fd_pr__cap_var_hvt sky130_fd_pr__cap_var} full_metal 1}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003968}
3969
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003970proc sky130::sky130_fd_pr__cap_var_hvt_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003971 return {w 1.0 l 0.18 m 1 nf 1 diffcov 100 polycov 100 \
3972 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
3973 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.18 wmin 1.0 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003974 compatible {sky130_fd_pr__cap_var_lvt \
3975 sky130_fd_pr__cap_var_hvt sky130_fd_pr__cap_var} full_metal 1}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003976}
3977
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003978proc sky130::sky130_fd_pr__cap_var_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003979 return {w 1.0 l 0.50 m 1 nf 1 diffcov 100 polycov 100 \
3980 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
3981 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.50 wmin 1.0 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003982 compatible {sky130_fd_pr__cap_var_lvt \
3983 sky130_fd_pr__cap_var_hvt sky130_fd_pr__cap_var} full_metal 1}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003984}
3985
3986#----------------------------------------------------------------
3987# mos: Conversion from SPICE netlist parameters to toolkit
3988#----------------------------------------------------------------
3989
3990proc sky130::mos_convert {parameters} {
3991 set pdkparams [dict create]
3992 dict for {key value} $parameters {
3993 switch -nocase $key {
3994 l -
3995 w {
3996 # Length and width are converted to units of microns
3997 set value [magic::spice2float $value]
3998 # set value [expr $value * 1e6]
3999 set value [magic::3digitpastdecimal $value]
4000 dict set pdkparams [string tolower $key] $value
4001 }
4002 m {
Tim Edwards23c97662020-08-09 11:57:32 -04004003 dict set pdkparams [string tolower $key] $value
4004 }
4005 nf {
4006 # Adjustment ot W will be handled below
4007 dict set pdkparams [string tolower $key] $value
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004008 }
4009 }
4010 }
Tim Edwards23c97662020-08-09 11:57:32 -04004011
4012 # Magic does not understand "nf" as a parameter, but expands to
4013 # "nf" number of devices connected horizontally. The "w" value
4014 # must be divided down accordingly, as the "nf" parameter implies
4015 # that the total width "w" is divided into "nf" fingers.
4016
4017 catch {
4018 set w [dict get $pdkparams w]
4019 set nf [dict get $pdkparams nf]
4020 if {$nf > 1} {
4021 dict set pdkparams w [expr $w / $nf]
4022 }
4023 }
4024
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004025 return $pdkparams
4026}
4027
4028#----------------------------------------------------------------
4029
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004030proc sky130::sky130_fd_pr__nfet_01v8_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004031 return [sky130::mos_convert $parameters]
4032}
4033
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004034proc sky130::sky130_fd_pr__nfet_01v8_lvt_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004035 return [sky130::mos_convert $parameters]
4036}
4037
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004038proc sky130::sky130_fd_bs_flash__special_sonosfet_star_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004039 return [sky130::mos_convert $parameters]
4040}
4041
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004042proc sky130::sky130_fd_pr__nfet_g5v0d10v5_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004043 return [sky130::mos_convert $parameters]
4044}
4045
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004046proc sky130::sky130_fd_pr__nfet_05v0_nvt_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004047 return [sky130::mos_convert $parameters]
4048}
4049
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004050proc sky130::sky130_fd_pr__pfet_01v8_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004051 return [sky130::mos_convert $parameters]
4052}
4053
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004054proc sky130::sky130_fd_pr__pfet_01v8_lvt_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004055 return [sky130::mos_convert $parameters]
4056}
4057
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004058proc sky130::sky130_fd_pr__pfet_01v8_hvt_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004059 return [sky130::mos_convert $parameters]
4060}
4061
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004062proc sky130::sky130_fd_pr__pfet_g5v0d10v5_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004063 return [sky130::mos_convert $parameters]
4064}
4065
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004066proc sky130::sky130_fd_pr__cap_var_lvt_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004067 return [sky130::mos_convert $parameters]
4068}
4069
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004070proc sky130::sky130_fd_pr__cap_var_hvt_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004071 return [sky130::mos_convert $parameters]
4072}
4073
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004074proc sky130::sky130_fd_pr__cap_var_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004075 return [sky130::mos_convert $parameters]
4076}
4077
4078#----------------------------------------------------------------
4079# mos: Interactively specifies the fixed layout parameters
4080#----------------------------------------------------------------
4081
4082proc sky130::mos_dialog {device parameters} {
4083 # Editable fields: w, l, nf, m, diffcov, polycov
4084 # Checked fields: topc, botc
4085 # For specific devices, gate type is a selection list
4086
4087 magic::add_entry w "Width (um)" $parameters
4088 magic::add_entry l "Length (um)" $parameters
4089 magic::add_entry nf "Fingers" $parameters
4090 magic::add_entry m "M" $parameters
4091
4092 if {[dict exists $parameters compatible]} {
4093 set sellist [dict get $parameters compatible]
4094 magic::add_selectlist gencell "Device type" $sellist $parameters $device
4095 }
4096
4097 magic::add_entry diffcov "Diffusion contact coverage (%)" $parameters
4098 magic::add_entry polycov "Poly contact coverage (%)" $parameters
4099 magic::add_entry rlcov "Guard ring contact coverage (%)" $parameters
4100 if {[dict exists $parameters gbc]} {
4101 magic::add_entry tbcov "Guard ring top/bottom contact coverage (%)" $parameters
4102 }
4103
4104 magic::add_checkbox poverlap "Overlap at poly contact" $parameters
4105 magic::add_checkbox doverlap "Overlap at diffusion contact" $parameters
4106 magic::add_checkbox topc "Add top gate contact" $parameters
4107 magic::add_checkbox botc "Add bottom gate contact" $parameters
4108
4109 magic::add_checkbox guard "Add guard ring" $parameters
4110 magic::add_checkbox full_metal "Full metal guard ring" $parameters
4111 magic::add_checkbox glc "Add left guard ring contact" $parameters
4112 magic::add_checkbox grc "Add right guard ring contact" $parameters
4113 if {[dict exists $parameters gbc]} {
4114 magic::add_checkbox gbc "Add bottom guard ring contact" $parameters
4115 }
4116 if {[dict exists $parameters gtc]} {
4117 magic::add_checkbox gtc "Add top guard ring contact" $parameters
4118 }
4119}
4120
4121#----------------------------------------------------------------
4122
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004123proc sky130::sky130_fd_pr__nfet_01v8_dialog {parameters} {
4124 sky130::mos_dialog sky130_fd_pr__nfet_01v8 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004125}
4126
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004127proc sky130::sky130_fd_pr__nfet_01v8_lvt_dialog {parameters} {
4128 sky130::mos_dialog sky130_fd_pr__nfet_01v8_lvt $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004129}
4130
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004131proc sky130::sky130_fd_bs_flash__special_sonosfet_star_dialog {parameters} {
4132 sky130::mos_dialog sky130_fd_bs_flash__special_sonosfet_star $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004133}
4134
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004135proc sky130::sky130_fd_pr__nfet_g5v0d10v5_dialog {parameters} {
4136 sky130::mos_dialog sky130_fd_pr__nfet_g5v0d10v5 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004137}
4138
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004139proc sky130::sky130_fd_pr__nfet_05v0_nvt_dialog {parameters} {
4140 sky130::mos_dialog sky130_fd_pr__nfet_05v0_nvt $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004141}
4142
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004143proc sky130::sky130_fd_pr__pfet_01v8_dialog {parameters} {
4144 sky130::mos_dialog sky130_fd_pr__pfet_01v8 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004145}
4146
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004147proc sky130::sky130_fd_pr__pfet_01v8_lvt_dialog {parameters} {
4148 sky130::mos_dialog sky130_fd_pr__pfet_01v8_lvt $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004149}
4150
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004151proc sky130::sky130_fd_pr__pfet_01v8_hvt_dialog {parameters} {
4152 sky130::mos_dialog sky130_fd_pr__pfet_01v8_hvt $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004153}
4154
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004155proc sky130::sky130_fd_pr__pfet_g5v0d10v5_dialog {parameters} {
4156 sky130::mos_dialog sky130_fd_pr__pfet_g5v0d10v5 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004157}
4158
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004159proc sky130::sky130_fd_pr__cap_var_lvt_dialog {parameters} {
4160 sky130::mos_dialog sky130_fd_pr__cap_var_lvt $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004161}
4162
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004163proc sky130::sky130_fd_pr__cap_var_hvt_dialog {parameters} {
4164 sky130::mos_dialog sky130_fd_pr__cap_var_hvt $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004165}
4166
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004167proc sky130::sky130_fd_pr__cap_var_dialog {parameters} {
4168 sky130::mos_dialog sky130_fd_pr__cap_var $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004169}
4170
4171#----------------------------------------------------------------
4172# getbox: Get the current cursor box, in microns
4173#----------------------------------------------------------------
4174
4175proc sky130::getbox {} {
4176 set curbox [box values]
4177 set newbox []
4178 set oscale [cif scale out]
4179 for {set i 0} {$i < 4} {incr i} {
4180 set v [* [lindex $curbox $i] $oscale]
4181 lappend newbox $v
4182 }
4183 return $newbox
4184}
4185
4186#----------------------------------------------------------------
4187# unionbox: Get the union bounding box of box1 and box2
4188#----------------------------------------------------------------
4189
4190proc sky130::unionbox {box1 box2} {
4191 set newbox []
4192 for {set i 0} {$i < 2} {incr i} {
4193 set v [lindex $box1 $i]
4194 set o [lindex $box2 $i]
4195 if {$v < $o} {
4196 lappend newbox $v
4197 } else {
4198 lappend newbox $o
4199 }
4200 }
4201 for {set i 2} {$i < 4} {incr i} {
4202 set v [lindex $box1 $i]
4203 set o [lindex $box2 $i]
4204 if {$v > $o} {
4205 lappend newbox $v
4206 } else {
4207 lappend newbox $o
4208 }
4209 }
4210 return $newbox
4211}
4212
4213#----------------------------------------------------------------
4214# Draw a contact
4215#----------------------------------------------------------------
4216
4217proc sky130::draw_contact {w h s o x atype ctype mtype {orient vert}} {
4218
4219 # Draw a minimum-size diff contact centered at current position
4220 # w is width, h is height. Minimum size ensured.
4221 # x is contact size
4222 # s is contact diffusion (or poly) surround
4223 # o is contact metal surround
4224 # atype is active (e.g., ndiff) or bottom metal if a via
4225 # ctype is contact (e.g., ndc)
4226 # mtype is metal (e.g., m1) or top metal if a via
4227 # orient is the orientation of the contact
4228
4229 # Set orientations for the bottom material based on material type.
4230 # Substrate diffusions (tap) need not overlap the contact in all
4231 # directions, but other (diff) types do. The metal (local
4232 # interconnect) layer always overlaps in two directions only.
4233
4234 set lv_sub_types {"psd" "nsd"}
4235 if {[lsearch $lv_sub_types $atype] >= 0} {
4236 set aorient $orient
4237 } else {
4238 set aorient "full"
4239 }
4240
4241 pushbox
4242 box size 0 0
4243 if {$w < $x} {set w $x}
4244 if {$h < $x} {set h $x}
4245 set hw [/ $w 2.0]
4246 set hh [/ $h 2.0]
4247 box grow n ${hh}um
4248 box grow s ${hh}um
4249 box grow e ${hw}um
4250 box grow w ${hw}um
4251 paint ${ctype}
4252 pushbox
4253 # Bottom layer surrounded on sides as declared by aorient
4254 if {($aorient == "vert") || ($aorient == "full")} {
4255 box grow n ${s}um
4256 box grow s ${s}um
4257 }
4258 if {($aorient == "horz") || ($aorient == "full")} {
4259 box grow e ${s}um
4260 box grow w ${s}um
4261 }
4262 paint ${atype}
4263 set extents [sky130::getbox]
4264 popbox
4265 # Top layer surrounded on sides as declared by orient
4266 if {($orient == "vert") || ($orient == "full")} {
4267 box grow n ${o}um
4268 box grow s ${o}um
4269 }
4270 if {($orient == "horz") || ($orient == "full")} {
4271 box grow e ${o}um
4272 box grow w ${o}um
4273 }
4274 paint ${mtype}
4275 popbox
4276 return $extents
4277}
4278
4279#----------------------------------------------------------------
4280# Draw a guard ring
4281#----------------------------------------------------------------
4282
4283proc sky130::guard_ring {gw gh parameters} {
4284
4285 # Set local default values if they are not in parameters
4286 set rlcov 100 ;# Right-left contact coverage percentage
4287 set tbcov 100 ;# Top-bottom contact coverage percentage
4288 set grc 1 ;# Draw right side contact
4289 set glc 1 ;# Draw left side contact
4290 set gtc 1 ;# Draw right side contact
4291 set gbc 1 ;# Draw left side contact
4292 set full_metal 1 ;# Draw full (continuous) metal ring
4293 set guard_sub_type pwell ;# substrate type under guard ring
4294 set guard_sub_surround 0 ;# substrate type surrounds guard ring
4295 set plus_diff_type nsd ;# guard ring diffusion type
4296 set plus_contact_type nsc ;# guard ring diffusion contact type
4297 set sub_type pwell ;# substrate type
4298
4299 # Set a local variable for each parameter (e.g., $l, $w, etc.)
4300 foreach key [dict keys $parameters] {
4301 set $key [dict get $parameters $key]
4302 }
4303
4304 # Set guard_sub_type to sub_type if it is not defined
4305 if {![dict exists $parameters guard_sub_type]} {
4306 set guard_sub_type $sub_type
4307 }
4308
4309 set hx [/ $contact_size 2.0]
4310 set hw [/ $gw 2.0]
4311 set hh [/ $gh 2.0]
4312
4313 # Watch for (LV) substrate diffusion types, which have a different
4314 # contact surround amount depending on the direction
4315
4316 set lv_sub_types {"psd" "nsd"}
4317 if {[lsearch $lv_sub_types $plus_diff_type] >= 0} {
4318 set diff_surround 0
4319 }
4320
4321 # Compute diffusion width
4322 set difft [+ $contact_size $diff_surround $diff_surround]
4323 set hdifft [/ $difft 2.0]
4324 # Compute guard ring diffusion width and height
4325 set hdiffw [/ [+ $gw $difft] 2.0]
4326 set hdiffh [/ [+ $gh $difft] 2.0]
4327
4328 pushbox
4329 box size 0 0
4330
4331 pushbox
4332 box move n ${hh}um
4333 box grow n ${hdifft}um
4334 box grow s ${hdifft}um
4335 box grow e ${hdiffw}um
4336 box grow w ${hdiffw}um
4337 paint $plus_diff_type
4338 if {$guard_sub_surround > 0} {
4339 box grow c ${guard_sub_surround}um
4340 paint $guard_sub_type
4341 }
4342 popbox
4343 pushbox
4344 box move s ${hh}um
4345 box grow n ${hdifft}um
4346 box grow s ${hdifft}um
4347 box grow e ${hdiffw}um
4348 box grow w ${hdiffw}um
4349 paint $plus_diff_type
4350 if {$guard_sub_surround > 0} {
4351 box grow c ${guard_sub_surround}um
4352 paint $guard_sub_type
4353 }
4354 popbox
4355 pushbox
4356 box move e ${hw}um
4357 box grow e ${hdifft}um
4358 box grow w ${hdifft}um
4359 box grow n ${hdiffh}um
4360 box grow s ${hdiffh}um
4361 paint $plus_diff_type
4362 if {$guard_sub_surround > 0} {
4363 box grow c ${guard_sub_surround}um
4364 paint $guard_sub_type
4365 }
4366 popbox
4367 pushbox
4368 box move w ${hw}um
4369 box grow e ${hdifft}um
4370 box grow w ${hdifft}um
4371 box grow n ${hdiffh}um
4372 box grow s ${hdiffh}um
4373 paint $plus_diff_type
4374 if {$guard_sub_surround > 0} {
4375 box grow c ${guard_sub_surround}um
4376 paint $guard_sub_type
4377 }
4378 popbox
4379
4380 if {$full_metal} {
4381 set hmetw [/ [+ $gw $contact_size] 2.0]
4382 set hmeth [/ [+ $gh $contact_size] 2.0]
4383 pushbox
4384 box move n ${hh}um
4385 box grow n ${hx}um
4386 box grow s ${hx}um
4387 box grow e ${hmetw}um
4388 box grow w ${hmetw}um
4389 paint li
4390 popbox
4391 pushbox
4392 box move s ${hh}um
4393 box grow n ${hx}um
4394 box grow s ${hx}um
4395 box grow e ${hmetw}um
4396 box grow w ${hmetw}um
4397 paint li
4398 popbox
4399 pushbox
4400 box move e ${hw}um
4401 box grow e ${hx}um
4402 box grow w ${hx}um
4403 box grow n ${hmeth}um
4404 box grow s ${hmeth}um
4405 paint li
4406 popbox
4407 pushbox
4408 box move w ${hw}um
4409 box grow e ${hx}um
4410 box grow w ${hx}um
4411 box grow n ${hmeth}um
4412 box grow s ${hmeth}um
4413 paint li
4414 popbox
4415 }
4416
4417 # Set guard ring height so that contact metal reaches to end, scale by $per
4418 # set ch [* [+ $gh $contact_size [* $metal_surround -2.0]] [/ $rlcov 100.0]]
4419 set ch [* [- $gh $contact_size [* [+ $metal_surround $metal_spacing] \
4420 2.0]] [/ $rlcov 100.0]]
4421 if {$ch < $contact_size} {set ch $contact_size}
4422
4423 # Set guard ring width so that contact metal reaches to side contacts
4424 set cw [* [- $gw $contact_size [* [+ $metal_surround $metal_spacing] \
4425 2.0]] [/ $tbcov 100.0]]
4426 if {$cw < $contact_size} {set cw $contact_size}
4427
4428 if {$tbcov > 0.0} {
4429 if {$gtc == 1} {
4430 pushbox
4431 box move n ${hh}um
4432 sky130::draw_contact $cw 0 $diff_surround $metal_surround \
4433 $contact_size $plus_diff_type $plus_contact_type li horz
4434 popbox
4435 }
4436 if {$gbc == 1} {
4437 pushbox
4438 box move s ${hh}um
4439 sky130::draw_contact $cw 0 $diff_surround $metal_surround \
4440 $contact_size $plus_diff_type $plus_contact_type li horz
4441 popbox
4442 }
4443 }
4444 if {$rlcov > 0.0} {
4445 if {$grc == 1} {
4446 pushbox
4447 box move e ${hw}um
4448 sky130::draw_contact 0 $ch $diff_surround $metal_surround \
4449 $contact_size $plus_diff_type $plus_contact_type li vert
4450 popbox
4451 }
4452 if {$glc == 1} {
4453 pushbox
4454 box move w ${hw}um
4455 sky130::draw_contact 0 $ch $diff_surround $metal_surround \
4456 $contact_size $plus_diff_type $plus_contact_type li vert
4457 popbox
4458 }
4459 }
4460
4461 pushbox
4462 box grow e ${hw}um
4463 box grow w ${hw}um
4464 box grow n ${hh}um
4465 box grow s ${hh}um
4466 # Create boundary using properties
4467 property FIXED_BBOX [box values]
4468 box grow c ${hx}um ;# to edge of contact
4469 box grow c ${diff_surround}um ;# to edge of diffusion
4470 box grow c ${sub_surround}um ;# sub/well overlap of diff (NOT guard_sub)
4471 paint $sub_type
4472 set cext [sky130::getbox]
4473 popbox
4474 popbox
4475
4476 return $cext
4477}
4478
4479#----------------------------------------------------------------
4480# MOSFET: Draw a single device
4481#----------------------------------------------------------------
4482
4483proc sky130::mos_device {parameters} {
4484
4485 # Epsilon for avoiding round-off errors
4486 set eps 0.0005
4487
4488 # Set local default values if they are not in parameters
4489 set diffcov 100 ;# percent coverage of diffusion contact
4490 set polycov 100 ;# percent coverage of poly contact
4491 set topc 1 ;# draw top poly contact
4492 set botc 1 ;# draw bottom poly contact
4493 set evenodd 1 ;# even or odd numbered device finger, in X
4494 set dev_sub_type "" ;# device substrate type (if different from guard ring)
4495 set min_effl 0 ;# gate length below which finger pitch must be stretched
4496 set diff_overlap_cont 0 ;# extra overlap of end contact by diffusion
4497
4498 # Set a local variable for each parameter (e.g., $l, $w, etc.)
4499 foreach key [dict keys $parameters] {
4500 set $key [dict get $parameters $key]
4501 }
4502
4503 # Draw the diffusion and poly
4504 pushbox
4505 box size 0 0
4506 pushbox
4507 set hw [/ $w 2.0]
4508 set hl [/ $l 2.0]
4509 set he [/ $min_effl 2.0]
4510 if {$nf == 1 || $he < $hl} {set he $hl}
4511 box grow n ${hw}um
4512 box grow s ${hw}um
4513 box grow e ${hl}um
4514 box grow w ${hl}um
4515 pushbox
4516 if {${diff_extension} > ${gate_to_diffcont}} {
4517 box grow e ${diff_extension}um
4518 box grow w ${diff_extension}um
4519 } else {
4520 box grow e ${gate_to_diffcont}um
4521 box grow w ${gate_to_diffcont}um
4522 }
4523 paint ${diff_type}
4524 popbox
4525 pushbox
4526 if {${gate_extension} > ${gate_to_polycont}} {
4527 box grow n ${gate_extension}um
4528 box grow s ${gate_extension}um
4529 } else {
4530 if {$topc} {
4531 box grow n ${gate_to_polycont}um
4532 } else {
4533 box grow n ${gate_extension}um
4534 }
4535 if {$botc} {
4536 box grow s ${gate_to_polycont}um
4537 } else {
4538 box grow s ${gate_extension}um
4539 }
4540 }
4541 paint ${poly_type}
4542 set cext [sky130::getbox]
4543 popbox
4544 # save gate area now and paint later, so that diffusion surrounding the
4545 # contact does not paint over the gate area, in case the gate type is
4546 # not part of a "compose" entry in the techfile.
4547 set gaterect [box values]
4548 popbox
4549
4550 # Adjust position of contacts for dogbone geometry
4551 # Rule 1: Minimize diffusion length. Contacts only move out
4552 # if width < contact diffusion height. They move out enough
4553 # that the diffusion-to-poly spacing is satisfied.
4554
4555 set ddover 0
4556 set cdwmin [+ ${contact_size} [* ${diff_surround} 2]]
4557 set cstem [- ${gate_to_diffcont} [/ ${cdwmin} 2.0]]
4558 set cgrow [- ${diff_poly_space} ${cstem}]
4559 if {[+ ${w} ${eps}] < ${cdwmin}} {
4560 if {${cgrow} > 0} {
4561 set gate_to_diffcont [+ ${gate_to_diffcont} ${cgrow}]
4562 }
4563 set ddover [/ [- ${cdwmin} ${w}] 2.0]
4564 }
4565
4566 # Rule 2: Minimum poly width. Poly contacts only move out
4567 # if length < contact poly width. They move out enough
4568 # that the diffusion-to-poly spacing is satisfied.
4569
4570 set gporig ${gate_to_polycont}
4571 set cplmin [+ ${contact_size} [* ${poly_surround} 2]]
4572 set cstem [- ${gate_to_polycont} [/ ${cplmin} 2.0]]
4573 set cgrow [- ${diff_poly_space} ${cstem}]
4574 if {[+ ${l} ${eps}] < ${cplmin}} {
4575 if {${cgrow} > 0} {
4576 set gate_to_polycont [+ ${gate_to_polycont} ${cgrow}]
4577 }
4578 }
4579
4580 # Rule 3: If both poly and diffusion are dogboned, then move
4581 # poly out further to clear spacing to the diffusion contact
4582
4583 if {[+ ${w} ${eps}] < ${cdwmin}} {
4584 if {[+ ${l} ${eps}] < ${cplmin}} {
4585 set cgrow [/ [- ${cplmin} ${w}] 2.0]
4586 set gate_to_polycont [+ ${gate_to_polycont} ${cgrow}]
4587 }
4588 }
4589
4590 # Rule 4: If M > 1 and poly contacts overlap, then increase the
4591 # transistor-to-poly-contact distance by the amount of any
4592 # diffusion dogbone overhang.
4593
4594 if {($poverlap == 1) && ($m > 1)} {
4595 if {${gate_to_polycont} - $gporig < $ddover} {
4596 set gate_to_polycont [+ ${gporig} ${ddover}]
4597 }
4598 }
4599
4600 # Reduce contact sizes by poly or diffusion surround so that
4601 # the contact area edges match the device diffusion or poly.
4602 # (Minimum dimensions will be enforced by the contact drawing routine)
4603 set tsurround [+ ${diff_surround} ${diff_overlap_cont}]
4604 set cdw [- ${w} [* ${tsurround} 2]] ;# diff contact height
4605 set cpl [- ${l} [* ${poly_surround} 2]] ;# poly contact width
4606
4607 # Reduce by coverage percentage. NOTE: If overlapping multiple devices,
4608 # keep maximum poly contact coverage.
4609
4610 set cdw [* ${cdw} [/ ${diffcov} 100.0]]
4611 if {($poverlap == 0) || ($m == 1)} {
4612 set cpl [* ${cpl} [/ ${polycov} 100.0]]
4613 }
4614
4615 # Right diffusion contact
4616 pushbox
4617 box move e ${he}um
4618 box move e ${gate_to_diffcont}um
4619 set cext [sky130::unionbox $cext [sky130::draw_contact 0 ${cdw} \
4620 ${diff_surround} ${metal_surround} ${contact_size}\
4621 ${diff_type} ${diff_contact_type} li vert]]
4622 popbox
4623 # Left diffusion contact
4624 pushbox
4625 box move w ${he}um
4626 box move w ${gate_to_diffcont}um
4627 set cext [sky130::unionbox $cext [sky130::draw_contact 0 ${cdw} \
4628 ${diff_surround} ${metal_surround} ${contact_size} \
4629 ${diff_type} ${diff_contact_type} li vert]]
4630 set diffarea $cext
4631 popbox
4632 # Top poly contact
4633 if {$topc} {
4634 pushbox
4635 box move n ${hw}um
4636 box move n ${gate_to_polycont}um
4637 set cext [sky130::unionbox $cext [sky130::draw_contact ${cpl} 0 \
4638 ${poly_surround} ${metal_surround} ${contact_size} \
4639 ${poly_type} ${poly_contact_type} li horz]]
4640 popbox
4641 }
4642 # Bottom poly contact
4643 if {$botc} {
4644 pushbox
4645 box move s ${hw}um
4646 box move s ${gate_to_polycont}um
4647 set cext [sky130::unionbox $cext [sky130::draw_contact ${cpl} 0 \
4648 ${poly_surround} ${metal_surround} ${contact_size} \
4649 ${poly_type} ${poly_contact_type} li horz]]
4650 popbox
4651 }
4652
4653 # Now draw the gate, after contacts have been drawn
4654 pushbox
4655 box values {*}${gaterect}
4656 # gate_type need not be defined if poly over diff paints the right type.
4657 catch {paint ${gate_type}}
4658 # sub_surround_dev, if defined, may create a larger area around the gate
4659 # than sub_surround creates around the diffusion/poly area.
4660 if [dict exists $parameters sub_surround_dev] {
4661 box grow n ${sub_surround_dev}um
4662 box grow s ${sub_surround_dev}um
4663 box grow e ${sub_surround_dev}um
4664 box grow w ${sub_surround_dev}um
4665 paint ${dev_sub_type}
4666 set cext [sky130::unionbox $cext [sky130::getbox]]
4667 }
4668 popbox
4669
4670 if {$dev_sub_type != ""} {
4671 box values [lindex $diffarea 0]um [lindex $diffarea 1]um \
4672 [lindex $diffarea 2]um [lindex $diffarea 3]um
4673 box grow n ${sub_surround}um
4674 box grow s ${sub_surround}um
4675 box grow e ${sub_surround}um
4676 box grow w ${sub_surround}um
4677 paint ${dev_sub_type}
4678 set cext [sky130::unionbox $cext [sky130::getbox]]
4679 # puts stdout "Diagnostic: bounding box is $cext"
4680 }
4681
4682 popbox
4683 return $cext
4684}
4685
4686#----------------------------------------------------------------
4687# MOSFET: Draw the tiled device
4688#----------------------------------------------------------------
4689
4690proc sky130::mos_draw {parameters} {
4691 tech unlock *
4692 set savesnap [snap]
4693 snap internal
4694
4695 # Set defaults if they are not in parameters
4696 set poverlap 0 ;# overlap poly contacts when tiling
4697 set doverlap 1 ;# overlap diffusion contacts when tiling
4698 set dev_sub_dist 0 ;# substrate to guard ring, if dev_sub_type defined
4699 set dev_sub_space 0 ;# distance between substrate areas for arrayed devices
4700 set min_allc 0 ;# gate length below which poly contacts must be interleaved
4701 set id_type "" ;# additional type covering everything
4702 set id_surround 0 ;# amount of surround on above type
4703 set id2_type "" ;# additional type covering everything
4704 set id2_surround 0 ;# amount of surround on above type
4705
4706 # Set a local variable for each parameter (e.g., $l, $w, etc.)
4707 foreach key [dict keys $parameters] {
4708 set $key [dict get $parameters $key]
4709 }
4710
4711 # Diff-to-tap spacing is by default the same as diff spacing
4712 if {![dict exist $parameters diff_tap_space]} {
4713 set diff_tap_space $diff_spacing
4714 }
4715
4716 # If poverlap is 1 then both poly contacts must be present
4717 if {$poverlap == 1} {
4718 set topc 1
4719 set botc 1
4720 dict set parameters topc 1
4721 dict set parameters botc 1
4722 }
4723
4724 # Normalize distance units to microns
4725 set w [magic::spice2float $w]
4726 set l [magic::spice2float $l]
4727
4728 pushbox
4729 box values 0 0 0 0
4730
4731 # If dx < (poly contact space + poly contact width), then there is not
4732 # enough room for a row of contacts, so force alternating contacts
4733
4734 if {$nf > 1 && $l < $min_allc} {
4735 set intc 1
4736 set evenodd 1
4737 set topc 1
4738 set botc 1
4739 dict set parameters topc 1
4740 dict set parameters botc 1
4741 set poverlap 0
4742 } else {
4743 set intc 0
4744 }
4745
4746 # Determine the base device dimensions by drawing one device
4747 # while all layers are locked (nothing drawn). This allows the
4748 # base drawing routine to do complicated geometry without having
4749 # to duplicate it here with calculations.
4750
4751 tech lock *
4752 set bbox [sky130::mos_device $parameters]
4753 # puts stdout "Diagnostic: Device bounding box e $bbox (um)"
4754 tech unlock *
4755
4756 set fw [- [lindex $bbox 2] [lindex $bbox 0]]
4757 set fh [- [lindex $bbox 3] [lindex $bbox 1]]
4758 set lw [+ [lindex $bbox 2] [lindex $bbox 0]]
4759 set lh [+ [lindex $bbox 3] [lindex $bbox 1]]
4760
4761 # If dev_sub_dist > 0 then each device must be in its own substrate
4762 # (well) area, and overlaps are disallowed. dev_sub_space determines
4763 # the distance between individual devices in an array.
4764
4765 if {$dev_sub_dist > 0} {
4766 set poverlap 0
4767 set doverlap 0
4768
4769 if {$dev_sub_space > $poly_spacing} {
4770 set dx [+ $fw $dev_sub_space]
4771 set dy [+ $fh $dev_sub_space]
4772 } else {
4773 set dx [+ $fw $poly_spacing]
4774 set dy [+ $fh $poly_spacing]
4775 }
4776
4777 } else {
4778
4779 # Determine tile width and height (depends on overlap)
4780 if {$poverlap == 0} {
4781 set dy [+ $fh $poly_spacing]
4782 } else {
4783 # overlap poly
4784 set dy [- $fh [+ $poly_surround $poly_surround $contact_size]]
4785 }
4786
4787 if {$doverlap == 0} {
4788 set dx [+ $fw $diff_spacing]
4789 } else {
4790 # overlap diffusions
4791 set dx [- $fw [+ $diff_surround $diff_surround $contact_size]]
4792 }
4793 }
4794
4795 # Determine core width and height
4796 set corex [+ [* [- $nf 1] $dx] $fw]
4797 set corey [+ [* [- $m 1] $dy] $fh]
4798 set corellx [/ [+ [- $corex $fw] $lw] 2.0]
4799 set corelly [/ [+ [- $corey $fh] $lh] 2.0]
4800
4801 # If there is a diffusion dogbone, and no top poly contact, then
4802 # increase the core height by the amount of the dogbone overhang.
4803
4804 if {$topc == 0} {
4805 set cdwmin [+ ${contact_size} [* ${diff_surround} 2]]
4806 if {${w} < ${cdwmin}} {
4807 set corey [+ $corey [/ [- ${cdwmin} ${w}] 2.0]]
4808 }
4809 }
4810
4811 if {$guard != 0} {
4812 # Calculate guard ring size (measured to contact center)
4813 if {($dev_sub_dist > 0) && ([+ $dev_sub_dist $sub_surround] > $diff_tap_space)} {
4814 set gx [+ $corex [* 2.0 [+ $dev_sub_dist $diff_surround]] $contact_size]
4815 } else {
4816 set gx [+ $corex [* 2.0 [+ $diff_tap_space $diff_surround]] $contact_size]
4817 }
4818 if {($dev_sub_dist > 0) && ([+ $dev_sub_dist $sub_surround] > $diff_gate_space)} {
4819 set gy [+ $corey [* 2.0 [+ $dev_sub_dist $diff_surround]] $contact_size]
4820 } else {
4821 set gy [+ $corey [* 2.0 [+ $diff_gate_space $diff_surround]] $contact_size]
4822 }
4823
4824 # Somewhat tricky. . . if the width is small and the diffusion is
4825 # a dogbone, and the top or bottom poly contact is missing, then
4826 # the spacing to the guard ring may be limited by diffusion spacing, not
4827 # poly to diffusion.
4828
4829 set inset [/ [+ $contact_size [* 2.0 $diff_surround] -$w] 2.0]
4830 set sdiff [- [+ $inset $diff_tap_space] [+ $gate_extension $diff_gate_space]]
4831
4832 if {$sdiff > 0} {
4833 if {$topc == 0} {
4834 set gy [+ $gy $sdiff]
4835 set corelly [+ $corelly [/ $sdiff 2.0]]
4836 }
4837 if {$botc == 0} {
4838 set gy [+ $gy $sdiff]
4839 set corelly [- $corelly [/ $sdiff 2.0]]
4840 }
4841 }
4842
4843 # Draw the guard ring first, as MOS well may interact with guard ring substrate
4844 sky130::guard_ring $gx $gy $parameters
4845 }
4846
4847 pushbox
4848 # If any surrounding identifier type is defined, draw it
4849 if {${id_type} != ""} {
4850 set hw [/ $gx 2]
4851 set hh [/ $gy 2]
4852 box grow e ${hw}um
4853 box grow w ${hw}um
4854 box grow n ${hh}um
4855 box grow s ${hh}um
4856 box grow c ${id_surround}um
4857 paint ${id_type}
4858 }
4859 popbox
4860 pushbox
4861 box move w ${corellx}um
4862 box move s ${corelly}um
4863 for {set xp 0} {$xp < $nf} {incr xp} {
4864 pushbox
4865 if {$intc == 1} {
4866 set evenodd [- 1 $evenodd]
4867 if {$evenodd == 1} {
4868 dict set parameters topc 1
4869 dict set parameters botc 0
4870 } else {
4871 dict set parameters topc 0
4872 dict set parameters botc 1
4873 }
4874 set saveeo $evenodd
4875 }
4876 for {set yp 0} {$yp < $m} {incr yp} {
4877 sky130::mos_device $parameters
4878 box move n ${dy}um
4879 if {$intc == 1} {
4880 set evenodd [- 1 $evenodd]
4881 if {$evenodd == 1} {
4882 dict set parameters topc 1
4883 dict set parameters botc 0
4884 } else {
4885 dict set parameters topc 0
4886 dict set parameters botc 1
4887 }
4888 }
4889 }
4890 if {$intc == 1} {
4891 set evenodd $saveeo
4892 }
4893 popbox
4894 box move e ${dx}um
4895 }
4896 popbox
4897 popbox
4898
4899 snap $savesnap
4900 tech revert
4901}
4902
4903#-------------------
4904# nMOS 1.8V
4905#-------------------
4906
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004907proc sky130::sky130_fd_pr__nfet_01v8_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004908 set newdict [dict create \
4909 gate_type nfet \
4910 diff_type ndiff \
4911 diff_contact_type ndc \
4912 plus_diff_type psd \
4913 plus_contact_type psc \
4914 poly_type poly \
4915 poly_contact_type pc \
4916 sub_type psub \
4917 min_effl 0.185 \
4918 min_allc 0.26 \
4919 ]
4920 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4921 return [sky130::mos_draw $drawdict]
4922}
4923
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004924proc sky130::sky130_fd_pr__nfet_01v8_lvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004925 set newdict [dict create \
4926 gate_type nfetlvt \
4927 diff_type ndiff \
4928 diff_contact_type ndc \
4929 plus_diff_type psd \
4930 plus_contact_type psc \
4931 poly_type poly \
4932 poly_contact_type pc \
4933 sub_type psub \
4934 min_effl 0.185 \
4935 min_allc 0.26 \
4936 ]
4937 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4938 return [sky130::mos_draw $drawdict]
4939}
4940
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004941proc sky130::sky130_fd_bs_flash__special_sonosfet_star_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004942 set newdict [dict create \
4943 gate_type nsonos \
4944 diff_type ndiff \
4945 diff_contact_type ndc \
4946 plus_diff_type psd \
4947 plus_contact_type psc \
4948 poly_type poly \
4949 poly_contact_type pc \
4950 sub_type psub \
4951 id_type dnwell \
4952 id_surround 1.355 \
4953 min_effl 0.185 \
4954 min_allc 0.26 \
4955 ]
4956 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4957 return [sky130::mos_draw $drawdict]
4958}
4959
4960#-------------------
4961# pMOS 1.8V
4962#-------------------
4963
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004964proc sky130::sky130_fd_pr__pfet_01v8_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004965 set newdict [dict create \
4966 gate_type pfet \
4967 diff_type pdiff \
4968 diff_contact_type pdc \
4969 plus_diff_type nsd \
4970 plus_contact_type nsc \
4971 poly_type poly \
4972 poly_contact_type pc \
4973 sub_type nwell \
4974 gate_to_polycont 0.32 \
4975 min_effl 0.185 \
4976 min_allc 0.26 \
4977 ]
4978 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4979 return [sky130::mos_draw $drawdict]
4980}
4981
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004982proc sky130::sky130_fd_pr__pfet_01v8_lvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004983 set newdict [dict create \
4984 gate_type pfetlvt \
4985 diff_type pdiff \
4986 diff_contact_type pdc \
4987 plus_diff_type nsd \
4988 plus_contact_type nsc \
4989 poly_type poly \
4990 poly_contact_type pc \
4991 sub_type nwell \
4992 gate_to_polycont 0.32 \
4993 min_effl 0.185 \
4994 min_allc 0.26 \
4995 ]
4996 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4997 return [sky130::mos_draw $drawdict]
4998}
4999
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005000proc sky130::sky130_fd_pr__pfet_01v8_hvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005001 set newdict [dict create \
5002 gate_type pfethvt \
5003 diff_type pdiff \
5004 diff_contact_type pdc \
5005 plus_diff_type nsd \
5006 plus_contact_type nsc \
5007 poly_type poly \
5008 poly_contact_type pc \
5009 sub_type nwell \
5010 gate_to_polycont 0.32 \
5011 min_effl 0.185 \
5012 min_allc 0.26 \
5013 ]
5014 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
5015 return [sky130::mos_draw $drawdict]
5016}
5017
5018#-------------------
5019# pMOS 5.0V
5020#-------------------
5021
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005022proc sky130::sky130_fd_pr__pfet_g5v0d10v5_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005023 set newdict [dict create \
5024 gate_type mvpfet \
5025 diff_type mvpdiff \
5026 diff_contact_type mvpdc \
5027 plus_diff_type mvnsd \
5028 plus_contact_type mvnsc \
5029 poly_type poly \
5030 poly_contact_type pc \
5031 sub_type nwell \
5032 guard_sub_surround 0.33 \
5033 gate_to_polycont 0.32 \
5034 diff_spacing 0.31 \
5035 diff_tap_space 0.38 \
5036 diff_gate_space 0.38 \
5037 ]
5038 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
5039 return [sky130::mos_draw $drawdict]
5040}
5041
5042#-------------------
5043# nMOS 5.0V
5044#-------------------
5045
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005046proc sky130::sky130_fd_pr__nfet_g5v0d10v5_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005047 set newdict [dict create \
5048 gate_type mvnfet \
5049 diff_type mvndiff \
5050 diff_contact_type mvndc \
5051 plus_diff_type mvpsd \
5052 plus_contact_type mvpsc \
5053 poly_type poly \
5054 poly_contact_type pc \
5055 sub_type psub \
5056 diff_spacing 0.31 \
5057 diff_tap_space 0.38 \
5058 diff_gate_space 0.38 \
5059 ]
5060 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
5061 return [sky130::mos_draw $drawdict]
5062}
5063
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005064proc sky130::sky130_fd_pr__nfet_05v0_nvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005065 set newdict [dict create \
5066 gate_type mvnnfet \
5067 diff_type mvndiff \
5068 diff_contact_type mvndc \
5069 plus_diff_type mvpsd \
5070 plus_contact_type mvpsc \
5071 poly_type poly \
5072 poly_contact_type pc \
5073 sub_type psub \
5074 diff_spacing 0.30 \
5075 diff_tap_space 0.38 \
5076 diff_gate_space 0.38 \
5077 ]
5078 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
5079 return [sky130::mos_draw $drawdict]
5080}
5081
5082#------------------------
5083# MOS varactor (1.8V)
5084#------------------------
5085
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005086proc sky130::sky130_fd_pr__cap_var_lvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005087 set newdict [dict create \
5088 gate_type var \
5089 diff_type nnd \
5090 diff_contact_type nsc \
5091 plus_diff_type psd \
5092 plus_contact_type psc \
5093 poly_type poly \
5094 poly_contact_type pc \
5095 sub_type psub \
5096 dev_sub_type nwell \
5097 diff_overlap_cont 0.06 \
5098 dev_sub_dist 0.14 \
5099 dev_sub_space 1.27 \
5100 gate_to_diffcont 0.34 \
5101 diff_extension 0.485 \
5102 ]
5103 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
5104 return [sky130::mos_draw $drawdict]
5105}
5106
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005107proc sky130::sky130_fd_pr__cap_var_hvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005108 set newdict [dict create \
5109 gate_type varhvt \
5110 diff_type nnd \
5111 diff_contact_type nsc \
5112 plus_diff_type psd \
5113 plus_contact_type psc \
5114 poly_type poly \
5115 poly_contact_type pc \
5116 sub_type psub \
5117 dev_sub_type nwell \
5118 diff_overlap_cont 0.06 \
5119 dev_sub_dist 0.14 \
5120 dev_sub_space 1.27 \
5121 gate_to_diffcont 0.34 \
5122 diff_extension 0.485 \
5123 ]
5124 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
5125 return [sky130::mos_draw $drawdict]
5126}
5127
5128#---------------------------------------------------------
5129# MOS varactor (5.0V)
5130# NOTE: dev_sub_space set to 2.0 assuming different nets.
5131# Should have option for same-net with merged wells.
5132#---------------------------------------------------------
5133
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005134proc sky130::sky130_fd_pr__cap_var_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005135 set newdict [dict create \
5136 gate_type mvvar \
5137 diff_type mvnsd \
5138 diff_contact_type mvnsc \
5139 plus_diff_type mvpsd \
5140 plus_contact_type mvpsc \
5141 poly_type poly \
5142 poly_contact_type pc \
5143 sub_type psub \
5144 dev_sub_type nwell \
5145 sub_surround 0.38 \
5146 sub_surround_dev 0.56 \
5147 guard_sub_surround 0.18 \
5148 diff_overlap_cont 0.06 \
5149 dev_sub_dist 0.785 \
5150 dev_sub_space 2.0 \
5151 gate_to_diffcont 0.34 \
5152 diff_extension 0.485 \
5153 ]
5154 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
5155 return [sky130::mos_draw $drawdict]
5156}
5157
5158#----------------------------------------------------------------
5159# MOSFET: Check device parameters for out-of-bounds values
5160#----------------------------------------------------------------
5161
5162proc sky130::mos_check {device parameters} {
5163
5164 # Set a local variable for each parameter (e.g., $l, $w, etc.)
5165 foreach key [dict keys $parameters] {
5166 set $key [dict get $parameters $key]
5167 }
5168
5169 # Normalize distance units to microns
5170 set l [magic::spice2float $l]
5171 set l [magic::3digitpastdecimal $l]
5172 set w [magic::spice2float $w]
5173 set w [magic::3digitpastdecimal $w]
5174
5175 # nf, m must be integer
5176 if {![string is int $nf]} {
5177 puts stderr "NF must be an integer!"
5178 dict set parameters nf 1
5179 }
5180 if {![string is int $m]} {
5181 puts stderr "M must be an integer!"
5182 dict set parameters m 1
5183 }
5184 # diffcov, polycov must be numeric
5185 if {[catch {expr abs($diffcov)}]} {
5186 puts stderr "diffcov must be numeric!"
5187 set diffcov 100
5188 }
5189 if {[catch {expr abs($polycov)}]} {
5190 puts stderr "polycov must be numeric!"
5191 set polycov 100
5192 }
5193
5194 if {$l < $lmin} {
5195 puts stderr "Mos length must be >= $lmin um"
5196 dict set parameters l $lmin
5197 }
5198 if {$w < $wmin} {
5199 puts stderr "Mos width must be >= $wmin um"
5200 dict set parameters w $wmin
5201 }
5202 if {$nf < 1} {
5203 puts stderr "NF must be >= 1"
5204 dict set parameters nf 1
5205 }
5206 if {$m < 1} {
5207 puts stderr "M must be >= 1"
5208 dict set parameters m 1
5209 }
5210 if {$diffcov < 20 } {
5211 puts stderr "Diffusion contact coverage must be at least 20%"
5212 dict set parameters diffcov 20
5213 } elseif {$diffcov > 100 } {
5214 puts stderr "Diffusion contact coverage can't be more than 100%"
5215 dict set parameters diffcov 100
5216 }
5217 if {$polycov < 20 } {
5218 puts stderr "Poly contact coverage must be at least 20%"
5219 dict set parameters polycov 20
5220 } elseif {$polycov > 100 } {
5221 puts stderr "Poly contact coverage can't be more than 100%"
5222 dict set parameters polycov 100
5223 }
5224
5225 # Values must satisfy diffusion-to-tap spacing of 20um.
5226 # Therefore the maximum of guard ring width or height cannot exceed 40um.
5227 # If in violation, reduce counts first, as these are easiest to recover
5228 # by duplicating the device and overlapping the wells.
5229 set origm $m
5230 set orignf $nf
5231 while true {
5232 set yext [expr ($w + 3.0) * $m]
5233 set xext [expr ($l + 1.0) * $nf + 1.1]
5234 if {[expr min($xext, $yext)] > 40.0} {
5235 if {$yext > 40.0 && $m > 1} {
5236 incr m -1
5237 } elseif {$xext > 40.0 && $nf > 1} {
5238 incr nf -1
5239 } elseif {$yext > 40.0} {
5240 set w 37
5241 puts -nonewline stderr "Transistor width must be < 37 um"
5242 puts stderr " to avoid tap spacing violation."
5243 dict set parameters w $w
5244 } elseif {$xext > 40.0} {
5245 set l 37.9
5246 puts -nonewline stderr "Transistor length must be < 37.9 um"
5247 puts stderr " to avoid tap spacing violation."
5248 dict set parameters l $l
5249 }
5250 } else {
5251 break
5252 }
5253 }
5254 if {$m != $origm} {
5255 puts stderr "Y repeat reduced to prevent tap distance violation"
5256 dict set parameters m $m
5257 }
5258 if {$nf != $orignf} {
5259 puts stderr "X repeat reduced to prevent tap distance violation"
5260 dict set parameters nf $nf
5261 }
5262
5263 return $parameters
5264}
5265
5266#----------------------------------------------------------------
5267
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005268proc sky130::sky130_fd_pr__nfet_01v8_check {parameters} {
5269 return [sky130::mos_check sky130_fd_pr__nfet_01v8 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005270}
5271
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005272proc sky130::sky130_fd_pr__nfet_01v8_lvt_check {parameters} {
5273 return [sky130::mos_check sky130_fd_pr__nfet_01v8_lvt $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005274}
5275
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005276proc sky130::sky130_fd_bs_flash__special_sonosfet_star_check {parameters} {
5277 return [sky130::mos_check sky130_fd_bs_flash__special_sonosfet_star $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005278}
5279
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005280proc sky130::sky130_fd_pr__nfet_g5v0d10v5_check {parameters} {
5281 return [sky130::mos_check sky130_fd_pr__nfet_g5v0d10v5 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005282}
5283
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005284proc sky130::sky130_fd_pr__nfet_05v0_nvt_check {parameters} {
5285 return [sky130::mos_check sky130_fd_pr__nfet_05v0_nvt $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005286}
5287
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005288proc sky130::sky130_fd_pr__pfet_01v8_check {parameters} {
5289 return [sky130::mos_check sky130_fd_pr__pfet_01v8 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005290}
5291
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005292proc sky130::sky130_fd_pr__pfet_01v8_lvt_check {parameters} {
5293 return [sky130::mos_check sky130_fd_pr__pfet_01v8_lvt $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005294}
5295
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005296proc sky130::sky130_fd_pr__pfet_01v8_hvt_check {parameters} {
5297 return [sky130::mos_check sky130_fd_pr__pfet_01v8_hvt $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005298}
5299
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005300proc sky130::sky130_fd_pr__pfet_g5v0d10v5_check {parameters} {
5301 return [sky130::mos_check sky130_fd_pr__pfet_g5v0d10v5 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005302}
5303
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005304proc sky130::sky130_fd_pr__cap_var_lvt_check {parameters} {
5305 return [sky130::mos_check sky130_fd_pr__cap_var_lvt $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005306}
5307
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005308proc sky130::sky130_fd_pr__cap_var_hvt_check {parameters} {
5309 return [sky130::mos_check sky130_fd_pr__cap_var_hvt $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005310}
5311
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005312proc sky130::sky130_fd_pr__cap_var_check {parameters} {
5313 return [sky130::mos_check sky130_fd_pr__cap_var $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005314}
5315
5316#----------------------------------------------------------------
5317# Fixed device: Specify all user-editable default values
5318#
5319# deltax --- Additional horizontal space between devices
5320# deltay --- Additional vertical space between devices
5321# nx --- Number of arrayed devices in X
5322# ny --- Number of arrayed devices in Y
5323#
5324# Note that these values, specifically nx, ny, deltax,
5325# and deltay, are properties of the instance, not the cell.
5326# They translate to the instance array x and y counts; while
5327# deltax is the x pitch less the cell width, and deltay is the
5328# y pitch less the cell height.
5329#
5330# non-user-editable
5331#
5332# nocell --- Indicates that this cell has a predefined layout
5333# and therefore there is no cell to draw.
5334# xstep --- Width of the cell (nominal array pitch in X)
5335# ystep --- Height of the cell (nominal array pitch in Y)
5336#----------------------------------------------------------------
5337
5338# Fixed-layout devices (from sky130_fd_pr_base, _rf, and _rf2 libraries)
5339#
5340# Bipolar transistors:
5341#
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005342# sky130_fd_pr__npn_05v5_W1p00L1p00
5343# sky130_fd_pr__npn_05v5_W1p00L2p00
5344# sky130_fd_pr__pnp_05v5_W0p68L0p68
5345# sky130_fd_pr__pnp_05v5_W3p40L3p40
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005346#
5347# Parallel Plate Capacitors:
5348#
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005349# sky130_fd_pr__cap_vpp_11p5x11p7_lim5_shield
5350# sky130_fd_pr__cap_vpp_11p5x11p7_m3_lim5_shield
5351# sky130_fd_pr__cap_vpp_11p5x11p7_m4_shield
5352# sky130_fd_pr__cap_vpp_11p5x11p7_pom4_shield
5353# sky130_fd_pr__cap_vpp_4p4x4p6_m3_lim5_shield
5354# sky130_fd_pr__cap_vpp_6p8x6p1_lim4_shield
5355# sky130_fd_pr__cap_vpp_6p8x6p1_pom4_shield
5356# sky130_fd_pr__cap_vpp_8p6x7p9_m3_lim5_shield
5357# sky130_fd_pr__cap_vpp_11p5x11p7_m3_li_shield
5358# sky130_fd_pr__cap_vpp_11p5x11p7_m3_shield
5359# sky130_fd_pr__cap_vpp_1p8x1p8_li_shield
5360# sky130_fd_pr__cap_vpp_1p8x1p8_m3_shield
5361# sky130_fd_pr__cap_vpp_4p4x4p6_m3_li_shield
5362# sky130_fd_pr__cap_vpp_4p4x4p6_m3_shield
5363# sky130_fd_pr__cap_vpp_8p6x7p9_m3_li_shield
5364# sky130_fd_pr__cap_vpp_8p6x7p9_m3_shield
5365#ifdef REDISTRIBUTION
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005366#
5367# Inductors:
5368#
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005369# sky130_fd_pr__ind_01_04
5370# sky130_fd_pr__ind_02_04
5371#endif (REDISTRIBUTION)
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005372
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005373proc sky130::sky130_fd_pr__npn_05v5_W1p00L1p00_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005374 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 7.03 ystep 7.03}
5375}
5376
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005377proc sky130::sky130_fd_pr__npn_05v5_W1p00L2p00_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005378 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 7.03 ystep 8.03}
5379}
5380
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005381proc sky130::sky130_fd_pr__pnp_05v5_W0p68L0p68_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005382 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 6.44 ystep 6.44}
5383}
5384
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005385proc sky130::sky130_fd_pr__pnp_05v5_W3p40L3p40_defaults {} {
5386 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 6.44 ystep 6.44}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005387}
5388
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005389#ifdef REDISTRIBUTION
5390proc sky130::sky130_fd_pr__ind_02_04_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005391 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 258 ystep 258}
5392}
5393
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005394proc sky130::sky130_fd_pr__ind_01_04_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005395 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 290 ystep 404}
5396}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005397#endif (REDISTRIBUTION)
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005398
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005399proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_lim5_shield_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005400 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 11.08 ystep 11.36}
5401}
5402
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005403proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m3_lim5_shield_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005404 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 11.08 ystep 11.36}
5405}
5406
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005407proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m4_shield_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005408 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 11.08 ystep 11.36}
5409}
5410
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005411proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_pom4_shield_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005412 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 11.08 ystep 11.36}
5413}
5414
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005415proc sky130::sky130_fd_pr__cap_vpp_4p4x4p6_m3_lim5_shield_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005416 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 4.05 ystep 4.26}
5417}
5418
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005419proc sky130::sky130_fd_pr__cap_vpp_6p8x6p1_lim4_shield_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005420 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 6.47 ystep 5.76}
5421}
5422
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005423proc sky130::sky130_fd_pr__cap_vpp_6p8x6p1_pom4_shield_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005424 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 6.47 ystep 5.76}
5425}
5426
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005427proc sky130::sky130_fd_pr__cap_vpp_8p6x7p9_m3_lim5_shield_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005428 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 8.25 ystep 7.51}
5429}
5430
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005431proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m3_li_shield_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005432 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 11.08 ystep 11.36}
5433}
5434
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005435proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m3_shield_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005436 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 11.08 ystep 11.36}
5437}
5438
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005439proc sky130::sky130_fd_pr__cap_vpp_1p8x1p8_li_shield_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005440 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 1.77 ystep 1.77}
5441}
5442
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005443proc sky130::sky130_fd_pr__cap_vpp_1p8x1p8_m3_shield_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005444 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 3.88 ystep 3.88}
5445}
5446
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005447proc sky130::sky130_fd_pr__cap_vpp_4p4x4p6_m3_li_shield_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005448 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 4.05 ystep 4.26}
5449}
5450
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005451proc sky130::sky130_fd_pr__cap_vpp_4p4x4p6_m3_shield_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005452 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 4.05 ystep 4.26}
5453}
5454
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005455proc sky130::sky130_fd_pr__cap_vpp_8p6x7p9_m3_li_shield_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005456 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 8.25 ystep 7.51}
5457}
5458
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005459proc sky130::sky130_fd_pr__cap_vpp_8p6x7p9_m3_shield_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005460 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 8.25 ystep 7.51}
5461}
5462
5463#----------------------------------------------------------------
5464# Fixed device: Conversion from SPICE netlist parameters to toolkit
5465#----------------------------------------------------------------
5466
5467proc sky130::fixed_convert {parameters} {
5468 set pdkparams [dict create]
5469 dict for {key value} $parameters {
5470 switch -nocase $key {
5471 m {
5472 dict set pdkparams nx $value
5473 }
5474 }
5475 }
5476 return $pdkparams
5477}
5478
5479#----------------------------------------------------------------
5480
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005481proc sky130::sky130_fd_pr__npn_05v5_W1p00L1p00_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005482 return [sky130::fixed_convert $parameters]
5483}
5484
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005485proc sky130::sky130_fd_pr__npn_05v5_W1p00L2p00_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005486 return [sky130::fixed_convert $parameters]
5487}
5488
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005489proc sky130::sky130_fd_pr__pnp_05v5_W0p68L0p68_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005490 return [sky130::fixed_convert $parameters]
5491}
5492
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005493proc sky130::sky130_fd_pr__pnp_05v5_W3p40L3p40_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005494 return [sky130::fixed_convert $parameters]
5495}
5496
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005497#ifdef REDISTRIBUTION
5498proc sky130::sky130_fd_pr__ind_01_04_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005499 return [sky130::fixed_convert $parameters]
5500}
5501
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005502proc sky130::sky130_fd_pr__ind_02_04_convert {parameters} {
5503 return [sky130::fixed_convert $parameters]
5504}
5505#endif (REDISTRIBUTION)
5506
5507proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_lim5_shield_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005508 return [sky130::fixed_convert $parameters]
5509}
5510
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005511proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m3_lim5_shield_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005512 return [sky130::fixed_convert $parameters]
5513}
5514
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005515proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m4_shield_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005516 return [sky130::fixed_convert $parameters]
5517}
5518
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005519proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_pom4_shield_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005520 return [sky130::fixed_convert $parameters]
5521}
5522
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005523proc sky130::sky130_fd_pr__cap_vpp_4p4x4p6_m3_lim5_shield_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005524 return [sky130::fixed_convert $parameters]
5525}
5526
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005527proc sky130::sky130_fd_pr__cap_vpp_6p8x6p1_lim4_shield_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005528 return [sky130::fixed_convert $parameters]
5529}
5530
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005531proc sky130::sky130_fd_pr__cap_vpp_6p8x6p1_pom4_shield_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005532 return [sky130::fixed_convert $parameters]
5533}
5534
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005535proc sky130::sky130_fd_pr__cap_vpp_8p6x7p9_m3_lim5_shield_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005536 return [sky130::fixed_convert $parameters]
5537}
5538
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005539proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m3_li_shield_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005540 return [sky130::fixed_convert $parameters]
5541}
5542
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005543proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m3_shield_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005544 return [sky130::fixed_convert $parameters]
5545}
5546
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005547proc sky130::sky130_fd_pr__cap_vpp_1p8x1p8_li_shield_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005548 return [sky130::fixed_convert $parameters]
5549}
5550
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005551proc sky130::sky130_fd_pr__cap_vpp_1p8x1p8_m3_shield_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005552 return [sky130::fixed_convert $parameters]
5553}
5554
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005555proc sky130::sky130_fd_pr__cap_vpp_4p4x4p6_m3_li_shield_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005556 return [sky130::fixed_convert $parameters]
5557}
5558
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005559proc sky130::sky130_fd_pr__cap_vpp_4p4x4p6_m3_shield_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005560 return [sky130::fixed_convert $parameters]
5561}
5562
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005563proc sky130::sky130_fd_pr__cap_vpp_8p6x7p9_m3_li_shield_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005564 return [sky130::fixed_convert $parameters]
5565}
5566
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005567proc sky130::sky130_fd_pr__cap_vpp_8p6x7p9_m3_shield_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005568 return [sky130::fixed_convert $parameters]
5569}
5570
5571#----------------------------------------------------------------
5572# Fixed device: Interactively specifies the fixed layout parameters
5573#----------------------------------------------------------------
5574
5575proc sky130::fixed_dialog {parameters} {
5576 # Instance fields: nx, ny, pitchx, pitchy
5577 # Editable fields: nx, ny, deltax, deltay
5578 # Non-editable fields: nocell, xstep, ystep
5579
5580 # Set a local variable for each parameter (e.g., $l, $w, etc.)
5581 foreach key [dict keys $parameters] {
5582 set $key [dict get $parameters $key]
5583 }
5584
5585 # "nocell" field causes nx and ny to be dropped in from
5586 # "array count". Also "pitchx" and "pitchy" are passed
5587 # in internal units. Convert these to microns and generate
5588 # If there is no pitchx and pitchy, then the device has not
5589 # yet been created, so keep the deltax and deltay defaults.
5590
5591 if [dict exists $parameters pitchx] {
5592 set pitchux [magic::i2u $pitchx]
5593 set stepux [magic::spice2float $xstep]
5594 set deltax [magic::3digitpastdecimal [expr $pitchux - $stepux]]
5595 # An array size 1 should not cause deltax to go negative
5596 if {$deltax < 0.0} {set deltax 0.0}
5597 dict set parameters deltax $deltax
5598 }
5599 if [dict exists $parameters pitchy] {
5600 set pitchuy [magic::i2u $pitchy]
5601 set stepuy [magic::spice2float $ystep]
5602 set deltay [magic::3digitpastdecimal [expr $pitchuy - $stepuy]]
5603 # An array size 1 should not cause deltay to go negative
5604 if {$deltay < 0.0} {set deltay 0.0}
5605 dict set parameters deltay $deltay
5606 }
5607
5608 magic::add_entry nx "NX" $parameters
5609 magic::add_entry ny "NY" $parameters
5610 magic::add_entry deltax "X step (um)" $parameters
5611 magic::add_entry deltay "Y step (um)" $parameters
5612}
5613
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005614proc sky130::sky130_fd_pr__npn_05v5_W1p00L1p00_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005615 sky130::fixed_dialog $parameters
5616}
5617
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005618proc sky130::sky130_fd_pr__npn_05v5_W1p00L2p00_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005619 sky130::fixed_dialog $parameters
5620}
5621
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005622proc sky130::sky130_fd_pr__pnp_05v5_W0p68L0p68_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005623 sky130::fixed_dialog $parameters
5624}
5625
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005626proc sky130::sky130_fd_pr__pnp_05v5_W3p40L3p40_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005627 sky130::fixed_dialog $parameters
5628}
5629
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005630#ifdef REDISTRIBUTION
5631proc sky130::sky130_fd_pr__ind_01_04_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005632 sky130::fixed_dialog $parameters
5633}
5634
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005635proc sky130::sky130_fd_pr__ind_02_04_dialog {parameters} {
5636 sky130::fixed_dialog $parameters
5637}
5638#endif (REDISTRIBUTION)
5639
5640proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_lim5_shield_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005641 sky130::fixed_dialog $parameters
5642}
5643
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005644proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m3_lim5_shield_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005645 sky130::fixed_dialog $parameters
5646}
5647
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005648proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m4_shield_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005649 sky130::fixed_dialog $parameters
5650}
5651
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005652proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_pom4_shield_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005653 sky130::fixed_dialog $parameters
5654}
5655
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005656proc sky130::sky130_fd_pr__cap_vpp_4p4x4p6_m3_lim5_shield_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005657 sky130::fixed_dialog $parameters
5658}
5659
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005660proc sky130::sky130_fd_pr__cap_vpp_6p8x6p1_lim4_shield_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005661 sky130::fixed_dialog $parameters
5662}
5663
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005664proc sky130::sky130_fd_pr__cap_vpp_6p8x6p1_pom4_shield_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005665 sky130::fixed_dialog $parameters
5666}
5667
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005668proc sky130::sky130_fd_pr__cap_vpp_8p6x7p9_m3_lim5_shield_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005669 sky130::fixed_dialog $parameters
5670}
5671
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005672proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m3_li_shield_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005673 sky130::fixed_dialog $parameters
5674}
5675
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005676proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m3_shield_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005677 sky130::fixed_dialog $parameters
5678}
5679
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005680proc sky130::sky130_fd_pr__cap_vpp_1p8x1p8_li_shield_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005681 sky130::fixed_dialog $parameters
5682}
5683
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005684proc sky130::sky130_fd_pr__cap_vpp_1p8x1p8_m3_shield_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005685 sky130::fixed_dialog $parameters
5686}
5687
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005688proc sky130::sky130_fd_pr__cap_vpp_4p4x4p6_m3_li_shield_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005689 sky130::fixed_dialog $parameters
5690}
5691
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005692proc sky130::sky130_fd_pr__cap_vpp_4p4x4p6_m3_shield_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005693 sky130::fixed_dialog $parameters
5694}
5695
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005696proc sky130::sky130_fd_pr__cap_vpp_8p6x7p9_m3_li_shield_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005697 sky130::fixed_dialog $parameters
5698}
5699
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005700proc sky130::sky130_fd_pr__cap_vpp_8p6x7p9_m3_shield_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005701 sky130::fixed_dialog $parameters
5702}
5703
5704#----------------------------------------------------------------
5705# Fixed device: Draw the device
5706#----------------------------------------------------------------
5707
5708proc sky130::fixed_draw {devname parameters} {
5709
5710 # Set a local variable for each parameter (e.g., $l, $w, etc.)
5711 foreach key [dict keys $parameters] {
5712 set $key [dict get $parameters $key]
5713 }
5714
5715 # This cell declares "nocell" in parameters, so it needs to
5716 # instance the cell and set properties.
5717
5718 # Instantiate the cell. The name corresponds to the cell in the sky130_fd_pr_* directory.
5719 set instname [getcell ${devname}]
5720
5721 set deltax [magic::spice2float $deltax]
5722 set deltay [magic::spice2float $deltay]
5723 set xstep [magic::spice2float $xstep]
5724 set ystep [magic::spice2float $ystep]
5725
5726 # Array stepping
5727 if {$nx > 1 || $ny > 1} {
5728 set xstep [expr $xstep + $deltax]
5729 set ystep [expr $ystep + $deltay]
5730 box size ${xstep}um ${ystep}um
5731 array $nx $ny
5732 }
5733 select cell $instname
5734 expand
5735 return $instname
5736}
5737
5738#----------------------------------------------------------------
5739# No additional parameters declared for drawing
5740#----------------------------------------------------------------
5741
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005742proc sky130::sky130_fd_pr__npn_05v5_W1p00L1p00_draw {parameters} {
5743 return [sky130::fixed_draw sky130_fd_pr__npn_05v5_W1p00L1p00 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005744}
5745
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005746proc sky130::sky130_fd_pr__npn_05v5_W1p00L2p00_draw {parameters} {
5747 return [sky130::fixed_draw sky130_fd_pr__npn_05v5_W1p00L2p00 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005748}
5749
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005750proc sky130::sky130_fd_pr__pnp_05v5_W0p68L0p68_draw {parameters} {
5751 return [sky130::fixed_draw sky130_fd_pr__pnp_05v5_W0p68L0p68 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005752}
5753
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005754proc sky130::sky130_fd_pr__pnp_05v5_W3p40L3p40_draw {parameters} {
5755 return [sky130::fixed_draw sky130_fd_pr__pnp_05v5_W3p40L3p40 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005756}
5757
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005758#ifdef REDISTRIBUTION
5759proc sky130::sky130_fd_pr__ind_01_04_draw {parameters} {
5760 return [sky130::fixed_draw sky130_fd_pr__ind_01_04 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005761}
5762
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005763proc sky130::sky130_fd_pr__ind_02_04_draw {parameters} {
5764 return [sky130::fixed_draw sky130_fd_pr__ind_02_04 $parameters]
5765}
5766#endif (REDISTRIBUTION)
5767
5768proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_lim5_shield_draw {parameters} {
5769 return [sky130::fixed_draw sky130_fd_pr__cap_vpp_11p5x11p7_lim5_shield $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005770}
5771
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005772proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m3_lim5_shield_draw {parameters} {
5773 return [sky130::fixed_draw sky130_fd_pr__cap_vpp_11p5x11p7_m3_lim5_shield $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005774}
5775
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005776proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m4_shield_draw {parameters} {
5777 return [sky130::fixed_draw sky130_fd_pr__cap_vpp_11p5x11p7_m4_shield $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005778}
5779
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005780proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_pom4_shield_draw {parameters} {
5781 return [sky130::fixed_draw sky130_fd_pr__cap_vpp_11p5x11p7_pom4_shield $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005782}
5783
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005784proc sky130::sky130_fd_pr__cap_vpp_4p4x4p6_m3_lim5_shield_draw {parameters} {
5785 return [sky130::fixed_draw sky130_fd_pr__cap_vpp_4p4x4p6_m3_lim5_shield $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005786}
5787
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005788proc sky130::sky130_fd_pr__cap_vpp_6p8x6p1_lim4_shield_draw {parameters} {
5789 return [sky130::fixed_draw sky130_fd_pr__cap_vpp_6p8x6p1_lim4_shield $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005790}
5791
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005792proc sky130::sky130_fd_pr__cap_vpp_6p8x6p1_pom4_shield_draw {parameters} {
5793 return [sky130::fixed_draw sky130_fd_pr__cap_vpp_6p8x6p1_pom4_shield $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005794}
5795
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005796proc sky130::sky130_fd_pr__cap_vpp_8p6x7p9_m3_lim5_shield_draw {parameters} {
5797 return [sky130::fixed_draw sky130_fd_pr__cap_vpp_8p6x7p9_m3_lim5_shield $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005798}
5799
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005800proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m3_li_shield_draw {parameters} {
5801 return [sky130::fixed_draw sky130_fd_pr__cap_vpp_11p5x11p7_m3_li_shield $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005802}
5803
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005804proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m3_shield_draw {parameters} {
5805 return [sky130::fixed_draw sky130_fd_pr__cap_vpp_11p5x11p7_m3_shield $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005806}
5807
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005808proc sky130::sky130_fd_pr__cap_vpp_1p8x1p8_li_shield_draw {parameters} {
5809 return [sky130::fixed_draw sky130_fd_pr__cap_vpp_1p8x1p8_li_shield $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005810}
5811
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005812proc sky130::sky130_fd_pr__cap_vpp_1p8x1p8_m3_shield_draw {parameters} {
5813 return [sky130::fixed_draw sky130_fd_pr__cap_vpp_1p8x1p8_m3_shield $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005814}
5815
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005816proc sky130::sky130_fd_pr__cap_vpp_4p4x4p6_m3_li_shield_draw {parameters} {
5817 return [sky130::fixed_draw sky130_fd_pr__cap_vpp_4p4x4p6_m3_li_shield $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005818}
5819
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005820proc sky130::sky130_fd_pr__cap_vpp_4p4x4p6_m3_shield_draw {parameters} {
5821 return [sky130::fixed_draw sky130_fd_pr__cap_vpp_4p4x4p6_m3_shield $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005822}
5823
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005824proc sky130::sky130_fd_pr__cap_vpp_8p6x7p9_m3_li_shield_draw {parameters} {
5825 return [sky130::fixed_draw sky130_fd_pr__cap_vpp_8p6x7p9_m3_li_shield $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005826}
5827
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005828proc sky130::sky130_fd_pr__cap_vpp_8p6x7p9_m3_shield_draw {parameters} {
5829 return [sky130::fixed_draw sky130_fd_pr__cap_vpp_8p6x7p9_m3_shield $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005830}
5831
5832#----------------------------------------------------------------
5833# Fixed device: Check device parameters for out-of-bounds values
5834#----------------------------------------------------------------
5835
5836proc sky130::fixed_check {parameters} {
5837
5838 # Set a local variable for each parameter (e.g., $l, $w, etc.)
5839 foreach key [dict keys $parameters] {
5840 set $key [dict get $parameters $key]
5841 }
5842
5843 # Normalize distance units to microns
5844 set deltax [magic::spice2float $deltax -1]
5845 set deltax [magic::3digitpastdecimal $deltax]
5846 set deltay [magic::spice2float $deltay -1]
5847 set deltay [magic::3digitpastdecimal $deltay]
5848
5849 # nx, ny must be integer
5850 if {![string is int $nx]} {
5851 puts stderr "NX must be an integer!"
5852 dict set parameters nx 1
5853 }
5854 if {![string is int $ny]} {
5855 puts stderr "NY must be an integer!"
5856 dict set parameters nx 1
5857 }
5858
5859 # Number of devices in X and Y must be at least 1
5860 if {$nx < 1} {
5861 puts stderr "NX must be >= 1"
5862 dict set parameters nx 1
5863 }
5864 if {$ny < 1} {
5865 puts stderr "NY must be >= 1"
5866 dict set parameters nx 1
5867 }
5868 # Step less than zero violates DRC
5869 if {$deltax < 0} {
5870 puts stderr "X step must be >= 0"
5871 dict set parameters deltax 0
5872 }
5873 if {$deltay < 0} {
5874 puts stderr "Y step must be >= 0"
5875 dict set parameters deltay 0
5876 }
5877 return $parameters
5878}
5879
5880#----------------------------------------------------------------
5881
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005882proc sky130::sky130_fd_pr__npn_05v5_W1p00L1p00_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005883 return [sky130::fixed_check $parameters]
5884}
5885
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005886proc sky130::sky130_fd_pr__npn_05v5_W1p00L2p00_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005887 return [sky130::fixed_check $parameters]
5888}
5889
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005890proc sky130::sky130_fd_pr__pnp_05v5_W0p68L0p68_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005891 return [sky130::fixed_check $parameters]
5892}
5893
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005894proc sky130::sky130_fd_pr__pnp_05v5_W3p40L3p40_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005895 return [sky130::fixed_check $parameters]
5896}
5897
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005898#ifdef REDISTRIBUTION
5899proc sky130::sky130_fd_pr__ind_01_04_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005900 return [sky130::fixed_check $parameters]
5901}
5902
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005903proc sky130::sky130_fd_pr__ind_02_04_check {parameters} {
5904 return [sky130::fixed_check $parameters]
5905}
5906#endif (REDISTRIBUTION)
5907
5908proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_lim5_shield_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005909 return [sky130::fixed_check $parameters]
5910}
5911
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005912proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m3_lim5_shield_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005913 return [sky130::fixed_check $parameters]
5914}
5915
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005916proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m4_shield_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005917 return [sky130::fixed_check $parameters]
5918}
5919
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005920proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_pom4_shield_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005921 return [sky130::fixed_check $parameters]
5922}
5923
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005924proc sky130::sky130_fd_pr__cap_vpp_4p4x4p6_m3_lim5_shield_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005925 return [sky130::fixed_check $parameters]
5926}
5927
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005928proc sky130::sky130_fd_pr__cap_vpp_6p8x6p1_lim4_shield_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005929 return [sky130::fixed_check $parameters]
5930}
5931
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005932proc sky130::sky130_fd_pr__cap_vpp_6p8x6p1_pom4_shield_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005933 return [sky130::fixed_check $parameters]
5934}
5935
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005936proc sky130::sky130_fd_pr__cap_vpp_8p6x7p9_m3_lim5_shield_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005937 return [sky130::fixed_check $parameters]
5938}
5939
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005940proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m3_li_shield_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005941 return [sky130::fixed_check $parameters]
5942}
5943
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005944proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m3_shield_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005945 return [sky130::fixed_check $parameters]
5946}
5947
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005948proc sky130::sky130_fd_pr__cap_vpp_1p8x1p8_li_shield_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005949 return [sky130::fixed_check $parameters]
5950}
5951
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005952proc sky130::sky130_fd_pr__cap_vpp_1p8x1p8_m3_shield_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005953 return [sky130::fixed_check $parameters]
5954}
5955
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005956proc sky130::sky130_fd_pr__cap_vpp_4p4x4p6_m3_li_shield_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005957 return [sky130::fixed_check $parameters]
5958}
5959
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005960proc sky130::sky130_fd_pr__cap_vpp_4p4x4p6_m3_shield_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005961 return [sky130::fixed_check $parameters]
5962}
5963
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005964proc sky130::sky130_fd_pr__cap_vpp_8p6x7p9_m3_li_shield_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005965 return [sky130::fixed_check $parameters]
5966}
5967
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005968proc sky130::sky130_fd_pr__cap_vpp_8p6x7p9_m3_shield_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005969 return [sky130::fixed_check $parameters]
5970}
5971