Skip to content

Commit

Permalink
Merge pull request #1496 from gdsfactory/6726
Browse files Browse the repository at this point in the history
fix mzi with new routing
  • Loading branch information
joamatab committed Mar 28, 2023
2 parents 644b248 + 6495c69 commit 2ac53b8
Show file tree
Hide file tree
Showing 37 changed files with 642 additions and 243 deletions.
11 changes: 7 additions & 4 deletions gdsfactory/components/mzi.py
Expand Up @@ -142,7 +142,8 @@ def mzi(
sxt.connect("o1", b2.ports["o1"])

cp2.mirror()
cp2.xmin = sxt.ports["o2"].x + bend.info["radius"] * nbends + 0.1
xs = gf.get_cross_section(cross_section)
cp2.xmin = sxt.ports["o2"].x + bend.info["radius"] * nbends + 2 * xs.min_length

route = get_route(
sxt.ports["o2"],
Expand All @@ -159,6 +160,7 @@ def mzi(
straight=straight,
bend=bend_spec,
cross_section=cross_section,
with_sbend=False,
)
c.add(route.references)

Expand Down Expand Up @@ -210,12 +212,13 @@ def mzi(


if __name__ == "__main__":
c = mzi(cross_section="nitride")
# c = gf.components.mzi2x2_2x2(straight_x_top="straight_heater_metal")
# c.show(show_ports=True)

c = gf.components.mzi2x2_2x2(straight_x_top="straight_heater_metal")
c2 = gf.routing.add_fiber_array(c)
c2.show()
# c = gf.components.mzi2x2_2x2(straight_x_top="straight_heater_metal")
# c2 = gf.routing.add_fiber_array(c)
c.show()

# c1.write_gds("a.gds")

Expand Down
3 changes: 2 additions & 1 deletion gdsfactory/components/mzm.py
Expand Up @@ -113,7 +113,8 @@ def mzm(
if combiner:
cp2 = c << cp2
cp2.mirror()
cp2.xmin = sxt.ports["o2"].x + bend.info["radius"] * nbends + 0.1
xs = gf.get_cross_section(cross_section)
cp2.xmin = sxt.ports["o2"].x + bend.info["radius"] * nbends + 2 * xs.min_length

route = get_route(
sxt.ports["o2"],
Expand Down
75 changes: 42 additions & 33 deletions gdsfactory/components/via_stack.py
@@ -1,5 +1,6 @@
from __future__ import annotations

import warnings
from typing import Optional, Tuple

import numpy as np
Expand Down Expand Up @@ -40,13 +41,20 @@ def via_stack(
vias: vias to use to fill the rectangles.
layer_port: if None assumes port is on the last layer.
correct_size: if True, if the specified dimensions are too small it increases
them to the minimum possible to fit a via
them to the minimum possible to fit a via.
"""
width_m, height_m = size
a = width_m / 2
b = height_m / 2

layers = layers or []
layer_offsets = layer_offsets or [0] * len(layers)

elements = {len(layers), len(layer_offsets), len(vias)}
if len(elements) > 1:
warnings.warn(
f"Got {len(layers)} layers, {len(layer_offsets)} layer_offsets, {len(vias)} vias "
)

if layers:
layer_port = layer_port or layers[-1]
Expand All @@ -56,8 +64,6 @@ def via_stack(
c.info["size"] = (float(size[0]), float(size[1]))
c.info["layer"] = layer_port

layer_offsets = layer_offsets or [0] * len(layers)

for layer, offset in zip(layers, layer_offsets):
size_m = (width_m + 2 * offset, height_m + 2 * offset)
if layer == layer_port:
Expand All @@ -67,18 +73,16 @@ def via_stack(
ref = c << compass(size=size_m, layer=layer, port_type="placement")

vias = vias or []
for via_type, offs in zip(vias, layer_offsets):
if via_type is not None:
for via, offs in zip(vias, layer_offsets):
if via is not None:
width, height = size
via = gf.get_component(via)
w, h = via.info["size"]
enclosure = via.info["enclosure"]
pitch_x, pitch_y = via.info["spacing"]

via_type = gf.get_component(via_type)

w, h = via_type.info["size"]
g = via_type.info["enclosure"]
pitch_x, pitch_y = via_type.info["spacing"]

min_width = w + g
min_height = h + g
min_width = w + enclosure
min_height = h + enclosure

if (
min_width > width
Expand All @@ -87,20 +91,25 @@ def via_stack(
and min_height > height
and correct_size
):
print("Changing sizes to fit a via! Check this is desired")
warnings.warn("Changing sizes to fit a via! Check this is desired")
width = max(min_width, width)
height = max(min_height, height)
elif min_width > width or min_height > height:
raise ValueError(f"size {size} is too small to fit a {(w, h)} um via")

nb_vias_x = (width + 2 * offs - w - 2 * g) / pitch_x + 1
nb_vias_y = (height + 2 * offs - h - 2 * g) / pitch_y + 1
nb_vias_x = abs(width + 2 * offs - w - 2 * enclosure) / pitch_x + 1
nb_vias_y = abs(height + 2 * offs - h - 2 * enclosure) / pitch_y + 1

nb_vias_x = int(np.floor(nb_vias_x)) or 1
nb_vias_y = int(np.floor(nb_vias_y)) or 1
ref = c.add_array(
via_type, columns=nb_vias_x, rows=nb_vias_y, spacing=(pitch_x, pitch_y)
via, columns=nb_vias_x, rows=nb_vias_y, spacing=(pitch_x, pitch_y)
)
if ref.xsize + enclosure > width or ref.ysize + enclosure > height:
warnings.warn(
f"size = {size} for layer {layer} violates min enclosure"
f" {enclosure} for via {via.name!r}"
)

a = width / 2
b = height / 2
Expand Down Expand Up @@ -166,17 +175,17 @@ def via_stack_circular(
# This will of course fail if no via information is provided,
# but why would you instantiate a ViaStack without any via?

for level, via_type in enumerate(vias):
if via_type is None:
for level, via in enumerate(vias):
if via is None:
continue

metal_bottom = layers[level]
metal_top = layers[level + 1]
via_type = gf.get_component(via_type)
via = gf.get_component(via)

w, h = via_type.info["size"]
g = via_type.info["enclosure"]
pitch_x, pitch_y = via_type.info["spacing"]
w, h = via.info["size"]
g = via.info["enclosure"]
pitch_x, pitch_y = via.info["spacing"]

nb_vias_x = (width - w - 2 * g) / pitch_x + 1
nb_vias_x = int(np.floor(nb_vias_x)) or 1
Expand All @@ -191,7 +200,7 @@ def via_stack_circular(
pos = radius * np.array((np.cos(ang), np.sin(ang)))

ref = c.add_array(
via_type, columns=nb_vias_x, rows=1, spacing=(pitch_x, pitch_y)
via, columns=nb_vias_x, rows=1, spacing=(pitch_x, pitch_y)
)
ref.center = pos

Expand Down Expand Up @@ -315,22 +324,22 @@ def via_stack_from_rules(
):
if current_via is not None:
# Optimize via
via_type = gf.get_component(
via = gf.get_component(
optimized_via(current_via, size, min_size, min_gap, min_enclosure)
)
c.info["vias"].append(via_type.info)
c.info["vias"].append(via.info)

w, h = via_type.info["size"]
g = via_type.info["enclosure"]
pitch_x, pitch_y = via_type.info["spacing"]
w, h = via.info["size"]
g = via.info["enclosure"]
pitch_x, pitch_y = via.info["spacing"]

nb_vias_x = (width - w - 2 * g) / pitch_x + 1
nb_vias_y = (height - h - 2 * g) / pitch_y + 1

nb_vias_x = int(np.floor(nb_vias_x)) or 1
nb_vias_y = int(np.floor(nb_vias_y)) or 1
ref = c.add_array(
via_type, columns=nb_vias_x, rows=nb_vias_y, spacing=(pitch_x, pitch_y)
via, columns=nb_vias_x, rows=nb_vias_y, spacing=(pitch_x, pitch_y)
)

cw = (width - (nb_vias_x - 1) * pitch_x - w) / 2
Expand Down Expand Up @@ -411,7 +420,7 @@ def test_via_stack_from_rules():
via_stack_m1_m3 = gf.partial(
via_stack,
layers=("M1", "M2", "M3"),
vias=(via1, via2),
vias=(via1, via2, None),
)

via_stack_slab_m3 = gf.partial(
Expand All @@ -435,10 +444,10 @@ def test_via_stack_from_rules():


if __name__ == "__main__":
c = via_stack_heater_mtop(layer_offsets=(0, 1, 2))
# c = via_stack_heater_mtop(layer_offsets=(0, 1, 2))

# c = via_stack_circular()
# c = via_stack_m1_m3(size=(1.0, 1.0))
c = via_stack_m1_m3(size=(4.5, 4.5))
# print(c.to_dict())
# c.show(show_ports=True)

Expand Down
14 changes: 13 additions & 1 deletion gdsfactory/components/via_stack_slot.py
@@ -1,5 +1,6 @@
from __future__ import annotations

import warnings
from typing import Optional

from numpy import floor
Expand Down Expand Up @@ -31,7 +32,7 @@ def via_stack_slot(
layers: layers on which to draw rectangles.
layer_offsets: cladding_offset for each layer.
layer_offsetsx: optional xoffset for layers, defaults to layer_offsets.
layer_offsetsx: optional yoffset for layers, defaults to layer_offsets.
layer_offsetsy: optional yoffset for layers, defaults to layer_offsets.
layer_port: if None assumes port is on the last layer.
via: via to use to fill the rectangles.
enclosure: of the via by rectangle.
Expand Down Expand Up @@ -85,6 +86,17 @@ def via_stack_slot(
layer_offsetsx = list(layer_offsetsx) + [0] * len(layers)
layer_offsetsy = list(layer_offsetsy) + [0] * len(layers)

elements = {
len(layers),
len(layer_offsets),
len(layer_offsetsx),
len(layer_offsetsy),
}
if len(elements) > 1:
warnings.warn(
f"Got {len(layers)} layers, {len(layer_offsets)} layer_offsets, {len(layer_offsetsx)} layer_offsetsx, {len(layer_offsetsy)} layer_offsetsy."
)

for layer, offsetx, offsety in zip(layers, layer_offsetsx, layer_offsetsy):
ref = c << compass(
size=(size[0] + 2 * offsetx, size[1] + 2 * offsety), layer=layer
Expand Down
4 changes: 2 additions & 2 deletions gdsfactory/components/via_stack_with_offset.py
Expand Up @@ -56,9 +56,9 @@ def via_stack_with_offset(

offsets = offsets or [0] * len(layers)
sizes = sizes or [size] * len(layers)
elements = {len(layers), len(sizes), len(vias)}
previous_layer = layers[0]

elements = {len(layers), len(sizes), len(vias)}
if len(elements) > 1:
warnings.warn(
f"Got {len(layers)} layers, {len(sizes)} sizes, {len(vias)} vias "
Expand Down Expand Up @@ -102,7 +102,7 @@ def via_stack_with_offset(
y0 += height
if ref.xsize + enclosure > width or ref.ysize + enclosure > height:
warnings.warn(
f"size[0] = {size[0]} for layer {layer} violates min enclosure"
f"size = {size} for layer {layer} violates min enclosure"
f" {enclosure} for via {via.name!r}"
)

Expand Down
Expand Up @@ -14,7 +14,7 @@ ports:
width: 1.0
o2:
center:
- 81.2
- 81.12
- 0.0
layer:
- 34
Expand Down
Expand Up @@ -14,7 +14,7 @@ ports:
width: 0.9
o2:
center:
- 81.2
- 81.12
- 0.0
layer:
- 34
Expand Down
2 changes: 1 addition & 1 deletion gdsfactory/write_cells.py
Expand Up @@ -216,7 +216,7 @@ def write_cells(
def test_write_cells_recursively():
gdspath = PATH.gdsdir / "mzi2x2.gds"
gdspaths = write_cells(gdspath=gdspath, dirpath="extra/gds", recursively=True)
assert len(gdspaths) == 10, len(gdspaths)
assert len(gdspaths) == 9, len(gdspaths)


def test_write_cells():
Expand Down
Binary file modified tests/gds/mzi2x2.gds
Binary file not shown.

0 comments on commit 2ac53b8

Please sign in to comment.