Adding Instances to a Design
This example adds instances of components to a design and then adds that design as an instance to another design
# Copyright Keysight Technologies 2023 - 2023
import os
from keysight.ads import ael, de
from keysight.ads.de import ArcOrientation, GenPolyline, PointF, db_uu
from keysight.ads.de.experimental import generate_symbol as gs
def create_lpf_circuit_workspace_design_and_simulate() -> None:
# This workspace will reside in the user's home directory under workspaces/Instances_example_wrk
home_dir = os.environ["HOME"]
workspace_path = os.path.join(home_dir, "workspaces/Instances_example_wrk")
# Ensure there is no open workspace
if de.workspace_is_open():
de.close_workspace()
# Create the workspace
de.create_workspace(workspace_path)
workspace = de.open_workspace(workspace_path)
# Create the library
de.create_new_library("LPF_lib", os.path.join(workspace_path, "LPF_lib"))
# And add it to the workspace
workspace.add_library("LPF_lib", os.path.join(workspace_path, "LPF_lib"), de.LibraryMode.SHARED)
# Create an empty schematic
schematic_lpf = db_uu.create_schematic("LPF_lib:LPF:schematic")
assert schematic_lpf is not None
# And write out the design
# By creating and committing a transaction, we force a connectivitiy check on the design
transaction = de.db.Transaction(schematic_lpf, "Create schematic")
create_an_ideal_lpf_circuit(schematic_lpf)
transaction.commit()
schematic_lpf.save_design()
# Generate a symbol for the design
symbol_lpf = create_symbol_for_ideal_lpf_circuit(schematic_lpf)
# Create a new design in a new cell
schematic_sp = db_uu.create_schematic("LPF_lib:LPF_SP:schematic")
assert schematic_sp is not None
# Designs may be referenced in multiple ways, such as with a CellviewRef
cvr = de.CellviewRef(view=symbol_lpf.view)
assert cvr is not None
# Write out the new design
transaction = de.db.Transaction(schematic_sp, "Create schematic")
add_subcircuit_to_design_and_create_lpf_circuit(schematic_sp, cvr)
transaction.commit()
schematic_sp.save_design()
# qthelp://ads.2024/doc/appguide/Designing_a_Simple_Low_Pass_Filter.html
# TODO: Specify hierarchy policy
# TODO: Perform schematic simulation
# TODO: Add Parameters Sweep/Values
# TODO: Simulate
def create_an_ideal_lpf_circuit(design: db_uu.Design) -> None:
# ensure the design is empty
design.clear_design()
# ads_device:drawing for schematic, cond for layout
layer_id = db_uu.LayerId(231 if design.is_schematic is True else 1)
# Add an input pin to the design
net = design.find_or_add_net("P1")
term = design.add_term(net, "P1", db_uu.TermType.INPUT)
dot = design.add_dot(layer_id, (0.0, 0.0))
# Pin angle may be passed into the constructor, or
pin = design.add_pin(term, dot, angle=0.0)
# The pin angle may be modified after being placed
pin.angle = 180.0
# And when setting the pin angle this way, update the annotation position, if desired
pin.update_pin_annotation(False)
assert pin.term.name == "P1"
# Add an output pin to the design
net = design.find_or_add_net("P2")
term = design.add_term(net, "P2", db_uu.TermType.OUTPUT)
dot = design.add_dot(layer_id, (5.0, 0.0))
pin = design.add_pin(term, dot)
assert pin.term.name == "P2"
# Add a couple instances of an inductor to the design
# An instance may be referred by using the Library, Cell, and View name directly
inductor = design.add_instance(de.LCVName("ads_rflib", "L", "symbol"), (0.750, 0.0), name="L1", angle=0.0)
assert inductor is not None and inductor.name == "L1"
# Or an instance may be referred by using a CellviewRef
cell_view_ref = de.CellviewRef("ads_rflib", "L", "symbol")
inductor = design.add_instance(cell_view_ref, (3.250, 0.0), name="L2", angle=0.0)
assert inductor is not None and inductor.name == "L2"
# Add a capacitor to the design at a -90 degree angle
capacitor = design.add_instance(de.LCVName("ads_rflib", "C", "symbol"), (2.50, -1.25), name="C1", angle=-90.0)
assert capacitor is not None and capacitor.name == "C1"
# Add a ground to the design at a -90 degree angle
ground = design.add_instance(de.LCVName("ads_rflib", "GROUND", "symbol"), (2.50, -2.25), name="GND", angle=-90.0)
assert ground is not None and ground.name == "GND"
# Wire them up
# P1 to L1
design.add_wire([(0.0, 0.0), (0.750, 0.0)])
# L1 to L2
design.add_wire([(1.750, 0.0), (3.250, 0.0)])
# L2 to P2
design.add_wire([(4.250, 0.0), (5.0, 0.0)])
# C1 to L1 and L2
design.add_wire([(2.50, 0.0), (2.50, -1.250)])
def create_symbol_for_ideal_lpf_circuit(schematic_lpf: db_uu.Design) -> db_uu.Design:
symbol_lpf = db_uu.create_symbol("LPF_lib:LPF:symbol")
# Create the symbol in LPF using SymbolGenerator
symbol_generator = gs.SymbolGenerator(symbol_lpf, schematic_lpf, 0.25, 0.25)
symbol_generator.is_dual_symbol_type = True
symbol_generator.should_replace = True
symbol_generator.pin_shape = "square"
symbol_generator.generate_symbol()
points_l = [(0.3, 0.2), (0.5, 0)]
polyline_l = GenPolyline(points_l)
polyline_l.set_segment_as_arc(0, PointF(0.375, 0), ArcOrientation.CLOCKWISE)
symbol_layer_id = ael.call.db_get_layerid_for_symbol_body(symbol_lpf)
symbol_lpf.add_line(symbol_layer_id, polyline_l.outline)
points_r = [(0.7, -0.2), (0.5, 0)]
polyline_r = GenPolyline(points_r)
polyline_r.set_segment_as_arc(0, PointF(0.625, 0), ArcOrientation.CLOCKWISE)
symbol_lpf.add_line(symbol_layer_id, polyline_r.outline)
symbol_lpf.add_text(symbol_layer_id, "Input", (0.3, 0.125), "Ariel for CAE", 0.069, db_uu.TextAlignment.LOWER_LEFT)
symbol_lpf.add_text(
symbol_layer_id, "Output", (0.7, -0.125), "Ariel for CAE", 0.069, db_uu.TextAlignment.UPPER_RIGHT
)
symbol_lpf.save_design()
return symbol_lpf
def add_subcircuit_to_design_and_create_lpf_circuit(design: db_uu.Design, sub_circuit: de.CellviewRef) -> None:
# Add an instance of sub_circuit to design
design.add_instance(sub_circuit, (2.50, 0.0))
# Add some terms
design.add_instance(de.LCVName("ads_simulation", "Term", "symbol"), (0.0, 0.0), name="Term1", angle=-90.0)
design.add_instance(de.LCVName("ads_simulation", "Term", "symbol"), (6.0, 0.0), name="Term2", angle=-90.0)
# Add some ground
design.add_instance(de.LCVName("ads_rflib", "GROUND", "symbol"), (0.0, -1.0), name="GND1", angle=-90.0)
design.add_instance(de.LCVName("ads_rflib", "GROUND", "symbol"), (6.0, -1.0), name="GND2", angle=-90.0)
# Add an S-Param
design.add_instance(de.LCVName("ads_simulation", "S_Param", "symbol"), (0.0, -3.0), name="S_Param", angle=0.0)
# Wire up the terms to the sub_circuit
design.add_wire([(0.0, 0.0), (2.50, 0.0)])
design.add_wire([(3.50, 0.0), (6.0, 0.0)])