Skip to content

Commit

Permalink
Implement skip_extras option in mask export
Browse files Browse the repository at this point in the history
This commit adds the option -s to mask export. With -s, extra export steps
that are not required for the geometry are skipped, such as netlist generation.
  • Loading branch information
caspar-iqm committed Nov 1, 2023
1 parent bffd523 commit bf33121
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 52 deletions.
1 change: 1 addition & 0 deletions klayout_package/python/console_scripts/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def run():
"print logs to standard output too.")
mask_parser.add_argument('-m', '--mock_chips', action="store_true", help="Replace all chips with empty frames for "
"faster testing of the mask layout")
mask_parser.add_argument('-s', '--skip_extras', action="store_true", help="Skip netlist and documentation export")
mask_parser.add_argument('-c N', action="store_true", help="Limit the number of used CPUs to 'N'")

singularity_parser.add_argument('--build', action="store_true", help='build singularity image locally')
Expand Down
102 changes: 52 additions & 50 deletions klayout_package/python/kqcircuits/masks/mask_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,13 @@


@logged
def export_mask_set(mask_set):
def export_mask_set(mask_set, skip_extras=False):
"""Exports the designs, bitmap and documentation for the mask_set."""

export_bitmaps(mask_set)
export_designs(mask_set)
export_docs(mask_set)
if not skip_extras:
export_docs(mask_set)


@logged
Expand All @@ -55,7 +56,7 @@ def export_designs(mask_set):
export_masks_of_face(mask_set._mask_set_dir, mask_layout, mask_set)


def export_chip(chip_cell, chip_name, chip_dir, layout, export_drc, alt_netlists=None):
def export_chip(chip_cell, chip_name, chip_dir, layout, export_drc, alt_netlists=None, skip_extras=False):
"""Exports a chip used in a maskset."""

