Basic sample generation

Let’s generate a 10 x 10 mm sample with an array of nTrons with different dimensions. First, imports:

1import qnngds as qg
2from phidl import quickplot as qp
3from functools import partial
4import phidl.geometry as pg
5import numpy as np

We’ll just use a single layer, so we can define the PDK as so:

 1ls = qg.LayerSet()
 2ls.add_layer(qg.Layer(name="PHOTO", gds_layer=1))
 3cross_sections = dict(
 4    photo=partial(qg.geometries.default_cross_section, layer="PHOTO"),
 5)
 6layer_transitions = qg.layer_auto_transitions(ls)
 7PDK = qg.Pdk(
 8    "single_layer_pdk",
 9    layers=ls,
10    cross_sections=cross_sections,
11    layer_transitions=layer_transitions,
12)
13PDK.activate()

Now we’ll set up an array of devices that we want to place on the sample:

 1ntrons = []
 2channel_w = 2.0
 3pad_array = qg.pads.array_single(
 4    pad_specs=(qg.pads.stack(size=(200, 100), layers=("PHOTO",)),),
 5    columns=1,
 6    rows=3,
 7    pitch=300,
 8)
 9route_groups = (
10    qg.experiment.RouteGroup(qg.get_cross_section("photo"), {"g": 2, "s": 1, "d": 3}),
11)
12ext = partial(pg.optimal_step, end_width=5, symmetric=True, layer=qg.get_layer("PHOTO"))
13for choke_w in np.linspace(0.2, 1.0, 9):
14    label_text = f"wg/wc {round(choke_w, 2)}/{round(channel_w, 2)}"
15    label = pg.text(
16        label_text, size=25, layer=qg.get_layer("PHOTO"), justify="center"
17    ).rotate(-90)
18    ntron = qg.devices.ntron.sharp(
19        choke_w=choke_w,
20        gate_w=2 * channel_w,
21        channel_w=channel_w,
22        drain_w=2 * channel_w,
23        source_w=2 * channel_w,
24        layer="PHOTO",
25    )
26    dut = qg.utilities.extend_ports(
27        device=ntron, port_names=["g", "s", "d"], extension=ext, auto_width=True
28    )
29    ntron_experiment = qg.experiment.generate(
30        dut=dut,
31        pad_array=pad_array,
32        label=label,
33        route_groups=route_groups,
34        dut_offset=(100, 0),
35        pad_offset=(-pad_array.xsize, -300),
36        label_offset=(150, 0),
37        retries=1,
38    )
39    ntron_experiment.rotate(90)
40    ntrons.append(ntron_experiment)

We can set up the sample and place the devices on it:

1sample = qg.sample.Sample(
2    cell_size=1e3, sample=qg.sample.piece10mm, edge_exclusion=500, allow_cell_span=False
3)
4sample.place_multiple_on_sample(
5    devices=ntrons * 9,
6    cell_coordinate_bbox=((0, 0), (8, 8)),
7)
8qp(sample.devices)
../../../_images/sample1.png ../../../_images/sample1_zoom.png

Reference

 1import qnngds as qg
 2from phidl import quickplot as qp
 3from functools import partial
 4import phidl.geometry as pg
 5import numpy as np
 6
 7ls = qg.LayerSet()
 8ls.add_layer(qg.Layer(name="PHOTO", gds_layer=1))
 9cross_sections = dict(
10    photo=partial(qg.geometries.default_cross_section, layer="PHOTO"),
11)
12layer_transitions = qg.layer_auto_transitions(ls)
13PDK = qg.Pdk(
14    "single_layer_pdk",
15    layers=ls,
16    cross_sections=cross_sections,
17    layer_transitions=layer_transitions,
18)
19PDK.activate()
20ntrons = []
21channel_w = 2.0
22pad_array = qg.pads.array_single(
23    pad_specs=(qg.pads.stack(size=(200, 100), layers=("PHOTO",)),),
24    columns=1,
25    rows=3,
26    pitch=300,
27)
28route_groups = (
29    qg.experiment.RouteGroup(qg.get_cross_section("photo"), {"g": 2, "s": 1, "d": 3}),
30)
31ext = partial(pg.optimal_step, end_width=5, symmetric=True, layer=qg.get_layer("PHOTO"))
32for choke_w in np.linspace(0.2, 1.0, 9):
33    label_text = f"wg/wc {round(choke_w, 2)}/{round(channel_w, 2)}"
34    label = pg.text(
35        label_text, size=25, layer=qg.get_layer("PHOTO"), justify="center"
36    ).rotate(-90)
37    ntron = qg.devices.ntron.sharp(
38        choke_w=choke_w,
39        gate_w=2 * channel_w,
40        channel_w=channel_w,
41        drain_w=2 * channel_w,
42        source_w=2 * channel_w,
43        layer="PHOTO",
44    )
45    dut = qg.utilities.extend_ports(
46        device=ntron, port_names=["g", "s", "d"], extension=ext, auto_width=True
47    )
48    ntron_experiment = qg.experiment.generate(
49        dut=dut,
50        pad_array=pad_array,
51        label=label,
52        route_groups=route_groups,
53        dut_offset=(100, 0),
54        pad_offset=(-pad_array.xsize, -300),
55        label_offset=(150, 0),
56        retries=1,
57    )
58    ntron_experiment.rotate(90)
59    ntrons.append(ntron_experiment)
60sample = qg.sample.Sample(
61    cell_size=1e3, sample=qg.sample.piece10mm, edge_exclusion=500, allow_cell_span=False
62)
63sample.place_multiple_on_sample(
64    devices=ntrons * 9,
65    cell_coordinate_bbox=((0, 0), (8, 8)),
66)
67qp(sample.devices)