mirror of
https://codeberg.org/LibrEDA/libreda-python
synced 2026-06-06 00:39:41 +08:00
123 lines
3.4 KiB
Python
123 lines
3.4 KiB
Python
# SPDX-FileCopyrightText: 2022 Thomas Kramer <code@tkramer.ch>
|
|
#
|
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
import libreda as ldb
|
|
from libreda import geo
|
|
import klayout.db as kdb
|
|
|
|
def convert_geometry_klayout2libreda(geo):
|
|
"""
|
|
TODO: Convert a KLayout geometry into a LibrEDA geometry.
|
|
"""
|
|
pass
|
|
|
|
class Layout:
|
|
"""
|
|
Wrap a KLayout layout structure into the LibrEDA layout interface.
|
|
"""
|
|
|
|
def __init__(self, layout: kdb.Layout):
|
|
assert isinstance(layout, kdb.Layout)
|
|
self.base = layout
|
|
|
|
def cell_by_name(self, name):
|
|
return self.base.cell(name)
|
|
|
|
def cell_name(self, cell: kdb.Cell):
|
|
assert isinstance(cell, kdb.Cell)
|
|
return cell.name
|
|
|
|
def cell_instance_name(self, inst):
|
|
"""
|
|
Klayout cell instances have no names. Always returns None.
|
|
"""
|
|
return None
|
|
|
|
def template_cell(self, inst: kdb.Instance):
|
|
assert isinstance(inst, kdb.Instance)
|
|
return inst.cell
|
|
|
|
def each_cell_vec(self):
|
|
"""
|
|
Get a list of all cells.
|
|
"""
|
|
return list(self.base.each_cell())
|
|
|
|
def each_cell_instance_vec(self, cell: kdb.Cell):
|
|
"""
|
|
Get a list of all child instanes inside cell.
|
|
"""
|
|
assert isinstance(cell, kdb.Cell)
|
|
return list(cell.each_inst())
|
|
|
|
def each_cell_reference_vec(self, cell: kdb.Cell):
|
|
"""
|
|
Get a list of all usages of `cell`.
|
|
"""
|
|
assert isinstance(cell, kdb.Cell)
|
|
# Naive implementation to find all usages of `cell` in the layout.
|
|
return [
|
|
inst for p_id in cell.each_parent_cell()
|
|
for inst in self.base.cell(p_id).each_inst()
|
|
if inst.cell == cell
|
|
]
|
|
|
|
def num_cell_references(self, cell: kdb.Cell):
|
|
"""
|
|
Count how many times `cell` is used.
|
|
"""
|
|
assert isinstance(cell, kdb.Cell)
|
|
return len(self.each_cell_reference_vec(cell))
|
|
#assert False, "Not supported"
|
|
|
|
def num_child_instances(self, cell: kdb.Cell):
|
|
assert isinstance(cell, kdb.Cell)
|
|
return cell.child_instances()
|
|
|
|
def num_dependent_cells(self, cell: kdb.Cell):
|
|
assert isinstance(cell, kdb.Cell)
|
|
return cell.parent_cells()
|
|
|
|
def num_dependent_cells(self, cell: kdb.Cell):
|
|
assert isinstance(cell, kdb.Cell)
|
|
return cell.child_cells()
|
|
|
|
## LayoutBase ##
|
|
|
|
def dbu(self):
|
|
"""
|
|
Database unit.
|
|
"""
|
|
return self.base.dbu()
|
|
|
|
def get_transform(self, inst: kdb.Instance):
|
|
"""
|
|
Get the placement of the instance. The placement is relative to the cell which contains the instance.
|
|
"""
|
|
assert isinstance(inst, kdb.Instance)
|
|
# Convert KLayout Trans into `SimpleTrans` of Libreda.
|
|
k_tf = inst.trans
|
|
|
|
l_tf = geo.SimpleTransform()
|
|
l_tf.mirror = k_tf.is_mirror()
|
|
l_tf.rotation = k_tf.rot
|
|
l_tf.displacement = geo.Point(k_tf.disp.x, k_tf.disp.y)
|
|
|
|
return l_tf
|
|
|
|
# Read a layout into a KLayout data structure.
|
|
layout = kdb.Layout()
|
|
layout.read("../libreda-examples/test/output/example_output.oas")
|
|
|
|
# Wrap the KLayout data structure into the LibrEDA interfae.
|
|
chip = Layout(layout)
|
|
|
|
# Call a simple function provided by the LibrEDA Python library.
|
|
ldb.print_hierarchy(chip)
|
|
|
|
# Test accessing instane locations.
|
|
for cell_id in chip.each_cell_vec():
|
|
for inst_id in chip.each_cell_instance_vec(cell_id):
|
|
tf = chip.get_transform(inst_id)
|