Coverage for tests/rcx25/rcx25_CC_ihp_sg13g2_test.py: 100%
33 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-02 23:32 +0000
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-02 23:32 +0000
1#
2# --------------------------------------------------------------------------------
3# SPDX-FileCopyrightText: 2024-2026 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/iic-jku/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 csv
27import pytest
29from rcx25_test_helpers import *
31parent_suite = "kpex/2.5D Extraction Tests [PDK ihp-sg13g2 | mode CC]"
32tags = ("PEX", "2.5D")
35pex_whiteboxed = RCX25Extraction(pdk=PDKTestConfig(PDKName.IHP_SG13G2), pex_mode=PEXMode.CC, blackbox=False)
36pex_blackboxed = RCX25Extraction(pdk=PDKTestConfig(PDKName.IHP_SG13G2), pex_mode=PEXMode.CC, blackbox=True)
39@allure.parent_suite(parent_suite)
40@allure.tag(*tags)
41@pytest.mark.slow
42def test_mim_cap__whiteboxed():
43 # The device model gives cap_carea 1.5 fF/µm² * 6.99 µm * 6.99 µm = 73.29 fF
44 # plus CJSW 40 aF/µm * 27.96 µm = 1.12 fF, the fringe to the bottom plate (Metal5) around the top plate (MIM)
45 # NOTE: the plates' nets have no labels, so their names ($1, $2, ...) depend on the LVS run
46 _, csv_path, _ = pex_whiteboxed.run_rcx25d_single_cell('sg13g2_pr__cmim', 'cmim.gds.gz')
47 with open(csv_path) as f:
48 rows = list(csv.DictReader(f, delimiter=';'))
49 caps = [(('VSUBS' in (row['Net1'], row['Net2'])), float(row['Capacitance [fF]'])) for row in rows]
50 assert sorted(cap for to_substrate, cap in caps if not to_substrate) == [74.784] # between the plates
51 assert sorted(cap for to_substrate, cap in caps if to_substrate) == [0.878, 1.38] # top and bottom plate
54@allure.parent_suite(parent_suite)
55@allure.tag(*tags)
56@pytest.mark.slow
57def test_mom_cap__whiteboxed():
58 # The device model gives 0.915 fF/µm² (fingers on Metal2 … Metal4) * 10 µm * 25 µm = 228.75 fF
59 pex_whiteboxed.assert_expected_matches_obtained(
60 'test_patterns', 'cap_cmomf_w10u_l25u_m2_m4_m5_wire.gds.gz',
61 expected_csv_content="""Device;Net1;Net2;Capacitance [fF];Resistance [Ω]
62C1;MINUS;PLUS;205.148;
63C2;MINUS;VSUBS;6.757;
64C3;MINUS;X;1.805;
65C4;PLUS;VSUBS;6.829;
66C5;PLUS;X;1.911;
67C6;VSUBS;X;1.292;"""
68 )
71@allure.parent_suite(parent_suite)
72@allure.tag(*tags)
73@pytest.mark.slow
74def test_mom_cap__blackboxed():
75 # The fingers of the MOM cap are metal of its terminal nets, so --blackbox extracted their capacitance
76 # on top of the device, whose model has it: 205.148 fF more between PLUS and MINUS (#211 §9).
77 # The model has no substrate terminal, so the capacitances of the fingers to the substrate
78 # and to the wire X across are extracted, the same as in white-box mode
79 pex_blackboxed.assert_expected_matches_obtained(
80 'test_patterns', 'cap_cmomf_w10u_l25u_m2_m4_m5_wire.gds.gz',
81 expected_csv_content="""Device;Net1;Net2;Capacitance [fF];Resistance [Ω]
82C1;MINUS;VSUBS;6.757;
83C2;MINUS;X;1.805;
84C3;PLUS;VSUBS;6.829;
85C4;PLUS;X;1.911;
86C5;VSUBS;X;1.292;"""
87 )
90@allure.parent_suite(parent_suite)
91@allure.tag(*tags)
92@pytest.mark.slow
93def test_rf_mim_cap__blackboxed():
94 # The rfcmim of the PDK's cell library (sg13g2_pr), its model is cap_rfcmim, with the substrate as 3rd terminal
95 assert pex_blackboxed.written_device_lines('sg13g2_pr__rfcmim', 'rfcmim.gds.gz') == [
96 'X$1 \\$5 \\$4 sub! cap_rfcmim w=7e-06 l=7e-06 m=1 wfeed=3e-06',
97 ]