Coverage for klayout_pex/netlist/spice_netlist.py: 100%
39 statements
« prev ^ index » next coverage.py v7.17.2, created at 2026-11-06 13:14 +0000
« prev ^ index » next coverage.py v7.17.2, created at 2026-11-06 13:14 +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#
25"""
26A SPICE netlist as its elements and subcircuits, with the values as numbers or expressions
27(of parameters, see spice_hierarchy.py for their values in the subcircuit calls).
29It is what the writers of other netlist formats take (e.g. the VACASK writer),
30from a SPICE file (the SPICE reader) or from a KLayout netlist (the netlist printers).
32NOTE: imports neither KLayout nor generated protobuf code, so that format-only paths can use it
33"""
35from __future__ import annotations
36from dataclasses import dataclass, field
37from typing import *
39from .expression.nodes import NumberOrExpression
42@dataclass
43class SpiceSourceFunction:
44 """
45 The transient function of an independent source, e.g. PULSE(0 1 0 1n 1n 5n 10n)
46 """
47 name: str # lowercase, e.g. 'pulse', 'sin', 'exp', 'pwl'
48 arguments: List[float]
51@dataclass
52class SpiceSource:
53 """
54 The value of an independent source (V or I)
55 """
56 dc: Optional[float] = None
57 ac_magnitude: Optional[float] = None
58 ac_phase: Optional[float] = None # in degrees
59 function: Optional[SpiceSourceFunction] = None
62@dataclass
63class SpiceElement:
64 """
65 An element of a SPICE netlist, e.g. R1 a b 1k, or a subcircuit call, e.g. X1 a b inv.
67 The names are the ones of the netlist: nodes with the same name are one node
68 (a reader resolves SPICE's case insensitivity), the parameter names are lowercase.
69 """
70 name: str # the first letter is the kind of the element, e.g. 'R1', 'Xinv'
71 nodes: List[str] = field(default_factory=list)
73 # the model or subcircuit, e.g. of a diode or a subcircuit call
74 model: Optional[str] = None
76 # the value of R, C, L (resistance, capacitance, inductance), the coupling of K,
77 # the gain of E, F, G, H
78 value: Optional[NumberOrExpression] = None
80 parameters: Dict[str, NumberOrExpression] = field(default_factory=dict)
82 # K: the coupled inductors, F and H: the voltage source of the controlling current
83 references: List[str] = field(default_factory=list)
85 # V and I
86 source: Optional[SpiceSource] = None
88 @property
89 def kind(self) -> str:
90 """
91 The element letter in uppercase, e.g. 'R' or 'X'
92 """
93 return self.name[0].upper()
96@dataclass
97class SpiceSubcircuit:
98 name: str
99 ports: List[str]
100 parameters: Dict[str, NumberOrExpression] = field(default_factory=dict) # the defaults
101 elements: List[SpiceElement] = field(default_factory=list)
103 # of its .param lines, which its calls don't set
104 local_parameters: Dict[str, NumberOrExpression] = field(default_factory=dict)
107@dataclass
108class SpiceNetlist:
109 subcircuits: List[SpiceSubcircuit] = field(default_factory=list)
111 # the elements outside of subcircuits (e.g. of a testbench)
112 elements: List[SpiceElement] = field(default_factory=list)
114 # nodes that are the same in all subcircuits (.global), besides ground
115 global_nodes: List[str] = field(default_factory=list)
117 # of the .param lines outside of subcircuits
118 parameters: Dict[str, NumberOrExpression] = field(default_factory=dict)