Creation of positive-tone ebeam layouts with experiment.generate

Now, we will demonstrate how to generate a layout with experiment.generate for a positive-tone ebeam lithography process using two layers for different beam currents.

Imports are the same as in Basic usage of experiment.generate:

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

When setting up the PDK, we define two layers this time, as well as a new interlayer transition between them using geometries.fine_to_coarse. Note the outline argument being passed to the Layer constructor.

 1ls = qg.LayerSet()
 2ls.add_layer(qg.Layer(name="EBEAM_FINE", gds_layer=1, outline=0.1))
 3ls.add_layer(qg.Layer(name="EBEAM_COARSE", gds_layer=2, outline=10))
 4cross_sections = dict(
 5    ebeam=partial(qg.geometries.default_cross_section, layer="EBEAM_COARSE"),
 6)
 7layer_transitions = {
 8    ("EBEAM_FINE", "EBEAM_COARSE"): partial(
 9        qg.geometries.fine_to_coarse,
10        layer1="EBEAM_FINE",
11        layer2="EBEAM_COARSE",
12    )
13}
14layer_transitions |= qg.layer_auto_transitions(ls)
15PDK = qg.Pdk(
16    "single_layer_postone_ebeam_pdk",
17    layers=ls,
18    cross_sections=cross_sections,
19    layer_transitions=layer_transitions,
20)
21PDK.activate()

The rest of the code is almost the same as in Basic usage of experiment.generate:

 1ntron = qg.devices.ntron.sharp(layer="EBEAM_FINE")
 2ext = partial(
 3    pg.optimal_step, end_width=1, symmetric=True, layer=qg.get_layer("EBEAM_FINE")
 4)
 5dut = qg.utilities.extend_ports(
 6    device=ntron, port_names=["g", "s", "d"], extension=ext, auto_width=True
 7)
 8pad_array = qg.pads.array_single(
 9    pad_specs=(qg.pads.stack(size=(200, 200), layers=("EBEAM_COARSE",)),),
10    columns=1,
11    rows=3,
12    pitch=250,
13)
14route_groups = (
15    qg.experiment.RouteGroup(qg.get_cross_section("ebeam"), {"g": 2, "s": 1, "d": 3}),
16)
17c = qg.experiment.generate(
18    dut=dut,
19    pad_array=pad_array,
20    label=None,
21    route_groups=route_groups,
22    dut_offset=(350, 250),
23    pad_offset=(0, 0),
24    label_offset=(0, 0),
25    retries=1,
26)
27qp(c)
../../../_images/experiment_generate_beginner2.png

Zooming in on the nTron:

../../../_images/experiment_generate_beginner2_zoom.png

Reference

 1import qnngds as qg
 2import phidl.geometry as pg
 3from phidl import quickplot as qp
 4from functools import partial
 5
 6ls = qg.LayerSet()
 7ls.add_layer(qg.Layer(name="EBEAM_FINE", gds_layer=1, outline=0.1))
 8ls.add_layer(qg.Layer(name="EBEAM_COARSE", gds_layer=2, outline=10))
 9cross_sections = dict(
10    ebeam=partial(qg.geometries.default_cross_section, layer="EBEAM_COARSE"),
11)
12layer_transitions = {
13    ("EBEAM_FINE", "EBEAM_COARSE"): partial(
14        qg.geometries.fine_to_coarse,
15        layer1="EBEAM_FINE",
16        layer2="EBEAM_COARSE",
17    )
18}
19layer_transitions |= qg.layer_auto_transitions(ls)
20PDK = qg.Pdk(
21    "single_layer_postone_ebeam_pdk",
22    layers=ls,
23    cross_sections=cross_sections,
24    layer_transitions=layer_transitions,
25)
26PDK.activate()
27ntron = qg.devices.ntron.sharp(layer="EBEAM_FINE")
28ext = partial(
29    pg.optimal_step, end_width=1, symmetric=True, layer=qg.get_layer("EBEAM_FINE")
30)
31dut = qg.utilities.extend_ports(
32    device=ntron, port_names=["g", "s", "d"], extension=ext, auto_width=True
33)
34pad_array = qg.pads.array_single(
35    pad_specs=(qg.pads.stack(size=(200, 200), layers=("EBEAM_COARSE",)),),
36    columns=1,
37    rows=3,
38    pitch=250,
39)
40route_groups = (
41    qg.experiment.RouteGroup(qg.get_cross_section("ebeam"), {"g": 2, "s": 1, "d": 3}),
42)
43c = qg.experiment.generate(
44    dut=dut,
45    pad_array=pad_array,
46    label=None,
47    route_groups=route_groups,
48    dut_offset=(350, 250),
49    pad_offset=(0, 0),
50    label_offset=(0, 0),
51    retries=1,
52)
53qp(c)