blob: 89717de54a9ea01aafc171952cb8c7344433e4a8 [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
Tim Edwards2c4a2762022-02-11 11:30:16 -050012if {[catch {set TECHPATH $env(PDK_ROOT)}]} {
Tim Edwardsd2e91442022-02-11 11:33:37 -050013 set TECHPATH STAGING_PATH
Tim Edwards2c4a2762022-02-11 11:30:16 -050014}
Tim Edwards55f4d0e2020-07-05 15:41:02 -040015if [catch {set PDKPATH}] {set PDKPATH ${TECHPATH}/TECHNAME}
16set PDKNAME TECHNAME
17# "sky130" is the namespace used for all devices
18set PDKNAMESPACE sky130
19puts stdout "Loading TECHNAME Device Generator Menu ..."
20
21# Initialize toolkit menus to the wrapper window
22
23global Opts
24namespace eval sky130 {}
25
26# Set the window callback
27if [catch {set Opts(callback)}] {set Opts(callback) ""}
28set Opts(callback) [subst {sky130::addtechmenu \$framename; $Opts(callback)}]
29
30# if {![info exists Opts(cmdentry)]} {set Opts(cmdentry) 1}
31
32# Set options specific to this PDK
33set Opts(hidelocked) 1
Tim Edwards708a9422021-03-09 22:07:22 -050034set Opts(hidespecial) 0
Tim Edwards55f4d0e2020-07-05 15:41:02 -040035
36# Wrap the closewrapper procedure so that closing the last
37# window is equivalent to quitting.
38if {[info commands closewrapper] == "closewrapper"} {
39 rename closewrapper closewrapperonly
40 proc closewrapper { framename } {
41 if {[llength [windownames all]] <= 1} {
42 magic::quit
43 } else {
44 closewrapperonly $framename
45 }
46 }
47}
48
49# Remove maze router layers from the toolbar by locking them
50tech lock fence,magnet,rotate
51
52namespace eval sky130 {
53 namespace path {::tcl::mathop ::tcl::mathfunc}
54
55 set ruleset [dict create]
56
57 # Process DRC rules (magic style)
58
59 dict set ruleset poly_surround 0.08 ;# Poly surrounds contact
60 dict set ruleset diff_surround 0.06 ;# Diffusion surrounds contact
61 dict set ruleset gate_to_diffcont 0.145 ;# Gate to diffusion contact center
62 dict set ruleset gate_to_polycont 0.275 ;# Gate to poly contact center
63 dict set ruleset gate_extension 0.13 ;# Poly extension beyond gate
64 dict set ruleset diff_extension 0.29 ;# Diffusion extension beyond gate
65 dict set ruleset contact_size 0.17 ;# Minimum contact size
66 dict set ruleset via_size 0.17 ;# Minimum via size
67 dict set ruleset metal_surround 0.08 ;# Local interconnect overlaps contact
68 dict set ruleset sub_surround 0.18 ;# Sub/well surrounds diffusion
69 dict set ruleset diff_spacing 0.28 ;# Diffusion spacing rule
70 dict set ruleset poly_spacing 0.21 ;# Poly spacing rule
71 dict set ruleset diff_poly_space 0.075 ;# Diffusion to poly spacing rule
72 dict set ruleset diff_gate_space 0.20 ;# Diffusion to gate poly spacing rule
73 dict set ruleset metal_spacing 0.23 ;# Local interconnect spacing rule
74 dict set ruleset mmetal_spacing 0.14 ;# Metal spacing rule (above local interconnect)
75 dict set ruleset res_to_cont 0.20 ;# resistor to contact center
76 dict set ruleset res_diff_space 0.20 ;# resistor to guard ring
77}
78
79#-----------------------------------------------------
80# magic::addtechmenu
81#-----------------------------------------------------
82
83proc sky130::addtechmenu {framename} {
84 global Winopts Opts
85
86 # Check for difference between magic 8.1.125 and earlier, and 8.1.126 and later
87 if {[catch {${framename}.titlebar cget -height}]} {
88 set layoutframe ${framename}.pane.top
89 } else {
90 set layoutframe ${framename}
91 }
92
93 # List of devices is long. Divide into two sections for active and passive deivces
94 magic::add_toolkit_menu $layoutframe "Devices 1" pdk1
95
96 magic::add_toolkit_command $layoutframe "nmos (MOSFET)" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -040097 "magic::gencell sky130::sky130_fd_pr__nfet_01v8" pdk1
Tim Edwards55f4d0e2020-07-05 15:41:02 -040098 magic::add_toolkit_command $layoutframe "pmos (MOSFET)" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -040099 "magic::gencell sky130::sky130_fd_pr__pfet_01v8" pdk1
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400100
101 magic::add_toolkit_separator $layoutframe pdk1
102 magic::add_toolkit_command $layoutframe "n-diode" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400103 "magic::gencell sky130::sky130_fd_pr__diode_pw2nd_05v5" pdk1
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400104 magic::add_toolkit_command $layoutframe "p-diode" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400105 "magic::gencell sky130::sky130_fd_pr__diode_pd2nw_05v5" pdk1
Tim Edwardsc2787e82021-11-17 15:27:23 -0500106 magic::add_toolkit_command $layoutframe "photodiode" \
107 "magic::gencell sky130::sky130_fd_pr__photodiode" pdk1
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400108
109 magic::add_toolkit_separator $layoutframe pdk1
110 magic::add_toolkit_command $layoutframe "MOS varactor" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400111 "magic::gencell sky130::sky130_fd_pr__cap_var_lvt" pdk1
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400112 magic::add_toolkit_separator $layoutframe pdk1
113
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400114 magic::add_toolkit_command $layoutframe "NPN 1.0 x 1.0" \
Tim Edwardsc6202ef2020-09-20 17:16:33 -0400115 "magic::gencell sky130::sky130_fd_pr__rf_npn_05v5_W1p00L1p00" pdk1
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400116 magic::add_toolkit_command $layoutframe "NPN 1.0 x 2.0" \
Tim Edwardsc6202ef2020-09-20 17:16:33 -0400117 "magic::gencell sky130::sky130_fd_pr__rf_npn_05v5_W1p00L2p00" pdk1
Tim Edwards7e294962021-05-04 20:33:17 -0400118 magic::add_toolkit_command $layoutframe "PNP 0.68 x 0.68" \
Tim Edwards956e3022021-05-27 20:43:26 -0400119 "magic::gencell sky130::sky130_fd_pr__rf_pnp_05v5_W0p68L0p68" pdk1
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400120 magic::add_toolkit_command $layoutframe "PNP 3.4 x 3.4" \
Tim Edwards956e3022021-05-27 20:43:26 -0400121 "magic::gencell sky130::sky130_fd_pr__rf_pnp_05v5_W3p40L3p40" pdk1
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400122
123 magic::add_toolkit_separator $layoutframe pdk1
124
Tim Edwardsc6202ef2020-09-20 17:16:33 -0400125 magic::add_toolkit_command $layoutframe "inductor 1" \
126 "magic::gencell sky130::sky130_fd_pr__rf_test_coil1" pdk1
127 magic::add_toolkit_command $layoutframe "inductor 2" \
128 "magic::gencell sky130::sky130_fd_pr__rf_test_coil2" pdk1
129 magic::add_toolkit_command $layoutframe "inductor 3" \
130 "magic::gencell sky130::sky130_fd_pr__rf_test_coil3" pdk1
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400131
132 magic::add_toolkit_separator $layoutframe pdk1
133
134 magic::add_toolkit_command $layoutframe "substrate contact (1.8V)" \
135 "sky130::subconn_draw" pdk1
136 magic::add_toolkit_command $layoutframe "substrate contact (5.0V)" \
137 "sky130::mvsubconn_draw" pdk1
138 magic::add_toolkit_command $layoutframe "deep n-well region" \
139 "sky130::deep_nwell_draw" pdk1
140 magic::add_toolkit_command $layoutframe "mcon" \
141 "sky130::mcon_draw" pdk1
142 magic::add_toolkit_command $layoutframe "via1" \
143 "sky130::via1_draw" pdk1
144 magic::add_toolkit_command $layoutframe "via2" \
145 "sky130::via2_draw" pdk1
146#ifdef METAL5
147 magic::add_toolkit_command $layoutframe "via3" \
148 "sky130::via3_draw" pdk1
149 magic::add_toolkit_command $layoutframe "via4" \
150 "sky130::via4_draw" pdk1
151#endif (METAL5)
152
153
154 magic::add_toolkit_menu $layoutframe "Devices 2" pdk2
155
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400156 magic::add_toolkit_command $layoutframe "n-diff resistor (1.8V) - 120 Ohm/sq" \
157 "magic::gencell sky130::sky130_fd_pr__res_generic_nd" pdk2
158 magic::add_toolkit_command $layoutframe "p-diff resistor (1.8V) - 197 Ohm/sq" \
159 "magic::gencell sky130::sky130_fd_pr__res_generic_pd" pdk2
160 magic::add_toolkit_command $layoutframe "n-diff resistor (5.0V) - 114 Ohm/sq" \
Tim Edwards0ee0f182020-11-21 16:15:07 -0500161 "magic::gencell sky130::sky130_fd_pr__res_generic_nd__hv" pdk2
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400162 magic::add_toolkit_command $layoutframe "p-diff resistor (5.0V) - 191 Ohm/sq" \
Tim Edwards0ee0f182020-11-21 16:15:07 -0500163 "magic::gencell sky130::sky130_fd_pr__res_generic_pd__hv" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400164
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400165 magic::add_toolkit_command $layoutframe "poly resistor - 48.2 Ohm/sq" \
166 "magic::gencell sky130::sky130_fd_pr__res_generic_po" pdk2
167 magic::add_toolkit_command $layoutframe "poly resistor - 319.8 Ohm/sq" \
168 "magic::gencell sky130::sky130_fd_pr__res_high_po_0p35" pdk2
169 magic::add_toolkit_command $layoutframe "poly resistor - 2000 Ohm/sq" \
170 "magic::gencell sky130::sky130_fd_pr__res_xhigh_po_0p35" pdk2
171 magic::add_toolkit_command $layoutframe "p-well resistor - 3050 Ohm/sq" \
172 "magic::gencell sky130::sky130_fd_pr__res_iso_pw" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400173 magic::add_toolkit_separator $layoutframe pdk2
174
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400175 magic::add_toolkit_command $layoutframe "l1 metal resistor - 12.2 Ohm/sq" \
176 "magic::gencell sky130::sky130_fd_pr__res_generic_l1" pdk2
177 magic::add_toolkit_command $layoutframe "m1 metal resistor - 125 mOhm/sq" \
178 "magic::gencell sky130::sky130_fd_pr__res_generic_m1" pdk2
179 magic::add_toolkit_command $layoutframe "m2 metal resistor - 125 mOhm/sq" \
180 "magic::gencell sky130::sky130_fd_pr__res_generic_m2" pdk2
181 magic::add_toolkit_command $layoutframe "m3 metal resistor - 47 mOhm/sq" \
182 "magic::gencell sky130::sky130_fd_pr__res_generic_m3" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400183#ifdef METAL5
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400184 magic::add_toolkit_command $layoutframe "m4 metal resistor - 47 mOhm/sq" \
185 "magic::gencell sky130::sky130_fd_pr__res_generic_m4" pdk2
186 magic::add_toolkit_command $layoutframe "m5 metal resistor - 29 mOhm/sq" \
187 "magic::gencell sky130::sky130_fd_pr__res_generic_m5" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400188#endif (METAL5)
189
190#ifdef MIM
Tim Edwards15463bc2021-05-12 21:33:31 -0400191 magic::add_toolkit_command $layoutframe "MiM cap - 2fF/um^2 (metal3)" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400192 "magic::gencell sky130::sky130_fd_pr__cap_mim_m3_1" pdk2
Tim Edwards15463bc2021-05-12 21:33:31 -0400193 magic::add_toolkit_command $layoutframe "MiM cap - 2fF/um^2 (metal4)" \
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400194 "magic::gencell sky130::sky130_fd_pr__cap_mim_m3_2" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400195#endif (MIM)
196 magic::add_toolkit_separator $layoutframe pdk2
197
Tim Edwardsc6202ef2020-09-20 17:16:33 -0400198 magic::add_toolkit_command $layoutframe "vpp 11.5x11.7 m1-m4, li/m5 shield" \
199 "magic::gencell sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5" pdk2
200 magic::add_toolkit_command $layoutframe "vpp 11.5x11.7 m1-m2" \
201 "magic::gencell sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield" pdk2
202 magic::add_toolkit_command $layoutframe "vpp 8.6x7.8 m1-m2 l1 shield" \
Tim Edwardse4b45352022-01-01 11:53:31 -0500203 "magic::gencell sky130::sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_shieldl1" pdk2
Tim Edwardsc6202ef2020-09-20 17:16:33 -0400204 magic::add_toolkit_command $layoutframe "vpp 4.4x4.6 m1-m2 l1 shield" \
Tim Edwardse4b45352022-01-01 11:53:31 -0500205 "magic::gencell sky130::sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_shieldl1" pdk2
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400206
Tim Edwards708a9422021-03-09 22:07:22 -0500207 # Additional DRC style for routing only---add this to the DRC menu
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400208 ${layoutframe}.titlebar.mbuttons.drc.toolmenu add command -label "DRC Routing" -command {drc style drc(routing)}
209
Tim Edwards708a9422021-03-09 22:07:22 -0500210 # Add SPICE import function to File menu
211 ${layoutframe}.titlebar.mbuttons.file.toolmenu insert 4 command -label "Import SPICE" -command {sky130::importspice}
212 ${layoutframe}.titlebar.mbuttons.file.toolmenu insert 4 separator
213
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400214 # Add command entry window by default if enabled
215 if {[info exists Opts(cmdentry)]} {
216 set Winopts(${framename},cmdentry) $Opts(cmdentry)
217 } else {
218 set Winopts(${framename},cmdentry) 0
219 }
220 if {$Winopts(${framename},cmdentry) == 1} {
221 addcommandentry $framename
222 }
223}
224
225#----------------------------------------------------------------
Tim Edwards708a9422021-03-09 22:07:22 -0500226# Menu callback function to read a SPICE netlist and generate an
227# initial layout using the SKYWATER TECHNAME gencells.
228#----------------------------------------------------------------
229
230proc sky130::importspice {} {
231 global CAD_ROOT
232
233 set Layoutfilename [ tk_getOpenFile -filetypes \
234 {{SPICE {.spice .spc .spi .ckt .cir .sp \
235 {.spice .spc .spi .ckt .cir .sp}}} {"All files" {*}}}]
236 if {$Layoutfilename != ""} {
237 magic::netlist_to_layout $Layoutfilename sky130
238 }
239}
240
241#----------------------------------------------------------------
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400242
Tim Edwards0ee0f182020-11-21 16:15:07 -0500243proc sky130::mcon_draw {{dir default}} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400244 set w [magic::i2u [box width]]
245 set h [magic::i2u [box height]]
246 if {$w < 0.17} {
247 puts stderr "Mcon width must be at least 0.17um"
248 return
249 }
250 if {$h < 0.17} {
251 puts stderr "Mcon height must be at least 0.17um"
252 return
253 }
Tim Edwards8ebc7742020-11-22 11:41:28 -0500254 suspendall
Tim Edwards0b1a8732020-12-30 15:15:08 -0500255 paint mcon
Tim Edwards0ee0f182020-11-21 16:15:07 -0500256 pushbox
257 if {($w < $h) || ($dir == "vert")} {
258 box grow e 0.03um
259 box grow w 0.03um
260 box grow n 0.06um
261 box grow s 0.06um
262 paint m1
263 } else {
264 box grow n 0.03um
265 box grow s 0.03um
266 box grow e 0.06um
267 box grow w 0.06um
268 paint m1
269 }
270 popbox
271 resumeall
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400272}
273
274proc sky130::via1_draw {} {
275 set w [magic::i2u [box width]]
276 set h [magic::i2u [box height]]
277 if {$w < 0.26} {
278 puts stderr "Via1 width must be at least 0.26um"
279 return
280 }
281 if {$h < 0.26} {
282 puts stderr "Via1 height must be at least 0.26um"
283 return
284 }
Tim Edwards8ebc7742020-11-22 11:41:28 -0500285 suspendall
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400286 paint via1
287 box grow n 0.05um
288 box grow s 0.05um
289 paint m2
290 box grow n -0.05um
291 box grow s -0.05um
292 box grow e 0.05um
293 box grow w 0.05um
294 paint m1
295 box grow e -0.05um
296 box grow w -0.05um
Tim Edwards0ee0f182020-11-21 16:15:07 -0500297 resumeall
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400298}
299
300proc sky130::via2_draw {} {
301 set w [magic::i2u [box width]]
302 set h [magic::i2u [box height]]
303 if {$w < 0.28} {
304 puts stderr "Via2 width must be at least 0.28um"
305 return
306 }
307 if {$h < 0.28} {
308 puts stderr "Via2 height must be at least 0.28um"
309 return
310 }
Tim Edwards8ebc7742020-11-22 11:41:28 -0500311 suspendall
Tim Edwardsb427e3b2020-11-22 15:28:54 -0500312 pushbox
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400313 paint via2
314 box grow n 0.05um
315 box grow s 0.05um
316 paint m2
Tim Edwardsb427e3b2020-11-22 15:28:54 -0500317 popbox
318 pushbox
319 box grow n 0.025um
320 box grow s 0.025um
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400321 box grow e 0.05um
322 box grow w 0.05um
323 paint m3
Tim Edwardsb427e3b2020-11-22 15:28:54 -0500324 popbox
Tim Edwards0ee0f182020-11-21 16:15:07 -0500325 resumeall
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400326}
327
328#ifdef METAL5
329proc sky130::via3_draw {} {
330 set w [magic::i2u [box width]]
331 set h [magic::i2u [box height]]
332 if {$w < 0.32} {
333 puts stderr "Via3 width must be at least 0.32um"
334 return
335 }
336 if {$h < 0.32} {
337 puts stderr "Via3 height must be at least 0.32um"
338 return
339 }
Tim Edwards8ebc7742020-11-22 11:41:28 -0500340 suspendall
Tim Edwardsb427e3b2020-11-22 15:28:54 -0500341 pushbox
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400342 paint via3
Tim Edwardsb427e3b2020-11-22 15:28:54 -0500343 box grow n 0.005um
344 box grow s 0.005um
345 box grow e 0.005um
346 box grow w 0.005um
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400347 paint m4
Tim Edwardsb427e3b2020-11-22 15:28:54 -0500348 popbox
349 pushbox
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400350 box grow e 0.05um
351 box grow w 0.05um
352 paint m3
Tim Edwardsb427e3b2020-11-22 15:28:54 -0500353 popbox
Tim Edwards0ee0f182020-11-21 16:15:07 -0500354 resumeall
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400355}
356
357proc sky130::via4_draw {} {
358 set w [magic::i2u [box width]]
359 set h [magic::i2u [box height]]
360 if {$w < 1.18} {
361 puts stderr "Via3 width must be at least 1.18um"
362 return
363 }
364 if {$h < 1.18} {
365 puts stderr "Via3 height must be at least 1.18um"
366 return
367 }
Tim Edwards8ebc7742020-11-22 11:41:28 -0500368 suspendall
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400369 paint via4
Tim Edwardsb427e3b2020-11-22 15:28:54 -0500370 pushbox
371 box grow n 0.12um
372 box grow s 0.12um
373 box grow e 0.12um
374 box grow w 0.12um
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400375 paint m5
Tim Edwardsb427e3b2020-11-22 15:28:54 -0500376 popbox
Tim Edwards0ee0f182020-11-21 16:15:07 -0500377 resumeall
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400378}
379#endif (METAL5)
380
381proc sky130::subconn_draw {} {
382 set w [magic::i2u [box width]]
383 set h [magic::i2u [box height]]
384 if {$w < 0.17} {
385 puts stderr "Substrate tap width must be at least 0.17um"
386 return
387 }
388 if {$h < 0.17} {
389 puts stderr "Substrate tap height must be at least 0.17um"
390 return
391 }
Tim Edwards8ebc7742020-11-22 11:41:28 -0500392 suspendall
Tim Edwardsb427e3b2020-11-22 15:28:54 -0500393 paint psc
394 pushbox
395 if {$w > $h} {
396 box grow e 0.08um
397 box grow w 0.08um
398 paint li
399 box grow e 0.04um
400 box grow w 0.04um
401 } else {
402 box grow n 0.08um
403 box grow s 0.08um
404 paint li
405 box grow n 0.04um
406 box grow s 0.04um
407 }
408 paint psd
409 popbox
Tim Edwards0ee0f182020-11-21 16:15:07 -0500410 resumeall
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400411}
412
413#----------------------------------------------------------------
414
415proc sky130::mvsubconn_draw {} {
416 set w [magic::i2u [box width]]
417 set h [magic::i2u [box height]]
418 if {$w < 0.17} {
419 puts stderr "Substrate tap width must be at least 0.17um"
420 return
421 }
422 if {$h < 0.17} {
423 puts stderr "Substrate tap height must be at least 0.17um"
424 return
425 }
Tim Edwards8ebc7742020-11-22 11:41:28 -0500426 suspendall
Tim Edwardsb427e3b2020-11-22 15:28:54 -0500427 paint mvpsc
428 pushbox
429 if {$w > $h} {
430 box grow e 0.08um
431 box grow w 0.08um
432 paint li
433 box grow e 0.04um
434 box grow w 0.04um
435 } else {
436 box grow n 0.08um
437 box grow s 0.08um
438 paint li
439 box grow n 0.04um
440 box grow s 0.04um
441 }
442 paint mvpsd
443 popbox
Tim Edwards0ee0f182020-11-21 16:15:07 -0500444 resumeall
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400445}
446
447#----------------------------------------------------------------
448
449proc sky130::deep_nwell_draw {} {
450 set w [magic::i2u [box width]]
451 set h [magic::i2u [box height]]
452 if {$w < 3.0} {
453 puts stderr "Deep-nwell region width must be at least 3.0um"
454 return
455 }
456 if {$h < 3.0} {
457 puts stderr "Deep-nwell region height must be at least 3.0um"
458 return
459 }
460 suspendall
461 tech unlock *
462 paint dnwell
463 pushbox
464 pushbox
465 box grow c 0.4um
466 paint nwell
467 box grow c -1.43um
468 erase nwell
469 popbox
470 box grow c 0.03um
471
472 pushbox
473 box width 0
474 box grow c 0.085um
475 paint li
476 pushbox
477 box grow n -0.3um
478 box grow s -0.3um
479 paint nsc
480 popbox
481 box grow c 0.1um
482 paint nsd
483 popbox
484
485 pushbox
486 box height 0
487 box grow c 0.085um
488 paint li
489 pushbox
490 box grow e -0.3um
491 box grow w -0.3um
492 paint nsc
493 popbox
494 box grow c 0.1um
495 paint nsd
496 popbox
497
498 pushbox
499 box move n [box height]i
500 box height 0
501 box grow c 0.085um
502 paint li
503 pushbox
504 box grow e -0.3um
505 box grow w -0.3um
506 paint nsc
507 popbox
508 box grow c 0.1um
509 paint nsd
510 popbox
511
512 pushbox
513 box move e [box width]i
514 box width 0
515 box grow c 0.085um
516 paint li
517 pushbox
518 box grow n -0.3um
519 box grow s -0.3um
520 paint nsc
521 box grow c 0.1um
522 paint nsd
523 popbox
524
525 popbox
526 tech revert
527 resumeall
528}
529
530#----------------------------------------------------------------
531
532proc sky130::res_recalc {field parameters} {
533 set snake 0
534 set sterm 0.0
535 set caplen 0
536 # Set a local variable for each parameter (e.g., $l, $w, etc.)
537 foreach key [dict keys $parameters] {
538 set $key [dict get $parameters $key]
539 }
540 set val [magic::spice2float $val]
541 set l [magic::spice2float $l]
542 set w [magic::spice2float $w]
543
544 if {$snake == 0} {
545 # Straight resistor calculation
546 switch $field {
547 val { set l [expr ($val * ($w - $dw) - (2 * $term)) / $rho]
548 set w [expr ((2 * $term + $l * $rho) / $val) + $dw]
549 }
550 w { set val [expr (2 * $term + $l * $rho) / ($w - $dw)]
551 set l [expr ($val * ($w - $dw) - (2 * $term)) / $rho]
552 }
553 l { set val [expr (2 * $term + $l * $rho) / ($w - $dw)]
554 set w [expr ((2 * $term + $l * $rho) / $val) + $dw]
555 }
556 }
557 } else {
558 set term [expr $term + $sterm]
559 # Snake resistor calculation
560 switch $field {
561 val { set l [expr (($val - $rho * ($nx - 1)) * ($w - $dw) \
562 - (2 * $term) - ($rho * $caplen * ($nx - 1))) \
563 / ($rho * $nx)]
564
565 set w [expr ((2 * $term + $l * $rho * $nx \
566 + $caplen * $rho * ($nx - 1)) \
567 / ($val - $rho * ($nx - 1))) + $dw]
568 }
569 w { set val [expr $rho * ($nx - 1) + ((2 * $term) \
570 + ($rho * $l * $nx) + ($rho * $caplen * ($nx - 1))) \
571 / ($w - $dw)]
572
573 set l [expr (($val - $rho * ($nx - 1)) * ($w - $dw) \
574 - (2 * $term) - ($rho * $caplen * ($nx - 1))) \
575 / ($rho * $nx)]
576 }
577 l { set val [expr $rho * ($nx - 1) + ((2 * $term) \
578 + ($rho * $l * $nx) + ($rho * $caplen * ($nx - 1))) \
579 / ($w - $dw)]
580
581 set w [expr ((2 * $term + $l * $rho * $nx \
582 + $caplen * $rho * ($nx - 1)) \
583 / ($val - $rho * ($nx - 1))) + $dw]
584 }
585 }
586 }
587
588 set val [magic::3digitpastdecimal $val]
589 set w [magic::3digitpastdecimal $w]
590 set l [magic::3digitpastdecimal $l]
591
592 dict set parameters val $val
593 dict set parameters w $w
594 dict set parameters l $l
595
596 return $parameters
597}
598
599#----------------------------------------------------------------
600# Drawn diode routines
601#----------------------------------------------------------------
602
603proc sky130::diode_recalc {field parameters} {
604 # Set a local variable for each parameter (e.g., $l, $w, etc.)
605 foreach key [dict keys $parameters] {
606 set $key [dict get $parameters $key]
607 }
608 switch $field {
609 area { puts stdout "area changed" }
610 peri { puts stdout "perimeter changed" }
611 w { puts stdout "width changed" }
612 l { puts stdout "length changed" }
613 }
614 dict set parameters area $area
615 dict set parameters peri $peri
616 dict set parameters w $w
617 dict set parameters l $l
618}
619
620#----------------------------------------------------------------
621# diode: Conversion from SPICE netlist parameters to toolkit
622#----------------------------------------------------------------
623
624proc sky130::diode_convert {parameters} {
625 set pdkparams [dict create]
626 dict for {key value} $parameters {
627 switch -nocase $key {
628 l -
629 w -
630 peri {
631 # Length, width, and perimeter are converted to units of microns
632 set value [magic::spice2float $value]
633 # set value [expr $value * 1e6]
634 set value [magic::3digitpastdecimal $value]
635 dict set pdkparams [string tolower $key] $value
636 }
637 area {
638 # area also converted to units of microns
639 set value [magic::spice2float $value]
640 # set value [expr $value * 1e12]
641 set value [magic::3digitpastdecimal $value]
642 dict set pdkparams [string tolower $key] $value
643 }
644 m {
645 # Convert m to ny
646 dict set pdkparams ny $value
647 }
648 }
649 }
650 return $pdkparams
651}
652
653#----------------------------------------------------------------
654# diode: Interactively specifies the fixed layout parameters
655#----------------------------------------------------------------
656
657proc sky130::diode_dialog {device parameters} {
658 # Editable fields: w, l, area, perim, nx, ny
659
660 magic::add_entry area "Area (um^2)" $parameters
661 magic::add_entry peri "Perimeter (um)" $parameters
662 sky130::compute_aptot $parameters
663 magic::add_message atot "Total area (um^2)" $parameters
664 magic::add_message ptot "Total perimeter (um)" $parameters
665 magic::add_entry l "Length (um)" $parameters
666 magic::add_entry w "Width (um)" $parameters
667 magic::add_entry nx "X Repeat" $parameters
668 magic::add_entry ny "Y Repeat" $parameters
669
670 if {[dict exists $parameters compatible]} {
671 set sellist [dict get $parameters compatible]
672 magic::add_selectlist gencell "Device type" $sellist $parameters $device
673 }
674
675 if {[dict exists $parameters doverlap]} {
676 magic::add_checkbox doverlap "Overlap at end contact" $parameters
677 }
678 if {[dict exists $parameters elc]} {
679 magic::add_checkbox elc "Add left end contact" $parameters
680 }
681 if {[dict exists $parameters erc]} {
682 magic::add_checkbox erc "Add right end contact" $parameters
683 }
684 if {[dict exists $parameters etc]} {
685 magic::add_checkbox etc "Add top end contact" $parameters
686 }
687 if {[dict exists $parameters ebc]} {
688 magic::add_checkbox ebc "Add bottom end contact" $parameters
689 }
690
691 if {[dict exists $parameters guard]} {
692 magic::add_checkbox full_metal "Full metal guard ring" $parameters
693 }
694 if {[dict exists $parameters glc]} {
695 magic::add_checkbox glc "Add left guard ring contact" $parameters
696 }
697 if {[dict exists $parameters grc]} {
698 magic::add_checkbox grc "Add right guard ring contact" $parameters
699 }
700 if {[dict exists $parameters gtc]} {
701 magic::add_checkbox gtc "Add top guard ring contact" $parameters
702 }
703 if {[dict exists $parameters gbc]} {
704 magic::add_checkbox gbc "Add bottom guard ring contact" $parameters
705 }
Tim Edwards0ee0f182020-11-21 16:15:07 -0500706 if {[dict exists $parameters viagb]} {
707 magic::add_entry viagb "Bottom guard ring via coverage \[+/-\](%)" $parameters
708 }
709 if {[dict exists $parameters viagt]} {
710 magic::add_entry viagt "Top guard ring via coverage \[+/-\](%)" $parameters
711 }
712 if {[dict exists $parameters viagr]} {
713 magic::add_entry viagr "Right guard ring via coverage \[+/-\](%)" $parameters
714 }
715 if {[dict exists $parameters viagl]} {
716 magic::add_entry viagl "Left guard ring via coverage \[+/-\](%)" $parameters
717 }
718
719 if {[dict exists $parameters vias]} {
720 magic::add_checkbox vias "Add vias over contacts" $parameters
721 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400722
723 magic::add_dependency sky130::diode_recalc $device sky130 l w area peri
724
725 # magic::add_checkbox dummy "Add dummy" $parameters
726}
727
728#----------------------------------------------------------------
729# Diode total area and perimeter computation
730#----------------------------------------------------------------
731
732proc sky130::compute_aptot {parameters} {
733 foreach key [dict keys $parameters] {
734 set $key [dict get $parameters $key]
735 }
736 set area [magic::spice2float $area]
737 set area [magic::3digitpastdecimal $area]
738 set peri [magic::spice2float $peri]
739 set peri [magic::3digitpastdecimal $peri]
740
741 # Compute total area
742 catch {set magic::atot_val [expr ($area * $nx * $ny)]}
743 # Compute total perimeter
744 catch {set magic::ptot_val [expr ($peri * $nx * $ny)]}
745}
746
747#----------------------------------------------------------------
748# diode: Check device parameters for out-of-bounds values
749#----------------------------------------------------------------
750
751proc sky130::diode_check {parameters} {
752
Tim Edwards2b758912021-05-20 16:01:18 -0400753 set guard 0
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400754 # Set a local variable for each parameter (e.g., $l, $w, etc.)
755 foreach key [dict keys $parameters] {
756 set $key [dict get $parameters $key]
757 }
758
759 # Normalize distance units to microns
760 set l [magic::spice2float $l]
761 set l [magic::3digitpastdecimal $l]
762 set w [magic::spice2float $w]
763 set w [magic::3digitpastdecimal $w]
764
765 set area [magic::spice2float $area]
766 set area [magic::3digitpastdecimal $area]
767 set peri [magic::spice2float $peri]
768 set peri [magic::3digitpastdecimal $peri]
769
770 if {$l == 0} {
771 # Calculate L from W and area
772 set l [expr ($area / $w)]
773 dict set parameters l [magic::float2spice $l]
774 } elseif {$w == 0} {
775 # Calculate W from L and area
776 set w [expr ($area / $l)]
777 dict set parameters w [magic::float2spice $w]
778 }
779 if {$w < $wmin} {
780 puts stderr "Diode width must be >= $wmin"
781 dict set parameters w $wmin
782 }
783 if {$l < $lmin} {
784 puts stderr "Diode length must be >= $lmin"
785 dict set parameters l $lmin
786 }
Tim Edwards0ee0f182020-11-21 16:15:07 -0500787
788 # Check via coverage for syntax
789 if {$guard == 1} {
790 if {[catch {expr abs($viagb)}]} {
791 puts stderr "Guard ring bottom via coverage must be numeric!"
792 dict set parameters viagb 0
793 } elseif {[expr abs($viagb)] > 100} {
794 puts stderr "Guard ring bottom via coverage can't be more than 100%"
795 dict set parameters viagb 100
796 }
797 if {[catch {expr abs($viagt)}]} {
798 puts stderr "Guard ring top via coverage must be numeric!"
799 dict set parameters viagt 0
800 } elseif {[expr abs($viagt)] > 100} {
801 puts stderr "Guard ring top via coverage can't be more than 100%"
802 dict set parameters viagt 100
803 }
804 if {[catch {expr abs($viagr)}]} {
805 puts stderr "Guard ring right via coverage must be numeric!"
806 dict set parameters viagr 0
807 } elseif {[expr abs($viagr)] > 100} {
808 puts stderr "Guard ring right via coverage can't be more than 100%"
809 dict set parameters viagr 100
810 }
811 if {[catch {expr abs($viagl)}]} {
812 puts stderr "Guard ring left via coverage must be numeric!"
813 dict set parameters viagl 0
814 } elseif {[expr abs($viagl)] > 100} {
815 puts stderr "Guard ring left via coverage can't be more than 100%"
816 dict set parameters viagl 100
817 }
818 }
819
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400820 # Calculate area and perimeter from L and W
821 set area [expr ($l * $w)]
822 dict set parameters area [magic::float2spice $area]
823 set peri [expr (2 * ($l + $w))]
824 dict set parameters peri [magic::float2spice $peri]
825 sky130::compute_aptot $parameters
826
827 return $parameters
828}
829
830#------------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400831# NOTE: sky130_fd_pr__diode_pw2nd_05v5_lvt,
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400832# sky130_fd_pr__diode_pw2nd_05v5_nvt, sky130_fd_pr__diode_pd2nw_05v5_lvt,
833# and sky130_fd_pr__diode_pd2nw_11v0 are all considered parasitic diodes.
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400834# They may be generated by invoking the build procedure on the
835# command line. To enable them in the PDK, add them to the
836# appropriate compatible {} list.
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400837#------------------------------------------------------------------
838
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400839proc sky130::sky130_fd_pr__diode_pw2nd_05v5_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400840 return {w 0.45 l 0.45 area 0.2025 peri 1.8 \
841 nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
842 elc 1 erc 1 etc 1 ebc 1 doverlap 0 \
Tim Edwards27348db2020-10-28 22:49:29 -0400843 compatible {sky130_fd_pr__diode_pw2nd_05v5 sky130_fd_pr__diode_pw2nd_05v5_lvt \
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400844 sky130_fd_pr__diode_pw2nd_05v5_nvt sky130_fd_pr__diode_pw2nd_11v0} \
Tim Edwards0ee0f182020-11-21 16:15:07 -0500845 full_metal 1 vias 1 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400846}
847
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400848proc sky130::sky130_fd_pr__diode_pw2nd_05v5_lvt_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400849 return {w 0.45 l 0.45 area 0.2025 peri 1.8 \
850 nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
851 elc 1 erc 1 etc 1 ebc 1 doverlap 0 \
Tim Edwards27348db2020-10-28 22:49:29 -0400852 compatible {sky130_fd_pr__diode_pw2nd_05v5 sky130_fd_pr__diode_pw2nd_05v5_lvt \
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400853 sky130_fd_pr__diode_pw2nd_05v5_nvt sky130_fd_pr__diode_pw2nd_11v0} \
Tim Edwards0ee0f182020-11-21 16:15:07 -0500854 full_metal 1 vias 1 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400855}
856
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400857proc sky130::sky130_fd_pr__diode_pw2nd_05v5_nvt_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400858 return {w 0.45 l 0.45 area 0.2024 peri 1.8 \
859 nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
860 elc 1 erc 1 etc 1 ebc 1 doverlap 0 \
Tim Edwards27348db2020-10-28 22:49:29 -0400861 compatible {sky130_fd_pr__diode_pw2nd_05v5 sky130_fd_pr__diode_pw2nd_05v5_lvt \
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400862 sky130_fd_pr__diode_pw2nd_05v5_nvt sky130_fd_pr__diode_pw2nd_11v0} \
Tim Edwards0ee0f182020-11-21 16:15:07 -0500863 full_metal 1 vias 1 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400864}
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400865
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400866proc sky130::sky130_fd_pr__diode_pw2nd_11v0_defaults {} {
867 return {w 0.45 l 0.45 area 0.2024 peri 1.8 \
868 nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
869 elc 1 erc 1 etc 1 ebc 1 doverlap 0 \
870 compatible {sky130_fd_pr__diode_pw2nd_05v5 sky130_fd_pr__diode_pw2nd_05v5_lvt \
871 sky130_fd_pr__diode_pw2nd_05v5_nvt sky130_fd_pr__diode_pw2nd_11v0} \
Tim Edwards0ee0f182020-11-21 16:15:07 -0500872 full_metal 1 vias 1 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400873}
874
Tim Edwardsc2787e82021-11-17 15:27:23 -0500875proc sky130::sky130_fd_pr__photodiode_defaults {} {
876 return {nx 1 ny 1 deltax 0 deltay 0 xstep 8.0 ystep 8.0}
877}
878
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400879proc sky130::sky130_fd_pr__diode_pd2nw_05v5_defaults {} {
880 return {w 0.45 l 0.45 area 0.2025 peri 1.8 \
881 nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
882 elc 1 erc 1 etc 1 ebc 1 \
883 glc 1 grc 1 gtc 1 gbc 1 doverlap 0 \
884 compatible {sky130_fd_pr__diode_pd2nw_05v5 sky130_fd_pr__diode_pd2nw_05v5_lvt \
Tim Edwards0ee0f182020-11-21 16:15:07 -0500885 sky130_fd_pr__diode_pd2nw_05v5_hvt sky130_fd_pr__diode_pd2nw_11v0} \
886 full_metal 1 vias 1 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400887}
888
889proc sky130::sky130_fd_pr__diode_pd2nw_05v5_lvt_defaults {} {
890 return {w 0.45 l 0.45 area 0.2025 peri 1.8 \
891 nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
892 elc 1 erc 1 etc 1 ebc 1 \
893 glc 1 grc 1 gtc 1 gbc 1 doverlap 0 \
894 compatible {sky130_fd_pr__diode_pd2nw_05v5 sky130_fd_pr__diode_pd2nw_05v5_lvt \
895 sky130_fd_pr__diode_pd2nw_05v5_hvt sky130_fd_pr__diode_pd2nw_11v0} \
Tim Edwards0ee0f182020-11-21 16:15:07 -0500896 full_metal 1 vias 1 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400897}
898
899proc sky130::sky130_fd_pr__diode_pd2nw_05v5_hvt_defaults {} {
900 return {w 0.45 l 0.45 area 0.2025 peri 1.8 \
901 nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
902 elc 1 erc 1 etc 1 ebc 1 \
903 glc 1 grc 1 gtc 1 gbc 1 doverlap 0 \
904 compatible {sky130_fd_pr__diode_pd2nw_05v5 sky130_fd_pr__diode_pd2nw_05v5_lvt \
905 sky130_fd_pr__diode_pd2nw_05v5_hvt sky130_fd_pr__diode_pd2nw_11v0} \
Tim Edwards0ee0f182020-11-21 16:15:07 -0500906 full_metal 1 vias 1 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400907}
908
909
910proc sky130::sky130_fd_pr__diode_pd2nw_11v0_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400911 return {w 0.45 l 0.45 area 0.2024 peri 1.8 \
912 nx 1 ny 1 dummy 0 lmin 0.45 wmin 0.45 \
913 elc 1 erc 1 etc 1 ebc 1 \
914 glc 1 grc 1 gtc 1 gbc 1 doverlap 0 \
Tim Edwards27348db2020-10-28 22:49:29 -0400915 compatible {sky130_fd_pr__diode_pd2nw_05v5 sky130_fd_pr__diode_pd2nw_05v5_lvt \
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400916 sky130_fd_pr__diode_pd2nw_05v5_hvt sky130_fd_pr__diode_pd2nw_11v0} \
Tim Edwards0ee0f182020-11-21 16:15:07 -0500917 full_metal 1 vias 1 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400918}
919
920#----------------------------------------------------------------
921
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400922proc sky130::sky130_fd_pr__diode_pw2nd_05v5_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_05v5_lvt_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_pw2nd_05v5_nvt_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400931 return [sky130::diode_convert $parameters]
932}
933
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400934proc sky130::sky130_fd_pr__diode_pw2nd_11v0_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400935 return [sky130::diode_convert $parameters]
936}
937
Tim Edwardsc2787e82021-11-17 15:27:23 -0500938proc sky130::sky130_fd_pr__photodiode_convert {parameters} {
939 return [sky130::fixed_convert $parameters]
940}
941
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400942proc sky130::sky130_fd_pr__diode_pd2nw_05v5_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400943 return [sky130::diode_convert $parameters]
944}
945
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400946proc sky130::sky130_fd_pr__diode_pd2nw_05v5_lvt_convert {parameters} {
947 return [sky130::diode_convert $parameters]
948}
949
950proc sky130::sky130_fd_pr__diode_pd2nw_05v5_hvt_convert {parameters} {
951 return [sky130::diode_convert $parameters]
952}
953
954proc sky130::sky130_fd_pr__diode_pd2nw_11v0_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400955 return [sky130::diode_convert $parameters]
956}
957
958#----------------------------------------------------------------
959
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400960proc sky130::sky130_fd_pr__diode_pw2nd_05v5_dialog {parameters} {
Tim Edwards27348db2020-10-28 22:49:29 -0400961 sky130::diode_dialog sky130_fd_pr__diode_pw2nd_05v5 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400962}
963
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400964proc sky130::sky130_fd_pr__diode_pw2nd_05v5_lvt_dialog {parameters} {
965 sky130::diode_dialog sky130_fd_pr__diode_pw2nd_05v5_lvt $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400966}
967
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400968proc sky130::sky130_fd_pr__diode_pw2nd_05v5_nvt_dialog {parameters} {
969 sky130::diode_dialog sky130_fd_pr__diode_pw2nd_05v5_nvt $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400970}
971
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400972proc sky130::sky130_fd_pr__diode_pw2nd_11v0_dialog {parameters} {
973 sky130::diode_dialog sky130_fd_pr__diode_pw2nd_11v0 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400974}
975
Tim Edwardsc2787e82021-11-17 15:27:23 -0500976proc sky130::sky130_fd_pr__photodiode_dialog {parameters} {
977 sky130::fixed_dialog $parameters
978}
979
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400980proc sky130::sky130_fd_pr__diode_pd2nw_05v5_dialog {parameters} {
981 sky130::diode_dialog sky130_fd_pr__diode_pd2nw_05v5 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400982}
983
Tim Edwardsbe6f1202020-10-29 10:37:46 -0400984proc sky130::sky130_fd_pr__diode_pd2nw_05v5_lvt_dialog {parameters} {
985 sky130::diode_dialog sky130_fd_pr__diode_pd2nw_05v5_lvt $parameters
986}
987
988proc sky130::sky130_fd_pr__diode_pd2nw_05v5_hvt_dialog {parameters} {
989 sky130::diode_dialog sky130_fd_pr__diode_pd2nw_05v5_hvt $parameters
990}
991
992proc sky130::sky130_fd_pr__diode_pd2nw_11v0_dialog {parameters} {
993 sky130::diode_dialog sky130_fd_pr__diode_pd2nw_11v0 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400994}
995
996#----------------------------------------------------------------
997
Tim Edwardsd7289eb2020-09-10 21:48:31 -0400998proc sky130::sky130_fd_pr__diode_pw2nd_05v5_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -0400999 sky130::diode_check $parameters
1000}
1001
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001002proc sky130::sky130_fd_pr__diode_pw2nd_05v5_lvt_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001003 sky130::diode_check $parameters
1004}
1005
Tim Edwardsbe6f1202020-10-29 10:37:46 -04001006proc sky130::sky130_fd_pr__diode_pw2nd_05v5_nvt_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001007 sky130::diode_check $parameters
1008}
1009
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001010proc sky130::sky130_fd_pr__diode_pw2nd_11v0_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001011 sky130::diode_check $parameters
1012}
1013
Tim Edwardsc2787e82021-11-17 15:27:23 -05001014proc sky130::sky130_fd_pr__photodiode_check {parameters} {
1015 sky130::fixed_check $parameters
1016}
1017
Tim Edwardsbe6f1202020-10-29 10:37:46 -04001018proc sky130::sky130_fd_pr__diode_pd2nw_05v5_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001019 sky130::diode_check $parameters
1020}
1021
Tim Edwardsbe6f1202020-10-29 10:37:46 -04001022proc sky130::sky130_fd_pr__diode_pd2nw_05v5_lvt_check {parameters} {
1023 sky130::diode_check $parameters
1024}
1025
1026proc sky130::sky130_fd_pr__diode_pd2nw_05v5_hvt_check {parameters} {
1027 sky130::diode_check $parameters
1028}
1029
1030proc sky130::sky130_fd_pr__diode_pd2nw_11v0_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001031 sky130::diode_check $parameters
1032}
1033
1034#----------------------------------------------------------------
1035# Diode: Draw a single device
1036#----------------------------------------------------------------
1037
1038proc sky130::diode_device {parameters} {
1039 # Epsilon for avoiding round-off errors
1040 set eps 0.0005
1041
1042 # Set local default values if they are not in parameters
1043 set dev_surround 0
1044 set dev_sub_type ""
1045
1046 # Set a local variable for each parameter (e.g., $l, $w, etc.)
1047 foreach key [dict keys $parameters] {
1048 set $key [dict get $parameters $key]
1049 }
1050
1051 # If there is no end_sub_surround, set it to sub_surround
1052 if {![dict exists $parameters end_sub_surround]} {
1053 set end_sub_surround $sub_surround
1054 }
1055
1056 # Draw the device
1057 pushbox
1058 box size 0 0
1059
1060 set hw [/ $w 2.0]
1061 set hl [/ $l 2.0]
1062
1063 # Calculate ring size (measured to contact center)
1064 set gx [+ $w [* 2.0 [+ $dev_spacing $dev_surround]] $contact_size]
1065 set gy [+ $l [* 2.0 [+ $dev_spacing $dev_surround]] $contact_size]
1066
1067 # Draw the ring first, because diode may occupy well/substrate plane
1068 set guardparams $parameters
1069 dict set guardparams plus_diff_type $end_type
1070 dict set guardparams plus_contact_type $end_contact_type
1071 dict set guardparams diff_surround $end_surround
1072 dict set guardparams sub_type $end_sub_type
1073 dict set guardparams sub_surround $sub_surround
1074 dict set guardparams guard_sub_surround $end_sub_surround
1075 dict set guardparams glc $elc
1076 dict set guardparams grc $erc
1077 dict set guardparams gtc $etc
1078 dict set guardparams gbc $ebc
1079 set cext [sky130::guard_ring $gx $gy $guardparams]
1080
1081 pushbox
1082 box grow n ${hl}um
1083 box grow s ${hl}um
1084 box grow e ${hw}um
1085 box grow w ${hw}um
1086 paint ${dev_type}
1087 set cext [sky130::unionbox $cext [sky130::getbox]]
1088
1089 if {$dev_sub_type != ""} {
1090 box grow n ${sub_surround}um
1091 box grow s ${sub_surround}um
1092 box grow e ${sub_surround}um
1093 box grow w ${sub_surround}um
1094 paint ${dev_sub_type}
1095 }
1096 popbox
1097
1098 if {${w} < ${l}} {
1099 set orient vert
1100 } else {
1101 set orient horz
1102 }
1103
1104 # Reduce width by surround amount
1105 set w [- $w [* ${dev_surround} 2.0]]
1106 set l [- $l [* ${dev_surround} 2.0]]
1107
Tim Edwards0ee0f182020-11-21 16:15:07 -05001108 # Draw via over contact first
1109 if {$vias != 0} {
1110 pushbox
1111 set ch $l
1112 if {$ch < $via_size} {set ch $via_size}
1113 set cw $w
1114 if {$cw < $via_size} {set cw $via_size}
1115 box grow n [/ $ch 2]um
1116 box grow s [/ $ch 2]um
1117 box grow w [/ $cw 2]um
1118 box grow e [/ $cw 2]um
1119 sky130::mcon_draw
1120 popbox
1121 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001122 set cext [sky130::unionbox $cext [sky130::draw_contact ${w} ${l} \
1123 ${dev_surround} ${metal_surround} ${contact_size} \
1124 ${dev_type} ${dev_contact_type} li ${orient}]]
1125
1126 popbox
1127 return $cext
1128}
1129
1130#----------------------------------------------------------------
1131# Diode: Draw the tiled device
1132#----------------------------------------------------------------
1133
1134proc sky130::diode_draw {parameters} {
1135 tech unlock *
1136
1137 # Set defaults if they are not in parameters
1138 set doverlap 0 ;# overlap diodes at contacts
1139 set guard 0 ;# draw a guard ring
1140 set prohibit_overlap false ;# don't prohibit overlaps
1141
1142 # Set a local variable for each parameter (e.g., $l, $w, etc.)
1143 foreach key [dict keys $parameters] {
1144 set $key [dict get $parameters $key]
1145 }
1146
1147 # Normalize distance units to microns
1148 set w [magic::spice2float $w]
1149 set l [magic::spice2float $l]
1150
1151 pushbox
1152 box values 0 0 0 0
1153
1154 # Determine the base device dimensions by drawing one device
1155 # while all layers are locked (nothing drawn). This allows the
1156 # base drawing routine to do complicated geometry without having
1157 # to duplicate it here with calculations.
1158
1159 tech lock *
1160 set bbox [sky130::diode_device $parameters]
1161 # puts stdout "Diagnostic: Device bounding box e $bbox (um)"
1162 tech unlock *
1163
1164 set fw [- [lindex $bbox 2] [lindex $bbox 0]]
1165 set fh [- [lindex $bbox 3] [lindex $bbox 1]]
1166 set lw [+ [lindex $bbox 2] [lindex $bbox 0]]
1167 set lh [+ [lindex $bbox 3] [lindex $bbox 1]]
1168
1169 # If prohibit_overlap is true, then end overlapping is prohibited when
1170 # nx or ny is > 1 to prevent DRC errors (typically from well spacing rule)
1171 if {$prohibit_overlap == true} {
1172 if {($nx > 1) || ($ny > 1)} {
1173 set doverlap 0
1174 }
1175 }
1176
1177 # Determine tile width and height (depends on overlap)
1178
1179 if {$doverlap == 0} {
1180 set dx [+ $fw $end_spacing]
1181 set dy [+ $fh $end_spacing]
1182 } else {
1183 # overlap contact
1184 set dx [- $fw [+ [* 2.0 $sub_surround] [* 2.0 $end_surround] $contact_size]]
1185 set dy [- $fh [+ [* 2.0 $sub_surround] [* 2.0 $end_surround] $contact_size]]
1186 }
1187
1188 # Determine core width and height
1189 set corex [+ [* [- $nx 1] $dx] $fw]
1190 set corey [+ [* [- $ny 1] $dy] $fh]
1191 set corellx [/ [+ [- $corex $fw] $lw] 2.0]
1192 set corelly [/ [+ [- $corey $fh] $lh] 2.0]
1193
1194 if {$guard != 0} {
1195 # Calculate guard ring size (measured to contact center)
1196 set gx [+ $corex [* 2.0 [+ $diff_spacing $diff_surround]] $contact_size]
1197 set gy [+ $corey [* 2.0 [+ $diff_spacing $diff_surround]] $contact_size]
1198
1199 # Draw the guard ring first, because diode may occupy well/substrate plane
1200 sky130::guard_ring $gx $gy $parameters
1201 }
1202
1203 pushbox
1204 box move w ${corellx}um
1205 box move s ${corelly}um
1206 if {($nx > 1) || ($ny > 1)} {
1207 pushbox
1208 set hfw [/ $fw 2.0]
1209 set hfh [/ $fh 2.0]
1210 box move w ${hfw}um
1211 box move s ${hfh}um
1212 box size ${corex}um ${corey}um
1213 paint $end_sub_type
1214 popbox
1215 }
1216 for {set xp 0} {$xp < $nx} {incr xp} {
1217 pushbox
1218 for {set yp 0} {$yp < $ny} {incr yp} {
1219 sky130::diode_device $parameters
1220 box move n ${dy}um
1221 }
1222 popbox
1223 box move e ${dx}um
1224 }
1225 popbox
1226 popbox
1227
1228 tech revert
1229}
1230
1231#----------------------------------------------------------------
Tim Edwardsc2787e82021-11-17 15:27:23 -05001232# Photodiode: Draw a single device
1233#----------------------------------------------------------------
1234
1235proc sky130::photodiode_device {parameters} {
1236
1237 # Set a local variable for each parameter (e.g., $l, $w, etc.)
1238 foreach key [dict keys $parameters] {
1239 set $key [dict get $parameters $key]
1240 }
1241
1242 # Draw the device
1243 pushbox
1244 box size 0 0
1245
1246 # Device has ntap fixed width of 0.41 x 0.41
1247 # Surrounded by nwell 0.84 x 0.84
1248 # Surrounded by deep nwell 3.0 x 3.0
1249
1250 pushbox
1251 box grow c 0.205um
1252 paint nsd
1253 popbox
1254 pushbox
1255 box grow c 0.42um
1256 paint nwell
1257 popbox
1258 pushbox
1259 box grow c 1.5um
1260 paint photo
1261
1262 set cext [sky130::getbox]
1263
1264 popbox
1265
1266 # Only enough space for one contact
1267 set w ${contact_size}
1268 set l ${contact_size}
1269
1270 set cext [sky130::unionbox $cext [sky130::draw_contact ${w} ${l} \
1271 0 ${metal_surround} ${contact_size} \
1272 nsd nsc li horz]]
1273
1274 popbox
1275 return $cext
1276}
1277
1278#----------------------------------------------------------------
1279
1280proc sky130::photodiode_draw {parameters} {
1281
1282 # Set a local variable for each parameter (e.g., $l, $w, etc.)
1283 foreach key [dict keys $parameters] {
1284 set $key [dict get $parameters $key]
1285 }
1286
1287 pushbox
1288 box values 0 0 0 0
1289
1290 # Determine the base device dimensions by drawing one device
1291 # while all layers are locked (nothing drawn). This allows the
1292 # base drawing routine to do complicated geometry without having
1293 # to duplicate it here with calculations.
1294
1295 tech lock *
1296 set bbox [sky130::photodiode_device $parameters]
1297 # puts stdout "Diagnostic: Device bounding box e $bbox (um)"
1298 tech unlock *
1299
1300 set fw [- [lindex $bbox 2] [lindex $bbox 0]]
1301 set fh [- [lindex $bbox 3] [lindex $bbox 1]]
1302 set lw [+ [lindex $bbox 2] [lindex $bbox 0]]
1303 set lh [+ [lindex $bbox 3] [lindex $bbox 1]]
1304
1305 # Determine tile width and height
1306
1307 set dx [+ $fw $end_spacing]
1308 set dy [+ $fh $end_spacing]
1309
1310 # Determine core width and height
1311 set corex [+ [* [- $nx 1] $dx] $fw]
1312 set corey [+ [* [- $ny 1] $dy] $fh]
1313 set corellx [/ [+ [- $corex $fw] $lw] 2.0]
1314 set corelly [/ [+ [- $corey $fh] $lh] 2.0]
1315
1316 # Calculate guard ring size (measured to contact center)
1317 # Spacing between photodiode (deep nwell) and deep nwell (other) is 5.3um
1318 set gx [+ $corex 15.965]
1319 set gy [+ $corey 15.965]
1320
1321 pushbox
1322
1323 # The deep nwell is offset 0.315 from the nwell ring center to get the
1324 # right overlap. The deep nwell ring has a minimum width of 3um.
1325 set hgx [/ $gx 2.0]
1326 set hgy [/ $gy 2.0]
1327 set dwx [+ $hgx 0.315]
1328 set dwy [+ $hgy 0.315]
1329 box grow e ${dwx}um
1330 box grow w ${dwx}um
1331 box grow n ${dwy}um
1332 box grow s ${dwy}um
1333 paint dnwell
1334 box grow e -3.0um
1335 box grow w -3.0um
1336 box grow n -3.0um
1337 box grow s -3.0um
1338 erase dnwell
1339
1340 popbox
1341
1342 # Draw the guard ring first. 0.63 is the amount nwell surrounds contact;
1343 # 0.63 * 2 + 0.17 = total nwell width 1.43um, needed to cover dnwell edge.
1344 set newdict [dict create \
1345 sub_type space \
1346 guard_sub_type nwell \
1347 guard_sub_surround 0.63 \
1348 plus_diff_type nsd \
1349 plus_contact_type nsc \
1350 ]
1351 set guarddict [dict merge $parameters $newdict]
1352 sky130::guard_ring $gx $gy $guarddict
1353
1354 # Draw outside P-ring and generated the 2nd ring
1355 set gx [+ $gx [* 2.0 [+ 0.56 $diff_spacing $diff_surround]] $contact_size]
1356 set gy [+ $gy [* 2.0 [+ 0.56 $diff_spacing $diff_surround]] $contact_size]
1357 sky130::guard_ring $gx $gy $parameters
1358
1359 pushbox
1360 box move w ${corellx}um
1361 box move s ${corelly}um
1362
1363 for {set xp 0} {$xp < $nx} {incr xp} {
1364 pushbox
1365 for {set yp 0} {$yp < $ny} {incr yp} {
1366 sky130::photodiode_device $parameters
1367 box move n ${dy}um
1368 }
1369 popbox
1370 box move e ${dx}um
1371 }
1372 popbox
1373 popbox
1374
1375 tech revert
1376}
1377
1378#----------------------------------------------------------------
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001379
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001380proc sky130::sky130_fd_pr__diode_pw2nd_05v5_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001381
1382 # Set a local variable for each rule in ruleset
1383 foreach key [dict keys $sky130::ruleset] {
1384 set $key [dict get $sky130::ruleset $key]
1385 }
1386
1387 set newdict [dict create \
1388 dev_type ndiode \
1389 dev_contact_type ndic \
1390 end_type psd \
1391 end_contact_type psc \
1392 end_sub_type psub \
1393 dev_spacing ${diff_spacing} \
1394 dev_surround ${diff_surround} \
1395 end_spacing ${diff_spacing} \
1396 end_surround 0 \
1397 ]
1398 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1399 return [sky130::diode_draw $drawdict]
1400}
1401
1402#----------------------------------------------------------------
1403# NOTE: Use ppd instead of psd so that there is additional
1404# diffusion around the contact, allowing more space for the
Tim Edwardsbe6f1202020-10-29 10:37:46 -04001405# implant (likewise sky130_fd_pr__diode_pd2nw_05v5_lvt and
1406# sky130_fd_pr__diode_pd2nw_11v0).
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001407
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001408proc sky130::sky130_fd_pr__diode_pw2nd_05v5_lvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001409
1410 # Set a local variable for each rule in ruleset
1411 foreach key [dict keys $sky130::ruleset] {
1412 set $key [dict get $sky130::ruleset $key]
1413 }
1414
1415 set newdict [dict create \
1416 dev_type ndiodelvt \
1417 dev_contact_type ndilvtc \
1418 end_type ppd \
1419 end_contact_type psc \
1420 end_sub_type psub \
1421 dev_spacing ${diff_spacing} \
1422 dev_surround ${diff_surround} \
1423 end_spacing ${diff_spacing} \
1424 end_surround ${diff_surround} \
1425 ]
1426 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1427 return [sky130::diode_draw $drawdict]
1428}
1429
Tim Edwardsbe6f1202020-10-29 10:37:46 -04001430proc sky130::sky130_fd_pr__diode_pw2nd_05v5_nvt_draw {parameters} {
1431
1432 # Set a local variable for each rule in ruleset
1433 foreach key [dict keys $sky130::ruleset] {
1434 set $key [dict get $sky130::ruleset $key]
1435 }
1436
1437 set newdict [dict create \
1438 dev_type nndiode \
1439 dev_contact_type nndic \
1440 end_type mvpsd \
1441 end_contact_type mvpsc \
1442 end_sub_type psub \
1443 dev_spacing 0.37 \
1444 dev_surround ${diff_surround} \
1445 end_spacing 0.30 \
1446 end_surround ${diff_surround} \
1447 ]
1448 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1449 return [sky130::diode_draw $drawdict]
1450}
1451
1452proc sky130::sky130_fd_pr__diode_pw2nd_11v0_draw {parameters} {
1453
1454 # Set a local variable for each rule in ruleset
1455 foreach key [dict keys $sky130::ruleset] {
1456 set $key [dict get $sky130::ruleset $key]
1457 }
1458
1459 set newdict [dict create \
1460 dev_type mvndiode \
1461 dev_contact_type mvndic \
1462 end_type mvpsd \
1463 end_contact_type mvpsc \
1464 end_sub_type psub \
1465 diff_spacing 0.37 \
1466 dev_spacing 0.39 \
1467 dev_surround ${diff_surround} \
1468 end_spacing 0.36 \
1469 end_surround ${diff_surround} \
1470 ]
1471 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1472 return [sky130::diode_draw $drawdict]
1473}
1474
1475
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001476#----------------------------------------------------------------
1477
Tim Edwardsbe6f1202020-10-29 10:37:46 -04001478proc sky130::sky130_fd_pr__diode_pd2nw_05v5_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001479
1480 # Set a local variable for each rule in ruleset
1481 foreach key [dict keys $sky130::ruleset] {
1482 set $key [dict get $sky130::ruleset $key]
1483 }
1484
1485 set newdict [dict create \
1486 dev_type pdiode \
1487 guard 1 \
1488 dev_contact_type pdic \
1489 end_type nsd \
1490 end_contact_type nsc \
1491 end_sub_type nwell \
1492 plus_diff_type psd \
1493 plus_contact_type psc \
1494 sub_type psub \
1495 dev_spacing ${diff_spacing} \
1496 dev_surround ${diff_surround} \
1497 end_spacing ${diff_spacing} \
1498 end_surround 0 \
1499 ]
1500 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1501 return [sky130::diode_draw $drawdict]
1502}
1503
1504#----------------------------------------------------------------
1505
Tim Edwardsbe6f1202020-10-29 10:37:46 -04001506proc sky130::sky130_fd_pr__diode_pd2nw_05v5_lvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001507
1508 # Set a local variable for each rule in ruleset
1509 foreach key [dict keys $sky130::ruleset] {
1510 set $key [dict get $sky130::ruleset $key]
1511 }
1512
1513 set newdict [dict create \
1514 dev_type pdiodelvt \
1515 guard 1 \
1516 dev_contact_type pdilvtc \
1517 end_type nnd \
1518 end_contact_type nsc \
1519 end_sub_type nwell \
1520 plus_diff_type psd \
1521 plus_contact_type psc \
1522 sub_type psub \
1523 dev_spacing ${diff_spacing} \
1524 dev_surround ${diff_surround} \
1525 end_spacing ${diff_spacing} \
1526 end_surround ${diff_surround} \
1527 ]
1528 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1529 return [sky130::diode_draw $drawdict]
1530}
1531
1532#----------------------------------------------------------------
1533
Tim Edwardsbe6f1202020-10-29 10:37:46 -04001534proc sky130::sky130_fd_pr__diode_pd2nw_05v5_hvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001535
1536 # Set a local variable for each rule in ruleset
1537 foreach key [dict keys $sky130::ruleset] {
1538 set $key [dict get $sky130::ruleset $key]
1539 }
1540
1541 set newdict [dict create \
1542 dev_type pdiodehvt \
1543 guard 1 \
1544 dev_contact_type pdihvtc \
1545 end_type nnd \
1546 end_contact_type nsc \
1547 end_sub_type nwell \
1548 plus_diff_type psd \
1549 plus_contact_type psc \
1550 sub_type psub \
1551 dev_spacing ${diff_spacing} \
1552 dev_surround ${diff_surround} \
1553 end_spacing ${diff_spacing} \
1554 end_surround ${diff_surround} \
1555 ]
1556 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1557 return [sky130::diode_draw $drawdict]
1558}
1559
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001560
1561#----------------------------------------------------------------
1562
Tim Edwardsbe6f1202020-10-29 10:37:46 -04001563proc sky130::sky130_fd_pr__diode_pd2nw_11v0_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001564
1565 # Set a local variable for each rule in ruleset
1566 foreach key [dict keys $sky130::ruleset] {
1567 set $key [dict get $sky130::ruleset $key]
1568 }
1569
1570 set newdict [dict create \
1571 guard 1 \
1572 dev_type mvpdiode \
1573 dev_contact_type mvpdic \
1574 end_type mvnsd \
1575 end_contact_type mvnsc \
1576 end_sub_type nwell \
1577 plus_diff_type mvpsd \
1578 plus_contact_type mvpsc \
1579 sub_type psub \
1580 diff_spacing 0.58 \
1581 dev_spacing 0.37 \
1582 dev_surround ${diff_surround} \
1583 end_spacing 0.30 \
1584 end_sub_surround 0.33 \
1585 end_surround ${diff_surround} \
1586 ]
1587 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1588 return [sky130::diode_draw $drawdict]
1589}
1590
1591#----------------------------------------------------------------
Tim Edwardsc2787e82021-11-17 15:27:23 -05001592# The photodiode has its own drawing routine, so
1593#----------------------------------------------------------------
1594
1595proc sky130::sky130_fd_pr__photodiode_draw {parameters} {
1596 # Set a local variable for each rule in ruleset
1597 foreach key [dict keys $sky130::ruleset] {
1598 set $key [dict get $sky130::ruleset $key]
1599 }
1600
1601 set newdict [dict create \
1602 guard 1 \
1603 sub_type space \
1604 end_spacing 5.0 \
1605 end_surround 1.0 \
1606 sub_spacing 5.3 \
1607 guard_sub_type pwell \
1608 guard_sub_surround 0.18 \
1609 plus_diff_type psd \
1610 plus_contact_type psc \
1611 ]
1612 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
1613 return [sky130::photodiode_draw $drawdict]
1614}
1615
1616#----------------------------------------------------------------
Tim Edwards27348db2020-10-28 22:49:29 -04001617# Drawn capacitor routines
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001618# NOTE: Work in progress. These values need to be corrected.
1619#----------------------------------------------------------------
1620
1621#ifdef MIM
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001622proc sky130::sky130_fd_pr__cap_mim_m3_1_defaults {} {
Tim Edwards15463bc2021-05-12 21:33:31 -04001623 return {w 2.00 l 2.00 val 8.0 carea 2.00 cperi 0.19 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001624 nx 1 ny 1 dummy 0 square 0 lmin 2.00 wmin 2.00 \
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05001625 lmax 30.0 wmax 30.0 dc 0 bconnect 1 tconnect 1 \
1626 ccov 100}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001627}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001628proc sky130::sky130_fd_pr__cap_mim_m3_2_defaults {} {
Tim Edwards15463bc2021-05-12 21:33:31 -04001629 return {w 2.00 l 2.00 val 8.0 carea 2.00 cperi 0.19 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001630 nx 1 ny 1 dummy 0 square 0 lmin 2.00 wmin 2.00 \
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05001631 lmax 30.0 wmax 30.0 dc 0 bconnect 1 tconnect 1 \
1632 ccov 100}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001633}
1634#endif (MIM)
1635
1636
1637#----------------------------------------------------------------
1638# Recalculate capacitor values from GUI entries.
1639# Recomputes W/L and Value as long as 2 of them are present
1640# (To be completed)
1641#----------------------------------------------------------------
1642
1643proc sky130::cap_recalc {field parameters} {
1644 # Set a local variable for each parameter (e.g., $l, $w, etc.)
1645 foreach key [dict keys $parameters] {
1646 set $key [dict get $parameters $key]
1647 }
1648 switch $field {
1649 val { puts stdout "value changed" }
1650 w { puts stdout "width changed" }
1651 l { puts stdout "length changed" }
1652 }
1653 dict set parameters val $val
1654 dict set parameters w $w
1655 dict set parameters l $l
1656}
1657
1658#----------------------------------------------------------------
1659# Capacitor defaults:
1660#----------------------------------------------------------------
1661# w Width of drawn cap
1662# l Length of drawn cap
1663# nx Number of devices in X
1664# ny Number of devices in Y
1665# val Default cap value
1666# carea Area
1667# cperi Perimeter
1668# dummy Add dummy cap
1669# square Make square capacitor
1670#
1671# (not user-editable)
1672#
1673# wmin Minimum allowed width
1674# lmin Minimum allowed length
1675# dc Area to remove to calculated area
1676#----------------------------------------------------------------
1677
1678#----------------------------------------------------------------
1679# capacitor: Conversion from SPICE netlist parameters to toolkit
1680#----------------------------------------------------------------
1681
1682proc sky130::cap_convert {parameters} {
1683 set pdkparams [dict create]
1684 dict for {key value} $parameters {
1685 switch -nocase $key {
1686 l -
1687 w {
1688 # Length and width are converted to units of microns
1689 set value [magic::spice2float $value]
1690 # set value [expr $value * 1e6]
1691 set value [magic::3digitpastdecimal $value]
1692 dict set pdkparams [string tolower $key] $value
1693 }
1694 m {
1695 # Convert m to ny
1696 dict set pdkparams ny $value
1697 }
1698 }
1699 }
1700 return $pdkparams
1701}
1702
1703#ifdef MIM
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001704proc sky130::sky130_fd_pr__cap_mim_m3_1_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001705 return [cap_convert $parameters]
1706}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001707proc sky130::sky130_fd_pr__cap_mim_m3_2_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001708 return [cap_convert $parameters]
1709}
1710#endif (MIM)
1711
1712#----------------------------------------------------------------
1713# capacitor: Interactively specifies the fixed layout parameters
1714#----------------------------------------------------------------
1715
1716proc sky130::cap_dialog {device parameters} {
1717 # Editable fields: w, l, nx, ny, val
1718 # Checked fields: square, dummy
1719
1720 magic::add_entry val "Value (fF)" $parameters
1721 sky130::compute_ctot $parameters
1722 magic::add_message ctot "Total capacitance (pF)" $parameters
1723 magic::add_entry l "Length (um)" $parameters
1724 magic::add_entry w "Width (um)" $parameters
1725 magic::add_entry nx "X Repeat" $parameters
1726 magic::add_entry ny "Y Repeat" $parameters
1727
1728 if {[dict exists $parameters square]} {
1729 magic::add_checkbox square "Square capacitor" $parameters
1730 }
1731 if {[dict exists $parameters bconnect]} {
1732 magic::add_checkbox bconnect "Connect bottom plates in array" $parameters
1733 }
1734 if {[dict exists $parameters tconnect]} {
1735 magic::add_checkbox tconnect "Connect top plates in array" $parameters
1736 }
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05001737 if {[dict exists $parameters ccov]} {
1738 magic::add_entry ccov "Capacitor contact coverage \[+/-\](%)" $parameters
1739 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001740 if {[dict exists $parameters guard]} {
1741 magic::add_checkbox guard "Add guard ring" $parameters
1742 }
1743
1744 magic::add_dependency sky130::cap_recalc $device sky130 l w val
1745
1746 # magic::add_checkbox dummy "Add dummy" $parameters
1747}
1748
1749#ifdef MIM
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001750proc sky130::sky130_fd_pr__cap_mim_m3_1_dialog {parameters} {
1751 sky130::cap_dialog sky130_fd_pr__cap_mim_m3_1 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001752}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04001753proc sky130::sky130_fd_pr__cap_mim_m3_2_dialog {parameters} {
1754 sky130::cap_dialog sky130_fd_pr__cap_mim_m3_2 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001755}
1756#endif (MIM)
1757
1758#----------------------------------------------------------------
1759# Capacitor total capacitance computation
1760#----------------------------------------------------------------
1761
1762proc sky130::compute_ctot {parameters} {
1763 foreach key [dict keys $parameters] {
1764 set $key [dict get $parameters $key]
1765 }
1766 set val [magic::spice2float $val]
1767 set val [magic::3digitpastdecimal $val]
1768
1769 # Compute total capacitance (and convert fF to pF)
1770 catch {set magic::ctot_val [expr (0.001 * $val * $nx * $ny)]}
1771}
1772
1773#----------------------------------------------------------------
1774# Capacitor: Draw a single device
1775#----------------------------------------------------------------
1776
1777proc sky130::cap_device {parameters} {
1778 # Epsilon for avoiding round-off errors
1779 set eps 0.0005
1780
1781 # Set local default values if they are not in parameters
1782 set cap_surround 0
1783 set bot_surround 0
1784 set top_surround 0
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05001785 set end_spacing 0
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001786 set bconnect 0 ;# bottom plates are connected in array
1787 set cap_spacing 0 ;# cap spacing in array
1788 set top_metal_space 0 ;# top metal spacing (if larger than cap spacing)
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05001789 set top_metal_width 0 ;# top metal minimum width
1790 set contact_size 0 ;# cap contact minimum size
1791 set ccov 100 ;# amount of contact coverage
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001792
1793 # Set a local variable for each parameter (e.g., $l, $w, etc.)
1794 foreach key [dict keys $parameters] {
1795 set $key [dict get $parameters $key]
1796 }
1797
1798 if {![dict exists $parameters top_metal_space]} {
1799 set top_metal_space $metal_spacing
1800 }
1801
1802 # Draw the device
1803 pushbox
1804 box size 0 0
1805
1806 pushbox
1807 set hw [/ $w 2.0]
1808 set hl [/ $l 2.0]
1809 box grow e ${hw}um
1810 box grow w ${hw}um
1811 box grow n ${hl}um
1812 box grow s ${hl}um
1813 paint ${cap_type}
1814 pushbox
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05001815
1816 # Find contact width if ccov is other than 100
1817 set cmaxw [- $w [* $cap_surround 2]]
1818 set cw [* $cmaxw [/ [expr abs($ccov)] 100.0]]
1819 # Contact width must meet minimum
1820 if {$cw < $contact_size} {set cw $contact_size}
1821 if {$cw < $top_metal_width} {set cw $top_metal_width}
1822 # Difference between maximum contact width and actual contact width
1823 set cdif [- $cmaxw $cw]
1824
1825 # Reduce the box to the maximum contact area
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001826 box grow n -${cap_surround}um
1827 box grow s -${cap_surround}um
1828 box grow e -${cap_surround}um
1829 box grow w -${cap_surround}um
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05001830
1831 set anchor [string index $ccov 0]
1832 if {$anchor == "+"} {
1833 box grow e -${cdif}um
1834 } elseif {$anchor == "-"} {
1835 box grow w -${cdif}um
1836 } else {
1837 set cdif [/ ${cdif} 2]
1838 box grow w -${cdif}um
1839 box grow e -${cdif}um
1840 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001841 paint ${cap_contact_type}
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05001842
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001843 pushbox
1844 box grow n ${top_surround}um
1845 box grow s ${top_surround}um
1846 box grow e ${top_surround}um
1847 box grow w ${top_surround}um
1848 paint ${top_type}
1849 set cext [sky130::getbox]
1850 popbox
1851 popbox
1852 pushbox
1853 box grow n ${bot_surround}um
1854 box grow s ${bot_surround}um
1855 box grow e ${bot_surround}um
1856 box grow w ${bot_surround}um
1857
1858 paint ${bot_type}
1859 # Create boundary using properties
1860 property FIXED_BBOX [box values]
1861 set cext [sky130::unionbox $cext [sky130::getbox]]
1862
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05001863 # Calculate the distance from the top metal on the cap contact
1864 # to the top metal on the end contact.
1865 set top_met_sep [+ $end_spacing [- $cdif $top_surround]]
1866
1867 # Diagnostic!
1868 puts stdout "cdif = $cdif"
1869 puts stdout "top_met_sep = $top_met_sep"
1870
1871 # Increase end spacing if top metal spacing rule is not met
1872 set loc_end_spacing $end_spacing
1873 if {$top_met_sep < $top_metal_space} {
1874 set loc_end_spacing [+ $loc_end_spacing [- $top_metal_space $top_met_sep]]
1875 }
1876 # Diagnostic!
1877 puts stdout "loc_end_spacing = $loc_end_spacing"
1878
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001879 # Extend bottom metal under contact to right
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05001880 box grow e ${loc_end_spacing}um
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001881 set chw [/ ${contact_size} 2.0]
1882 box grow e ${chw}um
1883 box grow e ${end_surround}um
1884 paint ${bot_type}
1885
1886 popbox
1887 popbox
1888
1889 # Draw contact to right. Reduce contact extent if devices are not
1890 # wired together and the top metal spacing rule limits the distance
1891 set lcont $l
1892 if {($bconnect == 0) && ($ny > 1)} {
1893 if {$cap_spacing < $top_metal_space} {
1894 set cspace [- $top_metal_space $cap_spacing]
1895 set lcont [- $l $cspace]
1896 }
1897 }
1898
1899 pushbox
1900 box move e ${hw}um
1901 box move e ${bot_surround}um
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05001902 box move e ${loc_end_spacing}um
Tim Edwards55f4d0e2020-07-05 15:41:02 -04001903 set cl [- [+ ${lcont} [* ${bot_surround} 2.0]] [* ${end_surround} 2.0]]
1904 set cl [- ${cl} ${metal_surround}] ;# see below
1905 set cext [sky130::unionbox $cext [sky130::draw_contact 0 ${cl} \
1906 ${end_surround} ${metal_surround} ${contact_size} \
1907 ${bot_type} ${top_contact_type} ${top_type} full]]
1908 popbox
1909 popbox
1910
1911 return $cext
1912
1913 # cl shrinks top and bottom to accomodate larger bottom metal
1914 # surround rule for contacts near a MiM cap. This should be its
1915 # own variable, but metal_surround is sufficient.
1916}
1917
1918#----------------------------------------------------------------
1919# Metal plate sandwich capacitor: Draw a single device
1920#----------------------------------------------------------------
1921
1922proc sky130::sandwich_cap_device {parameters} {
1923
1924 # Set a local variable for each parameter (e.g., $l, $w, etc.)
1925 foreach key [dict keys $parameters] {
1926 set $key [dict get $parameters $key]
1927 }
1928
1929 pushbox
1930 box size 0 0
1931
1932 set hw [/ $w 2.0]
1933 set hl [/ $l 2.0]
1934
1935 set cw [- [* $hw [/ 2.0 3]] [* $cont_surround 2.0]]
1936 set cl [- [* $hl [/ 2.0 3]] [* $cont_surround 2.0]]
1937
1938 # plate capacitor defines layers p0, p1, etc.
1939 for {set i 0} {$i < 20} {incr i} {
1940 if {[catch {set layer [subst \$p${i}_type]}]} {break} ;# no more layers defined
1941 pushbox
1942 box grow e ${hw}um
1943 box grow w ${hw}um
1944 box grow n ${hl}um
1945 box grow s ${hl}um
1946 if {![catch {set shrink [subst \$p${i}_shrink]}]} {
1947 box grow e -${shrink}um
1948 box grow w -${shrink}um
1949 box grow n -${shrink}um
1950 box grow s -${shrink}um
1951 set cutout_spacing [+ [* ${shrink} 2.0] [/ $via_size 2.0] $cont_surround]
1952 } else {
1953 set cutout_spacing 0
1954 }
1955
1956 paint ${layer}
1957
1958 if {$i == 1} {
1959 # Note that cap_type geometry is coincident with p1_type.
1960 # Typically, this will define a layer that outputs as both
1961 # poly and a capacitor definition layer.
1962 if {[dict exists $parameters cap_type]} {
1963 paint $cap_type
1964 }
1965 }
1966 popbox
1967
1968 # Even layers connect at corners, odd layers connect at sides.
1969 # Even layers cut out the sides, odd layers cut out the corners.
1970 # Layer zero has no side contacts or cutout.
1971
1972 if {[% $i 2] == 0} {
1973 set cornercmd paint
1974 set cornersize $cutout_spacing
1975 set sidecmd erase
1976 set nssidelong [+ $cutout_spacing [/ $hw 3.0]]
1977 set ewsidelong [+ $cutout_spacing [/ $hl 3.0]]
1978 set sideshort $cutout_spacing
1979 } else {
1980 set cornercmd erase
1981 set cornersize $cutout_spacing
1982 set sidecmd paint
1983 set nssidelong [/ $hw 3.0]
1984 set ewsidelong [/ $hl 3.0]
1985 set sideshort $cutout_spacing
1986 }
1987
1988 if {$i > 0} {
1989 pushbox
1990 box move e ${hw}um
1991 box grow n ${ewsidelong}um
1992 box grow s ${ewsidelong}um
1993 box grow w ${sideshort}um
1994 ${sidecmd} ${layer}
1995 popbox
1996 pushbox
1997 box move n ${hl}um
1998 box grow e ${nssidelong}um
1999 box grow w ${nssidelong}um
2000 box grow s ${sideshort}um
2001 ${sidecmd} ${layer}
2002 popbox
2003 pushbox
2004 box move w ${hw}um
2005 box grow n ${ewsidelong}um
2006 box grow s ${ewsidelong}um
2007 box grow e ${sideshort}um
2008 ${sidecmd} ${layer}
2009 popbox
2010 pushbox
2011 box move s ${hl}um
2012 box grow e ${nssidelong}um
2013 box grow w ${nssidelong}um
2014 box grow n ${sideshort}um
2015 ${sidecmd} ${layer}
2016 popbox
2017
2018 pushbox
2019 box move n ${hl}um
2020 box move e ${hw}um
2021 box grow s ${cornersize}um
2022 box grow w ${cornersize}um
2023 ${cornercmd} ${layer}
2024 popbox
2025 pushbox
2026 box move n ${hl}um
2027 box move w ${hw}um
2028 box grow s ${cornersize}um
2029 box grow e ${cornersize}um
2030 ${cornercmd} ${layer}
2031 popbox
2032 pushbox
2033 box move s ${hl}um
2034 box move e ${hw}um
2035 box grow n ${cornersize}um
2036 box grow w ${cornersize}um
2037 ${cornercmd} ${layer}
2038 popbox
2039 pushbox
2040 box move s ${hl}um
2041 box move w ${hw}um
2042 box grow n ${cornersize}um
2043 box grow e ${cornersize}um
2044 ${cornercmd} ${layer}
2045 popbox
2046 }
2047 }
2048
2049 # Draw contacts after all layers have been drawn, so that erasing
2050 # layers does not affect the contacts.
2051
2052 for {set i 0} {$i < 20} {incr i} {
2053 if {![catch {set contact [subst \$p${i}_contact_type]}]} {
2054 set layer [subst \$p${i}_type]
2055 set j [+ $i 1]
2056 set toplayer [subst \$p${j}_type]
2057
2058 # Draw corner contacts
2059 pushbox
2060 box move e ${hw}um
2061 box move n ${hl}um
2062 sky130::draw_contact 0 0 \
2063 ${cont_surround} ${cont_surround} ${via_size} \
2064 ${layer} ${contact} ${toplayer} full
2065 popbox
2066 pushbox
2067 box move w ${hw}um
2068 box move n ${hl}um
2069 sky130::draw_contact 0 0 \
2070 ${cont_surround} ${cont_surround} ${via_size} \
2071 ${layer} ${contact} ${toplayer} full
2072 popbox
2073 pushbox
2074 box move e ${hw}um
2075 box move s ${hl}um
2076 sky130::draw_contact 0 0 \
2077 ${cont_surround} ${cont_surround} ${via_size} \
2078 ${layer} ${contact} ${toplayer} full
2079 popbox
2080 pushbox
2081 box move w ${hw}um
2082 box move s ${hl}um
2083 sky130::draw_contact 0 0 \
2084 ${cont_surround} ${cont_surround} ${via_size} \
2085 ${layer} ${contact} ${toplayer} full
2086 popbox
2087
2088 # Draw side contacts (except on poly)
2089 if {$i > 0} {
2090 pushbox
2091 box move w ${hw}um
2092 sky130::draw_contact 0 ${cl} \
2093 ${cont_surround} ${cont_surround} ${via_size} \
2094 ${layer} ${contact} ${toplayer} full
2095 popbox
2096 pushbox
2097 box move e ${hw}um
2098 sky130::draw_contact 0 ${cl} \
2099 ${cont_surround} ${cont_surround} ${via_size} \
2100 ${layer} ${contact} ${toplayer} full
2101 popbox
2102 pushbox
2103 box move n ${hl}um
2104 sky130::draw_contact ${cw} 0 \
2105 ${cont_surround} ${cont_surround} ${via_size} \
2106 ${layer} ${contact} ${toplayer} full
2107 popbox
2108 pushbox
2109 box move s ${hl}um
2110 sky130::draw_contact ${cw} 0 \
2111 ${cont_surround} ${cont_surround} ${via_size} \
2112 ${layer} ${contact} ${toplayer} full
2113 popbox
2114 }
2115 } else {
2116 break
2117 }
2118 }
2119
2120 popbox
2121 # Bounding box is the same as the device length and width
2122 set cext [list -$hw -$hl $hw $hl]
2123 return $cext
2124}
2125
2126#----------------------------------------------------------------
2127# Capacitor: Draw the tiled device
2128#----------------------------------------------------------------
2129
2130proc sky130::cap_draw {parameters} {
2131 tech unlock *
2132 set savesnap [snap]
2133 snap internal
2134
2135 # Set defaults if they are not in parameters
2136 set coverlap 0 ;# overlap capacitors at contacts
2137 set guard 0 ;# draw a guard ring
2138 set sandwich 0 ;# this is not a plate sandwich capacitor
2139 set cap_spacing 0 ;# abutted caps if spacing is zero
2140 set cap_diff_spacing 0
2141 set wide_cap_spacing 0 ;# additional spacing for wide metal rule
2142 set wide_cap_width 0
2143 set end_spacing 0
2144 set end_surround 0
2145 set bot_surround 0
2146 set top_metal_width 0
2147 set bconnect 0 ;# connect bottom plates in array
2148 set tconnect 0 ;# connect top plates in array
2149 set top_type ""
2150
2151 # Set a local variable for each parameter (e.g., $l, $w, etc.)
2152 foreach key [dict keys $parameters] {
2153 set $key [dict get $parameters $key]
2154 }
2155
2156 # Normalize distance units to microns
2157 set w [magic::spice2float $w]
2158 set l [magic::spice2float $l]
2159
2160 pushbox
2161 box values 0 0 0 0
2162
2163 # Determine the base device dimensions by drawing one device
2164 # while all layers are locked (nothing drawn). This allows the
2165 # base drawing routine to do complicated geometry without having
2166 # to duplicate it here with calculations.
2167
2168 tech lock *
2169 if {$sandwich == 1} {
2170 set bbox [sky130::sandwich_cap_device $parameters]
2171 } else {
2172 set bbox [sky130::cap_device $parameters]
2173 }
2174 # puts stdout "Diagnostic: Device bounding box e $bbox (um)"
2175 tech unlock *
2176
2177 set fw [- [lindex $bbox 2] [lindex $bbox 0]]
2178 set fh [- [lindex $bbox 3] [lindex $bbox 1]]
2179 set lw [+ [lindex $bbox 2] [lindex $bbox 0]]
2180 set lh [+ [lindex $bbox 3] [lindex $bbox 1]]
2181
2182 set dwide 0
2183 if {($fw >= $wide_cap_width) && ($fh >= $wide_cap_width)} {
2184 set dwide $wide_cap_spacing
2185 }
2186
2187 # Determine tile width and height (depends on overlap)
2188 if {$coverlap == 0} {
2189 set dy [+ $fh $cap_spacing $dwide]
2190 } else {
2191 # overlap at end contact
2192 set dy [- $fh [+ $end_surround $end_surround $contact_size]]
2193 }
2194 # Contact is placed on right so spacing is determined by end_spacing.
2195 set dx [+ $fw $end_spacing $dwide]
2196
2197 # Determine core width and height
2198 set corex [+ [* [- $nx 1] $dx] $fw]
2199 set corey [+ [* [- $ny 1] $dy] $fh]
2200 set corellx [/ [+ [- $corex $fw] $lw] 2.0]
2201 set corelly [/ [+ [- $corey $fh] $lh] 2.0]
2202
2203 if {$guard != 0} {
2204 # Calculate guard ring size (measured to contact center)
2205 set gx [+ $corex [* 2.0 [+ $cap_diff_spacing $diff_surround]] $contact_size]
2206 set gy [+ $corey [* 2.0 [+ $end_spacing $diff_surround]] $contact_size]
2207
2208 # Draw the guard ring first.
2209 sky130::guard_ring $gx $gy $parameters
2210 }
2211
2212 set twidth [+ ${contact_size} ${end_surround} ${end_surround}]
2213 if {${twidth} < ${top_metal_width}} {
2214 set twidth ${top_metal_width}
2215 }
2216 set hmw [/ $twidth 2.0]
2217 set hdy [/ $dy 2.0]
2218 set cdx [+ [/ ${w} 2.0] ${bot_surround} ${end_spacing}]
2219
2220 pushbox
2221 box move w ${corellx}um
2222 box move s ${corelly}um
2223 for {set xp 0} {$xp < $nx} {incr xp} {
2224 pushbox
2225 for {set yp 0} {$yp < $ny} {incr yp} {
2226 if {$sandwich == 1} {
2227 sky130::sandwich_cap_device $parameters
2228 } else {
2229 sky130::cap_device $parameters
2230 }
2231 if {$ny > 1} {
2232 pushbox
2233 box grow e ${hmw}um
2234 box grow w ${hmw}um
2235 box grow n ${hdy}um
2236 box grow s ${hdy}um
2237 if {($top_type != "") && ($tconnect == 1)} {
2238 paint ${top_type}
2239 }
2240 if {($top_type != "") && ($bconnect == 1)} {
2241 box move e ${cdx}um
2242 paint ${top_type}
2243 }
2244 popbox
2245 }
2246 box move n ${dy}um
2247 }
2248 popbox
2249 box move e ${dx}um
2250 }
2251 popbox
2252 popbox
2253
2254 snap $savesnap
2255 tech revert
2256}
2257
2258#----------------------------------------------------------------
2259
2260#ifdef MIM
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002261proc sky130::sky130_fd_pr__cap_mim_m3_1_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002262 set newdict [dict create \
2263 top_type m4 \
2264 top_contact_type via3 \
2265 cap_type mimcap \
2266 cap_contact_type mimcc \
2267 bot_type m3 \
2268 bot_surround 0.5 \
2269 cap_spacing 0.5 \
2270 cap_surround 0.2 \
2271 top_surround 0.005 \
2272 end_surround 0.1 \
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05002273 end_spacing 0.1 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002274 contact_size 0.32 \
2275 metal_surround 0.08 \
2276 ]
2277 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
2278 return [sky130::cap_draw $drawdict]
2279}
2280
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002281proc sky130::sky130_fd_pr__cap_mim_m3_2_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002282 set newdict [dict create \
2283 top_type m5 \
2284 top_contact_type via4 \
2285 cap_type mimcap2 \
2286 cap_contact_type mim2cc \
2287 bot_type m4 \
2288 bot_surround 0.5 \
2289 cap_spacing 0.5 \
2290 cap_surround 0.2 \
2291 top_surround 0.12 \
2292 end_surround 0.1 \
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05002293 end_spacing 0.1 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002294 contact_size 1.18 \
2295 metal_surround 0.21 \
2296 top_metal_width 1.6 \
2297 top_metal_space 1.7 \
2298 ]
2299 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
2300 return [sky130::cap_draw $drawdict]
2301}
2302
2303#endif (MIM)
2304
2305#----------------------------------------------------------------
2306# capacitor: Check device parameters for out-of-bounds values
2307#----------------------------------------------------------------
2308
2309proc sky130::cap_check {parameters} {
2310 # In case wmax and/or lmax are undefined
2311 set lmax 0
2312 set wmax 0
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05002313 set ccov 100
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002314
2315 # Set a local variable for each parameter (e.g., $l, $w, etc.)
2316 foreach key [dict keys $parameters] {
2317 set $key [dict get $parameters $key]
2318 }
2319
2320 # Normalize distance units to microns
2321 set l [magic::spice2float $l]
2322 set l [magic::3digitpastdecimal $l]
2323 set w [magic::spice2float $w]
2324 set w [magic::3digitpastdecimal $w]
2325
2326 set val [magic::spice2float $val]
2327 set carea [magic::spice2float $carea]
2328 set cperi [magic::spice2float $cperi]
2329 set dc [magic::spice2float $dc]
2330
2331 if {$square == 1} {
2332 # Calculate L and W from value
2333 set a $carea
2334 set b [expr $cperi * 4]
2335 set c [expr -4 * $dc - $val]
2336 set l [expr ((-$b + sqrt($b * $b - (4 * $a * $c))) / (2 * $a))]
2337 dict set parameters l [magic::float2spice $l]
2338 set w $l
2339 dict set parameters w [magic::float2spice $w]
2340 } elseif {$l == 0} {
2341 # Calculate L from W and value
2342 set l [expr (($val + 4 * $dc - 2 * $w * $cperi) / ($w * $carea + 2 * $cperi))]
2343 dict set parameters l [magic::float2spice $l]
2344 } elseif {$w == 0} {
2345 # Calculate W from L and value
2346 set w [expr (($val + 4 * $dc - 2 * $l * $cperi) / ($l * $carea + 2 * $cperi))]
2347 dict set parameters w [magic::float2spice $w]
2348 }
2349 if {$w < $wmin} {
2350 puts stderr "Capacitor width must be >= $wmin"
2351 dict set parameters w $wmin
2352 set w $wmin
2353 }
2354 if {$l < $lmin} {
2355 puts stderr "Capacitor length must be >= $lmin"
2356 dict set parameters l $lmin
2357 set l $lmin
2358 }
2359 if {($wmax > 0) && ($w > $wmax)} {
2360 puts stderr "Capacitor width must be <= $wmax"
2361 dict set parameters w $wmax
2362 set w $wmax
2363 }
2364 if {($lmax > 0) && ($l > $lmax)} {
2365 puts stderr "Capacitor length must be <= $lmax"
2366 dict set parameters l $lmax
2367 set l $lmax
2368 }
Tim Edwards3c1dd9a2020-11-27 13:49:58 -05002369 if {[catch {expr abs($ccov)}]} {
2370 puts stderr "Capacitor contact coverage must be numeric!"
2371 dict set parameters ccov 100
2372 } elseif {[expr abs($ccov)] > 100} {
2373 puts stderr "Capaitor contact coverage can't be more than 100%"
2374 dict set parameters ccov 100
2375 }
2376
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002377 # Calculate value from L and W
2378 set cval [expr ($l * $w * $carea + 2 * ($l + $w) * $cperi - 4 * $dc)]
2379 dict set parameters val [magic::float2spice $cval]
2380 sky130::compute_ctot $parameters
2381
2382 return $parameters
2383}
2384
2385#ifdef MIM
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002386proc sky130::sky130_fd_pr__cap_mim_m3_1_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002387 return [sky130::cap_check $parameters]
2388}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002389proc sky130::sky130_fd_pr__cap_mim_m3_2_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002390 return [sky130::cap_check $parameters]
2391}
2392#endif (MIM)
2393
2394#----------------------------------------------------------------
2395# Drawn resistors
2396#----------------------------------------------------------------
2397
2398#----------------------------------------------------------------
2399# Resistor defaults:
2400#----------------------------------------------------------------
2401# User editable values:
2402#
2403# val Resistor value in ohms
2404# w Width
2405# l Length
2406# t Number of turns
2407# m Number devices in Y
2408# nx Number devices in X
2409# snake Use snake geometry (if not present, snake geometry not allowed)
2410# dummy Flag to mark addition of dummy resistor
2411#
2412# Non-user editable values:
2413#
2414# wmin Minimum allowed width
2415# lmin Minimum allowed length
2416# rho Resistance in ohms per square
2417# dw Delta width
2418# term Resistance per terminal
2419# sterm Additional resistance per terminal for snake geometry
2420#----------------------------------------------------------------
2421
2422#----------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002423# sky130_fd_pr__res_iso_pw: Specify all user-editable default values and those
2424# needed by sky130_fd_pr__res_iso_pw_check
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002425# NOTE: Work in progress. These values need to be corrected.
2426#----------------------------------------------------------------
2427
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002428proc sky130::sky130_fd_pr__res_iso_pw_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002429 return {w 2.650 l 26.50 m 1 nx 1 wmin 2.650 lmin 26.50 \
2430 rho 975 val 4875 dummy 0 dw 0.25 term 1.0 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002431 guard 1 endcov 100 full_metal 1 vias 1 \
2432 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002433}
2434
2435#----------------------------------------------------------------
2436# rpp1: Specify all user-editable default values and those
2437# needed by rp1_check
2438#----------------------------------------------------------------
2439
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002440proc sky130::sky130_fd_pr__res_generic_po_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002441 return {w 0.330 l 1.650 m 1 nx 1 wmin 0.330 lmin 1.650 \
2442 rho 48.2 val 241 dummy 0 dw 0.0 term 0.0 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002443 sterm 0.0 caplen 0.4 snake 0 guard 1 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002444 glc 1 grc 1 gtc 1 gbc 1 roverlap 0 endcov 100 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04002445 full_metal 1 hv_guard 0 n_guard 0 vias 1 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002446 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002447}
2448
2449# "term" is rho * 0.06, the distance between xpc edge and CONT.
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002450proc sky130::sky130_fd_pr__res_high_po_0p35_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002451 return {w 0.350 l 0.50 m 1 nx 1 wmin 0.350 lmin 0.50 \
Tim Edwards89d8afc2022-02-11 18:11:15 -05002452 rho 319.8 val 456.857 dummy 0 dw 0.0 term 194.82 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002453 sterm 0.0 caplen 0 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002454 compatible {sky130_fd_pr__res_high_po_0p35 \
2455 sky130_fd_pr__res_high_po_0p69 sky130_fd_pr__res_high_po_1p41 \
2456 sky130_fd_pr__res_high_po_2p85 sky130_fd_pr__res_high_po_5p73} \
Tim Edwardsf788cea2021-04-20 12:43:52 -04002457 full_metal 1 wmax 0.350 vias 1 n_guard 0 hv_guard 0 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002458 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002459}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002460proc sky130::sky130_fd_pr__res_high_po_0p69_defaults {} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002461 return {w 0.690 l 1.00 m 1 nx 1 wmin 0.690 lmin 0.50 \
Tim Edwards89d8afc2022-02-11 18:11:15 -05002462 rho 319.8 val 463.480 dummy 0 dw 0.0 term 194.82 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002463 sterm 0.0 caplen 0 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002464 compatible {sky130_fd_pr__res_high_po_0p35 \
2465 sky130_fd_pr__res_high_po_0p69 sky130_fd_pr__res_high_po_1p41 \
2466 sky130_fd_pr__res_high_po_2p85 sky130_fd_pr__res_high_po_5p73} \
Tim Edwardsf788cea2021-04-20 12:43:52 -04002467 full_metal 1 wmax 0.690 n_guard 0 hv_guard 0 vias 1 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002468 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002469}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002470proc sky130::sky130_fd_pr__res_high_po_1p41_defaults {} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002471 return {w 1.410 l 2.00 m 1 nx 1 wmin 1.410 lmin 0.50 \
Tim Edwards89d8afc2022-02-11 18:11:15 -05002472 rho 319.8 val 453.620 dummy 0 dw 0.0 term 194.82 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002473 sterm 0.0 caplen 0 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002474 compatible {sky130_fd_pr__res_high_po_0p35 \
2475 sky130_fd_pr__res_high_po_0p69 sky130_fd_pr__res_high_po_1p41 \
2476 sky130_fd_pr__res_high_po_2p85 sky130_fd_pr__res_high_po_5p73} \
Tim Edwardsf788cea2021-04-20 12:43:52 -04002477 full_metal 1 wmax 1.410 n_guard 0 hv_guard 0 vias 1 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002478 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002479}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002480proc sky130::sky130_fd_pr__res_high_po_2p85_defaults {} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002481 return {w 2.850 l 3.00 m 1 nx 1 wmin 2.850 lmin 0.50 \
Tim Edwards89d8afc2022-02-11 18:11:15 -05002482 rho 319.8 val 336.630 dummy 0 dw 0.0 term 194.82 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002483 sterm 0.0 caplen 0 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002484 compatible {sky130_fd_pr__res_high_po_0p35 \
2485 sky130_fd_pr__res_high_po_0p69 sky130_fd_pr__res_high_po_1p41 \
2486 sky130_fd_pr__res_high_po_2p85 sky130_fd_pr__res_high_po_5p73} \
Tim Edwardsf788cea2021-04-20 12:43:52 -04002487 full_metal 1 wmax 2.850 n_guard 0 hv_guard 0 vias 1 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002488 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002489}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002490proc sky130::sky130_fd_pr__res_high_po_5p73_defaults {} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002491 return {w 5.730 l 6.00 m 1 nx 1 wmin 5.730 lmin 0.50 \
Tim Edwards89d8afc2022-02-11 18:11:15 -05002492 rho 319.8 val 334.870 dummy 0 dw 0.0 term 194.82 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002493 sterm 0.0 caplen 0 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002494 compatible {sky130_fd_pr__res_high_po_0p35 \
2495 sky130_fd_pr__res_high_po_0p69 sky130_fd_pr__res_high_po_1p41 \
2496 sky130_fd_pr__res_high_po_2p85 sky130_fd_pr__res_high_po_5p73} \
Tim Edwardsf788cea2021-04-20 12:43:52 -04002497 full_metal 1 wmax 5.730 n_guard 0 hv_guard 0 vias 1 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002498 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002499}
2500
2501# "term" is rho * 0.06, the distance between xpc edge and CONT.
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002502proc sky130::sky130_fd_pr__res_xhigh_po_0p35_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002503 return {w 0.350 l 0.50 m 1 nx 1 wmin 0.350 lmin 0.50 \
Tim Edwards89d8afc2022-02-11 18:11:15 -05002504 rho 2000 val 2875.143 dummy 0 dw 0.0 term 188.2 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002505 sterm 0.0 caplen 0 wmax 0.350 \
2506 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002507 compatible {sky130_fd_pr__res_xhigh_po_0p35 \
2508 sky130_fd_pr__res_xhigh_po_0p69 sky130_fd_pr__res_xhigh_po_1p41 \
2509 sky130_fd_pr__res_xhigh_po_2p85 sky130_fd_pr__res_xhigh_po_5p73} \
Tim Edwardsf788cea2021-04-20 12:43:52 -04002510 full_metal 1 n_guard 0 hv_guard 0 vias 1 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002511 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002512}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002513proc sky130::sky130_fd_pr__res_xhigh_po_0p69_defaults {} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002514 return {w 0.690 l 1.00 m 1 nx 1 wmin 0.690 lmin 0.50 \
Tim Edwards89d8afc2022-02-11 18:11:15 -05002515 rho 2000 val 2898.600 dummy 0 dw 0.0 term 188.2 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002516 sterm 0.0 caplen 0 wmax 0.690 \
2517 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002518 compatible {sky130_fd_pr__res_xhigh_po_0p35 \
2519 sky130_fd_pr__res_xhigh_po_0p69 sky130_fd_pr__res_xhigh_po_1p41 \
2520 sky130_fd_pr__res_xhigh_po_2p85 sky130_fd_pr__res_xhigh_po_5p73} \
Tim Edwardsf788cea2021-04-20 12:43:52 -04002521 full_metal 1 n_guard 0 hv_guard 0 vias 1 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002522 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002523}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002524proc sky130::sky130_fd_pr__res_xhigh_po_1p41_defaults {} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002525 return {w 1.410 l 2.00 m 1 nx 1 wmin 1.410 lmin 0.50 \
Tim Edwards89d8afc2022-02-11 18:11:15 -05002526 rho 2000 val 2836.900 dummy 0 dw 0.0 term 188.2 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002527 sterm 0.0 caplen 0 wmax 1.410 \
2528 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002529 compatible {sky130_fd_pr__res_xhigh_po_0p35 \
2530 sky130_fd_pr__res_xhigh_po_0p69 sky130_fd_pr__res_xhigh_po_1p41 \
2531 sky130_fd_pr__res_xhigh_po_2p85 sky130_fd_pr__res_xhigh_po_5p73} \
Tim Edwardsf788cea2021-04-20 12:43:52 -04002532 full_metal 1 n_guard 0 hv_guard 0 vias 1 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002533 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002534}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002535proc sky130::sky130_fd_pr__res_xhigh_po_2p85_defaults {} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002536 return {w 2.850 l 3.00 m 1 nx 1 wmin 2.850 lmin 0.50 \
Tim Edwards89d8afc2022-02-11 18:11:15 -05002537 rho 2000 val 2105.300 dummy 0 dw 0.0 term 188.2 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002538 sterm 0.0 caplen 0 wmax 2.850 \
2539 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002540 compatible {sky130_fd_pr__res_xhigh_po_0p35 \
2541 sky130_fd_pr__res_xhigh_po_0p69 sky130_fd_pr__res_xhigh_po_1p41 \
2542 sky130_fd_pr__res_xhigh_po_2p85 sky130_fd_pr__res_xhigh_po_5p73} \
Tim Edwardsf788cea2021-04-20 12:43:52 -04002543 full_metal 1 n_guard 0 hv_guard 0 vias 1 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002544 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002545}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002546proc sky130::sky130_fd_pr__res_xhigh_po_5p73_defaults {} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002547 return {w 5.730 l 6.00 m 1 nx 1 wmin 5.730 lmin 0.50 \
Tim Edwards89d8afc2022-02-11 18:11:15 -05002548 rho 2000 val 2094.200 dummy 0 dw 0.0 term 188.2 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002549 sterm 0.0 caplen 0 wmax 5.730 \
2550 guard 1 glc 1 grc 1 gtc 1 gbc 1 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002551 compatible {sky130_fd_pr__res_xhigh_po_0p35 \
2552 sky130_fd_pr__res_xhigh_po_0p69 sky130_fd_pr__res_xhigh_po_1p41 \
2553 sky130_fd_pr__res_xhigh_po_2p85 sky130_fd_pr__res_xhigh_po_5p73} \
Tim Edwardsf788cea2021-04-20 12:43:52 -04002554 full_metal 1 n_guard 0 hv_guard 0 vias 1 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002555 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002556}
2557
2558#----------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002559# sky130_fd_pr__res_generic_nd: Specify all user-editable default values and those
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002560# needed by rdn_check
2561#----------------------------------------------------------------
2562
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002563proc sky130::sky130_fd_pr__res_generic_nd_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002564 return {w 0.420 l 2.100 m 1 nx 1 wmin 0.42 lmin 2.10 \
2565 rho 120 val 600.0 dummy 0 dw 0.05 term 0.0 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002566 sterm 0.0 caplen 0.4 snake 0 guard 1 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002567 glc 1 grc 1 gtc 1 gbc 1 roverlap 0 endcov 100 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002568 full_metal 1 vias 1 \
2569 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002570}
2571
Tim Edwards0ee0f182020-11-21 16:15:07 -05002572proc sky130::sky130_fd_pr__res_generic_nd__hv_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002573 return {w 0.420 l 2.100 m 1 nx 1 wmin 0.42 lmin 2.10 \
2574 rho 120 val 600.0 dummy 0 dw 0.02 term 0.0 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002575 sterm 0.0 caplen 0.4 snake 0 guard 1 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002576 glc 1 grc 1 gtc 1 gbc 1 roverlap 0 endcov 100 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002577 full_metal 1 vias 1 \
2578 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002579}
2580
2581#----------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002582# sky130_fd_pr__res_generic_pd: Specify all user-editable default values and those
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002583# needed by rdp_check
2584#----------------------------------------------------------------
2585
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002586proc sky130::sky130_fd_pr__res_generic_pd_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002587 return {w 0.420 l 2.100 m 1 nx 1 wmin 0.42 lmin 2.10 \
2588 rho 197 val 985.0 dummy 0 dw 0.02 term 0.0 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002589 sterm 0.0 caplen 0.60 snake 0 guard 1 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002590 glc 1 grc 1 gtc 1 gbc 1 roverlap 0 endcov 100 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002591 full_metal 1 vias 1 \
2592 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002593}
2594
Tim Edwards0ee0f182020-11-21 16:15:07 -05002595proc sky130::sky130_fd_pr__res_generic_pd__hv_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002596 return {w 0.420 l 2.100 m 1 nx 1 wmin 0.42 lmin 2.10 \
2597 rho 197 val 985.0 dummy 0 dw 0.02 term 0.0 \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002598 sterm 0.0 caplen 0.60 snake 0 guard 1 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002599 glc 1 grc 1 gtc 1 gbc 1 roverlap 0 endcov 100 \
Tim Edwards0ee0f182020-11-21 16:15:07 -05002600 full_metal 1 vias 1 \
2601 viagb 0 viagt 0 viagl 0 viagr 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002602}
2603
2604#----------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002605# sky130_fd_pr__res_generic_l1: Specify all user-editable default values and those needed
2606# by sky130_fd_pr__res_generic_l1_check
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002607#----------------------------------------------------------------
2608
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002609proc sky130::sky130_fd_pr__res_generic_l1_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002610 return {w 0.170 l 0.170 m 1 nx 1 wmin 0.17 lmin 0.17 \
2611 rho 12.8 val 12.8 dummy 0 dw 0.0 term 0.0 snake 0 \
2612 roverlap 0}
2613}
2614
2615#----------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002616# sky130_fd_pr__res_generic_m1: Specify all user-editable default values and those needed
2617# by sky130_fd_pr__res_generic_m1_check
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002618#----------------------------------------------------------------
2619
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002620proc sky130::sky130_fd_pr__res_generic_m1_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002621 return {w 0.140 l 0.140 m 1 nx 1 wmin 0.14 lmin 0.14 \
2622 rho 0.125 val 0.125 dummy 0 dw 0.0 term 0.0 \
2623 roverlap 0}
2624}
2625
2626#----------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002627# sky130_fd_pr__res_generic_m2: Specify all user-editable default values and those needed
2628# by sky130_fd_pr__res_generic_m2_check
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002629#----------------------------------------------------------------
2630
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002631proc sky130::sky130_fd_pr__res_generic_m2_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002632 return {w 0.140 l 0.140 m 1 nx 1 wmin 0.14 lmin 0.14 \
2633 rho 0.125 val 0.125 dummy 0 dw 0.0 term 0.0 \
2634 roverlap 0}
2635}
2636
2637#----------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002638# sky130_fd_pr__res_generic_m3: Specify all user-editable default values and those needed
2639# by sky130_fd_pr__res_generic_m3_check
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002640#----------------------------------------------------------------
2641
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002642proc sky130::sky130_fd_pr__res_generic_m3_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002643 return {w 0.300 l 0.300 m 1 nx 1 wmin 0.30 lmin 0.30 \
2644 rho 0.047 val 0.047 dummy 0 dw 0.0 term 0.0 \
2645 roverlap 0}
2646}
2647
2648#----------------------------------------------------------------
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002649# 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 -04002650# back-end metal stack.
2651#----------------------------------------------------------------
2652
2653#ifdef METAL5
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002654proc sky130::sky130_fd_pr__res_generic_m4_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002655 return {w 0.300 l 0.300 m 1 nx 1 wmin 0.30 lmin 0.30 \
2656 rho 0.047 val 0.047 dummy 0 dw 0.0 term 0.0 \
2657 roverlap 0}
2658}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002659proc sky130::sky130_fd_pr__res_generic_m5_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002660 return {w 1.600 l 1.600 m 1 nx 1 wmin 1.60 lmin 1.60 \
2661 rho 0.029 val 0.029 dummy 0 dw 0.0 term 0.0 \
2662 roverlap 0}
2663}
2664#endif (METAL5)
2665
2666#----------------------------------------------------------------
2667# resistor: Conversion from SPICE netlist parameters to toolkit
2668#----------------------------------------------------------------
2669
2670proc sky130::res_convert {parameters} {
2671 set pdkparams [dict create]
2672 dict for {key value} $parameters {
2673 switch -nocase $key {
2674 l -
2675 w {
2676 # Length and width are converted to units of microns
2677 set value [magic::spice2float $value]
2678 # set value [expr $value * 1e6]
2679 set value [magic::3digitpastdecimal $value]
2680 dict set pdkparams [string tolower $key] $value
2681 }
2682 }
2683 }
2684 return $pdkparams
2685}
2686
2687#----------------------------------------------------------------
2688
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002689proc sky130::sky130_fd_pr__res_iso_pw_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002690 return [sky130::res_convert $parameters]
2691}
2692
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002693proc sky130::sky130_fd_pr__res_generic_po_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002694 return [sky130::res_convert $parameters]
2695}
2696
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002697proc sky130::sky130_fd_pr__res_high_po_0p35_convert {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002698 return [sky130::res_convert $parameters]
2699}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002700proc sky130::sky130_fd_pr__res_high_po_0p69_convert {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002701 return [sky130::res_convert $parameters]
2702}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002703proc sky130::sky130_fd_pr__res_high_po_1p41_convert {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002704 return [sky130::res_convert $parameters]
2705}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002706proc sky130::sky130_fd_pr__res_high_po_2p85_convert {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002707 return [sky130::res_convert $parameters]
2708}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002709proc sky130::sky130_fd_pr__res_high_po_5p73_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002710 return [sky130::res_convert $parameters]
2711}
2712
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002713proc sky130::sky130_fd_pr__res_xhigh_po_0p35_convert {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002714 return [sky130::res_convert $parameters]
2715}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002716proc sky130::sky130_fd_pr__res_xhigh_po_0p69_convert {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002717 return [sky130::res_convert $parameters]
2718}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002719proc sky130::sky130_fd_pr__res_xhigh_po_1p41_convert {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002720 return [sky130::res_convert $parameters]
2721}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002722proc sky130::sky130_fd_pr__res_xhigh_po_2p85_convert {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002723 return [sky130::res_convert $parameters]
2724}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002725proc sky130::sky130_fd_pr__res_xhigh_po_5p73_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002726 return [sky130::res_convert $parameters]
2727}
2728
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002729proc sky130::sky130_fd_pr__res_generic_nd_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002730 return [sky130::res_convert $parameters]
2731}
2732
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002733proc sky130::sky130_fd_pr__res_generic_pd_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002734 return [sky130::res_convert $parameters]
2735}
2736
Tim Edwards0ee0f182020-11-21 16:15:07 -05002737proc sky130::sky130_fd_pr__res_generic_nd__hv_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002738 return [sky130::res_convert $parameters]
2739}
2740
Tim Edwards0ee0f182020-11-21 16:15:07 -05002741proc sky130::sky130_fd_pr__res_generic_pd__hv_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002742 return [sky130::res_convert $parameters]
2743}
2744
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002745proc sky130::sky130_fd_pr__res_generic_l1_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002746 return [sky130::res_convert $parameters]
2747}
2748
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002749proc sky130::sky130_fd_pr__res_generic_m1_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002750 return [sky130::res_convert $parameters]
2751}
2752
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002753proc sky130::sky130_fd_pr__res_generic_m2_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002754 return [sky130::res_convert $parameters]
2755}
2756
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002757proc sky130::sky130_fd_pr__res_generic_m3_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002758 return [sky130::res_convert $parameters]
2759}
2760
2761#ifdef METAL5
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002762proc sky130::sky130_fd_pr__res_generic_m4_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002763 return [sky130::res_convert $parameters]
2764}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002765proc sky130::sky130_fd_pr__res_generic_m5_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002766 return [sky130::res_convert $parameters]
2767}
2768#endif (METAL5)
2769
2770#----------------------------------------------------------------
2771# resistor: Interactively specifies the fixed layout parameters
2772#----------------------------------------------------------------
2773
2774proc sky130::res_dialog {device parameters} {
2775 # Editable fields: w, l, t, nx, m, val
2776 # Checked fields:
2777
2778 magic::add_entry val "Value (ohms)" $parameters
2779 if {[dict exists $parameters snake]} {
2780 sky130::compute_ltot $parameters
2781 magic::add_message ltot "Total length (um)" $parameters
2782 }
2783 magic::add_entry l "Length (um)" $parameters
2784 magic::add_entry w "Width (um)" $parameters
2785 magic::add_entry nx "X Repeat" $parameters
2786 magic::add_entry m "Y Repeat" $parameters
2787 if {[dict exists $parameters endcov]} {
2788 magic::add_entry endcov "End contact coverage (%)" $parameters
2789 }
2790
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002791 if {[dict exists $parameters compatible]} {
2792 set sellist [dict get $parameters compatible]
2793 magic::add_selectlist gencell "Device type" $sellist $parameters $device
2794 }
2795
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002796 # magic::add_checkbox dummy "Add dummy" $parameters
2797
2798 if {[dict exists $parameters snake]} {
2799 magic::add_checkbox snake "Use snake geometry" $parameters
2800 }
2801 if {[dict exists $parameters roverlap]} {
2802 if {[dict exists $parameters endcov]} {
2803 magic::add_checkbox roverlap "Overlap at end contact" $parameters
2804 } else {
2805 magic::add_checkbox roverlap "Overlap at ends" $parameters
2806 }
2807 }
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002808 if {[dict exists $parameters guard]} {
2809 magic::add_checkbox guard "Add guard ring" $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002810
Tim Edwards8469aa62020-11-29 12:42:25 -05002811 if {[dict exists $parameters hv_guard]} {
2812 magic::add_checkbox hv_guard "High-voltage guard ring" $parameters
2813 }
Tim Edwardsf788cea2021-04-20 12:43:52 -04002814 if {[dict exists $parameters n_guard]} {
2815 magic::add_checkbox n_guard "N-well connected guard ring" $parameters
2816 }
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002817 if {[dict exists $parameters full_metal]} {
2818 magic::add_checkbox full_metal "Full metal guard ring" $parameters
2819 }
2820 if {[dict exists $parameters glc]} {
2821 magic::add_checkbox glc "Add left guard ring contact" $parameters
2822 }
2823 if {[dict exists $parameters grc]} {
2824 magic::add_checkbox grc "Add right guard ring contact" $parameters
2825 }
2826 if {[dict exists $parameters gtc]} {
2827 magic::add_checkbox gtc "Add top guard ring contact" $parameters
2828 }
2829 if {[dict exists $parameters gbc]} {
2830 magic::add_checkbox gbc "Add bottom guard ring contact" $parameters
2831 }
Tim Edwards0ee0f182020-11-21 16:15:07 -05002832
Tim Edwardsf788cea2021-04-20 12:43:52 -04002833
Tim Edwards0ee0f182020-11-21 16:15:07 -05002834 magic::add_entry viagb "Bottom guard ring via coverage \[+/-\](%)" $parameters
2835 magic::add_entry viagt "Top guard ring via coverage \[+/-\](%)" $parameters
2836 magic::add_entry viagr "Right guard ring via coverage \[+/-\](%)" $parameters
2837 magic::add_entry viagl "Left guard ring via coverage \[+/-\](%)" $parameters
2838 }
2839
2840 if {[dict exists $parameters vias]} {
2841 magic::add_checkbox vias "Add vias over contacts" $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002842 }
2843
2844 if {[dict exists $parameters snake]} {
2845 magic::add_dependency sky130::res_recalc $device sky130 l w val nx snake
2846 } else {
2847 magic::add_dependency sky130::res_recalc $device sky130 l w val nx
2848 }
2849}
2850
2851#----------------------------------------------------------------
2852
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002853proc sky130::sky130_fd_pr__res_iso_pw_dialog {parameters} {
2854 sky130::res_dialog sky130_fd_pr__res_iso_pw $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002855}
2856
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002857proc sky130::sky130_fd_pr__res_generic_po_dialog {parameters} {
2858 sky130::res_dialog sky130_fd_pr__res_generic_po $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002859}
2860
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002861proc sky130::sky130_fd_pr__res_high_po_0p35_dialog {parameters} {
2862 sky130::res_dialog sky130_fd_pr__res_high_po_0p35 $parameters
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002863}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002864proc sky130::sky130_fd_pr__res_high_po_0p69_dialog {parameters} {
2865 sky130::res_dialog sky130_fd_pr__res_high_po_0p69 $parameters
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002866}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002867proc sky130::sky130_fd_pr__res_high_po_1p41_dialog {parameters} {
2868 sky130::res_dialog sky130_fd_pr__res_high_po_1p41 $parameters
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002869}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002870proc sky130::sky130_fd_pr__res_high_po_2p85_dialog {parameters} {
2871 sky130::res_dialog sky130_fd_pr__res_high_po_2p85 $parameters
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002872}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002873proc sky130::sky130_fd_pr__res_high_po_5p73_dialog {parameters} {
2874 sky130::res_dialog sky130_fd_pr__res_high_po_5p73 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002875}
2876
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002877proc sky130::sky130_fd_pr__res_xhigh_po_0p35_dialog {parameters} {
2878 sky130::res_dialog sky130_fd_pr__res_xhigh_po_0p35 $parameters
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002879}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002880proc sky130::sky130_fd_pr__res_xhigh_po_0p69_dialog {parameters} {
2881 sky130::res_dialog sky130_fd_pr__res_xhigh_po_0p69 $parameters
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002882}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002883proc sky130::sky130_fd_pr__res_xhigh_po_1p41_dialog {parameters} {
2884 sky130::res_dialog sky130_fd_pr__res_xhigh_po_1p41 $parameters
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002885}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002886proc sky130::sky130_fd_pr__res_xhigh_po_2p85_dialog {parameters} {
2887 sky130::res_dialog sky130_fd_pr__res_xhigh_po_2p85 $parameters
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002888}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002889proc sky130::sky130_fd_pr__res_xhigh_po_5p73_dialog {parameters} {
2890 sky130::res_dialog sky130_fd_pr__res_xhigh_po_5p73 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002891}
2892
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002893proc sky130::sky130_fd_pr__res_generic_nd_dialog {parameters} {
2894 sky130::res_dialog sky130_fd_pr__res_generic_nd $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002895}
2896
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002897proc sky130::sky130_fd_pr__res_generic_pd_dialog {parameters} {
2898 sky130::res_dialog sky130_fd_pr__res_generic_pd $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002899}
2900
Tim Edwards0ee0f182020-11-21 16:15:07 -05002901proc sky130::sky130_fd_pr__res_generic_nd__hv_dialog {parameters} {
2902 sky130::res_dialog sky130_fd_pr__res_generic_nd__hv $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002903}
2904
Tim Edwards0ee0f182020-11-21 16:15:07 -05002905proc sky130::sky130_fd_pr__res_generic_pd__hv_dialog {parameters} {
2906 sky130::res_dialog sky130_fd_pr__res_generic_pd__hv $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002907}
2908
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002909proc sky130::sky130_fd_pr__res_generic_l1_dialog {parameters} {
2910 sky130::res_dialog sky130_fd_pr__res_generic_l1 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002911}
2912
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002913proc sky130::sky130_fd_pr__res_generic_m1_dialog {parameters} {
2914 sky130::res_dialog sky130_fd_pr__res_generic_m1 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002915}
2916
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002917proc sky130::sky130_fd_pr__res_generic_m2_dialog {parameters} {
2918 sky130::res_dialog sky130_fd_pr__res_generic_m2 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002919}
2920
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002921proc sky130::sky130_fd_pr__res_generic_m3_dialog {parameters} {
2922 sky130::res_dialog sky130_fd_pr__res_generic_m3 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002923}
2924
2925#ifdef METAL5
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002926proc sky130::sky130_fd_pr__res_generic_m4_dialog {parameters} {
2927 sky130::res_dialog sky130_fd_pr__res_generic_m4 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002928}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04002929proc sky130::sky130_fd_pr__res_generic_m5_dialog {parameters} {
2930 sky130::res_dialog sky130_fd_pr__res_generic_m5 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002931}
2932#endif (METAL5)
2933
2934#----------------------------------------------------------------
2935# Resistor: Draw a single device in straight geometry
2936#----------------------------------------------------------------
2937
2938proc sky130::res_device {parameters} {
2939 # Epsilon for avoiding round-off errors
2940 set eps 0.0005
2941
2942 # Set local default values if they are not in parameters
2943 set endcov 0 ;# percent coverage of end contacts
2944 set roverlap 0 ;# overlap resistors at end contacts
2945 set well_res_overlap 0 ;# not a well resistor
2946 set end_contact_type "" ;# no contacts for metal resistors
2947 set end_overlap_cont 0 ;# additional end overlap on sides
Tim Edwards0ee0f182020-11-21 16:15:07 -05002948 set vias 0 ;# add vias over contacts
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002949 set res_idtype none
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002950
2951 # Set a local variable for each parameter (e.g., $l, $w, etc.)
2952 foreach key [dict keys $parameters] {
2953 set $key [dict get $parameters $key]
2954 }
2955
2956 if {![dict exists $parameters end_contact_size]} {
2957 set end_contact_size $contact_size
2958 }
2959
2960 # Draw the resistor and endcaps
2961 pushbox
2962 box size 0 0
2963 pushbox
2964 set hw [/ $w 2.0]
2965 set hl [/ $l 2.0]
2966 box grow n ${hl}um
2967 box grow s ${hl}um
2968 box grow e ${hw}um
2969 box grow w ${hw}um
2970
2971 pushbox
2972 box grow n ${res_to_endcont}um
2973 box grow s ${res_to_endcont}um
2974 if {$well_res_overlap > 0} {
2975 set well_extend [+ ${well_res_overlap} [/ ${end_contact_size} 2.0] ${end_surround}]
2976 box grow n ${well_extend}um
2977 box grow s ${well_extend}um
2978 paint ${well_res_type}
2979 } else {
2980 paint ${end_type}
2981 }
2982 set cext [sky130::getbox]
2983 popbox
2984
2985 if {$well_res_overlap > 0} {
2986 erase ${well_res_type}
2987 } else {
2988 erase ${end_type}
2989 }
2990 paint ${res_type}
Tim Edwardsbf5ec172020-08-09 14:04:00 -04002991 if {"$res_idtype" != "none"} {
2992 box grow c 2
2993 paint ${res_idtype}
2994 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -04002995 popbox
2996
2997 # Reduce contact sizes by (end type) surround so that
2998 # the contact area edges match the device type width.
2999 # (Minimum dimensions will be enforced by the contact drawing routine)
3000 set epl [- ${w} [* ${end_surround} 2]] ;# end contact width
3001
3002 # Reduce end material size for well resistor types
3003 if {$well_res_overlap > 0} {
3004 set epl [- ${epl} [* ${well_res_overlap} 2]]
3005 }
3006
3007 # Reduce by coverage percentage unless overlapping at contacts
3008 if {(${roverlap} == 0) && (${endcov} > 0)} {
3009 set cpl [* ${epl} [/ ${endcov} 100.0]]
3010 } else {
3011 set cpl $epl
3012 }
3013
3014 # Ensure additional overlap of diffusion contact if required
3015 set dov [* ${end_overlap_cont} 2]
3016 if {[- ${epl} ${cpl}] < $dov} {
3017 set cpl [- ${epl} $dov] ;# additional end contact width
3018 }
3019
3020 set hepl [+ [/ ${epl} 2.0] ${end_surround}]
3021 set hesz [/ ${end_contact_size} 2.0]
3022
3023 # LV substrate diffusion types have a different surround requirement
3024 set lv_sub_types {"psd" "nsd"}
3025 if {[lsearch $lv_sub_types $end_type] < 0} {
3026 set hesz [+ ${hesz} ${end_surround}]
3027 }
3028
3029 # Top end material & contact
3030 pushbox
3031 box move n ${hl}um
3032 box move n ${res_to_endcont}um
3033
3034 pushbox
3035 box size 0 0
3036 box grow n ${hesz}um
3037 box grow s ${hesz}um
3038 box grow e ${hepl}um
3039 box grow w ${hepl}um
3040 paint ${end_type}
3041 set cext [sky130::unionbox $cext [sky130::getbox]]
3042 popbox
3043
3044 if {${end_contact_type} != ""} {
Tim Edwards0ee0f182020-11-21 16:15:07 -05003045 # Draw via over contact first
3046 if {$vias != 0} {
3047 pushbox
3048 set ch $res_to_endcont
3049 if {$ch < $via_size} {set ch $via_size}
3050 set cw $epl
3051 if {$cw < $via_size} {set cw $via_size}
3052 box grow n [/ $via_size 2]um
3053 box grow s [- $ch [/ $via_size 2]]um
3054 box grow w [/ $cw 2]um
3055 box grow e [/ $cw 2]um
3056 sky130::mcon_draw
3057 popbox
3058 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003059 set cext [sky130::unionbox $cext [sky130::draw_contact ${cpl} 0 \
3060 ${end_surround} ${metal_surround} ${end_contact_size} \
3061 ${end_type} ${end_contact_type} li horz]]
3062 }
3063 popbox
3064
3065 # Bottom end material & contact
3066 pushbox
3067 box move s ${hl}um
3068 box move s ${res_to_endcont}um
3069
3070 pushbox
3071 box size 0 0
3072 box grow n ${hesz}um
3073 box grow s ${hesz}um
3074 box grow e ${hepl}um
3075 box grow w ${hepl}um
3076 paint ${end_type}
3077 set cext [sky130::unionbox $cext [sky130::getbox]]
3078 popbox
3079
3080 if {${end_contact_type} != ""} {
Tim Edwards0ee0f182020-11-21 16:15:07 -05003081 # Draw via over contact first
3082 if {$vias != 0} {
3083 pushbox
3084 set ch $res_to_endcont
3085 if {$ch < $via_size} {set ch $via_size}
3086 set cw $epl
3087 if {$cw < $via_size} {set cw $via_size}
3088 box grow n [- $ch [/ $via_size 2]]um
3089 box grow s [/ $via_size 2]um
3090 box grow w [/ $cw 2]um
3091 box grow e [/ $cw 2]um
3092 sky130::mcon_draw
3093 popbox
3094 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003095 set cext [sky130::unionbox $cext [sky130::draw_contact ${cpl} 0 \
3096 ${end_surround} ${metal_surround} ${end_contact_size} \
3097 ${end_type} ${end_contact_type} li horz]]
3098 }
3099 popbox
3100
3101 popbox
3102 return $cext
3103}
3104
3105#----------------------------------------------------------------
3106# Resistor: Draw a single device in snake geometry
3107#----------------------------------------------------------------
3108
3109proc sky130::res_snake_device {nf parameters} {
3110 # nf is the number of fingers of the snake geometry
3111
3112 # Epsilon for avoiding round-off errors
3113 set eps 0.0005
3114
3115 # Set local default values if they are not in parameters
3116 set endcov 100 ;# percent coverage of end contacts
3117 set well_res_overlap 0 ;# not a well resistor
3118 set end_contact_type "" ;# no contacts for metal resistors
3119 set mask_clearance 0 ;# additional length to clear mask
3120
3121 # Set a local variable for each parameter (e.g., $l, $w, etc.)
3122 foreach key [dict keys $parameters] {
3123 set $key [dict get $parameters $key]
3124 }
3125
3126 if {![dict exists $parameters end_contact_size]} {
3127 set end_contact_size $contact_size
3128 }
3129
3130 # Compute half width and length
3131 set hw [/ $w 2.0]
3132 set hl [/ $l 2.0]
3133
3134 # Reduce contact sizes by (end type) surround so that
3135 # the contact area edges match the device type width.
3136 # (Minimum dimensions will be enforced by the contact drawing routine)
3137 set epl [- ${w} [* ${end_surround} 2]] ;# end contact width
3138
3139 # Reduce contact size for well resistor types
3140 if {$well_res_overlap > 0} {
3141 set epl [- ${epl} [* ${well_res_overlap} 2]]
3142 }
3143
3144 # Reduce contact part of end by coverage percentage
3145 if {${endcov} > 0} {
3146 set cpl [* ${epl} [/ ${endcov} 100.0]]
3147 } else {
3148 set cpl $epl
3149 }
3150
3151 set hepl [+ [/ ${epl} 2.0] ${end_surround}]
3152 set hesz [+ [/ ${end_contact_size} 2.0] ${end_surround}]
3153
3154 pushbox
3155 box size 0 0 ;# Position is taken from caller
3156
3157 # Front end contact (always bottom)
3158 pushbox
3159 box move s ${hl}um
3160 pushbox
3161 box move s ${mask_clearance}um
3162 box move s ${res_to_endcont}um
3163
3164 pushbox
3165 box size 0 0
3166 box grow n ${hesz}um
3167 box grow s ${hesz}um
3168 box grow e ${hepl}um
3169 box grow w ${hepl}um
3170 paint ${end_type}
3171 set cext [sky130::getbox]
3172 popbox
3173
3174 if {${end_contact_type} != ""} {
3175 set cext [sky130::draw_contact ${cpl} 0 \
3176 ${end_surround} ${metal_surround} ${end_contact_size} \
3177 ${end_type} ${end_contact_type} li horz]
3178 }
3179 popbox
3180
3181 # Draw portion between resistor end and contact.
3182 box grow e ${hw}um
3183 box grow w ${hw}um
3184 pushbox
3185 box grow s ${mask_clearance}um
3186 paint ${res_type}
3187 popbox
3188 box move s ${mask_clearance}um
3189 box grow s ${res_to_endcont}um
3190 if {$well_res_overlap > 0} {
3191 set well_extend [+ ${well_res_overlap} [/ ${end_contact_size} 2.0] ${end_surround}]
3192 box grow s ${well_extend}um
3193 paint ${well_res_type}
3194 } else {
3195 paint ${end_type}
3196 }
3197 set cext [sky130::unionbox $cext [sky130::getbox]]
3198 popbox
3199
3200 # Draw the resistor and endcaps
3201 pushbox
3202 box grow n ${hl}um
3203 box grow s ${hl}um
3204 box grow e ${hw}um
3205 box grow w ${hw}um
3206
3207 # Capture these extents in the bounding box in case both contacts
3208 # are on one side.
3209 set cext [sky130::unionbox $cext [sky130::getbox]]
3210
3211 set deltax [+ ${res_spacing} ${w}]
3212 set deltay [- ${l} ${w}]
3213 for {set i 0} {$i < [- $nf 1]} {incr i} {
3214 paint ${res_type}
3215 pushbox
3216 if {[% $i 2] == 0} {
3217 box move n ${deltay}um
3218 }
3219 box height ${w}um
3220 box width ${deltax}um
3221 paint ${res_type}
3222 popbox
3223 box move e ${deltax}um
3224 }
3225 paint ${res_type}
3226 # Capture these extents in the bounding box
3227 set cext [sky130::unionbox $cext [sky130::getbox]]
3228 popbox
3229
3230 # Move box to last finger
3231 set lastf [* [- $nf 1] $deltax]
3232 box move e ${lastf}um
3233
3234 # Back-end contact (top or bottom, depending if odd or even turns)
3235 pushbox
3236
3237 if {[% $nf 2] == 1} {
3238 set dir n
3239 } else {
3240 set dir s
3241 }
3242 box move $dir ${hl}um
3243 pushbox
3244 box move $dir ${mask_clearance}um
3245 box move $dir ${res_to_endcont}um
3246
3247 pushbox
3248 box size 0 0
3249 box grow n ${hesz}um
3250 box grow s ${hesz}um
3251 box grow e ${hepl}um
3252 box grow w ${hepl}um
3253 paint ${end_type}
3254 set cext [sky130::unionbox $cext [sky130::getbox]]
3255 popbox
3256
3257 if {${end_contact_type} != ""} {
3258 set cext [sky130::unionbox $cext [sky130::draw_contact ${cpl} 0 \
3259 ${end_surround} ${metal_surround} ${end_contact_size} \
3260 ${end_type} ${end_contact_type} li horz]]
3261 }
3262 popbox
3263 # Draw portion between resistor end and contact.
3264 box grow e ${hw}um
3265 box grow w ${hw}um
3266 pushbox
3267 box grow $dir ${mask_clearance}um
3268 paint ${res_type}
3269 popbox
3270 box move $dir ${mask_clearance}um
3271 box grow $dir ${res_to_endcont}um
3272
3273 if {$well_res_overlap > 0} {
3274 set well_extend [+ ${well_res_overlap} [/ ${end_contact_size} 2.0] ${end_surround}]
3275 box grow $dir ${well_extend}um
3276 paint ${well_res_type}
3277 } else {
3278 paint ${end_type}
3279 }
3280 popbox
3281
3282 popbox
3283 return $cext
3284}
3285
3286#----------------------------------------------------------------
3287# Resistor: Draw the tiled device
3288#----------------------------------------------------------------
3289
3290proc sky130::res_draw {parameters} {
3291 tech unlock *
3292 set savesnap [snap]
3293 snap internal
3294
3295 # Set defaults if they are not in parameters
3296 set snake 0 ;# some resistors don't allow snake geometry
3297 set roverlap 0 ;# overlap resistors at contacts
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003298 set guard 0 ;# draw a guard ring
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003299 set plus_diff_type nsd ;# guard ring diffusion type
3300 set overlap_compress 0 ;# special Y distance compression
3301 set well_res_overlap 0 ;# additional well extension behind contact
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003302 set res_diff_spacing 0 ;# spacing from resistor to diffusion
3303 set res_idtype none
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003304
3305 # Set a local variable for each parameter (e.g., $l, $w, etc.)
3306 foreach key [dict keys $parameters] {
3307 set $key [dict get $parameters $key]
3308 }
3309
3310 # For devices where inter-device space is smaller than device-to-guard ring
3311 if {![dict exists $parameters end_to_end_space]} {
3312 set end_to_end_space $end_spacing
3313 }
3314
3315 if {![dict exists $parameters end_contact_size]} {
3316 set end_contact_size $contact_size
3317 }
3318
3319 # Normalize distance units to microns
3320 set w [magic::spice2float $w]
3321 set l [magic::spice2float $l]
3322
3323 pushbox
3324 box values 0 0 0 0
3325
3326 # Determine the base device dimensions by drawing one device
3327 # while all layers are locked (nothing drawn). This allows the
3328 # base drawing routine to do complicated geometry without having
3329 # to duplicate it here with calculations.
3330
3331 tech lock *
3332 set nf $nx
3333 if {($snake == 1) && ($nx == 1)} {set snake 0}
3334 if {$snake == 1} {
3335 set bbox [sky130::res_snake_device $nf $parameters]
3336 set nx 1
3337 } else {
3338 set bbox [sky130::res_device $parameters]
3339 }
3340 # puts stdout "Diagnostic: Device bounding box e $bbox (um)"
3341 tech unlock *
3342
3343 set fw [- [lindex $bbox 2] [lindex $bbox 0]]
3344 set fh [- [lindex $bbox 3] [lindex $bbox 1]]
3345 set lw [+ [lindex $bbox 2] [lindex $bbox 0]]
3346 set lh [+ [lindex $bbox 3] [lindex $bbox 1]]
3347
3348 # Determine tile width and height (depends on overlap)
3349 # Snake resistors cannot overlap.
3350 # However, snake resistors with an odd number of fingers can
3351 # compress the space if overlap_compress is defined
3352
3353 if {($roverlap == 1) && ($snake == 1) && ([% $nf 2] == 1) && ($m > 1)} {
3354 set dy [- $fh $overlap_compress]
3355 } elseif {($roverlap == 0) || ($snake == 1)} {
3356 set dy [+ $fh $end_to_end_space]
3357 } else {
3358 # overlap poly
3359 set dy [- $fh [+ [* [+ $end_surround $well_res_overlap] 2.0] $end_contact_size]]
3360 }
3361 set dx [+ $fw $res_spacing]
3362
3363 # Determine core width and height
3364 set corex [+ [* [- $nx 1] $dx] $fw]
3365 set corey [+ [* [- $m 1] $dy] $fh]
3366 set corellx [/ [+ [- $corex $fw] $lw] 2.0]
3367 set corelly [/ [+ [- $corey $fh] $lh] 2.0]
3368
3369 set lv_sub_types {"psd" "nsd"}
3370 if {[lsearch $lv_sub_types $plus_diff_type] >= 0} {
3371 set guard_diff_surround 0
3372 } else {
3373 set guard_diff_surround ${diff_surround}
3374 }
3375
3376 if {$guard != 0} {
3377 # Calculate guard ring size (measured to contact center)
3378 set gx [+ $corex [* 2.0 [+ $res_diff_spacing $guard_diff_surround]] $contact_size]
3379 set gy [+ $corey [* 2.0 [+ $end_spacing $guard_diff_surround]] $contact_size]
3380
3381 # Draw the guard ring first, because well resistors are on the substrate plane
3382 sky130::guard_ring $gx $gy $parameters
3383 }
3384
3385 pushbox
3386 box move w ${corellx}um
3387 box move s ${corelly}um
3388 # puts "Device position at = [sky130::getbox]"
3389 for {set xp 0} {$xp < $nx} {incr xp} {
3390 pushbox
3391 for {set yp 0} {$yp < $m} {incr yp} {
3392 if {$snake == 1} {
3393 sky130::res_snake_device $nf $parameters
3394 } else {
3395 sky130::res_device $parameters
3396 }
3397 box move n ${dy}um
3398 }
3399 popbox
3400 box move e ${dx}um
3401 }
3402 popbox
3403 popbox
3404
3405 snap $savesnap
3406 tech revert
3407}
3408
3409#----------------------------------------------------------------
3410
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003411proc sky130::sky130_fd_pr__res_generic_po_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003412
3413 # Set a local variable for each rule in ruleset
3414 foreach key [dict keys $sky130::ruleset] {
3415 set $key [dict get $sky130::ruleset $key]
3416 }
3417
Tim Edwardsf788cea2021-04-20 12:43:52 -04003418 # Handle options related to guard ring type (high/low voltage, nwell/psub)
Tim Edwards8469aa62020-11-29 12:42:25 -05003419 if {[dict exists $parameters hv_guard]} {
Tim Edwardsf788cea2021-04-20 12:43:52 -04003420 set use_hv_guard [dict get $parameters hv_guard]
3421 } else {
3422 set use_hv_guard 0
3423 }
3424 if {[dict exists $parameters n_guard]} {
3425 set use_n_guard [dict get $parameters n_guard]
3426 } else {
3427 set use_n_guard 0
3428 }
3429
3430 if {$use_hv_guard == 1} {
3431 if {$use_n_guard == 1} {
Tim Edwards8469aa62020-11-29 12:42:25 -05003432 set gdifftype mvnsd
3433 set gdiffcont mvnsc
Tim Edwards8469aa62020-11-29 12:42:25 -05003434 } else {
Tim Edwardsf788cea2021-04-20 12:43:52 -04003435 set gdifftype mvpsd
3436 set gdiffcont mvpsc
3437 }
3438 set gsurround 0.33
3439 } else {
3440 if {$use_n_guard == 1} {
Tim Edwards8469aa62020-11-29 12:42:25 -05003441 set gdifftype nsd
3442 set gdiffcont nsc
Tim Edwardsf788cea2021-04-20 12:43:52 -04003443 } else {
3444 set gdifftype psd
3445 set gdiffcont psc
Tim Edwards8469aa62020-11-29 12:42:25 -05003446 }
Tim Edwardsf788cea2021-04-20 12:43:52 -04003447 set gsurround $sub_surround
3448 }
3449 if {$use_n_guard == 1} {
3450 set gsubtype nwell
3451 } else {
3452 set gsubtype psub
Tim Edwards8469aa62020-11-29 12:42:25 -05003453 }
3454
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003455 set newdict [dict create \
3456 res_type npres \
3457 end_type poly \
3458 end_contact_type pc \
Tim Edwards8469aa62020-11-29 12:42:25 -05003459 plus_diff_type $gdifftype \
3460 plus_contact_type $gdiffcont \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003461 sub_type $gsubtype \
Tim Edwards8469aa62020-11-29 12:42:25 -05003462 guard_sub_surround $gsurround \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003463 end_surround $poly_surround \
3464 end_spacing 0.48 \
3465 end_to_end_space 0.52 \
3466 res_to_endcont $res_to_cont \
3467 res_spacing $poly_spacing \
3468 res_diff_spacing 0.48 \
3469 mask_clearance 0.52 \
3470 overlap_compress 0.36 \
3471 ]
Tim Edwards8469aa62020-11-29 12:42:25 -05003472
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003473 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3474 return [sky130::res_draw $drawdict]
3475}
3476
3477#----------------------------------------------------------------
3478
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003479proc sky130::sky130_fd_pr__res_high_po_0p35_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003480
3481 # Set a local variable for each rule in ruleset
3482 foreach key [dict keys $sky130::ruleset] {
3483 set $key [dict get $sky130::ruleset $key]
3484 }
3485
Tim Edwardsf788cea2021-04-20 12:43:52 -04003486 # Handle options related to guard ring type (high/low voltage, nwell/psub)
3487 if {[dict exists $parameters hv_guard]} {
3488 set use_hv_guard [dict get $parameters hv_guard]
3489 } else {
3490 set use_hv_guard 0
3491 }
3492 if {[dict exists $parameters n_guard]} {
3493 set use_n_guard [dict get $parameters n_guard]
3494 } else {
3495 set use_n_guard 0
3496 }
3497
3498 if {$use_hv_guard == 1} {
3499 if {$use_n_guard == 1} {
3500 set gdifftype mvnsd
3501 set gdiffcont mvnsc
3502 } else {
3503 set gdifftype mvpsd
3504 set gdiffcont mvpsc
3505 }
3506 set gsurround 0.33
3507 } else {
3508 if {$use_n_guard == 1} {
3509 set gdifftype nsd
3510 set gdiffcont nsc
3511 } else {
3512 set gdifftype psd
3513 set gdiffcont psc
3514 }
3515 set gsurround $sub_surround
3516 }
3517 if {$use_n_guard == 1} {
3518 set gsubtype nwell
3519 set gresdiff_spacing 0.785
3520 set gresdiff_end 0.525
3521 } else {
3522 set gsubtype psub
3523 set gresdiff_spacing 0.48
3524 set gresdiff_end 0.48
3525 }
3526
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003527 set newdict [dict create \
3528 res_type ppres \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003529 res_idtype res0p35 \
3530 end_type xpc \
3531 end_contact_type xpc \
3532 end_contact_size 0 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003533 plus_diff_type $gdifftype \
3534 plus_contact_type $gdiffcont \
3535 sub_type $gsubtype \
3536 guard_sub_surround $gsurround \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003537 end_surround $poly_surround \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003538 end_spacing $gresdiff_end \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003539 end_to_end_space 0.52 \
3540 end_contact_size 0.19 \
3541 res_to_endcont 1.985 \
3542 res_spacing 1.24 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003543 res_diff_spacing $gresdiff_spacing \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003544 mask_clearance 0.52 \
3545 overlap_compress 0.36 \
3546 ]
3547 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3548 return [sky130::res_draw $drawdict]
3549}
3550
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003551proc sky130::sky130_fd_pr__res_high_po_0p69_draw {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003552
3553 # Set a local variable for each rule in ruleset
3554 foreach key [dict keys $sky130::ruleset] {
3555 set $key [dict get $sky130::ruleset $key]
3556 }
3557
Tim Edwardsf788cea2021-04-20 12:43:52 -04003558 # Handle options related to guard ring type (high/low voltage, nwell/psub)
3559 if {[dict exists $parameters hv_guard]} {
3560 set use_hv_guard [dict get $parameters hv_guard]
3561 } else {
3562 set use_hv_guard 0
3563 }
3564 if {[dict exists $parameters n_guard]} {
3565 set use_n_guard [dict get $parameters n_guard]
3566 } else {
3567 set use_n_guard 0
3568 }
3569
3570 if {$use_hv_guard == 1} {
3571 if {$use_n_guard == 1} {
3572 set gdifftype mvnsd
3573 set gdiffcont mvnsc
3574 } else {
3575 set gdifftype mvpsd
3576 set gdiffcont mvpsc
3577 }
3578 set gsurround 0.33
3579 } else {
3580 if {$use_n_guard == 1} {
3581 set gdifftype nsd
3582 set gdiffcont nsc
3583 } else {
3584 set gdifftype psd
3585 set gdiffcont psc
3586 }
3587 set gsurround $sub_surround
3588 }
3589 if {$use_n_guard == 1} {
3590 set gsubtype nwell
3591 set gresdiff_spacing 0.615
3592 set gresdiff_end 0.525
3593 } else {
3594 set gsubtype psub
3595 set gresdiff_spacing 0.48
3596 set gresdiff_end 0.48
3597 }
3598
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003599 set newdict [dict create \
3600 res_type ppres \
3601 res_idtype res0p69 \
3602 end_type xpc \
3603 end_contact_type xpc \
3604 end_contact_size 0 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003605 plus_diff_type $gdifftype \
3606 plus_contact_type $gdiffcont \
3607 sub_type $gsubtype \
3608 guard_sub_surround $gsurround \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003609 end_surround $poly_surround \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003610 end_spacing $gresdiff_end \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003611 end_to_end_space 0.52 \
3612 end_contact_size 0.19 \
3613 res_to_endcont 1.985 \
3614 res_spacing 1.24 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003615 res_diff_spacing $gresdiff_spacing \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003616 mask_clearance 0.52 \
3617 overlap_compress 0.36 \
3618 ]
3619 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3620 return [sky130::res_draw $drawdict]
3621}
3622
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003623proc sky130::sky130_fd_pr__res_high_po_1p41_draw {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003624
3625 # Set a local variable for each rule in ruleset
3626 foreach key [dict keys $sky130::ruleset] {
3627 set $key [dict get $sky130::ruleset $key]
3628 }
3629
Tim Edwardsf788cea2021-04-20 12:43:52 -04003630 # Handle options related to guard ring type (high/low voltage, nwell/psub)
3631 if {[dict exists $parameters hv_guard]} {
3632 set use_hv_guard [dict get $parameters hv_guard]
3633 } else {
3634 set use_hv_guard 0
3635 }
3636 if {[dict exists $parameters n_guard]} {
3637 set use_n_guard [dict get $parameters n_guard]
3638 } else {
3639 set use_n_guard 0
3640 }
3641
3642 if {$use_hv_guard == 1} {
3643 if {$use_n_guard == 1} {
3644 set gdifftype mvnsd
3645 set gdiffcont mvnsc
3646 } else {
3647 set gdifftype mvpsd
3648 set gdiffcont mvpsc
3649 }
3650 set gsurround 0.33
3651 } else {
3652 if {$use_n_guard == 1} {
3653 set gdifftype nsd
3654 set gdiffcont nsc
3655 } else {
3656 set gdifftype psd
3657 set gdiffcont psc
3658 }
3659 set gsurround $sub_surround
3660 }
3661 if {$use_n_guard == 1} {
3662 set gsubtype nwell
3663 set gresdiff_spacing 0.525
3664 set gresdiff_end 0.525
3665 } else {
3666 set gsubtype psub
3667 set gresdiff_spacing 0.48
3668 set gresdiff_end 0.48
3669 }
3670
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003671 set newdict [dict create \
3672 res_type ppres \
3673 res_idtype res1p41 \
3674 end_type xpc \
3675 end_contact_type xpc \
3676 end_contact_size 0 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003677 plus_diff_type $gdifftype \
3678 plus_contact_type $gdiffcont \
3679 sub_type $gsubtype \
3680 guard_sub_surround $gsurround \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003681 end_surround $poly_surround \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003682 end_spacing $gresdiff_end \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003683 end_to_end_space 0.52 \
3684 end_contact_size 0.19 \
3685 res_to_endcont 1.985 \
3686 res_spacing 1.24 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003687 res_diff_spacing $gresdiff_spacing \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003688 mask_clearance 0.52 \
3689 overlap_compress 0.36 \
3690 ]
3691 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3692 return [sky130::res_draw $drawdict]
3693}
3694
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003695proc sky130::sky130_fd_pr__res_high_po_2p85_draw {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003696
3697 # Set a local variable for each rule in ruleset
3698 foreach key [dict keys $sky130::ruleset] {
3699 set $key [dict get $sky130::ruleset $key]
3700 }
3701
Tim Edwardsf788cea2021-04-20 12:43:52 -04003702 # Handle options related to guard ring type (high/low voltage, nwell/psub)
3703 if {[dict exists $parameters hv_guard]} {
3704 set use_hv_guard [dict get $parameters hv_guard]
3705 } else {
3706 set use_hv_guard 0
3707 }
3708 if {[dict exists $parameters n_guard]} {
3709 set use_n_guard [dict get $parameters n_guard]
3710 } else {
3711 set use_n_guard 0
3712 }
3713
3714 if {$use_hv_guard == 1} {
3715 if {$use_n_guard == 1} {
3716 set gdifftype mvnsd
3717 set gdiffcont mvnsc
3718 } else {
3719 set gdifftype mvpsd
3720 set gdiffcont mvpsc
3721 }
3722 set gsurround 0.33
3723 } else {
3724 if {$use_n_guard == 1} {
3725 set gdifftype nsd
3726 set gdiffcont nsc
3727 } else {
3728 set gdifftype psd
3729 set gdiffcont psc
3730 }
3731 set gsurround $sub_surround
3732 }
3733 if {$use_n_guard == 1} {
3734 set gsubtype nwell
3735 set gresdiff_spacing 0.525
3736 set gresdiff_end 0.525
3737 } else {
3738 set gsubtype psub
3739 set gresdiff_spacing 0.48
3740 set gresdiff_end 0.48
3741 }
3742
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003743 set newdict [dict create \
3744 res_type ppres \
3745 res_idtype res2p85 \
3746 end_type xpc \
3747 end_contact_type xpc \
3748 end_contact_size 0 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003749 plus_diff_type $gdifftype \
3750 plus_contact_type $gdiffcont \
3751 sub_type $gsubtype \
3752 guard_sub_surround $gsurround \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003753 end_surround $poly_surround \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003754 end_spacing $gresdiff_end \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003755 end_to_end_space 0.52 \
3756 end_contact_size 0.19 \
3757 res_to_endcont 1.985 \
3758 res_spacing 1.24 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003759 res_diff_spacing $gresdiff_spacing \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003760 mask_clearance 0.52 \
3761 overlap_compress 0.36 \
3762 ]
3763 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3764 return [sky130::res_draw $drawdict]
3765}
3766
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003767proc sky130::sky130_fd_pr__res_high_po_5p73_draw {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003768
3769 # Set a local variable for each rule in ruleset
3770 foreach key [dict keys $sky130::ruleset] {
3771 set $key [dict get $sky130::ruleset $key]
3772 }
3773
Tim Edwardsf788cea2021-04-20 12:43:52 -04003774 # Handle options related to guard ring type (high/low voltage, nwell/psub)
3775 if {[dict exists $parameters hv_guard]} {
3776 set use_hv_guard [dict get $parameters hv_guard]
3777 } else {
3778 set use_hv_guard 0
3779 }
3780 if {[dict exists $parameters n_guard]} {
3781 set use_n_guard [dict get $parameters n_guard]
3782 } else {
3783 set use_n_guard 0
3784 }
3785
3786 if {$use_hv_guard == 1} {
3787 if {$use_n_guard == 1} {
3788 set gdifftype mvnsd
3789 set gdiffcont mvnsc
3790 } else {
3791 set gdifftype mvpsd
3792 set gdiffcont mvpsc
3793 }
3794 set gsurround 0.33
3795 } else {
3796 if {$use_n_guard == 1} {
3797 set gdifftype nsd
3798 set gdiffcont nsc
3799 } else {
3800 set gdifftype psd
3801 set gdiffcont psc
3802 }
3803 set gsurround $sub_surround
3804 }
3805 if {$use_n_guard == 1} {
3806 set gsubtype nwell
3807 set gresdiff_spacing 0.525
3808 set gresdiff_end 0.525
3809 } else {
3810 set gsubtype psub
3811 set gresdiff_spacing 0.48
3812 set gresdiff_end 0.48
3813 }
3814
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003815 set newdict [dict create \
3816 res_type ppres \
3817 res_idtype res5p73 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003818 end_type xpc \
3819 end_contact_type xpc \
3820 end_contact_size 0 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003821 plus_diff_type $gdifftype \
3822 plus_contact_type $gdiffcont \
3823 sub_type $gsubtype \
3824 guard_sub_surround $gsurround \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003825 end_surround $poly_surround \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003826 end_spacing $gresdiff_end \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003827 end_to_end_space 0.52 \
3828 end_contact_size 0.19 \
3829 res_to_endcont 1.985 \
3830 res_spacing 1.24 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003831 res_diff_spacing $gresdiff_spacing \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003832 mask_clearance 0.52 \
3833 overlap_compress 0.36 \
3834 ]
3835 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3836 return [sky130::res_draw $drawdict]
3837}
3838
3839#----------------------------------------------------------------
3840
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003841proc sky130::sky130_fd_pr__res_xhigh_po_0p35_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003842
3843 # Set a local variable for each rule in ruleset
3844 foreach key [dict keys $sky130::ruleset] {
3845 set $key [dict get $sky130::ruleset $key]
3846 }
3847
Tim Edwardsf788cea2021-04-20 12:43:52 -04003848 # Handle options related to guard ring type (high/low voltage, nwell/psub)
3849 if {[dict exists $parameters hv_guard]} {
3850 set use_hv_guard [dict get $parameters hv_guard]
3851 } else {
3852 set use_hv_guard 0
3853 }
3854 if {[dict exists $parameters n_guard]} {
3855 set use_n_guard [dict get $parameters n_guard]
3856 } else {
3857 set use_n_guard 0
3858 }
3859
3860 if {$use_hv_guard == 1} {
3861 if {$use_n_guard == 1} {
3862 set gdifftype mvnsd
3863 set gdiffcont mvnsc
3864 } else {
3865 set gdifftype mvpsd
3866 set gdiffcont mvpsc
3867 }
3868 set gsurround 0.33
3869 } else {
3870 if {$use_n_guard == 1} {
3871 set gdifftype nsd
3872 set gdiffcont nsc
3873 } else {
3874 set gdifftype psd
3875 set gdiffcont psc
3876 }
3877 set gsurround $sub_surround
3878 }
3879 if {$use_n_guard == 1} {
3880 set gsubtype nwell
3881 set gresdiff_spacing 0.785
3882 set gresdiff_end 0.525
3883 } else {
3884 set gsubtype psub
3885 set gresdiff_spacing 0.48
3886 set gresdiff_end 0.48
3887 }
3888
Tim Edwards55f4d0e2020-07-05 15:41:02 -04003889 set newdict [dict create \
3890 res_type xpres \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003891 res_idtype res0p35 \
3892 end_type xpc \
3893 end_contact_type xpc \
3894 end_contact_size 0 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003895 plus_diff_type $gdifftype \
3896 plus_contact_type $gdiffcont \
3897 sub_type $gsubtype \
3898 guard_sub_surround $gsurround \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003899 end_surround $poly_surround \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003900 end_spacing $gresdiff_end \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003901 end_to_end_space 0.52 \
3902 end_contact_size 0.19 \
3903 res_to_endcont 1.985 \
3904 res_spacing 1.24 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003905 res_diff_spacing $gresdiff_spacing \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003906 mask_clearance 0.52 \
3907 overlap_compress 0.36 \
3908 ]
3909 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3910 return [sky130::res_draw $drawdict]
3911}
3912
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003913proc sky130::sky130_fd_pr__res_xhigh_po_0p69_draw {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003914
3915 # Set a local variable for each rule in ruleset
3916 foreach key [dict keys $sky130::ruleset] {
3917 set $key [dict get $sky130::ruleset $key]
3918 }
3919
Tim Edwardsf788cea2021-04-20 12:43:52 -04003920 # Handle options related to guard ring type (high/low voltage, nwell/psub)
3921 if {[dict exists $parameters hv_guard]} {
3922 set use_hv_guard [dict get $parameters hv_guard]
3923 } else {
3924 set use_hv_guard 0
3925 }
3926 if {[dict exists $parameters n_guard]} {
3927 set use_n_guard [dict get $parameters n_guard]
3928 } else {
3929 set use_n_guard 0
3930 }
3931
3932 if {$use_hv_guard == 1} {
3933 if {$use_n_guard == 1} {
3934 set gdifftype mvnsd
3935 set gdiffcont mvnsc
3936 } else {
3937 set gdifftype mvpsd
3938 set gdiffcont mvpsc
3939 }
3940 set gsurround 0.33
3941 } else {
3942 if {$use_n_guard == 1} {
3943 set gdifftype nsd
3944 set gdiffcont nsc
3945 } else {
3946 set gdifftype psd
3947 set gdiffcont psc
3948 }
3949 set gsurround $sub_surround
3950 }
3951 if {$use_n_guard == 1} {
3952 set gsubtype nwell
3953 set gresdiff_spacing 0.615
3954 set gresdiff_end 0.525
3955 } else {
3956 set gsubtype psub
3957 set gresdiff_spacing 0.48
3958 set gresdiff_end 0.48
3959 }
3960
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003961 set newdict [dict create \
3962 res_type xpres \
3963 res_idtype res0p69 \
3964 end_type xpc \
3965 end_contact_type xpc \
3966 end_contact_size 0 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003967 plus_diff_type $gdifftype \
3968 plus_contact_type $gdiffcont \
3969 sub_type $gsubtype \
3970 guard_sub_surround $gsurround \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003971 end_surround $poly_surround \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003972 end_spacing $gresdiff_end \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003973 end_to_end_space 0.52 \
3974 end_contact_size 0.19 \
3975 res_to_endcont 1.985 \
3976 res_spacing 1.24 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04003977 res_diff_spacing $gresdiff_spacing \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003978 mask_clearance 0.52 \
3979 overlap_compress 0.36 \
3980 ]
3981 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
3982 return [sky130::res_draw $drawdict]
3983}
3984
Tim Edwardsd7289eb2020-09-10 21:48:31 -04003985proc sky130::sky130_fd_pr__res_xhigh_po_1p41_draw {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04003986
3987 # Set a local variable for each rule in ruleset
3988 foreach key [dict keys $sky130::ruleset] {
3989 set $key [dict get $sky130::ruleset $key]
3990 }
3991
Tim Edwardsf788cea2021-04-20 12:43:52 -04003992 # Handle options related to guard ring type (high/low voltage, nwell/psub)
3993 if {[dict exists $parameters hv_guard]} {
3994 set use_hv_guard [dict get $parameters hv_guard]
3995 } else {
3996 set use_hv_guard 0
3997 }
3998 if {[dict exists $parameters n_guard]} {
3999 set use_n_guard [dict get $parameters n_guard]
4000 } else {
4001 set use_n_guard 0
4002 }
4003
4004 if {$use_hv_guard == 1} {
4005 if {$use_n_guard == 1} {
4006 set gdifftype mvnsd
4007 set gdiffcont mvnsc
4008 } else {
4009 set gdifftype mvpsd
4010 set gdiffcont mvpsc
4011 }
4012 set gsurround 0.33
4013 } else {
4014 if {$use_n_guard == 1} {
4015 set gdifftype nsd
4016 set gdiffcont nsc
4017 } else {
4018 set gdifftype psd
4019 set gdiffcont psc
4020 }
4021 set gsurround $sub_surround
4022 }
4023 if {$use_n_guard == 1} {
4024 set gsubtype nwell
4025 set gresdiff_spacing 0.525
4026 set gresdiff_end 0.525
4027 } else {
4028 set gsubtype psub
4029 set gresdiff_spacing 0.48
4030 set gresdiff_end 0.48
4031 }
4032
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004033 set newdict [dict create \
4034 res_type xpres \
4035 res_idtype res1p41 \
4036 end_type xpc \
4037 end_contact_type xpc \
4038 end_contact_size 0 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04004039 plus_diff_type $gdifftype \
4040 plus_contact_type $gdiffcont \
4041 sub_type $gsubtype \
4042 guard_sub_surround $gsurround \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004043 end_surround $poly_surround \
Tim Edwardsf788cea2021-04-20 12:43:52 -04004044 end_spacing $gresdiff_end \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004045 end_to_end_space 0.52 \
4046 end_contact_size 0.19 \
4047 res_to_endcont 1.985 \
4048 res_spacing 1.24 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04004049 res_diff_spacing $gresdiff_spacing \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004050 mask_clearance 0.52 \
4051 overlap_compress 0.36 \
4052 ]
4053 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4054 return [sky130::res_draw $drawdict]
4055}
4056
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004057proc sky130::sky130_fd_pr__res_xhigh_po_2p85_draw {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004058
4059 # Set a local variable for each rule in ruleset
4060 foreach key [dict keys $sky130::ruleset] {
4061 set $key [dict get $sky130::ruleset $key]
4062 }
4063
Tim Edwardsf788cea2021-04-20 12:43:52 -04004064 # Handle options related to guard ring type (high/low voltage, nwell/psub)
4065 if {[dict exists $parameters hv_guard]} {
4066 set use_hv_guard [dict get $parameters hv_guard]
4067 } else {
4068 set use_hv_guard 0
4069 }
4070 if {[dict exists $parameters n_guard]} {
4071 set use_n_guard [dict get $parameters n_guard]
4072 } else {
4073 set use_n_guard 0
4074 }
4075
4076 if {$use_hv_guard == 1} {
4077 if {$use_n_guard == 1} {
4078 set gdifftype mvnsd
4079 set gdiffcont mvnsc
4080 } else {
4081 set gdifftype mvpsd
4082 set gdiffcont mvpsc
4083 }
4084 set gsurround 0.33
4085 } else {
4086 if {$use_n_guard == 1} {
4087 set gdifftype nsd
4088 set gdiffcont nsc
4089 } else {
4090 set gdifftype psd
4091 set gdiffcont psc
4092 }
4093 set gsurround $sub_surround
4094 }
4095 if {$use_n_guard == 1} {
4096 set gsubtype nwell
4097 set gresdiff_spacing 0.525
4098 set gresdiff_end 0.525
4099 } else {
4100 set gsubtype psub
4101 set gresdiff_spacing 0.48
4102 set gresdiff_end 0.48
4103 }
4104
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004105 set newdict [dict create \
4106 res_type xpres \
4107 res_idtype res2p85 \
4108 end_type xpc \
4109 end_contact_type xpc \
4110 end_contact_size 0 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04004111 plus_diff_type $gdifftype \
4112 plus_contact_type $gdiffcont \
4113 sub_type $gsubtype \
4114 guard_sub_surround $gsurround \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004115 end_surround $poly_surround \
Tim Edwardsf788cea2021-04-20 12:43:52 -04004116 end_spacing $gresdiff_end \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004117 end_to_end_space 0.52 \
4118 end_contact_size 0.19 \
4119 res_to_endcont 1.985 \
4120 res_spacing 1.24 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04004121 res_diff_spacing $gresdiff_spacing \
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004122 mask_clearance 0.52 \
4123 overlap_compress 0.36 \
4124 ]
4125 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4126 return [sky130::res_draw $drawdict]
4127}
4128
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004129proc sky130::sky130_fd_pr__res_xhigh_po_5p73_draw {parameters} {
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004130
4131 # Set a local variable for each rule in ruleset
4132 foreach key [dict keys $sky130::ruleset] {
4133 set $key [dict get $sky130::ruleset $key]
4134 }
4135
Tim Edwardsf788cea2021-04-20 12:43:52 -04004136 # Handle options related to guard ring type (high/low voltage, nwell/psub)
4137 if {[dict exists $parameters hv_guard]} {
4138 set use_hv_guard [dict get $parameters hv_guard]
4139 } else {
4140 set use_hv_guard 0
4141 }
4142 if {[dict exists $parameters n_guard]} {
4143 set use_n_guard [dict get $parameters n_guard]
4144 } else {
4145 set use_n_guard 0
4146 }
4147
4148 if {$use_hv_guard == 1} {
4149 if {$use_n_guard == 1} {
4150 set gdifftype mvnsd
4151 set gdiffcont mvnsc
4152 } else {
4153 set gdifftype mvpsd
4154 set gdiffcont mvpsc
4155 }
4156 set gsurround 0.33
4157 } else {
4158 if {$use_n_guard == 1} {
4159 set gdifftype nsd
4160 set gdiffcont nsc
4161 } else {
4162 set gdifftype psd
4163 set gdiffcont psc
4164 }
4165 set gsurround $sub_surround
4166 }
4167 if {$use_n_guard == 1} {
4168 set gsubtype nwell
4169 set gresdiff_spacing 0.525
4170 set gresdiff_end 0.525
4171 } else {
4172 set gsubtype psub
4173 set gresdiff_spacing 0.48
4174 set gresdiff_end 0.48
4175 }
4176
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004177 set newdict [dict create \
4178 res_type xpres \
4179 res_idtype res5p73 \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004180 end_type xpc \
4181 end_contact_type xpc \
4182 end_contact_size 0 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04004183 plus_diff_type $gdifftype \
4184 plus_contact_type $gdiffcont \
4185 sub_type $gsubtype \
4186 guard_sub_surround $gsurround \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004187 end_surround $poly_surround \
Tim Edwardsf788cea2021-04-20 12:43:52 -04004188 end_spacing $gresdiff_end \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004189 end_to_end_space 0.52 \
4190 end_contact_size 0.19 \
4191 res_to_endcont 1.985 \
4192 res_spacing 1.24 \
Tim Edwardsf788cea2021-04-20 12:43:52 -04004193 res_diff_spacing $gresdiff_spacing \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004194 mask_clearance 0.52 \
4195 overlap_compress 0.36 \
4196 ]
4197 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4198 return [sky130::res_draw $drawdict]
4199}
4200
4201#----------------------------------------------------------------
4202
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004203proc sky130::sky130_fd_pr__res_generic_nd_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004204
4205 # Set a local variable for each rule in ruleset
4206 foreach key [dict keys $sky130::ruleset] {
4207 set $key [dict get $sky130::ruleset $key]
4208 }
4209
4210 set newdict [dict create \
4211 res_type rdn \
4212 end_type ndiff \
4213 end_contact_type ndc \
4214 plus_diff_type psd \
4215 plus_contact_type psc \
4216 sub_type psub \
4217 end_surround $diff_surround \
4218 end_spacing 0.44 \
4219 res_to_endcont 0.37 \
4220 res_spacing 0.30 \
4221 res_diff_spacing 0.44 \
4222 mask_clearance 0.22 \
4223 overlap_compress 0.36 \
4224 ]
4225 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4226 return [sky130::res_draw $drawdict]
4227}
4228
4229#----------------------------------------------------------------
4230
Tim Edwards0ee0f182020-11-21 16:15:07 -05004231proc sky130::sky130_fd_pr__res_generic_nd__hv_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004232
4233 # Set a local variable for each rule in ruleset
4234 foreach key [dict keys $sky130::ruleset] {
4235 set $key [dict get $sky130::ruleset $key]
4236 }
4237
4238 set newdict [dict create \
4239 res_type mvrdn \
4240 end_type mvndiff \
4241 end_contact_type mvndc \
4242 plus_diff_type mvpsd \
4243 plus_contact_type mvpsc \
4244 sub_type psub \
4245 end_surround $diff_surround \
4246 end_spacing 0.44 \
4247 res_to_endcont 0.37 \
4248 res_spacing 0.30 \
4249 res_diff_spacing 0.44 \
4250 mask_clearance 0.22 \
4251 overlap_compress 0.36 \
4252 ]
4253 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4254 return [sky130::res_draw $drawdict]
4255}
4256
4257#----------------------------------------------------------------
4258
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004259proc sky130::sky130_fd_pr__res_generic_pd_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004260
4261 # Set a local variable for each rule in ruleset
4262 foreach key [dict keys $sky130::ruleset] {
4263 set $key [dict get $sky130::ruleset $key]
4264 }
4265
4266 set newdict [dict create \
4267 res_type rdp \
4268 end_type pdiff \
4269 end_contact_type pdc \
4270 plus_diff_type nsd \
4271 plus_contact_type nsc \
4272 sub_type nwell \
4273 end_surround $diff_surround \
4274 end_spacing 0.44 \
4275 res_to_endcont 0.37 \
4276 res_spacing $diff_spacing \
4277 res_diff_spacing 0.44 \
4278 mask_clearance 0.22 \
4279 overlap_compress 0.36 \
4280 ]
4281 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4282 return [sky130::res_draw $drawdict]
4283}
4284
4285#----------------------------------------------------------------
4286
Tim Edwards0ee0f182020-11-21 16:15:07 -05004287proc sky130::sky130_fd_pr__res_generic_pd__hv_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004288
4289 # Set a local variable for each rule in ruleset
4290 foreach key [dict keys $sky130::ruleset] {
4291 set $key [dict get $sky130::ruleset $key]
4292 }
4293
4294 set newdict [dict create \
4295 res_type mvrdp \
4296 end_type mvpdiff \
4297 end_contact_type mvpdc \
4298 plus_diff_type mvnsd \
4299 plus_contact_type mvnsc \
4300 sub_type nwell \
4301 end_surround $diff_surround \
4302 guard_sub_surround 0.33 \
4303 end_spacing 0.44 \
4304 res_to_endcont 0.37 \
4305 res_spacing 0.30 \
4306 res_diff_spacing 0.44 \
4307 mask_clearance 0.22 \
4308 overlap_compress 0.36 \
4309 ]
4310 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4311 return [sky130::res_draw $drawdict]
4312}
4313
4314#----------------------------------------------------------------
4315
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004316proc sky130::sky130_fd_pr__res_iso_pw_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004317
4318 # Set a local variable for each rule in ruleset
4319 foreach key [dict keys $sky130::ruleset] {
4320 set $key [dict get $sky130::ruleset $key]
4321 }
4322
4323 set newdict [dict create \
4324 well_res_type pwell \
4325 res_type rpw \
4326 end_type psd \
4327 end_contact_type psc \
4328 plus_diff_type nsd \
4329 plus_contact_type nsc \
4330 sub_type dnwell \
4331 sub_surround 0.23 \
4332 guard_sub_type nwell \
4333 guard_sub_surround 0.63 \
4334 end_surround $diff_surround \
4335 end_spacing 0.63 \
4336 end_to_end_space 1.15 \
4337 end_overlap_cont 0.06 \
4338 end_contact_size 0.53 \
4339 overlap_compress -0.17 \
4340 res_to_endcont 0.265 \
4341 res_spacing 1.4 \
4342 res_diff_spacing 0.63 \
4343 well_res_overlap 0.2 \
4344 ]
4345 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4346 return [sky130::res_draw $drawdict]
4347}
4348
4349#----------------------------------------------------------------
4350
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004351proc sky130::sky130_fd_pr__res_generic_l1_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004352
4353 # Set a local variable for each rule in ruleset
4354 foreach key [dict keys $sky130::ruleset] {
4355 set $key [dict get $sky130::ruleset $key]
4356 }
4357
4358 set newdict [dict create \
4359 guard 0 \
4360 res_type rli \
4361 end_type li \
4362 end_surround 0.0 \
4363 end_spacing 0.0 \
4364 res_to_endcont 0.2 \
4365 end_to_end_space 0.23 \
4366 res_spacing $metal_spacing \
4367 ]
4368 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4369 return [sky130::res_draw $drawdict]
4370}
4371
4372#----------------------------------------------------------------
4373
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004374proc sky130::sky130_fd_pr__res_generic_m1_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004375
4376 # Set a local variable for each rule in ruleset
4377 foreach key [dict keys $sky130::ruleset] {
4378 set $key [dict get $sky130::ruleset $key]
4379 }
4380
4381 set newdict [dict create \
4382 guard 0 \
4383 res_type rm1 \
4384 end_type m1 \
4385 end_surround 0.0 \
4386 end_spacing 0.0 \
4387 end_to_end_space 0.28 \
4388 res_to_endcont 0.2 \
4389 res_spacing $mmetal_spacing \
4390 ]
4391 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4392 return [sky130::res_draw $drawdict]
4393}
4394
4395#----------------------------------------------------------------
4396
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004397proc sky130::sky130_fd_pr__res_generic_m2_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004398
4399 # Set a local variable for each rule in ruleset
4400 foreach key [dict keys $sky130::ruleset] {
4401 set $key [dict get $sky130::ruleset $key]
4402 }
4403
4404 set newdict [dict create \
4405 guard 0 \
4406 res_type rm2 \
4407 end_type m2 \
4408 end_surround 0.0 \
4409 end_spacing 0.0 \
4410 end_to_end_space 0.28 \
4411 res_to_endcont 0.2 \
4412 res_spacing $mmetal_spacing \
4413 ]
4414 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4415 return [sky130::res_draw $drawdict]
4416}
4417
4418#----------------------------------------------------------------
4419
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004420proc sky130::sky130_fd_pr__res_generic_m3_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004421
4422 # Set a local variable for each rule in ruleset
4423 foreach key [dict keys $sky130::ruleset] {
4424 set $key [dict get $sky130::ruleset $key]
4425 }
4426
4427 set newdict [dict create \
4428 guard 0 \
4429 res_type rm3 \
4430 end_type m3 \
4431 end_surround 0.0 \
4432 end_spacing 0.0 \
4433 end_to_end_space 0.28 \
4434 res_to_endcont 0.2 \
4435 res_spacing $mmetal_spacing \
4436 ]
4437 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4438 return [sky130::res_draw $drawdict]
4439}
4440
4441#----------------------------------------------------------------
4442
4443#ifdef METAL5
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004444proc sky130::sky130_fd_pr__res_generic_m4_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004445
4446 # Set a local variable for each rule in ruleset
4447 foreach key [dict keys $sky130::ruleset] {
4448 set $key [dict get $sky130::ruleset $key]
4449 }
4450
4451 set newdict [dict create \
4452 guard 0 \
4453 res_type rm4 \
4454 end_type m4 \
4455 end_surround 0.0 \
4456 end_spacing 0.0 \
4457 end_to_end_space 0.28 \
4458 res_to_endcont 0.2 \
4459 res_spacing $mmetal_spacing \
4460 ]
4461 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4462 return [sky130::res_draw $drawdict]
4463}
4464
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004465proc sky130::sky130_fd_pr__res_generic_m5_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004466 # Set a local variable for each rule in ruleset
4467 foreach key [dict keys $sky130::ruleset] {
4468 set $key [dict get $sky130::ruleset $key]
4469 }
4470
4471 set newdict [dict create \
4472 guard 0 \
4473 res_type rm5 \
4474 end_type m5 \
4475 end_surround 0.0 \
4476 end_spacing 0.0 \
4477 end_to_end_space 1.6 \
4478 res_to_endcont 0.2 \
4479 res_spacing $mmetal_spacing \
4480 ]
4481 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
4482 return [sky130::res_draw $drawdict]
4483}
4484#endif (METAL5)
4485
4486#----------------------------------------------------------------
4487# Resistor total length computation
4488#----------------------------------------------------------------
4489
4490proc sky130::compute_ltot {parameters} {
4491 # In case snake not defined
4492 set snake 0
4493 set caplen 0
4494
4495 foreach key [dict keys $parameters] {
4496 set $key [dict get $parameters $key]
4497 }
4498
4499 set l [magic::spice2float $l]
4500 set l [magic::3digitpastdecimal $l]
4501
4502 # Compute total length. Use catch to prevent error in batch/scripted mode.
4503 if {$snake == 1} {
4504 catch {set magic::ltot_val [expr ($caplen * ($nx - 1)) + ($l * $nx) + ($nx - 1)]}
4505 } else {
4506 catch {set magic::ltot_val $l}
4507 }
4508}
4509
4510#----------------------------------------------------------------
4511# resistor: Check device parameters for out-of-bounds values
4512#----------------------------------------------------------------
4513
4514proc sky130::res_check {device parameters} {
4515
4516 # Set a local variable for each parameter (e.g., $l, $w, etc.)
4517 set snake 0
Tim Edwards0ee0f182020-11-21 16:15:07 -05004518 set guard 0
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004519 set sterm 0.0
4520 set caplen 0
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004521 set wmax 0
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004522
4523 foreach key [dict keys $parameters] {
4524 set $key [dict get $parameters $key]
4525 }
4526
4527 # Normalize distance units to microns
4528 set w [magic::spice2float $w]
4529 set w [magic::3digitpastdecimal $w]
4530 set l [magic::spice2float $l]
4531 set l [magic::3digitpastdecimal $l]
4532
4533 set val [magic::spice2float $val]
4534 set rho [magic::spice2float $rho]
4535
4536 # nf, m must be integer
4537 if {![string is int $nx]} {
4538 puts stderr "X repeat must be an integer!"
4539 dict set parameters nx 1
4540 }
4541 if {![string is int $m]} {
4542 puts stderr "Y repeat must be an integer!"
4543 dict set parameters m 1
4544 }
4545
4546 # Width always needs to be specified
4547 if {$w < $wmin} {
4548 puts stderr "Resistor width must be >= $wmin um"
4549 dict set parameters w $wmin
4550 }
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004551 if {$wmax > 0 && $w > $wmax} {
4552 puts stderr "Resistor width must be <= $wmax um"
4553 dict set parameters w $wmax
4554 }
4555
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004556 # Val and W specified - no L
4557 if {$l == 0} {
4558 set l [expr ($w - $dw) * $val / $rho]
4559 set l [magic::3digitpastdecimal $l]
4560 set stringval [magic::float2spice $val]
4561 dict set parameters l [magic::float2spice [expr $l * 1e-6]]
4562 # L and W specified - ignore Val if specified
4563 } else {
4564 if {$snake == 0} {
4565 set val [expr (2 * $term + $l * $rho) / ($w - $dw)]
4566 } else {
4567 set val [expr $rho * ($nx - 1) + ((2 * ($term + $sterm)) \
4568 + ($rho * $l * $nx) + ($rho * $caplen * ($nx - 1))) \
4569 / ($w - $dw)]
4570 }
4571 set val [magic::float2spice $val]
4572 dict set parameters val $val
4573 }
4574 if {$l < $lmin} {
4575 puts stderr "Resistor length must be >= $lmin um"
4576 dict set parameters l $lmin
4577 }
4578 if {$nx < 1} {
4579 puts stderr "X repeat must be >= 1"
4580 dict set parameters nx 1
4581 }
4582 if {$m < 1} {
4583 puts stderr "Y repeat must be >= 1"
4584 dict set parameters m 1
4585 }
4586
4587 # Snake resistors cannot have width greater than length
4588 if {$snake == 1} {
4589 if {$w > $l} {
4590 puts stderr "Snake resistor width must be < length"
4591 dict set parameters w $l
4592 }
4593 }
4594
Tim Edwards0ee0f182020-11-21 16:15:07 -05004595 # Check via coverage for syntax
4596 if {$guard == 1} {
4597 if {[catch {expr abs($viagb)}]} {
4598 puts stderr "Guard ring bottom via coverage must be numeric!"
4599 dict set parameters viagb 0
4600 } elseif {[expr abs($viagb)] > 100} {
4601 puts stderr "Guard ring bottom via coverage can't be more than 100%"
4602 dict set parameters viagb 100
4603 }
4604 if {[catch {expr abs($viagt)}]} {
4605 puts stderr "Guard ring top via coverage must be numeric!"
4606 dict set parameters viagt 0
4607 } elseif {[expr abs($viagt)] > 100} {
4608 puts stderr "Guard ring top via coverage can't be more than 100%"
4609 dict set parameters viagt 100
4610 }
4611 if {[catch {expr abs($viagr)}]} {
4612 puts stderr "Guard ring right via coverage must be numeric!"
4613 dict set parameters viagr 0
4614 } elseif {[expr abs($viagr)] > 100} {
4615 puts stderr "Guard ring right via coverage can't be more than 100%"
4616 dict set parameters viagr 100
4617 }
4618 if {[catch {expr abs($viagl)}]} {
4619 puts stderr "Guard ring left via coverage must be numeric!"
4620 dict set parameters viagl 0
4621 } elseif {[expr abs($viagl)] > 100} {
4622 puts stderr "Guard ring left via coverage can't be more than 100%"
4623 dict set parameters viagl 100
4624 }
4625 }
4626
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004627 # Diffusion resistors must satisfy diffusion-to-tap spacing of 20um.
4628 # Therefore the maximum of guard ring width or height cannot exceed 40um.
4629 # If in violation, reduce counts first, as these are easiest to recover
4630 # by duplicating the device and overlapping the wells.
4631 if {$device == "rdn" || $device == "rdp"} {
4632 set origm $m
4633 set orignx $nx
4634 while true {
4635 set xext [expr ($w + 0.8) * $nx + 1.0]
4636 set yext [expr ($l + 1.7) * $m + 1.7]
4637 if {[expr min($xext, $yext)] > 40.0} {
4638 if {$yext > 40.0 && $m > 1} {
4639 incr m -1
4640 } elseif {$xext > 40.0 && $nx > 1} {
4641 incr nx -1
4642 } elseif {$yext > 40.0} {
4643 set l 36.6
4644 puts -nonewline stderr "Diffusion resistor length must be < 36.6 um"
4645 puts stderr " to avoid tap spacing violation."
4646 dict set parameters l $l
4647 } elseif {$xext > 40.0} {
4648 set w 38.2
4649 puts -nonewline stderr "Diffusion resistor width must be < 38.2 um"
4650 puts stderr " to avoid tap spacing violation."
4651 dict set parameters w $w
4652 }
4653 } else {
4654 break
4655 }
4656 }
4657 if {$m != $origm} {
4658 puts stderr "Y repeat reduced to prevent tap distance violation"
4659 dict set parameters m $m
4660 }
4661 if {$nx != $orignx} {
4662 puts stderr "X repeat reduced to prevent tap distance violation"
4663 dict set parameters nx $nx
4664 }
4665 }
4666 sky130::compute_ltot $parameters
4667 return $parameters
4668}
4669
4670#----------------------------------------------------------------
4671
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004672proc sky130::sky130_fd_pr__res_iso_pw_check {parameters} {
4673 return [sky130::res_check sky130_fd_pr__res_iso_pw $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004674}
4675
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004676proc sky130::sky130_fd_pr__res_generic_po_check {parameters} {
4677 return [sky130::res_check sky130_fd_pr__res_generic_po $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004678}
4679
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004680proc sky130::sky130_fd_pr__res_high_po_0p35_check {parameters} {
4681 return [sky130::res_check sky130_fd_pr__res_high_po_0p35 $parameters]
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004682}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004683proc sky130::sky130_fd_pr__res_high_po_0p69_check {parameters} {
4684 return [sky130::res_check sky130_fd_pr__res_high_po_0p69 $parameters]
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004685}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004686proc sky130::sky130_fd_pr__res_high_po_1p41_check {parameters} {
4687 return [sky130::res_check sky130_fd_pr__res_high_po_1p41 $parameters]
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004688}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004689proc sky130::sky130_fd_pr__res_high_po_2p85_check {parameters} {
4690 return [sky130::res_check sky130_fd_pr__res_high_po_2p85 $parameters]
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004691}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004692proc sky130::sky130_fd_pr__res_high_po_5p73_check {parameters} {
4693 return [sky130::res_check sky130_fd_pr__res_high_po_5p73 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004694}
4695
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004696proc sky130::sky130_fd_pr__res_xhigh_po_0p35_check {parameters} {
4697 return [sky130::res_check sky130_fd_pr__res_xhigh_po_0p35 $parameters]
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004698}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004699proc sky130::sky130_fd_pr__res_xhigh_po_0p69_check {parameters} {
4700 return [sky130::res_check sky130_fd_pr__res_xhigh_po_0p69 $parameters]
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004701}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004702proc sky130::sky130_fd_pr__res_xhigh_po_1p41_check {parameters} {
4703 return [sky130::res_check sky130_fd_pr__res_xhigh_po_1p41 $parameters]
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004704}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004705proc sky130::sky130_fd_pr__res_xhigh_po_2p85_check {parameters} {
4706 return [sky130::res_check sky130_fd_pr__res_xhigh_po_2p85 $parameters]
Tim Edwardsbf5ec172020-08-09 14:04:00 -04004707}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004708proc sky130::sky130_fd_pr__res_xhigh_po_5p73_check {parameters} {
4709 return [sky130::res_check sky130_fd_pr__res_xhigh_po_5p73 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004710}
4711
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004712proc sky130::sky130_fd_pr__res_generic_nd_check {parameters} {
4713 return [sky130::res_check sky130_fd_pr__res_generic_nd $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004714}
4715
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004716proc sky130::sky130_fd_pr__res_generic_pd_check {parameters} {
4717 return [sky130::res_check sky130_fd_pr__res_generic_pd $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004718}
4719
Tim Edwards0ee0f182020-11-21 16:15:07 -05004720proc sky130::sky130_fd_pr__res_generic_nd__hv_check {parameters} {
4721 return [sky130::res_check sky130_fd_pr__res_generic_nd__hv $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004722}
4723
Tim Edwards0ee0f182020-11-21 16:15:07 -05004724proc sky130::sky130_fd_pr__res_generic_pd__hv_check {parameters} {
4725 return [sky130::res_check sky130_fd_pr__res_generic_pd__hv $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004726}
4727
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004728proc sky130::sky130_fd_pr__res_generic_l1_check {parameters} {
4729 return [sky130::res_check sky130_fd_pr__res_generic_l1 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004730}
4731
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004732proc sky130::sky130_fd_pr__res_generic_m1_check {parameters} {
4733 return [sky130::res_check sky130_fd_pr__res_generic_m1 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004734}
4735
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004736proc sky130::sky130_fd_pr__res_generic_m2_check {parameters} {
4737 return [sky130::res_check sky130_fd_pr__res_generic_m2 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004738}
4739
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004740proc sky130::sky130_fd_pr__res_generic_m3_check {parameters} {
4741 return [sky130::res_check sky130_fd_pr__res_generic_m3 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004742}
4743
4744#ifdef METAL5
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004745proc sky130::sky130_fd_pr__res_generic_m4_check {parameters} {
4746 return [sky130::res_check sky130_fd_pr__res_generic_m4 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004747}
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004748proc sky130::sky130_fd_pr__res_generic_m5_check {parameters} {
4749 return [sky130::res_check sky130_fd_pr__res_generic_m5 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004750}
4751#endif (METAL5)
4752
4753#----------------------------------------------------------------
4754# MOS defaults:
4755#----------------------------------------------------------------
4756# w = Gate width
4757# l = Gate length
4758# m = Multiplier
4759# nf = Number of fingers
4760# diffcov = Diffusion contact coverage
4761# polycov = Poly contact coverage
4762# topc = Top gate contact
4763# botc = Bottom gate contact
4764# guard = Guard ring
4765#
4766# (not user-editable)
4767#
4768# lmin = Gate minimum length
4769# wmin = Gate minimum width
4770#----------------------------------------------------------------
4771
4772#----------------------------------------------------------------
4773# pmos: Specify all user-editable default values and those
4774# needed by mos_check
4775#----------------------------------------------------------------
4776
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004777proc sky130::sky130_fd_pr__pfet_01v8_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004778 return {w 0.42 l 0.15 m 1 nf 1 diffcov 100 polycov 100 \
4779 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4780 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.15 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004781 compatible {sky130_fd_pr__pfet_01v8 \
4782 sky130_fd_pr__pfet_01v8_lvt sky130_fd_pr__pfet_01v8_hvt \
Tim Edwards3e4e81e2021-02-13 17:13:05 -05004783 sky130_fd_pr__pfet_g5v0d10v5} full_metal 1 \
4784 viasrc 100 viadrn 100 viagate 100 \
4785 viagb 0 viagr 0 viagl 0 viagt 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004786}
4787
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004788proc sky130::sky130_fd_pr__pfet_01v8_lvt_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004789 return {w 0.42 l 0.35 m 1 nf 1 diffcov 100 polycov 100 \
4790 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4791 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.35 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004792 compatible {sky130_fd_pr__pfet_01v8 \
4793 sky130_fd_pr__pfet_01v8_lvt sky130_fd_pr__pfet_01v8_hvt \
Tim Edwards3e4e81e2021-02-13 17:13:05 -05004794 sky130_fd_pr__pfet_g5v0d10v5} full_metal 1 \
4795 viasrc 100 viadrn 100 viagate 100 \
4796 viagb 0 viagr 0 viagl 0 viagt 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004797}
4798
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004799proc sky130::sky130_fd_pr__pfet_01v8_hvt_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004800 return {w 0.42 l 0.15 m 1 nf 1 diffcov 100 polycov 100 \
4801 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4802 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.15 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004803 compatible {sky130_fd_pr__pfet_01v8 \
4804 sky130_fd_pr__pfet_01v8_lvt sky130_fd_pr__pfet_01v8_hvt \
Tim Edwards3e4e81e2021-02-13 17:13:05 -05004805 sky130_fd_pr__pfet_g5v0d10v5} full_metal 1 \
4806 viasrc 100 viadrn 100 viagate 100 \
4807 viagb 0 viagr 0 viagl 0 viagt 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004808}
4809
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004810proc sky130::sky130_fd_pr__pfet_g5v0d10v5_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004811 return {w 0.42 l 0.50 m 1 nf 1 diffcov 100 polycov 100 \
4812 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4813 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.50 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004814 compatible {sky130_fd_pr__pfet_01v8 \
4815 sky130_fd_pr__pfet_01v8_lvt sky130_fd_pr__pfet_01v8_hvt \
Tim Edwards3e4e81e2021-02-13 17:13:05 -05004816 sky130_fd_pr__pfet_g5v0d10v5} full_metal 1 \
4817 viasrc 100 viadrn 100 viagate 100 \
4818 viagb 0 viagr 0 viagl 0 viagt 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004819}
4820
4821#----------------------------------------------------------------
4822# nmos: Specify all user-editable default values and those
4823# needed by mos_check
4824#----------------------------------------------------------------
4825
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004826proc sky130::sky130_fd_pr__nfet_01v8_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004827 return {w 0.420 l 0.150 m 1 nf 1 diffcov 100 polycov 100 \
4828 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4829 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.15 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004830 compatible {sky130_fd_pr__nfet_01v8 sky130_fd_pr__nfet_01v8_lvt \
4831 sky130_fd_bs_flash__special_sonosfet_star \
Tim Edwardsee445932021-03-31 12:32:04 -04004832 sky130_fd_pr__nfet_g5v0d10v5 sky130_fd_pr__nfet_05v0_nvt \
4833 sky130_fd_pr__nfet_03v3_nvt} \
Tim Edwards0ee0f182020-11-21 16:15:07 -05004834 full_metal 1 viasrc 100 viadrn 100 viagate 100 \
4835 viagb 0 viagr 0 viagl 0 viagt 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004836}
4837
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004838proc sky130::sky130_fd_pr__nfet_01v8_lvt_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004839 return {w 0.420 l 0.150 m 1 nf 1 diffcov 100 polycov 100 \
4840 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4841 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.15 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004842 compatible {sky130_fd_pr__nfet_01v8 sky130_fd_pr__nfet_01v8_lvt \
4843 sky130_fd_bs_flash__special_sonosfet_star \
Tim Edwardsee445932021-03-31 12:32:04 -04004844 sky130_fd_pr__nfet_g5v0d10v5 sky130_fd_pr__nfet_05v0_nvt \
4845 sky130_fd_pr__nfet_03v3_nvt} \
Tim Edwards0ee0f182020-11-21 16:15:07 -05004846 full_metal 1 viasrc 100 viadrn 100 viagate 100 \
4847 viagb 0 viagr 0 viagl 0 viagt 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004848}
4849
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004850proc sky130::sky130_fd_bs_flash__special_sonosfet_star_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004851 return {w 0.420 l 0.150 m 1 nf 1 diffcov 100 polycov 100 \
4852 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4853 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.15 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004854 compatible {sky130_fd_pr__nfet_01v8 sky130_fd_pr__nfet_01v8_lvt \
4855 sky130_fd_bs_flash__special_sonosfet_star \
Tim Edwardsee445932021-03-31 12:32:04 -04004856 sky130_fd_pr__nfet_g5v0d10v5 sky130_fd_pr__nfet_05v0_nvt \
4857 sky130_fd_pr__nfet_03v3_nvt} \
Tim Edwards0ee0f182020-11-21 16:15:07 -05004858 full_metal 1 viasrc 100 viadrn 100 viagate 100 \
4859 viagb 0 viagr 0 viagl 0 viagt 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004860}
4861
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004862proc sky130::sky130_fd_pr__nfet_g5v0d10v5_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004863 return {w 0.42 l 0.50 m 1 nf 1 diffcov 100 polycov 100 \
4864 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4865 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.50 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004866 compatible {sky130_fd_pr__nfet_01v8 sky130_fd_pr__nfet_01v8_lvt \
4867 sky130_fd_bs_flash__special_sonosfet_star \
Tim Edwardsee445932021-03-31 12:32:04 -04004868 sky130_fd_pr__nfet_g5v0d10v5 sky130_fd_pr__nfet_05v0_nvt \
4869 sky130_fd_pr__nfet_03v3_nvt} \
Tim Edwards0ee0f182020-11-21 16:15:07 -05004870 full_metal 1 viasrc 100 viadrn 100 viagate 100 \
4871 viagb 0 viagr 0 viagl 0 viagt 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004872}
4873
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004874proc sky130::sky130_fd_pr__nfet_05v0_nvt_defaults {} {
Tim Edwardsee445932021-03-31 12:32:04 -04004875 return {w 0.42 l 0.90 m 1 nf 1 diffcov 100 polycov 100 \
4876 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4877 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.90 wmin 0.42 \
4878 compatible {sky130_fd_pr__nfet_01v8 sky130_fd_pr__nfet_01v8_lvt \
4879 sky130_fd_bs_flash__special_sonosfet_star \
4880 sky130_fd_pr__nfet_g5v0d10v5 sky130_fd_pr__nfet_05v0_nvt \
4881 sky130_fd_pr__nfet_03v3_nvt} \
4882 full_metal 1 viasrc 100 viadrn 100 viagate 100 \
4883 viagb 0 viagr 0 viagl 0 viagt 0}
4884}
4885
4886proc sky130::sky130_fd_pr__nfet_03v3_nvt_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004887 return {w 0.42 l 0.50 m 1 nf 1 diffcov 100 polycov 100 \
4888 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4889 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.50 wmin 0.42 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004890 compatible {sky130_fd_pr__nfet_01v8 sky130_fd_pr__nfet_01v8_lvt \
4891 sky130_fd_bs_flash__special_sonosfet_star \
Tim Edwardsee445932021-03-31 12:32:04 -04004892 sky130_fd_pr__nfet_g5v0d10v5 sky130_fd_pr__nfet_05v0_nvt \
4893 sky130_fd_pr__nfet_03v3_nvt} \
Tim Edwards0ee0f182020-11-21 16:15:07 -05004894 full_metal 1 viasrc 100 viadrn 100 viagate 100 \
4895 viagb 0 viagr 0 viagl 0 viagt 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004896}
4897
4898#----------------------------------------------------------------
4899# mos varactor: Specify all user-editable default values and those
4900# needed by mosvc_check
4901#----------------------------------------------------------------
4902
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004903proc sky130::sky130_fd_pr__cap_var_lvt_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004904 return {w 1.0 l 0.18 m 1 nf 1 diffcov 100 polycov 100 \
4905 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4906 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.18 wmin 1.0 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004907 compatible {sky130_fd_pr__cap_var_lvt \
Tim Edwards0ee0f182020-11-21 16:15:07 -05004908 sky130_fd_pr__cap_var_hvt sky130_fd_pr__cap_var} \
4909 full_metal 1 viasrc 100 viadrn 100 viagate 100 \
4910 viagb 0 viagr 0 viagl 0 viagt 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004911}
4912
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004913proc sky130::sky130_fd_pr__cap_var_hvt_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004914 return {w 1.0 l 0.18 m 1 nf 1 diffcov 100 polycov 100 \
4915 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4916 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.18 wmin 1.0 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004917 compatible {sky130_fd_pr__cap_var_lvt \
Tim Edwards0ee0f182020-11-21 16:15:07 -05004918 sky130_fd_pr__cap_var_hvt sky130_fd_pr__cap_var} \
4919 full_metal 1 viasrc 100 viadrn 100 viagate 100 \
4920 viagb 0 viagr 0 viagl 0 viagt 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004921}
4922
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004923proc sky130::sky130_fd_pr__cap_var_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004924 return {w 1.0 l 0.50 m 1 nf 1 diffcov 100 polycov 100 \
4925 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 \
4926 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.50 wmin 1.0 \
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004927 compatible {sky130_fd_pr__cap_var_lvt \
Tim Edwards0ee0f182020-11-21 16:15:07 -05004928 sky130_fd_pr__cap_var_hvt sky130_fd_pr__cap_var} \
4929 full_metal 1 viasrc 100 viadrn 100 viagate 100 \
4930 viagb 0 viagr 0 viagl 0 viagt 0}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004931}
4932
4933#----------------------------------------------------------------
4934# mos: Conversion from SPICE netlist parameters to toolkit
4935#----------------------------------------------------------------
4936
4937proc sky130::mos_convert {parameters} {
4938 set pdkparams [dict create]
4939 dict for {key value} $parameters {
4940 switch -nocase $key {
4941 l -
4942 w {
4943 # Length and width are converted to units of microns
4944 set value [magic::spice2float $value]
4945 # set value [expr $value * 1e6]
4946 set value [magic::3digitpastdecimal $value]
4947 dict set pdkparams [string tolower $key] $value
4948 }
4949 m {
Tim Edwards23c97662020-08-09 11:57:32 -04004950 dict set pdkparams [string tolower $key] $value
4951 }
4952 nf {
4953 # Adjustment ot W will be handled below
4954 dict set pdkparams [string tolower $key] $value
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004955 }
4956 }
4957 }
Tim Edwards23c97662020-08-09 11:57:32 -04004958
4959 # Magic does not understand "nf" as a parameter, but expands to
4960 # "nf" number of devices connected horizontally. The "w" value
4961 # must be divided down accordingly, as the "nf" parameter implies
4962 # that the total width "w" is divided into "nf" fingers.
4963
4964 catch {
4965 set w [dict get $pdkparams w]
4966 set nf [dict get $pdkparams nf]
4967 if {$nf > 1} {
4968 dict set pdkparams w [expr $w / $nf]
4969 }
4970 }
4971
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004972 return $pdkparams
4973}
4974
4975#----------------------------------------------------------------
4976
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004977proc sky130::sky130_fd_pr__nfet_01v8_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004978 return [sky130::mos_convert $parameters]
4979}
4980
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004981proc sky130::sky130_fd_pr__nfet_01v8_lvt_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004982 return [sky130::mos_convert $parameters]
4983}
4984
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004985proc sky130::sky130_fd_bs_flash__special_sonosfet_star_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004986 return [sky130::mos_convert $parameters]
4987}
4988
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004989proc sky130::sky130_fd_pr__nfet_g5v0d10v5_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004990 return [sky130::mos_convert $parameters]
4991}
4992
Tim Edwardsd7289eb2020-09-10 21:48:31 -04004993proc sky130::sky130_fd_pr__nfet_05v0_nvt_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04004994 return [sky130::mos_convert $parameters]
4995}
4996
Tim Edwardsee445932021-03-31 12:32:04 -04004997proc sky130::sky130_fd_pr__nfet_03v3_nvt_convert {parameters} {
4998 return [sky130::mos_convert $parameters]
4999}
5000
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005001proc sky130::sky130_fd_pr__pfet_01v8_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005002 return [sky130::mos_convert $parameters]
5003}
5004
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005005proc sky130::sky130_fd_pr__pfet_01v8_lvt_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005006 return [sky130::mos_convert $parameters]
5007}
5008
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005009proc sky130::sky130_fd_pr__pfet_01v8_hvt_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005010 return [sky130::mos_convert $parameters]
5011}
5012
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005013proc sky130::sky130_fd_pr__pfet_g5v0d10v5_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005014 return [sky130::mos_convert $parameters]
5015}
5016
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005017proc sky130::sky130_fd_pr__cap_var_lvt_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005018 return [sky130::mos_convert $parameters]
5019}
5020
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005021proc sky130::sky130_fd_pr__cap_var_hvt_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005022 return [sky130::mos_convert $parameters]
5023}
5024
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005025proc sky130::sky130_fd_pr__cap_var_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005026 return [sky130::mos_convert $parameters]
5027}
5028
5029#----------------------------------------------------------------
5030# mos: Interactively specifies the fixed layout parameters
5031#----------------------------------------------------------------
5032
5033proc sky130::mos_dialog {device parameters} {
5034 # Editable fields: w, l, nf, m, diffcov, polycov
5035 # Checked fields: topc, botc
5036 # For specific devices, gate type is a selection list
5037
5038 magic::add_entry w "Width (um)" $parameters
5039 magic::add_entry l "Length (um)" $parameters
5040 magic::add_entry nf "Fingers" $parameters
5041 magic::add_entry m "M" $parameters
5042
5043 if {[dict exists $parameters compatible]} {
5044 set sellist [dict get $parameters compatible]
5045 magic::add_selectlist gencell "Device type" $sellist $parameters $device
5046 }
5047
5048 magic::add_entry diffcov "Diffusion contact coverage (%)" $parameters
5049 magic::add_entry polycov "Poly contact coverage (%)" $parameters
5050 magic::add_entry rlcov "Guard ring contact coverage (%)" $parameters
5051 if {[dict exists $parameters gbc]} {
5052 magic::add_entry tbcov "Guard ring top/bottom contact coverage (%)" $parameters
5053 }
5054
5055 magic::add_checkbox poverlap "Overlap at poly contact" $parameters
5056 magic::add_checkbox doverlap "Overlap at diffusion contact" $parameters
5057 magic::add_checkbox topc "Add top gate contact" $parameters
5058 magic::add_checkbox botc "Add bottom gate contact" $parameters
5059
5060 magic::add_checkbox guard "Add guard ring" $parameters
5061 magic::add_checkbox full_metal "Full metal guard ring" $parameters
5062 magic::add_checkbox glc "Add left guard ring contact" $parameters
5063 magic::add_checkbox grc "Add right guard ring contact" $parameters
5064 if {[dict exists $parameters gbc]} {
5065 magic::add_checkbox gbc "Add bottom guard ring contact" $parameters
5066 }
5067 if {[dict exists $parameters gtc]} {
5068 magic::add_checkbox gtc "Add top guard ring contact" $parameters
5069 }
Tim Edwards0ee0f182020-11-21 16:15:07 -05005070
5071 magic::add_entry viasrc "Source via coverage \[+/-\](%)" $parameters
5072 magic::add_entry viadrn "Drain via coverage \[+/-\](%)" $parameters
5073 magic::add_entry viagate "Gate via coverage \[+/-\](%)" $parameters
5074 magic::add_entry viagb "Bottom guard ring via coverage \[+/-\](%)" $parameters
5075 magic::add_entry viagt "Top guard ring via coverage \[+/-\](%)" $parameters
5076 magic::add_entry viagr "Right guard ring via coverage \[+/-\](%)" $parameters
5077 magic::add_entry viagl "Left guard ring via coverage \[+/-\](%)" $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005078}
5079
5080#----------------------------------------------------------------
5081
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005082proc sky130::sky130_fd_pr__nfet_01v8_dialog {parameters} {
5083 sky130::mos_dialog sky130_fd_pr__nfet_01v8 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005084}
5085
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005086proc sky130::sky130_fd_pr__nfet_01v8_lvt_dialog {parameters} {
5087 sky130::mos_dialog sky130_fd_pr__nfet_01v8_lvt $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005088}
5089
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005090proc sky130::sky130_fd_bs_flash__special_sonosfet_star_dialog {parameters} {
5091 sky130::mos_dialog sky130_fd_bs_flash__special_sonosfet_star $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005092}
5093
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005094proc sky130::sky130_fd_pr__nfet_g5v0d10v5_dialog {parameters} {
5095 sky130::mos_dialog sky130_fd_pr__nfet_g5v0d10v5 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005096}
5097
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005098proc sky130::sky130_fd_pr__nfet_05v0_nvt_dialog {parameters} {
5099 sky130::mos_dialog sky130_fd_pr__nfet_05v0_nvt $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005100}
5101
Tim Edwardsee445932021-03-31 12:32:04 -04005102proc sky130::sky130_fd_pr__nfet_03v3_nvt_dialog {parameters} {
5103 sky130::mos_dialog sky130_fd_pr__nfet_03v3_nvt $parameters
5104}
5105
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005106proc sky130::sky130_fd_pr__pfet_01v8_dialog {parameters} {
5107 sky130::mos_dialog sky130_fd_pr__pfet_01v8 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005108}
5109
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005110proc sky130::sky130_fd_pr__pfet_01v8_lvt_dialog {parameters} {
5111 sky130::mos_dialog sky130_fd_pr__pfet_01v8_lvt $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005112}
5113
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005114proc sky130::sky130_fd_pr__pfet_01v8_hvt_dialog {parameters} {
5115 sky130::mos_dialog sky130_fd_pr__pfet_01v8_hvt $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005116}
5117
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005118proc sky130::sky130_fd_pr__pfet_g5v0d10v5_dialog {parameters} {
5119 sky130::mos_dialog sky130_fd_pr__pfet_g5v0d10v5 $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005120}
5121
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005122proc sky130::sky130_fd_pr__cap_var_lvt_dialog {parameters} {
5123 sky130::mos_dialog sky130_fd_pr__cap_var_lvt $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005124}
5125
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005126proc sky130::sky130_fd_pr__cap_var_hvt_dialog {parameters} {
5127 sky130::mos_dialog sky130_fd_pr__cap_var_hvt $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005128}
5129
Tim Edwardsd7289eb2020-09-10 21:48:31 -04005130proc sky130::sky130_fd_pr__cap_var_dialog {parameters} {
5131 sky130::mos_dialog sky130_fd_pr__cap_var $parameters
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005132}
5133
5134#----------------------------------------------------------------
5135# getbox: Get the current cursor box, in microns
5136#----------------------------------------------------------------
5137
5138proc sky130::getbox {} {
5139 set curbox [box values]
5140 set newbox []
5141 set oscale [cif scale out]
5142 for {set i 0} {$i < 4} {incr i} {
5143 set v [* [lindex $curbox $i] $oscale]
5144 lappend newbox $v
5145 }
5146 return $newbox
5147}
5148
5149#----------------------------------------------------------------
5150# unionbox: Get the union bounding box of box1 and box2
5151#----------------------------------------------------------------
5152
5153proc sky130::unionbox {box1 box2} {
5154 set newbox []
5155 for {set i 0} {$i < 2} {incr i} {
5156 set v [lindex $box1 $i]
5157 set o [lindex $box2 $i]
5158 if {$v < $o} {
5159 lappend newbox $v
5160 } else {
5161 lappend newbox $o
5162 }
5163 }
5164 for {set i 2} {$i < 4} {incr i} {
5165 set v [lindex $box1 $i]
5166 set o [lindex $box2 $i]
5167 if {$v > $o} {
5168 lappend newbox $v
5169 } else {
5170 lappend newbox $o
5171 }
5172 }
5173 return $newbox
5174}
5175
5176#----------------------------------------------------------------
5177# Draw a contact
5178#----------------------------------------------------------------
5179
5180proc sky130::draw_contact {w h s o x atype ctype mtype {orient vert}} {
5181
5182 # Draw a minimum-size diff contact centered at current position
5183 # w is width, h is height. Minimum size ensured.
5184 # x is contact size
5185 # s is contact diffusion (or poly) surround
5186 # o is contact metal surround
5187 # atype is active (e.g., ndiff) or bottom metal if a via
5188 # ctype is contact (e.g., ndc)
5189 # mtype is metal (e.g., m1) or top metal if a via
5190 # orient is the orientation of the contact
5191
5192 # Set orientations for the bottom material based on material type.
5193 # Substrate diffusions (tap) need not overlap the contact in all
5194 # directions, but other (diff) types do. The metal (local
5195 # interconnect) layer always overlaps in two directions only.
5196
5197 set lv_sub_types {"psd" "nsd"}
5198 if {[lsearch $lv_sub_types $atype] >= 0} {
5199 set aorient $orient
5200 } else {
5201 set aorient "full"
5202 }
5203
5204 pushbox
5205 box size 0 0
5206 if {$w < $x} {set w $x}
5207 if {$h < $x} {set h $x}
5208 set hw [/ $w 2.0]
5209 set hh [/ $h 2.0]
5210 box grow n ${hh}um
5211 box grow s ${hh}um
5212 box grow e ${hw}um
5213 box grow w ${hw}um
5214 paint ${ctype}
5215 pushbox
5216 # Bottom layer surrounded on sides as declared by aorient
5217 if {($aorient == "vert") || ($aorient == "full")} {
5218 box grow n ${s}um
5219 box grow s ${s}um
5220 }
5221 if {($aorient == "horz") || ($aorient == "full")} {
5222 box grow e ${s}um
5223 box grow w ${s}um
5224 }
5225 paint ${atype}
5226 set extents [sky130::getbox]
5227 popbox
5228 # Top layer surrounded on sides as declared by orient
5229 if {($orient == "vert") || ($orient == "full")} {
5230 box grow n ${o}um
5231 box grow s ${o}um
5232 }
5233 if {($orient == "horz") || ($orient == "full")} {
5234 box grow e ${o}um
5235 box grow w ${o}um
5236 }
5237 paint ${mtype}
5238 popbox
5239 return $extents
5240}
5241
5242#----------------------------------------------------------------
5243# Draw a guard ring
5244#----------------------------------------------------------------
5245
5246proc sky130::guard_ring {gw gh parameters} {
5247
5248 # Set local default values if they are not in parameters
5249 set rlcov 100 ;# Right-left contact coverage percentage
5250 set tbcov 100 ;# Top-bottom contact coverage percentage
5251 set grc 1 ;# Draw right side contact
5252 set glc 1 ;# Draw left side contact
5253 set gtc 1 ;# Draw right side contact
5254 set gbc 1 ;# Draw left side contact
Tim Edwards0ee0f182020-11-21 16:15:07 -05005255 set viagb 0 ;# Draw bottom side via
5256 set viagt 0 ;# Draw top side via
5257 set viagr 0 ;# Draw right side via
5258 set viagl 0 ;# Draw left side via
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005259 set full_metal 1 ;# Draw full (continuous) metal ring
5260 set guard_sub_type pwell ;# substrate type under guard ring
5261 set guard_sub_surround 0 ;# substrate type surrounds guard ring
5262 set plus_diff_type nsd ;# guard ring diffusion type
5263 set plus_contact_type nsc ;# guard ring diffusion contact type
5264 set sub_type pwell ;# substrate type
5265
5266 # Set a local variable for each parameter (e.g., $l, $w, etc.)
5267 foreach key [dict keys $parameters] {
5268 set $key [dict get $parameters $key]
5269 }
5270
5271 # Set guard_sub_type to sub_type if it is not defined
5272 if {![dict exists $parameters guard_sub_type]} {
5273 set guard_sub_type $sub_type
5274 }
5275
5276 set hx [/ $contact_size 2.0]
5277 set hw [/ $gw 2.0]
5278 set hh [/ $gh 2.0]
5279
5280 # Watch for (LV) substrate diffusion types, which have a different
5281 # contact surround amount depending on the direction
5282
5283 set lv_sub_types {"psd" "nsd"}
5284 if {[lsearch $lv_sub_types $plus_diff_type] >= 0} {
5285 set diff_surround 0
5286 }
5287
5288 # Compute diffusion width
5289 set difft [+ $contact_size $diff_surround $diff_surround]
5290 set hdifft [/ $difft 2.0]
5291 # Compute guard ring diffusion width and height
5292 set hdiffw [/ [+ $gw $difft] 2.0]
5293 set hdiffh [/ [+ $gh $difft] 2.0]
5294
5295 pushbox
5296 box size 0 0
5297
5298 pushbox
5299 box move n ${hh}um
5300 box grow n ${hdifft}um
5301 box grow s ${hdifft}um
5302 box grow e ${hdiffw}um
5303 box grow w ${hdiffw}um
5304 paint $plus_diff_type
5305 if {$guard_sub_surround > 0} {
5306 box grow c ${guard_sub_surround}um
5307 paint $guard_sub_type
5308 }
5309 popbox
5310 pushbox
5311 box move s ${hh}um
5312 box grow n ${hdifft}um
5313 box grow s ${hdifft}um
5314 box grow e ${hdiffw}um
5315 box grow w ${hdiffw}um
5316 paint $plus_diff_type
5317 if {$guard_sub_surround > 0} {
5318 box grow c ${guard_sub_surround}um
5319 paint $guard_sub_type
5320 }
5321 popbox
5322 pushbox
5323 box move e ${hw}um
5324 box grow e ${hdifft}um
5325 box grow w ${hdifft}um
5326 box grow n ${hdiffh}um
5327 box grow s ${hdiffh}um
5328 paint $plus_diff_type
5329 if {$guard_sub_surround > 0} {
5330 box grow c ${guard_sub_surround}um
5331 paint $guard_sub_type
5332 }
5333 popbox
5334 pushbox
5335 box move w ${hw}um
5336 box grow e ${hdifft}um
5337 box grow w ${hdifft}um
5338 box grow n ${hdiffh}um
5339 box grow s ${hdiffh}um
5340 paint $plus_diff_type
5341 if {$guard_sub_surround > 0} {
5342 box grow c ${guard_sub_surround}um
5343 paint $guard_sub_type
5344 }
5345 popbox
5346
5347 if {$full_metal} {
5348 set hmetw [/ [+ $gw $contact_size] 2.0]
5349 set hmeth [/ [+ $gh $contact_size] 2.0]
5350 pushbox
5351 box move n ${hh}um
5352 box grow n ${hx}um
5353 box grow s ${hx}um
5354 box grow e ${hmetw}um
5355 box grow w ${hmetw}um
5356 paint li
5357 popbox
5358 pushbox
5359 box move s ${hh}um
5360 box grow n ${hx}um
5361 box grow s ${hx}um
5362 box grow e ${hmetw}um
5363 box grow w ${hmetw}um
5364 paint li
5365 popbox
5366 pushbox
5367 box move e ${hw}um
5368 box grow e ${hx}um
5369 box grow w ${hx}um
5370 box grow n ${hmeth}um
5371 box grow s ${hmeth}um
5372 paint li
5373 popbox
5374 pushbox
5375 box move w ${hw}um
5376 box grow e ${hx}um
5377 box grow w ${hx}um
5378 box grow n ${hmeth}um
5379 box grow s ${hmeth}um
5380 paint li
5381 popbox
5382 }
5383
5384 # Set guard ring height so that contact metal reaches to end, scale by $per
5385 # set ch [* [+ $gh $contact_size [* $metal_surround -2.0]] [/ $rlcov 100.0]]
5386 set ch [* [- $gh $contact_size [* [+ $metal_surround $metal_spacing] \
5387 2.0]] [/ $rlcov 100.0]]
5388 if {$ch < $contact_size} {set ch $contact_size}
5389
5390 # Set guard ring width so that contact metal reaches to side contacts
5391 set cw [* [- $gw $contact_size [* [+ $metal_surround $metal_spacing] \
5392 2.0]] [/ $tbcov 100.0]]
5393 if {$cw < $contact_size} {set cw $contact_size}
5394
5395 if {$tbcov > 0.0} {
5396 if {$gtc == 1} {
5397 pushbox
5398 box move n ${hh}um
5399 sky130::draw_contact $cw 0 $diff_surround $metal_surround \
5400 $contact_size $plus_diff_type $plus_contact_type li horz
5401 popbox
5402 }
5403 if {$gbc == 1} {
5404 pushbox
5405 box move s ${hh}um
5406 sky130::draw_contact $cw 0 $diff_surround $metal_surround \
5407 $contact_size $plus_diff_type $plus_contact_type li horz
5408 popbox
5409 }
5410 }
5411 if {$rlcov > 0.0} {
5412 if {$grc == 1} {
5413 pushbox
5414 box move e ${hw}um
5415 sky130::draw_contact 0 $ch $diff_surround $metal_surround \
5416 $contact_size $plus_diff_type $plus_contact_type li vert
5417 popbox
5418 }
5419 if {$glc == 1} {
5420 pushbox
5421 box move w ${hw}um
5422 sky130::draw_contact 0 $ch $diff_surround $metal_surround \
5423 $contact_size $plus_diff_type $plus_contact_type li vert
5424 popbox
5425 }
5426 }
5427
Tim Edwards0ee0f182020-11-21 16:15:07 -05005428 # Vias
5429 if {$viagb != 0} {
5430 pushbox
5431 set ch $via_size
5432 set cw [* [- $gw $via_size] [/ [expr abs($viagb)] 100.0]]
5433 if {$cw < $via_size} {set cw $via_size}
5434 box move s ${hh}um
5435 box grow n [/ $ch 2]um
5436 box grow s [/ $ch 2]um
5437 set anchor [string index $viagb 0]
5438 if {$anchor == "+"} {
5439 box move w [/ [- $gw $via_size] 2]um
5440 box grow e ${cw}um
5441 } elseif {$anchor == "-"} {
5442 box move e [/ [- $gw $via_size] 2]um
5443 box grow w ${cw}um
5444 } else {
5445 box grow e [/ $cw 2]um
5446 box grow w [/ $cw 2]um
5447 }
5448 sky130::mcon_draw horz
5449 popbox
5450 }
5451 if {$viagt != 0} {
5452 pushbox
5453 set ch $via_size
5454 set cw [* [- $gw $via_size] [/ [expr abs($viagt)] 100.0]]
5455 if {$cw < $via_size} {set cw $via_size}
5456 box move n ${hh}um
5457 box grow n [/ $ch 2]um
5458 box grow s [/ $ch 2]um
5459 set anchor [string index $viagt 0]
5460 if {$anchor == "+"} {
5461 box move w [/ [- $gw $via_size] 2]um
5462 box grow e ${cw}um
5463 } elseif {$anchor == "-"} {
5464 box move e [/ [- $gw $via_size] 2]um
5465 box grow w ${cw}um
5466 } else {
5467 box grow e [/ $cw 2]um
5468 box grow w [/ $cw 2]um
5469 }
5470 sky130::mcon_draw horz
5471 popbox
5472 }
5473 if {$viagr != 0} {
5474 pushbox
5475 set ch [* [- $gh $via_size] [/ [expr abs($viagr)] 100.0]]
5476 if {$ch < $via_size} {set ch $via_size}
5477 set cw $via_size
5478 box move e ${hw}um
5479 box grow e [/ $cw 2]um
5480 box grow w [/ $cw 2]um
5481 set anchor [string index $viagr 0]
5482 if {$anchor == "+"} {
Tim Edwards933e61e2020-11-21 16:50:06 -05005483 box move s [/ [- $gh $via_size] 2]um
Tim Edwards0ee0f182020-11-21 16:15:07 -05005484 box grow n ${ch}um
5485 } elseif {$anchor == "-"} {
Tim Edwards933e61e2020-11-21 16:50:06 -05005486 box move n [/ [- $gh $via_size] 2]um
Tim Edwards0ee0f182020-11-21 16:15:07 -05005487 box grow s ${ch}um
5488 } else {
5489 box grow n [/ $ch 2]um
5490 box grow s [/ $ch 2]um
5491 }
5492 sky130::mcon_draw vert
5493 popbox
5494 }
5495 if {$viagl != 0} {
5496 pushbox
5497 set ch [* [- $gh $via_size] [/ [expr abs($viagl)] 100.0]]
5498 if {$ch < $via_size} {set ch $via_size}
5499 set cw $via_size
5500 box move w ${hw}um
5501 box grow e [/ $cw 2]um
5502 box grow w [/ $cw 2]um
5503 set anchor [string index $viagl 0]
5504 if {$anchor == "+"} {
Tim Edwards933e61e2020-11-21 16:50:06 -05005505 box move s [/ [- $gh $via_size] 2]um
Tim Edwards275e28d2020-11-21 16:43:41 -05005506 box grow n ${ch}um
Tim Edwards0ee0f182020-11-21 16:15:07 -05005507 } elseif {$anchor == "-"} {
Tim Edwards933e61e2020-11-21 16:50:06 -05005508 box move n [/ [- $gh $via_size] 2]um
Tim Edwards0ee0f182020-11-21 16:15:07 -05005509 box grow s ${ch}um
5510 } else {
5511 box grow n [/ $ch 2]um
5512 box grow s [/ $ch 2]um
5513 }
5514 sky130::mcon_draw vert
5515 popbox
5516 }
5517
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005518 pushbox
5519 box grow e ${hw}um
5520 box grow w ${hw}um
5521 box grow n ${hh}um
5522 box grow s ${hh}um
5523 # Create boundary using properties
5524 property FIXED_BBOX [box values]
5525 box grow c ${hx}um ;# to edge of contact
5526 box grow c ${diff_surround}um ;# to edge of diffusion
5527 box grow c ${sub_surround}um ;# sub/well overlap of diff (NOT guard_sub)
5528 paint $sub_type
5529 set cext [sky130::getbox]
5530 popbox
5531 popbox
5532
5533 return $cext
5534}
5535
5536#----------------------------------------------------------------
5537# MOSFET: Draw a single device
5538#----------------------------------------------------------------
5539
5540proc sky130::mos_device {parameters} {
5541
5542 # Epsilon for avoiding round-off errors
5543 set eps 0.0005
5544
5545 # Set local default values if they are not in parameters
5546 set diffcov 100 ;# percent coverage of diffusion contact
5547 set polycov 100 ;# percent coverage of poly contact
5548 set topc 1 ;# draw top poly contact
5549 set botc 1 ;# draw bottom poly contact
Tim Edwards0ee0f182020-11-21 16:15:07 -05005550 set viasrc 100 ;# draw source vias
5551 set viadrn 100 ;# draw drain vias
5552 set viagate 100 ;# draw gate vias
5553 set evens 1 ;# even or odd numbered device finger, in X
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005554 set dev_sub_type "" ;# device substrate type (if different from guard ring)
Tim Edwards0ee0f182020-11-21 16:15:07 -05005555 set dev_sub_dist 0 ;# device substrate distance (if nondefault dev_sub_type)
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005556 set min_effl 0 ;# gate length below which finger pitch must be stretched
5557 set diff_overlap_cont 0 ;# extra overlap of end contact by diffusion
5558
5559 # Set a local variable for each parameter (e.g., $l, $w, etc.)
5560 foreach key [dict keys $parameters] {
5561 set $key [dict get $parameters $key]
5562 }
5563
5564 # Draw the diffusion and poly
5565 pushbox
5566 box size 0 0
5567 pushbox
5568 set hw [/ $w 2.0]
5569 set hl [/ $l 2.0]
5570 set he [/ $min_effl 2.0]
5571 if {$nf == 1 || $he < $hl} {set he $hl}
5572 box grow n ${hw}um
5573 box grow s ${hw}um
5574 box grow e ${hl}um
5575 box grow w ${hl}um
5576 pushbox
5577 if {${diff_extension} > ${gate_to_diffcont}} {
5578 box grow e ${diff_extension}um
5579 box grow w ${diff_extension}um
5580 } else {
5581 box grow e ${gate_to_diffcont}um
5582 box grow w ${gate_to_diffcont}um
5583 }
5584 paint ${diff_type}
5585 popbox
5586 pushbox
5587 if {${gate_extension} > ${gate_to_polycont}} {
5588 box grow n ${gate_extension}um
5589 box grow s ${gate_extension}um
5590 } else {
5591 if {$topc} {
5592 box grow n ${gate_to_polycont}um
5593 } else {
5594 box grow n ${gate_extension}um
5595 }
5596 if {$botc} {
5597 box grow s ${gate_to_polycont}um
5598 } else {
5599 box grow s ${gate_extension}um
5600 }
5601 }
5602 paint ${poly_type}
5603 set cext [sky130::getbox]
5604 popbox
5605 # save gate area now and paint later, so that diffusion surrounding the
5606 # contact does not paint over the gate area, in case the gate type is
5607 # not part of a "compose" entry in the techfile.
5608 set gaterect [box values]
5609 popbox
5610
5611 # Adjust position of contacts for dogbone geometry
5612 # Rule 1: Minimize diffusion length. Contacts only move out
5613 # if width < contact diffusion height. They move out enough
5614 # that the diffusion-to-poly spacing is satisfied.
5615
5616 set ddover 0
5617 set cdwmin [+ ${contact_size} [* ${diff_surround} 2]]
5618 set cstem [- ${gate_to_diffcont} [/ ${cdwmin} 2.0]]
5619 set cgrow [- ${diff_poly_space} ${cstem}]
5620 if {[+ ${w} ${eps}] < ${cdwmin}} {
5621 if {${cgrow} > 0} {
5622 set gate_to_diffcont [+ ${gate_to_diffcont} ${cgrow}]
5623 }
5624 set ddover [/ [- ${cdwmin} ${w}] 2.0]
5625 }
5626
5627 # Rule 2: Minimum poly width. Poly contacts only move out
5628 # if length < contact poly width. They move out enough
5629 # that the diffusion-to-poly spacing is satisfied.
5630
5631 set gporig ${gate_to_polycont}
5632 set cplmin [+ ${contact_size} [* ${poly_surround} 2]]
5633 set cstem [- ${gate_to_polycont} [/ ${cplmin} 2.0]]
5634 set cgrow [- ${diff_poly_space} ${cstem}]
5635 if {[+ ${l} ${eps}] < ${cplmin}} {
5636 if {${cgrow} > 0} {
5637 set gate_to_polycont [+ ${gate_to_polycont} ${cgrow}]
5638 }
5639 }
5640
5641 # Rule 3: If both poly and diffusion are dogboned, then move
5642 # poly out further to clear spacing to the diffusion contact
5643
5644 if {[+ ${w} ${eps}] < ${cdwmin}} {
5645 if {[+ ${l} ${eps}] < ${cplmin}} {
5646 set cgrow [/ [- ${cplmin} ${w}] 2.0]
5647 set gate_to_polycont [+ ${gate_to_polycont} ${cgrow}]
5648 }
5649 }
5650
5651 # Rule 4: If M > 1 and poly contacts overlap, then increase the
5652 # transistor-to-poly-contact distance by the amount of any
5653 # diffusion dogbone overhang.
5654
5655 if {($poverlap == 1) && ($m > 1)} {
5656 if {${gate_to_polycont} - $gporig < $ddover} {
5657 set gate_to_polycont [+ ${gporig} ${ddover}]
5658 }
5659 }
5660
5661 # Reduce contact sizes by poly or diffusion surround so that
5662 # the contact area edges match the device diffusion or poly.
5663 # (Minimum dimensions will be enforced by the contact drawing routine)
5664 set tsurround [+ ${diff_surround} ${diff_overlap_cont}]
5665 set cdw [- ${w} [* ${tsurround} 2]] ;# diff contact height
5666 set cpl [- ${l} [* ${poly_surround} 2]] ;# poly contact width
5667
Tim Edwards0ee0f182020-11-21 16:15:07 -05005668 # Save the full diffusion (source/drain) and poly (gate) lengths
5669 set cdwfull $cdw
5670 set cplfull $cpl
5671
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005672 # Reduce by coverage percentage. NOTE: If overlapping multiple devices,
5673 # keep maximum poly contact coverage.
5674
5675 set cdw [* ${cdw} [/ ${diffcov} 100.0]]
5676 if {($poverlap == 0) || ($m == 1)} {
5677 set cpl [* ${cpl} [/ ${polycov} 100.0]]
5678 }
5679
5680 # Right diffusion contact
5681 pushbox
5682 box move e ${he}um
5683 box move e ${gate_to_diffcont}um
Tim Edwards0ee0f182020-11-21 16:15:07 -05005684
5685 # Source via on top of contact
5686 if {$evens == 1} {set viatype $viasrc} else {set viatype $viadrn}
5687 if {$viatype != 0} {
5688 pushbox
5689 set cw $via_size
5690 set ch [* $cdwfull [/ [expr abs($viatype)] 100.0]]
5691 if {$ch < $via_size} {set ch $via_size}
5692 box grow e [/ $cw 2]um
5693 box grow w [/ $cw 2]um
5694 set anchor [string index $viatype 0]
5695 if {$anchor == "+"} {
5696 box move s [/ [- $cdwfull $via_size] 2]um
5697 box grow n ${ch}um
5698 } elseif {$anchor == "-"} {
5699 box move n [/ [- $cdwfull $via_size] 2]um
5700 box grow s ${ch}um
5701 } else {
5702 box grow n [/ $ch 2]um
5703 box grow s [/ $ch 2]um
5704 }
5705 sky130::mcon_draw vert
5706 popbox
5707 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005708 set cext [sky130::unionbox $cext [sky130::draw_contact 0 ${cdw} \
5709 ${diff_surround} ${metal_surround} ${contact_size}\
5710 ${diff_type} ${diff_contact_type} li vert]]
5711 popbox
5712 # Left diffusion contact
5713 pushbox
5714 box move w ${he}um
5715 box move w ${gate_to_diffcont}um
Tim Edwards0ee0f182020-11-21 16:15:07 -05005716
5717 # Drain via on top of contact
5718 if {$evens == 1} {set viatype $viadrn} else {set viatype $viasrc}
5719 if {$viatype != 0} {
5720 pushbox
5721 set cw $via_size
5722 set ch [* $cdwfull [/ [expr abs($viatype)] 100.0]]
5723 if {$ch < $via_size} {set ch $via_size}
5724 box grow e [/ $cw 2]um
5725 box grow w [/ $cw 2]um
5726 set anchor [string index $viatype 0]
5727 if {$anchor == "+"} {
5728 box move s [/ [- $cdwfull $via_size] 2]um
5729 box grow n ${ch}um
5730 } elseif {$anchor == "-"} {
5731 box move n [/ [- $cdwfull $via_size] 2]um
5732 box grow s ${ch}um
5733 } else {
5734 box grow n [/ $ch 2]um
5735 box grow s [/ $ch 2]um
5736 }
5737 sky130::mcon_draw vert
5738 popbox
5739 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005740 set cext [sky130::unionbox $cext [sky130::draw_contact 0 ${cdw} \
5741 ${diff_surround} ${metal_surround} ${contact_size} \
5742 ${diff_type} ${diff_contact_type} li vert]]
5743 set diffarea $cext
5744 popbox
5745 # Top poly contact
5746 if {$topc} {
5747 pushbox
5748 box move n ${hw}um
5749 box move n ${gate_to_polycont}um
Tim Edwards0ee0f182020-11-21 16:15:07 -05005750
5751 # Gate via on top of contact
5752 if {$viagate != 0} {
5753 pushbox
5754 set ch $via_size
5755 set cw [* $cplfull [/ [expr abs($viagate)] 100.0]]
5756 if {$cw < $via_size} {set cw $via_size}
5757 box grow n [/ $ch 2]um
5758 box grow s [/ $ch 2]um
5759 set anchor [string index $viagate 0]
5760 if {$anchor == "+"} {
5761 box move w [/ [- $cplfull $via_size] 2]um
5762 box grow e ${cw}um
5763 } elseif {$anchor == "-"} {
5764 box move e [/ [- $cplfull $via_size] 2]um
5765 box grow w ${cw}um
5766 } else {
5767 box grow e [/ $cw 2]um
5768 box grow w [/ $cw 2]um
5769 }
5770 sky130::mcon_draw horz
5771 popbox
5772 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005773 set cext [sky130::unionbox $cext [sky130::draw_contact ${cpl} 0 \
5774 ${poly_surround} ${metal_surround} ${contact_size} \
5775 ${poly_type} ${poly_contact_type} li horz]]
5776 popbox
5777 }
5778 # Bottom poly contact
5779 if {$botc} {
5780 pushbox
5781 box move s ${hw}um
5782 box move s ${gate_to_polycont}um
Tim Edwards0ee0f182020-11-21 16:15:07 -05005783
5784 # Gate via on top of contact
5785 if {$viagate != 0} {
5786 pushbox
5787 set ch $via_size
5788 set cw [* $cplfull [/ [expr abs($viagate)] 100.0]]
5789 if {$cw < $via_size} {set cw $via_size}
5790 box grow n [/ $ch 2]um
5791 box grow s [/ $ch 2]um
5792 set anchor [string index $viagate 0]
5793 if {$anchor == "+"} {
5794 box move w [/ [- $cplfull $via_size] 2]um
5795 box grow e ${cw}um
5796 } elseif {$anchor == "-"} {
5797 box move e [/ [- $cplfull $via_size] 2]um
5798 box grow w ${cw}um
5799 } else {
5800 box grow e [/ $cw 2]um
5801 box grow w [/ $cw 2]um
5802 }
5803 sky130::mcon_draw horz
5804 popbox
5805 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005806 set cext [sky130::unionbox $cext [sky130::draw_contact ${cpl} 0 \
5807 ${poly_surround} ${metal_surround} ${contact_size} \
5808 ${poly_type} ${poly_contact_type} li horz]]
5809 popbox
5810 }
5811
5812 # Now draw the gate, after contacts have been drawn
5813 pushbox
5814 box values {*}${gaterect}
5815 # gate_type need not be defined if poly over diff paints the right type.
5816 catch {paint ${gate_type}}
5817 # sub_surround_dev, if defined, may create a larger area around the gate
5818 # than sub_surround creates around the diffusion/poly area.
5819 if [dict exists $parameters sub_surround_dev] {
5820 box grow n ${sub_surround_dev}um
5821 box grow s ${sub_surround_dev}um
5822 box grow e ${sub_surround_dev}um
5823 box grow w ${sub_surround_dev}um
5824 paint ${dev_sub_type}
5825 set cext [sky130::unionbox $cext [sky130::getbox]]
5826 }
5827 popbox
5828
5829 if {$dev_sub_type != ""} {
5830 box values [lindex $diffarea 0]um [lindex $diffarea 1]um \
5831 [lindex $diffarea 2]um [lindex $diffarea 3]um
5832 box grow n ${sub_surround}um
5833 box grow s ${sub_surround}um
5834 box grow e ${sub_surround}um
5835 box grow w ${sub_surround}um
5836 paint ${dev_sub_type}
Tim Edwards0ee0f182020-11-21 16:15:07 -05005837 if {$dev_sub_dist > 0} {
5838 set cext [sky130::unionbox $cext [sky130::getbox]]
5839 }
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005840 # puts stdout "Diagnostic: bounding box is $cext"
5841 }
5842
5843 popbox
5844 return $cext
5845}
5846
5847#----------------------------------------------------------------
5848# MOSFET: Draw the tiled device
5849#----------------------------------------------------------------
5850
5851proc sky130::mos_draw {parameters} {
5852 tech unlock *
5853 set savesnap [snap]
5854 snap internal
5855
5856 # Set defaults if they are not in parameters
5857 set poverlap 0 ;# overlap poly contacts when tiling
5858 set doverlap 1 ;# overlap diffusion contacts when tiling
5859 set dev_sub_dist 0 ;# substrate to guard ring, if dev_sub_type defined
5860 set dev_sub_space 0 ;# distance between substrate areas for arrayed devices
5861 set min_allc 0 ;# gate length below which poly contacts must be interleaved
5862 set id_type "" ;# additional type covering everything
5863 set id_surround 0 ;# amount of surround on above type
5864 set id2_type "" ;# additional type covering everything
5865 set id2_surround 0 ;# amount of surround on above type
5866
5867 # Set a local variable for each parameter (e.g., $l, $w, etc.)
5868 foreach key [dict keys $parameters] {
5869 set $key [dict get $parameters $key]
5870 }
5871
5872 # Diff-to-tap spacing is by default the same as diff spacing
5873 if {![dict exist $parameters diff_tap_space]} {
5874 set diff_tap_space $diff_spacing
5875 }
5876
5877 # If poverlap is 1 then both poly contacts must be present
5878 if {$poverlap == 1} {
5879 set topc 1
5880 set botc 1
5881 dict set parameters topc 1
5882 dict set parameters botc 1
5883 }
5884
5885 # Normalize distance units to microns
5886 set w [magic::spice2float $w]
5887 set l [magic::spice2float $l]
5888
5889 pushbox
5890 box values 0 0 0 0
5891
5892 # If dx < (poly contact space + poly contact width), then there is not
5893 # enough room for a row of contacts, so force alternating contacts
5894
Tim Edwards0ee0f182020-11-21 16:15:07 -05005895 set evens 1
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005896 if {$nf > 1 && $l < $min_allc} {
5897 set intc 1
5898 set evenodd 1
5899 set topc 1
5900 set botc 1
5901 dict set parameters topc 1
5902 dict set parameters botc 1
5903 set poverlap 0
5904 } else {
5905 set intc 0
5906 }
5907
5908 # Determine the base device dimensions by drawing one device
5909 # while all layers are locked (nothing drawn). This allows the
5910 # base drawing routine to do complicated geometry without having
5911 # to duplicate it here with calculations.
5912
5913 tech lock *
5914 set bbox [sky130::mos_device $parameters]
5915 # puts stdout "Diagnostic: Device bounding box e $bbox (um)"
5916 tech unlock *
5917
5918 set fw [- [lindex $bbox 2] [lindex $bbox 0]]
5919 set fh [- [lindex $bbox 3] [lindex $bbox 1]]
5920 set lw [+ [lindex $bbox 2] [lindex $bbox 0]]
5921 set lh [+ [lindex $bbox 3] [lindex $bbox 1]]
5922
5923 # If dev_sub_dist > 0 then each device must be in its own substrate
5924 # (well) area, and overlaps are disallowed. dev_sub_space determines
5925 # the distance between individual devices in an array.
5926
5927 if {$dev_sub_dist > 0} {
5928 set poverlap 0
5929 set doverlap 0
5930
5931 if {$dev_sub_space > $poly_spacing} {
5932 set dx [+ $fw $dev_sub_space]
5933 set dy [+ $fh $dev_sub_space]
5934 } else {
5935 set dx [+ $fw $poly_spacing]
5936 set dy [+ $fh $poly_spacing]
5937 }
5938
5939 } else {
5940
5941 # Determine tile width and height (depends on overlap)
5942 if {$poverlap == 0} {
5943 set dy [+ $fh $poly_spacing]
5944 } else {
5945 # overlap poly
5946 set dy [- $fh [+ $poly_surround $poly_surround $contact_size]]
5947 }
5948
5949 if {$doverlap == 0} {
5950 set dx [+ $fw $diff_spacing]
5951 } else {
5952 # overlap diffusions
5953 set dx [- $fw [+ $diff_surround $diff_surround $contact_size]]
5954 }
5955 }
5956
5957 # Determine core width and height
5958 set corex [+ [* [- $nf 1] $dx] $fw]
5959 set corey [+ [* [- $m 1] $dy] $fh]
5960 set corellx [/ [+ [- $corex $fw] $lw] 2.0]
5961 set corelly [/ [+ [- $corey $fh] $lh] 2.0]
5962
5963 # If there is a diffusion dogbone, and no top poly contact, then
5964 # increase the core height by the amount of the dogbone overhang.
5965
5966 if {$topc == 0} {
5967 set cdwmin [+ ${contact_size} [* ${diff_surround} 2]]
5968 if {${w} < ${cdwmin}} {
5969 set corey [+ $corey [/ [- ${cdwmin} ${w}] 2.0]]
5970 }
5971 }
5972
Tim Edwards0ee0f182020-11-21 16:15:07 -05005973 # Calculate guard ring size (measured to contact center)
5974 if {($guard != 0) || (${id_type} != "")} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04005975 if {($dev_sub_dist > 0) && ([+ $dev_sub_dist $sub_surround] > $diff_tap_space)} {
5976 set gx [+ $corex [* 2.0 [+ $dev_sub_dist $diff_surround]] $contact_size]
5977 } else {
5978 set gx [+ $corex [* 2.0 [+ $diff_tap_space $diff_surround]] $contact_size]
5979 }
5980 if {($dev_sub_dist > 0) && ([+ $dev_sub_dist $sub_surround] > $diff_gate_space)} {
5981 set gy [+ $corey [* 2.0 [+ $dev_sub_dist $diff_surround]] $contact_size]
5982 } else {
5983 set gy [+ $corey [* 2.0 [+ $diff_gate_space $diff_surround]] $contact_size]
5984 }
5985
5986 # Somewhat tricky. . . if the width is small and the diffusion is
5987 # a dogbone, and the top or bottom poly contact is missing, then
5988 # the spacing to the guard ring may be limited by diffusion spacing, not
5989 # poly to diffusion.
5990
5991 set inset [/ [+ $contact_size [* 2.0 $diff_surround] -$w] 2.0]
5992 set sdiff [- [+ $inset $diff_tap_space] [+ $gate_extension $diff_gate_space]]
5993
5994 if {$sdiff > 0} {
5995 if {$topc == 0} {
5996 set gy [+ $gy $sdiff]
5997 set corelly [+ $corelly [/ $sdiff 2.0]]
5998 }
5999 if {$botc == 0} {
6000 set gy [+ $gy $sdiff]
6001 set corelly [- $corelly [/ $sdiff 2.0]]
6002 }
6003 }
Tim Edwards0ee0f182020-11-21 16:15:07 -05006004 }
6005 if {$guard != 0} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006006 # Draw the guard ring first, as MOS well may interact with guard ring substrate
6007 sky130::guard_ring $gx $gy $parameters
6008 }
6009
6010 pushbox
6011 # If any surrounding identifier type is defined, draw it
6012 if {${id_type} != ""} {
6013 set hw [/ $gx 2]
6014 set hh [/ $gy 2]
6015 box grow e ${hw}um
6016 box grow w ${hw}um
6017 box grow n ${hh}um
6018 box grow s ${hh}um
6019 box grow c ${id_surround}um
6020 paint ${id_type}
6021 }
6022 popbox
6023 pushbox
6024 box move w ${corellx}um
6025 box move s ${corelly}um
6026 for {set xp 0} {$xp < $nf} {incr xp} {
Tim Edwards0ee0f182020-11-21 16:15:07 -05006027 dict set parameters evens $evens
6028 set evens [- 1 $evens]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006029 pushbox
6030 if {$intc == 1} {
6031 set evenodd [- 1 $evenodd]
6032 if {$evenodd == 1} {
6033 dict set parameters topc 1
6034 dict set parameters botc 0
6035 } else {
6036 dict set parameters topc 0
6037 dict set parameters botc 1
6038 }
6039 set saveeo $evenodd
6040 }
6041 for {set yp 0} {$yp < $m} {incr yp} {
6042 sky130::mos_device $parameters
6043 box move n ${dy}um
6044 if {$intc == 1} {
6045 set evenodd [- 1 $evenodd]
6046 if {$evenodd == 1} {
6047 dict set parameters topc 1
6048 dict set parameters botc 0
6049 } else {
6050 dict set parameters topc 0
6051 dict set parameters botc 1
6052 }
6053 }
6054 }
6055 if {$intc == 1} {
6056 set evenodd $saveeo
6057 }
6058 popbox
6059 box move e ${dx}um
6060 }
6061 popbox
6062 popbox
6063
6064 snap $savesnap
6065 tech revert
6066}
6067
6068#-------------------
6069# nMOS 1.8V
6070#-------------------
6071
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006072proc sky130::sky130_fd_pr__nfet_01v8_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006073 set newdict [dict create \
6074 gate_type nfet \
6075 diff_type ndiff \
6076 diff_contact_type ndc \
6077 plus_diff_type psd \
6078 plus_contact_type psc \
6079 poly_type poly \
6080 poly_contact_type pc \
6081 sub_type psub \
6082 min_effl 0.185 \
6083 min_allc 0.26 \
6084 ]
6085 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
6086 return [sky130::mos_draw $drawdict]
6087}
6088
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006089proc sky130::sky130_fd_pr__nfet_01v8_lvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006090 set newdict [dict create \
6091 gate_type nfetlvt \
6092 diff_type ndiff \
6093 diff_contact_type ndc \
6094 plus_diff_type psd \
6095 plus_contact_type psc \
6096 poly_type poly \
6097 poly_contact_type pc \
6098 sub_type psub \
6099 min_effl 0.185 \
6100 min_allc 0.26 \
6101 ]
6102 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
6103 return [sky130::mos_draw $drawdict]
6104}
6105
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006106proc sky130::sky130_fd_bs_flash__special_sonosfet_star_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006107 set newdict [dict create \
6108 gate_type nsonos \
6109 diff_type ndiff \
6110 diff_contact_type ndc \
6111 plus_diff_type psd \
6112 plus_contact_type psc \
6113 poly_type poly \
6114 poly_contact_type pc \
6115 sub_type psub \
6116 id_type dnwell \
6117 id_surround 1.355 \
6118 min_effl 0.185 \
6119 min_allc 0.26 \
6120 ]
6121 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
6122 return [sky130::mos_draw $drawdict]
6123}
6124
6125#-------------------
6126# pMOS 1.8V
6127#-------------------
6128
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006129proc sky130::sky130_fd_pr__pfet_01v8_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006130 set newdict [dict create \
6131 gate_type pfet \
6132 diff_type pdiff \
6133 diff_contact_type pdc \
6134 plus_diff_type nsd \
6135 plus_contact_type nsc \
6136 poly_type poly \
6137 poly_contact_type pc \
6138 sub_type nwell \
Tim Edwards2788f172020-10-14 22:32:33 -04006139 dev_sub_type nwell \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006140 gate_to_polycont 0.32 \
6141 min_effl 0.185 \
6142 min_allc 0.26 \
6143 ]
6144 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
6145 return [sky130::mos_draw $drawdict]
6146}
6147
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006148proc sky130::sky130_fd_pr__pfet_01v8_lvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006149 set newdict [dict create \
6150 gate_type pfetlvt \
6151 diff_type pdiff \
6152 diff_contact_type pdc \
6153 plus_diff_type nsd \
6154 plus_contact_type nsc \
6155 poly_type poly \
6156 poly_contact_type pc \
6157 sub_type nwell \
Tim Edwards2788f172020-10-14 22:32:33 -04006158 dev_sub_type nwell \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006159 gate_to_polycont 0.32 \
6160 min_effl 0.185 \
6161 min_allc 0.26 \
6162 ]
6163 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
6164 return [sky130::mos_draw $drawdict]
6165}
6166
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006167proc sky130::sky130_fd_pr__pfet_01v8_hvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006168 set newdict [dict create \
6169 gate_type pfethvt \
6170 diff_type pdiff \
6171 diff_contact_type pdc \
6172 plus_diff_type nsd \
6173 plus_contact_type nsc \
6174 poly_type poly \
6175 poly_contact_type pc \
6176 sub_type nwell \
Tim Edwards2788f172020-10-14 22:32:33 -04006177 dev_sub_type nwell \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006178 gate_to_polycont 0.32 \
6179 min_effl 0.185 \
6180 min_allc 0.26 \
6181 ]
6182 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
6183 return [sky130::mos_draw $drawdict]
6184}
6185
6186#-------------------
6187# pMOS 5.0V
6188#-------------------
6189
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006190proc sky130::sky130_fd_pr__pfet_g5v0d10v5_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006191 set newdict [dict create \
6192 gate_type mvpfet \
6193 diff_type mvpdiff \
6194 diff_contact_type mvpdc \
6195 plus_diff_type mvnsd \
6196 plus_contact_type mvnsc \
6197 poly_type poly \
6198 poly_contact_type pc \
6199 sub_type nwell \
Tim Edwards2788f172020-10-14 22:32:33 -04006200 dev_sub_type nwell \
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006201 guard_sub_surround 0.33 \
6202 gate_to_polycont 0.32 \
6203 diff_spacing 0.31 \
6204 diff_tap_space 0.38 \
6205 diff_gate_space 0.38 \
6206 ]
6207 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
6208 return [sky130::mos_draw $drawdict]
6209}
6210
6211#-------------------
6212# nMOS 5.0V
6213#-------------------
6214
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006215proc sky130::sky130_fd_pr__nfet_g5v0d10v5_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006216 set newdict [dict create \
6217 gate_type mvnfet \
6218 diff_type mvndiff \
6219 diff_contact_type mvndc \
6220 plus_diff_type mvpsd \
6221 plus_contact_type mvpsc \
6222 poly_type poly \
6223 poly_contact_type pc \
6224 sub_type psub \
6225 diff_spacing 0.31 \
6226 diff_tap_space 0.38 \
6227 diff_gate_space 0.38 \
6228 ]
6229 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
6230 return [sky130::mos_draw $drawdict]
6231}
6232
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006233proc sky130::sky130_fd_pr__nfet_05v0_nvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006234 set newdict [dict create \
6235 gate_type mvnnfet \
6236 diff_type mvndiff \
6237 diff_contact_type mvndc \
6238 plus_diff_type mvpsd \
6239 plus_contact_type mvpsc \
6240 poly_type poly \
6241 poly_contact_type pc \
6242 sub_type psub \
6243 diff_spacing 0.30 \
6244 diff_tap_space 0.38 \
6245 diff_gate_space 0.38 \
6246 ]
6247 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
6248 return [sky130::mos_draw $drawdict]
6249}
6250
Tim Edwardsee445932021-03-31 12:32:04 -04006251proc sky130::sky130_fd_pr__nfet_03v3_nvt_draw {parameters} {
6252 set newdict [dict create \
6253 gate_type nnfet \
6254 diff_type mvndiff \
6255 diff_contact_type mvndc \
6256 plus_diff_type mvpsd \
6257 plus_contact_type mvpsc \
6258 poly_type poly \
6259 poly_contact_type pc \
6260 sub_type psub \
6261 diff_spacing 0.30 \
6262 diff_tap_space 0.38 \
6263 diff_gate_space 0.38 \
6264 ]
6265 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
6266 return [sky130::mos_draw $drawdict]
6267}
6268
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006269#------------------------
6270# MOS varactor (1.8V)
6271#------------------------
6272
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006273proc sky130::sky130_fd_pr__cap_var_lvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006274 set newdict [dict create \
6275 gate_type var \
6276 diff_type nnd \
6277 diff_contact_type nsc \
6278 plus_diff_type psd \
6279 plus_contact_type psc \
6280 poly_type poly \
6281 poly_contact_type pc \
6282 sub_type psub \
6283 dev_sub_type nwell \
6284 diff_overlap_cont 0.06 \
6285 dev_sub_dist 0.14 \
6286 dev_sub_space 1.27 \
6287 gate_to_diffcont 0.34 \
6288 diff_extension 0.485 \
6289 ]
6290 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
6291 return [sky130::mos_draw $drawdict]
6292}
6293
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006294proc sky130::sky130_fd_pr__cap_var_hvt_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006295 set newdict [dict create \
6296 gate_type varhvt \
6297 diff_type nnd \
6298 diff_contact_type nsc \
6299 plus_diff_type psd \
6300 plus_contact_type psc \
6301 poly_type poly \
6302 poly_contact_type pc \
6303 sub_type psub \
6304 dev_sub_type nwell \
6305 diff_overlap_cont 0.06 \
6306 dev_sub_dist 0.14 \
6307 dev_sub_space 1.27 \
6308 gate_to_diffcont 0.34 \
6309 diff_extension 0.485 \
6310 ]
6311 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
6312 return [sky130::mos_draw $drawdict]
6313}
6314
6315#---------------------------------------------------------
6316# MOS varactor (5.0V)
6317# NOTE: dev_sub_space set to 2.0 assuming different nets.
6318# Should have option for same-net with merged wells.
6319#---------------------------------------------------------
6320
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006321proc sky130::sky130_fd_pr__cap_var_draw {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006322 set newdict [dict create \
6323 gate_type mvvar \
6324 diff_type mvnsd \
6325 diff_contact_type mvnsc \
6326 plus_diff_type mvpsd \
6327 plus_contact_type mvpsc \
6328 poly_type poly \
6329 poly_contact_type pc \
6330 sub_type psub \
6331 dev_sub_type nwell \
6332 sub_surround 0.38 \
6333 sub_surround_dev 0.56 \
6334 guard_sub_surround 0.18 \
6335 diff_overlap_cont 0.06 \
6336 dev_sub_dist 0.785 \
6337 dev_sub_space 2.0 \
6338 gate_to_diffcont 0.34 \
6339 diff_extension 0.485 \
6340 ]
6341 set drawdict [dict merge $sky130::ruleset $newdict $parameters]
6342 return [sky130::mos_draw $drawdict]
6343}
6344
6345#----------------------------------------------------------------
6346# MOSFET: Check device parameters for out-of-bounds values
6347#----------------------------------------------------------------
6348
6349proc sky130::mos_check {device parameters} {
6350
6351 # Set a local variable for each parameter (e.g., $l, $w, etc.)
6352 foreach key [dict keys $parameters] {
6353 set $key [dict get $parameters $key]
6354 }
6355
6356 # Normalize distance units to microns
6357 set l [magic::spice2float $l]
6358 set l [magic::3digitpastdecimal $l]
6359 set w [magic::spice2float $w]
6360 set w [magic::3digitpastdecimal $w]
6361
6362 # nf, m must be integer
6363 if {![string is int $nf]} {
6364 puts stderr "NF must be an integer!"
6365 dict set parameters nf 1
6366 }
6367 if {![string is int $m]} {
6368 puts stderr "M must be an integer!"
6369 dict set parameters m 1
6370 }
6371 # diffcov, polycov must be numeric
6372 if {[catch {expr abs($diffcov)}]} {
6373 puts stderr "diffcov must be numeric!"
6374 set diffcov 100
Tim Edwards0ee0f182020-11-21 16:15:07 -05006375 dict set parameters diffcov $diffcov
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006376 }
6377 if {[catch {expr abs($polycov)}]} {
6378 puts stderr "polycov must be numeric!"
6379 set polycov 100
Tim Edwards0ee0f182020-11-21 16:15:07 -05006380 dict set parameters polycov $polycov
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006381 }
6382
6383 if {$l < $lmin} {
6384 puts stderr "Mos length must be >= $lmin um"
6385 dict set parameters l $lmin
6386 }
6387 if {$w < $wmin} {
6388 puts stderr "Mos width must be >= $wmin um"
6389 dict set parameters w $wmin
6390 }
6391 if {$nf < 1} {
6392 puts stderr "NF must be >= 1"
6393 dict set parameters nf 1
6394 }
6395 if {$m < 1} {
6396 puts stderr "M must be >= 1"
6397 dict set parameters m 1
6398 }
6399 if {$diffcov < 20 } {
6400 puts stderr "Diffusion contact coverage must be at least 20%"
6401 dict set parameters diffcov 20
6402 } elseif {$diffcov > 100 } {
6403 puts stderr "Diffusion contact coverage can't be more than 100%"
6404 dict set parameters diffcov 100
6405 }
6406 if {$polycov < 20 } {
6407 puts stderr "Poly contact coverage must be at least 20%"
6408 dict set parameters polycov 20
6409 } elseif {$polycov > 100 } {
6410 puts stderr "Poly contact coverage can't be more than 100%"
6411 dict set parameters polycov 100
6412 }
6413
Tim Edwards0ee0f182020-11-21 16:15:07 -05006414 if {[catch {expr abs($viasrc)}]} {
6415 puts stderr "Source via coverage must be numeric!"
6416 dict set parameters viasrc 100
6417 } elseif {[expr abs($viasrc)] > 100} {
6418 puts stderr "Source via coverage can't be more than 100%"
6419 dict set parameters viasrc 100
6420 }
6421 if {[catch {expr abs($viadrn)}]} {
6422 puts stderr "Drain via coverage must be numeric!"
6423 dict set parameters viadrn 100
6424 } elseif {[expr abs($viadrn)] > 100} {
6425 puts stderr "Drain via coverage can't be more than 100%"
6426 dict set parameters viadrn 100
6427 }
6428 if {[catch {expr abs($viagate)}]} {
6429 puts stderr "Gate via coverage must be numeric!"
6430 dict set parameters viagate 100
6431 } elseif {[expr abs($viagate)] > 100} {
6432 puts stderr "Gate via coverage can't be more than 100%"
6433 dict set parameters viagate 100
6434 }
6435 if {[catch {expr abs($viagb)}]} {
6436 puts stderr "Guard ring bottom via coverage must be numeric!"
6437 dict set parameters viagb 0
6438 } elseif {[expr abs($viagb)] > 100} {
6439 puts stderr "Guard ring bottom via coverage can't be more than 100%"
6440 dict set parameters viagb 100
6441 }
6442 if {[catch {expr abs($viagt)}]} {
6443 puts stderr "Guard ring top via coverage must be numeric!"
6444 dict set parameters viagt 0
6445 } elseif {[expr abs($viagt)] > 100} {
6446 puts stderr "Guard ring top via coverage can't be more than 100%"
6447 dict set parameters viagt 100
6448 }
6449 if {[catch {expr abs($viagr)}]} {
6450 puts stderr "Guard ring right via coverage must be numeric!"
6451 dict set parameters viagr 0
6452 } elseif {[expr abs($viagr)] > 100} {
6453 puts stderr "Guard ring right via coverage can't be more than 100%"
6454 dict set parameters viagr 100
6455 }
6456 if {[catch {expr abs($viagl)}]} {
6457 puts stderr "Guard ring left via coverage must be numeric!"
6458 dict set parameters viagl 0
6459 } elseif {[expr abs($viagl)] > 100} {
6460 puts stderr "Guard ring left via coverage can't be more than 100%"
6461 dict set parameters viagl 100
6462 }
6463
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006464 # Values must satisfy diffusion-to-tap spacing of 20um.
6465 # Therefore the maximum of guard ring width or height cannot exceed 40um.
6466 # If in violation, reduce counts first, as these are easiest to recover
6467 # by duplicating the device and overlapping the wells.
6468 set origm $m
6469 set orignf $nf
6470 while true {
6471 set yext [expr ($w + 3.0) * $m]
6472 set xext [expr ($l + 1.0) * $nf + 1.1]
6473 if {[expr min($xext, $yext)] > 40.0} {
6474 if {$yext > 40.0 && $m > 1} {
6475 incr m -1
6476 } elseif {$xext > 40.0 && $nf > 1} {
6477 incr nf -1
6478 } elseif {$yext > 40.0} {
6479 set w 37
6480 puts -nonewline stderr "Transistor width must be < 37 um"
6481 puts stderr " to avoid tap spacing violation."
6482 dict set parameters w $w
6483 } elseif {$xext > 40.0} {
6484 set l 37.9
6485 puts -nonewline stderr "Transistor length must be < 37.9 um"
6486 puts stderr " to avoid tap spacing violation."
6487 dict set parameters l $l
6488 }
6489 } else {
6490 break
6491 }
6492 }
6493 if {$m != $origm} {
6494 puts stderr "Y repeat reduced to prevent tap distance violation"
6495 dict set parameters m $m
6496 }
6497 if {$nf != $orignf} {
6498 puts stderr "X repeat reduced to prevent tap distance violation"
6499 dict set parameters nf $nf
6500 }
6501
6502 return $parameters
6503}
6504
6505#----------------------------------------------------------------
6506
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006507proc sky130::sky130_fd_pr__nfet_01v8_check {parameters} {
6508 return [sky130::mos_check sky130_fd_pr__nfet_01v8 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006509}
6510
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006511proc sky130::sky130_fd_pr__nfet_01v8_lvt_check {parameters} {
6512 return [sky130::mos_check sky130_fd_pr__nfet_01v8_lvt $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006513}
6514
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006515proc sky130::sky130_fd_bs_flash__special_sonosfet_star_check {parameters} {
6516 return [sky130::mos_check sky130_fd_bs_flash__special_sonosfet_star $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006517}
6518
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006519proc sky130::sky130_fd_pr__nfet_g5v0d10v5_check {parameters} {
6520 return [sky130::mos_check sky130_fd_pr__nfet_g5v0d10v5 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006521}
6522
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006523proc sky130::sky130_fd_pr__nfet_05v0_nvt_check {parameters} {
6524 return [sky130::mos_check sky130_fd_pr__nfet_05v0_nvt $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006525}
6526
Tim Edwardsee445932021-03-31 12:32:04 -04006527proc sky130::sky130_fd_pr__nfet_03v3_nvt_check {parameters} {
6528 return [sky130::mos_check sky130_fd_pr__nfet_03v3_nvt $parameters]
6529}
6530
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006531proc sky130::sky130_fd_pr__pfet_01v8_check {parameters} {
6532 return [sky130::mos_check sky130_fd_pr__pfet_01v8 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006533}
6534
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006535proc sky130::sky130_fd_pr__pfet_01v8_lvt_check {parameters} {
6536 return [sky130::mos_check sky130_fd_pr__pfet_01v8_lvt $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006537}
6538
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006539proc sky130::sky130_fd_pr__pfet_01v8_hvt_check {parameters} {
6540 return [sky130::mos_check sky130_fd_pr__pfet_01v8_hvt $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006541}
6542
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006543proc sky130::sky130_fd_pr__pfet_g5v0d10v5_check {parameters} {
6544 return [sky130::mos_check sky130_fd_pr__pfet_g5v0d10v5 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006545}
6546
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006547proc sky130::sky130_fd_pr__cap_var_lvt_check {parameters} {
6548 return [sky130::mos_check sky130_fd_pr__cap_var_lvt $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006549}
6550
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006551proc sky130::sky130_fd_pr__cap_var_hvt_check {parameters} {
6552 return [sky130::mos_check sky130_fd_pr__cap_var_hvt $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006553}
6554
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006555proc sky130::sky130_fd_pr__cap_var_check {parameters} {
6556 return [sky130::mos_check sky130_fd_pr__cap_var $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006557}
6558
6559#----------------------------------------------------------------
6560# Fixed device: Specify all user-editable default values
6561#
6562# deltax --- Additional horizontal space between devices
6563# deltay --- Additional vertical space between devices
6564# nx --- Number of arrayed devices in X
6565# ny --- Number of arrayed devices in Y
6566#
6567# Note that these values, specifically nx, ny, deltax,
6568# and deltay, are properties of the instance, not the cell.
6569# They translate to the instance array x and y counts; while
6570# deltax is the x pitch less the cell width, and deltay is the
6571# y pitch less the cell height.
6572#
6573# non-user-editable
6574#
6575# nocell --- Indicates that this cell has a predefined layout
6576# and therefore there is no cell to draw.
6577# xstep --- Width of the cell (nominal array pitch in X)
6578# ystep --- Height of the cell (nominal array pitch in Y)
6579#----------------------------------------------------------------
6580
6581# Fixed-layout devices (from sky130_fd_pr_base, _rf, and _rf2 libraries)
6582#
6583# Bipolar transistors:
6584#
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006585# sky130_fd_pr__rf_npn_05v5_W1p00L1p00
6586# sky130_fd_pr__rf_npn_05v5_W1p00L2p00
Tim Edwards956e3022021-05-27 20:43:26 -04006587# sky130_fd_pr__rf_pnp_05v5_W3p40L3p40
6588# sky130_fd_pr__rf_pnp_05v5_W0p68L0p68
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006589#
6590# Parallel Plate Capacitors:
6591#
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006592# sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldlim5
6593# sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield
Tim Edwardse4b45352022-01-01 11:53:31 -05006594# sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_shieldl1
6595# sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_shieldl1
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006596#
6597# Inductors:
6598#
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006599# sky130_fd_pr__rf_test_coil1
6600# sky130_fd_pr__rf_test_coil2
6601# sky130_fd_pr__rf_test_coil3
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006602
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006603proc sky130::sky130_fd_pr__rf_npn_05v5_W1p00L1p00_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006604 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 7.03 ystep 7.03}
6605}
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006606proc sky130::sky130_fd_pr__rf_npn_05v5_W1p00L2p00_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006607 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 7.03 ystep 8.03}
6608}
6609
Tim Edwards956e3022021-05-27 20:43:26 -04006610proc sky130::sky130_fd_pr__rf_pnp_05v5_W0p68L0p68_defaults {} {
Tim Edwards7e294962021-05-04 20:33:17 -04006611 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 3.72 ystep 3.72}
6612}
6613
Tim Edwards956e3022021-05-27 20:43:26 -04006614proc sky130::sky130_fd_pr__rf_pnp_05v5_W3p40L3p40_defaults {} {
Tim Edwardsd7289eb2020-09-10 21:48:31 -04006615 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 6.44 ystep 6.44}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006616}
6617
Tim Edwardse4b45352022-01-01 11:53:31 -05006618proc sky130::sky130_fd_pr__rf_test_coil1_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006619 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 258 ystep 258}
6620}
Tim Edwardse4b45352022-01-01 11:53:31 -05006621proc sky130::sky130_fd_pr__rf_test_coil2_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006622 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 290 ystep 404}
6623}
Tim Edwardse4b45352022-01-01 11:53:31 -05006624proc sky130::sky130_fd_pr__rf_test_coil3_defaults {} {
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006625 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 290 ystep 404}
6626}
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006627
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006628proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006629 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 11.08 ystep 11.36}
6630}
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006631proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006632 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 11.08 ystep 11.36}
6633}
Tim Edwardse4b45352022-01-01 11:53:31 -05006634proc sky130::sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_shieldl1_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006635 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 11.08 ystep 11.36}
6636}
Tim Edwardse4b45352022-01-01 11:53:31 -05006637proc sky130::sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_shieldl1_defaults {} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006638 return {nx 1 ny 1 deltax 0 deltay 0 nocell 1 xstep 11.08 ystep 11.36}
6639}
6640
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006641#----------------------------------------------------------------
6642# Fixed device: Conversion from SPICE netlist parameters to toolkit
6643#----------------------------------------------------------------
6644
6645proc sky130::fixed_convert {parameters} {
6646 set pdkparams [dict create]
6647 dict for {key value} $parameters {
6648 switch -nocase $key {
6649 m {
6650 dict set pdkparams nx $value
6651 }
6652 }
6653 }
6654 return $pdkparams
6655}
6656
6657#----------------------------------------------------------------
6658
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006659proc sky130::sky130_fd_pr__rf_npn_05v5_W1p00L1p00_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006660 return [sky130::fixed_convert $parameters]
6661}
6662
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006663proc sky130::sky130_fd_pr__rf_npn_05v5_W1p00L2p00_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006664 return [sky130::fixed_convert $parameters]
6665}
6666
Tim Edwards956e3022021-05-27 20:43:26 -04006667proc sky130::sky130_fd_pr__rf_pnp_05v5_W0p68L0p68_convert {parameters} {
Tim Edwards7e294962021-05-04 20:33:17 -04006668 return [sky130::fixed_convert $parameters]
6669}
6670
Tim Edwards956e3022021-05-27 20:43:26 -04006671proc sky130::sky130_fd_pr__rf_pnp_05v5_W3p40L3p40_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006672 return [sky130::fixed_convert $parameters]
6673}
6674
Tim Edwardse4b45352022-01-01 11:53:31 -05006675proc sky130::sky130_fd_pr__rf_test_coil1_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006676 return [sky130::fixed_convert $parameters]
6677}
6678
Tim Edwardse4b45352022-01-01 11:53:31 -05006679proc sky130::sky130_fd_pr__rf_test_coil2_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006680 return [sky130::fixed_convert $parameters]
6681}
6682
Tim Edwardse4b45352022-01-01 11:53:31 -05006683proc sky130::sky130_fd_pr__rf_test_coil3_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006684 return [sky130::fixed_convert $parameters]
6685}
6686
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006687proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006688 return [sky130::fixed_convert $parameters]
6689}
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006690proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006691 return [sky130::fixed_convert $parameters]
6692}
Tim Edwardse4b45352022-01-01 11:53:31 -05006693proc sky130::sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_shieldl1_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006694 return [sky130::fixed_convert $parameters]
6695}
Tim Edwardse4b45352022-01-01 11:53:31 -05006696proc sky130::sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_shieldl1_convert {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006697 return [sky130::fixed_convert $parameters]
6698}
6699
6700#----------------------------------------------------------------
6701# Fixed device: Interactively specifies the fixed layout parameters
6702#----------------------------------------------------------------
6703
6704proc sky130::fixed_dialog {parameters} {
6705 # Instance fields: nx, ny, pitchx, pitchy
6706 # Editable fields: nx, ny, deltax, deltay
6707 # Non-editable fields: nocell, xstep, ystep
6708
6709 # Set a local variable for each parameter (e.g., $l, $w, etc.)
6710 foreach key [dict keys $parameters] {
6711 set $key [dict get $parameters $key]
6712 }
6713
6714 # "nocell" field causes nx and ny to be dropped in from
6715 # "array count". Also "pitchx" and "pitchy" are passed
6716 # in internal units. Convert these to microns and generate
6717 # If there is no pitchx and pitchy, then the device has not
6718 # yet been created, so keep the deltax and deltay defaults.
6719
6720 if [dict exists $parameters pitchx] {
6721 set pitchux [magic::i2u $pitchx]
6722 set stepux [magic::spice2float $xstep]
6723 set deltax [magic::3digitpastdecimal [expr $pitchux - $stepux]]
6724 # An array size 1 should not cause deltax to go negative
6725 if {$deltax < 0.0} {set deltax 0.0}
6726 dict set parameters deltax $deltax
6727 }
6728 if [dict exists $parameters pitchy] {
6729 set pitchuy [magic::i2u $pitchy]
6730 set stepuy [magic::spice2float $ystep]
6731 set deltay [magic::3digitpastdecimal [expr $pitchuy - $stepuy]]
6732 # An array size 1 should not cause deltay to go negative
6733 if {$deltay < 0.0} {set deltay 0.0}
6734 dict set parameters deltay $deltay
6735 }
6736
6737 magic::add_entry nx "NX" $parameters
6738 magic::add_entry ny "NY" $parameters
6739 magic::add_entry deltax "X step (um)" $parameters
6740 magic::add_entry deltay "Y step (um)" $parameters
6741}
6742
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006743proc sky130::sky130_fd_pr__rf_npn_05v5_W1p00L1p00_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006744 sky130::fixed_dialog $parameters
6745}
6746
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006747proc sky130::sky130_fd_pr__rf_npn_05v5_W1p00L2p00_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006748 sky130::fixed_dialog $parameters
6749}
6750
Tim Edwards956e3022021-05-27 20:43:26 -04006751proc sky130::sky130_fd_pr__rf_pnp_05v5_W0p68L0p68_dialog {parameters} {
Tim Edwards7e294962021-05-04 20:33:17 -04006752 sky130::fixed_dialog $parameters
6753}
6754
Tim Edwards956e3022021-05-27 20:43:26 -04006755proc sky130::sky130_fd_pr__rf_pnp_05v5_W3p40L3p40_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006756 sky130::fixed_dialog $parameters
6757}
6758
Tim Edwardse4b45352022-01-01 11:53:31 -05006759proc sky130::sky130_fd_pr__rf_test_coil1_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006760 sky130::fixed_dialog $parameters
6761}
6762
Tim Edwardse4b45352022-01-01 11:53:31 -05006763proc sky130::sky130_fd_pr__rf_test_coil2_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006764 sky130::fixed_dialog $parameters
6765}
6766
Tim Edwardse4b45352022-01-01 11:53:31 -05006767proc sky130::sky130_fd_pr__rf_test_coil3_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006768 sky130::fixed_dialog $parameters
6769}
6770
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006771proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006772 sky130::fixed_dialog $parameters
6773}
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006774proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006775 sky130::fixed_dialog $parameters
6776}
Tim Edwardse4b45352022-01-01 11:53:31 -05006777proc sky130::sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_shieldl1_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006778 sky130::fixed_dialog $parameters
6779}
Tim Edwardse4b45352022-01-01 11:53:31 -05006780proc sky130::sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_shieldl1_dialog {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006781 sky130::fixed_dialog $parameters
6782}
6783
6784#----------------------------------------------------------------
6785# Fixed device: Draw the device
6786#----------------------------------------------------------------
6787
6788proc sky130::fixed_draw {devname parameters} {
6789
6790 # Set a local variable for each parameter (e.g., $l, $w, etc.)
6791 foreach key [dict keys $parameters] {
6792 set $key [dict get $parameters $key]
6793 }
6794
6795 # This cell declares "nocell" in parameters, so it needs to
6796 # instance the cell and set properties.
6797
6798 # Instantiate the cell. The name corresponds to the cell in the sky130_fd_pr_* directory.
6799 set instname [getcell ${devname}]
6800
6801 set deltax [magic::spice2float $deltax]
6802 set deltay [magic::spice2float $deltay]
6803 set xstep [magic::spice2float $xstep]
6804 set ystep [magic::spice2float $ystep]
6805
6806 # Array stepping
6807 if {$nx > 1 || $ny > 1} {
6808 set xstep [expr $xstep + $deltax]
6809 set ystep [expr $ystep + $deltay]
6810 box size ${xstep}um ${ystep}um
6811 array $nx $ny
6812 }
6813 select cell $instname
6814 expand
6815 return $instname
6816}
6817
6818#----------------------------------------------------------------
6819# No additional parameters declared for drawing
6820#----------------------------------------------------------------
6821
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006822proc sky130::sky130_fd_pr__rf_npn_05v5_W1p00L1p00_draw {parameters} {
6823 return [sky130::fixed_draw sky130_fd_pr__rf_npn_05v5_W1p00L1p00 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006824}
6825
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006826proc sky130::sky130_fd_pr__rf_npn_05v5_W1p00L2p00_draw {parameters} {
6827 return [sky130::fixed_draw sky130_fd_pr__rf_npn_05v5_W1p00L2p00 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006828}
6829
Tim Edwards956e3022021-05-27 20:43:26 -04006830proc sky130::sky130_fd_pr__rf_pnp_05v5_W0p68L0p68_draw {parameters} {
6831 return [sky130::fixed_draw sky130_fd_pr__rf_pnp_05v5_W0p68L0p68 $parameters]
Tim Edwards7e294962021-05-04 20:33:17 -04006832}
6833
Tim Edwards956e3022021-05-27 20:43:26 -04006834proc sky130::sky130_fd_pr__rf_pnp_05v5_W3p40L3p40_draw {parameters} {
6835 return [sky130::fixed_draw sky130_fd_pr__rf_pnp_05v5_W3p40L3p40 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006836}
6837
Tim Edwardse4b45352022-01-01 11:53:31 -05006838proc sky130::sky130_fd_pr__rf_test_coil1_draw {parameters} {
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006839 return [sky130::fixed_draw sky130_fd_pr__rf_test_coil1 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006840}
6841
Tim Edwardse4b45352022-01-01 11:53:31 -05006842proc sky130::sky130_fd_pr__rf_test_coil2_draw {parameters} {
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006843 return [sky130::fixed_draw sky130_fd_pr__rf_test_coil2 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006844}
6845
Tim Edwardse4b45352022-01-01 11:53:31 -05006846proc sky130::sky130_fd_pr__rf_test_coil3_draw {parameters} {
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006847 return [sky130::fixed_draw sky130_fd_pr__rf_test_coil3 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006848}
6849
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006850proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5_draw {parameters} {
6851 return [sky130::fixed_draw sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006852}
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006853proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield_draw {parameters} {
6854 return [sky130::fixed_draw sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006855}
Tim Edwardse4b45352022-01-01 11:53:31 -05006856proc sky130::sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_shieldl1_draw {parameters} {
6857 return [sky130::fixed_draw sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_shieldl1 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006858}
Tim Edwardse4b45352022-01-01 11:53:31 -05006859proc sky130::sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_shieldl1_draw {parameters} {
6860 return [sky130::fixed_draw sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_shieldl1 $parameters]
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006861}
6862
6863#----------------------------------------------------------------
6864# Fixed device: Check device parameters for out-of-bounds values
6865#----------------------------------------------------------------
6866
6867proc sky130::fixed_check {parameters} {
6868
6869 # Set a local variable for each parameter (e.g., $l, $w, etc.)
6870 foreach key [dict keys $parameters] {
6871 set $key [dict get $parameters $key]
6872 }
6873
6874 # Normalize distance units to microns
6875 set deltax [magic::spice2float $deltax -1]
6876 set deltax [magic::3digitpastdecimal $deltax]
6877 set deltay [magic::spice2float $deltay -1]
6878 set deltay [magic::3digitpastdecimal $deltay]
6879
6880 # nx, ny must be integer
6881 if {![string is int $nx]} {
6882 puts stderr "NX must be an integer!"
6883 dict set parameters nx 1
6884 }
6885 if {![string is int $ny]} {
6886 puts stderr "NY must be an integer!"
6887 dict set parameters nx 1
6888 }
6889
6890 # Number of devices in X and Y must be at least 1
6891 if {$nx < 1} {
6892 puts stderr "NX must be >= 1"
6893 dict set parameters nx 1
6894 }
6895 if {$ny < 1} {
6896 puts stderr "NY must be >= 1"
6897 dict set parameters nx 1
6898 }
6899 # Step less than zero violates DRC
6900 if {$deltax < 0} {
6901 puts stderr "X step must be >= 0"
6902 dict set parameters deltax 0
6903 }
6904 if {$deltay < 0} {
6905 puts stderr "Y step must be >= 0"
6906 dict set parameters deltay 0
6907 }
6908 return $parameters
6909}
6910
6911#----------------------------------------------------------------
6912
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006913proc sky130::sky130_fd_pr__rf_npn_05v5_W1p00L1p00_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006914 return [sky130::fixed_check $parameters]
6915}
6916
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006917proc sky130::sky130_fd_pr__rf_npn_05v5_W1p00L2p00_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006918 return [sky130::fixed_check $parameters]
6919}
6920
Tim Edwards956e3022021-05-27 20:43:26 -04006921proc sky130::sky130_fd_pr__rf_pnp_05v5_W0p68L0p68_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006922 return [sky130::fixed_check $parameters]
6923}
6924
Tim Edwards956e3022021-05-27 20:43:26 -04006925proc sky130::sky130_fd_pr__rf_pnp_05v5_W3p40L3p40_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006926 return [sky130::fixed_check $parameters]
6927}
6928
Tim Edwardse4b45352022-01-01 11:53:31 -05006929proc sky130::sky130_fd_pr__rf_test_coil1_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006930 return [sky130::fixed_check $parameters]
6931}
6932
Tim Edwardse4b45352022-01-01 11:53:31 -05006933proc sky130::sky130_fd_pr__rf_test_coil2_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006934 return [sky130::fixed_check $parameters]
6935}
6936
Tim Edwardse4b45352022-01-01 11:53:31 -05006937proc sky130::sky130_fd_pr__rf_test_coil3_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006938 return [sky130::fixed_check $parameters]
6939}
6940
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006941proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006942 return [sky130::fixed_check $parameters]
6943}
Tim Edwardsc6202ef2020-09-20 17:16:33 -04006944proc sky130::sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006945 return [sky130::fixed_check $parameters]
6946}
Tim Edwardse4b45352022-01-01 11:53:31 -05006947proc sky130::sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_shieldl1_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006948 return [sky130::fixed_check $parameters]
6949}
Tim Edwardse4b45352022-01-01 11:53:31 -05006950proc sky130::sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_shieldl1_check {parameters} {
Tim Edwards55f4d0e2020-07-05 15:41:02 -04006951 return [sky130::fixed_check $parameters]
6952}