hhi 6.22.1__cp312-cp312-macosx_10_13_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. hhi/__init__.py +26 -0
  2. hhi/cells/__init__.py +5 -0
  3. hhi/cells/die.py +462 -0
  4. hhi/cells/fixed.py +6171 -0
  5. hhi/cells/waveguides.py +335 -0
  6. hhi/cli.py +65 -0
  7. hhi/config.py +31 -0
  8. hhi/klayout/layers.lyp +292 -0
  9. hhi/klayout/tech.lyt +161 -0
  10. hhi/layers.yaml +89 -0
  11. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_BJsingle.csvy +20 -0
  12. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_BJtwin.csvy +20 -0
  13. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_DFB_1540_EMISSION_SPECTRUM_data.csvy +1028 -0
  14. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_DFB_1540_LI_data.csvy +266 -0
  15. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_DFB_RIN.csvy +168304 -0
  16. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_DirCoupE1700.csvy +58 -0
  17. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_E1700_TE_group_index.csvy +66 -0
  18. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_ELECTRO_ABSORPTION_MODULATOR_L100_data.csvy +68 -0
  19. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_ELECTRO_ABSORPTION_MODULATOR_L200_data.csvy +68 -0
  20. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_ELECTRO_OPTIC_MODULATOR_N12_S21_data.csvy +421 -0
  21. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_ELECTRO_OPTIC_MODULATOR_N20_S21_data.csvy +421 -0
  22. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_EOPMTermination_data.csvy +424 -0
  23. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_GRAT.csvy +76 -0
  24. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_MIR1.csvy +94 -0
  25. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_MIR2.csvy +119 -0
  26. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_MMI_SP/HHI_MMI1x2E1700_smatrix.csvy +14122 -0
  27. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_MMI_SP/HHI_MMI1x2E600_smatrix.csvy +18124 -0
  28. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_MMI_SP/HHI_MMI2x2E1700_smatrix.csvy +18177 -0
  29. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_MMI_SP/HHI_MMI2x2E600_smatrix.csvy +14175 -0
  30. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_MZMDD.csvy +28616 -0
  31. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_PDDC_dark_current.csvy +129 -0
  32. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_PDRFsingle.csvy +821 -0
  33. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_PDRFtwin.csvy +821 -0
  34. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_PIN_DIODE_data.csvy +34 -0
  35. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_PolSplitter.csvy +20 -0
  36. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_SSCLATE1700.csvy +20 -0
  37. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_SSCLATE200.csvy +20 -0
  38. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_STRAIGHT_WG_E1700_data.csvy +26 -0
  39. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_STRAIGHT_WG_E200_data.csvy +25 -0
  40. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_STRAIGHT_WG_E600_data.csvy +26 -0
  41. hhi/models/HHI_PDK_6_22_0_bb_performance_numeric/HHI_WGTE200E1700.csvy +88 -0
  42. hhi/models/__init__.py +60 -0
  43. hhi/models/hhi_fixed.py +636 -0
  44. hhi/models/straights.py +132 -0
  45. hhi/models_deprecated.py +53 -0
  46. hhi/pdk/__init__.cpython-312-darwin.so +0 -0
  47. hhi/tech.py +559 -0
  48. hhi-6.22.1.dist-info/METADATA +73 -0
  49. hhi-6.22.1.dist-info/RECORD +53 -0
  50. hhi-6.22.1.dist-info/WHEEL +6 -0
  51. hhi-6.22.1.dist-info/entry_points.txt +2 -0
  52. hhi-6.22.1.dist-info/licenses/LICENSE +21 -0
  53. hhi-6.22.1.dist-info/top_level.txt +1 -0
