blob: bcf4df59adab6b01ad76f83d3573a1c366097cf3 [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
Tim Edwards708a9422021-03-09 22:07:22 -050032set Opts(hidespecial) 0
Tim Edwards55f4d0e2020-07-05 15:41:02 -040033
34# Wrap the closewrapper procedure so that closing the last
35# window is equivalent to quitting.
36if {[info commands closewrapper] == "closewrapper"} {
37 rename closewrapper closewrapperonly
38 proc closewrapper { framename } {
39 if {[llength [windownames all]] <= 1} {
40 magic::quit
41 } else {
42 closewrapperonly $framename
43 }
44 }
45}
46
47# Remove maze router layers from the toolbar by locking them
48tech lock fence,magnet,rotate
49
50namespace eval sky130 {
51 namespace path {::tcl::mathop ::tcl::mathfunc}
52
53 set ruleset [dict create]
54
55 # Process DRC rules (magic style)
56
57 dict set ruleset poly_surround 0.08 ;# Poly surrounds contact
58 dict set ruleset diff_surround 0.06 ;# Diffusion surrounds contact
59 dict set ruleset gate_to_diffcont 0.145 ;# Gate to diffusion contact center
60 dict set ruleset gate_to_polycont 0.275 ;# Gate to poly contact center
61 dict set ruleset gate_extension 0.13 ;# Poly extension beyond gate
62 dict set ruleset diff_extension 0.29 ;# Diffusion extension beyond gate
63 dict set ruleset contact_size 0.17 ;# Minimum contact size
64 dict set ruleset via_size 0.17 ;# Minimum via size
65 dict set ruleset metal_surround 0.08 ;# Local interconnect overlaps contact
66 dict set ruleset sub_surround 0.18 ;# Sub/well surrounds diffusion
67 dict set ruleset diff_spacing 0.28 ;# Diffusion spacing rule
68 dict set ruleset poly_spacing 0.21 ;# Poly spacing rule
69 dict set ruleset diff_poly_space 0.075 ;# Diffusion to poly spacing rule
70 dict set ruleset diff_gate_space 0.20 ;# Diffusion to gate poly spacing rule
71 dict set ruleset metal_spacing 0.23 ;# Local interconnect spacing rule
72 dict set ruleset mmetal_spacing 0.14 ;# Metal spacing rule (above local interconnect)
73 dict set ruleset res_to_cont 0.20 ;# resistor to contact center
74 dict set ruleset res_diff_space 0.20 ;# resistor to guard ring
75}
76
77#-----------------------------------------------------
78# magic::addtechmenu
79#-----------------------------------------------------
80
81proc sky130::addtechmenu {framename} {
82 global Winopts Opts
83
84 # Check for difference between magic 8.1.125 and earlier, and 8.1.126 and later
85 if {[catch {${framename}.titlebar cget -height}]} {
86 set layoutframe ${framename}.pane.top
87 } else {
88 set layoutframe ${framename}
89 }
90
91 # List of devices is long. Divide into two sections for active and passive deivces
92 magic::add_toolkit_menu $layoutframe "Devices 1" pdk1
93
94 magic::add_toolkit_command $layoutframe "nmos (MOSFET)" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -040095 "magic::gencell sky130::sky130_fd_pr__nfet_01v8" pdk1
Tim Edwards55f4d0e2020-07-05 15:41:02 -040096 magic::add_toolkit_command $layoutframe "pmos (MOSFET)" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -040097 "magic::gencell sky130::sky130_fd_pr__pfet_01v8" pdk1
Tim Edwards55f4d0e2020-07-05 15:41:02 -040098
99 magic::add_toolkit_separator $layoutframe pdk1
100 magic::add_toolkit_command $layoutframe "n-diode" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400101 "magic::gencell sky130::sky130_fd_pr__diode_pw2nd_05v5" pdk1
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400102 magic::add_toolkit_command $layoutframe "p-diode" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400103 "magic::gencell sky130::sky130_fd_pr__diode_pd2nw_05v5" pdk1
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400104
105 magic::add_toolkit_separator $layoutframe pdk1
106 magic::add_toolkit_command $layoutframe "MOS varactor" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400107 "magic::gencell sky130::sky130_fd_pr__cap_var_lvt" pdk1
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400108 magic::add_toolkit_separator $layoutframe pdk1
109
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400110 magic::add_toolkit_command $layoutframe "NPN 1.0 x 1.0" \
Tim Edwardsc6202ef2020-09-20 17:16:33 -0400111 "magic::gencell sky130::sky130_fd_pr__rf_npn_05v5_W1p00L1p00" pdk1
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400112 magic::add_toolkit_command $layoutframe "NPN 1.0 x 2.0" \
Tim Edwardsc6202ef2020-09-20 17:16:33 -0400113 "magic::gencell sky130::sky130_fd_pr__rf_npn_05v5_W1p00L2p00" pdk1
Tim Edwards7e294962021-05-04 20:33:17 -0400114 magic::add_toolkit_command $layoutframe "PNP 0.68 x 0.68" \
Tim Edwards956e3022021-05-27 20:43:26 -0400115 "magic::gencell sky130::sky130_fd_pr__rf_pnp_05v5_W0p68L0p68" pdk1
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400116 magic::add_toolkit_command $layoutframe "PNP 3.4 x 3.4" \
Tim Edwards956e3022021-05-27 20:43:26 -0400117 "magic::gencell sky130::sky130_fd_pr__rf_pnp_05v5_W3p40L3p40" pdk1
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400118
119 magic::add_toolkit_separator $layoutframe pdk1
120
Tim Edwardsc6202ef2020-09-20 17:16:33 -0400121 magic::add_toolkit_command $layoutframe "inductor 1" \
122 "magic::gencell sky130::sky130_fd_pr__rf_test_coil1" pdk1
123 magic::add_toolkit_command $layoutframe "inductor 2" \
124 "magic::gencell sky130::sky130_fd_pr__rf_test_coil2" pdk1
125 magic::add_toolkit_command $layoutframe "inductor 3" \
126 "magic::gencell sky130::sky130_fd_pr__rf_test_coil3" pdk1
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400127
128 magic::add_toolkit_separator $layoutframe pdk1
129
130 magic::add_toolkit_command $layoutframe "substrate contact (1.8V)" \
131 "sky130::subconn_draw" pdk1
132 magic::add_toolkit_command $layoutframe "substrate contact (5.0V)" \
133 "sky130::mvsubconn_draw" pdk1
134 magic::add_toolkit_command $layoutframe "deep n-well region" \
135 "sky130::deep_nwell_draw" pdk1
136 magic::add_toolkit_command $layoutframe "mcon" \
137 "sky130::mcon_draw" pdk1
138 magic::add_toolkit_command $layoutframe "via1" \
139 "sky130::via1_draw" pdk1
140 magic::add_toolkit_command $layoutframe "via2" \
141 "sky130::via2_draw" pdk1
142#ifdef METAL5
143 magic::add_toolkit_command $layoutframe "via3" \
144 "sky130::via3_draw" pdk1
145 magic::add_toolkit_command $layoutframe "via4" \
146 "sky130::via4_draw" pdk1
147#endif (METAL5)
148
149
150 magic::add_toolkit_menu $layoutframe "Devices 2" pdk2
151
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400152 magic::add_toolkit_command $layoutframe "n-diff resistor (1.8V) - 120 Ohm/sq" \
153 "magic::gencell sky130::sky130_fd_pr__res_generic_nd" pdk2
154 magic::add_toolkit_command $layoutframe "p-diff resistor (1.8V) - 197 Ohm/sq" \
155 "magic::gencell sky130::sky130_fd_pr__res_generic_pd" pdk2
156 magic::add_toolkit_command $layoutframe "n-diff resistor (5.0V) - 114 Ohm/sq" \
Tim Edwards0ee0f182020-11-21 16:15:07 -0500157 "magic::gencell sky130::sky130_fd_pr__res_generic_nd__hv" pdk2
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400158 magic::add_toolkit_command $layoutframe "p-diff resistor (5.0V) - 191 Ohm/sq" \
Tim Edwards0ee0f182020-11-21 16:15:07 -0500159 "magic::gencell sky130::sky130_fd_pr__res_generic_pd__hv" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400160
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400161 magic::add_toolkit_command $layoutframe "poly resistor - 48.2 Ohm/sq" \
162 "magic::gencell sky130::sky130_fd_pr__res_generic_po" pdk2
163 magic::add_toolkit_command $layoutframe "poly resistor - 319.8 Ohm/sq" \
164 "magic::gencell sky130::sky130_fd_pr__res_high_po_0p35" pdk2
165 magic::add_toolkit_command $layoutframe "poly resistor - 2000 Ohm/sq" \
166 "magic::gencell sky130::sky130_fd_pr__res_xhigh_po_0p35" pdk2
167 magic::add_toolkit_command $layoutframe "p-well resistor - 3050 Ohm/sq" \
168 "magic::gencell sky130::sky130_fd_pr__res_iso_pw" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400169 magic::add_toolkit_separator $layoutframe pdk2
170
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400171 magic::add_toolkit_command $layoutframe "l1 metal resistor - 12.2 Ohm/sq" \
172 "magic::gencell sky130::sky130_fd_pr__res_generic_l1" pdk2
173 magic::add_toolkit_command $layoutframe "m1 metal resistor - 125 mOhm/sq" \
174 "magic::gencell sky130::sky130_fd_pr__res_generic_m1" pdk2
175 magic::add_toolkit_command $layoutframe "m2 metal resistor - 125 mOhm/sq" \
176 "magic::gencell sky130::sky130_fd_pr__res_generic_m2" pdk2
177 magic::add_toolkit_command $layoutframe "m3 metal resistor - 47 mOhm/sq" \
178 "magic::gencell sky130::sky130_fd_pr__res_generic_m3" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400179#ifdef METAL5
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400180 magic::add_toolkit_command $layoutframe "m4 metal resistor - 47 mOhm/sq" \
181 "magic::gencell sky130::sky130_fd_pr__res_generic_m4" pdk2
182 magic::add_toolkit_command $layoutframe "m5 metal resistor - 29 mOhm/sq" \
183 "magic::gencell sky130::sky130_fd_pr__res_generic_m5" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400184#endif (METAL5)
185
186#ifdef MIM
Tim Edwards15463bc2021-05-12 21:33:31 -0400187 magic::add_toolkit_command $layoutframe "MiM cap - 2fF/um^2 (metal3)" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400188 "magic::gencell sky130::sky130_fd_pr__cap_mim_m3_1" pdk2
Tim Edwards15463bc2021-05-12 21:33:31 -0400189 magic::add_toolkit_command $layoutframe "MiM cap - 2fF/um^2 (metal4)" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400190 "magic::gencell sky130::sky130_fd_pr__cap_mim_m3_2" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400191#endif (MIM)
192 magic::add_toolkit_separator $layoutframe pdk2
193
Tim Edwardsc6202ef2020-09-20 17:16:33 -0400194 magic::add_toolkit_command $layoutframe "vpp 11.5x11.7 m1-m4, li/m5 shield" \
195 "magic::gencell sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5" pdk2
196 magic::add_toolkit_command $layoutframe "vpp 11.5x11.7 m1-m2" \
197 "magic::gencell sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield" pdk2
198 magic::add_toolkit_command $layoutframe "vpp 8.6x7.8 m1-m2 l1 shield" \
199 "magic::gencell sky130::sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_l1shield" pdk2
200 magic::add_toolkit_command $layoutframe "vpp 4.4x4.6 m1-m2 l1 shield" \
201 "magic::gencell sky130::sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_l1shield" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400202
Tim Edwards708a9422021-03-09 22:07:22 -0500203 # Additional DRC style for routing only---add this to the DRC menu
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400204 ${layoutframe}.titlebar.mbuttons.drc.toolmenu add command -label "DRC Routing" -command {drc style drc(routing)}
205
Tim Edwards708a9422021-03-09 22:07:22 -0500206 # Add SPICE import function to File menu
207 ${layoutframe}.titlebar.mbuttons.file.toolmenu insert 4 command -label "Import SPICE" -command {sky130::importspice}
208 ${layoutframe}.titlebar.mbuttons.file.toolmenu insert 4 separator
209
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400210 # Add command entry window by default if enabled
211 if {[info exists Opts(cmdentry)]} {
212 set Winopts(${framename},cmdentry) $Opts(cmdentry)
213 } else {
214 set Winopts(${framename},cmdentry) 0
215 }
216 if {$Winopts(${framename},cmdentry) == 1} {
217 addcommandentry $framename
218 }
219}
220
221#----------------------------------------------------------------
Tim Edwards708a9422021-03-09 22:07:22 -0500222# Menu callback function to read a SPICE netlist and generate an
223# initial layout using the SKYWATER TECHNAME gencells.
224#----------------------------------------------------------------
225
226proc sky130::importspice {} {
227 global CAD_ROOT
228
229 set Layoutfilename [ tk_getOpenFile -filetypes \
230 {{SPICE {.spice .spc .spi .ckt .cir .sp \
231 {.spice .spc .spi .ckt .cir .sp}}} {"All files" {*}}}]
232 if {$Layoutfilename != ""} {
233 magic::netlist_to_layout $Layoutfilename sky130
234 }
235}
236
237#----------------------------------------------------------------
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400238
Tim Edwards0ee0f182020-11-21 16:15:07 -0500239proc sky130::mcon_draw {{dir default}} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400240 set w [magic::i2u [box width]]
241 set h [magic::i2u [box height]]
242 if {$w < 0.17} {
243 puts stderr "Mcon width must be at least 0.17um"
244 return
245 }
246 if {$h < 0.17} {
247 puts stderr "Mcon height must be at least 0.17um"
248 return
249 }
Tim Edwards8ebc7742020-11-22 11:41:28 -0500250 suspendall
Tim Edwards0b1a8732020-12-30 15:15:08 -0500251 paint mcon
Tim Edwards0ee0f182020-11-21 16:15:07 -0500252 pushbox
253 if {($w < $h) || ($dir == "vert")} {
254 box grow e 0.03um
255 box grow w 0.03um
256 box grow n 0.06um
257 box grow s 0.06um
258 paint m1
259 } else {
260 box grow n 0.03um
261 box grow s 0.03um
262 box grow e 0.06um
263 box grow w 0.06um
264 paint m1
265 }
266 popbox
267 resumeall
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400268}
269
270proc sky130::via1_draw {} {
271 set w [magic::i2u [box width]]
272 set h [magic::i2u [box height]]
273 if {$w < 0.26} {
274 puts stderr "Via1 width must be at least 0.26um"
275 return
276 }
277 if {$h < 0.26} {
278 puts stderr "Via1 height must be at least 0.26um"
279 return
280 }
Tim Edwards8ebc7742020-11-22 11:41:28 -0500281 suspendall
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400282 paint via1
283 box grow n 0.05um
284 box grow s 0.05um
285 paint m2
286 box grow n -0.05um
287 box grow s -0.05um
288 box grow e 0.05um
289 box grow w 0.05um
290 paint m1
291 box grow e -0.05um
292 box grow w -0.05um
Tim Edwards0ee0f182020-11-21 16:15:07 -0500293 resumeall
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400294}
295
296proc sky130::via2_draw {} {
297 set w [magic::i2u [box width]]
298 set h [magic::i2u [box height]]
299 if {$w < 0.28} {
300 puts stderr "Via2 width must be at least 0.28um"
301 return
302 }
303 if {$h < 0.28} {
304 puts stderr "Via2 height must be at least 0.28um"
305 return
306 }
Tim Edwards8ebc7742020-11-22 11:41:28 -0500307 suspendall
Tim Edwardsb427e3b2020-11-22 15:28:54 -0500308 pushbox
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400309 paint via2
310 box grow n 0.05um
311 box grow s 0.05um
312 paint m2
Tim Edwardsb427e3b2020-11-22 15:28:54 -0500313 popbox
314 pushbox
315 box grow n 0.025um
316 box grow s 0.025um
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400317 box grow e 0.05um
318 box grow w 0.05um
319 paint m3
Tim Edwardsb427e3b2020-11-22 15:28:54 -0500320 popbox
Tim Edwards0ee0f182020-11-21 16:15:07 -0500321 resumeall
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400322}
323
324#ifdef METAL5
325proc sky130::via3_draw {} {
326 set w [magic::i2u [box width]]
327 set h [magic::i2u [box height]]
328 if {$w < 0.32} {
329 puts stderr "Via3 width must be at least 0.32um"
330 return
331 }
332 if {$h < 0.32} {
333 puts stderr "Via3 height must be at least 0.32um"
334 return
335 }
Tim Edwards8ebc7742020-11-22 11:41:28 -0500336 suspendall
Tim Edwardsb427e3b2020-11-22 15:28:54 -0500337 pushbox
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400338 paint via3
Tim Edwardsb427e3b2020-11-22 15:28:54 -0500339 box grow n 0.005um
340 box grow s 0.005um
341 box grow e 0.005um
342 box grow w 0.005um
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400343 paint m4
Tim Edwardsb427e3b2020-11-22 15:28:54 -0500344 popbox
345 pushbox
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400346 box grow e 0.05um
347 box grow w 0.05um
348 paint m3
Tim Edwardsb427e3b2020-11-22 15:28:54 -0500349 popbox
Tim Edwards0ee0f182020-11-21 16:15:07 -0500350 resumeall
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400351}
352
353proc sky130::via4_draw {} {
354 set w [magic::i2u [box width]]
355 set h [magic::i2u [box height]]
356 if {$w < 1.18} {
357 puts stderr "Via3 width must be at least 1.18um"
358 return
359 }
360 if {$h < 1.18} {
361 puts stderr "Via3 height must be at least 1.18um"
362 return
363 }
Tim Edwards8ebc7742020-11-22 11:41:28 -0500364 suspendall
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400365 paint via4
Tim Edwardsb427e3b2020-11-22 15:28:54 -0500366 pushbox
367 box grow n 0.12um
368 box grow s 0.12um
369 box grow e 0.12um
370 box grow w 0.12um
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400371 paint m5
Tim Edwardsb427e3b2020-11-22 15:28:54 -0500372 popbox
Tim Edwards0ee0f182020-11-21 16:15:07 -0500373 resumeall
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400374}
375#endif (METAL5)
376
377proc sky130::subconn_draw {} {
378 set w [magic::i2u [box width]]
379 set h [magic::i2u [box height]]
380 if {$w < 0.17} {
381 puts stderr "Substrate tap width must be at least 0.17um"
382 return
383 }
384 if {$h < 0.17} {
385 puts stderr "Substrate tap height must be at least 0.17um"
386 return
387 }
Tim Edwards8ebc7742020-11-22 11:41:28 -0500388 suspendall
Tim Edwardsb427e3b2020-11-22 15:28:54 -0500389 paint psc
390 pushbox
391 if {$w > $h} {
392 box grow e 0.08um
393 box grow w 0.08um
394 paint li
395 box grow e 0.04um
396 box grow w 0.04um
397 } else {
398 box grow n 0.08um
399 box grow s 0.08um
400 paint li
401 box grow n 0.04um
402 box grow s 0.04um
403 }
404 paint psd
405 popbox
Tim Edwards0ee0f182020-11-21 16:15:07 -0500406 resumeall
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400407}
408
409#----------------------------------------------------------------
410
411proc sky130::mvsubconn_draw {} {
412 set w [magic::i2u [box width]]
413 set h [magic::i2u [box height]]
414 if {$w < 0.17} {
415 puts stderr "Substrate tap width must be at least 0.17um"
416 return
417 }
418 if {$h < 0.17} {
419 puts stderr "Substrate tap height must be at least 0.17um"
420 return
421 }
Tim Edwards8ebc7742020-11-22 11:41:28 -0500422 suspendall
Tim Edwardsb427e3b2020-11-22 15:28:54 -0500423 paint mvpsc
424 pushbox
425 if {$w > $h} {
426 box grow e 0.08um
427 box grow w 0.08um
428 paint li
429 box grow e 0.04um
430 box grow w 0.04um
431 } else {
432 box grow n 0.08um
433 box grow s 0.08um
434 paint li
435 box grow n 0.04um
436 box grow s 0.04um
437 }
438 paint mvpsd
439 popbox
Tim Edwards0ee0f182020-11-21 16:15:07 -0500440 resumeall
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400441}
442
443#----------------------------------------------------------------
444
445proc sky130::deep_nwell_draw {} {
446 set w [magic::i2u [box width]]
447 set h [magic::i2u [box height]]
448 if {$w < 3.0} {
449 puts stderr "Deep-nwell region width must be at least 3.0um"
450 return
451 }
452 if {$h < 3.0} {
453 puts stderr "Deep-nwell region height must be at least 3.0um"
454 return
455 }
456 suspendall
457 tech unlock *
458 paint dnwell
459 pushbox
460 pushbox
461 box grow c 0.4um
462 paint nwell
463 box grow c -1.43um
464 erase nwell
465 popbox
466 box grow c 0.03um
467
468 pushbox
469 box width 0
470 box grow c 0.085um
471 paint li
472 pushbox
473 box grow n -0.3um
474 box grow s -0.3um
475 paint nsc
476 popbox
477 box grow c 0.1um
478 paint nsd
479 popbox
480
481 pushbox
482 box height 0
483 box grow c 0.085um
484 paint li
485 pushbox
486 box grow e -0.3um
487 box grow w -0.3um
488 paint nsc
489 popbox
490 box grow c 0.1um
491 paint nsd
492 popbox
493
494 pushbox
495 box move n [box height]i
496 box height 0
497 box grow c 0.085um
498 paint li
499 pushbox
500 box grow e -0.3um
501 box grow w -0.3um
502 paint nsc
503 popbox
504 box grow c 0.1um
505 paint nsd
506 popbox
507
508 pushbox
509 box move e [box width]i
510 box width 0
511 box grow c 0.085um
512 paint li
513 pushbox
514 box grow n -0.3um
515 box grow s -0.3um
516 paint nsc
517 box grow c 0.1um
518 paint nsd
519 popbox
520
521 popbox
522 tech revert
523 resumeall
524}
525
526#----------------------------------------------------------------
527
528proc sky130::res_recalc {field parameters} {
529 set snake 0
530 set sterm 0.0
531 set caplen 0
532 # Set a local variable for each parameter (e.g., $l, $w, etc.)
533 foreach key [dict keys $parameters] {
534 set $key [dict get $parameters $key]
535 }
536 set val [magic::spice2float $val]
537 set l [magic::spice2float $l]
538 set w [magic::spice2float $w]
539
540 if {$snake == 0} {
541 # Straight resistor calculation
542 switch $field {
543 val { set l [expr ($val * ($w - $dw) - (2 * $term)) / $rho]
544 set w [expr ((2 * $term + $l * $rho) / $val) + $dw]
545 }
546 w { set val [expr (2 * $term + $l * $rho) / ($w - $dw)]
547 set l [expr ($val * ($w - $dw) - (2 * $term)) / $rho]
548 }
549 l { set val [expr (2 * $term + $l * $rho) / ($w - $dw)]
550 set w [expr ((2 * $term + $l * $rho) / $val) + $dw]
551 }
552 }
553 } else {
554 set term [expr $term + $sterm]
555 # Snake resistor calculation
556 switch $field {
557 val { set l [expr (($val - $rho * ($nx - 1)) * ($w - $dw) \
558 - (2 * $term) - ($rho * $caplen * ($nx - 1))) \
559 / ($rho * $nx)]
560
561 set w [expr ((2 * $term + $l * $rho * $nx \
562 + $caplen * $rho * ($nx - 1)) \
563 / ($val - $rho * ($nx - 1))) + $dw]
564 }
565 w { set val [expr $rho * ($nx - 1) + ((2 * $term) \
566 + ($rho * $l * $nx) + ($rho * $caplen * ($nx - 1))) \
567 / ($w - $dw)]
568
569 set l [expr (($val - $rho * ($nx - 1)) * ($w - $dw) \
570 - (2 * $term) - ($rho * $caplen * ($nx - 1))) \
571 / ($rho * $nx)]
572 }
573 l { set val [expr $rho * ($nx - 1) + ((2 * $term) \
574 + ($rho * $l * $nx) + ($rho * $caplen * ($nx - 1))) \
575 / ($w - $dw)]
576
577 set w [expr ((2 * $term + $l * $rho * $nx \
578 + $caplen * $rho * ($nx - 1)) \
579 / ($val - $rho * ($nx - 1))) + $dw]
580 }
581 }
582 }
583
584 set val [magic::3digitpastdecimal $val]
585 set w [magic::3digitpastdecimal $w]
586 set l [magic::3digitpastdecimal $l]
587
588 dict set parameters val $val
589 dict set parameters w $w
590 dict set parameters l $l
591
592 return $parameters
593}
594
595#----------------------------------------------------------------
596# Drawn diode routines
597#----------------------------------------------------------------
598
599proc sky130::diode_recalc {field parameters} {
600 # Set a local variable for each parameter (e.g., $l, $w, etc.)
601 foreach key [dict keys $parameters] {
602 set $key [dict get $parameters $key]
603 }
604 switch $field {
605 area { puts stdout "area changed" }
606 peri { puts stdout "perimeter changed" }
607 w { puts stdout "width changed" }
608 l { puts stdout "length changed" }
609 }
610 dict set parameters area $area
611 dict set parameters peri $peri
612 dict set parameters w $w
613 dict set parameters l $l
614}
615
616#----------------------------------------------------------------
617# diode: Conversion from SPICE netlist parameters to toolkit
618#----------------------------------------------------------------
619
620proc sky130::diode_convert {parameters} {
621 set pdkparams [dict create]
622 dict for {key value} $parameters {
623 switch -nocase $key {
624 l -
625 w -
626 peri {
627 # Length, width, and perimeter are converted to units of microns
628 set value [magic::spice2float $value]
629 # set value [expr $value * 1e6]
630 set value [magic::3digitpastdecimal $value]
631 dict set pdkparams [string tolower $key] $value
632 }
633 area {
634 # area also converted to units of microns
635 set value [magic::spice2float $value]
636 # set value [expr $value * 1e12]
637 set value [magic::3digitpastdecimal $value]
638 dict set pdkparams [string tolower $key] $value
639 }
640 m {
641 # Convert m to ny
642 dict set pdkparams ny $value
643 }
644 }
645 }
646 return $pdkparams
647}
648
649#----------------------------------------------------------------
650# diode: Interactively specifies the fixed layout parameters
651#----------------------------------------------------------------
652
653proc sky130::diode_dialog {device parameters} {
654 # Editable fields: w, l, area, perim, nx, ny
655
656 magic::add_entry area "Area (um^2)" $parameters
657 magic::add_entry peri "Perimeter (um)" $parameters
658 sky130::compute_aptot $parameters
659 magic::add_message atot "Total area (um^2)" $parameters
660 magic::add_message ptot "Total perimeter (um)" $parameters
661 magic::add_entry l "Length (um)" $parameters
662 magic::add_entry w "Width (um)" $parameters
663 magic::add_entry nx "X Repeat" $parameters
664 magic::add_entry ny "Y Repeat" $parameters
665
666 if {[dict exists $parameters compatible]} {
667 set sellist [dict get $parameters compatible]
668 magic::add_selectlist gencell "Device type" $sellist $parameters $device
669 }
670
671 if {[dict exists $parameters doverlap]} {
672 magic::add_checkbox doverlap "Overlap at end contact" $parameters
673 }
674 if {[dict exists $parameters elc]} {
675 magic::add_checkbox elc "Add left end contact" $parameters
676 }
677 if {[dict exists $parameters erc]} {
678 magic::add_checkbox erc "Add right end contact" $parameters
679 }
680 if {[dict exists $parameters etc]} {
681 magic::add_checkbox etc "Add top end contact" $parameters
682 }
683 if {[dict exists $parameters ebc]} {
684 magic::add_checkbox ebc "Add bottom end contact" $parameters
685 }
686
687 if {[dict exists $parameters guard]} {
688 magic::add_checkbox full_metal "Full metal guard ring" $parameters
689 }
690 if {[dict exists $parameters glc]} {
691 magic::add_checkbox glc "Add left guard ring contact" $parameters
692 }
693 if {[dict exists $parameters grc]} {
694 magic::add_checkbox grc "Add right guard ring contact" $parameters
695 }
696 if {[dict exists $parameters gtc]} {
697 magic::add_checkbox gtc "Add top guard ring contact" $parameters
698 }
699 if {[dict exists $parameters gbc]} {
700 magic::add_checkbox gbc "Add bottom guard ring contact" $parameters
701 }
Tim Edwards0ee0f182020-11-21 16:15:07 -0500702 if {[dict exists $parameters viagb]} {
703 magic::add_entry viagb "Bottom guard ring via coverage \[+/-\](%)" $parameters
704 }
705 if {[dict exists $parameters viagt]} {
706 magic::add_entry viagt "Top guard ring via coverage \[+/-\](%)" $parameters
707 }
708 if {[dict exists $parameters viagr]} {
709 magic::add_entry viagr "Right guard ring via coverage \[+/-\](%)" $parameters
710 }
711 if {[dict exists $parameters viagl]} {
712 magic::add_entry viagl "Left guard ring via coverage \[+/-\](%)" $parameters
713 }
714
715 if {[dict exists $parameters vias]} {
716 magic::add_checkbox vias "Add vias over contacts" $parameters
717 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400718
719 magic::add_dependency sky130::diode_recalc $device sky130 l w area peri
720
721 # magic::add_checkbox dummy "Add dummy" $parameters
722}
723
724#----------------------------------------------------------------
725# Diode total area and perimeter computation
726#----------------------------------------------------------------
727
728proc sky130::compute_aptot {parameters} {
729 foreach key [dict keys $parameters] {
730 set $key [dict get $parameters $key]
731 }
732 set area [magic::spice2float $area]
733 set area [magic::3digitpastdecimal $area]
734 set peri [magic::spice2float $peri]
735 set peri [magic::3digitpastdecimal $peri]
736
737 # Compute total area
738 catch {set magic::atot_val [expr ($area * $nx * $ny)]}
739 # Compute total perimeter
740 catch {set magic::ptot_val [expr ($peri * $nx * $ny)]}
741}
742
743#----------------------------------------------------------------
744# diode: Check device parameters for out-of-bounds values
745#----------------------------------------------------------------
746
747proc sky130::diode_check {parameters} {
748
Tim Edwards2b758912021-05-20 16:01:18 -0400749 set guard 0
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400750 # Set a local variable for each parameter (e.g., $l, $w, etc.)
751 foreach key [dict keys $parameters] {
752 set $key [dict get $parameters $key]
753 }
754
755 # Normalize distance units to microns
756 set l [magic::spice2float $l]
757 set l [magic::3digitpastdecimal $l]
758 set w [magic::spice2float $w]
759 set w [magic::3digitpastdecimal $w]
760
761 set area [magic::spice2float $area]
762 set area [magic::3digitpastdecimal $area]
763 set peri [magic::spice2float $peri]
764 set peri [magic::3digitpastdecimal $peri]
765
766 if {$l == 0} {
767 # Calculate L from W and area
768 set l [expr ($area / $w)]
769 dict set parameters l [magic::float2spice $l]
770 } elseif {$w == 0} {
771 # Calculate W from L and area
772 set w [expr ($area / $l)]
773 dict set parameters w [magic::float2spice $w]
774 }
775 if {$w < $wmin} {
776 puts stderr "Diode width must be >= $wmin"
777 dict set parameters w $wmin
778 }
779 if {$l < $lmin} {
780 puts stderr "Diode length must be >= $lmin"
781 dict set parameters l $lmin
782 }
Tim Edwards0ee0f182020-11-21 16:15:07 -0500783
784 # Check via coverage for syntax
785 if {$guard == 1} {
786 if {[catch {expr abs($viagb)}]} {
787 puts stderr "Guard ring bottom via coverage must be numeric!"
788 dict set parameters viagb 0
789 } elseif {[expr abs($viagb)] > 100} {
790 puts stderr "Guard ring bottom via coverage can't be more than 100%"
791 dict set parameters viagb 100
792 }
793 if {[catch {expr abs($viagt)}]} {
794 puts stderr "Guard ring top via coverage must be numeric!"
795 dict set parameters viagt 0
796 } elseif {[expr abs($viagt)] > 100} {
797 puts stderr "Guard ring top via coverage can't be more than 100%"
798 dict set parameters viagt 100
799 }
800 if {[catch {expr abs($viagr)}]} {
801 puts stderr "Guard ring right via coverage must be numeric!"
802 dict set parameters viagr 0
803 } elseif {[expr abs($viagr)] > 100} {
804 puts stderr "Guard ring right via coverage can't be more than 100%"
805 dict set parameters viagr 100
806 }
807 if {[catch {expr abs($viagl)}]} {
808 puts stderr "Guard ring left via coverage must be numeric!"
809 dict set parameters viagl 0
810 } elseif {[expr abs($viagl)] > 100} {
811 puts stderr "Guard ring left via coverage can't be more than 100%"
812 dict set parameters viagl 100
813 }
814 }
815
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400816 # Calculate area and perimeter from L and W
817 set area [expr ($l * $w)]
818 dict set parameters area [magic::float2spice $area]
819 set peri [expr (2 * ($l + $w))]
820 dict set parameters peri [magic::float2spice $peri]
821 sky130::compute_aptot $parameters
822
823 return $parameters
824}
825
826#------------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400827# NOTE: sky130_fd_pr__diode_pw2nd_05v5_lvt,
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400828# sky130_fd_pr__diode_pw2nd_05v5_nvt, sky130_fd_pr__diode_pd2nw_05v5_lvt,
829# and sky130_fd_pr__diode_pd2nw_11v0 are all considered parasitic diodes.
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400830# They may be generated by invoking the build procedure on the
831# command line. To enable them in the PDK, add them to the
832# appropriate compatible {} list.
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400833#------------------------------------------------------------------
834
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400835proc sky130::sky130_fd_pr__diode_pw2nd_05v5_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400836 return {w 0.45 l 0.45 area 0.2025 peri 1.8 \
837 nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
838 elc 1 erc 1 etc 1 ebc 1 doverlap 0 \
Tim Edwards27348db2020-10-28 22:49:29 -0400839 compatible {sky130_fd_pr__diode_pw2nd_05v5 sky130_fd_pr__diode_pw2nd_05v5_lvt \
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400840 sky130_fd_pr__diode_pw2nd_05v5_nvt sky130_fd_pr__diode_pw2nd_11v0} \
Tim Edwards0ee0f182020-11-21 16:15:07 -0500841 full_metal 1 vias 1 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400842}
843
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400844proc sky130::sky130_fd_pr__diode_pw2nd_05v5_lvt_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400845 return {w 0.45 l 0.45 area 0.2025 peri 1.8 \
846 nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
847 elc 1 erc 1 etc 1 ebc 1 doverlap 0 \
Tim Edwards27348db2020-10-28 22:49:29 -0400848 compatible {sky130_fd_pr__diode_pw2nd_05v5 sky130_fd_pr__diode_pw2nd_05v5_lvt \
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400849 sky130_fd_pr__diode_pw2nd_05v5_nvt sky130_fd_pr__diode_pw2nd_11v0} \
Tim Edwards0ee0f182020-11-21 16:15:07 -0500850 full_metal 1 vias 1 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400851}
852
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400853proc sky130::sky130_fd_pr__diode_pw2nd_05v5_nvt_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400854 return {w 0.45 l 0.45 area 0.2024 peri 1.8 \
855 nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
856 elc 1 erc 1 etc 1 ebc 1 doverlap 0 \
Tim Edwards27348db2020-10-28 22:49:29 -0400857 compatible {sky130_fd_pr__diode_pw2nd_05v5 sky130_fd_pr__diode_pw2nd_05v5_lvt \
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400858 sky130_fd_pr__diode_pw2nd_05v5_nvt sky130_fd_pr__diode_pw2nd_11v0} \
Tim Edwards0ee0f182020-11-21 16:15:07 -0500859 full_metal 1 vias 1 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400860}
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400861
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400862proc sky130::sky130_fd_pr__diode_pw2nd_11v0_defaults {} {
863 return {w 0.45 l 0.45 area 0.2024 peri 1.8 \
864 nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
865 elc 1 erc 1 etc 1 ebc 1 doverlap 0 \
866 compatible {sky130_fd_pr__diode_pw2nd_05v5 sky130_fd_pr__diode_pw2nd_05v5_lvt \
867 sky130_fd_pr__diode_pw2nd_05v5_nvt sky130_fd_pr__diode_pw2nd_11v0} \
Tim Edwards0ee0f182020-11-21 16:15:07 -0500868 full_metal 1 vias 1 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400869}
870
871proc sky130::sky130_fd_pr__diode_pd2nw_05v5_defaults {} {
872 return {w 0.45 l 0.45 area 0.2025 peri 1.8 \
873 nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
874 elc 1 erc 1 etc 1 ebc 1 \
875 glc 1 grc 1 gtc 1 gbc 1 doverlap 0 \
876 compatible {sky130_fd_pr__diode_pd2nw_05v5 sky130_fd_pr__diode_pd2nw_05v5_lvt \
Tim Edwards0ee0f182020-11-21 16:15:07 -0500877 sky130_fd_pr__diode_pd2nw_05v5_hvt sky130_fd_pr__diode_pd2nw_11v0} \
878 full_metal 1 vias 1 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400879}
880
881proc sky130::sky130_fd_pr__diode_pd2nw_05v5_lvt_defaults {} {
882 return {w 0.45 l 0.45 area 0.2025 peri 1.8 \
883 nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
884 elc 1 erc 1 etc 1 ebc 1 \
885 glc 1 grc 1 gtc 1 gbc 1 doverlap 0 \
886 compatible {sky130_fd_pr__diode_pd2nw_05v5 sky130_fd_pr__diode_pd2nw_05v5_lvt \
887 sky130_fd_pr__diode_pd2nw_05v5_hvt sky130_fd_pr__diode_pd2nw_11v0} \
Tim Edwards0ee0f182020-11-21 16:15:07 -0500888 full_metal 1 vias 1 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400889}
890
891proc sky130::sky130_fd_pr__diode_pd2nw_05v5_hvt_defaults {} {
892 return {w 0.45 l 0.45 area 0.2025 peri 1.8 \
893 nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
894 elc 1 erc 1 etc 1 ebc 1 \
895 glc 1 grc 1 gtc 1 gbc 1 doverlap 0 \
896 compatible {sky130_fd_pr__diode_pd2nw_05v5 sky130_fd_pr__diode_pd2nw_05v5_lvt \
897 sky130_fd_pr__diode_pd2nw_05v5_hvt sky130_fd_pr__diode_pd2nw_11v0} \
Tim Edwards0ee0f182020-11-21 16:15:07 -0500898 full_metal 1 vias 1 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400899}
900
901
902proc sky130::sky130_fd_pr__diode_pd2nw_11v0_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400903 return {w 0.45 l 0.45 area 0.2024 peri 1.8 \
904 nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
905 elc 1 erc 1 etc 1 ebc 1 \
906 glc 1 grc 1 gtc 1 gbc 1 doverlap 0 \
Tim Edwards27348db2020-10-28 22:49:29 -0400907 compatible {sky130_fd_pr__diode_pd2nw_05v5 sky130_fd_pr__diode_pd2nw_05v5_lvt \
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400908 sky130_fd_pr__diode_pd2nw_05v5_hvt sky130_fd_pr__diode_pd2nw_11v0} \
Tim Edwards0ee0f182020-11-21 16:15:07 -0500909 full_metal 1 vias 1 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400910}
911
912#----------------------------------------------------------------
913
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400914proc sky130::sky130_fd_pr__diode_pw2nd_05v5_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400915 return [sky130::diode_convert $parameters]
916}
917
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400918proc sky130::sky130_fd_pr__diode_pw2nd_05v5_lvt_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400919 return [sky130::diode_convert $parameters]
920}
921
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400922proc sky130::sky130_fd_pr__diode_pw2nd_05v5_nvt_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400923 return [sky130::diode_convert $parameters]
924}
925
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400926proc sky130::sky130_fd_pr__diode_pw2nd_11v0_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400927 return [sky130::diode_convert $parameters]
928}
929
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400930proc sky130::sky130_fd_pr__diode_pd2nw_05v5_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400931 return [sky130::diode_convert $parameters]
932}
933
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400934proc sky130::sky130_fd_pr__diode_pd2nw_05v5_lvt_convert {parameters} {
935 return [sky130::diode_convert $parameters]
936}
937
938proc sky130::sky130_fd_pr__diode_pd2nw_05v5_hvt_convert {parameters} {
939 return [sky130::diode_convert $parameters]
940}
941
942proc sky130::sky130_fd_pr__diode_pd2nw_11v0_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400943 return [sky130::diode_convert $parameters]
944}
945
946#----------------------------------------------------------------
947
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400948proc sky130::sky130_fd_pr__diode_pw2nd_05v5_dialog {parameters} {
Tim Edwards27348db2020-10-28 22:49:29 -0400949 sky130::diode_dialog sky130_fd_pr__diode_pw2nd_05v5 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400950}
951
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400952proc sky130::sky130_fd_pr__diode_pw2nd_05v5_lvt_dialog {parameters} {
953 sky130::diode_dialog sky130_fd_pr__diode_pw2nd_05v5_lvt $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400954}
955
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400956proc sky130::sky130_fd_pr__diode_pw2nd_05v5_nvt_dialog {parameters} {
957 sky130::diode_dialog sky130_fd_pr__diode_pw2nd_05v5_nvt $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400958}
959
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400960proc sky130::sky130_fd_pr__diode_pw2nd_11v0_dialog {parameters} {
961 sky130::diode_dialog sky130_fd_pr__diode_pw2nd_11v0 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400962}
963
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400964proc sky130::sky130_fd_pr__diode_pd2nw_05v5_dialog {parameters} {
965 sky130::diode_dialog sky130_fd_pr__diode_pd2nw_05v5 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400966}
967
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400968proc sky130::sky130_fd_pr__diode_pd2nw_05v5_lvt_dialog {parameters} {
969 sky130::diode_dialog sky130_fd_pr__diode_pd2nw_05v5_lvt $parameters
970}
971
972proc sky130::sky130_fd_pr__diode_pd2nw_05v5_hvt_dialog {parameters} {
973 sky130::diode_dialog sky130_fd_pr__diode_pd2nw_05v5_hvt $parameters
974}
975
976proc sky130::sky130_fd_pr__diode_pd2nw_11v0_dialog {parameters} {
977 sky130::diode_dialog sky130_fd_pr__diode_pd2nw_11v0 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400978}
979
980#----------------------------------------------------------------
981
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400982proc sky130::sky130_fd_pr__diode_pw2nd_05v5_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400983 sky130::diode_check $parameters
984}
985
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400986proc sky130::sky130_fd_pr__diode_pw2nd_05v5_lvt_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400987 sky130::diode_check $parameters
988}
989
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400990proc sky130::sky130_fd_pr__diode_pw2nd_05v5_nvt_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400991 sky130::diode_check $parameters
992}
993
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400994proc sky130::sky130_fd_pr__diode_pw2nd_11v0_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400995 sky130::diode_check $parameters
996}
997
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400998proc sky130::sky130_fd_pr__diode_pd2nw_05v5_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400999 sky130::diode_check $parameters
1000}
1001
Tim Edwardsbe6f1202020-10-29 10:37:46 -04001002proc sky130::sky130_fd_pr__diode_pd2nw_05v5_lvt_check {parameters} {
1003 sky130::diode_check $parameters
1004}
1005
1006proc sky130::sky130_fd_pr__diode_pd2nw_05v5_hvt_check {parameters} {
1007 sky130::diode_check $parameters
1008}
1009
1010proc sky130::sky130_fd_pr__diode_pd2nw_11v0_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001011 sky130::diode_check $parameters
1012}
1013
1014#----------------------------------------------------------------
1015# Diode: Draw a single device
1016#----------------------------------------------------------------
1017
1018proc sky130::diode_device {parameters} {
1019 # Epsilon for avoiding round-off errors
1020 set eps 0.0005
1021
1022 # Set local default values if they are not in parameters
1023 set dev_surround 0
1024 set dev_sub_type ""
1025
1026 # Set a local variable for each parameter (e.g., $l, $w, etc.)
1027 foreach key [dict keys $parameters] {
1028 set $key [dict get $parameters $key]
1029 }
1030
1031 # If there is no end_sub_surround, set it to sub_surround
1032 if {![dict exists $parameters end_sub_surround]} {
1033 set end_sub_surround $sub_surround
1034 }
1035
1036 # Draw the device
1037 pushbox
1038 box size 0 0
1039
1040 set hw [/ $w 2.0]
1041 set hl [/ $l 2.0]
1042
1043 # Calculate ring size (measured to contact center)
1044 set gx [+ $w [* 2.0 [+ $dev_spacing $dev_surround]] $contact_size]
1045 set gy [+ $l [* 2.0 [+ $dev_spacing $dev_surround]] $contact_size]
1046
1047 # Draw the ring first, because diode may occupy well/substrate plane
1048 set guardparams $parameters
1049 dict set guardparams plus_diff_type $end_type
1050 dict set guardparams plus_contact_type $end_contact_type
1051 dict set guardparams diff_surround $end_surround
1052 dict set guardparams sub_type $end_sub_type
1053 dict set guardparams sub_surround $sub_surround
1054 dict set guardparams guard_sub_surround $end_sub_surround
1055 dict set guardparams glc $elc
1056 dict set guardparams grc $erc
1057 dict set guardparams gtc $etc
1058 dict set guardparams gbc $ebc
1059 set cext [sky130::guard_ring $gx $gy $guardparams]
1060
1061 pushbox
1062 box grow n ${hl}um
1063 box grow s ${hl}um
1064 box grow e ${hw}um
1065 box grow w ${hw}um
1066 paint ${dev_type}
1067 set cext [sky130::unionbox $cext [sky130::getbox]]
1068
1069 if {$dev_sub_type != ""} {
1070 box grow n ${sub_surround}um
1071 box grow s ${sub_surround}um
1072 box grow e ${sub_surround}um
1073 box grow w ${sub_surround}um
1074 paint ${dev_sub_type}
1075 }
1076 popbox
1077
1078 if {${w} < ${l}} {
1079 set orient vert
1080 } else {
1081 set orient horz
1082 }
1083
1084 # Reduce width by surround amount
1085 set w [- $w [* ${dev_surround} 2.0]]
1086 set l [- $l [* ${dev_surround} 2.0]]
1087
Tim Edwards0ee0f182020-11-21 16:15:07 -05001088 # Draw via over contact first
1089 if {$vias != 0} {
1090 pushbox
1091 set ch $l
1092 if {$ch < $via_size} {set ch $via_size}
1093 set cw $w
1094 if {$cw < $via_size} {set cw $via_size}
1095 box grow n [/ $ch 2]um
1096 box grow s [/ $ch 2]um
1097 box grow w [/ $cw 2]um
1098 box grow e [/ $cw 2]um
1099 sky130::mcon_draw
1100 popbox
1101 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001102 set cext [sky130::unionbox $cext [sky130::draw_contact ${w} ${l} \
1103 ${dev_surround} ${metal_surround} ${contact_size} \
1104 ${dev_type} ${dev_contact_type} li ${orient}]]
1105
1106 popbox
1107 return $cext
1108}
1109
1110#----------------------------------------------------------------
1111# Diode: Draw the tiled device
1112#----------------------------------------------------------------
1113
1114proc sky130::diode_draw {parameters} {
1115 tech unlock *
1116
1117 # Set defaults if they are not in parameters
1118 set doverlap 0 ;# overlap diodes at contacts
1119 set guard 0 ;# draw a guard ring
1120 set prohibit_overlap false ;# don't prohibit overlaps
1121
1122 # Set a local variable for each parameter (e.g., $l, $w, etc.)
1123 foreach key [dict keys $parameters] {
1124 set $key [dict get $parameters $key]
1125 }
1126
1127 # Normalize distance units to microns
1128 set w [magic::spice2float $w]
1129 set l [magic::spice2float $l]
1130
1131 pushbox
1132 box values 0 0 0 0
1133
1134 # Determine the base device dimensions by drawing one device
1135 # while all layers are locked (nothing drawn). This allows the
1136 # base drawing routine to do complicated geometry without having
1137 # to duplicate it here with calculations.
1138
1139 tech lock *
1140 set bbox [sky130::diode_device $parameters]
1141 # puts stdout "Diagnostic: Device bounding box e $bbox (um)"
1142 tech unlock *
1143
1144 set fw [- [lindex $bbox 2] [lindex $bbox 0]]
1145 set fh [- [lindex $bbox 3] [lindex $bbox 1]]
1146 set lw [+ [lindex $bbox 2] [lindex $bbox 0]]
1147 set lh [+ [lindex $bbox 3] [lindex $bbox 1]]
1148
1149 # If prohibit_overlap is true, then end overlapping is prohibited when
1150 # nx or ny is > 1 to prevent DRC errors (typically from well spacing rule)
1151 if {$prohibit_overlap == true} {
1152 if {($nx > 1) || ($ny > 1)} {
1153 set doverlap 0
1154 }
1155 }
1156
1157 # Determine tile width and height (depends on overlap)
1158
1159 if {$doverlap == 0} {
1160 set dx [+ $fw $end_spacing]
1161 set dy [+ $fh $end_spacing]
1162 } else {
1163 # overlap contact
1164 set dx [- $fw [+ [* 2.0 $sub_surround] [* 2.0 $end_surround] $contact_size]]
1165 set dy [- $fh [+ [* 2.0 $sub_surround] [* 2.0 $end_surround] $contact_size]]
1166 }
1167
1168 # Determine core width and height
1169 set corex [+ [* [- $nx 1] $dx] $fw]
1170 set corey [+ [* [- $ny 1] $dy] $fh]
1171 set corellx [/ [+ [- $corex $fw] $lw] 2.0]
1172 set corelly [/ [+ [- $corey $fh] $lh] 2.0]
1173
1174 if {$guard != 0} {
1175 # Calculate guard ring size (measured to contact center)
1176 set gx [+ $corex [* 2.0 [+ $diff_spacing $diff_surround]] $contact_size]
1177 set gy [+ $corey [* 2.0 [+ $diff_spacing $diff_surround]] $contact_size]
1178
1179 # Draw the guard ring first, because diode may occupy well/substrate plane
1180 sky130::guard_ring $gx $gy $parameters
1181 }
1182
1183 pushbox
1184 box move w ${corellx}um
1185 box move s ${corelly}um
1186 if {($nx > 1) || ($ny > 1)} {
1187 pushbox
1188 set hfw [/ $fw 2.0]
1189 set hfh [/ $fh 2.0]
1190 box move w ${hfw}um
1191 box move s ${hfh}um
1192 box size ${corex}um ${corey}um
1193 paint $end_sub_type
1194 popbox
1195 }
1196 for {set xp 0} {$xp < $nx} {incr xp} {
1197 pushbox
1198 for {set yp 0} {$yp < $ny} {incr yp} {
1199 sky130::diode_device $parameters
1200 box move n ${dy}um
1201 }
1202 popbox
1203 box move e ${dx}um
1204 }
1205 popbox
1206 popbox
1207
1208 tech revert
1209}
1210
1211#----------------------------------------------------------------
1212
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001213proc sky130::sky130_fd_pr__diode_pw2nd_05v5_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001214
1215 # Set a local variable for each rule in ruleset
1216 foreach key [dict keys $sky130::ruleset] {
1217 set $key [dict get $sky130::ruleset $key]
1218 }
1219
1220 set newdict [dict create \
1221 dev_type ndiode \
1222 dev_contact_type ndic \
1223 end_type psd \
1224 end_contact_type psc \
1225 end_sub_type psub \
1226 dev_spacing ${diff_spacing} \
1227 dev_surround ${diff_surround} \
1228 end_spacing ${diff_spacing} \
1229 end_surround 0 \
1230 ]
1231 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1232 return [sky130::diode_draw $drawdict]
1233}
1234
1235#----------------------------------------------------------------
1236# NOTE: Use ppd instead of psd so that there is additional
1237# diffusion around the contact, allowing more space for the
Tim Edwardsbe6f1202020-10-29 10:37:46 -04001238# implant (likewise sky130_fd_pr__diode_pd2nw_05v5_lvt and
1239# sky130_fd_pr__diode_pd2nw_11v0).
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001240
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001241proc sky130::sky130_fd_pr__diode_pw2nd_05v5_lvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001242
1243 # Set a local variable for each rule in ruleset
1244 foreach key [dict keys $sky130::ruleset] {
1245 set $key [dict get $sky130::ruleset $key]
1246 }
1247
1248 set newdict [dict create \
1249 dev_type ndiodelvt \
1250 dev_contact_type ndilvtc \
1251 end_type ppd \
1252 end_contact_type psc \
1253 end_sub_type psub \
1254 dev_spacing ${diff_spacing} \
1255 dev_surround ${diff_surround} \
1256 end_spacing ${diff_spacing} \
1257 end_surround ${diff_surround} \
1258 ]
1259 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1260 return [sky130::diode_draw $drawdict]
1261}
1262
Tim Edwardsbe6f1202020-10-29 10:37:46 -04001263proc sky130::sky130_fd_pr__diode_pw2nd_05v5_nvt_draw {parameters} {
1264
1265 # Set a local variable for each rule in ruleset
1266 foreach key [dict keys $sky130::ruleset] {
1267 set $key [dict get $sky130::ruleset $key]
1268 }
1269
1270 set newdict [dict create \
1271 dev_type nndiode \
1272 dev_contact_type nndic \
1273 end_type mvpsd \
1274 end_contact_type mvpsc \
1275 end_sub_type psub \
1276 dev_spacing 0.37 \
1277 dev_surround ${diff_surround} \
1278 end_spacing 0.30 \
1279 end_surround ${diff_surround} \
1280 ]
1281 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1282 return [sky130::diode_draw $drawdict]
1283}
1284
1285proc sky130::sky130_fd_pr__diode_pw2nd_11v0_draw {parameters} {
1286
1287 # Set a local variable for each rule in ruleset
1288 foreach key [dict keys $sky130::ruleset] {
1289 set $key [dict get $sky130::ruleset $key]
1290 }
1291
1292 set newdict [dict create \
1293 dev_type mvndiode \
1294 dev_contact_type mvndic \
1295 end_type mvpsd \
1296 end_contact_type mvpsc \
1297 end_sub_type psub \
1298 diff_spacing 0.37 \
1299 dev_spacing 0.39 \
1300 dev_surround ${diff_surround} \
1301 end_spacing 0.36 \
1302 end_surround ${diff_surround} \
1303 ]
1304 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1305 return [sky130::diode_draw $drawdict]
1306}
1307
1308
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001309#----------------------------------------------------------------
1310
Tim Edwardsbe6f1202020-10-29 10:37:46 -04001311proc sky130::sky130_fd_pr__diode_pd2nw_05v5_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001312
1313 # Set a local variable for each rule in ruleset
1314 foreach key [dict keys $sky130::ruleset] {
1315 set $key [dict get $sky130::ruleset $key]
1316 }
1317
1318 set newdict [dict create \
1319 dev_type pdiode \
1320 guard 1 \
1321 dev_contact_type pdic \
1322 end_type nsd \
1323 end_contact_type nsc \
1324 end_sub_type nwell \
1325 plus_diff_type psd \
1326 plus_contact_type psc \
1327 sub_type psub \
1328 dev_spacing ${diff_spacing} \
1329 dev_surround ${diff_surround} \
1330 end_spacing ${diff_spacing} \
1331 end_surround 0 \
1332 ]
1333 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1334 return [sky130::diode_draw $drawdict]
1335}
1336
1337#----------------------------------------------------------------
1338
Tim Edwardsbe6f1202020-10-29 10:37:46 -04001339proc sky130::sky130_fd_pr__diode_pd2nw_05v5_lvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001340
1341 # Set a local variable for each rule in ruleset
1342 foreach key [dict keys $sky130::ruleset] {
1343 set $key [dict get $sky130::ruleset $key]
1344 }
1345
1346 set newdict [dict create \
1347 dev_type pdiodelvt \
1348 guard 1 \
1349 dev_contact_type pdilvtc \
1350 end_type nnd \
1351 end_contact_type nsc \
1352 end_sub_type nwell \
1353 plus_diff_type psd \
1354 plus_contact_type psc \
1355 sub_type psub \
1356 dev_spacing ${diff_spacing} \
1357 dev_surround ${diff_surround} \
1358 end_spacing ${diff_spacing} \
1359 end_surround ${diff_surround} \
1360 ]
1361 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1362 return [sky130::diode_draw $drawdict]
1363}
1364
1365#----------------------------------------------------------------
1366
Tim Edwardsbe6f1202020-10-29 10:37:46 -04001367proc sky130::sky130_fd_pr__diode_pd2nw_05v5_hvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001368
1369 # Set a local variable for each rule in ruleset
1370 foreach key [dict keys $sky130::ruleset] {
1371 set $key [dict get $sky130::ruleset $key]
1372 }
1373
1374 set newdict [dict create \
1375 dev_type pdiodehvt \
1376 guard 1 \
1377 dev_contact_type pdihvtc \
1378 end_type nnd \
1379 end_contact_type nsc \
1380 end_sub_type nwell \
1381 plus_diff_type psd \
1382 plus_contact_type psc \
1383 sub_type psub \
1384 dev_spacing ${diff_spacing} \
1385 dev_surround ${diff_surround} \
1386 end_spacing ${diff_spacing} \
1387 end_surround ${diff_surround} \
1388 ]
1389 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1390 return [sky130::diode_draw $drawdict]
1391}
1392
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001393
1394#----------------------------------------------------------------
1395
Tim Edwardsbe6f1202020-10-29 10:37:46 -04001396proc sky130::sky130_fd_pr__diode_pd2nw_11v0_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001397
1398 # Set a local variable for each rule in ruleset
1399 foreach key [dict keys $sky130::ruleset] {
1400 set $key [dict get $sky130::ruleset $key]
1401 }
1402
1403 set newdict [dict create \
1404 guard 1 \
1405 dev_type mvpdiode \
1406 dev_contact_type mvpdic \
1407 end_type mvnsd \
1408 end_contact_type mvnsc \
1409 end_sub_type nwell \
1410 plus_diff_type mvpsd \
1411 plus_contact_type mvpsc \
1412 sub_type psub \
1413 diff_spacing 0.58 \
1414 dev_spacing 0.37 \
1415 dev_surround ${diff_surround} \
1416 end_spacing 0.30 \
1417 end_sub_surround 0.33 \
1418 end_surround ${diff_surround} \
1419 ]
1420 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1421 return [sky130::diode_draw $drawdict]
1422}
1423
1424#----------------------------------------------------------------
Tim Edwards27348db2020-10-28 22:49:29 -04001425# Drawn capacitor routines
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001426# NOTE: Work in progress. These values need to be corrected.
1427#----------------------------------------------------------------
1428
1429#ifdef MIM
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001430proc sky130::sky130_fd_pr__cap_mim_m3_1_defaults {} {
Tim Edwards15463bc2021-05-12 21:33:31 -04001431 return {w 2.00 l 2.00 val 8.0 carea 2.00 cperi 0.19 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001432 nx 1 ny 1 dummy 0 square 0 lmin 2.00 wmin 2.00 \
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05001433 lmax 30.0 wmax 30.0 dc 0 bconnect 1 tconnect 1 \
1434 ccov 100}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001435}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001436proc sky130::sky130_fd_pr__cap_mim_m3_2_defaults {} {
Tim Edwards15463bc2021-05-12 21:33:31 -04001437 return {w 2.00 l 2.00 val 8.0 carea 2.00 cperi 0.19 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001438 nx 1 ny 1 dummy 0 square 0 lmin 2.00 wmin 2.00 \
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05001439 lmax 30.0 wmax 30.0 dc 0 bconnect 1 tconnect 1 \
1440 ccov 100}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001441}
1442#endif (MIM)
1443
1444
1445#----------------------------------------------------------------
1446# Recalculate capacitor values from GUI entries.
1447# Recomputes W/L and Value as long as 2 of them are present
1448# (To be completed)
1449#----------------------------------------------------------------
1450
1451proc sky130::cap_recalc {field parameters} {
1452 # Set a local variable for each parameter (e.g., $l, $w, etc.)
1453 foreach key [dict keys $parameters] {
1454 set $key [dict get $parameters $key]
1455 }
1456 switch $field {
1457 val { puts stdout "value changed" }
1458 w { puts stdout "width changed" }
1459 l { puts stdout "length changed" }
1460 }
1461 dict set parameters val $val
1462 dict set parameters w $w
1463 dict set parameters l $l
1464}
1465
1466#----------------------------------------------------------------
1467# Capacitor defaults:
1468#----------------------------------------------------------------
1469# w Width of drawn cap
1470# l Length of drawn cap
1471# nx Number of devices in X
1472# ny Number of devices in Y
1473# val Default cap value
1474# carea Area
1475# cperi Perimeter
1476# dummy Add dummy cap
1477# square Make square capacitor
1478#
1479# (not user-editable)
1480#
1481# wmin Minimum allowed width
1482# lmin Minimum allowed length
1483# dc Area to remove to calculated area
1484#----------------------------------------------------------------
1485
1486#----------------------------------------------------------------
1487# capacitor: Conversion from SPICE netlist parameters to toolkit
1488#----------------------------------------------------------------
1489
1490proc sky130::cap_convert {parameters} {
1491 set pdkparams [dict create]
1492 dict for {key value} $parameters {
1493 switch -nocase $key {
1494 l -
1495 w {
1496 # Length and width are converted to units of microns
1497 set value [magic::spice2float $value]
1498 # set value [expr $value * 1e6]
1499 set value [magic::3digitpastdecimal $value]
1500 dict set pdkparams [string tolower $key] $value
1501 }
1502 m {
1503 # Convert m to ny
1504 dict set pdkparams ny $value
1505 }
1506 }
1507 }
1508 return $pdkparams
1509}
1510
1511#ifdef MIM
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001512proc sky130::sky130_fd_pr__cap_mim_m3_1_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001513 return [cap_convert $parameters]
1514}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001515proc sky130::sky130_fd_pr__cap_mim_m3_2_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001516 return [cap_convert $parameters]
1517}
1518#endif (MIM)
1519
1520#----------------------------------------------------------------
1521# capacitor: Interactively specifies the fixed layout parameters
1522#----------------------------------------------------------------
1523
1524proc sky130::cap_dialog {device parameters} {
1525 # Editable fields: w, l, nx, ny, val
1526 # Checked fields: square, dummy
1527
1528 magic::add_entry val "Value (fF)" $parameters
1529 sky130::compute_ctot $parameters
1530 magic::add_message ctot "Total capacitance (pF)" $parameters
1531 magic::add_entry l "Length (um)" $parameters
1532 magic::add_entry w "Width (um)" $parameters
1533 magic::add_entry nx "X Repeat" $parameters
1534 magic::add_entry ny "Y Repeat" $parameters
1535
1536 if {[dict exists $parameters square]} {
1537 magic::add_checkbox square "Square capacitor" $parameters
1538 }
1539 if {[dict exists $parameters bconnect]} {
1540 magic::add_checkbox bconnect "Connect bottom plates in array" $parameters
1541 }
1542 if {[dict exists $parameters tconnect]} {
1543 magic::add_checkbox tconnect "Connect top plates in array" $parameters
1544 }
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05001545 if {[dict exists $parameters ccov]} {
1546 magic::add_entry ccov "Capacitor contact coverage \[+/-\](%)" $parameters
1547 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001548 if {[dict exists $parameters guard]} {
1549 magic::add_checkbox guard "Add guard ring" $parameters
1550 }
1551
1552 magic::add_dependency sky130::cap_recalc $device sky130 l w val
1553
1554 # magic::add_checkbox dummy "Add dummy" $parameters
1555}
1556
1557#ifdef MIM
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001558proc sky130::sky130_fd_pr__cap_mim_m3_1_dialog {parameters} {
1559 sky130::cap_dialog sky130_fd_pr__cap_mim_m3_1 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001560}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001561proc sky130::sky130_fd_pr__cap_mim_m3_2_dialog {parameters} {
1562 sky130::cap_dialog sky130_fd_pr__cap_mim_m3_2 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001563}
1564#endif (MIM)
1565
1566#----------------------------------------------------------------
1567# Capacitor total capacitance computation
1568#----------------------------------------------------------------
1569
1570proc sky130::compute_ctot {parameters} {
1571 foreach key [dict keys $parameters] {
1572 set $key [dict get $parameters $key]
1573 }
1574 set val [magic::spice2float $val]
1575 set val [magic::3digitpastdecimal $val]
1576
1577 # Compute total capacitance (and convert fF to pF)
1578 catch {set magic::ctot_val [expr (0.001 * $val * $nx * $ny)]}
1579}
1580
1581#----------------------------------------------------------------
1582# Capacitor: Draw a single device
1583#----------------------------------------------------------------
1584
1585proc sky130::cap_device {parameters} {
1586 # Epsilon for avoiding round-off errors
1587 set eps 0.0005
1588
1589 # Set local default values if they are not in parameters
1590 set cap_surround 0
1591 set bot_surround 0
1592 set top_surround 0
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05001593 set end_spacing 0
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001594 set bconnect 0 ;# bottom plates are connected in array
1595 set cap_spacing 0 ;# cap spacing in array
1596 set top_metal_space 0 ;# top metal spacing (if larger than cap spacing)
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05001597 set top_metal_width 0 ;# top metal minimum width
1598 set contact_size 0 ;# cap contact minimum size
1599 set ccov 100 ;# amount of contact coverage
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001600
1601 # Set a local variable for each parameter (e.g., $l, $w, etc.)
1602 foreach key [dict keys $parameters] {
1603 set $key [dict get $parameters $key]
1604 }
1605
1606 if {![dict exists $parameters top_metal_space]} {
1607 set top_metal_space $metal_spacing
1608 }
1609
1610 # Draw the device
1611 pushbox
1612 box size 0 0
1613
1614 pushbox
1615 set hw [/ $w 2.0]
1616 set hl [/ $l 2.0]
1617 box grow e ${hw}um
1618 box grow w ${hw}um
1619 box grow n ${hl}um
1620 box grow s ${hl}um
1621 paint ${cap_type}
1622 pushbox
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05001623
1624 # Find contact width if ccov is other than 100
1625 set cmaxw [- $w [* $cap_surround 2]]
1626 set cw [* $cmaxw [/ [expr abs($ccov)] 100.0]]
1627 # Contact width must meet minimum
1628 if {$cw < $contact_size} {set cw $contact_size}
1629 if {$cw < $top_metal_width} {set cw $top_metal_width}
1630 # Difference between maximum contact width and actual contact width
1631 set cdif [- $cmaxw $cw]
1632
1633 # Reduce the box to the maximum contact area
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001634 box grow n -${cap_surround}um
1635 box grow s -${cap_surround}um
1636 box grow e -${cap_surround}um
1637 box grow w -${cap_surround}um
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05001638
1639 set anchor [string index $ccov 0]
1640 if {$anchor == "+"} {
1641 box grow e -${cdif}um
1642 } elseif {$anchor == "-"} {
1643 box grow w -${cdif}um
1644 } else {
1645 set cdif [/ ${cdif} 2]
1646 box grow w -${cdif}um
1647 box grow e -${cdif}um
1648 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001649 paint ${cap_contact_type}
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05001650
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001651 pushbox
1652 box grow n ${top_surround}um
1653 box grow s ${top_surround}um
1654 box grow e ${top_surround}um
1655 box grow w ${top_surround}um
1656 paint ${top_type}
1657 set cext [sky130::getbox]
1658 popbox
1659 popbox
1660 pushbox
1661 box grow n ${bot_surround}um
1662 box grow s ${bot_surround}um
1663 box grow e ${bot_surround}um
1664 box grow w ${bot_surround}um
1665
1666 paint ${bot_type}
1667 # Create boundary using properties
1668 property FIXED_BBOX [box values]
1669 set cext [sky130::unionbox $cext [sky130::getbox]]
1670
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05001671 # Calculate the distance from the top metal on the cap contact
1672 # to the top metal on the end contact.
1673 set top_met_sep [+ $end_spacing [- $cdif $top_surround]]
1674
1675 # Diagnostic!
1676 puts stdout "cdif = $cdif"
1677 puts stdout "top_met_sep = $top_met_sep"
1678
1679 # Increase end spacing if top metal spacing rule is not met
1680 set loc_end_spacing $end_spacing
1681 if {$top_met_sep < $top_metal_space} {
1682 set loc_end_spacing [+ $loc_end_spacing [- $top_metal_space $top_met_sep]]
1683 }
1684 # Diagnostic!
1685 puts stdout "loc_end_spacing = $loc_end_spacing"
1686
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001687 # Extend bottom metal under contact to right
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05001688 box grow e ${loc_end_spacing}um
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001689 set chw [/ ${contact_size} 2.0]
1690 box grow e ${chw}um
1691 box grow e ${end_surround}um
1692 paint ${bot_type}
1693
1694 popbox
1695 popbox
1696
1697 # Draw contact to right. Reduce contact extent if devices are not
1698 # wired together and the top metal spacing rule limits the distance
1699 set lcont $l
1700 if {($bconnect == 0) && ($ny > 1)} {
1701 if {$cap_spacing < $top_metal_space} {
1702 set cspace [- $top_metal_space $cap_spacing]
1703 set lcont [- $l $cspace]
1704 }
1705 }
1706
1707 pushbox
1708 box move e ${hw}um
1709 box move e ${bot_surround}um
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05001710 box move e ${loc_end_spacing}um
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001711 set cl [- [+ ${lcont} [* ${bot_surround} 2.0]] [* ${end_surround} 2.0]]
1712 set cl [- ${cl} ${metal_surround}] ;# see below
1713 set cext [sky130::unionbox $cext [sky130::draw_contact 0 ${cl} \
1714 ${end_surround} ${metal_surround} ${contact_size} \
1715 ${bot_type} ${top_contact_type} ${top_type} full]]
1716 popbox
1717 popbox
1718
1719 return $cext
1720
1721 # cl shrinks top and bottom to accomodate larger bottom metal
1722 # surround rule for contacts near a MiM cap. This should be its
1723 # own variable, but metal_surround is sufficient.
1724}
1725
1726#----------------------------------------------------------------
1727# Metal plate sandwich capacitor: Draw a single device
1728#----------------------------------------------------------------
1729
1730proc sky130::sandwich_cap_device {parameters} {
1731
1732 # Set a local variable for each parameter (e.g., $l, $w, etc.)
1733 foreach key [dict keys $parameters] {
1734 set $key [dict get $parameters $key]
1735 }
1736
1737 pushbox
1738 box size 0 0
1739
1740 set hw [/ $w 2.0]
1741 set hl [/ $l 2.0]
1742
1743 set cw [- [* $hw [/ 2.0 3]] [* $cont_surround 2.0]]
1744 set cl [- [* $hl [/ 2.0 3]] [* $cont_surround 2.0]]
1745
1746 # plate capacitor defines layers p0, p1, etc.
1747 for {set i 0} {$i < 20} {incr i} {
1748 if {[catch {set layer [subst \$p${i}_type]}]} {break} ;# no more layers defined
1749 pushbox
1750 box grow e ${hw}um
1751 box grow w ${hw}um
1752 box grow n ${hl}um
1753 box grow s ${hl}um
1754 if {![catch {set shrink [subst \$p${i}_shrink]}]} {
1755 box grow e -${shrink}um
1756 box grow w -${shrink}um
1757 box grow n -${shrink}um
1758 box grow s -${shrink}um
1759 set cutout_spacing [+ [* ${shrink} 2.0] [/ $via_size 2.0] $cont_surround]
1760 } else {
1761 set cutout_spacing 0
1762 }
1763
1764 paint ${layer}
1765
1766 if {$i == 1} {
1767 # Note that cap_type geometry is coincident with p1_type.
1768 # Typically, this will define a layer that outputs as both
1769 # poly and a capacitor definition layer.
1770 if {[dict exists $parameters cap_type]} {
1771 paint $cap_type
1772 }
1773 }
1774 popbox
1775
1776 # Even layers connect at corners, odd layers connect at sides.
1777 # Even layers cut out the sides, odd layers cut out the corners.
1778 # Layer zero has no side contacts or cutout.
1779
1780 if {[% $i 2] == 0} {
1781 set cornercmd paint
1782 set cornersize $cutout_spacing
1783 set sidecmd erase
1784 set nssidelong [+ $cutout_spacing [/ $hw 3.0]]
1785 set ewsidelong [+ $cutout_spacing [/ $hl 3.0]]
1786 set sideshort $cutout_spacing
1787 } else {
1788 set cornercmd erase
1789 set cornersize $cutout_spacing
1790 set sidecmd paint
1791 set nssidelong [/ $hw 3.0]
1792 set ewsidelong [/ $hl 3.0]
1793 set sideshort $cutout_spacing
1794 }
1795
1796 if {$i > 0} {
1797 pushbox
1798 box move e ${hw}um
1799 box grow n ${ewsidelong}um
1800 box grow s ${ewsidelong}um
1801 box grow w ${sideshort}um
1802 ${sidecmd} ${layer}
1803 popbox
1804 pushbox
1805 box move n ${hl}um
1806 box grow e ${nssidelong}um
1807 box grow w ${nssidelong}um
1808 box grow s ${sideshort}um
1809 ${sidecmd} ${layer}
1810 popbox
1811 pushbox
1812 box move w ${hw}um
1813 box grow n ${ewsidelong}um
1814 box grow s ${ewsidelong}um
1815 box grow e ${sideshort}um
1816 ${sidecmd} ${layer}
1817 popbox
1818 pushbox
1819 box move s ${hl}um
1820 box grow e ${nssidelong}um
1821 box grow w ${nssidelong}um
1822 box grow n ${sideshort}um
1823 ${sidecmd} ${layer}
1824 popbox
1825
1826 pushbox
1827 box move n ${hl}um
1828 box move e ${hw}um
1829 box grow s ${cornersize}um
1830 box grow w ${cornersize}um
1831 ${cornercmd} ${layer}
1832 popbox
1833 pushbox
1834 box move n ${hl}um
1835 box move w ${hw}um
1836 box grow s ${cornersize}um
1837 box grow e ${cornersize}um
1838 ${cornercmd} ${layer}
1839 popbox
1840 pushbox
1841 box move s ${hl}um
1842 box move e ${hw}um
1843 box grow n ${cornersize}um
1844 box grow w ${cornersize}um
1845 ${cornercmd} ${layer}
1846 popbox
1847 pushbox
1848 box move s ${hl}um
1849 box move w ${hw}um
1850 box grow n ${cornersize}um
1851 box grow e ${cornersize}um
1852 ${cornercmd} ${layer}
1853 popbox
1854 }
1855 }
1856
1857 # Draw contacts after all layers have been drawn, so that erasing
1858 # layers does not affect the contacts.
1859
1860 for {set i 0} {$i < 20} {incr i} {
1861 if {![catch {set contact [subst \$p${i}_contact_type]}]} {
1862 set layer [subst \$p${i}_type]
1863 set j [+ $i 1]
1864 set toplayer [subst \$p${j}_type]
1865
1866 # Draw corner contacts
1867 pushbox
1868 box move e ${hw}um
1869 box move n ${hl}um
1870 sky130::draw_contact 0 0 \
1871 ${cont_surround} ${cont_surround} ${via_size} \
1872 ${layer} ${contact} ${toplayer} full
1873 popbox
1874 pushbox
1875 box move w ${hw}um
1876 box move n ${hl}um
1877 sky130::draw_contact 0 0 \
1878 ${cont_surround} ${cont_surround} ${via_size} \
1879 ${layer} ${contact} ${toplayer} full
1880 popbox
1881 pushbox
1882 box move e ${hw}um
1883 box move s ${hl}um
1884 sky130::draw_contact 0 0 \
1885 ${cont_surround} ${cont_surround} ${via_size} \
1886 ${layer} ${contact} ${toplayer} full
1887 popbox
1888 pushbox
1889 box move w ${hw}um
1890 box move s ${hl}um
1891 sky130::draw_contact 0 0 \
1892 ${cont_surround} ${cont_surround} ${via_size} \
1893 ${layer} ${contact} ${toplayer} full
1894 popbox
1895
1896 # Draw side contacts (except on poly)
1897 if {$i > 0} {
1898 pushbox
1899 box move w ${hw}um
1900 sky130::draw_contact 0 ${cl} \
1901 ${cont_surround} ${cont_surround} ${via_size} \
1902 ${layer} ${contact} ${toplayer} full
1903 popbox
1904 pushbox
1905 box move e ${hw}um
1906 sky130::draw_contact 0 ${cl} \
1907 ${cont_surround} ${cont_surround} ${via_size} \
1908 ${layer} ${contact} ${toplayer} full
1909 popbox
1910 pushbox
1911 box move n ${hl}um
1912 sky130::draw_contact ${cw} 0 \
1913 ${cont_surround} ${cont_surround} ${via_size} \
1914 ${layer} ${contact} ${toplayer} full
1915 popbox
1916 pushbox
1917 box move s ${hl}um
1918 sky130::draw_contact ${cw} 0 \
1919 ${cont_surround} ${cont_surround} ${via_size} \
1920 ${layer} ${contact} ${toplayer} full
1921 popbox
1922 }
1923 } else {
1924 break
1925 }
1926 }
1927
1928 popbox
1929 # Bounding box is the same as the device length and width
1930 set cext [list -$hw -$hl $hw $hl]
1931 return $cext
1932}
1933
1934#----------------------------------------------------------------
1935# Capacitor: Draw the tiled device
1936#----------------------------------------------------------------
1937
1938proc sky130::cap_draw {parameters} {
1939 tech unlock *
1940 set savesnap [snap]
1941 snap internal
1942
1943 # Set defaults if they are not in parameters
1944 set coverlap 0 ;# overlap capacitors at contacts
1945 set guard 0 ;# draw a guard ring
1946 set sandwich 0 ;# this is not a plate sandwich capacitor
1947 set cap_spacing 0 ;# abutted caps if spacing is zero
1948 set cap_diff_spacing 0
1949 set wide_cap_spacing 0 ;# additional spacing for wide metal rule
1950 set wide_cap_width 0
1951 set end_spacing 0
1952 set end_surround 0
1953 set bot_surround 0
1954 set top_metal_width 0
1955 set bconnect 0 ;# connect bottom plates in array
1956 set tconnect 0 ;# connect top plates in array
1957 set top_type ""
1958
1959 # Set a local variable for each parameter (e.g., $l, $w, etc.)
1960 foreach key [dict keys $parameters] {
1961 set $key [dict get $parameters $key]
1962 }
1963
1964 # Normalize distance units to microns
1965 set w [magic::spice2float $w]
1966 set l [magic::spice2float $l]
1967
1968 pushbox
1969 box values 0 0 0 0
1970
1971 # Determine the base device dimensions by drawing one device
1972 # while all layers are locked (nothing drawn). This allows the
1973 # base drawing routine to do complicated geometry without having
1974 # to duplicate it here with calculations.
1975
1976 tech lock *
1977 if {$sandwich == 1} {
1978 set bbox [sky130::sandwich_cap_device $parameters]
1979 } else {
1980 set bbox [sky130::cap_device $parameters]
1981 }
1982 # puts stdout "Diagnostic: Device bounding box e $bbox (um)"
1983 tech unlock *
1984
1985 set fw [- [lindex $bbox 2] [lindex $bbox 0]]
1986 set fh [- [lindex $bbox 3] [lindex $bbox 1]]
1987 set lw [+ [lindex $bbox 2] [lindex $bbox 0]]
1988 set lh [+ [lindex $bbox 3] [lindex $bbox 1]]
1989
1990 set dwide 0
1991 if {($fw >= $wide_cap_width) && ($fh >= $wide_cap_width)} {
1992 set dwide $wide_cap_spacing
1993 }
1994
1995 # Determine tile width and height (depends on overlap)
1996 if {$coverlap == 0} {
1997 set dy [+ $fh $cap_spacing $dwide]
1998 } else {
1999 # overlap at end contact
2000 set dy [- $fh [+ $end_surround $end_surround $contact_size]]
2001 }
2002 # Contact is placed on right so spacing is determined by end_spacing.
2003 set dx [+ $fw $end_spacing $dwide]
2004
2005 # Determine core width and height
2006 set corex [+ [* [- $nx 1] $dx] $fw]
2007 set corey [+ [* [- $ny 1] $dy] $fh]
2008 set corellx [/ [+ [- $corex $fw] $lw] 2.0]
2009 set corelly [/ [+ [- $corey $fh] $lh] 2.0]
2010
2011 if {$guard != 0} {
2012 # Calculate guard ring size (measured to contact center)
2013 set gx [+ $corex [* 2.0 [+ $cap_diff_spacing $diff_surround]] $contact_size]
2014 set gy [+ $corey [* 2.0 [+ $end_spacing $diff_surround]] $contact_size]
2015
2016 # Draw the guard ring first.
2017 sky130::guard_ring $gx $gy $parameters
2018 }
2019
2020 set twidth [+ ${contact_size} ${end_surround} ${end_surround}]
2021 if {${twidth} < ${top_metal_width}} {
2022 set twidth ${top_metal_width}
2023 }
2024 set hmw [/ $twidth 2.0]
2025 set hdy [/ $dy 2.0]
2026 set cdx [+ [/ ${w} 2.0] ${bot_surround} ${end_spacing}]
2027
2028 pushbox
2029 box move w ${corellx}um
2030 box move s ${corelly}um
2031 for {set xp 0} {$xp < $nx} {incr xp} {
2032 pushbox
2033 for {set yp 0} {$yp < $ny} {incr yp} {
2034 if {$sandwich == 1} {
2035 sky130::sandwich_cap_device $parameters
2036 } else {
2037 sky130::cap_device $parameters
2038 }
2039 if {$ny > 1} {
2040 pushbox
2041 box grow e ${hmw}um
2042 box grow w ${hmw}um
2043 box grow n ${hdy}um
2044 box grow s ${hdy}um
2045 if {($top_type != "") && ($tconnect == 1)} {
2046 paint ${top_type}
2047 }
2048 if {($top_type != "") && ($bconnect == 1)} {
2049 box move e ${cdx}um
2050 paint ${top_type}
2051 }
2052 popbox
2053 }
2054 box move n ${dy}um
2055 }
2056 popbox
2057 box move e ${dx}um
2058 }
2059 popbox
2060 popbox
2061
2062 snap $savesnap
2063 tech revert
2064}
2065
2066#----------------------------------------------------------------
2067
2068#ifdef MIM
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002069proc sky130::sky130_fd_pr__cap_mim_m3_1_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002070 set newdict [dict create \
2071 top_type m4 \
2072 top_contact_type via3 \
2073 cap_type mimcap \
2074 cap_contact_type mimcc \
2075 bot_type m3 \
2076 bot_surround 0.5 \
2077 cap_spacing 0.5 \
2078 cap_surround 0.2 \
2079 top_surround 0.005 \
2080 end_surround 0.1 \
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05002081 end_spacing 0.1 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002082 contact_size 0.32 \
2083 metal_surround 0.08 \
2084 ]
2085 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
2086 return [sky130::cap_draw $drawdict]
2087}
2088
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002089proc sky130::sky130_fd_pr__cap_mim_m3_2_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002090 set newdict [dict create \
2091 top_type m5 \
2092 top_contact_type via4 \
2093 cap_type mimcap2 \
2094 cap_contact_type mim2cc \
2095 bot_type m4 \
2096 bot_surround 0.5 \
2097 cap_spacing 0.5 \
2098 cap_surround 0.2 \
2099 top_surround 0.12 \
2100 end_surround 0.1 \
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05002101 end_spacing 0.1 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002102 contact_size 1.18 \
2103 metal_surround 0.21 \
2104 top_metal_width 1.6 \
2105 top_metal_space 1.7 \
2106 ]
2107 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
2108 return [sky130::cap_draw $drawdict]
2109}
2110
2111#endif (MIM)
2112
2113#----------------------------------------------------------------
2114# capacitor: Check device parameters for out-of-bounds values
2115#----------------------------------------------------------------
2116
2117proc sky130::cap_check {parameters} {
2118 # In case wmax and/or lmax are undefined
2119 set lmax 0
2120 set wmax 0
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05002121 set ccov 100
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002122
2123 # Set a local variable for each parameter (e.g., $l, $w, etc.)
2124 foreach key [dict keys $parameters] {
2125 set $key [dict get $parameters $key]
2126 }
2127
2128 # Normalize distance units to microns
2129 set l [magic::spice2float $l]
2130 set l [magic::3digitpastdecimal $l]
2131 set w [magic::spice2float $w]
2132 set w [magic::3digitpastdecimal $w]
2133
2134 set val [magic::spice2float $val]
2135 set carea [magic::spice2float $carea]
2136 set cperi [magic::spice2float $cperi]
2137 set dc [magic::spice2float $dc]
2138
2139 if {$square == 1} {
2140 # Calculate L and W from value
2141 set a $carea
2142 set b [expr $cperi * 4]
2143 set c [expr -4 * $dc - $val]
2144 set l [expr ((-$b + sqrt($b * $b - (4 * $a * $c))) / (2 * $a))]
2145 dict set parameters l [magic::float2spice $l]
2146 set w $l
2147 dict set parameters w [magic::float2spice $w]
2148 } elseif {$l == 0} {
2149 # Calculate L from W and value
2150 set l [expr (($val + 4 * $dc - 2 * $w * $cperi) / ($w * $carea + 2 * $cperi))]
2151 dict set parameters l [magic::float2spice $l]
2152 } elseif {$w == 0} {
2153 # Calculate W from L and value
2154 set w [expr (($val + 4 * $dc - 2 * $l * $cperi) / ($l * $carea + 2 * $cperi))]
2155 dict set parameters w [magic::float2spice $w]
2156 }
2157 if {$w < $wmin} {
2158 puts stderr "Capacitor width must be >= $wmin"
2159 dict set parameters w $wmin
2160 set w $wmin
2161 }
2162 if {$l < $lmin} {
2163 puts stderr "Capacitor length must be >= $lmin"
2164 dict set parameters l $lmin
2165 set l $lmin
2166 }
2167 if {($wmax > 0) && ($w > $wmax)} {
2168 puts stderr "Capacitor width must be <= $wmax"
2169 dict set parameters w $wmax
2170 set w $wmax
2171 }
2172 if {($lmax > 0) && ($l > $lmax)} {
2173 puts stderr "Capacitor length must be <= $lmax"
2174 dict set parameters l $lmax
2175 set l $lmax
2176 }
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05002177 if {[catch {expr abs($ccov)}]} {
2178 puts stderr "Capacitor contact coverage must be numeric!"
2179 dict set parameters ccov 100
2180 } elseif {[expr abs($ccov)] > 100} {
2181 puts stderr "Capaitor contact coverage can't be more than 100%"
2182 dict set parameters ccov 100
2183 }
2184
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002185 # Calculate value from L and W
2186 set cval [expr ($l * $w * $carea + 2 * ($l + $w) * $cperi - 4 * $dc)]
2187 dict set parameters val [magic::float2spice $cval]
2188 sky130::compute_ctot $parameters
2189
2190 return $parameters
2191}
2192
2193#ifdef MIM
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002194proc sky130::sky130_fd_pr__cap_mim_m3_1_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002195 return [sky130::cap_check $parameters]
2196}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002197proc sky130::sky130_fd_pr__cap_mim_m3_2_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002198 return [sky130::cap_check $parameters]
2199}
2200#endif (MIM)
2201
2202#----------------------------------------------------------------
2203# Drawn resistors
2204#----------------------------------------------------------------
2205
2206#----------------------------------------------------------------
2207# Resistor defaults:
2208#----------------------------------------------------------------
2209# User editable values:
2210#
2211# val Resistor value in ohms
2212# w Width
2213# l Length
2214# t Number of turns
2215# m Number devices in Y
2216# nx Number devices in X
2217# snake Use snake geometry (if not present, snake geometry not allowed)
2218# dummy Flag to mark addition of dummy resistor
2219#
2220# Non-user editable values:
2221#
2222# wmin Minimum allowed width
2223# lmin Minimum allowed length
2224# rho Resistance in ohms per square
2225# dw Delta width
2226# term Resistance per terminal
2227# sterm Additional resistance per terminal for snake geometry
2228#----------------------------------------------------------------
2229
2230#----------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002231# sky130_fd_pr__res_iso_pw: Specify all user-editable default values and those
2232# needed by sky130_fd_pr__res_iso_pw_check
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002233# NOTE: Work in progress. These values need to be corrected.
2234#----------------------------------------------------------------
2235
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002236proc sky130::sky130_fd_pr__res_iso_pw_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002237 return {w 2.650 l 26.50 m 1 nx 1 wmin 2.650 lmin 26.50 \
2238 rho 975 val 4875 dummy 0 dw 0.25 term 1.0 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002239 guard 1 endcov 100 full_metal 1 vias 1 \
2240 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002241}
2242
2243#----------------------------------------------------------------
2244# rpp1: Specify all user-editable default values and those
2245# needed by rp1_check
2246#----------------------------------------------------------------
2247
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002248proc sky130::sky130_fd_pr__res_generic_po_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002249 return {w 0.330 l 1.650 m 1 nx 1 wmin 0.330 lmin 1.650 \
2250 rho 48.2 val 241 dummy 0 dw 0.0 term 0.0 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002251 sterm 0.0 caplen 0.4 snake 0 guard 1 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002252 glc 1 grc 1 gtc 1 gbc 1 roverlap 0 endcov 100 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04002253 full_metal 1 hv_guard 0 n_guard 0 vias 1 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002254 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002255}
2256
2257# "term" is rho * 0.06, the distance between xpc edge and CONT.
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002258proc sky130::sky130_fd_pr__res_high_po_0p35_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002259 return {w 0.350 l 0.50 m 1 nx 1 wmin 0.350 lmin 0.50 \
2260 rho 319.8 val 456.857 dummy 0 dw 0.0 term 19.188 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002261 sterm 0.0 caplen 0 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002262 compatible {sky130_fd_pr__res_high_po_0p35 \
2263 sky130_fd_pr__res_high_po_0p69 sky130_fd_pr__res_high_po_1p41 \
2264 sky130_fd_pr__res_high_po_2p85 sky130_fd_pr__res_high_po_5p73} \
Tim Edwardsf788cea2021-04-20 12:43:52 -04002265 full_metal 1 wmax 0.350 vias 1 n_guard 0 hv_guard 0 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002266 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002267}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002268proc sky130::sky130_fd_pr__res_high_po_0p69_defaults {} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002269 return {w 0.690 l 1.00 m 1 nx 1 wmin 0.690 lmin 0.50 \
2270 rho 319.8 val 463.480 dummy 0 dw 0.0 term 19.188 \
2271 sterm 0.0 caplen 0 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002272 compatible {sky130_fd_pr__res_high_po_0p35 \
2273 sky130_fd_pr__res_high_po_0p69 sky130_fd_pr__res_high_po_1p41 \
2274 sky130_fd_pr__res_high_po_2p85 sky130_fd_pr__res_high_po_5p73} \
Tim Edwardsf788cea2021-04-20 12:43:52 -04002275 full_metal 1 wmax 0.690 n_guard 0 hv_guard 0 vias 1 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002276 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002277}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002278proc sky130::sky130_fd_pr__res_high_po_1p41_defaults {} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002279 return {w 1.410 l 2.00 m 1 nx 1 wmin 1.410 lmin 0.50 \
2280 rho 319.8 val 453.620 dummy 0 dw 0.0 term 19.188 \
2281 sterm 0.0 caplen 0 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002282 compatible {sky130_fd_pr__res_high_po_0p35 \
2283 sky130_fd_pr__res_high_po_0p69 sky130_fd_pr__res_high_po_1p41 \
2284 sky130_fd_pr__res_high_po_2p85 sky130_fd_pr__res_high_po_5p73} \
Tim Edwardsf788cea2021-04-20 12:43:52 -04002285 full_metal 1 wmax 1.410 n_guard 0 hv_guard 0 vias 1 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002286 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002287}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002288proc sky130::sky130_fd_pr__res_high_po_2p85_defaults {} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002289 return {w 2.850 l 3.00 m 1 nx 1 wmin 2.850 lmin 0.50 \
2290 rho 319.8 val 336.630 dummy 0 dw 0.0 term 19.188 \
2291 sterm 0.0 caplen 0 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002292 compatible {sky130_fd_pr__res_high_po_0p35 \
2293 sky130_fd_pr__res_high_po_0p69 sky130_fd_pr__res_high_po_1p41 \
2294 sky130_fd_pr__res_high_po_2p85 sky130_fd_pr__res_high_po_5p73} \
Tim Edwardsf788cea2021-04-20 12:43:52 -04002295 full_metal 1 wmax 2.850 n_guard 0 hv_guard 0 vias 1 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002296 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002297}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002298proc sky130::sky130_fd_pr__res_high_po_5p73_defaults {} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002299 return {w 5.730 l 6.00 m 1 nx 1 wmin 5.730 lmin 0.50 \
2300 rho 319.8 val 334.870 dummy 0 dw 0.0 term 19.188 \
2301 sterm 0.0 caplen 0 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002302 compatible {sky130_fd_pr__res_high_po_0p35 \
2303 sky130_fd_pr__res_high_po_0p69 sky130_fd_pr__res_high_po_1p41 \
2304 sky130_fd_pr__res_high_po_2p85 sky130_fd_pr__res_high_po_5p73} \
Tim Edwardsf788cea2021-04-20 12:43:52 -04002305 full_metal 1 wmax 5.730 n_guard 0 hv_guard 0 vias 1 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002306 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002307}
2308
2309# "term" is rho * 0.06, the distance between xpc edge and CONT.
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002310proc sky130::sky130_fd_pr__res_xhigh_po_0p35_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002311 return {w 0.350 l 0.50 m 1 nx 1 wmin 0.350 lmin 0.50 \
Tim Edwards19e19832021-04-12 16:23:09 -04002312 rho 2000 val 2875.143 dummy 0 dw 0.0 term 19.188 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002313 sterm 0.0 caplen 0 wmax 0.350 \
2314 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002315 compatible {sky130_fd_pr__res_xhigh_po_0p35 \
2316 sky130_fd_pr__res_xhigh_po_0p69 sky130_fd_pr__res_xhigh_po_1p41 \
2317 sky130_fd_pr__res_xhigh_po_2p85 sky130_fd_pr__res_xhigh_po_5p73} \
Tim Edwardsf788cea2021-04-20 12:43:52 -04002318 full_metal 1 n_guard 0 hv_guard 0 vias 1 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002319 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002320}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002321proc sky130::sky130_fd_pr__res_xhigh_po_0p69_defaults {} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002322 return {w 0.690 l 1.00 m 1 nx 1 wmin 0.690 lmin 0.50 \
Tim Edwards19e19832021-04-12 16:23:09 -04002323 rho 2000 val 2898.600 dummy 0 dw 0.0 term 19.188 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002324 sterm 0.0 caplen 0 wmax 0.690 \
2325 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002326 compatible {sky130_fd_pr__res_xhigh_po_0p35 \
2327 sky130_fd_pr__res_xhigh_po_0p69 sky130_fd_pr__res_xhigh_po_1p41 \
2328 sky130_fd_pr__res_xhigh_po_2p85 sky130_fd_pr__res_xhigh_po_5p73} \
Tim Edwardsf788cea2021-04-20 12:43:52 -04002329 full_metal 1 n_guard 0 hv_guard 0 vias 1 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002330 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002331}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002332proc sky130::sky130_fd_pr__res_xhigh_po_1p41_defaults {} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002333 return {w 1.410 l 2.00 m 1 nx 1 wmin 1.410 lmin 0.50 \
Tim Edwards19e19832021-04-12 16:23:09 -04002334 rho 2000 val 2836.900 dummy 0 dw 0.0 term 19.188 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002335 sterm 0.0 caplen 0 wmax 1.410 \
2336 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002337 compatible {sky130_fd_pr__res_xhigh_po_0p35 \
2338 sky130_fd_pr__res_xhigh_po_0p69 sky130_fd_pr__res_xhigh_po_1p41 \
2339 sky130_fd_pr__res_xhigh_po_2p85 sky130_fd_pr__res_xhigh_po_5p73} \
Tim Edwardsf788cea2021-04-20 12:43:52 -04002340 full_metal 1 n_guard 0 hv_guard 0 vias 1 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002341 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002342}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002343proc sky130::sky130_fd_pr__res_xhigh_po_2p85_defaults {} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002344 return {w 2.850 l 3.00 m 1 nx 1 wmin 2.850 lmin 0.50 \
Tim Edwards19e19832021-04-12 16:23:09 -04002345 rho 2000 val 2105.300 dummy 0 dw 0.0 term 19.188 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002346 sterm 0.0 caplen 0 wmax 2.850 \
2347 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002348 compatible {sky130_fd_pr__res_xhigh_po_0p35 \
2349 sky130_fd_pr__res_xhigh_po_0p69 sky130_fd_pr__res_xhigh_po_1p41 \
2350 sky130_fd_pr__res_xhigh_po_2p85 sky130_fd_pr__res_xhigh_po_5p73} \
Tim Edwardsf788cea2021-04-20 12:43:52 -04002351 full_metal 1 n_guard 0 hv_guard 0 vias 1 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002352 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002353}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002354proc sky130::sky130_fd_pr__res_xhigh_po_5p73_defaults {} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002355 return {w 5.730 l 6.00 m 1 nx 1 wmin 5.730 lmin 0.50 \
Tim Edwards19e19832021-04-12 16:23:09 -04002356 rho 2000 val 2094.200 dummy 0 dw 0.0 term 19.188 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002357 sterm 0.0 caplen 0 wmax 5.730 \
2358 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002359 compatible {sky130_fd_pr__res_xhigh_po_0p35 \
2360 sky130_fd_pr__res_xhigh_po_0p69 sky130_fd_pr__res_xhigh_po_1p41 \
2361 sky130_fd_pr__res_xhigh_po_2p85 sky130_fd_pr__res_xhigh_po_5p73} \
Tim Edwardsf788cea2021-04-20 12:43:52 -04002362 full_metal 1 n_guard 0 hv_guard 0 vias 1 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002363 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002364}
2365
2366#----------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002367# sky130_fd_pr__res_generic_nd: Specify all user-editable default values and those
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002368# needed by rdn_check
2369#----------------------------------------------------------------
2370
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002371proc sky130::sky130_fd_pr__res_generic_nd_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002372 return {w 0.420 l 2.100 m 1 nx 1 wmin 0.42 lmin 2.10 \
2373 rho 120 val 600.0 dummy 0 dw 0.05 term 0.0 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002374 sterm 0.0 caplen 0.4 snake 0 guard 1 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002375 glc 1 grc 1 gtc 1 gbc 1 roverlap 0 endcov 100 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002376 full_metal 1 vias 1 \
2377 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002378}
2379
Tim Edwards0ee0f182020-11-21 16:15:07 -05002380proc sky130::sky130_fd_pr__res_generic_nd__hv_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002381 return {w 0.420 l 2.100 m 1 nx 1 wmin 0.42 lmin 2.10 \
2382 rho 120 val 600.0 dummy 0 dw 0.02 term 0.0 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002383 sterm 0.0 caplen 0.4 snake 0 guard 1 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002384 glc 1 grc 1 gtc 1 gbc 1 roverlap 0 endcov 100 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002385 full_metal 1 vias 1 \
2386 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002387}
2388
2389#----------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002390# sky130_fd_pr__res_generic_pd: Specify all user-editable default values and those
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002391# needed by rdp_check
2392#----------------------------------------------------------------
2393
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002394proc sky130::sky130_fd_pr__res_generic_pd_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002395 return {w 0.420 l 2.100 m 1 nx 1 wmin 0.42 lmin 2.10 \
2396 rho 197 val 985.0 dummy 0 dw 0.02 term 0.0 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002397 sterm 0.0 caplen 0.60 snake 0 guard 1 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002398 glc 1 grc 1 gtc 1 gbc 1 roverlap 0 endcov 100 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002399 full_metal 1 vias 1 \
2400 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002401}
2402
Tim Edwards0ee0f182020-11-21 16:15:07 -05002403proc sky130::sky130_fd_pr__res_generic_pd__hv_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002404 return {w 0.420 l 2.100 m 1 nx 1 wmin 0.42 lmin 2.10 \
2405 rho 197 val 985.0 dummy 0 dw 0.02 term 0.0 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002406 sterm 0.0 caplen 0.60 snake 0 guard 1 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002407 glc 1 grc 1 gtc 1 gbc 1 roverlap 0 endcov 100 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002408 full_metal 1 vias 1 \
2409 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002410}
2411
2412#----------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002413# sky130_fd_pr__res_generic_l1: Specify all user-editable default values and those needed
2414# by sky130_fd_pr__res_generic_l1_check
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002415#----------------------------------------------------------------
2416
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002417proc sky130::sky130_fd_pr__res_generic_l1_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002418 return {w 0.170 l 0.170 m 1 nx 1 wmin 0.17 lmin 0.17 \
2419 rho 12.8 val 12.8 dummy 0 dw 0.0 term 0.0 snake 0 \
2420 roverlap 0}
2421}
2422
2423#----------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002424# sky130_fd_pr__res_generic_m1: Specify all user-editable default values and those needed
2425# by sky130_fd_pr__res_generic_m1_check
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002426#----------------------------------------------------------------
2427
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002428proc sky130::sky130_fd_pr__res_generic_m1_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002429 return {w 0.140 l 0.140 m 1 nx 1 wmin 0.14 lmin 0.14 \
2430 rho 0.125 val 0.125 dummy 0 dw 0.0 term 0.0 \
2431 roverlap 0}
2432}
2433
2434#----------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002435# sky130_fd_pr__res_generic_m2: Specify all user-editable default values and those needed
2436# by sky130_fd_pr__res_generic_m2_check
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002437#----------------------------------------------------------------
2438
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002439proc sky130::sky130_fd_pr__res_generic_m2_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002440 return {w 0.140 l 0.140 m 1 nx 1 wmin 0.14 lmin 0.14 \
2441 rho 0.125 val 0.125 dummy 0 dw 0.0 term 0.0 \
2442 roverlap 0}
2443}
2444
2445#----------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002446# sky130_fd_pr__res_generic_m3: Specify all user-editable default values and those needed
2447# by sky130_fd_pr__res_generic_m3_check
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002448#----------------------------------------------------------------
2449
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002450proc sky130::sky130_fd_pr__res_generic_m3_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002451 return {w 0.300 l 0.300 m 1 nx 1 wmin 0.30 lmin 0.30 \
2452 rho 0.047 val 0.047 dummy 0 dw 0.0 term 0.0 \
2453 roverlap 0}
2454}
2455
2456#----------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002457# 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 -04002458# back-end metal stack.
2459#----------------------------------------------------------------
2460
2461#ifdef METAL5
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002462proc sky130::sky130_fd_pr__res_generic_m4_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002463 return {w 0.300 l 0.300 m 1 nx 1 wmin 0.30 lmin 0.30 \
2464 rho 0.047 val 0.047 dummy 0 dw 0.0 term 0.0 \
2465 roverlap 0}
2466}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002467proc sky130::sky130_fd_pr__res_generic_m5_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002468 return {w 1.600 l 1.600 m 1 nx 1 wmin 1.60 lmin 1.60 \
2469 rho 0.029 val 0.029 dummy 0 dw 0.0 term 0.0 \
2470 roverlap 0}
2471}
2472#endif (METAL5)
2473
2474#----------------------------------------------------------------
2475# resistor: Conversion from SPICE netlist parameters to toolkit
2476#----------------------------------------------------------------
2477
2478proc sky130::res_convert {parameters} {
2479 set pdkparams [dict create]
2480 dict for {key value} $parameters {
2481 switch -nocase $key {
2482 l -
2483 w {
2484 # Length and width are converted to units of microns
2485 set value [magic::spice2float $value]
2486 # set value [expr $value * 1e6]
2487 set value [magic::3digitpastdecimal $value]
2488 dict set pdkparams [string tolower $key] $value
2489 }
2490 }
2491 }
2492 return $pdkparams
2493}
2494
2495#----------------------------------------------------------------
2496
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002497proc sky130::sky130_fd_pr__res_iso_pw_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002498 return [sky130::res_convert $parameters]
2499}
2500
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002501proc sky130::sky130_fd_pr__res_generic_po_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002502 return [sky130::res_convert $parameters]
2503}
2504
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002505proc sky130::sky130_fd_pr__res_high_po_0p35_convert {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002506 return [sky130::res_convert $parameters]
2507}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002508proc sky130::sky130_fd_pr__res_high_po_0p69_convert {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002509 return [sky130::res_convert $parameters]
2510}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002511proc sky130::sky130_fd_pr__res_high_po_1p41_convert {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002512 return [sky130::res_convert $parameters]
2513}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002514proc sky130::sky130_fd_pr__res_high_po_2p85_convert {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002515 return [sky130::res_convert $parameters]
2516}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002517proc sky130::sky130_fd_pr__res_high_po_5p73_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002518 return [sky130::res_convert $parameters]
2519}
2520
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002521proc sky130::sky130_fd_pr__res_xhigh_po_0p35_convert {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002522 return [sky130::res_convert $parameters]
2523}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002524proc sky130::sky130_fd_pr__res_xhigh_po_0p69_convert {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002525 return [sky130::res_convert $parameters]
2526}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002527proc sky130::sky130_fd_pr__res_xhigh_po_1p41_convert {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002528 return [sky130::res_convert $parameters]
2529}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002530proc sky130::sky130_fd_pr__res_xhigh_po_2p85_convert {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002531 return [sky130::res_convert $parameters]
2532}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002533proc sky130::sky130_fd_pr__res_xhigh_po_5p73_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002534 return [sky130::res_convert $parameters]
2535}
2536
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002537proc sky130::sky130_fd_pr__res_generic_nd_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002538 return [sky130::res_convert $parameters]
2539}
2540
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002541proc sky130::sky130_fd_pr__res_generic_pd_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002542 return [sky130::res_convert $parameters]
2543}
2544
Tim Edwards0ee0f182020-11-21 16:15:07 -05002545proc sky130::sky130_fd_pr__res_generic_nd__hv_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002546 return [sky130::res_convert $parameters]
2547}
2548
Tim Edwards0ee0f182020-11-21 16:15:07 -05002549proc sky130::sky130_fd_pr__res_generic_pd__hv_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002550 return [sky130::res_convert $parameters]
2551}
2552
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002553proc sky130::sky130_fd_pr__res_generic_l1_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002554 return [sky130::res_convert $parameters]
2555}
2556
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002557proc sky130::sky130_fd_pr__res_generic_m1_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002558 return [sky130::res_convert $parameters]
2559}
2560
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002561proc sky130::sky130_fd_pr__res_generic_m2_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002562 return [sky130::res_convert $parameters]
2563}
2564
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002565proc sky130::sky130_fd_pr__res_generic_m3_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002566 return [sky130::res_convert $parameters]
2567}
2568
2569#ifdef METAL5
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002570proc sky130::sky130_fd_pr__res_generic_m4_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002571 return [sky130::res_convert $parameters]
2572}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002573proc sky130::sky130_fd_pr__res_generic_m5_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002574 return [sky130::res_convert $parameters]
2575}
2576#endif (METAL5)
2577
2578#----------------------------------------------------------------
2579# resistor: Interactively specifies the fixed layout parameters
2580#----------------------------------------------------------------
2581
2582proc sky130::res_dialog {device parameters} {
2583 # Editable fields: w, l, t, nx, m, val
2584 # Checked fields:
2585
2586 magic::add_entry val "Value (ohms)" $parameters
2587 if {[dict exists $parameters snake]} {
2588 sky130::compute_ltot $parameters
2589 magic::add_message ltot "Total length (um)" $parameters
2590 }
2591 magic::add_entry l "Length (um)" $parameters
2592 magic::add_entry w "Width (um)" $parameters
2593 magic::add_entry nx "X Repeat" $parameters
2594 magic::add_entry m "Y Repeat" $parameters
2595 if {[dict exists $parameters endcov]} {
2596 magic::add_entry endcov "End contact coverage (%)" $parameters
2597 }
2598
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002599 if {[dict exists $parameters compatible]} {
2600 set sellist [dict get $parameters compatible]
2601 magic::add_selectlist gencell "Device type" $sellist $parameters $device
2602 }
2603
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002604 # magic::add_checkbox dummy "Add dummy" $parameters
2605
2606 if {[dict exists $parameters snake]} {
2607 magic::add_checkbox snake "Use snake geometry" $parameters
2608 }
2609 if {[dict exists $parameters roverlap]} {
2610 if {[dict exists $parameters endcov]} {
2611 magic::add_checkbox roverlap "Overlap at end contact" $parameters
2612 } else {
2613 magic::add_checkbox roverlap "Overlap at ends" $parameters
2614 }
2615 }
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002616 if {[dict exists $parameters guard]} {
2617 magic::add_checkbox guard "Add guard ring" $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002618
Tim Edwards8469aa62020-11-29 12:42:25 -05002619 if {[dict exists $parameters hv_guard]} {
2620 magic::add_checkbox hv_guard "High-voltage guard ring" $parameters
2621 }
Tim Edwardsf788cea2021-04-20 12:43:52 -04002622 if {[dict exists $parameters n_guard]} {
2623 magic::add_checkbox n_guard "N-well connected guard ring" $parameters
2624 }
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002625 if {[dict exists $parameters full_metal]} {
2626 magic::add_checkbox full_metal "Full metal guard ring" $parameters
2627 }
2628 if {[dict exists $parameters glc]} {
2629 magic::add_checkbox glc "Add left guard ring contact" $parameters
2630 }
2631 if {[dict exists $parameters grc]} {
2632 magic::add_checkbox grc "Add right guard ring contact" $parameters
2633 }
2634 if {[dict exists $parameters gtc]} {
2635 magic::add_checkbox gtc "Add top guard ring contact" $parameters
2636 }
2637 if {[dict exists $parameters gbc]} {
2638 magic::add_checkbox gbc "Add bottom guard ring contact" $parameters
2639 }
Tim Edwards0ee0f182020-11-21 16:15:07 -05002640
Tim Edwardsf788cea2021-04-20 12:43:52 -04002641
Tim Edwards0ee0f182020-11-21 16:15:07 -05002642 magic::add_entry viagb "Bottom guard ring via coverage \[+/-\](%)" $parameters
2643 magic::add_entry viagt "Top guard ring via coverage \[+/-\](%)" $parameters
2644 magic::add_entry viagr "Right guard ring via coverage \[+/-\](%)" $parameters
2645 magic::add_entry viagl "Left guard ring via coverage \[+/-\](%)" $parameters
2646 }
2647
2648 if {[dict exists $parameters vias]} {
2649 magic::add_checkbox vias "Add vias over contacts" $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002650 }
2651
2652 if {[dict exists $parameters snake]} {
2653 magic::add_dependency sky130::res_recalc $device sky130 l w val nx snake
2654 } else {
2655 magic::add_dependency sky130::res_recalc $device sky130 l w val nx
2656 }
2657}
2658
2659#----------------------------------------------------------------
2660
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002661proc sky130::sky130_fd_pr__res_iso_pw_dialog {parameters} {
2662 sky130::res_dialog sky130_fd_pr__res_iso_pw $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002663}
2664
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002665proc sky130::sky130_fd_pr__res_generic_po_dialog {parameters} {
2666 sky130::res_dialog sky130_fd_pr__res_generic_po $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002667}
2668
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002669proc sky130::sky130_fd_pr__res_high_po_0p35_dialog {parameters} {
2670 sky130::res_dialog sky130_fd_pr__res_high_po_0p35 $parameters
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002671}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002672proc sky130::sky130_fd_pr__res_high_po_0p69_dialog {parameters} {
2673 sky130::res_dialog sky130_fd_pr__res_high_po_0p69 $parameters
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002674}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002675proc sky130::sky130_fd_pr__res_high_po_1p41_dialog {parameters} {
2676 sky130::res_dialog sky130_fd_pr__res_high_po_1p41 $parameters
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002677}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002678proc sky130::sky130_fd_pr__res_high_po_2p85_dialog {parameters} {
2679 sky130::res_dialog sky130_fd_pr__res_high_po_2p85 $parameters
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002680}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002681proc sky130::sky130_fd_pr__res_high_po_5p73_dialog {parameters} {
2682 sky130::res_dialog sky130_fd_pr__res_high_po_5p73 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002683}
2684
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002685proc sky130::sky130_fd_pr__res_xhigh_po_0p35_dialog {parameters} {
2686 sky130::res_dialog sky130_fd_pr__res_xhigh_po_0p35 $parameters
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002687}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002688proc sky130::sky130_fd_pr__res_xhigh_po_0p69_dialog {parameters} {
2689 sky130::res_dialog sky130_fd_pr__res_xhigh_po_0p69 $parameters
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002690}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002691proc sky130::sky130_fd_pr__res_xhigh_po_1p41_dialog {parameters} {
2692 sky130::res_dialog sky130_fd_pr__res_xhigh_po_1p41 $parameters
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002693}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002694proc sky130::sky130_fd_pr__res_xhigh_po_2p85_dialog {parameters} {
2695 sky130::res_dialog sky130_fd_pr__res_xhigh_po_2p85 $parameters
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002696}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002697proc sky130::sky130_fd_pr__res_xhigh_po_5p73_dialog {parameters} {
2698 sky130::res_dialog sky130_fd_pr__res_xhigh_po_5p73 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002699}
2700
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002701proc sky130::sky130_fd_pr__res_generic_nd_dialog {parameters} {
2702 sky130::res_dialog sky130_fd_pr__res_generic_nd $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002703}
2704
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002705proc sky130::sky130_fd_pr__res_generic_pd_dialog {parameters} {
2706 sky130::res_dialog sky130_fd_pr__res_generic_pd $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002707}
2708
Tim Edwards0ee0f182020-11-21 16:15:07 -05002709proc sky130::sky130_fd_pr__res_generic_nd__hv_dialog {parameters} {
2710 sky130::res_dialog sky130_fd_pr__res_generic_nd__hv $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002711}
2712
Tim Edwards0ee0f182020-11-21 16:15:07 -05002713proc sky130::sky130_fd_pr__res_generic_pd__hv_dialog {parameters} {
2714 sky130::res_dialog sky130_fd_pr__res_generic_pd__hv $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002715}
2716
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002717proc sky130::sky130_fd_pr__res_generic_l1_dialog {parameters} {
2718 sky130::res_dialog sky130_fd_pr__res_generic_l1 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002719}
2720
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002721proc sky130::sky130_fd_pr__res_generic_m1_dialog {parameters} {
2722 sky130::res_dialog sky130_fd_pr__res_generic_m1 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002723}
2724
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002725proc sky130::sky130_fd_pr__res_generic_m2_dialog {parameters} {
2726 sky130::res_dialog sky130_fd_pr__res_generic_m2 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002727}
2728
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002729proc sky130::sky130_fd_pr__res_generic_m3_dialog {parameters} {
2730 sky130::res_dialog sky130_fd_pr__res_generic_m3 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002731}
2732
2733#ifdef METAL5
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002734proc sky130::sky130_fd_pr__res_generic_m4_dialog {parameters} {
2735 sky130::res_dialog sky130_fd_pr__res_generic_m4 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002736}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002737proc sky130::sky130_fd_pr__res_generic_m5_dialog {parameters} {
2738 sky130::res_dialog sky130_fd_pr__res_generic_m5 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002739}
2740#endif (METAL5)
2741
2742#----------------------------------------------------------------
2743# Resistor: Draw a single device in straight geometry
2744#----------------------------------------------------------------
2745
2746proc sky130::res_device {parameters} {
2747 # Epsilon for avoiding round-off errors
2748 set eps 0.0005
2749
2750 # Set local default values if they are not in parameters
2751 set endcov 0 ;# percent coverage of end contacts
2752 set roverlap 0 ;# overlap resistors at end contacts
2753 set well_res_overlap 0 ;# not a well resistor
2754 set end_contact_type "" ;# no contacts for metal resistors
2755 set end_overlap_cont 0 ;# additional end overlap on sides
Tim Edwards0ee0f182020-11-21 16:15:07 -05002756 set vias 0 ;# add vias over contacts
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002757 set res_idtype none
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002758
2759 # Set a local variable for each parameter (e.g., $l, $w, etc.)
2760 foreach key [dict keys $parameters] {
2761 set $key [dict get $parameters $key]
2762 }
2763
2764 if {![dict exists $parameters end_contact_size]} {
2765 set end_contact_size $contact_size
2766 }
2767
2768 # Draw the resistor and endcaps
2769 pushbox
2770 box size 0 0
2771 pushbox
2772 set hw [/ $w 2.0]
2773 set hl [/ $l 2.0]
2774 box grow n ${hl}um
2775 box grow s ${hl}um
2776 box grow e ${hw}um
2777 box grow w ${hw}um
2778
2779 pushbox
2780 box grow n ${res_to_endcont}um
2781 box grow s ${res_to_endcont}um
2782 if {$well_res_overlap > 0} {
2783 set well_extend [+ ${well_res_overlap} [/ ${end_contact_size} 2.0] ${end_surround}]
2784 box grow n ${well_extend}um
2785 box grow s ${well_extend}um
2786 paint ${well_res_type}
2787 } else {
2788 paint ${end_type}
2789 }
2790 set cext [sky130::getbox]
2791 popbox
2792
2793 if {$well_res_overlap > 0} {
2794 erase ${well_res_type}
2795 } else {
2796 erase ${end_type}
2797 }
2798 paint ${res_type}
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002799 if {"$res_idtype" != "none"} {
2800 box grow c 2
2801 paint ${res_idtype}
2802 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002803 popbox
2804
2805 # Reduce contact sizes by (end type) surround so that
2806 # the contact area edges match the device type width.
2807 # (Minimum dimensions will be enforced by the contact drawing routine)
2808 set epl [- ${w} [* ${end_surround} 2]] ;# end contact width
2809
2810 # Reduce end material size for well resistor types
2811 if {$well_res_overlap > 0} {
2812 set epl [- ${epl} [* ${well_res_overlap} 2]]
2813 }
2814
2815 # Reduce by coverage percentage unless overlapping at contacts
2816 if {(${roverlap} == 0) && (${endcov} > 0)} {
2817 set cpl [* ${epl} [/ ${endcov} 100.0]]
2818 } else {
2819 set cpl $epl
2820 }
2821
2822 # Ensure additional overlap of diffusion contact if required
2823 set dov [* ${end_overlap_cont} 2]
2824 if {[- ${epl} ${cpl}] < $dov} {
2825 set cpl [- ${epl} $dov] ;# additional end contact width
2826 }
2827
2828 set hepl [+ [/ ${epl} 2.0] ${end_surround}]
2829 set hesz [/ ${end_contact_size} 2.0]
2830
2831 # LV substrate diffusion types have a different surround requirement
2832 set lv_sub_types {"psd" "nsd"}
2833 if {[lsearch $lv_sub_types $end_type] < 0} {
2834 set hesz [+ ${hesz} ${end_surround}]
2835 }
2836
2837 # Top end material & contact
2838 pushbox
2839 box move n ${hl}um
2840 box move n ${res_to_endcont}um
2841
2842 pushbox
2843 box size 0 0
2844 box grow n ${hesz}um
2845 box grow s ${hesz}um
2846 box grow e ${hepl}um
2847 box grow w ${hepl}um
2848 paint ${end_type}
2849 set cext [sky130::unionbox $cext [sky130::getbox]]
2850 popbox
2851
2852 if {${end_contact_type} != ""} {
Tim Edwards0ee0f182020-11-21 16:15:07 -05002853 # Draw via over contact first
2854 if {$vias != 0} {
2855 pushbox
2856 set ch $res_to_endcont
2857 if {$ch < $via_size} {set ch $via_size}
2858 set cw $epl
2859 if {$cw < $via_size} {set cw $via_size}
2860 box grow n [/ $via_size 2]um
2861 box grow s [- $ch [/ $via_size 2]]um
2862 box grow w [/ $cw 2]um
2863 box grow e [/ $cw 2]um
2864 sky130::mcon_draw
2865 popbox
2866 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002867 set cext [sky130::unionbox $cext [sky130::draw_contact ${cpl} 0 \
2868 ${end_surround} ${metal_surround} ${end_contact_size} \
2869 ${end_type} ${end_contact_type} li horz]]
2870 }
2871 popbox
2872
2873 # Bottom end material & contact
2874 pushbox
2875 box move s ${hl}um
2876 box move s ${res_to_endcont}um
2877
2878 pushbox
2879 box size 0 0
2880 box grow n ${hesz}um
2881 box grow s ${hesz}um
2882 box grow e ${hepl}um
2883 box grow w ${hepl}um
2884 paint ${end_type}
2885 set cext [sky130::unionbox $cext [sky130::getbox]]
2886 popbox
2887
2888 if {${end_contact_type} != ""} {
Tim Edwards0ee0f182020-11-21 16:15:07 -05002889 # Draw via over contact first
2890 if {$vias != 0} {
2891 pushbox
2892 set ch $res_to_endcont
2893 if {$ch < $via_size} {set ch $via_size}
2894 set cw $epl
2895 if {$cw < $via_size} {set cw $via_size}
2896 box grow n [- $ch [/ $via_size 2]]um
2897 box grow s [/ $via_size 2]um
2898 box grow w [/ $cw 2]um
2899 box grow e [/ $cw 2]um
2900 sky130::mcon_draw
2901 popbox
2902 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002903 set cext [sky130::unionbox $cext [sky130::draw_contact ${cpl} 0 \
2904 ${end_surround} ${metal_surround} ${end_contact_size} \
2905 ${end_type} ${end_contact_type} li horz]]
2906 }
2907 popbox
2908
2909 popbox
2910 return $cext
2911}
2912
2913#----------------------------------------------------------------
2914# Resistor: Draw a single device in snake geometry
2915#----------------------------------------------------------------
2916
2917proc sky130::res_snake_device {nf parameters} {
2918 # nf is the number of fingers of the snake geometry
2919
2920 # Epsilon for avoiding round-off errors
2921 set eps 0.0005
2922
2923 # Set local default values if they are not in parameters
2924 set endcov 100 ;# percent coverage of end contacts
2925 set well_res_overlap 0 ;# not a well resistor
2926 set end_contact_type "" ;# no contacts for metal resistors
2927 set mask_clearance 0 ;# additional length to clear mask
2928
2929 # Set a local variable for each parameter (e.g., $l, $w, etc.)
2930 foreach key [dict keys $parameters] {
2931 set $key [dict get $parameters $key]
2932 }
2933
2934 if {![dict exists $parameters end_contact_size]} {
2935 set end_contact_size $contact_size
2936 }
2937
2938 # Compute half width and length
2939 set hw [/ $w 2.0]
2940 set hl [/ $l 2.0]
2941
2942 # Reduce contact sizes by (end type) surround so that
2943 # the contact area edges match the device type width.
2944 # (Minimum dimensions will be enforced by the contact drawing routine)
2945 set epl [- ${w} [* ${end_surround} 2]] ;# end contact width
2946
2947 # Reduce contact size for well resistor types
2948 if {$well_res_overlap > 0} {
2949 set epl [- ${epl} [* ${well_res_overlap} 2]]
2950 }
2951
2952 # Reduce contact part of end by coverage percentage
2953 if {${endcov} > 0} {
2954 set cpl [* ${epl} [/ ${endcov} 100.0]]
2955 } else {
2956 set cpl $epl
2957 }
2958
2959 set hepl [+ [/ ${epl} 2.0] ${end_surround}]
2960 set hesz [+ [/ ${end_contact_size} 2.0] ${end_surround}]
2961
2962 pushbox
2963 box size 0 0 ;# Position is taken from caller
2964
2965 # Front end contact (always bottom)
2966 pushbox
2967 box move s ${hl}um
2968 pushbox
2969 box move s ${mask_clearance}um
2970 box move s ${res_to_endcont}um
2971
2972 pushbox
2973 box size 0 0
2974 box grow n ${hesz}um
2975 box grow s ${hesz}um
2976 box grow e ${hepl}um
2977 box grow w ${hepl}um
2978 paint ${end_type}
2979 set cext [sky130::getbox]
2980 popbox
2981
2982 if {${end_contact_type} != ""} {
2983 set cext [sky130::draw_contact ${cpl} 0 \
2984 ${end_surround} ${metal_surround} ${end_contact_size} \
2985 ${end_type} ${end_contact_type} li horz]
2986 }
2987 popbox
2988
2989 # Draw portion between resistor end and contact.
2990 box grow e ${hw}um
2991 box grow w ${hw}um
2992 pushbox
2993 box grow s ${mask_clearance}um
2994 paint ${res_type}
2995 popbox
2996 box move s ${mask_clearance}um
2997 box grow s ${res_to_endcont}um
2998 if {$well_res_overlap > 0} {
2999 set well_extend [+ ${well_res_overlap} [/ ${end_contact_size} 2.0] ${end_surround}]
3000 box grow s ${well_extend}um
3001 paint ${well_res_type}
3002 } else {
3003 paint ${end_type}
3004 }
3005 set cext [sky130::unionbox $cext [sky130::getbox]]
3006 popbox
3007
3008 # Draw the resistor and endcaps
3009 pushbox
3010 box grow n ${hl}um
3011 box grow s ${hl}um
3012 box grow e ${hw}um
3013 box grow w ${hw}um
3014
3015 # Capture these extents in the bounding box in case both contacts
3016 # are on one side.
3017 set cext [sky130::unionbox $cext [sky130::getbox]]
3018
3019 set deltax [+ ${res_spacing} ${w}]
3020 set deltay [- ${l} ${w}]
3021 for {set i 0} {$i < [- $nf 1]} {incr i} {
3022 paint ${res_type}
3023 pushbox
3024 if {[% $i 2] == 0} {
3025 box move n ${deltay}um
3026 }
3027 box height ${w}um
3028 box width ${deltax}um
3029 paint ${res_type}
3030 popbox
3031 box move e ${deltax}um
3032 }
3033 paint ${res_type}
3034 # Capture these extents in the bounding box
3035 set cext [sky130::unionbox $cext [sky130::getbox]]
3036 popbox
3037
3038 # Move box to last finger
3039 set lastf [* [- $nf 1] $deltax]
3040 box move e ${lastf}um
3041
3042 # Back-end contact (top or bottom, depending if odd or even turns)
3043 pushbox
3044
3045 if {[% $nf 2] == 1} {
3046 set dir n
3047 } else {
3048 set dir s
3049 }
3050 box move $dir ${hl}um
3051 pushbox
3052 box move $dir ${mask_clearance}um
3053 box move $dir ${res_to_endcont}um
3054
3055 pushbox
3056 box size 0 0
3057 box grow n ${hesz}um
3058 box grow s ${hesz}um
3059 box grow e ${hepl}um
3060 box grow w ${hepl}um
3061 paint ${end_type}
3062 set cext [sky130::unionbox $cext [sky130::getbox]]
3063 popbox
3064
3065 if {${end_contact_type} != ""} {
3066 set cext [sky130::unionbox $cext [sky130::draw_contact ${cpl} 0 \
3067 ${end_surround} ${metal_surround} ${end_contact_size} \
3068 ${end_type} ${end_contact_type} li horz]]
3069 }
3070 popbox
3071 # Draw portion between resistor end and contact.
3072 box grow e ${hw}um
3073 box grow w ${hw}um
3074 pushbox
3075 box grow $dir ${mask_clearance}um
3076 paint ${res_type}
3077 popbox
3078 box move $dir ${mask_clearance}um
3079 box grow $dir ${res_to_endcont}um
3080
3081 if {$well_res_overlap > 0} {
3082 set well_extend [+ ${well_res_overlap} [/ ${end_contact_size} 2.0] ${end_surround}]
3083 box grow $dir ${well_extend}um
3084 paint ${well_res_type}
3085 } else {
3086 paint ${end_type}
3087 }
3088 popbox
3089
3090 popbox
3091 return $cext
3092}
3093
3094#----------------------------------------------------------------
3095# Resistor: Draw the tiled device
3096#----------------------------------------------------------------
3097
3098proc sky130::res_draw {parameters} {
3099 tech unlock *
3100 set savesnap [snap]
3101 snap internal
3102
3103 # Set defaults if they are not in parameters
3104 set snake 0 ;# some resistors don't allow snake geometry
3105 set roverlap 0 ;# overlap resistors at contacts
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003106 set guard 0 ;# draw a guard ring
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003107 set plus_diff_type nsd ;# guard ring diffusion type
3108 set overlap_compress 0 ;# special Y distance compression
3109 set well_res_overlap 0 ;# additional well extension behind contact
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003110 set res_diff_spacing 0 ;# spacing from resistor to diffusion
3111 set res_idtype none
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003112
3113 # Set a local variable for each parameter (e.g., $l, $w, etc.)
3114 foreach key [dict keys $parameters] {
3115 set $key [dict get $parameters $key]
3116 }
3117
3118 # For devices where inter-device space is smaller than device-to-guard ring
3119 if {![dict exists $parameters end_to_end_space]} {
3120 set end_to_end_space $end_spacing
3121 }
3122
3123 if {![dict exists $parameters end_contact_size]} {
3124 set end_contact_size $contact_size
3125 }
3126
3127 # Normalize distance units to microns
3128 set w [magic::spice2float $w]
3129 set l [magic::spice2float $l]
3130
3131 pushbox
3132 box values 0 0 0 0
3133
3134 # Determine the base device dimensions by drawing one device
3135 # while all layers are locked (nothing drawn). This allows the
3136 # base drawing routine to do complicated geometry without having
3137 # to duplicate it here with calculations.
3138
3139 tech lock *
3140 set nf $nx
3141 if {($snake == 1) && ($nx == 1)} {set snake 0}
3142 if {$snake == 1} {
3143 set bbox [sky130::res_snake_device $nf $parameters]
3144 set nx 1
3145 } else {
3146 set bbox [sky130::res_device $parameters]
3147 }
3148 # puts stdout "Diagnostic: Device bounding box e $bbox (um)"
3149 tech unlock *
3150
3151 set fw [- [lindex $bbox 2] [lindex $bbox 0]]
3152 set fh [- [lindex $bbox 3] [lindex $bbox 1]]
3153 set lw [+ [lindex $bbox 2] [lindex $bbox 0]]
3154 set lh [+ [lindex $bbox 3] [lindex $bbox 1]]
3155
3156 # Determine tile width and height (depends on overlap)
3157 # Snake resistors cannot overlap.
3158 # However, snake resistors with an odd number of fingers can
3159 # compress the space if overlap_compress is defined
3160
3161 if {($roverlap == 1) && ($snake == 1) && ([% $nf 2] == 1) && ($m > 1)} {
3162 set dy [- $fh $overlap_compress]
3163 } elseif {($roverlap == 0) || ($snake == 1)} {
3164 set dy [+ $fh $end_to_end_space]
3165 } else {
3166 # overlap poly
3167 set dy [- $fh [+ [* [+ $end_surround $well_res_overlap] 2.0] $end_contact_size]]
3168 }
3169 set dx [+ $fw $res_spacing]
3170
3171 # Determine core width and height
3172 set corex [+ [* [- $nx 1] $dx] $fw]
3173 set corey [+ [* [- $m 1] $dy] $fh]
3174 set corellx [/ [+ [- $corex $fw] $lw] 2.0]
3175 set corelly [/ [+ [- $corey $fh] $lh] 2.0]
3176
3177 set lv_sub_types {"psd" "nsd"}
3178 if {[lsearch $lv_sub_types $plus_diff_type] >= 0} {
3179 set guard_diff_surround 0
3180 } else {
3181 set guard_diff_surround ${diff_surround}
3182 }
3183
3184 if {$guard != 0} {
3185 # Calculate guard ring size (measured to contact center)
3186 set gx [+ $corex [* 2.0 [+ $res_diff_spacing $guard_diff_surround]] $contact_size]
3187 set gy [+ $corey [* 2.0 [+ $end_spacing $guard_diff_surround]] $contact_size]
3188
3189 # Draw the guard ring first, because well resistors are on the substrate plane
3190 sky130::guard_ring $gx $gy $parameters
3191 }
3192
3193 pushbox
3194 box move w ${corellx}um
3195 box move s ${corelly}um
3196 # puts "Device position at = [sky130::getbox]"
3197 for {set xp 0} {$xp < $nx} {incr xp} {
3198 pushbox
3199 for {set yp 0} {$yp < $m} {incr yp} {
3200 if {$snake == 1} {
3201 sky130::res_snake_device $nf $parameters
3202 } else {
3203 sky130::res_device $parameters
3204 }
3205 box move n ${dy}um
3206 }
3207 popbox
3208 box move e ${dx}um
3209 }
3210 popbox
3211 popbox
3212
3213 snap $savesnap
3214 tech revert
3215}
3216
3217#----------------------------------------------------------------
3218
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003219proc sky130::sky130_fd_pr__res_generic_po_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003220
3221 # Set a local variable for each rule in ruleset
3222 foreach key [dict keys $sky130::ruleset] {
3223 set $key [dict get $sky130::ruleset $key]
3224 }
3225
Tim Edwardsf788cea2021-04-20 12:43:52 -04003226 # Handle options related to guard ring type (high/low voltage, nwell/psub)
Tim Edwards8469aa62020-11-29 12:42:25 -05003227 if {[dict exists $parameters hv_guard]} {
Tim Edwardsf788cea2021-04-20 12:43:52 -04003228 set use_hv_guard [dict get $parameters hv_guard]
3229 } else {
3230 set use_hv_guard 0
3231 }
3232 if {[dict exists $parameters n_guard]} {
3233 set use_n_guard [dict get $parameters n_guard]
3234 } else {
3235 set use_n_guard 0
3236 }
3237
3238 if {$use_hv_guard == 1} {
3239 if {$use_n_guard == 1} {
Tim Edwards8469aa62020-11-29 12:42:25 -05003240 set gdifftype mvnsd
3241 set gdiffcont mvnsc
Tim Edwards8469aa62020-11-29 12:42:25 -05003242 } else {
Tim Edwardsf788cea2021-04-20 12:43:52 -04003243 set gdifftype mvpsd
3244 set gdiffcont mvpsc
3245 }
3246 set gsurround 0.33
3247 } else {
3248 if {$use_n_guard == 1} {
Tim Edwards8469aa62020-11-29 12:42:25 -05003249 set gdifftype nsd
3250 set gdiffcont nsc
Tim Edwardsf788cea2021-04-20 12:43:52 -04003251 } else {
3252 set gdifftype psd
3253 set gdiffcont psc
Tim Edwards8469aa62020-11-29 12:42:25 -05003254 }
Tim Edwardsf788cea2021-04-20 12:43:52 -04003255 set gsurround $sub_surround
3256 }
3257 if {$use_n_guard == 1} {
3258 set gsubtype nwell
3259 } else {
3260 set gsubtype psub
Tim Edwards8469aa62020-11-29 12:42:25 -05003261 }
3262
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003263 set newdict [dict create \
3264 res_type npres \
3265 end_type poly \
3266 end_contact_type pc \
Tim Edwards8469aa62020-11-29 12:42:25 -05003267 plus_diff_type $gdifftype \
3268 plus_contact_type $gdiffcont \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003269 sub_type $gsubtype \
Tim Edwards8469aa62020-11-29 12:42:25 -05003270 guard_sub_surround $gsurround \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003271 end_surround $poly_surround \
3272 end_spacing 0.48 \
3273 end_to_end_space 0.52 \
3274 res_to_endcont $res_to_cont \
3275 res_spacing $poly_spacing \
3276 res_diff_spacing 0.48 \
3277 mask_clearance 0.52 \
3278 overlap_compress 0.36 \
3279 ]
Tim Edwards8469aa62020-11-29 12:42:25 -05003280
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003281 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3282 return [sky130::res_draw $drawdict]
3283}
3284
3285#----------------------------------------------------------------
3286
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003287proc sky130::sky130_fd_pr__res_high_po_0p35_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003288
3289 # Set a local variable for each rule in ruleset
3290 foreach key [dict keys $sky130::ruleset] {
3291 set $key [dict get $sky130::ruleset $key]
3292 }
3293
Tim Edwardsf788cea2021-04-20 12:43:52 -04003294 # Handle options related to guard ring type (high/low voltage, nwell/psub)
3295 if {[dict exists $parameters hv_guard]} {
3296 set use_hv_guard [dict get $parameters hv_guard]
3297 } else {
3298 set use_hv_guard 0
3299 }
3300 if {[dict exists $parameters n_guard]} {
3301 set use_n_guard [dict get $parameters n_guard]
3302 } else {
3303 set use_n_guard 0
3304 }
3305
3306 if {$use_hv_guard == 1} {
3307 if {$use_n_guard == 1} {
3308 set gdifftype mvnsd
3309 set gdiffcont mvnsc
3310 } else {
3311 set gdifftype mvpsd
3312 set gdiffcont mvpsc
3313 }
3314 set gsurround 0.33
3315 } else {
3316 if {$use_n_guard == 1} {
3317 set gdifftype nsd
3318 set gdiffcont nsc
3319 } else {
3320 set gdifftype psd
3321 set gdiffcont psc
3322 }
3323 set gsurround $sub_surround
3324 }
3325 if {$use_n_guard == 1} {
3326 set gsubtype nwell
3327 set gresdiff_spacing 0.785
3328 set gresdiff_end 0.525
3329 } else {
3330 set gsubtype psub
3331 set gresdiff_spacing 0.48
3332 set gresdiff_end 0.48
3333 }
3334
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003335 set newdict [dict create \
3336 res_type ppres \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003337 res_idtype res0p35 \
3338 end_type xpc \
3339 end_contact_type xpc \
3340 end_contact_size 0 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003341 plus_diff_type $gdifftype \
3342 plus_contact_type $gdiffcont \
3343 sub_type $gsubtype \
3344 guard_sub_surround $gsurround \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003345 end_surround $poly_surround \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003346 end_spacing $gresdiff_end \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003347 end_to_end_space 0.52 \
3348 end_contact_size 0.19 \
3349 res_to_endcont 1.985 \
3350 res_spacing 1.24 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003351 res_diff_spacing $gresdiff_spacing \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003352 mask_clearance 0.52 \
3353 overlap_compress 0.36 \
3354 ]
3355 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3356 return [sky130::res_draw $drawdict]
3357}
3358
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003359proc sky130::sky130_fd_pr__res_high_po_0p69_draw {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003360
3361 # Set a local variable for each rule in ruleset
3362 foreach key [dict keys $sky130::ruleset] {
3363 set $key [dict get $sky130::ruleset $key]
3364 }
3365
Tim Edwardsf788cea2021-04-20 12:43:52 -04003366 # Handle options related to guard ring type (high/low voltage, nwell/psub)
3367 if {[dict exists $parameters hv_guard]} {
3368 set use_hv_guard [dict get $parameters hv_guard]
3369 } else {
3370 set use_hv_guard 0
3371 }
3372 if {[dict exists $parameters n_guard]} {
3373 set use_n_guard [dict get $parameters n_guard]
3374 } else {
3375 set use_n_guard 0
3376 }
3377
3378 if {$use_hv_guard == 1} {
3379 if {$use_n_guard == 1} {
3380 set gdifftype mvnsd
3381 set gdiffcont mvnsc
3382 } else {
3383 set gdifftype mvpsd
3384 set gdiffcont mvpsc
3385 }
3386 set gsurround 0.33
3387 } else {
3388 if {$use_n_guard == 1} {
3389 set gdifftype nsd
3390 set gdiffcont nsc
3391 } else {
3392 set gdifftype psd
3393 set gdiffcont psc
3394 }
3395 set gsurround $sub_surround
3396 }
3397 if {$use_n_guard == 1} {
3398 set gsubtype nwell
3399 set gresdiff_spacing 0.615
3400 set gresdiff_end 0.525
3401 } else {
3402 set gsubtype psub
3403 set gresdiff_spacing 0.48
3404 set gresdiff_end 0.48
3405 }
3406
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003407 set newdict [dict create \
3408 res_type ppres \
3409 res_idtype res0p69 \
3410 end_type xpc \
3411 end_contact_type xpc \
3412 end_contact_size 0 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003413 plus_diff_type $gdifftype \
3414 plus_contact_type $gdiffcont \
3415 sub_type $gsubtype \
3416 guard_sub_surround $gsurround \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003417 end_surround $poly_surround \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003418 end_spacing $gresdiff_end \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003419 end_to_end_space 0.52 \
3420 end_contact_size 0.19 \
3421 res_to_endcont 1.985 \
3422 res_spacing 1.24 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003423 res_diff_spacing $gresdiff_spacing \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003424 mask_clearance 0.52 \
3425 overlap_compress 0.36 \
3426 ]
3427 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3428 return [sky130::res_draw $drawdict]
3429}
3430
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003431proc sky130::sky130_fd_pr__res_high_po_1p41_draw {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003432
3433 # Set a local variable for each rule in ruleset
3434 foreach key [dict keys $sky130::ruleset] {
3435 set $key [dict get $sky130::ruleset $key]
3436 }
3437
Tim Edwardsf788cea2021-04-20 12:43:52 -04003438 # Handle options related to guard ring type (high/low voltage, nwell/psub)
3439 if {[dict exists $parameters hv_guard]} {
3440 set use_hv_guard [dict get $parameters hv_guard]
3441 } else {
3442 set use_hv_guard 0
3443 }
3444 if {[dict exists $parameters n_guard]} {
3445 set use_n_guard [dict get $parameters n_guard]
3446 } else {
3447 set use_n_guard 0
3448 }
3449
3450 if {$use_hv_guard == 1} {
3451 if {$use_n_guard == 1} {
3452 set gdifftype mvnsd
3453 set gdiffcont mvnsc
3454 } else {
3455 set gdifftype mvpsd
3456 set gdiffcont mvpsc
3457 }
3458 set gsurround 0.33
3459 } else {
3460 if {$use_n_guard == 1} {
3461 set gdifftype nsd
3462 set gdiffcont nsc
3463 } else {
3464 set gdifftype psd
3465 set gdiffcont psc
3466 }
3467 set gsurround $sub_surround
3468 }
3469 if {$use_n_guard == 1} {
3470 set gsubtype nwell
3471 set gresdiff_spacing 0.525
3472 set gresdiff_end 0.525
3473 } else {
3474 set gsubtype psub
3475 set gresdiff_spacing 0.48
3476 set gresdiff_end 0.48
3477 }
3478
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003479 set newdict [dict create \
3480 res_type ppres \
3481 res_idtype res1p41 \
3482 end_type xpc \
3483 end_contact_type xpc \
3484 end_contact_size 0 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003485 plus_diff_type $gdifftype \
3486 plus_contact_type $gdiffcont \
3487 sub_type $gsubtype \
3488 guard_sub_surround $gsurround \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003489 end_surround $poly_surround \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003490 end_spacing $gresdiff_end \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003491 end_to_end_space 0.52 \
3492 end_contact_size 0.19 \
3493 res_to_endcont 1.985 \
3494 res_spacing 1.24 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003495 res_diff_spacing $gresdiff_spacing \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003496 mask_clearance 0.52 \
3497 overlap_compress 0.36 \
3498 ]
3499 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3500 return [sky130::res_draw $drawdict]
3501}
3502
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003503proc sky130::sky130_fd_pr__res_high_po_2p85_draw {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003504
3505 # Set a local variable for each rule in ruleset
3506 foreach key [dict keys $sky130::ruleset] {
3507 set $key [dict get $sky130::ruleset $key]
3508 }
3509
Tim Edwardsf788cea2021-04-20 12:43:52 -04003510 # Handle options related to guard ring type (high/low voltage, nwell/psub)
3511 if {[dict exists $parameters hv_guard]} {
3512 set use_hv_guard [dict get $parameters hv_guard]
3513 } else {
3514 set use_hv_guard 0
3515 }
3516 if {[dict exists $parameters n_guard]} {
3517 set use_n_guard [dict get $parameters n_guard]
3518 } else {
3519 set use_n_guard 0
3520 }
3521
3522 if {$use_hv_guard == 1} {
3523 if {$use_n_guard == 1} {
3524 set gdifftype mvnsd
3525 set gdiffcont mvnsc
3526 } else {
3527 set gdifftype mvpsd
3528 set gdiffcont mvpsc
3529 }
3530 set gsurround 0.33
3531 } else {
3532 if {$use_n_guard == 1} {
3533 set gdifftype nsd
3534 set gdiffcont nsc
3535 } else {
3536 set gdifftype psd
3537 set gdiffcont psc
3538 }
3539 set gsurround $sub_surround
3540 }
3541 if {$use_n_guard == 1} {
3542 set gsubtype nwell
3543 set gresdiff_spacing 0.525
3544 set gresdiff_end 0.525
3545 } else {
3546 set gsubtype psub
3547 set gresdiff_spacing 0.48
3548 set gresdiff_end 0.48
3549 }
3550
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003551 set newdict [dict create \
3552 res_type ppres \
3553 res_idtype res2p85 \
3554 end_type xpc \
3555 end_contact_type xpc \
3556 end_contact_size 0 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003557 plus_diff_type $gdifftype \
3558 plus_contact_type $gdiffcont \
3559 sub_type $gsubtype \
3560 guard_sub_surround $gsurround \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003561 end_surround $poly_surround \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003562 end_spacing $gresdiff_end \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003563 end_to_end_space 0.52 \
3564 end_contact_size 0.19 \
3565 res_to_endcont 1.985 \
3566 res_spacing 1.24 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003567 res_diff_spacing $gresdiff_spacing \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003568 mask_clearance 0.52 \
3569 overlap_compress 0.36 \
3570 ]
3571 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3572 return [sky130::res_draw $drawdict]
3573}
3574
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003575proc sky130::sky130_fd_pr__res_high_po_5p73_draw {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003576
3577 # Set a local variable for each rule in ruleset
3578 foreach key [dict keys $sky130::ruleset] {
3579 set $key [dict get $sky130::ruleset $key]
3580 }
3581
Tim Edwardsf788cea2021-04-20 12:43:52 -04003582 # Handle options related to guard ring type (high/low voltage, nwell/psub)
3583 if {[dict exists $parameters hv_guard]} {
3584 set use_hv_guard [dict get $parameters hv_guard]
3585 } else {
3586 set use_hv_guard 0
3587 }
3588 if {[dict exists $parameters n_guard]} {
3589 set use_n_guard [dict get $parameters n_guard]
3590 } else {
3591 set use_n_guard 0
3592 }
3593
3594 if {$use_hv_guard == 1} {
3595 if {$use_n_guard == 1} {
3596 set gdifftype mvnsd
3597 set gdiffcont mvnsc
3598 } else {
3599 set gdifftype mvpsd
3600 set gdiffcont mvpsc
3601 }
3602 set gsurround 0.33
3603 } else {
3604 if {$use_n_guard == 1} {
3605 set gdifftype nsd
3606 set gdiffcont nsc
3607 } else {
3608 set gdifftype psd
3609 set gdiffcont psc
3610 }
3611 set gsurround $sub_surround
3612 }
3613 if {$use_n_guard == 1} {
3614 set gsubtype nwell
3615 set gresdiff_spacing 0.525
3616 set gresdiff_end 0.525
3617 } else {
3618 set gsubtype psub
3619 set gresdiff_spacing 0.48
3620 set gresdiff_end 0.48
3621 }
3622
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003623 set newdict [dict create \
3624 res_type ppres \
3625 res_idtype res5p73 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003626 end_type xpc \
3627 end_contact_type xpc \
3628 end_contact_size 0 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003629 plus_diff_type $gdifftype \
3630 plus_contact_type $gdiffcont \
3631 sub_type $gsubtype \
3632 guard_sub_surround $gsurround \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003633 end_surround $poly_surround \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003634 end_spacing $gresdiff_end \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003635 end_to_end_space 0.52 \
3636 end_contact_size 0.19 \
3637 res_to_endcont 1.985 \
3638 res_spacing 1.24 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003639 res_diff_spacing $gresdiff_spacing \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003640 mask_clearance 0.52 \
3641 overlap_compress 0.36 \
3642 ]
3643 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3644 return [sky130::res_draw $drawdict]
3645}
3646
3647#----------------------------------------------------------------
3648
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003649proc sky130::sky130_fd_pr__res_xhigh_po_0p35_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003650
3651 # Set a local variable for each rule in ruleset
3652 foreach key [dict keys $sky130::ruleset] {
3653 set $key [dict get $sky130::ruleset $key]
3654 }
3655
Tim Edwardsf788cea2021-04-20 12:43:52 -04003656 # Handle options related to guard ring type (high/low voltage, nwell/psub)
3657 if {[dict exists $parameters hv_guard]} {
3658 set use_hv_guard [dict get $parameters hv_guard]
3659 } else {
3660 set use_hv_guard 0
3661 }
3662 if {[dict exists $parameters n_guard]} {
3663 set use_n_guard [dict get $parameters n_guard]
3664 } else {
3665 set use_n_guard 0
3666 }
3667
3668 if {$use_hv_guard == 1} {
3669 if {$use_n_guard == 1} {
3670 set gdifftype mvnsd
3671 set gdiffcont mvnsc
3672 } else {
3673 set gdifftype mvpsd
3674 set gdiffcont mvpsc
3675 }
3676 set gsurround 0.33
3677 } else {
3678 if {$use_n_guard == 1} {
3679 set gdifftype nsd
3680 set gdiffcont nsc
3681 } else {
3682 set gdifftype psd
3683 set gdiffcont psc
3684 }
3685 set gsurround $sub_surround
3686 }
3687 if {$use_n_guard == 1} {
3688 set gsubtype nwell
3689 set gresdiff_spacing 0.785
3690 set gresdiff_end 0.525
3691 } else {
3692 set gsubtype psub
3693 set gresdiff_spacing 0.48
3694 set gresdiff_end 0.48
3695 }
3696
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003697 set newdict [dict create \
3698 res_type xpres \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003699 res_idtype res0p35 \
3700 end_type xpc \
3701 end_contact_type xpc \
3702 end_contact_size 0 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003703 plus_diff_type $gdifftype \
3704 plus_contact_type $gdiffcont \
3705 sub_type $gsubtype \
3706 guard_sub_surround $gsurround \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003707 end_surround $poly_surround \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003708 end_spacing $gresdiff_end \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003709 end_to_end_space 0.52 \
3710 end_contact_size 0.19 \
3711 res_to_endcont 1.985 \
3712 res_spacing 1.24 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003713 res_diff_spacing $gresdiff_spacing \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003714 mask_clearance 0.52 \
3715 overlap_compress 0.36 \
3716 ]
3717 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3718 return [sky130::res_draw $drawdict]
3719}
3720
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003721proc sky130::sky130_fd_pr__res_xhigh_po_0p69_draw {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003722
3723 # Set a local variable for each rule in ruleset
3724 foreach key [dict keys $sky130::ruleset] {
3725 set $key [dict get $sky130::ruleset $key]
3726 }
3727
Tim Edwardsf788cea2021-04-20 12:43:52 -04003728 # Handle options related to guard ring type (high/low voltage, nwell/psub)
3729 if {[dict exists $parameters hv_guard]} {
3730 set use_hv_guard [dict get $parameters hv_guard]
3731 } else {
3732 set use_hv_guard 0
3733 }
3734 if {[dict exists $parameters n_guard]} {
3735 set use_n_guard [dict get $parameters n_guard]
3736 } else {
3737 set use_n_guard 0
3738 }
3739
3740 if {$use_hv_guard == 1} {
3741 if {$use_n_guard == 1} {
3742 set gdifftype mvnsd
3743 set gdiffcont mvnsc
3744 } else {
3745 set gdifftype mvpsd
3746 set gdiffcont mvpsc
3747 }
3748 set gsurround 0.33
3749 } else {
3750 if {$use_n_guard == 1} {
3751 set gdifftype nsd
3752 set gdiffcont nsc
3753 } else {
3754 set gdifftype psd
3755 set gdiffcont psc
3756 }
3757 set gsurround $sub_surround
3758 }
3759 if {$use_n_guard == 1} {
3760 set gsubtype nwell
3761 set gresdiff_spacing 0.615
3762 set gresdiff_end 0.525
3763 } else {
3764 set gsubtype psub
3765 set gresdiff_spacing 0.48
3766 set gresdiff_end 0.48
3767 }
3768
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003769 set newdict [dict create \
3770 res_type xpres \
3771 res_idtype res0p69 \
3772 end_type xpc \
3773 end_contact_type xpc \
3774 end_contact_size 0 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003775 plus_diff_type $gdifftype \
3776 plus_contact_type $gdiffcont \
3777 sub_type $gsubtype \
3778 guard_sub_surround $gsurround \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003779 end_surround $poly_surround \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003780 end_spacing $gresdiff_end \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003781 end_to_end_space 0.52 \
3782 end_contact_size 0.19 \
3783 res_to_endcont 1.985 \
3784 res_spacing 1.24 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003785 res_diff_spacing $gresdiff_spacing \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003786 mask_clearance 0.52 \
3787 overlap_compress 0.36 \
3788 ]
3789 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3790 return [sky130::res_draw $drawdict]
3791}
3792
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003793proc sky130::sky130_fd_pr__res_xhigh_po_1p41_draw {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003794
3795 # Set a local variable for each rule in ruleset
3796 foreach key [dict keys $sky130::ruleset] {
3797 set $key [dict get $sky130::ruleset $key]
3798 }
3799
Tim Edwardsf788cea2021-04-20 12:43:52 -04003800 # Handle options related to guard ring type (high/low voltage, nwell/psub)
3801 if {[dict exists $parameters hv_guard]} {
3802 set use_hv_guard [dict get $parameters hv_guard]
3803 } else {
3804 set use_hv_guard 0
3805 }
3806 if {[dict exists $parameters n_guard]} {
3807 set use_n_guard [dict get $parameters n_guard]
3808 } else {
3809 set use_n_guard 0
3810 }
3811
3812 if {$use_hv_guard == 1} {
3813 if {$use_n_guard == 1} {
3814 set gdifftype mvnsd
3815 set gdiffcont mvnsc
3816 } else {
3817 set gdifftype mvpsd
3818 set gdiffcont mvpsc
3819 }
3820 set gsurround 0.33
3821 } else {
3822 if {$use_n_guard == 1} {
3823 set gdifftype nsd
3824 set gdiffcont nsc
3825 } else {
3826 set gdifftype psd
3827 set gdiffcont psc
3828 }
3829 set gsurround $sub_surround
3830 }
3831 if {$use_n_guard == 1} {
3832 set gsubtype nwell
3833 set gresdiff_spacing 0.525
3834 set gresdiff_end 0.525
3835 } else {
3836 set gsubtype psub
3837 set gresdiff_spacing 0.48
3838 set gresdiff_end 0.48
3839 }
3840
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003841 set newdict [dict create \
3842 res_type xpres \
3843 res_idtype res1p41 \
3844 end_type xpc \
3845 end_contact_type xpc \
3846 end_contact_size 0 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003847 plus_diff_type $gdifftype \
3848 plus_contact_type $gdiffcont \
3849 sub_type $gsubtype \
3850 guard_sub_surround $gsurround \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003851 end_surround $poly_surround \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003852 end_spacing $gresdiff_end \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003853 end_to_end_space 0.52 \
3854 end_contact_size 0.19 \
3855 res_to_endcont 1.985 \
3856 res_spacing 1.24 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003857 res_diff_spacing $gresdiff_spacing \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003858 mask_clearance 0.52 \
3859 overlap_compress 0.36 \
3860 ]
3861 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3862 return [sky130::res_draw $drawdict]
3863}
3864
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003865proc sky130::sky130_fd_pr__res_xhigh_po_2p85_draw {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003866
3867 # Set a local variable for each rule in ruleset
3868 foreach key [dict keys $sky130::ruleset] {
3869 set $key [dict get $sky130::ruleset $key]
3870 }
3871
Tim Edwardsf788cea2021-04-20 12:43:52 -04003872 # Handle options related to guard ring type (high/low voltage, nwell/psub)
3873 if {[dict exists $parameters hv_guard]} {
3874 set use_hv_guard [dict get $parameters hv_guard]
3875 } else {
3876 set use_hv_guard 0
3877 }
3878 if {[dict exists $parameters n_guard]} {
3879 set use_n_guard [dict get $parameters n_guard]
3880 } else {
3881 set use_n_guard 0
3882 }
3883
3884 if {$use_hv_guard == 1} {
3885 if {$use_n_guard == 1} {
3886 set gdifftype mvnsd
3887 set gdiffcont mvnsc
3888 } else {
3889 set gdifftype mvpsd
3890 set gdiffcont mvpsc
3891 }
3892 set gsurround 0.33
3893 } else {
3894 if {$use_n_guard == 1} {
3895 set gdifftype nsd
3896 set gdiffcont nsc
3897 } else {
3898 set gdifftype psd
3899 set gdiffcont psc
3900 }
3901 set gsurround $sub_surround
3902 }
3903 if {$use_n_guard == 1} {
3904 set gsubtype nwell
3905 set gresdiff_spacing 0.525
3906 set gresdiff_end 0.525
3907 } else {
3908 set gsubtype psub
3909 set gresdiff_spacing 0.48
3910 set gresdiff_end 0.48
3911 }
3912
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003913 set newdict [dict create \
3914 res_type xpres \
3915 res_idtype res2p85 \
3916 end_type xpc \
3917 end_contact_type xpc \
3918 end_contact_size 0 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003919 plus_diff_type $gdifftype \
3920 plus_contact_type $gdiffcont \
3921 sub_type $gsubtype \
3922 guard_sub_surround $gsurround \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003923 end_surround $poly_surround \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003924 end_spacing $gresdiff_end \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003925 end_to_end_space 0.52 \
3926 end_contact_size 0.19 \
3927 res_to_endcont 1.985 \
3928 res_spacing 1.24 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003929 res_diff_spacing $gresdiff_spacing \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003930 mask_clearance 0.52 \
3931 overlap_compress 0.36 \
3932 ]
3933 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3934 return [sky130::res_draw $drawdict]
3935}
3936
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003937proc sky130::sky130_fd_pr__res_xhigh_po_5p73_draw {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003938
3939 # Set a local variable for each rule in ruleset
3940 foreach key [dict keys $sky130::ruleset] {
3941 set $key [dict get $sky130::ruleset $key]
3942 }
3943
Tim Edwardsf788cea2021-04-20 12:43:52 -04003944 # Handle options related to guard ring type (high/low voltage, nwell/psub)
3945 if {[dict exists $parameters hv_guard]} {
3946 set use_hv_guard [dict get $parameters hv_guard]
3947 } else {
3948 set use_hv_guard 0
3949 }
3950 if {[dict exists $parameters n_guard]} {
3951 set use_n_guard [dict get $parameters n_guard]
3952 } else {
3953 set use_n_guard 0
3954 }
3955
3956 if {$use_hv_guard == 1} {
3957 if {$use_n_guard == 1} {
3958 set gdifftype mvnsd
3959 set gdiffcont mvnsc
3960 } else {
3961 set gdifftype mvpsd
3962 set gdiffcont mvpsc
3963 }
3964 set gsurround 0.33
3965 } else {
3966 if {$use_n_guard == 1} {
3967 set gdifftype nsd
3968 set gdiffcont nsc
3969 } else {
3970 set gdifftype psd
3971 set gdiffcont psc
3972 }
3973 set gsurround $sub_surround
3974 }
3975 if {$use_n_guard == 1} {
3976 set gsubtype nwell
3977 set gresdiff_spacing 0.525
3978 set gresdiff_end 0.525
3979 } else {
3980 set gsubtype psub
3981 set gresdiff_spacing 0.48
3982 set gresdiff_end 0.48
3983 }
3984
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003985 set newdict [dict create \
3986 res_type xpres \
3987 res_idtype res5p73 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003988 end_type xpc \
3989 end_contact_type xpc \
3990 end_contact_size 0 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003991 plus_diff_type $gdifftype \
3992 plus_contact_type $gdiffcont \
3993 sub_type $gsubtype \
3994 guard_sub_surround $gsurround \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003995 end_surround $poly_surround \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003996 end_spacing $gresdiff_end \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003997 end_to_end_space 0.52 \
3998 end_contact_size 0.19 \
3999 res_to_endcont 1.985 \
4000 res_spacing 1.24 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04004001 res_diff_spacing $gresdiff_spacing \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004002 mask_clearance 0.52 \
4003 overlap_compress 0.36 \
4004 ]
4005 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4006 return [sky130::res_draw $drawdict]
4007}
4008
4009#----------------------------------------------------------------
4010
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004011proc sky130::sky130_fd_pr__res_generic_nd_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004012
4013 # Set a local variable for each rule in ruleset
4014 foreach key [dict keys $sky130::ruleset] {
4015 set $key [dict get $sky130::ruleset $key]
4016 }
4017
4018 set newdict [dict create \
4019 res_type rdn \
4020 end_type ndiff \
4021 end_contact_type ndc \
4022 plus_diff_type psd \
4023 plus_contact_type psc \
4024 sub_type psub \
4025 end_surround $diff_surround \
4026 end_spacing 0.44 \
4027 res_to_endcont 0.37 \
4028 res_spacing 0.30 \
4029 res_diff_spacing 0.44 \
4030 mask_clearance 0.22 \
4031 overlap_compress 0.36 \
4032 ]
4033 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4034 return [sky130::res_draw $drawdict]
4035}
4036
4037#----------------------------------------------------------------
4038
Tim Edwards0ee0f182020-11-21 16:15:07 -05004039proc sky130::sky130_fd_pr__res_generic_nd__hv_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004040
4041 # Set a local variable for each rule in ruleset
4042 foreach key [dict keys $sky130::ruleset] {
4043 set $key [dict get $sky130::ruleset $key]
4044 }
4045
4046 set newdict [dict create \
4047 res_type mvrdn \
4048 end_type mvndiff \
4049 end_contact_type mvndc \
4050 plus_diff_type mvpsd \
4051 plus_contact_type mvpsc \
4052 sub_type psub \
4053 end_surround $diff_surround \
4054 end_spacing 0.44 \
4055 res_to_endcont 0.37 \
4056 res_spacing 0.30 \
4057 res_diff_spacing 0.44 \
4058 mask_clearance 0.22 \
4059 overlap_compress 0.36 \
4060 ]
4061 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4062 return [sky130::res_draw $drawdict]
4063}
4064
4065#----------------------------------------------------------------
4066
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004067proc sky130::sky130_fd_pr__res_generic_pd_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004068
4069 # Set a local variable for each rule in ruleset
4070 foreach key [dict keys $sky130::ruleset] {
4071 set $key [dict get $sky130::ruleset $key]
4072 }
4073
4074 set newdict [dict create \
4075 res_type rdp \
4076 end_type pdiff \
4077 end_contact_type pdc \
4078 plus_diff_type nsd \
4079 plus_contact_type nsc \
4080 sub_type nwell \
4081 end_surround $diff_surround \
4082 end_spacing 0.44 \
4083 res_to_endcont 0.37 \
4084 res_spacing $diff_spacing \
4085 res_diff_spacing 0.44 \
4086 mask_clearance 0.22 \
4087 overlap_compress 0.36 \
4088 ]
4089 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4090 return [sky130::res_draw $drawdict]
4091}
4092
4093#----------------------------------------------------------------
4094
Tim Edwards0ee0f182020-11-21 16:15:07 -05004095proc sky130::sky130_fd_pr__res_generic_pd__hv_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004096
4097 # Set a local variable for each rule in ruleset
4098 foreach key [dict keys $sky130::ruleset] {
4099 set $key [dict get $sky130::ruleset $key]
4100 }
4101
4102 set newdict [dict create \
4103 res_type mvrdp \
4104 end_type mvpdiff \
4105 end_contact_type mvpdc \
4106 plus_diff_type mvnsd \
4107 plus_contact_type mvnsc \
4108 sub_type nwell \
4109 end_surround $diff_surround \
4110 guard_sub_surround 0.33 \
4111 end_spacing 0.44 \
4112 res_to_endcont 0.37 \
4113 res_spacing 0.30 \
4114 res_diff_spacing 0.44 \
4115 mask_clearance 0.22 \
4116 overlap_compress 0.36 \
4117 ]
4118 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4119 return [sky130::res_draw $drawdict]
4120}
4121
4122#----------------------------------------------------------------
4123
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004124proc sky130::sky130_fd_pr__res_iso_pw_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004125
4126 # Set a local variable for each rule in ruleset
4127 foreach key [dict keys $sky130::ruleset] {
4128 set $key [dict get $sky130::ruleset $key]
4129 }
4130
4131 set newdict [dict create \
4132 well_res_type pwell \
4133 res_type rpw \
4134 end_type psd \
4135 end_contact_type psc \
4136 plus_diff_type nsd \
4137 plus_contact_type nsc \
4138 sub_type dnwell \
4139 sub_surround 0.23 \
4140 guard_sub_type nwell \
4141 guard_sub_surround 0.63 \
4142 end_surround $diff_surround \
4143 end_spacing 0.63 \
4144 end_to_end_space 1.15 \
4145 end_overlap_cont 0.06 \
4146 end_contact_size 0.53 \
4147 overlap_compress -0.17 \
4148 res_to_endcont 0.265 \
4149 res_spacing 1.4 \
4150 res_diff_spacing 0.63 \
4151 well_res_overlap 0.2 \
4152 ]
4153 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4154 return [sky130::res_draw $drawdict]
4155}
4156
4157#----------------------------------------------------------------
4158
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004159proc sky130::sky130_fd_pr__res_generic_l1_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004160
4161 # Set a local variable for each rule in ruleset
4162 foreach key [dict keys $sky130::ruleset] {
4163 set $key [dict get $sky130::ruleset $key]
4164 }
4165
4166 set newdict [dict create \
4167 guard 0 \
4168 res_type rli \
4169 end_type li \
4170 end_surround 0.0 \
4171 end_spacing 0.0 \
4172 res_to_endcont 0.2 \
4173 end_to_end_space 0.23 \
4174 res_spacing $metal_spacing \
4175 ]
4176 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4177 return [sky130::res_draw $drawdict]
4178}
4179
4180#----------------------------------------------------------------
4181
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004182proc sky130::sky130_fd_pr__res_generic_m1_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004183
4184 # Set a local variable for each rule in ruleset
4185 foreach key [dict keys $sky130::ruleset] {
4186 set $key [dict get $sky130::ruleset $key]
4187 }
4188
4189 set newdict [dict create \
4190 guard 0 \
4191 res_type rm1 \
4192 end_type m1 \
4193 end_surround 0.0 \
4194 end_spacing 0.0 \
4195 end_to_end_space 0.28 \
4196 res_to_endcont 0.2 \
4197 res_spacing $mmetal_spacing \
4198 ]
4199 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4200 return [sky130::res_draw $drawdict]
4201}
4202
4203#----------------------------------------------------------------
4204
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004205proc sky130::sky130_fd_pr__res_generic_m2_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004206
4207 # Set a local variable for each rule in ruleset
4208 foreach key [dict keys $sky130::ruleset] {
4209 set $key [dict get $sky130::ruleset $key]
4210 }
4211
4212 set newdict [dict create \
4213 guard 0 \
4214 res_type rm2 \
4215 end_type m2 \
4216 end_surround 0.0 \
4217 end_spacing 0.0 \
4218 end_to_end_space 0.28 \
4219 res_to_endcont 0.2 \
4220 res_spacing $mmetal_spacing \
4221 ]
4222 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4223 return [sky130::res_draw $drawdict]
4224}
4225
4226#----------------------------------------------------------------
4227
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004228proc sky130::sky130_fd_pr__res_generic_m3_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004229
4230 # Set a local variable for each rule in ruleset
4231 foreach key [dict keys $sky130::ruleset] {
4232 set $key [dict get $sky130::ruleset $key]
4233 }
4234
4235 set newdict [dict create \
4236 guard 0 \
4237 res_type rm3 \
4238 end_type m3 \
4239 end_surround 0.0 \
4240 end_spacing 0.0 \
4241 end_to_end_space 0.28 \
4242 res_to_endcont 0.2 \
4243 res_spacing $mmetal_spacing \
4244 ]
4245 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4246 return [sky130::res_draw $drawdict]
4247}
4248
4249#----------------------------------------------------------------
4250
4251#ifdef METAL5
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004252proc sky130::sky130_fd_pr__res_generic_m4_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004253
4254 # Set a local variable for each rule in ruleset
4255 foreach key [dict keys $sky130::ruleset] {
4256 set $key [dict get $sky130::ruleset $key]
4257 }
4258
4259 set newdict [dict create \
4260 guard 0 \
4261 res_type rm4 \
4262 end_type m4 \
4263 end_surround 0.0 \
4264 end_spacing 0.0 \
4265 end_to_end_space 0.28 \
4266 res_to_endcont 0.2 \
4267 res_spacing $mmetal_spacing \
4268 ]
4269 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4270 return [sky130::res_draw $drawdict]
4271}
4272
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004273proc sky130::sky130_fd_pr__res_generic_m5_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004274 # Set a local variable for each rule in ruleset
4275 foreach key [dict keys $sky130::ruleset] {
4276 set $key [dict get $sky130::ruleset $key]
4277 }
4278
4279 set newdict [dict create \
4280 guard 0 \
4281 res_type rm5 \
4282 end_type m5 \
4283 end_surround 0.0 \
4284 end_spacing 0.0 \
4285 end_to_end_space 1.6 \
4286 res_to_endcont 0.2 \
4287 res_spacing $mmetal_spacing \
4288 ]
4289 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4290 return [sky130::res_draw $drawdict]
4291}
4292#endif (METAL5)
4293
4294#----------------------------------------------------------------
4295# Resistor total length computation
4296#----------------------------------------------------------------
4297
4298proc sky130::compute_ltot {parameters} {
4299 # In case snake not defined
4300 set snake 0
4301 set caplen 0
4302
4303 foreach key [dict keys $parameters] {
4304 set $key [dict get $parameters $key]
4305 }
4306
4307 set l [magic::spice2float $l]
4308 set l [magic::3digitpastdecimal $l]
4309
4310 # Compute total length. Use catch to prevent error in batch/scripted mode.
4311 if {$snake == 1} {
4312 catch {set magic::ltot_val [expr ($caplen * ($nx - 1)) + ($l * $nx) + ($nx - 1)]}
4313 } else {
4314 catch {set magic::ltot_val $l}
4315 }
4316}
4317
4318#----------------------------------------------------------------
4319# resistor: Check device parameters for out-of-bounds values
4320#----------------------------------------------------------------
4321
4322proc sky130::res_check {device parameters} {
4323
4324 # Set a local variable for each parameter (e.g., $l, $w, etc.)
4325 set snake 0
Tim Edwards0ee0f182020-11-21 16:15:07 -05004326 set guard 0
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004327 set sterm 0.0
4328 set caplen 0
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004329 set wmax 0
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004330
4331 foreach key [dict keys $parameters] {
4332 set $key [dict get $parameters $key]
4333 }
4334
4335 # Normalize distance units to microns
4336 set w [magic::spice2float $w]
4337 set w [magic::3digitpastdecimal $w]
4338 set l [magic::spice2float $l]
4339 set l [magic::3digitpastdecimal $l]
4340
4341 set val [magic::spice2float $val]
4342 set rho [magic::spice2float $rho]
4343
4344 # nf, m must be integer
4345 if {![string is int $nx]} {
4346 puts stderr "X repeat must be an integer!"
4347 dict set parameters nx 1
4348 }
4349 if {![string is int $m]} {
4350 puts stderr "Y repeat must be an integer!"
4351 dict set parameters m 1
4352 }
4353
4354 # Width always needs to be specified
4355 if {$w < $wmin} {
4356 puts stderr "Resistor width must be >= $wmin um"
4357 dict set parameters w $wmin
4358 }
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004359 if {$wmax > 0 && $w > $wmax} {
4360 puts stderr "Resistor width must be <= $wmax um"
4361 dict set parameters w $wmax
4362 }
4363
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004364 # Val and W specified - no L
4365 if {$l == 0} {
4366 set l [expr ($w - $dw) * $val / $rho]
4367 set l [magic::3digitpastdecimal $l]
4368 set stringval [magic::float2spice $val]
4369 dict set parameters l [magic::float2spice [expr $l * 1e-6]]
4370 # L and W specified - ignore Val if specified
4371 } else {
4372 if {$snake == 0} {
4373 set val [expr (2 * $term + $l * $rho) / ($w - $dw)]
4374 } else {
4375 set val [expr $rho * ($nx - 1) + ((2 * ($term + $sterm)) \
4376 + ($rho * $l * $nx) + ($rho * $caplen * ($nx - 1))) \
4377 / ($w - $dw)]
4378 }
4379 set val [magic::float2spice $val]
4380 dict set parameters val $val
4381 }
4382 if {$l < $lmin} {
4383 puts stderr "Resistor length must be >= $lmin um"
4384 dict set parameters l $lmin
4385 }
4386 if {$nx < 1} {
4387 puts stderr "X repeat must be >= 1"
4388 dict set parameters nx 1
4389 }
4390 if {$m < 1} {
4391 puts stderr "Y repeat must be >= 1"
4392 dict set parameters m 1
4393 }
4394
4395 # Snake resistors cannot have width greater than length
4396 if {$snake == 1} {
4397 if {$w > $l} {
4398 puts stderr "Snake resistor width must be < length"
4399 dict set parameters w $l
4400 }
4401 }
4402
Tim Edwards0ee0f182020-11-21 16:15:07 -05004403 # Check via coverage for syntax
4404 if {$guard == 1} {
4405 if {[catch {expr abs($viagb)}]} {
4406 puts stderr "Guard ring bottom via coverage must be numeric!"
4407 dict set parameters viagb 0
4408 } elseif {[expr abs($viagb)] > 100} {
4409 puts stderr "Guard ring bottom via coverage can't be more than 100%"
4410 dict set parameters viagb 100
4411 }
4412 if {[catch {expr abs($viagt)}]} {
4413 puts stderr "Guard ring top via coverage must be numeric!"
4414 dict set parameters viagt 0
4415 } elseif {[expr abs($viagt)] > 100} {
4416 puts stderr "Guard ring top via coverage can't be more than 100%"
4417 dict set parameters viagt 100
4418 }
4419 if {[catch {expr abs($viagr)}]} {
4420 puts stderr "Guard ring right via coverage must be numeric!"
4421 dict set parameters viagr 0
4422 } elseif {[expr abs($viagr)] > 100} {
4423 puts stderr "Guard ring right via coverage can't be more than 100%"
4424 dict set parameters viagr 100
4425 }
4426 if {[catch {expr abs($viagl)}]} {
4427 puts stderr "Guard ring left via coverage must be numeric!"
4428 dict set parameters viagl 0
4429 } elseif {[expr abs($viagl)] > 100} {
4430 puts stderr "Guard ring left via coverage can't be more than 100%"
4431 dict set parameters viagl 100
4432 }
4433 }
4434
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004435 # Diffusion resistors must satisfy diffusion-to-tap spacing of 20um.
4436 # Therefore the maximum of guard ring width or height cannot exceed 40um.
4437 # If in violation, reduce counts first, as these are easiest to recover
4438 # by duplicating the device and overlapping the wells.
4439 if {$device == "rdn" || $device == "rdp"} {
4440 set origm $m
4441 set orignx $nx
4442 while true {
4443 set xext [expr ($w + 0.8) * $nx + 1.0]
4444 set yext [expr ($l + 1.7) * $m + 1.7]
4445 if {[expr min($xext, $yext)] > 40.0} {
4446 if {$yext > 40.0 && $m > 1} {
4447 incr m -1
4448 } elseif {$xext > 40.0 && $nx > 1} {
4449 incr nx -1
4450 } elseif {$yext > 40.0} {
4451 set l 36.6
4452 puts -nonewline stderr "Diffusion resistor length must be < 36.6 um"
4453 puts stderr " to avoid tap spacing violation."
4454 dict set parameters l $l
4455 } elseif {$xext > 40.0} {
4456 set w 38.2
4457 puts -nonewline stderr "Diffusion resistor width must be < 38.2 um"
4458 puts stderr " to avoid tap spacing violation."
4459 dict set parameters w $w
4460 }
4461 } else {
4462 break
4463 }
4464 }
4465 if {$m != $origm} {
4466 puts stderr "Y repeat reduced to prevent tap distance violation"
4467 dict set parameters m $m
4468 }
4469 if {$nx != $orignx} {
4470 puts stderr "X repeat reduced to prevent tap distance violation"
4471 dict set parameters nx $nx
4472 }
4473 }
4474 sky130::compute_ltot $parameters
4475 return $parameters
4476}
4477
4478#----------------------------------------------------------------
4479
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004480proc sky130::sky130_fd_pr__res_iso_pw_check {parameters} {
4481 return [sky130::res_check sky130_fd_pr__res_iso_pw $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004482}
4483
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004484proc sky130::sky130_fd_pr__res_generic_po_check {parameters} {
4485 return [sky130::res_check sky130_fd_pr__res_generic_po $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004486}
4487
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004488proc sky130::sky130_fd_pr__res_high_po_0p35_check {parameters} {
4489 return [sky130::res_check sky130_fd_pr__res_high_po_0p35 $parameters]
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004490}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004491proc sky130::sky130_fd_pr__res_high_po_0p69_check {parameters} {
4492 return [sky130::res_check sky130_fd_pr__res_high_po_0p69 $parameters]
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004493}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004494proc sky130::sky130_fd_pr__res_high_po_1p41_check {parameters} {
4495 return [sky130::res_check sky130_fd_pr__res_high_po_1p41 $parameters]
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004496}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004497proc sky130::sky130_fd_pr__res_high_po_2p85_check {parameters} {
4498 return [sky130::res_check sky130_fd_pr__res_high_po_2p85 $parameters]
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004499}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004500proc sky130::sky130_fd_pr__res_high_po_5p73_check {parameters} {
4501 return [sky130::res_check sky130_fd_pr__res_high_po_5p73 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004502}
4503
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004504proc sky130::sky130_fd_pr__res_xhigh_po_0p35_check {parameters} {
4505 return [sky130::res_check sky130_fd_pr__res_xhigh_po_0p35 $parameters]
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004506}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004507proc sky130::sky130_fd_pr__res_xhigh_po_0p69_check {parameters} {
4508 return [sky130::res_check sky130_fd_pr__res_xhigh_po_0p69 $parameters]
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004509}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004510proc sky130::sky130_fd_pr__res_xhigh_po_1p41_check {parameters} {
4511 return [sky130::res_check sky130_fd_pr__res_xhigh_po_1p41 $parameters]
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004512}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004513proc sky130::sky130_fd_pr__res_xhigh_po_2p85_check {parameters} {
4514 return [sky130::res_check sky130_fd_pr__res_xhigh_po_2p85 $parameters]
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004515}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004516proc sky130::sky130_fd_pr__res_xhigh_po_5p73_check {parameters} {
4517 return [sky130::res_check sky130_fd_pr__res_xhigh_po_5p73 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004518}
4519
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004520proc sky130::sky130_fd_pr__res_generic_nd_check {parameters} {
4521 return [sky130::res_check sky130_fd_pr__res_generic_nd $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004522}
4523
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004524proc sky130::sky130_fd_pr__res_generic_pd_check {parameters} {
4525 return [sky130::res_check sky130_fd_pr__res_generic_pd $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004526}
4527
Tim Edwards0ee0f182020-11-21 16:15:07 -05004528proc sky130::sky130_fd_pr__res_generic_nd__hv_check {parameters} {
4529 return [sky130::res_check sky130_fd_pr__res_generic_nd__hv $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004530}
4531
Tim Edwards0ee0f182020-11-21 16:15:07 -05004532proc sky130::sky130_fd_pr__res_generic_pd__hv_check {parameters} {
4533 return [sky130::res_check sky130_fd_pr__res_generic_pd__hv $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004534}
4535
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004536proc sky130::sky130_fd_pr__res_generic_l1_check {parameters} {
4537 return [sky130::res_check sky130_fd_pr__res_generic_l1 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004538}
4539
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004540proc sky130::sky130_fd_pr__res_generic_m1_check {parameters} {
4541 return [sky130::res_check sky130_fd_pr__res_generic_m1 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004542}
4543
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004544proc sky130::sky130_fd_pr__res_generic_m2_check {parameters} {
4545 return [sky130::res_check sky130_fd_pr__res_generic_m2 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004546}
4547
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004548proc sky130::sky130_fd_pr__res_generic_m3_check {parameters} {
4549 return [sky130::res_check sky130_fd_pr__res_generic_m3 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004550}
4551
4552#ifdef METAL5
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004553proc sky130::sky130_fd_pr__res_generic_m4_check {parameters} {
4554 return [sky130::res_check sky130_fd_pr__res_generic_m4 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004555}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004556proc sky130::sky130_fd_pr__res_generic_m5_check {parameters} {
4557 return [sky130::res_check sky130_fd_pr__res_generic_m5 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004558}
4559#endif (METAL5)
4560
4561#----------------------------------------------------------------
4562# MOS defaults:
4563#----------------------------------------------------------------
4564# w = Gate width
4565# l = Gate length
4566# m = Multiplier
4567# nf = Number of fingers
4568# diffcov = Diffusion contact coverage
4569# polycov = Poly contact coverage
4570# topc = Top gate contact
4571# botc = Bottom gate contact
4572# guard = Guard ring
4573#
4574# (not user-editable)
4575#
4576# lmin = Gate minimum length
4577# wmin = Gate minimum width
4578#----------------------------------------------------------------
4579
4580#----------------------------------------------------------------
4581# pmos: Specify all user-editable default values and those
4582# needed by mos_check
4583#----------------------------------------------------------------
4584
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004585proc sky130::sky130_fd_pr__pfet_01v8_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004586 return {w 0.42 l 0.15 m 1 nf 1 diffcov 100 polycov 100 \
4587 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4588 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.15 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004589 compatible {sky130_fd_pr__pfet_01v8 \
4590 sky130_fd_pr__pfet_01v8_lvt sky130_fd_pr__pfet_01v8_hvt \
Tim Edwards3e4e81e2021-02-13 17:13:05 -05004591 sky130_fd_pr__pfet_g5v0d10v5} full_metal 1 \
4592 viasrc 100 viadrn 100 viagate 100 \
4593 viagb 0 viagr 0 viagl 0 viagt 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004594}
4595
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004596proc sky130::sky130_fd_pr__pfet_01v8_lvt_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004597 return {w 0.42 l 0.35 m 1 nf 1 diffcov 100 polycov 100 \
4598 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4599 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.35 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004600 compatible {sky130_fd_pr__pfet_01v8 \
4601 sky130_fd_pr__pfet_01v8_lvt sky130_fd_pr__pfet_01v8_hvt \
Tim Edwards3e4e81e2021-02-13 17:13:05 -05004602 sky130_fd_pr__pfet_g5v0d10v5} full_metal 1 \
4603 viasrc 100 viadrn 100 viagate 100 \
4604 viagb 0 viagr 0 viagl 0 viagt 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004605}
4606
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004607proc sky130::sky130_fd_pr__pfet_01v8_hvt_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004608 return {w 0.42 l 0.15 m 1 nf 1 diffcov 100 polycov 100 \
4609 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4610 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.15 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004611 compatible {sky130_fd_pr__pfet_01v8 \
4612 sky130_fd_pr__pfet_01v8_lvt sky130_fd_pr__pfet_01v8_hvt \
Tim Edwards3e4e81e2021-02-13 17:13:05 -05004613 sky130_fd_pr__pfet_g5v0d10v5} full_metal 1 \
4614 viasrc 100 viadrn 100 viagate 100 \
4615 viagb 0 viagr 0 viagl 0 viagt 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004616}
4617
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004618proc sky130::sky130_fd_pr__pfet_g5v0d10v5_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004619 return {w 0.42 l 0.50 m 1 nf 1 diffcov 100 polycov 100 \
4620 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4621 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.50 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004622 compatible {sky130_fd_pr__pfet_01v8 \
4623 sky130_fd_pr__pfet_01v8_lvt sky130_fd_pr__pfet_01v8_hvt \
Tim Edwards3e4e81e2021-02-13 17:13:05 -05004624 sky130_fd_pr__pfet_g5v0d10v5} full_metal 1 \
4625 viasrc 100 viadrn 100 viagate 100 \
4626 viagb 0 viagr 0 viagl 0 viagt 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004627}
4628
4629#----------------------------------------------------------------
4630# nmos: Specify all user-editable default values and those
4631# needed by mos_check
4632#----------------------------------------------------------------
4633
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004634proc sky130::sky130_fd_pr__nfet_01v8_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004635 return {w 0.420 l 0.150 m 1 nf 1 diffcov 100 polycov 100 \
4636 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4637 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.15 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004638 compatible {sky130_fd_pr__nfet_01v8 sky130_fd_pr__nfet_01v8_lvt \
4639 sky130_fd_bs_flash__special_sonosfet_star \
Tim Edwardsee445932021-03-31 12:32:04 -04004640 sky130_fd_pr__nfet_g5v0d10v5 sky130_fd_pr__nfet_05v0_nvt \
4641 sky130_fd_pr__nfet_03v3_nvt} \
Tim Edwards0ee0f182020-11-21 16:15:07 -05004642 full_metal 1 viasrc 100 viadrn 100 viagate 100 \
4643 viagb 0 viagr 0 viagl 0 viagt 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004644}
4645
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004646proc sky130::sky130_fd_pr__nfet_01v8_lvt_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004647 return {w 0.420 l 0.150 m 1 nf 1 diffcov 100 polycov 100 \
4648 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4649 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.15 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004650 compatible {sky130_fd_pr__nfet_01v8 sky130_fd_pr__nfet_01v8_lvt \
4651 sky130_fd_bs_flash__special_sonosfet_star \
Tim Edwardsee445932021-03-31 12:32:04 -04004652 sky130_fd_pr__nfet_g5v0d10v5 sky130_fd_pr__nfet_05v0_nvt \
4653 sky130_fd_pr__nfet_03v3_nvt} \
Tim Edwards0ee0f182020-11-21 16:15:07 -05004654 full_metal 1 viasrc 100 viadrn 100 viagate 100 \
4655 viagb 0 viagr 0 viagl 0 viagt 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004656}
4657
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004658proc sky130::sky130_fd_bs_flash__special_sonosfet_star_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004659 return {w 0.420 l 0.150 m 1 nf 1 diffcov 100 polycov 100 \
4660 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4661 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.15 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004662 compatible {sky130_fd_pr__nfet_01v8 sky130_fd_pr__nfet_01v8_lvt \
4663 sky130_fd_bs_flash__special_sonosfet_star \
Tim Edwardsee445932021-03-31 12:32:04 -04004664 sky130_fd_pr__nfet_g5v0d10v5 sky130_fd_pr__nfet_05v0_nvt \
4665 sky130_fd_pr__nfet_03v3_nvt} \
Tim Edwards0ee0f182020-11-21 16:15:07 -05004666 full_metal 1 viasrc 100 viadrn 100 viagate 100 \
4667 viagb 0 viagr 0 viagl 0 viagt 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004668}
4669
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004670proc sky130::sky130_fd_pr__nfet_g5v0d10v5_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004671 return {w 0.42 l 0.50 m 1 nf 1 diffcov 100 polycov 100 \
4672 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4673 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.50 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004674 compatible {sky130_fd_pr__nfet_01v8 sky130_fd_pr__nfet_01v8_lvt \
4675 sky130_fd_bs_flash__special_sonosfet_star \
Tim Edwardsee445932021-03-31 12:32:04 -04004676 sky130_fd_pr__nfet_g5v0d10v5 sky130_fd_pr__nfet_05v0_nvt \
4677 sky130_fd_pr__nfet_03v3_nvt} \
Tim Edwards0ee0f182020-11-21 16:15:07 -05004678 full_metal 1 viasrc 100 viadrn 100 viagate 100 \
4679 viagb 0 viagr 0 viagl 0 viagt 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004680}
4681
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004682proc sky130::sky130_fd_pr__nfet_05v0_nvt_defaults {} {
Tim Edwardsee445932021-03-31 12:32:04 -04004683 return {w 0.42 l 0.90 m 1 nf 1 diffcov 100 polycov 100 \
4684 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4685 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.90 wmin 0.42 \
4686 compatible {sky130_fd_pr__nfet_01v8 sky130_fd_pr__nfet_01v8_lvt \
4687 sky130_fd_bs_flash__special_sonosfet_star \
4688 sky130_fd_pr__nfet_g5v0d10v5 sky130_fd_pr__nfet_05v0_nvt \
4689 sky130_fd_pr__nfet_03v3_nvt} \
4690 full_metal 1 viasrc 100 viadrn 100 viagate 100 \
4691 viagb 0 viagr 0 viagl 0 viagt 0}
4692}
4693
4694proc sky130::sky130_fd_pr__nfet_03v3_nvt_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004695 return {w 0.42 l 0.50 m 1 nf 1 diffcov 100 polycov 100 \
4696 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4697 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.50 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004698 compatible {sky130_fd_pr__nfet_01v8 sky130_fd_pr__nfet_01v8_lvt \
4699 sky130_fd_bs_flash__special_sonosfet_star \
Tim Edwardsee445932021-03-31 12:32:04 -04004700 sky130_fd_pr__nfet_g5v0d10v5 sky130_fd_pr__nfet_05v0_nvt \
4701 sky130_fd_pr__nfet_03v3_nvt} \
Tim Edwards0ee0f182020-11-21 16:15:07 -05004702 full_metal 1 viasrc 100 viadrn 100 viagate 100 \
4703 viagb 0 viagr 0 viagl 0 viagt 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004704}
4705
4706#----------------------------------------------------------------
4707# mos varactor: Specify all user-editable default values and those
4708# needed by mosvc_check
4709#----------------------------------------------------------------
4710
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004711proc sky130::sky130_fd_pr__cap_var_lvt_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004712 return {w 1.0 l 0.18 m 1 nf 1 diffcov 100 polycov 100 \
4713 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4714 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.18 wmin 1.0 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004715 compatible {sky130_fd_pr__cap_var_lvt \
Tim Edwards0ee0f182020-11-21 16:15:07 -05004716 sky130_fd_pr__cap_var_hvt sky130_fd_pr__cap_var} \
4717 full_metal 1 viasrc 100 viadrn 100 viagate 100 \
4718 viagb 0 viagr 0 viagl 0 viagt 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004719}
4720
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004721proc sky130::sky130_fd_pr__cap_var_hvt_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004722 return {w 1.0 l 0.18 m 1 nf 1 diffcov 100 polycov 100 \
4723 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4724 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.18 wmin 1.0 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004725 compatible {sky130_fd_pr__cap_var_lvt \
Tim Edwards0ee0f182020-11-21 16:15:07 -05004726 sky130_fd_pr__cap_var_hvt sky130_fd_pr__cap_var} \
4727 full_metal 1 viasrc 100 viadrn 100 viagate 100 \
4728 viagb 0 viagr 0 viagl 0 viagt 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004729}
4730
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004731proc sky130::sky130_fd_pr__cap_var_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004732 return {w 1.0 l 0.50 m 1 nf 1 diffcov 100 polycov 100 \
4733 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4734 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.50 wmin 1.0 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004735 compatible {sky130_fd_pr__cap_var_lvt \
Tim Edwards0ee0f182020-11-21 16:15:07 -05004736 sky130_fd_pr__cap_var_hvt sky130_fd_pr__cap_var} \
4737 full_metal 1 viasrc 100 viadrn 100 viagate 100 \
4738 viagb 0 viagr 0 viagl 0 viagt 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004739}
4740
4741#----------------------------------------------------------------
4742# mos: Conversion from SPICE netlist parameters to toolkit
4743#----------------------------------------------------------------
4744
4745proc sky130::mos_convert {parameters} {
4746 set pdkparams [dict create]
4747 dict for {key value} $parameters {
4748 switch -nocase $key {
4749 l -
4750 w {
4751 # Length and width are converted to units of microns
4752 set value [magic::spice2float $value]
4753 # set value [expr $value * 1e6]
4754 set value [magic::3digitpastdecimal $value]
4755 dict set pdkparams [string tolower $key] $value
4756 }
4757 m {
Tim Edwards23c97662020-08-09 11:57:32 -04004758 dict set pdkparams [string tolower $key] $value
4759 }
4760 nf {
4761 # Adjustment ot W will be handled below
4762 dict set pdkparams [string tolower $key] $value
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004763 }
4764 }
4765 }
Tim Edwards23c97662020-08-09 11:57:32 -04004766
4767 # Magic does not understand "nf" as a parameter, but expands to
4768 # "nf" number of devices connected horizontally. The "w" value
4769 # must be divided down accordingly, as the "nf" parameter implies
4770 # that the total width "w" is divided into "nf" fingers.
4771
4772 catch {
4773 set w [dict get $pdkparams w]
4774 set nf [dict get $pdkparams nf]
4775 if {$nf > 1} {
4776 dict set pdkparams w [expr $w / $nf]
4777 }
4778 }
4779
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004780 return $pdkparams
4781}
4782
4783#----------------------------------------------------------------
4784
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004785proc sky130::sky130_fd_pr__nfet_01v8_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004786 return [sky130::mos_convert $parameters]
4787}
4788
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004789proc sky130::sky130_fd_pr__nfet_01v8_lvt_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004790 return [sky130::mos_convert $parameters]
4791}
4792
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004793proc sky130::sky130_fd_bs_flash__special_sonosfet_star_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004794 return [sky130::mos_convert $parameters]
4795}
4796
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004797proc sky130::sky130_fd_pr__nfet_g5v0d10v5_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004798 return [sky130::mos_convert $parameters]
4799}
4800
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004801proc sky130::sky130_fd_pr__nfet_05v0_nvt_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004802 return [sky130::mos_convert $parameters]
4803}
4804
Tim Edwardsee445932021-03-31 12:32:04 -04004805proc sky130::sky130_fd_pr__nfet_03v3_nvt_convert {parameters} {
4806 return [sky130::mos_convert $parameters]
4807}
4808
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004809proc sky130::sky130_fd_pr__pfet_01v8_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004810 return [sky130::mos_convert $parameters]
4811}
4812
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004813proc sky130::sky130_fd_pr__pfet_01v8_lvt_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004814 return [sky130::mos_convert $parameters]
4815}
4816
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004817proc sky130::sky130_fd_pr__pfet_01v8_hvt_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004818 return [sky130::mos_convert $parameters]
4819}
4820
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004821proc sky130::sky130_fd_pr__pfet_g5v0d10v5_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004822 return [sky130::mos_convert $parameters]
4823}
4824
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004825proc sky130::sky130_fd_pr__cap_var_lvt_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004826 return [sky130::mos_convert $parameters]
4827}
4828
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004829proc sky130::sky130_fd_pr__cap_var_hvt_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004830 return [sky130::mos_convert $parameters]
4831}
4832
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004833proc sky130::sky130_fd_pr__cap_var_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004834 return [sky130::mos_convert $parameters]
4835}
4836
4837#----------------------------------------------------------------
4838# mos: Interactively specifies the fixed layout parameters
4839#----------------------------------------------------------------
4840
4841proc sky130::mos_dialog {device parameters} {
4842 # Editable fields: w, l, nf, m, diffcov, polycov
4843 # Checked fields: topc, botc
4844 # For specific devices, gate type is a selection list
4845
4846 magic::add_entry w "Width (um)" $parameters
4847 magic::add_entry l "Length (um)" $parameters
4848 magic::add_entry nf "Fingers" $parameters
4849 magic::add_entry m "M" $parameters
4850
4851 if {[dict exists $parameters compatible]} {
4852 set sellist [dict get $parameters compatible]
4853 magic::add_selectlist gencell "Device type" $sellist $parameters $device
4854 }
4855
4856 magic::add_entry diffcov "Diffusion contact coverage (%)" $parameters
4857 magic::add_entry polycov "Poly contact coverage (%)" $parameters
4858 magic::add_entry rlcov "Guard ring contact coverage (%)" $parameters
4859 if {[dict exists $parameters gbc]} {
4860 magic::add_entry tbcov "Guard ring top/bottom contact coverage (%)" $parameters
4861 }
4862
4863 magic::add_checkbox poverlap "Overlap at poly contact" $parameters
4864 magic::add_checkbox doverlap "Overlap at diffusion contact" $parameters
4865 magic::add_checkbox topc "Add top gate contact" $parameters
4866 magic::add_checkbox botc "Add bottom gate contact" $parameters
4867
4868 magic::add_checkbox guard "Add guard ring" $parameters
4869 magic::add_checkbox full_metal "Full metal guard ring" $parameters
4870 magic::add_checkbox glc "Add left guard ring contact" $parameters
4871 magic::add_checkbox grc "Add right guard ring contact" $parameters
4872 if {[dict exists $parameters gbc]} {
4873 magic::add_checkbox gbc "Add bottom guard ring contact" $parameters
4874 }
4875 if {[dict exists $parameters gtc]} {
4876 magic::add_checkbox gtc "Add top guard ring contact" $parameters
4877 }
Tim Edwards0ee0f182020-11-21 16:15:07 -05004878
4879 magic::add_entry viasrc "Source via coverage \[+/-\](%)" $parameters
4880 magic::add_entry viadrn "Drain via coverage \[+/-\](%)" $parameters
4881 magic::add_entry viagate "Gate via coverage \[+/-\](%)" $parameters
4882 magic::add_entry viagb "Bottom guard ring via coverage \[+/-\](%)" $parameters
4883 magic::add_entry viagt "Top guard ring via coverage \[+/-\](%)" $parameters
4884 magic::add_entry viagr "Right guard ring via coverage \[+/-\](%)" $parameters
4885 magic::add_entry viagl "Left guard ring via coverage \[+/-\](%)" $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004886}
4887
4888#----------------------------------------------------------------
4889
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004890proc sky130::sky130_fd_pr__nfet_01v8_dialog {parameters} {
4891 sky130::mos_dialog sky130_fd_pr__nfet_01v8 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004892}
4893
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004894proc sky130::sky130_fd_pr__nfet_01v8_lvt_dialog {parameters} {
4895 sky130::mos_dialog sky130_fd_pr__nfet_01v8_lvt $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004896}
4897
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004898proc sky130::sky130_fd_bs_flash__special_sonosfet_star_dialog {parameters} {
4899 sky130::mos_dialog sky130_fd_bs_flash__special_sonosfet_star $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004900}
4901
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004902proc sky130::sky130_fd_pr__nfet_g5v0d10v5_dialog {parameters} {
4903 sky130::mos_dialog sky130_fd_pr__nfet_g5v0d10v5 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004904}
4905
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004906proc sky130::sky130_fd_pr__nfet_05v0_nvt_dialog {parameters} {
4907 sky130::mos_dialog sky130_fd_pr__nfet_05v0_nvt $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004908}
4909
Tim Edwardsee445932021-03-31 12:32:04 -04004910proc sky130::sky130_fd_pr__nfet_03v3_nvt_dialog {parameters} {
4911 sky130::mos_dialog sky130_fd_pr__nfet_03v3_nvt $parameters
4912}
4913
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004914proc sky130::sky130_fd_pr__pfet_01v8_dialog {parameters} {
4915 sky130::mos_dialog sky130_fd_pr__pfet_01v8 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004916}
4917
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004918proc sky130::sky130_fd_pr__pfet_01v8_lvt_dialog {parameters} {
4919 sky130::mos_dialog sky130_fd_pr__pfet_01v8_lvt $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004920}
4921
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004922proc sky130::sky130_fd_pr__pfet_01v8_hvt_dialog {parameters} {
4923 sky130::mos_dialog sky130_fd_pr__pfet_01v8_hvt $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004924}
4925
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004926proc sky130::sky130_fd_pr__pfet_g5v0d10v5_dialog {parameters} {
4927 sky130::mos_dialog sky130_fd_pr__pfet_g5v0d10v5 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004928}
4929
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004930proc sky130::sky130_fd_pr__cap_var_lvt_dialog {parameters} {
4931 sky130::mos_dialog sky130_fd_pr__cap_var_lvt $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004932}
4933
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004934proc sky130::sky130_fd_pr__cap_var_hvt_dialog {parameters} {
4935 sky130::mos_dialog sky130_fd_pr__cap_var_hvt $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004936}
4937
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004938proc sky130::sky130_fd_pr__cap_var_dialog {parameters} {
4939 sky130::mos_dialog sky130_fd_pr__cap_var $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004940}
4941
4942#----------------------------------------------------------------
4943# getbox: Get the current cursor box, in microns
4944#----------------------------------------------------------------
4945
4946proc sky130::getbox {} {
4947 set curbox [box values]
4948 set newbox []
4949 set oscale [cif scale out]
4950 for {set i 0} {$i < 4} {incr i} {
4951 set v [* [lindex $curbox $i] $oscale]
4952 lappend newbox $v
4953 }
4954 return $newbox
4955}
4956
4957#----------------------------------------------------------------
4958# unionbox: Get the union bounding box of box1 and box2
4959#----------------------------------------------------------------
4960
4961proc sky130::unionbox {box1 box2} {
4962 set newbox []
4963 for {set i 0} {$i < 2} {incr i} {
4964 set v [lindex $box1 $i]
4965 set o [lindex $box2 $i]
4966 if {$v < $o} {
4967 lappend newbox $v
4968 } else {
4969 lappend newbox $o
4970 }
4971 }
4972 for {set i 2} {$i < 4} {incr i} {
4973 set v [lindex $box1 $i]
4974 set o [lindex $box2 $i]
4975 if {$v > $o} {
4976 lappend newbox $v
4977 } else {
4978 lappend newbox $o
4979 }
4980 }
4981 return $newbox
4982}
4983
4984#----------------------------------------------------------------
4985# Draw a contact
4986#----------------------------------------------------------------
4987
4988proc sky130::draw_contact {w h s o x atype ctype mtype {orient vert}} {
4989
4990 # Draw a minimum-size diff contact centered at current position
4991 # w is width, h is height. Minimum size ensured.
4992 # x is contact size
4993 # s is contact diffusion (or poly) surround
4994 # o is contact metal surround
4995 # atype is active (e.g., ndiff) or bottom metal if a via
4996 # ctype is contact (e.g., ndc)
4997 # mtype is metal (e.g., m1) or top metal if a via
4998 # orient is the orientation of the contact
4999
5000 # Set orientations for the bottom material based on material type.
5001 # Substrate diffusions (tap) need not overlap the contact in all
5002 # directions, but other (diff) types do. The metal (local
5003 # interconnect) layer always overlaps in two directions only.
5004
5005 set lv_sub_types {"psd" "nsd"}
5006 if {[lsearch $lv_sub_types $atype] >= 0} {
5007 set aorient $orient
5008 } else {
5009 set aorient "full"
5010 }
5011
5012 pushbox
5013 box size 0 0
5014 if {$w < $x} {set w $x}
5015 if {$h < $x} {set h $x}
5016 set hw [/ $w 2.0]
5017 set hh [/ $h 2.0]
5018 box grow n ${hh}um
5019 box grow s ${hh}um
5020 box grow e ${hw}um
5021 box grow w ${hw}um
5022 paint ${ctype}
5023 pushbox
5024 # Bottom layer surrounded on sides as declared by aorient
5025 if {($aorient == "vert") || ($aorient == "full")} {
5026 box grow n ${s}um
5027 box grow s ${s}um
5028 }
5029 if {($aorient == "horz") || ($aorient == "full")} {
5030 box grow e ${s}um
5031 box grow w ${s}um
5032 }
5033 paint ${atype}
5034 set extents [sky130::getbox]
5035 popbox
5036 # Top layer surrounded on sides as declared by orient
5037 if {($orient == "vert") || ($orient == "full")} {
5038 box grow n ${o}um
5039 box grow s ${o}um
5040 }
5041 if {($orient == "horz") || ($orient == "full")} {
5042 box grow e ${o}um
5043 box grow w ${o}um
5044 }
5045 paint ${mtype}
5046 popbox
5047 return $extents
5048}
5049
5050#----------------------------------------------------------------
5051# Draw a guard ring
5052#----------------------------------------------------------------
5053
5054proc sky130::guard_ring {gw gh parameters} {
5055
5056 # Set local default values if they are not in parameters
5057 set rlcov 100 ;# Right-left contact coverage percentage
5058 set tbcov 100 ;# Top-bottom contact coverage percentage
5059 set grc 1 ;# Draw right side contact
5060 set glc 1 ;# Draw left side contact
5061 set gtc 1 ;# Draw right side contact
5062 set gbc 1 ;# Draw left side contact
Tim Edwards0ee0f182020-11-21 16:15:07 -05005063 set viagb 0 ;# Draw bottom side via
5064 set viagt 0 ;# Draw top side via
5065 set viagr 0 ;# Draw right side via
5066 set viagl 0 ;# Draw left side via
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005067 set full_metal 1 ;# Draw full (continuous) metal ring
5068 set guard_sub_type pwell ;# substrate type under guard ring
5069 set guard_sub_surround 0 ;# substrate type surrounds guard ring
5070 set plus_diff_type nsd ;# guard ring diffusion type
5071 set plus_contact_type nsc ;# guard ring diffusion contact type
5072 set sub_type pwell ;# substrate type
5073
5074 # Set a local variable for each parameter (e.g., $l, $w, etc.)
5075 foreach key [dict keys $parameters] {
5076 set $key [dict get $parameters $key]
5077 }
5078
5079 # Set guard_sub_type to sub_type if it is not defined
5080 if {![dict exists $parameters guard_sub_type]} {
5081 set guard_sub_type $sub_type
5082 }
5083
5084 set hx [/ $contact_size 2.0]
5085 set hw [/ $gw 2.0]
5086 set hh [/ $gh 2.0]
5087
5088 # Watch for (LV) substrate diffusion types, which have a different
5089 # contact surround amount depending on the direction
5090
5091 set lv_sub_types {"psd" "nsd"}
5092 if {[lsearch $lv_sub_types $plus_diff_type] >= 0} {
5093 set diff_surround 0
5094 }
5095
5096 # Compute diffusion width
5097 set difft [+ $contact_size $diff_surround $diff_surround]
5098 set hdifft [/ $difft 2.0]
5099 # Compute guard ring diffusion width and height
5100 set hdiffw [/ [+ $gw $difft] 2.0]
5101 set hdiffh [/ [+ $gh $difft] 2.0]
5102
5103 pushbox
5104 box size 0 0
5105
5106 pushbox
5107 box move n ${hh}um
5108 box grow n ${hdifft}um
5109 box grow s ${hdifft}um
5110 box grow e ${hdiffw}um
5111 box grow w ${hdiffw}um
5112 paint $plus_diff_type
5113 if {$guard_sub_surround > 0} {
5114 box grow c ${guard_sub_surround}um
5115 paint $guard_sub_type
5116 }
5117 popbox
5118 pushbox
5119 box move s ${hh}um
5120 box grow n ${hdifft}um
5121 box grow s ${hdifft}um
5122 box grow e ${hdiffw}um
5123 box grow w ${hdiffw}um
5124 paint $plus_diff_type
5125 if {$guard_sub_surround > 0} {
5126 box grow c ${guard_sub_surround}um
5127 paint $guard_sub_type
5128 }
5129 popbox
5130 pushbox
5131 box move e ${hw}um
5132 box grow e ${hdifft}um
5133 box grow w ${hdifft}um
5134 box grow n ${hdiffh}um
5135 box grow s ${hdiffh}um
5136 paint $plus_diff_type
5137 if {$guard_sub_surround > 0} {
5138 box grow c ${guard_sub_surround}um
5139 paint $guard_sub_type
5140 }
5141 popbox
5142 pushbox
5143 box move w ${hw}um
5144 box grow e ${hdifft}um
5145 box grow w ${hdifft}um
5146 box grow n ${hdiffh}um
5147 box grow s ${hdiffh}um
5148 paint $plus_diff_type
5149 if {$guard_sub_surround > 0} {
5150 box grow c ${guard_sub_surround}um
5151 paint $guard_sub_type
5152 }
5153 popbox
5154
5155 if {$full_metal} {
5156 set hmetw [/ [+ $gw $contact_size] 2.0]
5157 set hmeth [/ [+ $gh $contact_size] 2.0]
5158 pushbox
5159 box move n ${hh}um
5160 box grow n ${hx}um
5161 box grow s ${hx}um
5162 box grow e ${hmetw}um
5163 box grow w ${hmetw}um
5164 paint li
5165 popbox
5166 pushbox
5167 box move s ${hh}um
5168 box grow n ${hx}um
5169 box grow s ${hx}um
5170 box grow e ${hmetw}um
5171 box grow w ${hmetw}um
5172 paint li
5173 popbox
5174 pushbox
5175 box move e ${hw}um
5176 box grow e ${hx}um
5177 box grow w ${hx}um
5178 box grow n ${hmeth}um
5179 box grow s ${hmeth}um
5180 paint li
5181 popbox
5182 pushbox
5183 box move w ${hw}um
5184 box grow e ${hx}um
5185 box grow w ${hx}um
5186 box grow n ${hmeth}um
5187 box grow s ${hmeth}um
5188 paint li
5189 popbox
5190 }
5191
5192 # Set guard ring height so that contact metal reaches to end, scale by $per
5193 # set ch [* [+ $gh $contact_size [* $metal_surround -2.0]] [/ $rlcov 100.0]]
5194 set ch [* [- $gh $contact_size [* [+ $metal_surround $metal_spacing] \
5195 2.0]] [/ $rlcov 100.0]]
5196 if {$ch < $contact_size} {set ch $contact_size}
5197
5198 # Set guard ring width so that contact metal reaches to side contacts
5199 set cw [* [- $gw $contact_size [* [+ $metal_surround $metal_spacing] \
5200 2.0]] [/ $tbcov 100.0]]
5201 if {$cw < $contact_size} {set cw $contact_size}
5202
5203 if {$tbcov > 0.0} {
5204 if {$gtc == 1} {
5205 pushbox
5206 box move n ${hh}um
5207 sky130::draw_contact $cw 0 $diff_surround $metal_surround \
5208 $contact_size $plus_diff_type $plus_contact_type li horz
5209 popbox
5210 }
5211 if {$gbc == 1} {
5212 pushbox
5213 box move s ${hh}um
5214 sky130::draw_contact $cw 0 $diff_surround $metal_surround \
5215 $contact_size $plus_diff_type $plus_contact_type li horz
5216 popbox
5217 }
5218 }
5219 if {$rlcov > 0.0} {
5220 if {$grc == 1} {
5221 pushbox
5222 box move e ${hw}um
5223 sky130::draw_contact 0 $ch $diff_surround $metal_surround \
5224 $contact_size $plus_diff_type $plus_contact_type li vert
5225 popbox
5226 }
5227 if {$glc == 1} {
5228 pushbox
5229 box move w ${hw}um
5230 sky130::draw_contact 0 $ch $diff_surround $metal_surround \
5231 $contact_size $plus_diff_type $plus_contact_type li vert
5232 popbox
5233 }
5234 }
5235
Tim Edwards0ee0f182020-11-21 16:15:07 -05005236 # Vias
5237 if {$viagb != 0} {
5238 pushbox
5239 set ch $via_size
5240 set cw [* [- $gw $via_size] [/ [expr abs($viagb)] 100.0]]
5241 if {$cw < $via_size} {set cw $via_size}
5242 box move s ${hh}um
5243 box grow n [/ $ch 2]um
5244 box grow s [/ $ch 2]um
5245 set anchor [string index $viagb 0]
5246 if {$anchor == "+"} {
5247 box move w [/ [- $gw $via_size] 2]um
5248 box grow e ${cw}um
5249 } elseif {$anchor == "-"} {
5250 box move e [/ [- $gw $via_size] 2]um
5251 box grow w ${cw}um
5252 } else {
5253 box grow e [/ $cw 2]um
5254 box grow w [/ $cw 2]um
5255 }
5256 sky130::mcon_draw horz
5257 popbox
5258 }
5259 if {$viagt != 0} {
5260 pushbox
5261 set ch $via_size
5262 set cw [* [- $gw $via_size] [/ [expr abs($viagt)] 100.0]]
5263 if {$cw < $via_size} {set cw $via_size}
5264 box move n ${hh}um
5265 box grow n [/ $ch 2]um
5266 box grow s [/ $ch 2]um
5267 set anchor [string index $viagt 0]
5268 if {$anchor == "+"} {
5269 box move w [/ [- $gw $via_size] 2]um
5270 box grow e ${cw}um
5271 } elseif {$anchor == "-"} {
5272 box move e [/ [- $gw $via_size] 2]um
5273 box grow w ${cw}um
5274 } else {
5275 box grow e [/ $cw 2]um
5276 box grow w [/ $cw 2]um
5277 }
5278 sky130::mcon_draw horz
5279 popbox
5280 }
5281 if {$viagr != 0} {
5282 pushbox
5283 set ch [* [- $gh $via_size] [/ [expr abs($viagr)] 100.0]]
5284 if {$ch < $via_size} {set ch $via_size}
5285 set cw $via_size
5286 box move e ${hw}um
5287 box grow e [/ $cw 2]um
5288 box grow w [/ $cw 2]um
5289 set anchor [string index $viagr 0]
5290 if {$anchor == "+"} {
Tim Edwards933e61e2020-11-21 16:50:06 -05005291 box move s [/ [- $gh $via_size] 2]um
Tim Edwards0ee0f182020-11-21 16:15:07 -05005292 box grow n ${ch}um
5293 } elseif {$anchor == "-"} {
Tim Edwards933e61e2020-11-21 16:50:06 -05005294 box move n [/ [- $gh $via_size] 2]um
Tim Edwards0ee0f182020-11-21 16:15:07 -05005295 box grow s ${ch}um
5296 } else {
5297 box grow n [/ $ch 2]um
5298 box grow s [/ $ch 2]um
5299 }
5300 sky130::mcon_draw vert
5301 popbox
5302 }
5303 if {$viagl != 0} {
5304 pushbox
5305 set ch [* [- $gh $via_size] [/ [expr abs($viagl)] 100.0]]
5306 if {$ch < $via_size} {set ch $via_size}
5307 set cw $via_size
5308 box move w ${hw}um
5309 box grow e [/ $cw 2]um
5310 box grow w [/ $cw 2]um
5311 set anchor [string index $viagl 0]
5312 if {$anchor == "+"} {
Tim Edwards933e61e2020-11-21 16:50:06 -05005313 box move s [/ [- $gh $via_size] 2]um
Tim Edwards275e28d2020-11-21 16:43:41 -05005314 box grow n ${ch}um
Tim Edwards0ee0f182020-11-21 16:15:07 -05005315 } elseif {$anchor == "-"} {
Tim Edwards933e61e2020-11-21 16:50:06 -05005316 box move n [/ [- $gh $via_size] 2]um
Tim Edwards0ee0f182020-11-21 16:15:07 -05005317 box grow s ${ch}um
5318 } else {
5319 box grow n [/ $ch 2]um
5320 box grow s [/ $ch 2]um
5321 }
5322 sky130::mcon_draw vert
5323 popbox
5324 }
5325
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005326 pushbox
5327 box grow e ${hw}um
5328 box grow w ${hw}um
5329 box grow n ${hh}um
5330 box grow s ${hh}um
5331 # Create boundary using properties
5332 property FIXED_BBOX [box values]
5333 box grow c ${hx}um ;# to edge of contact
5334 box grow c ${diff_surround}um ;# to edge of diffusion
5335 box grow c ${sub_surround}um ;# sub/well overlap of diff (NOT guard_sub)
5336 paint $sub_type
5337 set cext [sky130::getbox]
5338 popbox
5339 popbox
5340
5341 return $cext
5342}
5343
5344#----------------------------------------------------------------
5345# MOSFET: Draw a single device
5346#----------------------------------------------------------------
5347
5348proc sky130::mos_device {parameters} {
5349
5350 # Epsilon for avoiding round-off errors
5351 set eps 0.0005
5352
5353 # Set local default values if they are not in parameters
5354 set diffcov 100 ;# percent coverage of diffusion contact
5355 set polycov 100 ;# percent coverage of poly contact
5356 set topc 1 ;# draw top poly contact
5357 set botc 1 ;# draw bottom poly contact
Tim Edwards0ee0f182020-11-21 16:15:07 -05005358 set viasrc 100 ;# draw source vias
5359 set viadrn 100 ;# draw drain vias
5360 set viagate 100 ;# draw gate vias
5361 set evens 1 ;# even or odd numbered device finger, in X
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005362 set dev_sub_type "" ;# device substrate type (if different from guard ring)
Tim Edwards0ee0f182020-11-21 16:15:07 -05005363 set dev_sub_dist 0 ;# device substrate distance (if nondefault dev_sub_type)
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005364 set min_effl 0 ;# gate length below which finger pitch must be stretched
5365 set diff_overlap_cont 0 ;# extra overlap of end contact by diffusion
5366
5367 # Set a local variable for each parameter (e.g., $l, $w, etc.)
5368 foreach key [dict keys $parameters] {
5369 set $key [dict get $parameters $key]
5370 }
5371
5372 # Draw the diffusion and poly
5373 pushbox
5374 box size 0 0
5375 pushbox
5376 set hw [/ $w 2.0]
5377 set hl [/ $l 2.0]
5378 set he [/ $min_effl 2.0]
5379 if {$nf == 1 || $he < $hl} {set he $hl}
5380 box grow n ${hw}um
5381 box grow s ${hw}um
5382 box grow e ${hl}um
5383 box grow w ${hl}um
5384 pushbox
5385 if {${diff_extension} > ${gate_to_diffcont}} {
5386 box grow e ${diff_extension}um
5387 box grow w ${diff_extension}um
5388 } else {
5389 box grow e ${gate_to_diffcont}um
5390 box grow w ${gate_to_diffcont}um
5391 }
5392 paint ${diff_type}
5393 popbox
5394 pushbox
5395 if {${gate_extension} > ${gate_to_polycont}} {
5396 box grow n ${gate_extension}um
5397 box grow s ${gate_extension}um
5398 } else {
5399 if {$topc} {
5400 box grow n ${gate_to_polycont}um
5401 } else {
5402 box grow n ${gate_extension}um
5403 }
5404 if {$botc} {
5405 box grow s ${gate_to_polycont}um
5406 } else {
5407 box grow s ${gate_extension}um
5408 }
5409 }
5410 paint ${poly_type}
5411 set cext [sky130::getbox]
5412 popbox
5413 # save gate area now and paint later, so that diffusion surrounding the
5414 # contact does not paint over the gate area, in case the gate type is
5415 # not part of a "compose" entry in the techfile.
5416 set gaterect [box values]
5417 popbox
5418
5419 # Adjust position of contacts for dogbone geometry
5420 # Rule 1: Minimize diffusion length. Contacts only move out
5421 # if width < contact diffusion height. They move out enough
5422 # that the diffusion-to-poly spacing is satisfied.
5423
5424 set ddover 0
5425 set cdwmin [+ ${contact_size} [* ${diff_surround} 2]]
5426 set cstem [- ${gate_to_diffcont} [/ ${cdwmin} 2.0]]
5427 set cgrow [- ${diff_poly_space} ${cstem}]
5428 if {[+ ${w} ${eps}] < ${cdwmin}} {
5429 if {${cgrow} > 0} {
5430 set gate_to_diffcont [+ ${gate_to_diffcont} ${cgrow}]
5431 }
5432 set ddover [/ [- ${cdwmin} ${w}] 2.0]
5433 }
5434
5435 # Rule 2: Minimum poly width. Poly contacts only move out
5436 # if length < contact poly width. They move out enough
5437 # that the diffusion-to-poly spacing is satisfied.
5438
5439 set gporig ${gate_to_polycont}
5440 set cplmin [+ ${contact_size} [* ${poly_surround} 2]]
5441 set cstem [- ${gate_to_polycont} [/ ${cplmin} 2.0]]
5442 set cgrow [- ${diff_poly_space} ${cstem}]
5443 if {[+ ${l} ${eps}] < ${cplmin}} {
5444 if {${cgrow} > 0} {
5445 set gate_to_polycont [+ ${gate_to_polycont} ${cgrow}]
5446 }
5447 }
5448
5449 # Rule 3: If both poly and diffusion are dogboned, then move
5450 # poly out further to clear spacing to the diffusion contact
5451
5452 if {[+ ${w} ${eps}] < ${cdwmin}} {
5453 if {[+ ${l} ${eps}] < ${cplmin}} {
5454 set cgrow [/ [- ${cplmin} ${w}] 2.0]
5455 set gate_to_polycont [+ ${gate_to_polycont} ${cgrow}]
5456 }
5457 }
5458
5459 # Rule 4: If M > 1 and poly contacts overlap, then increase the
5460 # transistor-to-poly-contact distance by the amount of any
5461 # diffusion dogbone overhang.
5462
5463 if {($poverlap == 1) && ($m > 1)} {
5464 if {${gate_to_polycont} - $gporig < $ddover} {
5465 set gate_to_polycont [+ ${gporig} ${ddover}]
5466 }
5467 }
5468
5469 # Reduce contact sizes by poly or diffusion surround so that
5470 # the contact area edges match the device diffusion or poly.
5471 # (Minimum dimensions will be enforced by the contact drawing routine)
5472 set tsurround [+ ${diff_surround} ${diff_overlap_cont}]
5473 set cdw [- ${w} [* ${tsurround} 2]] ;# diff contact height
5474 set cpl [- ${l} [* ${poly_surround} 2]] ;# poly contact width
5475
Tim Edwards0ee0f182020-11-21 16:15:07 -05005476 # Save the full diffusion (source/drain) and poly (gate) lengths
5477 set cdwfull $cdw
5478 set cplfull $cpl
5479
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005480 # Reduce by coverage percentage. NOTE: If overlapping multiple devices,
5481 # keep maximum poly contact coverage.
5482
5483 set cdw [* ${cdw} [/ ${diffcov} 100.0]]
5484 if {($poverlap == 0) || ($m == 1)} {
5485 set cpl [* ${cpl} [/ ${polycov} 100.0]]
5486 }
5487
5488 # Right diffusion contact
5489 pushbox
5490 box move e ${he}um
5491 box move e ${gate_to_diffcont}um
Tim Edwards0ee0f182020-11-21 16:15:07 -05005492
5493 # Source via on top of contact
5494 if {$evens == 1} {set viatype $viasrc} else {set viatype $viadrn}
5495 if {$viatype != 0} {
5496 pushbox
5497 set cw $via_size
5498 set ch [* $cdwfull [/ [expr abs($viatype)] 100.0]]
5499 if {$ch < $via_size} {set ch $via_size}
5500 box grow e [/ $cw 2]um
5501 box grow w [/ $cw 2]um
5502 set anchor [string index $viatype 0]
5503 if {$anchor == "+"} {
5504 box move s [/ [- $cdwfull $via_size] 2]um
5505 box grow n ${ch}um
5506 } elseif {$anchor == "-"} {
5507 box move n [/ [- $cdwfull $via_size] 2]um
5508 box grow s ${ch}um
5509 } else {
5510 box grow n [/ $ch 2]um
5511 box grow s [/ $ch 2]um
5512 }
5513 sky130::mcon_draw vert
5514 popbox
5515 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005516 set cext [sky130::unionbox $cext [sky130::draw_contact 0 ${cdw} \
5517 ${diff_surround} ${metal_surround} ${contact_size}\
5518 ${diff_type} ${diff_contact_type} li vert]]
5519 popbox
5520 # Left diffusion contact
5521 pushbox
5522 box move w ${he}um
5523 box move w ${gate_to_diffcont}um
Tim Edwards0ee0f182020-11-21 16:15:07 -05005524
5525 # Drain via on top of contact
5526 if {$evens == 1} {set viatype $viadrn} else {set viatype $viasrc}
5527 if {$viatype != 0} {
5528 pushbox
5529 set cw $via_size
5530 set ch [* $cdwfull [/ [expr abs($viatype)] 100.0]]
5531 if {$ch < $via_size} {set ch $via_size}
5532 box grow e [/ $cw 2]um
5533 box grow w [/ $cw 2]um
5534 set anchor [string index $viatype 0]
5535 if {$anchor == "+"} {
5536 box move s [/ [- $cdwfull $via_size] 2]um
5537 box grow n ${ch}um
5538 } elseif {$anchor == "-"} {
5539 box move n [/ [- $cdwfull $via_size] 2]um
5540 box grow s ${ch}um
5541 } else {
5542 box grow n [/ $ch 2]um
5543 box grow s [/ $ch 2]um
5544 }
5545 sky130::mcon_draw vert
5546 popbox
5547 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005548 set cext [sky130::unionbox $cext [sky130::draw_contact 0 ${cdw} \
5549 ${diff_surround} ${metal_surround} ${contact_size} \
5550 ${diff_type} ${diff_contact_type} li vert]]
5551 set diffarea $cext
5552 popbox
5553 # Top poly contact
5554 if {$topc} {
5555 pushbox
5556 box move n ${hw}um
5557 box move n ${gate_to_polycont}um
Tim Edwards0ee0f182020-11-21 16:15:07 -05005558
5559 # Gate via on top of contact
5560 if {$viagate != 0} {
5561 pushbox
5562 set ch $via_size
5563 set cw [* $cplfull [/ [expr abs($viagate)] 100.0]]
5564 if {$cw < $via_size} {set cw $via_size}
5565 box grow n [/ $ch 2]um
5566 box grow s [/ $ch 2]um
5567 set anchor [string index $viagate 0]
5568 if {$anchor == "+"} {
5569 box move w [/ [- $cplfull $via_size] 2]um
5570 box grow e ${cw}um
5571 } elseif {$anchor == "-"} {
5572 box move e [/ [- $cplfull $via_size] 2]um
5573 box grow w ${cw}um
5574 } else {
5575 box grow e [/ $cw 2]um
5576 box grow w [/ $cw 2]um
5577 }
5578 sky130::mcon_draw horz
5579 popbox
5580 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005581 set cext [sky130::unionbox $cext [sky130::draw_contact ${cpl} 0 \
5582 ${poly_surround} ${metal_surround} ${contact_size} \
5583 ${poly_type} ${poly_contact_type} li horz]]
5584 popbox
5585 }
5586 # Bottom poly contact
5587 if {$botc} {
5588 pushbox
5589 box move s ${hw}um
5590 box move s ${gate_to_polycont}um
Tim Edwards0ee0f182020-11-21 16:15:07 -05005591
5592 # Gate via on top of contact
5593 if {$viagate != 0} {
5594 pushbox
5595 set ch $via_size
5596 set cw [* $cplfull [/ [expr abs($viagate)] 100.0]]
5597 if {$cw < $via_size} {set cw $via_size}
5598 box grow n [/ $ch 2]um
5599 box grow s [/ $ch 2]um
5600 set anchor [string index $viagate 0]
5601 if {$anchor == "+"} {
5602 box move w [/ [- $cplfull $via_size] 2]um
5603 box grow e ${cw}um
5604 } elseif {$anchor == "-"} {
5605 box move e [/ [- $cplfull $via_size] 2]um
5606 box grow w ${cw}um
5607 } else {
5608 box grow e [/ $cw 2]um
5609 box grow w [/ $cw 2]um
5610 }
5611 sky130::mcon_draw horz
5612 popbox
5613 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005614 set cext [sky130::unionbox $cext [sky130::draw_contact ${cpl} 0 \
5615 ${poly_surround} ${metal_surround} ${contact_size} \
5616 ${poly_type} ${poly_contact_type} li horz]]
5617 popbox
5618 }
5619
5620 # Now draw the gate, after contacts have been drawn
5621 pushbox
5622 box values {*}${gaterect}
5623 # gate_type need not be defined if poly over diff paints the right type.
5624 catch {paint ${gate_type}}
5625 # sub_surround_dev, if defined, may create a larger area around the gate
5626 # than sub_surround creates around the diffusion/poly area.
5627 if [dict exists $parameters sub_surround_dev] {
5628 box grow n ${sub_surround_dev}um
5629 box grow s ${sub_surround_dev}um
5630 box grow e ${sub_surround_dev}um
5631 box grow w ${sub_surround_dev}um
5632 paint ${dev_sub_type}
5633 set cext [sky130::unionbox $cext [sky130::getbox]]
5634 }
5635 popbox
5636
5637 if {$dev_sub_type != ""} {
5638 box values [lindex $diffarea 0]um [lindex $diffarea 1]um \
5639 [lindex $diffarea 2]um [lindex $diffarea 3]um
5640 box grow n ${sub_surround}um
5641 box grow s ${sub_surround}um
5642 box grow e ${sub_surround}um
5643 box grow w ${sub_surround}um
5644 paint ${dev_sub_type}
Tim Edwards0ee0f182020-11-21 16:15:07 -05005645 if {$dev_sub_dist > 0} {
5646 set cext [sky130::unionbox $cext [sky130::getbox]]
5647 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005648 # puts stdout "Diagnostic: bounding box is $cext"
5649 }
5650
5651 popbox
5652 return $cext
5653}
5654
5655#----------------------------------------------------------------
5656# MOSFET: Draw the tiled device
5657#----------------------------------------------------------------
5658
5659proc sky130::mos_draw {parameters} {
5660 tech unlock *
5661 set savesnap [snap]
5662 snap internal
5663
5664 # Set defaults if they are not in parameters
5665 set poverlap 0 ;# overlap poly contacts when tiling
5666 set doverlap 1 ;# overlap diffusion contacts when tiling
5667 set dev_sub_dist 0 ;# substrate to guard ring, if dev_sub_type defined
5668 set dev_sub_space 0 ;# distance between substrate areas for arrayed devices
5669 set min_allc 0 ;# gate length below which poly contacts must be interleaved
5670 set id_type "" ;# additional type covering everything
5671 set id_surround 0 ;# amount of surround on above type
5672 set id2_type "" ;# additional type covering everything
5673 set id2_surround 0 ;# amount of surround on above type
5674
5675 # Set a local variable for each parameter (e.g., $l, $w, etc.)
5676 foreach key [dict keys $parameters] {
5677 set $key [dict get $parameters $key]
5678 }
5679
5680 # Diff-to-tap spacing is by default the same as diff spacing
5681 if {![dict exist $parameters diff_tap_space]} {
5682 set diff_tap_space $diff_spacing
5683 }
5684
5685 # If poverlap is 1 then both poly contacts must be present
5686 if {$poverlap == 1} {
5687 set topc 1
5688 set botc 1
5689 dict set parameters topc 1
5690 dict set parameters botc 1
5691 }
5692
5693 # Normalize distance units to microns
5694 set w [magic::spice2float $w]
5695 set l [magic::spice2float $l]
5696
5697 pushbox
5698 box values 0 0 0 0
5699
5700 # If dx < (poly contact space + poly contact width), then there is not
5701 # enough room for a row of contacts, so force alternating contacts
5702
Tim Edwards0ee0f182020-11-21 16:15:07 -05005703 set evens 1
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005704 if {$nf > 1 && $l < $min_allc} {
5705 set intc 1
5706 set evenodd 1
5707 set topc 1
5708 set botc 1
5709 dict set parameters topc 1
5710 dict set parameters botc 1
5711 set poverlap 0
5712 } else {
5713 set intc 0
5714 }
5715
5716 # Determine the base device dimensions by drawing one device
5717 # while all layers are locked (nothing drawn). This allows the
5718 # base drawing routine to do complicated geometry without having
5719 # to duplicate it here with calculations.
5720
5721 tech lock *
5722 set bbox [sky130::mos_device $parameters]
5723 # puts stdout "Diagnostic: Device bounding box e $bbox (um)"
5724 tech unlock *
5725
5726 set fw [- [lindex $bbox 2] [lindex $bbox 0]]
5727 set fh [- [lindex $bbox 3] [lindex $bbox 1]]
5728 set lw [+ [lindex $bbox 2] [lindex $bbox 0]]
5729 set lh [+ [lindex $bbox 3] [lindex $bbox 1]]
5730
5731 # If dev_sub_dist > 0 then each device must be in its own substrate
5732 # (well) area, and overlaps are disallowed. dev_sub_space determines
5733 # the distance between individual devices in an array.
5734
5735 if {$dev_sub_dist > 0} {
5736 set poverlap 0
5737 set doverlap 0
5738
5739 if {$dev_sub_space > $poly_spacing} {
5740 set dx [+ $fw $dev_sub_space]
5741 set dy [+ $fh $dev_sub_space]
5742 } else {
5743 set dx [+ $fw $poly_spacing]
5744 set dy [+ $fh $poly_spacing]
5745 }
5746
5747 } else {
5748
5749 # Determine tile width and height (depends on overlap)
5750 if {$poverlap == 0} {
5751 set dy [+ $fh $poly_spacing]
5752 } else {
5753 # overlap poly
5754 set dy [- $fh [+ $poly_surround $poly_surround $contact_size]]
5755 }
5756
5757 if {$doverlap == 0} {
5758 set dx [+ $fw $diff_spacing]
5759 } else {
5760 # overlap diffusions
5761 set dx [- $fw [+ $diff_surround $diff_surround $contact_size]]
5762 }
5763 }
5764
5765 # Determine core width and height
5766 set corex [+ [* [- $nf 1] $dx] $fw]
5767 set corey [+ [* [- $m 1] $dy] $fh]
5768 set corellx [/ [+ [- $corex $fw] $lw] 2.0]
5769 set corelly [/ [+ [- $corey $fh] $lh] 2.0]
5770
5771 # If there is a diffusion dogbone, and no top poly contact, then
5772 # increase the core height by the amount of the dogbone overhang.
5773
5774 if {$topc == 0} {
5775 set cdwmin [+ ${contact_size} [* ${diff_surround} 2]]
5776 if {${w} < ${cdwmin}} {
5777 set corey [+ $corey [/ [- ${cdwmin} ${w}] 2.0]]
5778 }
5779 }
5780
Tim Edwards0ee0f182020-11-21 16:15:07 -05005781 # Calculate guard ring size (measured to contact center)
5782 if {($guard != 0) || (${id_type} != "")} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005783 if {($dev_sub_dist > 0) && ([+ $dev_sub_dist $sub_surround] > $diff_tap_space)} {
5784 set gx [+ $corex [* 2.0 [+ $dev_sub_dist $diff_surround]] $contact_size]
5785 } else {
5786 set gx [+ $corex [* 2.0 [+ $diff_tap_space $diff_surround]] $contact_size]
5787 }
5788 if {($dev_sub_dist > 0) && ([+ $dev_sub_dist $sub_surround] > $diff_gate_space)} {
5789 set gy [+ $corey [* 2.0 [+ $dev_sub_dist $diff_surround]] $contact_size]
5790 } else {
5791 set gy [+ $corey [* 2.0 [+ $diff_gate_space $diff_surround]] $contact_size]
5792 }
5793
5794 # Somewhat tricky. . . if the width is small and the diffusion is
5795 # a dogbone, and the top or bottom poly contact is missing, then
5796 # the spacing to the guard ring may be limited by diffusion spacing, not
5797 # poly to diffusion.
5798
5799 set inset [/ [+ $contact_size [* 2.0 $diff_surround] -$w] 2.0]
5800 set sdiff [- [+ $inset $diff_tap_space] [+ $gate_extension $diff_gate_space]]
5801
5802 if {$sdiff > 0} {
5803 if {$topc == 0} {
5804 set gy [+ $gy $sdiff]
5805 set corelly [+ $corelly [/ $sdiff 2.0]]
5806 }
5807 if {$botc == 0} {
5808 set gy [+ $gy $sdiff]
5809 set corelly [- $corelly [/ $sdiff 2.0]]
5810 }
5811 }
Tim Edwards0ee0f182020-11-21 16:15:07 -05005812 }
5813 if {$guard != 0} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005814 # Draw the guard ring first, as MOS well may interact with guard ring substrate
5815 sky130::guard_ring $gx $gy $parameters
5816 }
5817
5818 pushbox
5819 # If any surrounding identifier type is defined, draw it
5820 if {${id_type} != ""} {
5821 set hw [/ $gx 2]
5822 set hh [/ $gy 2]
5823 box grow e ${hw}um
5824 box grow w ${hw}um
5825 box grow n ${hh}um
5826 box grow s ${hh}um
5827 box grow c ${id_surround}um
5828 paint ${id_type}
5829 }
5830 popbox
5831 pushbox
5832 box move w ${corellx}um
5833 box move s ${corelly}um
5834 for {set xp 0} {$xp < $nf} {incr xp} {
Tim Edwards0ee0f182020-11-21 16:15:07 -05005835 dict set parameters evens $evens
5836 set evens [- 1 $evens]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005837 pushbox
5838 if {$intc == 1} {
5839 set evenodd [- 1 $evenodd]
5840 if {$evenodd == 1} {
5841 dict set parameters topc 1
5842 dict set parameters botc 0
5843 } else {
5844 dict set parameters topc 0
5845 dict set parameters botc 1
5846 }
5847 set saveeo $evenodd
5848 }
5849 for {set yp 0} {$yp < $m} {incr yp} {
5850 sky130::mos_device $parameters
5851 box move n ${dy}um
5852 if {$intc == 1} {
5853 set evenodd [- 1 $evenodd]
5854 if {$evenodd == 1} {
5855 dict set parameters topc 1
5856 dict set parameters botc 0
5857 } else {
5858 dict set parameters topc 0
5859 dict set parameters botc 1
5860 }
5861 }
5862 }
5863 if {$intc == 1} {
5864 set evenodd $saveeo
5865 }
5866 popbox
5867 box move e ${dx}um
5868 }
5869 popbox
5870 popbox
5871
5872 snap $savesnap
5873 tech revert
5874}
5875
5876#-------------------
5877# nMOS 1.8V
5878#-------------------
5879
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005880proc sky130::sky130_fd_pr__nfet_01v8_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005881 set newdict [dict create \
5882 gate_type nfet \
5883 diff_type ndiff \
5884 diff_contact_type ndc \
5885 plus_diff_type psd \
5886 plus_contact_type psc \
5887 poly_type poly \
5888 poly_contact_type pc \
5889 sub_type psub \
5890 min_effl 0.185 \
5891 min_allc 0.26 \
5892 ]
5893 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
5894 return [sky130::mos_draw $drawdict]
5895}
5896
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005897proc sky130::sky130_fd_pr__nfet_01v8_lvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005898 set newdict [dict create \
5899 gate_type nfetlvt \
5900 diff_type ndiff \
5901 diff_contact_type ndc \
5902 plus_diff_type psd \
5903 plus_contact_type psc \
5904 poly_type poly \
5905 poly_contact_type pc \
5906 sub_type psub \
5907 min_effl 0.185 \
5908 min_allc 0.26 \
5909 ]
5910 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
5911 return [sky130::mos_draw $drawdict]
5912}
5913
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005914proc sky130::sky130_fd_bs_flash__special_sonosfet_star_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005915 set newdict [dict create \
5916 gate_type nsonos \
5917 diff_type ndiff \
5918 diff_contact_type ndc \
5919 plus_diff_type psd \
5920 plus_contact_type psc \
5921 poly_type poly \
5922 poly_contact_type pc \
5923 sub_type psub \
5924 id_type dnwell \
5925 id_surround 1.355 \
5926 min_effl 0.185 \
5927 min_allc 0.26 \
5928 ]
5929 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
5930 return [sky130::mos_draw $drawdict]
5931}
5932
5933#-------------------
5934# pMOS 1.8V
5935#-------------------
5936
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005937proc sky130::sky130_fd_pr__pfet_01v8_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005938 set newdict [dict create \
5939 gate_type pfet \
5940 diff_type pdiff \
5941 diff_contact_type pdc \
5942 plus_diff_type nsd \
5943 plus_contact_type nsc \
5944 poly_type poly \
5945 poly_contact_type pc \
5946 sub_type nwell \
Tim Edwards2788f172020-10-14 22:32:33 -04005947 dev_sub_type nwell \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005948 gate_to_polycont 0.32 \
5949 min_effl 0.185 \
5950 min_allc 0.26 \
5951 ]
5952 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
5953 return [sky130::mos_draw $drawdict]
5954}
5955
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005956proc sky130::sky130_fd_pr__pfet_01v8_lvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005957 set newdict [dict create \
5958 gate_type pfetlvt \
5959 diff_type pdiff \
5960 diff_contact_type pdc \
5961 plus_diff_type nsd \
5962 plus_contact_type nsc \
5963 poly_type poly \
5964 poly_contact_type pc \
5965 sub_type nwell \
Tim Edwards2788f172020-10-14 22:32:33 -04005966 dev_sub_type nwell \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005967 gate_to_polycont 0.32 \
5968 min_effl 0.185 \
5969 min_allc 0.26 \
5970 ]
5971 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
5972 return [sky130::mos_draw $drawdict]
5973}
5974
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005975proc sky130::sky130_fd_pr__pfet_01v8_hvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005976 set newdict [dict create \
5977 gate_type pfethvt \
5978 diff_type pdiff \
5979 diff_contact_type pdc \
5980 plus_diff_type nsd \
5981 plus_contact_type nsc \
5982 poly_type poly \
5983 poly_contact_type pc \
5984 sub_type nwell \
Tim Edwards2788f172020-10-14 22:32:33 -04005985 dev_sub_type nwell \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005986 gate_to_polycont 0.32 \
5987 min_effl 0.185 \
5988 min_allc 0.26 \
5989 ]
5990 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
5991 return [sky130::mos_draw $drawdict]
5992}
5993
5994#-------------------
5995# pMOS 5.0V
5996#-------------------
5997
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005998proc sky130::sky130_fd_pr__pfet_g5v0d10v5_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005999 set newdict [dict create \
6000 gate_type mvpfet \
6001 diff_type mvpdiff \
6002 diff_contact_type mvpdc \
6003 plus_diff_type mvnsd \
6004 plus_contact_type mvnsc \
6005 poly_type poly \
6006 poly_contact_type pc \
6007 sub_type nwell \
Tim Edwards2788f172020-10-14 22:32:33 -04006008 dev_sub_type nwell \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006009 guard_sub_surround 0.33 \
6010 gate_to_polycont 0.32 \
6011 diff_spacing 0.31 \
6012 diff_tap_space 0.38 \
6013 diff_gate_space 0.38 \
6014 ]
6015 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
6016 return [sky130::mos_draw $drawdict]
6017}
6018
6019#-------------------
6020# nMOS 5.0V
6021#-------------------
6022
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006023proc sky130::sky130_fd_pr__nfet_g5v0d10v5_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006024 set newdict [dict create \
6025 gate_type mvnfet \
6026 diff_type mvndiff \
6027 diff_contact_type mvndc \
6028 plus_diff_type mvpsd \
6029 plus_contact_type mvpsc \
6030 poly_type poly \
6031 poly_contact_type pc \
6032 sub_type psub \
6033 diff_spacing 0.31 \
6034 diff_tap_space 0.38 \
6035 diff_gate_space 0.38 \
6036 ]
6037 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
6038 return [sky130::mos_draw $drawdict]
6039}
6040
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006041proc sky130::sky130_fd_pr__nfet_05v0_nvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006042 set newdict [dict create \
6043 gate_type mvnnfet \
6044 diff_type mvndiff \
6045 diff_contact_type mvndc \
6046 plus_diff_type mvpsd \
6047 plus_contact_type mvpsc \
6048 poly_type poly \
6049 poly_contact_type pc \
6050 sub_type psub \
6051 diff_spacing 0.30 \
6052 diff_tap_space 0.38 \
6053 diff_gate_space 0.38 \
6054 ]
6055 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
6056 return [sky130::mos_draw $drawdict]
6057}
6058
Tim Edwardsee445932021-03-31 12:32:04 -04006059proc sky130::sky130_fd_pr__nfet_03v3_nvt_draw {parameters} {
6060 set newdict [dict create \
6061 gate_type nnfet \
6062 diff_type mvndiff \
6063 diff_contact_type mvndc \
6064 plus_diff_type mvpsd \
6065 plus_contact_type mvpsc \
6066 poly_type poly \
6067 poly_contact_type pc \
6068 sub_type psub \
6069 diff_spacing 0.30 \
6070 diff_tap_space 0.38 \
6071 diff_gate_space 0.38 \
6072 ]
6073 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
6074 return [sky130::mos_draw $drawdict]
6075}
6076
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006077#------------------------
6078# MOS varactor (1.8V)
6079#------------------------
6080
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006081proc sky130::sky130_fd_pr__cap_var_lvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006082 set newdict [dict create \
6083 gate_type var \
6084 diff_type nnd \
6085 diff_contact_type nsc \
6086 plus_diff_type psd \
6087 plus_contact_type psc \
6088 poly_type poly \
6089 poly_contact_type pc \
6090 sub_type psub \
6091 dev_sub_type nwell \
6092 diff_overlap_cont 0.06 \
6093 dev_sub_dist 0.14 \
6094 dev_sub_space 1.27 \
6095 gate_to_diffcont 0.34 \
6096 diff_extension 0.485 \
6097 ]
6098 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
6099 return [sky130::mos_draw $drawdict]
6100}
6101
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006102proc sky130::sky130_fd_pr__cap_var_hvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006103 set newdict [dict create \
6104 gate_type varhvt \
6105 diff_type nnd \
6106 diff_contact_type nsc \
6107 plus_diff_type psd \
6108 plus_contact_type psc \
6109 poly_type poly \
6110 poly_contact_type pc \
6111 sub_type psub \
6112 dev_sub_type nwell \
6113 diff_overlap_cont 0.06 \
6114 dev_sub_dist 0.14 \
6115 dev_sub_space 1.27 \
6116 gate_to_diffcont 0.34 \
6117 diff_extension 0.485 \
6118 ]
6119 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
6120 return [sky130::mos_draw $drawdict]
6121}
6122
6123#---------------------------------------------------------
6124# MOS varactor (5.0V)
6125# NOTE: dev_sub_space set to 2.0 assuming different nets.
6126# Should have option for same-net with merged wells.
6127#---------------------------------------------------------
6128
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006129proc sky130::sky130_fd_pr__cap_var_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006130 set newdict [dict create \
6131 gate_type mvvar \
6132 diff_type mvnsd \
6133 diff_contact_type mvnsc \
6134 plus_diff_type mvpsd \
6135 plus_contact_type mvpsc \
6136 poly_type poly \
6137 poly_contact_type pc \
6138 sub_type psub \
6139 dev_sub_type nwell \
6140 sub_surround 0.38 \
6141 sub_surround_dev 0.56 \
6142 guard_sub_surround 0.18 \
6143 diff_overlap_cont 0.06 \
6144 dev_sub_dist 0.785 \
6145 dev_sub_space 2.0 \
6146 gate_to_diffcont 0.34 \
6147 diff_extension 0.485 \
6148 ]
6149 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
6150 return [sky130::mos_draw $drawdict]
6151}
6152
6153#----------------------------------------------------------------
6154# MOSFET: Check device parameters for out-of-bounds values
6155#----------------------------------------------------------------
6156
6157proc sky130::mos_check {device parameters} {
6158
6159 # Set a local variable for each parameter (e.g., $l, $w, etc.)
6160 foreach key [dict keys $parameters] {
6161 set $key [dict get $parameters $key]
6162 }
6163
6164 # Normalize distance units to microns
6165 set l [magic::spice2float $l]
6166 set l [magic::3digitpastdecimal $l]
6167 set w [magic::spice2float $w]
6168 set w [magic::3digitpastdecimal $w]
6169
6170 # nf, m must be integer
6171 if {![string is int $nf]} {
6172 puts stderr "NF must be an integer!"
6173 dict set parameters nf 1
6174 }
6175 if {![string is int $m]} {
6176 puts stderr "M must be an integer!"
6177 dict set parameters m 1
6178 }
6179 # diffcov, polycov must be numeric
6180 if {[catch {expr abs($diffcov)}]} {
6181 puts stderr "diffcov must be numeric!"
6182 set diffcov 100
Tim Edwards0ee0f182020-11-21 16:15:07 -05006183 dict set parameters diffcov $diffcov
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006184 }
6185 if {[catch {expr abs($polycov)}]} {
6186 puts stderr "polycov must be numeric!"
6187 set polycov 100
Tim Edwards0ee0f182020-11-21 16:15:07 -05006188 dict set parameters polycov $polycov
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006189 }
6190
6191 if {$l < $lmin} {
6192 puts stderr "Mos length must be >= $lmin um"
6193 dict set parameters l $lmin
6194 }
6195 if {$w < $wmin} {
6196 puts stderr "Mos width must be >= $wmin um"
6197 dict set parameters w $wmin
6198 }
6199 if {$nf < 1} {
6200 puts stderr "NF must be >= 1"
6201 dict set parameters nf 1
6202 }
6203 if {$m < 1} {
6204 puts stderr "M must be >= 1"
6205 dict set parameters m 1
6206 }
6207 if {$diffcov < 20 } {
6208 puts stderr "Diffusion contact coverage must be at least 20%"
6209 dict set parameters diffcov 20
6210 } elseif {$diffcov > 100 } {
6211 puts stderr "Diffusion contact coverage can't be more than 100%"
6212 dict set parameters diffcov 100
6213 }
6214 if {$polycov < 20 } {
6215 puts stderr "Poly contact coverage must be at least 20%"
6216 dict set parameters polycov 20
6217 } elseif {$polycov > 100 } {
6218 puts stderr "Poly contact coverage can't be more than 100%"
6219 dict set parameters polycov 100
6220 }
6221
Tim Edwards0ee0f182020-11-21 16:15:07 -05006222 if {[catch {expr abs($viasrc)}]} {
6223 puts stderr "Source via coverage must be numeric!"
6224 dict set parameters viasrc 100
6225 } elseif {[expr abs($viasrc)] > 100} {
6226 puts stderr "Source via coverage can't be more than 100%"
6227 dict set parameters viasrc 100
6228 }
6229 if {[catch {expr abs($viadrn)}]} {
6230 puts stderr "Drain via coverage must be numeric!"
6231 dict set parameters viadrn 100
6232 } elseif {[expr abs($viadrn)] > 100} {
6233 puts stderr "Drain via coverage can't be more than 100%"
6234 dict set parameters viadrn 100
6235 }
6236 if {[catch {expr abs($viagate)}]} {
6237 puts stderr "Gate via coverage must be numeric!"
6238 dict set parameters viagate 100
6239 } elseif {[expr abs($viagate)] > 100} {
6240 puts stderr "Gate via coverage can't be more than 100%"
6241 dict set parameters viagate 100
6242 }
6243 if {[catch {expr abs($viagb)}]} {
6244 puts stderr "Guard ring bottom via coverage must be numeric!"
6245 dict set parameters viagb 0
6246 } elseif {[expr abs($viagb)] > 100} {
6247 puts stderr "Guard ring bottom via coverage can't be more than 100%"
6248 dict set parameters viagb 100
6249 }
6250 if {[catch {expr abs($viagt)}]} {
6251 puts stderr "Guard ring top via coverage must be numeric!"
6252 dict set parameters viagt 0
6253 } elseif {[expr abs($viagt)] > 100} {
6254 puts stderr "Guard ring top via coverage can't be more than 100%"
6255 dict set parameters viagt 100
6256 }
6257 if {[catch {expr abs($viagr)}]} {
6258 puts stderr "Guard ring right via coverage must be numeric!"
6259 dict set parameters viagr 0
6260 } elseif {[expr abs($viagr)] > 100} {
6261 puts stderr "Guard ring right via coverage can't be more than 100%"
6262 dict set parameters viagr 100
6263 }
6264 if {[catch {expr abs($viagl)}]} {
6265 puts stderr "Guard ring left via coverage must be numeric!"
6266 dict set parameters viagl 0
6267 } elseif {[expr abs($viagl)] > 100} {
6268 puts stderr "Guard ring left via coverage can't be more than 100%"
6269 dict set parameters viagl 100
6270 }
6271
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006272 # Values must satisfy diffusion-to-tap spacing of 20um.
6273 # Therefore the maximum of guard ring width or height cannot exceed 40um.
6274 # If in violation, reduce counts first, as these are easiest to recover
6275 # by duplicating the device and overlapping the wells.
6276 set origm $m
6277 set orignf $nf
6278 while true {
6279 set yext [expr ($w + 3.0) * $m]
6280 set xext [expr ($l + 1.0) * $nf + 1.1]
6281 if {[expr min($xext, $yext)] > 40.0} {
6282 if {$yext > 40.0 && $m > 1} {
6283 incr m -1
6284 } elseif {$xext > 40.0 && $nf > 1} {
6285 incr nf -1
6286 } elseif {$yext > 40.0} {
6287 set w 37
6288 puts -nonewline stderr "Transistor width must be < 37 um"
6289 puts stderr " to avoid tap spacing violation."
6290 dict set parameters w $w
6291 } elseif {$xext > 40.0} {
6292 set l 37.9
6293 puts -nonewline stderr "Transistor length must be < 37.9 um"
6294 puts stderr " to avoid tap spacing violation."
6295 dict set parameters l $l
6296 }
6297 } else {
6298 break
6299 }
6300 }
6301 if {$m != $origm} {
6302 puts stderr "Y repeat reduced to prevent tap distance violation"
6303 dict set parameters m $m
6304 }
6305 if {$nf != $orignf} {
6306 puts stderr "X repeat reduced to prevent tap distance violation"
6307 dict set parameters nf $nf
6308 }
6309
6310 return $parameters
6311}
6312
6313#----------------------------------------------------------------
6314
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006315proc sky130::sky130_fd_pr__nfet_01v8_check {parameters} {
6316 return [sky130::mos_check sky130_fd_pr__nfet_01v8 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006317}
6318
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006319proc sky130::sky130_fd_pr__nfet_01v8_lvt_check {parameters} {
6320 return [sky130::mos_check sky130_fd_pr__nfet_01v8_lvt $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006321}
6322
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006323proc sky130::sky130_fd_bs_flash__special_sonosfet_star_check {parameters} {
6324 return [sky130::mos_check sky130_fd_bs_flash__special_sonosfet_star $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006325}
6326
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006327proc sky130::sky130_fd_pr__nfet_g5v0d10v5_check {parameters} {
6328 return [sky130::mos_check sky130_fd_pr__nfet_g5v0d10v5 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006329}
6330
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006331proc sky130::sky130_fd_pr__nfet_05v0_nvt_check {parameters} {
6332 return [sky130::mos_check sky130_fd_pr__nfet_05v0_nvt $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006333}
6334
Tim Edwardsee445932021-03-31 12:32:04 -04006335proc sky130::sky130_fd_pr__nfet_03v3_nvt_check {parameters} {
6336 return [sky130::mos_check sky130_fd_pr__nfet_03v3_nvt $parameters]
6337}
6338
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006339proc sky130::sky130_fd_pr__pfet_01v8_check {parameters} {
6340 return [sky130::mos_check sky130_fd_pr__pfet_01v8 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006341}
6342
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006343proc sky130::sky130_fd_pr__pfet_01v8_lvt_check {parameters} {
6344 return [sky130::mos_check sky130_fd_pr__pfet_01v8_lvt $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006345}
6346
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006347proc sky130::sky130_fd_pr__pfet_01v8_hvt_check {parameters} {
6348 return [sky130::mos_check sky130_fd_pr__pfet_01v8_hvt $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006349}
6350
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006351proc sky130::sky130_fd_pr__pfet_g5v0d10v5_check {parameters} {
6352 return [sky130::mos_check sky130_fd_pr__pfet_g5v0d10v5 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006353}
6354
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006355proc sky130::sky130_fd_pr__cap_var_lvt_check {parameters} {
6356 return [sky130::mos_check sky130_fd_pr__cap_var_lvt $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006357}
6358
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006359proc sky130::sky130_fd_pr__cap_var_hvt_check {parameters} {
6360 return [sky130::mos_check sky130_fd_pr__cap_var_hvt $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006361}
6362
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006363proc sky130::sky130_fd_pr__cap_var_check {parameters} {
6364 return [sky130::mos_check sky130_fd_pr__cap_var $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006365}
6366
6367#----------------------------------------------------------------
6368# Fixed device: Specify all user-editable default values
6369#
6370# deltax --- Additional horizontal space between devices
6371# deltay --- Additional vertical space between devices
6372# nx --- Number of arrayed devices in X
6373# ny --- Number of arrayed devices in Y
6374#
6375# Note that these values, specifically nx, ny, deltax,
6376# and deltay, are properties of the instance, not the cell.
6377# They translate to the instance array x and y counts; while
6378# deltax is the x pitch less the cell width, and deltay is the
6379# y pitch less the cell height.
6380#
6381# non-user-editable
6382#
6383# nocell --- Indicates that this cell has a predefined layout
6384# and therefore there is no cell to draw.
6385# xstep --- Width of the cell (nominal array pitch in X)
6386# ystep --- Height of the cell (nominal array pitch in Y)
6387#----------------------------------------------------------------
6388
6389# Fixed-layout devices (from sky130_fd_pr_base, _rf, and _rf2 libraries)
6390#
6391# Bipolar transistors:
6392#
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006393# sky130_fd_pr__rf_npn_05v5_W1p00L1p00
6394# sky130_fd_pr__rf_npn_05v5_W1p00L2p00
Tim Edwards956e3022021-05-27 20:43:26 -04006395# sky130_fd_pr__rf_pnp_05v5_W3p40L3p40
6396# sky130_fd_pr__rf_pnp_05v5_W0p68L0p68
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006397#
6398# Parallel Plate Capacitors:
6399#
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006400# sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldlim5
6401# sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield
6402# sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_lishield
6403# sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_lishield
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006404#
6405# Inductors:
6406#
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006407# sky130_fd_pr__rf_test_coil1
6408# sky130_fd_pr__rf_test_coil2
6409# sky130_fd_pr__rf_test_coil3
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006410
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006411proc sky130::sky130_fd_pr__rf_npn_05v5_W1p00L1p00_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006412 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 7.03 ystep 7.03}
6413}
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006414proc sky130::sky130_fd_pr__rf_npn_05v5_W1p00L2p00_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006415 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 7.03 ystep 8.03}
6416}
6417
Tim Edwards956e3022021-05-27 20:43:26 -04006418proc sky130::sky130_fd_pr__rf_pnp_05v5_W0p68L0p68_defaults {} {
Tim Edwards7e294962021-05-04 20:33:17 -04006419 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 3.72 ystep 3.72}
6420}
6421
Tim Edwards956e3022021-05-27 20:43:26 -04006422proc sky130::sky130_fd_pr__rf_pnp_05v5_W3p40L3p40_defaults {} {
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006423 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 6.44 ystep 6.44}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006424}
6425
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006426proc sky130::sky130_fd_pr__rf_test_coil1 {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006427 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 258 ystep 258}
6428}
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006429proc sky130::sky130_fd_pr__rf_test_coil2 {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006430 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 290 ystep 404}
6431}
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006432proc sky130::sky130_fd_pr__rf_test_coil3 {} {
6433 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 290 ystep 404}
6434}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006435
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006436proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006437 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 11.08 ystep 11.36}
6438}
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006439proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006440 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 11.08 ystep 11.36}
6441}
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006442proc sky130::sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_lishield_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006443 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 11.08 ystep 11.36}
6444}
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006445proc sky130::sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_lishield_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006446 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 11.08 ystep 11.36}
6447}
6448
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006449#----------------------------------------------------------------
6450# Fixed device: Conversion from SPICE netlist parameters to toolkit
6451#----------------------------------------------------------------
6452
6453proc sky130::fixed_convert {parameters} {
6454 set pdkparams [dict create]
6455 dict for {key value} $parameters {
6456 switch -nocase $key {
6457 m {
6458 dict set pdkparams nx $value
6459 }
6460 }
6461 }
6462 return $pdkparams
6463}
6464
6465#----------------------------------------------------------------
6466
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006467proc sky130::sky130_fd_pr__rf_npn_05v5_W1p00L1p00_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006468 return [sky130::fixed_convert $parameters]
6469}
6470
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006471proc sky130::sky130_fd_pr__rf_npn_05v5_W1p00L2p00_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006472 return [sky130::fixed_convert $parameters]
6473}
6474
Tim Edwards956e3022021-05-27 20:43:26 -04006475proc sky130::sky130_fd_pr__rf_pnp_05v5_W0p68L0p68_convert {parameters} {
Tim Edwards7e294962021-05-04 20:33:17 -04006476 return [sky130::fixed_convert $parameters]
6477}
6478
Tim Edwards956e3022021-05-27 20:43:26 -04006479proc sky130::sky130_fd_pr__rf_pnp_05v5_W3p40L3p40_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006480 return [sky130::fixed_convert $parameters]
6481}
6482
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006483proc sky130::sky130_fd_pr__rf_test_coil1 {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006484 return [sky130::fixed_convert $parameters]
6485}
6486
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006487proc sky130::sky130_fd_pr__rf_test_coil2 {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006488 return [sky130::fixed_convert $parameters]
6489}
6490
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006491proc sky130::sky130_fd_pr__rf_test_coil3 {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006492 return [sky130::fixed_convert $parameters]
6493}
6494
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006495proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006496 return [sky130::fixed_convert $parameters]
6497}
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006498proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006499 return [sky130::fixed_convert $parameters]
6500}
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006501proc sky130::sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_lishield_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006502 return [sky130::fixed_convert $parameters]
6503}
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006504proc sky130::sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_lishield_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006505 return [sky130::fixed_convert $parameters]
6506}
6507
6508#----------------------------------------------------------------
6509# Fixed device: Interactively specifies the fixed layout parameters
6510#----------------------------------------------------------------
6511
6512proc sky130::fixed_dialog {parameters} {
6513 # Instance fields: nx, ny, pitchx, pitchy
6514 # Editable fields: nx, ny, deltax, deltay
6515 # Non-editable fields: nocell, xstep, ystep
6516
6517 # Set a local variable for each parameter (e.g., $l, $w, etc.)
6518 foreach key [dict keys $parameters] {
6519 set $key [dict get $parameters $key]
6520 }
6521
6522 # "nocell" field causes nx and ny to be dropped in from
6523 # "array count". Also "pitchx" and "pitchy" are passed
6524 # in internal units. Convert these to microns and generate
6525 # If there is no pitchx and pitchy, then the device has not
6526 # yet been created, so keep the deltax and deltay defaults.
6527
6528 if [dict exists $parameters pitchx] {
6529 set pitchux [magic::i2u $pitchx]
6530 set stepux [magic::spice2float $xstep]
6531 set deltax [magic::3digitpastdecimal [expr $pitchux - $stepux]]
6532 # An array size 1 should not cause deltax to go negative
6533 if {$deltax < 0.0} {set deltax 0.0}
6534 dict set parameters deltax $deltax
6535 }
6536 if [dict exists $parameters pitchy] {
6537 set pitchuy [magic::i2u $pitchy]
6538 set stepuy [magic::spice2float $ystep]
6539 set deltay [magic::3digitpastdecimal [expr $pitchuy - $stepuy]]
6540 # An array size 1 should not cause deltay to go negative
6541 if {$deltay < 0.0} {set deltay 0.0}
6542 dict set parameters deltay $deltay
6543 }
6544
6545 magic::add_entry nx "NX" $parameters
6546 magic::add_entry ny "NY" $parameters
6547 magic::add_entry deltax "X step (um)" $parameters
6548 magic::add_entry deltay "Y step (um)" $parameters
6549}
6550
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006551proc sky130::sky130_fd_pr__rf_npn_05v5_W1p00L1p00_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006552 sky130::fixed_dialog $parameters
6553}
6554
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006555proc sky130::sky130_fd_pr__rf_npn_05v5_W1p00L2p00_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006556 sky130::fixed_dialog $parameters
6557}
6558
Tim Edwards956e3022021-05-27 20:43:26 -04006559proc sky130::sky130_fd_pr__rf_pnp_05v5_W0p68L0p68_dialog {parameters} {
Tim Edwards7e294962021-05-04 20:33:17 -04006560 sky130::fixed_dialog $parameters
6561}
6562
Tim Edwards956e3022021-05-27 20:43:26 -04006563proc sky130::sky130_fd_pr__rf_pnp_05v5_W3p40L3p40_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006564 sky130::fixed_dialog $parameters
6565}
6566
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006567proc sky130::sky130_fd_pr__rf_test_coil1 {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006568 sky130::fixed_dialog $parameters
6569}
6570
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006571proc sky130::sky130_fd_pr__rf_test_coil2 {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006572 sky130::fixed_dialog $parameters
6573}
6574
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006575proc sky130::sky130_fd_pr__rf_test_coil3 {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006576 sky130::fixed_dialog $parameters
6577}
6578
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006579proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006580 sky130::fixed_dialog $parameters
6581}
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006582proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006583 sky130::fixed_dialog $parameters
6584}
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006585proc sky130::sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_lishield_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006586 sky130::fixed_dialog $parameters
6587}
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006588proc sky130::sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_lishield_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006589 sky130::fixed_dialog $parameters
6590}
6591
6592#----------------------------------------------------------------
6593# Fixed device: Draw the device
6594#----------------------------------------------------------------
6595
6596proc sky130::fixed_draw {devname parameters} {
6597
6598 # Set a local variable for each parameter (e.g., $l, $w, etc.)
6599 foreach key [dict keys $parameters] {
6600 set $key [dict get $parameters $key]
6601 }
6602
6603 # This cell declares "nocell" in parameters, so it needs to
6604 # instance the cell and set properties.
6605
6606 # Instantiate the cell. The name corresponds to the cell in the sky130_fd_pr_* directory.
6607 set instname [getcell ${devname}]
6608
6609 set deltax [magic::spice2float $deltax]
6610 set deltay [magic::spice2float $deltay]
6611 set xstep [magic::spice2float $xstep]
6612 set ystep [magic::spice2float $ystep]
6613
6614 # Array stepping
6615 if {$nx > 1 || $ny > 1} {
6616 set xstep [expr $xstep + $deltax]
6617 set ystep [expr $ystep + $deltay]
6618 box size ${xstep}um ${ystep}um
6619 array $nx $ny
6620 }
6621 select cell $instname
6622 expand
6623 return $instname
6624}
6625
6626#----------------------------------------------------------------
6627# No additional parameters declared for drawing
6628#----------------------------------------------------------------
6629
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006630proc sky130::sky130_fd_pr__rf_npn_05v5_W1p00L1p00_draw {parameters} {
6631 return [sky130::fixed_draw sky130_fd_pr__rf_npn_05v5_W1p00L1p00 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006632}
6633
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006634proc sky130::sky130_fd_pr__rf_npn_05v5_W1p00L2p00_draw {parameters} {
6635 return [sky130::fixed_draw sky130_fd_pr__rf_npn_05v5_W1p00L2p00 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006636}
6637
Tim Edwards956e3022021-05-27 20:43:26 -04006638proc sky130::sky130_fd_pr__rf_pnp_05v5_W0p68L0p68_draw {parameters} {
6639 return [sky130::fixed_draw sky130_fd_pr__rf_pnp_05v5_W0p68L0p68 $parameters]
Tim Edwards7e294962021-05-04 20:33:17 -04006640}
6641
Tim Edwards956e3022021-05-27 20:43:26 -04006642proc sky130::sky130_fd_pr__rf_pnp_05v5_W3p40L3p40_draw {parameters} {
6643 return [sky130::fixed_draw sky130_fd_pr__rf_pnp_05v5_W3p40L3p40 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006644}
6645
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006646proc sky130::sky130_fd_pr__rf_test_coil1 {parameters} {
6647 return [sky130::fixed_draw sky130_fd_pr__rf_test_coil1 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006648}
6649
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006650proc sky130::sky130_fd_pr__rf_test_coil2 {parameters} {
6651 return [sky130::fixed_draw sky130_fd_pr__rf_test_coil2 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006652}
6653
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006654proc sky130::sky130_fd_pr__rf_test_coil3 {parameters} {
6655 return [sky130::fixed_draw sky130_fd_pr__rf_test_coil3 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006656}
6657
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006658proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5_draw {parameters} {
6659 return [sky130::fixed_draw sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006660}
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006661proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield_draw {parameters} {
6662 return [sky130::fixed_draw sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006663}
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006664proc sky130::sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_lishield_draw {parameters} {
6665 return [sky130::fixed_draw sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_lishield $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006666}
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006667proc sky130::sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_lishield_draw {parameters} {
6668 return [sky130::fixed_draw sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_lishield $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006669}
6670
6671#----------------------------------------------------------------
6672# Fixed device: Check device parameters for out-of-bounds values
6673#----------------------------------------------------------------
6674
6675proc sky130::fixed_check {parameters} {
6676
6677 # Set a local variable for each parameter (e.g., $l, $w, etc.)
6678 foreach key [dict keys $parameters] {
6679 set $key [dict get $parameters $key]
6680 }
6681
6682 # Normalize distance units to microns
6683 set deltax [magic::spice2float $deltax -1]
6684 set deltax [magic::3digitpastdecimal $deltax]
6685 set deltay [magic::spice2float $deltay -1]
6686 set deltay [magic::3digitpastdecimal $deltay]
6687
6688 # nx, ny must be integer
6689 if {![string is int $nx]} {
6690 puts stderr "NX must be an integer!"
6691 dict set parameters nx 1
6692 }
6693 if {![string is int $ny]} {
6694 puts stderr "NY must be an integer!"
6695 dict set parameters nx 1
6696 }
6697
6698 # Number of devices in X and Y must be at least 1
6699 if {$nx < 1} {
6700 puts stderr "NX must be >= 1"
6701 dict set parameters nx 1
6702 }
6703 if {$ny < 1} {
6704 puts stderr "NY must be >= 1"
6705 dict set parameters nx 1
6706 }
6707 # Step less than zero violates DRC
6708 if {$deltax < 0} {
6709 puts stderr "X step must be >= 0"
6710 dict set parameters deltax 0
6711 }
6712 if {$deltay < 0} {
6713 puts stderr "Y step must be >= 0"
6714 dict set parameters deltay 0
6715 }
6716 return $parameters
6717}
6718
6719#----------------------------------------------------------------
6720
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006721proc sky130::sky130_fd_pr__rf_npn_05v5_W1p00L1p00_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006722 return [sky130::fixed_check $parameters]
6723}
6724
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006725proc sky130::sky130_fd_pr__rf_npn_05v5_W1p00L2p00_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006726 return [sky130::fixed_check $parameters]
6727}
6728
Tim Edwards956e3022021-05-27 20:43:26 -04006729proc sky130::sky130_fd_pr__rf_pnp_05v5_W0p68L0p68_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006730 return [sky130::fixed_check $parameters]
6731}
6732
Tim Edwards956e3022021-05-27 20:43:26 -04006733proc sky130::sky130_fd_pr__rf_pnp_05v5_W3p40L3p40_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006734 return [sky130::fixed_check $parameters]
6735}
6736
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006737proc sky130::sky130_fd_pr__rf_test_coil1 {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006738 return [sky130::fixed_check $parameters]
6739}
6740
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006741proc sky130::sky130_fd_pr__rf_test_coil2 {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006742 return [sky130::fixed_check $parameters]
6743}
6744
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006745proc sky130::sky130_fd_pr__rf_test_coil3 {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006746 return [sky130::fixed_check $parameters]
6747}
6748
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006749proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006750 return [sky130::fixed_check $parameters]
6751}
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006752proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006753 return [sky130::fixed_check $parameters]
6754}
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006755proc sky130::sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_lishield_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006756 return [sky130::fixed_check $parameters]
6757}
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006758proc sky130::sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_lishield_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006759 return [sky130::fixed_check $parameters]
6760}