Some enhancements

* Device#net_for_terminal with terminal name
* Spice writer now dumps all parameters for resistors and caps (also secondary)
* Enabled Spice writer delegate in LVS (spice_format(...))
* Device class factories for built-in device extractors
This commit is contained in:
Matthias Koefferlein
2021-07-05 22:22:13 +02:00
parent ba35ac9bfe
commit e34fc8967a
18 changed files with 665 additions and 25 deletions
+11
View File
@@ -0,0 +1,11 @@
* Extracted by KLayout
* cell Rre
* pin gnd!
* pin vdd!
.SUBCKT Rre 1 2
* net 1 gnd!
* net 2 vdd!
* device instance $1 r0 *1 8.43,1.51 RR1
R$1 1 2 RR1 10 W=0.6 L=6
.ENDS Rre
+52
View File
@@ -0,0 +1,52 @@
# test spice writer delegate on this occasion
class MyWriterDelegate < RBA::NetlistSpiceWriterDelegate
def write_device(device)
if device.device_class.name == "RR1"
line = "R"
line += format_name(device.expanded_name)
line += " "
line += net_to_string(device.net_for_terminal("A"))
line += " "
line += net_to_string(device.net_for_terminal("B"))
line += " "
line += format_name(device.device_class.name)
line += " "
line += "%.12g" % device.parameter("R")
line += " W="
line += "%.12g" % device.parameter("W")
line += " L="
line += "%.12g" % device.parameter("L")
emit_line(line)
else
super
end
end
end
source($lvs_test_source)
report_lvs($lvs_test_target_lvsdb, true)
target_netlist($lvs_test_target_cir, write_spice(MyWriterDelegate::new), "Extracted by KLayout")
schematic("resistor.cir")
deep
contact = input(15, 0)
metal1 = input(16, 0)
metal1_ver = input(16, 5)
metal1_lbl = labels(16, 3)
res = metal1 & metal1_ver
metal1_not_res = metal1 - metal1_ver
dc = extract_devices(resistor("RR1", 1), { "R" => res , "C" => metal1_not_res})
dc.enable_parameter("W", true)
dc.enable_parameter("L", true)
connect(contact, metal1_not_res)
connect(metal1_not_res, metal1_lbl)
align
netlist.simplify
compare
+118
View File
@@ -0,0 +1,118 @@
#%lvsdb-klayout
# Layout
layout(
top(Rre)
unit(0.001)
# Layer section
# This section lists the mask layers (drawing or derived) and their connections.
# Mask layers
layer(l3 '15/0')
layer(l4 '16/3')
layer(l1)
# Mask layer connectivity
connect(l3 l3 l1)
connect(l4 l1)
connect(l1 l3 l4 l1)
# Device class section
class(RR1 RES
param(L 1 0)
param(W 1 0)
)
# Device abstracts section
# Device abstracts list the pin shapes of the devices.
device(D$RR1 RR1
terminal(A
rect(l1 (-3160 -300) (160 600))
)
terminal(B
rect(l1 (3000 -300) (160 600))
)
)
# Circuit section
# Circuits are the hierarchical building blocks of the netlist.
circuit(Rre
# Circuit boundary
rect((5270 1210) (6320 600))
# Nets with their geometries
net(1 name('gnd!')
rect(l3 (5295 1230) (120 560))
text(l4 'gnd!' (-60 -60))
rect(l1 (-70 -505) (125 570))
rect(l1 (-140 -585) (160 600))
)
net(2 name('vdd!')
rect(l3 (11455 1240) (120 540))
text(l4 'vdd!' (-65 -60))
rect(l1 (-65 -495) (125 560))
rect(l1 (-140 -575) (160 600))
)
# Outgoing pins and their connections to nets
pin(1 name('gnd!'))
pin(2 name('vdd!'))
# Devices and their connections
device(1 D$RR1
location(8430 1510)
param(R 10)
param(L 6)
param(W 0.6)
param(A 3.6)
param(P 13.2)
terminal(A 1)
terminal(B 2)
)
)
)
# Reference netlist
reference(
# Device class section
class(RR1 RES)
# Circuit section
# Circuits are the hierarchical building blocks of the netlist.
circuit(RRE
# Nets
net(1 name('VDD!'))
net(2 name('GND!'))
# Devices and their connections
device(1 RR1
name(R0)
param(R 10)
param(L 6)
param(W 0.6)
param(A 0)
param(P 0)
terminal(A 1)
terminal(B 2)
)
)
)
# Cross reference
xref(
circuit(Rre RRE match
xref(
net(1 2 match)
net(2 1 match)
pin(0 () match)
pin(1 () match)
device(1 1 match)
)
)
)
+11
View File
@@ -0,0 +1,11 @@
* Extracted by KLayout
* cell Rre
* pin gnd!
* pin vdd!
.SUBCKT Rre 1 2
* net 1 gnd!
* net 2 vdd!
* device instance $1 r0 *1 8.43,1.51 RR1
R$1 1 2 10 RR1 L=6U W=0.6U A=3.6P P=13.2U
.ENDS Rre
+33
View File
@@ -0,0 +1,33 @@
source($lvs_test_source)
report_lvs($lvs_test_target_lvsdb, true)
target_netlist($lvs_test_target_cir, write_spice, "Extracted by KLayout")
schematic("resistor.cir")
deep
contact = input(15, 0)
metal1 = input(16, 0)
metal1_ver = input(16, 5)
metal1_lbl = labels(16, 3)
res = metal1 & metal1_ver
metal1_not_res = metal1 - metal1_ver
class MyResistorClass < RBA::DeviceClassResistor
def initialize
super
enable_parameter("W", true)
enable_parameter("L", true)
end
end
extract_devices(resistor("RR1", 1, MyResistorClass), { "R" => res , "C" => metal1_not_res})
connect(contact, metal1_not_res)
connect(metal1_not_res, metal1_lbl)
align
netlist.simplify
compare
+118
View File
@@ -0,0 +1,118 @@
#%lvsdb-klayout
# Layout
layout(
top(Rre)
unit(0.001)
# Layer section
# This section lists the mask layers (drawing or derived) and their connections.
# Mask layers
layer(l3 '15/0')
layer(l4 '16/3')
layer(l1)
# Mask layer connectivity
connect(l3 l3 l1)
connect(l4 l1)
connect(l1 l3 l4 l1)
# Device class section
class(RR1 RES
param(L 1 0)
param(W 1 0)
)
# Device abstracts section
# Device abstracts list the pin shapes of the devices.
device(D$RR1 RR1
terminal(A
rect(l1 (-3160 -300) (160 600))
)
terminal(B
rect(l1 (3000 -300) (160 600))
)
)
# Circuit section
# Circuits are the hierarchical building blocks of the netlist.
circuit(Rre
# Circuit boundary
rect((5270 1210) (6320 600))
# Nets with their geometries
net(1 name('gnd!')
rect(l3 (5295 1230) (120 560))
text(l4 'gnd!' (-60 -60))
rect(l1 (-70 -505) (125 570))
rect(l1 (-140 -585) (160 600))
)
net(2 name('vdd!')
rect(l3 (11455 1240) (120 540))
text(l4 'vdd!' (-65 -60))
rect(l1 (-65 -495) (125 560))
rect(l1 (-140 -575) (160 600))
)
# Outgoing pins and their connections to nets
pin(1 name('gnd!'))
pin(2 name('vdd!'))
# Devices and their connections
device(1 D$RR1
location(8430 1510)
param(R 10)
param(L 6)
param(W 0.6)
param(A 3.6)
param(P 13.2)
terminal(A 1)
terminal(B 2)
)
)
)
# Reference netlist
reference(
# Device class section
class(RR1 RES)
# Circuit section
# Circuits are the hierarchical building blocks of the netlist.
circuit(RRE
# Nets
net(1 name('VDD!'))
net(2 name('GND!'))
# Devices and their connections
device(1 RR1
name(R0)
param(R 10)
param(L 6)
param(W 0.6)
param(A 0)
param(P 0)
terminal(A 1)
terminal(B 2)
)
)
)
# Cross reference
xref(
circuit(Rre RRE match
xref(
net(1 2 match)
net(2 1 match)
pin(0 () match)
pin(1 () match)
device(1 1 match)
)
)
)
+11
View File
@@ -0,0 +1,11 @@
* Extracted by KLayout
* cell Rre
* pin gnd!
* pin vdd!
.SUBCKT Rre 1 2
* net 1 gnd!
* net 2 vdd!
* device instance $1 r0 *1 8.43,1.51 RR1
R$1 1 2 10 RR1 L=6U W=0.6U A=3.6P P=13.2U
.ENDS Rre
+33
View File
@@ -0,0 +1,33 @@
source($lvs_test_source)
report_lvs($lvs_test_target_lvsdb, true)
target_netlist($lvs_test_target_cir, write_spice, "Extracted by KLayout")
schematic("resistor2.cir")
deep
contact = input(15, 0)
metal1 = input(16, 0)
metal1_ver = input(16, 5)
metal1_lbl = labels(16, 3)
res = metal1 & metal1_ver
metal1_not_res = metal1 - metal1_ver
class MyResistorClass < RBA::DeviceClassResistor
def initialize
super
enable_parameter("W", true)
enable_parameter("L", true)
end
end
extract_devices(resistor("RR1", 1, MyResistorClass), { "R" => res , "C" => metal1_not_res})
connect(contact, metal1_not_res)
connect(metal1_not_res, metal1_lbl)
align
netlist.simplify
compare
+121
View File
@@ -0,0 +1,121 @@
#%lvsdb-klayout
# Layout
layout(
top(Rre)
unit(0.001)
# Layer section
# This section lists the mask layers (drawing or derived) and their connections.
# Mask layers
layer(l3 '15/0')
layer(l4 '16/3')
layer(l1)
# Mask layer connectivity
connect(l3 l3 l1)
connect(l4 l1)
connect(l1 l3 l4 l1)
# Device class section
class(RR1 RES
param(L 1 0)
param(W 1 0)
)
# Device abstracts section
# Device abstracts list the pin shapes of the devices.
device(D$RR1 RR1
terminal(A
rect(l1 (-3160 -300) (160 600))
)
terminal(B
rect(l1 (3000 -300) (160 600))
)
)
# Circuit section
# Circuits are the hierarchical building blocks of the netlist.
circuit(Rre
# Circuit boundary
rect((5270 1210) (6320 600))
# Nets with their geometries
net(1 name('gnd!')
rect(l3 (5295 1230) (120 560))
text(l4 'gnd!' (-60 -60))
rect(l1 (-70 -505) (125 570))
rect(l1 (-140 -585) (160 600))
)
net(2 name('vdd!')
rect(l3 (11455 1240) (120 540))
text(l4 'vdd!' (-65 -60))
rect(l1 (-65 -495) (125 560))
rect(l1 (-140 -575) (160 600))
)
# Outgoing pins and their connections to nets
pin(1 name('gnd!'))
pin(2 name('vdd!'))
# Devices and their connections
device(1 D$RR1
location(8430 1510)
param(R 10)
param(L 6)
param(W 0.6)
param(A 3.6)
param(P 13.2)
terminal(A 1)
terminal(B 2)
)
)
)
# Reference netlist
reference(
# Device class section
class(RR1 RES)
# Circuit section
# Circuits are the hierarchical building blocks of the netlist.
circuit(RRE
# Nets
net(1 name('VDD!'))
net(2 name('GND!'))
# Devices and their connections
device(1 RR1
name(R0)
param(R 10)
param(L 7)
param(W 0.6)
param(A 0)
param(P 0)
terminal(A 1)
terminal(B 2)
)
)
)
# Cross reference
xref(
circuit(Rre RRE nomatch
xref(
net(() 2 mismatch)
net(() 1 mismatch)
net(1 () mismatch)
net(2 () mismatch)
pin(0 () match)
pin(1 () match)
device(() 1 mismatch)
device(1 () mismatch)
)
)
)
+4
View File
@@ -0,0 +1,4 @@
.SUBCKT Rre
RR0 vdd! gnd! 10 RR1 W=600n L=6u M=1
.ENDS
BIN
View File
Binary file not shown.
+4
View File
@@ -0,0 +1,4 @@
.SUBCKT Rre
RR0 vdd! gnd! 10 RR1 W=600n L=7u M=1
.ENDS
+2
View File
@@ -331,6 +331,8 @@ class DBNetlist_TestClass < TestBase
assert_equal(net.terminal_count, 1)
assert_equal(d1.net_for_terminal(1).name, "NET")
assert_equal(d1.net_for_terminal("B").name, "NET")
assert_equal(d1.net_for_terminal("X").inspect, "nil")
assert_equal(d1.net_for_terminal(0).inspect, "nil")
d1.disconnect_terminal("B")