hhi/__init__.py ADDED
@@ -0,0 +1,26 @@
1
+ """hhi - HHI photonics PDK"""
2
+
3
+ from gdsfactory.config import CONF
4
+
5
+ from hhi import cells, config
6
+ from hhi.pdk import PDK
7
+ from hhi.tech import (
8
+ LAYER,
9
+ LAYER_STACK,
10
+ LAYER_VIEWS,
11
+ constants,
12
+ cross_sections,
13
+ )
14
+
15
+ CONF.max_cellname_length = 32
16
+ __all__ = (
17
+ "cells",
18
+ "config",
19
+ "PDK",
20
+ "LAYER",
21
+ "LAYER_VIEWS",
22
+ "LAYER_STACK",
23
+ "cross_sections",
24
+ "constants",
25
+ )
26
+ __version__ = "6.22.1"
hhi/cells/__init__.py ADDED
@@ -0,0 +1,5 @@
1
+ """All cells in PDK library."""
2
+
3
+ from hhi.cells.die import *
4
+ from hhi.cells.fixed import *
5
+ from hhi.cells.waveguides import *
hhi/cells/die.py ADDED
@@ -0,0 +1,462 @@
1
+ from functools import partial
2
+ from typing import Any
3
+
4
+ import gdsfactory as gf
5
+ import numpy as np
6
+ from gdsfactory.typings import (
7
+ ComponentSpec,
8
+ Float2,
9
+ LayerSpec,
10
+ LayerSpecs,
11
+ Size,
12
+ )
13
+
14
+ from hhi.tech import LAYER
15
+
16
+
17
+ @gf.cell
18
+ def pad(size: Size = (66, 66)) -> gf.Component:
19
+ """Returns rectangular pad with ports.
20
+
21
+ Args:
22
+ size: x, y size.
23
+ """
24
+ return gf.c.pad(
25
+ size=size,
26
+ layer="M2",
27
+ bbox_layers=("M1", "ISO"),
28
+ bbox_offsets=(2, 2),
29
+ )
30
+
31
+
32
+ @gf.cell
33
+ def cleave_mark() -> gf.Component:
34
+ """Create a cleave mark for the die."""
35
+ c = gf.Component(name="cleave_mark")
36
+ c.add_polygon([[0.0, 0.0], [15.442, 33.12], [33.119, 15.441]], layer=LAYER.TEXT)
37
+ return c
38
+
39
+
40
+ @gf.cell
41
+ def pad_GSG(xsize: float = 98, pitch: float = 136) -> gf.Component:
42
+ c = gf.components.straight_array(
43
+ n=1, spacing=pitch, length=xsize, cross_section="GSG"
44
+ ).copy()
45
+ # gf.add_padding(
46
+ # component=c,
47
+ # layers=("BB_outline",),
48
+ # default=0,
49
+ # )
50
+ gf.add_padding(
51
+ component=c,
52
+ layers=("ISO",),
53
+ default=0,
54
+ right=16,
55
+ left=16,
56
+ )
57
+ c.flatten()
58
+ return c
59
+
60
+
61
+ @gf.cell
62
+ def pad_GS(xsize: float = 98) -> gf.Component:
63
+ c = gf.components.straight(length=xsize, cross_section="GS")
64
+ return c
65
+
66
+
67
+ @gf.cell
68
+ def die(
69
+ size: tuple[float, float] = (8000, 4000), centered: bool = False
70
+ ) -> gf.Component:
71
+ """Create a die template with cleave marks.
72
+
73
+ Args:
74
+ size: Size of the die.
75
+ centered: If True, center the die on the origin.
76
+ """
77
+ c = gf.Component()
78
+ allowed_sizes = (
79
+ np.array(
80
+ [
81
+ (1, 1),
82
+ (1, 2),
83
+ (1, 4),
84
+ (1, 6),
85
+ (1, 8),
86
+ (2, 1),
87
+ (2, 2),
88
+ (2, 4),
89
+ (2, 6),
90
+ (4, 1),
91
+ (8, 1),
92
+ (2, 2),
93
+ (4, 2),
94
+ (8, 2),
95
+ (12, 2),
96
+ (4, 4),
97
+ (8, 4),
98
+ (8, 6),
99
+ (12, 4),
100
+ (1, 8),
101
+ (2, 8),
102
+ (3, 8),
103
+ (4, 8),
104
+ (1, 12),
105
+ (12, 12),
106
+ (2, 12),
107
+ (3, 12),
108
+ (4, 12),
109
+ (8, 24),
110
+ ]
111
+ )
112
+ * 1000
113
+ )
114
+
115
+ # Check size is in the available sizes
116
+ if not any(np.allclose(size, s) for s in allowed_sizes):
117
+ allowed_sizes = " mm \n".join(map(str, np.round(allowed_sizes * 1e-3)))
118
+ raise ValueError(f"Size must be one of {allowed_sizes}")
119
+ # Add the BB exclusion zone, demarking the chip boundary
120
+ die = c << gf.components.die(size=size, street_width=50, die_name="")
121
+ if not centered:
122
+ die.movex(size[0] / 2)
123
+ die.movey(size[1] / 2)
124
+
125
+ # Add the 4 cleave marks in each corner
126
+ for corner, p2 in zip(
127
+ [(0, 0), (0, 1), (1, 0), (1, 1)], [(1, 1), (1, 0), (0, 1), (1, -1)]
128
+ ):
129
+ cm = c << cleave_mark()
130
+ p1 = (0, 0)
131
+ p2 = (p2[0], p2[1])
132
+ cm.dmirror(p1=p1, p2=p2)
133
+ cm.movex(corner[0] * size[0] - size[0] / 2 * (centered))
134
+ cm.movey(corner[1] * size[1] - size[1] / 2 * (centered))
135
+
136
+ return c
137
+
138
+
139
+ @gf.cell
140
+ def die_rf(
141
+ size: tuple[float, float] = (8000, 4000),
142
+ num_dc_pads: int = 23,
143
+ dc_pad_pitch: float = 150.0,
144
+ dc_pad_size: tuple[float, float] = (98, 138),
145
+ chip_facet_to_pad_center: float = 3230,
146
+ num_rf_pads: int = 8,
147
+ rf_pad_sizex: float = 98.0,
148
+ rf_pad_pitch: float = 400,
149
+ rf_pad_pos=(100, 0),
150
+ num_SSCs: int = 10,
151
+ ssc: ComponentSpec = "HHI_SSCLATE1700",
152
+ ) -> gf.Component:
153
+ """Create a template for RF connections.
154
+ # TODO: Add the RF connections, text labels, design region, etc.
155
+
156
+ Args:
157
+ size: Size of the die.
158
+ num_dc_pads: Number of DC pads.
159
+ dc_pad_pitch: Spacing between DC pads.
160
+ dc_pad_size: Size of the DC pads.
161
+ num_rf_pads: Number of RF pads.
162
+ rf_pad_sizex: Size of the RF pads in the x-direction.
163
+ rf_pad_pitch: Spacing between RF pads.
164
+ rf_pad_pos: Position of the RF pads.
165
+ num_SSCs: Number of spot size converters SSCs.
166
+ ssc: SSC component.
167
+ """
168
+ c = gf.Component()
169
+
170
+ # Fixed parameters
171
+ dc_pad_pos_top = (chip_facet_to_pad_center, size[1] - 114 - dc_pad_size[1] / 2)
172
+ dc_pad_pos_bot = (chip_facet_to_pad_center, 114 + dc_pad_size[1] / 2)
173
+
174
+ ssc = gf.get_component(ssc)
175
+
176
+ SSCs_pos = (size[0] - ssc.xsize / 2, size[1] / 2)
177
+ SSCs_spacing = 127
178
+
179
+ d = c << die(size=size)
180
+
181
+ # Add HHI_ID cell square
182
+ # id_pos = (size[0] - 150, 150)
183
+ # HHI_ID = gf.components.rectangle(
184
+ # size=(100, 100), layer="BB_outline", centered=True, port_type=None
185
+ # ).copy()
186
+ # HHI_ID.name = "HHI_ID"
187
+ # hhi_id = c << HHI_ID
188
+ # hhi_id.move(id_pos)
189
+
190
+ # Add the DC pads at the top
191
+ dc_pads = c << gf.components.array(
192
+ pad(size=dc_pad_size), column_pitch=dc_pad_pitch, columns=num_dc_pads
193
+ )
194
+ dc_pads.move(dc_pad_pos_top)
195
+ c.add_ports(dc_pads.ports, prefix="top_")
196
+ dc_ports = dc_pads.ports.filter(orientation=270)
197
+
198
+ for i, port in enumerate(dc_ports[:-2]):
199
+ t = c << gf.c.text(
200
+ text=f"T{i + 1}",
201
+ size=60,
202
+ layer="BB_outline",
203
+ justify="center",
204
+ )
205
+ t.center = port.center
206
+ t.movey(-100)
207
+
208
+ port = dc_ports[-2]
209
+ t = c << gf.c.text(
210
+ text="P",
211
+ size=60,
212
+ layer="BB_outline",
213
+ justify="center",
214
+ )
215
+ t.center = port.center
216
+ t.movey(-100)
217
+
218
+ port = dc_ports[-1]
219
+ t = c << gf.c.text(
220
+ text="N",
221
+ size=60,
222
+ layer="BB_outline",
223
+ justify="center",
224
+ )
225
+ t.center = port.center
226
+ t.movey(-100)
227
+
228
+ # Add the DC pads at the bottom
229
+ dc_pads = c << gf.components.array(
230
+ pad(size=dc_pad_size), column_pitch=dc_pad_pitch, columns=num_dc_pads
231
+ )
232
+ dc_pads.move(dc_pad_pos_bot)
233
+ c.add_ports(dc_pads.ports, prefix="bot_")
234
+ dc_ports = dc_pads.ports.filter(orientation=90)
235
+ dy = +100
236
+
237
+ for i, port in enumerate(dc_ports[:-2]):
238
+ t = c << gf.c.text(
239
+ text=f"B{i + 1}",
240
+ size=60,
241
+ layer="BB_outline",
242
+ justify="center",
243
+ )
244
+ t.center = port.center
245
+ t.movey(dy)
246
+
247
+ port = dc_ports[-2]
248
+ t = c << gf.c.text(
249
+ text="P",
250
+ size=60,
251
+ layer="BB_outline",
252
+ justify="center",
253
+ )
254
+ t.center = port.center
255
+ t.movey(dy)
256
+
257
+ port = dc_ports[-1]
258
+ t = c << gf.c.text(
259
+ text="N",
260
+ size=60,
261
+ layer="BB_outline",
262
+ justify="center",
263
+ )
264
+ t.center = port.center
265
+ t.movey(dy)
266
+
267
+ # Add the RF ports on the left side
268
+ pad_array = gf.components.straight_array(
269
+ n=num_rf_pads, spacing=rf_pad_pitch, length=rf_pad_sizex, cross_section="GSG"
270
+ )
271
+ rf_pads = c << pad_array
272
+ rf_pads.y = d.y
273
+ rf_pads.move((rf_pad_pos[0], rf_pad_pos[1]))
274
+ rf_ports = rf_pads.ports.filter(orientation=0)
275
+
276
+ for i, port in enumerate(rf_ports):
277
+ t = c << gf.c.text(
278
+ text=f"GSG{i + 1}",
279
+ size=60,
280
+ layer="BB_outline",
281
+ justify="center",
282
+ )
283
+ t.center = port.center
284
+ t.movex(100)
285
+
286
+ c.add_ports(rf_ports, prefix="rf_")
287
+
288
+ # Add the SSCs at the right side
289
+ sscs = c << gf.components.array(
290
+ ssc,
291
+ row_pitch=SSCs_spacing,
292
+ columns=1,
293
+ rows=num_SSCs,
294
+ centered=True,
295
+ )
296
+ sscs.move(SSCs_pos)
297
+ SSC_E1700_ports = gf.port.get_ports_list(sscs.ports, prefix="o1")
298
+ c.add_ports(SSC_E1700_ports, prefix="SSC_")
299
+
300
+ for i, port in enumerate(SSC_E1700_ports[1:-1]):
301
+ t = c << gf.c.text(
302
+ text=f"OPT{i + 1}",
303
+ size=60,
304
+ layer="BB_outline",
305
+ justify="center",
306
+ )
307
+ t.center = port.center
308
+ t.movex(-150)
309
+
310
+ port = SSC_E1700_ports[0]
311
+ t = c << gf.c.text(
312
+ text="PD S0",
313
+ size=60,
314
+ layer="BB_outline",
315
+ justify="center",
316
+ )
317
+ t.center = port.center
318
+ t.movex(-150)
319
+
320
+ port = SSC_E1700_ports[-1]
321
+ t = c << gf.c.text(
322
+ text="PD N0",
323
+ size=60,
324
+ layer="BB_outline",
325
+ justify="center",
326
+ )
327
+ t.center = port.center
328
+ t.movex(-150)
329
+
330
+ return c
331
+
332
+
333
+ add_pads_bot = partial(
334
+ gf.routing.add_pads_bot,
335
+ component="HHI_DFB",
336
+ pad="pad",
337
+ cross_section="DC",
338
+ straight_separation=30,
339
+ bend="bend_circular",
340
+ port_names=("e1", "e2"),
341
+ auto_taper=False,
342
+ )
343
+
344
+ add_pads_top = partial(
345
+ gf.routing.add_pads_top,
346
+ component="HHI_DFB",
347
+ pad="pad",
348
+ cross_section="DC",
349
+ straight_separation=30,
350
+ bend="bend_circular",
351
+ port_names=("e1", "e2"),
352
+ auto_taper=False,
353
+ )
354
+
355
+
356
+ @gf.cell
357
+ def edge_coupler_with_angle(
358
+ angle: float | None = -8,
359
+ cross_section="E1700",
360
+ edge_coupler: ComponentSpec = "HHI_SSCLATE1700",
361
+ ) -> gf.Component:
362
+ """Inverse taper edge coupler Cband."""
363
+ c = gf.get_component(edge_coupler)
364
+
365
+ if angle:
366
+ c2 = gf.Component()
367
+ ref = c2.add_ref(c)
368
+ ref.rotate(angle=angle)
369
+ bend = c2.add_ref_off_grid(
370
+ gf.c.bend_euler_all_angle(angle=angle, cross_section=cross_section)
371
+ )
372
+ bend.connect("o2", ref.ports["o1"])
373
+ c2.add_port(name="o1", port=bend.ports["o1"])
374
+ c2.add_port(name="o2", port=ref.ports["o2"])
375
+ c2.flatten()
376
+ return c2
377
+ else:
378
+ return c
379
+
380
+
381
+ @gf.cell
382
+ def text_rectangular(
383
+ text: str = "abc",
384
+ size: float = 3,
385
+ justify: str = "left",
386
+ layer: LayerSpec = "M1",
387
+ ) -> gf.Component:
388
+ """Returns Pixel based font, guaranteed to be manhattan, without acute angles.
389
+
390
+ Args:
391
+ text: string.
392
+ size: pixel size.
393
+ justify: left, right or center.
394
+ layer: for text.
395
+ """
396
+ return gf.c.text_rectangular(
397
+ text=text,
398
+ size=size,
399
+ justify=justify,
400
+ layer=None,
401
+ position=(0.0, 0.0),
402
+ layers=(layer,),
403
+ )
404
+
405
+
406
+ @gf.cell
407
+ def text_rectangular_multi_layer(
408
+ text: str = "abc",
409
+ layers: LayerSpecs = (
410
+ "M1",
411
+ "M2",
412
+ ),
413
+ text_factory: ComponentSpec = "text_rectangular",
414
+ **kwargs: Any,
415
+ ) -> gf.Component:
416
+ """Returns rectangular text in different layers.
417
+
418
+ Args:
419
+ text: string of text.
420
+ layers: list of layers to replicate the text.
421
+ text_factory: function to create the text Components.
422
+ kwargs: keyword arguments for text_factory.
423
+ """
424
+ return gf.c.text_rectangular_multi_layer(
425
+ text=text,
426
+ layers=layers,
427
+ text_factory=text_factory,
428
+ **kwargs,
429
+ )
430
+
431
+
432
+ @gf.cell
433
+ def edge_coupler_array(
434
+ edge_coupler: ComponentSpec = "edge_coupler_with_angle",
435
+ n: int = 5,
436
+ pitch: float = 127.0,
437
+ text: ComponentSpec | None = "text_rectangular",
438
+ text_offset: Float2 = (-50, 0),
439
+ text_rotation: float = 0,
440
+ ) -> gf.Component:
441
+ """Fiber array edge coupler.
442
+
443
+ Args:
444
+ edge_coupler: edge coupler.
445
+ cross_section: spec.
446
+ radius: bend radius loopback (um).
447
+ n: number of channels.
448
+ pitch: Fiber pitch (um).
449
+ text: Optional text spec.
450
+ text_offset: x, y.
451
+ text_rotation: text rotation in degrees.
452
+ """
453
+
454
+ return gf.c.edge_coupler_array(
455
+ edge_coupler=edge_coupler,
456
+ n=n,
457
+ pitch=pitch,
458
+ text=text,
459
+ text_offset=text_offset,
460
+ text_rotation=text_rotation,
461
+ x_reflection=False,
462
+ )