mirror of
https://github.com/KLayout/klayout.git
synced 2026-09-07 03:21:34 +02:00
* WIP: some refactoring * WIP: some refactoring * Netlist compare: introducing ambiguity resolution by net names By default now net names are used for resolving ambiguities. If net names match, they will be used to associate nets if the choice is ambiguous. This is usually much faster and more reliable than trying to resolve ambiguities through topology analysis. This feature can be disabled using "consider_net_names(false)" in the LVS script. * Some refactoring, Jenkinsfile modified for better test coverage
133 lines
3.0 KiB
Plaintext
133 lines
3.0 KiB
Plaintext
|
|
source($lvs_test_source)
|
|
|
|
report_lvs($lvs_test_target_lvsdb)
|
|
|
|
writer = write_spice(true, false)
|
|
target_netlist($lvs_test_target_cir, writer, "Extracted by KLayout")
|
|
|
|
# needs this delegate because we use MOS3 which is not available in Spice
|
|
class SpiceReaderDelegate < RBA::NetlistSpiceReaderDelegate
|
|
|
|
# says we want to catch these subcircuits as devices
|
|
def wants_subcircuit(name)
|
|
name == "HVNMOS" || name == "HVPMOS"
|
|
end
|
|
|
|
# translate the element
|
|
def element(circuit, el, name, model, value, nets, params)
|
|
|
|
if el != "M"
|
|
# all other elements are left to the standard implementation
|
|
return super
|
|
end
|
|
|
|
if nets.size != 4
|
|
error("Device #{model} needs four nodes")
|
|
end
|
|
|
|
# provide a device class
|
|
cls = circuit.netlist.device_class_by_name(model)
|
|
if ! cls
|
|
cls = RBA::DeviceClassMOS3Transistor::new
|
|
cls.name = model
|
|
circuit.netlist.add(cls)
|
|
end
|
|
|
|
# create a device
|
|
device = circuit.create_device(cls, name)
|
|
|
|
# and configure the device
|
|
[ "S", "G", "D" ].each_with_index do |t,index|
|
|
device.connect_terminal(t, nets[index])
|
|
end
|
|
device.set_parameter("W", params["W"] * 1e6)
|
|
device.set_parameter("L", params["L"] * 1e6)
|
|
|
|
device
|
|
|
|
end
|
|
|
|
end
|
|
|
|
reader = RBA::NetlistSpiceReader::new(SpiceReaderDelegate::new)
|
|
schematic("invchain_for_cheat.cir", reader)
|
|
|
|
deep
|
|
|
|
# Drawing layers
|
|
|
|
nwell = input(1, 0)
|
|
active = input(2, 0)
|
|
poly = input(3, 0)
|
|
poly_lbl = input(3, 1)
|
|
diff_cont = input(4, 0)
|
|
poly_cont = input(5, 0)
|
|
metal1 = input(6, 0)
|
|
metal1_lbl = input(6, 1)
|
|
via1 = input(7, 0)
|
|
metal2 = input(8, 0)
|
|
metal2_lbl = input(8, 1)
|
|
|
|
# Bulk layer for terminal provisioning
|
|
|
|
bulk = polygon_layer
|
|
|
|
psd = nil
|
|
nsd = nil
|
|
|
|
cheat("INV") do
|
|
|
|
# Computed layers
|
|
|
|
active_in_nwell = active & nwell
|
|
pactive = active_in_nwell
|
|
pgate = pactive & poly
|
|
psd = pactive - pgate
|
|
|
|
active_outside_nwell = active - nwell
|
|
nactive = active_outside_nwell
|
|
ngate = nactive & poly
|
|
nsd = nactive - ngate
|
|
|
|
# Device extraction
|
|
|
|
# PMOS transistor device extraction
|
|
extract_devices(mos3("PMOS"), { "SD" => psd, "G" => pgate,
|
|
"tS" => psd, "tD" => psd, "tG" => poly })
|
|
|
|
# NMOS transistor device extraction
|
|
extract_devices(mos3("NMOS"), { "SD" => nsd, "G" => ngate,
|
|
"tS" => nsd, "tD" => nsd, "tG" => poly })
|
|
|
|
end
|
|
|
|
# Define connectivity for netlist extraction
|
|
|
|
# Inter-layer
|
|
connect(psd, diff_cont)
|
|
connect(nsd, diff_cont)
|
|
connect(poly, poly_cont)
|
|
connect(diff_cont, metal1)
|
|
connect(poly_cont, metal1)
|
|
connect(metal1, via1)
|
|
connect(via1, metal2)
|
|
|
|
# attach labels
|
|
connect(poly, poly_lbl)
|
|
connect(metal1, metal1_lbl)
|
|
connect(metal2, metal2_lbl)
|
|
|
|
# Global
|
|
connect_global(bulk, "SUBSTRATE")
|
|
|
|
# Compare section
|
|
|
|
netlist.simplify
|
|
align
|
|
|
|
consider_net_names(false)
|
|
|
|
compare
|
|
|