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

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# 

24 

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). 

28 

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). 

31 

32NOTE: imports neither KLayout nor generated protobuf code, so that format-only paths can use it 

33""" 

34 

35from __future__ import annotations 

36from dataclasses import dataclass, field 

37from typing import * 

38 

39from .expression.nodes import NumberOrExpression 

40 

41 

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] 

49 

50 

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 

60 

61 

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. 

66 

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) 

72 

73 # the model or subcircuit, e.g. of a diode or a subcircuit call 

74 model: Optional[str] = None 

75 

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 

79 

80 parameters: Dict[str, NumberOrExpression] = field(default_factory=dict) 

81 

82 # K: the coupled inductors, F and H: the voltage source of the controlling current 

83 references: List[str] = field(default_factory=list) 

84 

85 # V and I 

86 source: Optional[SpiceSource] = None 

87 

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() 

94 

95 

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) 

102 

103 # of its .param lines, which its calls don't set 

104 local_parameters: Dict[str, NumberOrExpression] = field(default_factory=dict) 

105 

106 

107@dataclass 

108class SpiceNetlist: 

109 subcircuits: List[SpiceSubcircuit] = field(default_factory=list) 

110 

111 # the elements outside of subcircuits (e.g. of a testbench) 

112 elements: List[SpiceElement] = field(default_factory=list) 

113 

114 # nodes that are the same in all subcircuits (.global), besides ground 

115 global_nodes: List[str] = field(default_factory=list) 

116 

117 # of the .param lines outside of subcircuits 

118 parameters: Dict[str, NumberOrExpression] = field(default_factory=dict)