mirror of https://github.com/KLayout/klayout.git
99 lines
2.8 KiB
Plaintext
99 lines
2.8 KiB
Plaintext
source($lvs_test_source)
|
|
report_lvs($lvs_test_target_lvsdb, true)
|
|
target_netlist($lvs_test_target_cir, write_spice, "Extracted by KLayout")
|
|
|
|
schematic("res_combine_schematic.cir")
|
|
deep
|
|
|
|
# -------------------------------------------------------------------
|
|
# Layers
|
|
|
|
pimp = input(7, 0)
|
|
poly_dg = input(13, 0)
|
|
cont = input(15, 0)
|
|
met1_dg = input(16, 0)
|
|
sblk = input(34, 0)
|
|
rp_1 = sblk & poly_dg
|
|
rpp1 = rp_1 & pimp
|
|
p1trm = poly_dg - rpp1
|
|
|
|
class ResistorExtractor < RBA::GenericDeviceExtractor
|
|
|
|
def initialize(name, sheet_rho)
|
|
self.name = name
|
|
@sheet_rho = sheet_rho
|
|
end
|
|
|
|
def setup
|
|
define_layer("C", "Conductor")
|
|
define_layer("R", "Resistor")
|
|
define_opt_layer("tR", 1, "Resistor")
|
|
register_device_class(RBA::DeviceClassResistor::new)
|
|
end
|
|
|
|
def get_connectivity(layout, layers)
|
|
# this "connectivity" forms the shape clusters that make up the device
|
|
conn = RBA::Connectivity::new
|
|
conn.connect(layers[0], layers[1]) # collect touching contacts
|
|
conn.connect(layers[1], layers[1]) # combine resistor shapes into one area
|
|
conn
|
|
end
|
|
|
|
def extract_devices(layer_geometry)
|
|
# layer_geometry provides the input layers in the order they are defined with "define_layer"
|
|
conductor = layer_geometry[0]
|
|
resistor = layer_geometry[1]
|
|
|
|
resistor_regions = resistor.merged
|
|
|
|
resistor_regions.each do |r|
|
|
terminals = conductor.interacting(resistor)
|
|
if terminals.size != 2
|
|
error("Resistor shape does not touch marker border in exactly two places", r)
|
|
else
|
|
double_width = 0
|
|
(terminals.edges & resistor.edges).merged.each do |e|
|
|
double_width += e.length
|
|
end
|
|
# A = L*W
|
|
# -> L = A/W
|
|
a = r.area*dbu*dbu
|
|
w = (double_width / 2.0)*dbu
|
|
l = a / w
|
|
|
|
device = create_device
|
|
device.set_parameter(RBA::DeviceClassResistor::PARAM_R, @sheet_rho * l / w);
|
|
|
|
device.set_parameter(RBA::DeviceClassResistor::PARAM_A, a)
|
|
device.set_parameter(RBA::DeviceClassResistor::PARAM_L, l)
|
|
device.set_parameter(RBA::DeviceClassResistor::PARAM_P, 2*l+2*w)
|
|
device.set_parameter(RBA::DeviceClassResistor::PARAM_W, w)
|
|
define_terminal(device, RBA::DeviceClassResistor::TERMINAL_A, 0, terminals[0]);
|
|
define_terminal(device, RBA::DeviceClassResistor::TERMINAL_B, 0, terminals[1]);
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
# enable/disable
|
|
enable_parameter("RPP1", "L")
|
|
enable_parameter("RPP1", "W")
|
|
disable_parameter("RPP1", "R")
|
|
|
|
extract_devices(ResistorExtractor::new("RPP1", 0.5), # intentionally wrong: 1565.15/5
|
|
{ "C" => p1trm, "R" => rpp1, "tR" => rpp1 })
|
|
|
|
connect(met1_dg, cont)
|
|
connect(p1trm, cont)
|
|
|
|
netlist.flatten_circuit("Res1")
|
|
schematic.flatten_circuit("RES1")
|
|
|
|
schematic.simplify
|
|
|
|
# Netlist vs. netlist
|
|
align
|
|
netlist.simplify
|
|
no_lvs_hints
|
|
compare
|