is_pcell = chip_cell.pcell_declaration() is not None
Expand All @@ -78,53 +79,54 @@ def export_chip(chip_cell, chip_name, chip_dir, layout, export_drc, alt_netlists
save_opts.write_context_info = False # to save all cells as static cells
static_cell.write(str(chip_dir / f"{chip_name}.oas"), save_opts)

# export netlist
export_cell_netlist(static_cell, chip_dir / f"{chip_name}-netlist.json", chip_cell, alt_netlists)
# calculate flip-chip bump count
bump_count = count_instances_in_cell(chip_cell, FlipChipConnectorDc)
# find layer areas and densities
layer_areas_and_densities = {}
for layer, area, density in zip(*get_area_and_density(static_cell)):
if area != 0.0:
layer_areas_and_densities[layer] = {"area": f"{area:.2f}", "density": f"{density * 100:.2f}"}

# save auxiliary chip data into json-file
chip_json = {
"Chip class module": chip_class.__module__ if is_pcell else None,
"Chip class name": chip_class.__name__ if is_pcell else None,
"Chip parameters": chip_params if is_pcell else None,
"Bump count": bump_count,
"Layer areas and densities": layer_areas_and_densities
}

with open(chip_dir / (chip_name + ".json"), "w") as f:
json.dump(chip_json, f, cls=GeometryJsonEncoder, sort_keys=True, indent=4)

# export .gds files for EBL or laser writer
for cluster_name, layer_cluster in chip_export_layer_clusters.items():
# If the chip has no shapes in the main layers of the layer cluster, should not export the chip with
# that layer cluster.
export_layer_cluster = False
for layer_name in layer_cluster.main_layers:
shapes_iter = static_cell.begin_shapes_rec(layout.layer(default_layers[layer_name]))
if not shapes_iter.at_end():
export_layer_cluster = True
break
if export_layer_cluster:
# To transform the exported layer cluster chip correctly (e.g. mirroring for top chip),
# an instance of the cell is inserted to a temporary cell with the correct transformation.
# Was not able to get this working by just using static_cell.transform_into().
temporary_cell = layout.create_cell(chip_name)
temporary_cell.insert(pya.DCellInstArray(static_cell.cell_index(), default_mask_parameters[
layer_cluster.face_id]["chip_trans"]))
layers_to_export = {name: layout.layer(default_layers[name]) for name in layer_cluster.all_layers()}
path = chip_dir / f"{chip_name}-{cluster_name}.gds"
_export_cell(path, temporary_cell, layers_to_export)
temporary_cell.delete()

# export drc report for the chip
if export_drc:
export_drc_report(chip_name, chip_dir)
if not skip_extras:
# export netlist
export_cell_netlist(static_cell, chip_dir / f"{chip_name}-netlist.json", chip_cell, alt_netlists)
# calculate flip-chip bump count
bump_count = count_instances_in_cell(chip_cell, FlipChipConnectorDc)
# find layer areas and densities
layer_areas_and_densities = {}
for layer, area, density in zip(*get_area_and_density(static_cell)):
if area != 0.0:
layer_areas_and_densities[layer] = {"area": f"{area:.2f}", "density": f"{density * 100:.2f}"}

# save auxiliary chip data into json-file
chip_json = {
"Chip class module": chip_class.__module__ if is_pcell else None,
"Chip class name": chip_class.__name__ if is_pcell else None,
"Chip parameters": chip_params if is_pcell else None,
"Bump count": bump_count,
"Layer areas and densities": layer_areas_and_densities
}

with open(chip_dir / (chip_name + ".json"), "w") as f:
json.dump(chip_json, f, cls=GeometryJsonEncoder, sort_keys=True, indent=4)

# export .gds files for EBL or laser writer
for cluster_name, layer_cluster in chip_export_layer_clusters.items():
# If the chip has no shapes in the main layers of the layer cluster, should not export the chip with
# that layer cluster.
export_layer_cluster = False
for layer_name in layer_cluster.main_layers:
shapes_iter = static_cell.begin_shapes_rec(layout.layer(default_layers[layer_name]))
if not shapes_iter.at_end():
export_layer_cluster = True
break
if export_layer_cluster:
# To transform the exported layer cluster chip correctly (e.g. mirroring for top chip),
# an instance of the cell is inserted to a temporary cell with the correct transformation.
# Was not able to get this working by just using static_cell.transform_into().
temporary_cell = layout.create_cell(chip_name)
temporary_cell.insert(pya.DCellInstArray(static_cell.cell_index(), default_mask_parameters[
layer_cluster.face_id]["chip_trans"]))
layers_to_export = {name: layout.layer(default_layers[name]) for name in layer_cluster.all_layers()}
path = chip_dir / f"{chip_name}-{cluster_name}.gds"
_export_cell(path, temporary_cell, layers_to_export)
temporary_cell.delete()

# export drc report for the chip
if export_drc:
export_drc_report(chip_name, chip_dir)

# delete the static cell which was only needed for export
if static_cell.cell_index() != chip_cell.cell_index():
Expand Down
6 changes: 4 additions & 2 deletions klayout_package/python/kqcircuits/masks/mask_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ def __init__(self, view=None, name="MaskSet", version=1, with_grid=False, export
self._single_process = self._extra_params["enable_debug"] or not is_standalone_session()

self._extra_params["mock_chips"] = '-m' in argv
self._extra_params["skip_extras"] = '-s' in argv

self._cpu_override = 0
if '-c' in argv and len(argv) > argv.index('-c') + 1:
Expand Down Expand Up @@ -213,6 +214,7 @@ def _create_chip(chip_arg):
route_log(filename=chip_path/f"{variant_name}.log", stdout=_extra_params["enable_debug"])

mock_chips = _extra_params['mock_chips']
skip_extras = _extra_params['skip_extras']

view = KLayoutView()
layout = view.layout
Expand Down Expand Up @@ -248,7 +250,7 @@ def _create_chip(chip_arg):
layout.read(chip_class, load_opts)
cell = layout.top_cells()[-1]

export_chip(cell, variant_name, chip_path, layout, export_drc, alt_netlists)
export_chip(cell, variant_name, chip_path, layout, export_drc, alt_netlists, skip_extras)
view.close()

return variant_name, str(chip_path / f"{variant_name}.oas")
Expand Down Expand Up @@ -336,7 +338,7 @@ def export(self):
self._time['EXPORT'] = perf_counter()

print("Exporting mask set...")
export_mask_set(self)
export_mask_set(self, self._extra_params["skip_extras"])

self._time['END'] = perf_counter()

Expand Down

0 comments on commit bf33121

Please sign in to comment.