Coverage for qpdk / cells / airbridge.py: 100%

25 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-04-02 17:50 +0000

1"""Airbridge components for superconducting quantum circuits. 

2 

3This module provides airbridge components for crossing transmission lines 

4without electrical contact, essential for complex quantum circuit layouts. 

5Airbridges are elevated metal structures that span over underlying circuits. 

6""" 

7 

8from __future__ import annotations 

9 

10import gdsfactory as gf 

11from gdsfactory.component import Component 

12from gdsfactory.typings import LayerSpec 

13 

14from qpdk import tech 

15from qpdk.tech import LAYER 

16 

17 

18@gf.cell(tags=("interconnects",)) 

19def airbridge( 

20 bridge_length: float = 30.0, 

21 bridge_width: float = 8.0, 

22 pad_width: float = 15.0, 

23 pad_length: float = 12.0, 

24 bridge_layer: LayerSpec = LAYER.AB_DRAW, 

25 pad_layer: LayerSpec = LAYER.AB_VIA, 

26) -> Component: 

27 """Generate a superconducting airbridge component. 

28 

29 Creates an airbridge consisting of a suspended bridge span and landing pads 

30 on either side. The bridge allows transmission lines to cross over each other 

31 without electrical contact, which is essential for complex quantum circuit 

32 routing without crosstalk. 

33 

34 .. svgbob:: 

35 

36 +─────────+ 

37 │ landing │ AB_VIA 

38 │ pad │ 

39 +─+ +─+ 

40 │ │ 

41 │ │ bridge AB_DRAW 

42 │ │ 

43 +─+ +─+ 

44 │ landing │ AB_VIA 

45 │ pad │ 

46 +─────────+ 

47 

48 The bridge_layer (AB_DRAW) represents the elevated metal bridge structure, 

49 while the pad_layer (AB_VIA) represents the contact/landing pads that connect 

50 to the underlying circuit. 

51 

52 Note: 

53 To be used with :class:`~gdsfactory.cross_section.ComponentAlongPath` 

54 the unrotated version should be *oriented for placement on a horizontal line*. 

55 

56 Args: 

57 bridge_length: Total length of the airbridge span in µm. 

58 bridge_width: Width of the suspended bridge in µm. 

59 pad_width: Width of the landing pads in µm. 

60 pad_length: Length of each landing pad in µm. 

61 bridge_layer: Layer for the suspended bridge metal (default: AB_DRAW). 

62 pad_layer: Layer for the landing pads/contacts (default: AB_VIA). 

63 

64 Returns: 

65 Component containing the airbridge geometry with appropriate ports. 

66 """ 

67 c = gf.Component() 

68 

69 # Create the suspended bridge 

70 c << gf.components.rectangle( 

71 size=(bridge_length, bridge_width), 

72 layer=bridge_layer, 

73 centered=True, 

74 ) 

75 

76 # Create left landing pad 

77 left_pad = c << gf.components.rectangle( 

78 size=(pad_length, pad_width), 

79 layer=pad_layer, 

80 centered=True, 

81 ) 

82 left_pad.move((-bridge_length / 2 - pad_length / 2, 0)) 

83 

84 # Create right landing pad 

85 right_pad = c << gf.components.rectangle( 

86 size=(pad_length, pad_width), 

87 layer=pad_layer, 

88 centered=True, 

89 ) 

90 right_pad.move((bridge_length / 2 + pad_length / 2, 0)) 

91 

92 # Port configuration data 

93 port_configs = [ 

94 { 

95 "name": "o1", 

96 "center": (0, bridge_width / 2), 

97 "width": bridge_width, 

98 "orientation": 90, 

99 "layer": bridge_layer, 

100 "port_type": "placement", 

101 }, 

102 { 

103 "name": "o2", 

104 "center": (0, -bridge_width / 2), 

105 "width": bridge_width, 

106 "orientation": 270, 

107 "layer": bridge_layer, 

108 "port_type": "placement", 

109 }, 

110 { 

111 "name": "e1", 

112 "center": (-bridge_length / 2 - pad_length, 0), 

113 "width": pad_width, 

114 "orientation": 180, 

115 "layer": pad_layer, 

116 "port_type": "electrical", 

117 }, 

118 { 

119 "name": "e2", 

120 "center": (bridge_length / 2 + pad_length, 0), 

121 "width": pad_width, 

122 "orientation": 0, 

123 "layer": pad_layer, 

124 "port_type": "electrical", 

125 }, 

126 ] 

127 

128 # Add all ports using the configuration data 

129 for config in port_configs: 

130 c.add_port(**config) 

131 

132 c.rotate(90) 

133 

134 return c 

135 

136 

137def cpw_with_airbridges( 

138 airbridge_spacing: float = 100.0, 

139 airbridge_padding: float = 10.0, 

140 bridge_component: Component | None = None, 

141 **cpw_kwargs, 

142) -> gf.CrossSection: 

143 """Create a coplanar waveguide cross-section with airbridges. 

144 

145 This function creates a CPW cross-section that includes airbridges placed 

146 at regular intervals along the transmission line. This is useful for 

147 preventing slot mode propagation and reducing crosstalk in quantum circuits. 

148 

149 Args: 

150 airbridge_spacing: Distance between airbridge centers in µm. 

151 airbridge_padding: Minimum distance from path start to first airbridge in µm. 

152 bridge_component: Custom airbridge component. If None, uses default airbridge. 

153 **cpw_kwargs: Additional arguments passed to the coplanar_waveguide function. 

154 

155 Returns: 

156 CrossSection with airbridges for use in routing functions. 

157 """ 

158 if bridge_component is None: 

159 bridge_component = airbridge() 

160 

161 # Create base CPW cross-section 

162 base_xs = tech.coplanar_waveguide(**cpw_kwargs) 

163 

164 # Create ComponentAlongPath for airbridges 

165 component_along_path = gf.ComponentAlongPath( 

166 component=bridge_component, 

167 spacing=airbridge_spacing, 

168 padding=airbridge_padding, 

169 ) 

170 

171 # Create a copy with airbridges using Pydantic model_copy 

172 return base_xs.model_copy(update={"components_along_path": (component_along_path,)}) 

173 

174 

175if __name__ == "__main__": 

176 # Example usage and testing 

177 from qpdk import PDK 

178 

179 PDK.activate() 

180 

181 # Create and display a single airbridge 

182 bridge = airbridge() 

183 bridge.show()