Coverage for tests/rcx25/rcx25_CC_sky130A_test.py: 100%
89 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-31 20:14 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-31 20:14 +0000
1#
2# --------------------------------------------------------------------------------
3# SPDX-FileCopyrightText: 2024-2025 Martin Jan Köhler and Harald Pretl
4# Johannes Kepler University, Institute for Integrated Circuits.
5#
6# This file is part of KPEX
7# (see https://github.com/martinjankoehler/klayout-pex).
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <http://www.gnu.org/licenses/>.
21# SPDX-License-Identifier: GPL-3.0-or-later
22# --------------------------------------------------------------------------------
23#
25import allure
26import pytest
28from rcx25_test_helpers import *
30CSVPath = str
31PNGPath = str
32parent_suite = "kpex/2.5D Extraction Tests [PDK sky130A | mode CC]"
33tags = ("PEX", "2.5D", "MAGIC")
36pex_whiteboxed = RCX25Extraction(pdk=PDKTestConfig(PDKName.SKY130A), pex_mode=PEXMode.CC, blackbox=False)
37pex_blackboxed = RCX25Extraction(pdk=PDKTestConfig(PDKName.SKY130A), pex_mode=PEXMode.CC, blackbox=True)
40@allure.parent_suite(parent_suite)
41@allure.tag(*tags)
42@pytest.mark.slow
43def test_single_plate_100um_x_100um_li1_over_substrate():
44 # MAGIC GIVES (8.3 revision 485):
45 #_______________________________ NOTE: with halo=8µm __________________________________
46 # C0 PLATE VSUBS 0.38618p
47 pex_whiteboxed.assert_expected_matches_obtained(
48 'test_patterns', 'single_plate_100um_x_100um_li1_over_substrate.gds.gz',
49 expected_csv_content="""Device;Net1;Net2;Capacitance [fF];Resistance [Ω]
50C1;PLATE;VSUBS;386.179;"""
51 )
54@allure.parent_suite(parent_suite)
55@allure.tag(*tags)
56@pytest.mark.slow
57def test_overlap_plates_100um_x_100um_li1_m1():
58 # MAGIC GIVES (8.3 revision 485):
59 #_______________________________ NOTE: with halo=8µm __________________________________
60 # C2 LOWER VSUBS 0.38618p
61 # C0 UPPER LOWER 0.294756p
62 # C1 UPPER VSUBS 0.205833p
63 #_______________________________ NOTE: with halo=50µm __________________________________
64 # C2 LOWER VSUBS 0.38618p
65 # C0 LOWER UPPER 0.294867p
66 # C1 UPPER VSUBS 0.205621p
67 # NOTE: magic with --magic_halo=50 (µm) gives UPPER-VSUBS of 0.205621p
68 # which is due to the handling of https://github.com/martinjankoehler/magic/issues/1
69 pex_whiteboxed.assert_expected_matches_obtained(
70 'test_patterns', 'overlap_plates_100um_x_100um_li1_m1.gds.gz',
71 expected_csv_content="""Device;Net1;Net2;Capacitance [fF];Resistance [Ω]
72C1;LOWER;UPPER;294.867;
73C2;LOWER;VSUBS;386.179;
74C3;UPPER;VSUBS;205.619;"""
75 )
77@allure.parent_suite(parent_suite)
78@allure.tag(*tags)
79@pytest.mark.slow
80def test_overlap_plates_100um_x_100um_li1_m1_m2_m3():
81 # MAGIC GIVES (8.3 revision 485): (sorting changed to match order)
82 #_______________________________ NOTE: with halo=8µm __________________________________
83 # C7 li1 VSUBS 0.38618p
84 # C6 met1 VSUBS 0.205833p
85 # C5 met2 VSUBS 52.151802f
86 # C4 met3 VSUBS 0.136643p
87 # C3 li1 met1 0.294756p
88 # C0 met1 met2 0.680652p
89 # C2 li1 met2 99.3128f
90 # C1 li1 met3 5.59194f
91 #_______________________________ NOTE: with halo=50µm __________________________________
92 # C9 li1 VSUBS 0.38618p
93 # C8 met1 VSUBS 0.205621p
94 # C7 met2 VSUBS 51.5767f
95 # C6 met3 VSUBS 0.136103p
96 # C5 li1 met1 0.294867p
97 # C4 li1 met2 99.518005f
98 # C2 met1 met2 0.680769p
99 # C3 li1 met3 6.01281f
100 # C1 met1 met3 0.012287f
101 # C0 met2 met3 0.0422f
103 pex_whiteboxed.assert_expected_matches_obtained(
104 'test_patterns', 'overlap_plates_100um_x_100um_li1_m1_m2_m3.gds.gz',
105 expected_csv_content="""Device;Net1;Net2;Capacitance [fF];Resistance [Ω]
106C1;li1;met1;294.867;
107C2;li1;met2;99.518;
108C3;li1;met3;6.013;
109C4;met1;met2;680.769;
110C5;met1;met3;0.016;
111C6;met2;met3;0.056;
112C7;VSUBS;li1;386.179;
113C8;VSUBS;met1;205.619;
114C9;VSUBS;met2;51.574;
115C10;VSUBS;met3;136.063;"""
116 )
119@allure.parent_suite(parent_suite)
120@allure.tag(*tags)
121@pytest.mark.slow
122def test_sidewall_100um_x_100um_distance_200nm_li1():
123 # MAGIC GIVES (8.3 revision 485): (sorting changed to match order)
124 # _______________________________ NOTE: with halo=8µm __________________________________
125 # C0 A B 7.5f
126 # C1 B VSUBS 8.231f
127 # C2 A VSUBS 8.231f
128 # _______________________________ NOTE: with halo=50µm __________________________________
129 # (same!)
131 pex_whiteboxed.assert_expected_matches_obtained(
132 'test_patterns', 'sidewall_100um_x_100um_distance_200nm_li1.gds.gz',
133 expected_csv_content="""Device;Net1;Net2;Capacitance [fF];Resistance [Ω]
134C1;A;B;7.5;
135C2;A;VSUBS;8.231;
136C3;B;VSUBS;8.231;"""
137 )
140@allure.parent_suite(parent_suite)
141@allure.tag(*tags)
142@pytest.mark.slow
143def test_sidewall_net_uturn_l1_redux():
144 # MAGIC GIVES (8.3 revision 485): (sorting changed to match order)
145 # _______________________________ NOTE: with halo=8µm __________________________________
146 # C1 C1 VSUBS 12.5876f
147 # C2 C0 VSUBS 38.1255f
148 # C0 C0 C1 1.87386f
149 # _______________________________ NOTE: with halo=50µm __________________________________
150 # (same!)
152 pex_whiteboxed.assert_expected_matches_obtained(
153 'test_patterns', 'sidewall_net_uturn_l1_redux.gds.gz',
154 expected_csv_content="""Device;Net1;Net2;Capacitance [fF];Resistance [Ω]
155C1;C0;C1;1.874;
156C2;C0;VSUBS;38.125;
157C3;C1;VSUBS;12.588;"""
158 )
161@allure.parent_suite(parent_suite)
162@allure.tag(*tags)
163@pytest.mark.slow
164def test_sidewall_cap_vpp_04p4x04p6_l1_redux():
165 # MAGIC GIVES (8.3 revision 485): (sorting changed to match order)
166 # _______________________________ NOTE: with halo=8µm __________________________________
167 # C1 C1 VSUBS 0.086832f
168 # C2 C0 VSUBS 0.300359f
169 # C0 C0 C1 0.286226f
170 # _______________________________ NOTE: with halo=50µm __________________________________
171 # (same!)
173 pex_whiteboxed.assert_expected_matches_obtained(
174 'test_patterns', 'sidewall_cap_vpp_04p4x04p6_l1_redux.gds.gz',
175 expected_csv_content="""Device;Net1;Net2;Capacitance [fF];Resistance [Ω]
176C1;C0;C1;0.286;
177C2;C0;VSUBS;0.3;
178C3;C1;VSUBS;0.087;"""
179 )
182@allure.parent_suite(parent_suite)
183@allure.tag(*tags)
184@pytest.mark.slow
185def test_near_body_shield_li1_m1():
186 # MAGIC GIVES (8.3 revision 485): (sorting changed to match order)
187 #_______________________________ NOTE: with halo=8µm __________________________________
188 # C5 BOTTOM VSUBS 0.405082p
189 # C1 BOTTOM TOPB 0.215823p # DIFFERS marginally <0,1fF
190 # C2 BOTTOM TOPA 0.215823p # DIFFERS marginally <0,1fF
191 # C0 TOPA TOPB 0.502857f
192 # C3 TOPB VSUBS 0.737292f # DIFFERS, but that's a MAGIC issue (see test_overlap_plates_100um_x_100um_li1_m1)
193 # C4 TOPA VSUBS 0.737292f # DIFFERS, but that's a MAGIC issue (see test_overlap_plates_100um_x_100um_li1_m1)
194 #_______________________________ NOTE: with halo=50µm __________________________________
195 # NOTE: with halo=50µm, C3/C4 becomes 0.29976f
196 # see https://github.com/martinjankoehler/magic/issues/2
198 pex_whiteboxed.assert_expected_matches_obtained(
199 'test_patterns', 'near_body_shield_li1_m1.gds.gz',
200 expected_csv_content="""Device;Net1;Net2;Capacitance [fF];Resistance [Ω]
201C1;BOTTOM;TOPA;215.972;
202C2;BOTTOM;TOPB;215.972;
203C3;BOTTOM;VSUBS;405.081;
204C4;TOPA;TOPB;0.503;
205C5;TOPA;VSUBS;0.299;
206C6;TOPB;VSUBS;0.299;"""
207 )
210@allure.parent_suite(parent_suite)
211@allure.tag(*tags)
212@pytest.mark.slow
213def test_lateral_fringe_shield_by_same_polygon_li1():
214 # MAGIC GIVES (8.3 revision 485): (sorting changed to match order)
215 #_______________________________ NOTE: with halo=8µm __________________________________
216 # C0 C0 VSUBS 6.41431f $ **FLOATING
217 #_______________________________ NOTE: with halo=50µm __________________________________
218 # C0 C0 VSUBS 6.41431f $ **FLOATING
219 pex_whiteboxed.assert_expected_matches_obtained(
220 'test_patterns', 'lateral_fringe_shield_by_same_polygon_li1.gds.gz',
221 expected_csv_content="""Device;Net1;Net2;Capacitance [fF];Resistance [Ω]
222C1;C0;VSUBS;6.414;"""
223 )
226@allure.parent_suite(parent_suite)
227@allure.tag(*tags)
228@pytest.mark.slow
229def test_sideoverlap_simple_plates_li1_m1():
230 # MAGIC GIVES (8.3 revision 485): (sorting changed to match order)
231 # _______________________________ NOTE: with halo=8µm __________________________________
232 # C2 li1 VSUBS 7.931799f
233 # C1 met1 VSUBS 0.248901p
234 # C0 li1 met1 0.143335f
235 # _______________________________ NOTE: with halo=50µm __________________________________
236 # C2 li1 VSUBS 7.931799f
237 # C1 met1 VSUBS 0.248901p
238 # C0 li1 met1 0.156859f
240 pex_whiteboxed.assert_expected_matches_obtained(
241 'test_patterns', 'sideoverlap_simple_plates_li1_m1.gds.gz',
242 expected_csv_content="""Device;Net1;Net2;Capacitance [fF];Resistance [Ω]
243C1;li1;met1;0.157;
244C2;VSUBS;li1;7.931;
245C3;VSUBS;met1;248.899;"""
246 )
248@allure.parent_suite(parent_suite)
249@allure.tag(*tags)
250@pytest.mark.slow
251def test_sideoverlap_shielding_simple_plates_li1_m1_m2():
252 # MAGIC GIVES (8.3 revision 485): (sorting changed to match order)
253 # _______________________________ NOTE: with halo=8µm __________________________________
254 # C5 li1 VSUBS 11.7936f
255 # C4 met1 VSUBS 57.990803f
256 # C2 li1 met1 15.661301f
257 # C0 met1 met2 0.257488p
258 # C3 met2 VSUBS 5.29197f
259 # C1 li1 met2 0.151641f
260 # _______________________________ NOTE: with halo=50µm __________________________________
261 # C5 li1 VSUBS 11.7936f
262 # C4 met1 VSUBS 57.990803f
263 # C2 li1 met1 15.709599f
264 # C0 met1 met2 0.257488p
265 # C3 met2 VSUBS 5.29197f
266 # C1 li1 met2 0.151641f
268 pex_whiteboxed.assert_expected_matches_obtained(
269 'test_patterns', 'sideoverlap_shielding_simple_plates_li1_m1_m2.gds.gz',
270 expected_csv_content="""Device;Net1;Net2;Capacitance [fF];Resistance [Ω]
271C1;li1;met1;15.71;
272C2;li1;met2;0.152;
273C3;met1;met2;257.488;
274C4;VSUBS;li1;11.793;
275C5;VSUBS;met1;57.99;
276C6;VSUBS;met2;5.291;"""
277 )
280@allure.parent_suite(parent_suite)
281@allure.tag(*tags)
282@pytest.mark.slow
283def test_sideoverlap_plates_li1_m1():
284 # MAGIC GIVES (8.3 revision 485): (sorting changed to match order)
285 # _______________________________ NOTE: with halo=50µm __________________________________
286 # C15 LOWER_NoHaloOverlap_InsideTop VSUBS 51.9938f
287 # C12 LOWER_OutsideHalo VSUBS 73.274605f
288 # C17 LOWER_PartialSideHaloOverlap_Separated VSUBS 90.6184f
289 # C13 LOWER_PartialSideHaloOverlap_BothSides_separated VSUBS 7.93086f
290 # C14 LOWER_PartialSideHaloOverlap_Touching VSUBS 13.637f
291 # C16 LOWER_FullHaloOverlap VSUBS 0.177602p
292 # C11 UPPER VSUBS 0.214853p
293 # C8 LOWER_NoHaloOverlap_InsideTop UPPER 0.146991p
294 # C7 LOWER_PartialSideHaloOverlap_Touching UPPER 32.1587f
295 # C10 LOWER_FullHaloOverlap UPPER 0.262817p
296 # C3 LOWER_FullHaloOverlap LOWER_NoHaloOverlap_InsideTop 0.12574f
297 # C2 LOWER_NoHaloOverlap_InsideTop LOWER_PartialSideHaloOverlap_Touching 0.063307f
298 # C9 LOWER_NoHaloOverlap_InsideTop LOWER_OutsideHalo 0.06287f
299 # C1 LOWER_FullHaloOverlap LOWER_OutsideHalo 0.100592f
300 # C4 LOWER_PartialSideHaloOverlap_Separated LOWER_FullHaloOverlap 0.248054f
301 # C5 LOWER_OutsideHalo UPPER 0.076223f
302 # C6 LOWER_PartialSideHaloOverlap_BothSides_separated UPPER 0.261432f
303 # C0 LOWER_PartialSideHaloOverlap_Separated UPPER 0.148834f
304 #
306 pex_whiteboxed.assert_expected_matches_obtained(
307 'test_patterns', 'sideoverlap_plates_li1_m1.gds.gz',
308 expected_csv_content="""Device;Net1;Net2;Capacitance [fF];Resistance [Ω]
309C1;LOWER_FullHaloOverlap;LOWER_NoHaloOverlap_InsideTop;0.126;
310C2;LOWER_FullHaloOverlap;LOWER_OutsideHalo;0.101;
311C3;LOWER_FullHaloOverlap;LOWER_PartialSideHaloOverlap_BothSides_separated;0.001;
312C4;LOWER_FullHaloOverlap;LOWER_PartialSideHaloOverlap_Separated;0.248;
313C5;LOWER_FullHaloOverlap;UPPER;262.817;
314C6;LOWER_FullHaloOverlap;VSUBS;177.601;
315C7;LOWER_NoHaloOverlap_InsideTop;LOWER_OutsideHalo;0.063;
316C8;LOWER_NoHaloOverlap_InsideTop;LOWER_PartialSideHaloOverlap_Touching;0.063;
317C9;LOWER_NoHaloOverlap_InsideTop;UPPER;146.991;
318C10;LOWER_NoHaloOverlap_InsideTop;VSUBS;51.994;
319C11;LOWER_OutsideHalo;UPPER;0.076;
320C12;LOWER_OutsideHalo;VSUBS;73.274;
321C13;LOWER_PartialSideHaloOverlap_BothSides_separated;UPPER;0.261;
322C14;LOWER_PartialSideHaloOverlap_BothSides_separated;VSUBS;7.931;
323C15;LOWER_PartialSideHaloOverlap_Separated;UPPER;0.149;
324C16;LOWER_PartialSideHaloOverlap_Separated;VSUBS;90.618;
325C17;LOWER_PartialSideHaloOverlap_Touching;UPPER;32.159;
326C18;LOWER_PartialSideHaloOverlap_Touching;VSUBS;13.637;
327C19;UPPER;VSUBS;214.85;"""
328 )
331@allure.parent_suite(parent_suite)
332@allure.tag(*tags)
333@pytest.mark.slow
334def test_sideoverlap_fingered_li1_m1_patternA():
335 # MAGIC GIVES (8.3 revision 485): (sorting changed to match order)
336 # _______________________________ NOTE: with halo=50µm __________________________________
337 #
338 # C2 LOWER VSUBS 5.89976f
339 # C1 UPPER VSUBS 72.328f
340 # C0 LOWER UPPER 0.357768f
342 pex_whiteboxed.assert_expected_matches_obtained(
343 'test_patterns', 'sideoverlap_fingered_li1_m1_patternA.gds.gz',
344 expected_csv_content="""Device;Net1;Net2;Capacitance [fF];Resistance [Ω]
345C1;LOWER;UPPER;0.358;
346C2;LOWER;VSUBS;5.9;
347C3;UPPER;VSUBS;72.327;"""
348 )
351@allure.parent_suite(parent_suite)
352@allure.tag(*tags)
353@pytest.mark.slow
354def test_sideoverlap_fingered_li1_m1():
355 # MAGIC GIVES (8.3 revision 485): (sorting changed to match order)
356 # _______________________________ NOTE: with halo=50µm __________________________________
357 #
358 # C6 LOWER_PartialSideHaloOverlap_Fingered2 VSUBS 8.15974f
359 # C8 LOWER_PartialSideHaloOverlap_Fingered3 VSUBS 8.16395f
360 # C7 LOWER_PartialSideHaloOverlap_Fingered1 VSUBS 5.8844f
361 # C5 LOWER_PartialSideHaloOverlap_Fingered4 VSUBS 5.88862f
362 # C4 UPPER VSUBS 0.215283p
363 # C0 LOWER_PartialSideHaloOverlap_Fingered3 UPPER 0.158769f
364 # C2 LOWER_PartialSideHaloOverlap_Fingered2 UPPER 2.46581f
365 # C1 LOWER_PartialSideHaloOverlap_Fingered4 UPPER 0.35839f
366 # C3 LOWER_PartialSideHaloOverlap_Fingered1 UPPER 0.244356f
368 pex_whiteboxed.assert_expected_matches_obtained(
369 'test_patterns', 'sideoverlap_fingered_li1_m1.gds.gz',
370 expected_csv_content="""Device;Net1;Net2;Capacitance [fF];Resistance [Ω]
371C1;LOWER_PartialSideHaloOverlap_Fingered1;LOWER_PartialSideHaloOverlap_Fingered2;0.003;
372C2;LOWER_PartialSideHaloOverlap_Fingered1;LOWER_PartialSideHaloOverlap_Fingered4;0.016;
373C3;LOWER_PartialSideHaloOverlap_Fingered1;UPPER;0.244;
374C4;LOWER_PartialSideHaloOverlap_Fingered1;VSUBS;5.884;
375C5;LOWER_PartialSideHaloOverlap_Fingered2;LOWER_PartialSideHaloOverlap_Fingered3;0.002;
376C6;LOWER_PartialSideHaloOverlap_Fingered2;UPPER;2.466;
377C7;LOWER_PartialSideHaloOverlap_Fingered2;VSUBS;8.16;
378C8;LOWER_PartialSideHaloOverlap_Fingered3;UPPER;0.159;
379C9;LOWER_PartialSideHaloOverlap_Fingered3;VSUBS;8.164;
380C10;LOWER_PartialSideHaloOverlap_Fingered4;UPPER;0.358;
381C11;LOWER_PartialSideHaloOverlap_Fingered4;VSUBS;5.889;
382C12;UPPER;VSUBS;215.281;"""
383 )
386@allure.parent_suite(parent_suite)
387@allure.tag(*tags)
388@pytest.mark.slow
389def test_sideoverlap_complex_li1_m1():
390 # MAGIC GIVES (8.3 revision 485): (sorting changed to match order)
391 # _______________________________ NOTE: with halo=50µm __________________________________
392 #
393 # C6 Complex_Shape_L VSUBS 3.19991f
394 # C8 Complex_Shape_T VSUBS 3.19991f
395 # C7 Complex_Shape_R VSUBS 3.19991f
396 # C5 Complex_Shape_B VSUBS 3.19991f
397 # C4 UPPER VSUBS 13.0192f
398 # C0 Complex_Shape_B UPPER 1.34751f
399 # C3 Complex_Shape_T UPPER 0.064969f
400 # C2 Complex_Shape_R UPPER 0.089357f
401 # C1 Complex_Shape_L UPPER 0.24889f
403 pex_whiteboxed.assert_expected_matches_obtained(
404 'test_patterns', 'sideoverlap_complex_li1_m1.gds.gz',
405 expected_csv_content="""Device;Net1;Net2;Capacitance [fF];Resistance [Ω]
406C1;Complex_Shape_B;UPPER;1.348;
407C2;Complex_Shape_B;VSUBS;3.2;
408C3;Complex_Shape_L;UPPER;0.249;
409C4;Complex_Shape_L;VSUBS;3.2;
410C5;Complex_Shape_R;UPPER;0.089;
411C6;Complex_Shape_R;VSUBS;3.2;
412C7;Complex_Shape_T;UPPER;0.065;
413C8;Complex_Shape_T;VSUBS;3.2;
414C9;UPPER;VSUBS;13.019;"""
415 )
417@allure.parent_suite(parent_suite)
418@allure.tag(*tags)
419@pytest.mark.slow
420def test_mom_cap__whiteboxed():
421 # MAGIC GIVES (8.3 revision 485): (sorting changed to match order)
422 # _______________________________ NOTE: with halo=50µm __________________________________
423 # C0 C0 C1 13.4653f
424 # C1 C1 SUB 0.77621f
425 # C2 C0 SUB 2.83686f
427 pex_whiteboxed.assert_expected_matches_obtained(
428 'cap_vpp_04p4x04p6_l1m1m2_noshield', 'cap_vpp_04p4x04p6_l1m1m2_noshield.gds.gz',
429 expected_csv_content="""Device;Net1;Net2;Capacitance [fF];Resistance [Ω]
430C1;C0;C1;13.917;
431C2;C0;VSUBS;2.827;
432C3;C1;VSUBS;0.765;"""
433 )
435@allure.parent_suite(parent_suite)
436@allure.tag(*tags)
437@pytest.mark.slow
438def test_mom_cap__blackboxed():
439 # MAGIC GIVES (8.3 revision 485): (sorting changed to match order)
440 # _______________________________ NOTE: with halo=50µm __________________________________
441 # C0 C0 C1 13.4653f
442 # C1 C1 SUB 0.77621f
443 # C2 C0 SUB 2.83686f
445 pex_blackboxed.assert_expected_matches_obtained(
446 'cap_vpp_04p4x04p6_l1m1m2_noshield', 'cap_vpp_04p4x04p6_l1m1m2_noshield.gds.gz',
447 expected_csv_content="""Device;Net1;Net2;Capacitance [fF];Resistance [Ω]
448C1;C0;C1;0.218;
449C2;C0;VSUBS;3.562;
450C3;C1;VSUBS;0.117;"""
451 )