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)
Zooming in on the nTron:
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)