WIP: one more test for LVS

This commit is contained in:
Matthias Koefferlein 2019-07-06 09:08:32 +02:00
parent 2f6aae7204
commit 0595ec2e0f
3 changed files with 351 additions and 27 deletions

View File

@ -124,39 +124,106 @@ TEST(1)
compare_text_files (output_lvsdb, au_lvsdb);
}
#if 0
TEST(2)
{
std::string input = tl::testsrc ();
input += "/testdata/lvs/inv2.oas";
std::string schematic = "inv2.cir"; // relative to inv2.oas
std::string au_cir = tl::testsrc ();
au_cir += "/testdata/lvs/inv2_layout.cir";
std::string au_lvsdb = tl::testsrc ();
au_lvsdb += "/testdata/lvs/inv2.lvsdb";
std::string output_cir = this->tmp_file ("tmp.cir");
std::string output_lvsdb = this->tmp_file ("tmp.lvsdb");
lym::Macro lvs;
lvs.set_text (
"dbu 0.001\n"
"def compare(a, b, ex)\n"
" a = a.to_s\n"
" b = b.to_s\n"
" if a != b\n"
" raise(ex + \" (actual=#{a}, ref=#{b})\")\n"
" end\n"
"end\n"
"compare(0.1.um, 0.1, \"unexpected value when converting um\")\n"
"compare(0.1.micron, 0.1, \"unexpected value when converting micron\")\n"
"compare(0.1.um2, 0.1, \"unexpected value when converting um2\")\n"
"compare(0.1.mm2, 100000.0, \"unexpected value when converting mm2\")\n"
"compare(120.dbu, 0.12, \"unexpected value when converting dbu\")\n"
"compare((0.1.um + 120.dbu), 0.22, \"unexpected value when adding values\")\n"
"compare(0.1.mm, 100.0, \"unexpected value when converting mm\")\n"
"compare(1e-6.m, 1.0, \"unexpected value when converting m\")\n"
"compare(1.um, 1.0, \"unexpected value when converting integer um\")\n"
"compare(1.micron, 1.0, \"unexpected value when convering integer micron\")\n"
"compare(1.um2, 1.0, \"unexpected value when converting integer um2\")\n"
"compare(1.mm2, 1000000.0, \"unexpected value when converting integer mm2\")\n"
"compare((1.um + 120.dbu), 1.12, \"unexpected value when adding integer values\")\n"
"compare(1.mm, 1000.0, \"unexpected value when converting integer mm\")\n"
"compare(1.m, 1000000.0, \"unexpected value when converting integer m\")\n"
lvs.set_text (tl::sprintf (
"source('%s', 'INVERTER_WITH_DIODES')\n"
"\n"
"deep\n"
"\n"
"# Reports generated\n"
"\n"
"# LVS report to inv.lvsdb\n"
"report_lvs('%s')\n"
"\n"
"# Write extracted netlist to inv_extracted.cir\n"
"target_netlist('%s', write_spice, 'Extracted by KLayout')\n"
"\n"
"# Drawing layers\n"
"\n"
"nwell = input(1, 0)\n"
"active = input(2, 0)\n"
"pplus = input(3, 0)\n"
"nplus = input(4, 0)\n"
"poly = input(5, 0)\n"
"contact = input(6, 0)\n"
"metal1 = input(7, 0)\n"
"metal1_lbl = labels(7, 1)\n"
"via1 = input(8, 0)\n"
"metal2 = input(9, 0)\n"
"metal2_lbl = labels(9, 1)\n"
"\n"
"# Bulk layer for terminal provisioning\n"
"\n"
"bulk = polygon_layer\n"
"\n"
"# Computed layers\n"
"\n"
"active_in_nwell = active & nwell\n"
"pactive = active_in_nwell & pplus\n"
"pgate = pactive & poly\n"
"psd = pactive - pgate\n"
"ntie = active_in_nwell & nplus\n"
"\n"
"active_outside_nwell = active - nwell\n"
"nactive = active_outside_nwell & nplus\n"
"ngate = nactive & poly\n"
"nsd = nactive - ngate\n"
"ptie = active_outside_nwell & pplus\n"
"\n"
"# Device extraction\n"
"\n"
"# PMOS transistor device extraction\n"
"extract_devices(mos4('PMOS'), { 'SD' => psd, 'G' => pgate, 'W' => nwell, \n"
" 'tS' => psd, 'tD' => psd, 'tG' => poly, 'tW' => nwell })\n"
"\n"
"# NMOS transistor device extraction\n"
"extract_devices(mos4('NMOS'), { 'SD' => nsd, 'G' => ngate, 'W' => bulk, \n"
" 'tS' => nsd, 'tD' => nsd, 'tG' => poly, 'tW' => bulk })\n"
"\n"
"# Define connectivity for netlist extraction\n"
"\n"
"# Inter-layer\n"
"connect(psd, contact)\n"
"connect(nsd, contact)\n"
"connect(poly, contact)\n"
"connect(ntie, contact)\n"
"connect(nwell, ntie)\n"
"connect(ptie, contact)\n"
"connect(contact, metal1)\n"
"connect(metal1, metal1_lbl) # attaches labels\n"
"connect(metal1, via1)\n"
"connect(via1, metal2)\n"
"connect(metal2, metal2_lbl) # attaches labels\n"
"\n"
"# Global\n"
"connect_global(bulk, 'SUBSTRATE')\n"
"connect_global(ptie, 'SUBSTRATE')\n"
"\n"
"# Compare section\n"
"\n"
"schematic('%s')\n"
"\n"
"compare\n"
, input, output_lvsdb, output_cir, schematic)
);
lvs.set_interpreter (lym::Macro::DSLInterpreter);
lvs.set_dsl_interpreter ("lvs-dsl");
EXPECT_EQ (lvs.run (), 0);
}
#endif
compare_text_files (output_cir, au_cir);
compare_text_files (output_lvsdb, au_lvsdb);
}

244
testdata/lvs/inv2.lvsdb vendored Normal file
View File

@ -0,0 +1,244 @@
#%lvsdb-klayout
# Layout
layout(
top(INVERTER_WITH_DIODES)
unit(0.001)
# Layer section
# This section lists the mask layers (drawing or derived) and their connections.
# Mask layers
layer(l103 'NWELL (1/0)')
layer(l108 'POLY (5/0)')
layer(l109 'CONTACT (6/0)')
layer(l110 'METAL1 (7/0)')
layer(l111 'METAL1_LABEL (7/1)')
layer(l112 'VIA1 (8/0)')
layer(l113 'METAL2 (9/0)')
layer(l114 'METAL2_LABEL (9/1)')
layer(l115)
layer(l123)
layer(l125)
layer(l133)
layer(l135)
# Mask layer connectivity
connect(l103 l103 l125)
connect(l108 l108 l109)
connect(l109 l108 l109 l110 l123 l125 l133 l135)
connect(l110 l109 l110 l111 l112)
connect(l111 l110 l111)
connect(l112 l110 l112 l113)
connect(l113 l112 l113 l114)
connect(l114 l113 l114)
connect(l115 l115)
connect(l123 l109 l123)
connect(l125 l103 l109 l125)
connect(l133 l109 l133)
connect(l135 l109 l135)
# Global nets and connectivity
global(l115 SUBSTRATE)
global(l135 SUBSTRATE)
# Device class section
class(PMOS MOS4)
class(NMOS MOS4)
# Device abstracts section
# Device abstracts list the pin shapes of the devices.
device(D$PMOS PMOS
terminal(S
rect(l123 (-575 -750) (450 1500))
)
terminal(G
rect(l108 (-125 -750) (250 1500))
)
terminal(D
rect(l123 (125 -750) (450 1500))
)
terminal(B
rect(l103 (-125 -750) (250 1500))
)
)
device(D$NMOS NMOS
terminal(S
rect(l133 (-575 -450) (450 900))
)
terminal(G
rect(l108 (-125 -450) (250 900))
)
terminal(D
rect(l133 (125 -450) (450 900))
)
terminal(B
rect(l115 (-125 -450) (250 900))
)
)
# Circuit section
# Circuits are the hierarchical building blocks of the netlist.
circuit(INVERTER_WITH_DIODES
# Nets with their geometries
net(1 name(IN)
rect(l108 (900 50) (250 1050))
rect(l108 (-250 0) (250 3100))
rect(l108 (-250 0) (250 1650))
rect(l108 (-800 -3100) (550 400))
rect(l109 (-450 -300) (200 200))
rect(l110 (-300 -300) (400 400))
rect(l111 (-201 -201) (2 2))
)
net(2 name(VDD)
rect(l103 (0 2950) (3000 3200))
rect(l109 (-2450 -1800) (200 200))
rect(l109 (-200 300) (200 200))
rect(l109 (-200 300) (200 200))
rect(l109 (1400 -800) (200 200))
rect(l109 (-200 300) (200 200))
rect(l110 (-1850 -1200) (300 1600))
rect(l110 (1300 -1200) (300 1200))
rect(l112 (-1850 -800) (200 200))
rect(l112 (-200 300) (200 200))
rect(l112 (1400 -700) (200 200))
rect(l112 (-200 300) (200 200))
rect(l113 (-2350 -850) (3000 1000))
rect(l114 (-151 -851) (2 2))
rect(l123 (-2401 -851) (450 1500))
rect(l125 (1050 -1200) (600 1200))
)
net(3 name(OUT)
rect(l109 (1300 4350) (200 200))
rect(l109 (-200 300) (200 200))
rect(l109 (-200 300) (200 200))
rect(l109 (-200 -5250) (200 200))
rect(l109 (-200 300) (200 200))
rect(l110 (-250 3250) (300 1400))
rect(l110 (-300 -4600) (300 3200))
rect(l110 (-300 -2900) (450 400))
rect(l110 (-450 -1550) (300 850))
rect(l111 (-51 499) (2 2))
rect(l123 (-351 2649) (450 1500))
rect(l133 (-450 -5500) (450 900))
)
net(4 name(VSS)
rect(l109 (550 300) (200 200))
rect(l109 (-200 300) (200 200))
rect(l109 (1400 -550) (200 200))
rect(l109 (-200 300) (200 200))
rect(l110 (-1850 -1100) (300 1050))
rect(l110 (1300 -1050) (300 1200))
rect(l112 (-1850 -1100) (200 200))
rect(l112 (-200 300) (200 200))
rect(l112 (1400 -700) (200 200))
rect(l112 (-200 300) (200 200))
rect(l113 (-2350 -850) (3000 1000))
rect(l114 (-151 -851) (2 2))
rect(l133 (-2401 49) (450 900))
rect(l135 (1050 -900) (600 1200))
)
# Devices and their connections
device(1 D$PMOS
location(1025 4950)
param(L 0.25)
param(W 1.5)
param(AS 0.675)
param(AD 0.675)
param(PS 3.9)
param(PD 3.9)
terminal(S 2)
terminal(G 1)
terminal(D 3)
terminal(B 2)
)
device(2 D$NMOS
location(1025 650)
param(L 0.25)
param(W 0.9)
param(AS 0.405)
param(AD 0.405)
param(PS 2.7)
param(PD 2.7)
terminal(S 4)
terminal(G 1)
terminal(D 3)
terminal(B 4)
)
)
)
# Reference netlist
reference(
# Device class section
class(PMOS MOS4)
class(NMOS MOS4)
# Circuit section
# Circuits are the hierarchical building blocks of the netlist.
circuit(INVERTER_WITH_DIODES
# Nets
net(1 name(VSS))
net(2 name(IN))
net(3 name(OUT))
net(4 name(VDD))
# Outgoing pins and their connections to nets
pin(1)
pin(2)
pin(3)
pin(4)
# Devices and their connections
device(1 PMOS
name(P)
param(L 0.25)
param(W 1.5)
param(AS 0)
param(AD 0)
param(PS 0)
param(PD 0)
terminal(S 4)
terminal(G 2)
terminal(D 3)
terminal(B 4)
)
device(2 NMOS
name(N)
param(L 0.25)
param(W 0.9)
param(AS 0)
param(AD 0)
param(PS 0)
param(PD 0)
terminal(S 3)
terminal(G 2)
terminal(D 1)
terminal(B 1)
)
)
)
# Cross reference
xref(
circuit(INVERTER_WITH_DIODES INVERTER_WITH_DIODES match
xref(
net(1 2 match)
net(3 3 match)
net(2 4 match)
net(4 1 match)
pin(() 0 match)
pin(() 1 match)
pin(() 2 match)
pin(() 3 match)
device(2 2 match)
device(1 1 match)
)
)
)

13
testdata/lvs/inv2_layout.cir vendored Normal file
View File

@ -0,0 +1,13 @@
* Extracted by KLayout
* cell INVERTER_WITH_DIODES
.SUBCKT INVERTER_WITH_DIODES
* net 1 IN
* net 2 VDD
* net 3 OUT
* net 4 VSS
* device instance $1 r0 *1 1.025,4.95 PMOS
M$1 2 1 3 2 PMOS L=0.25U W=1.5U AS=0.675P AD=0.675P PS=3.9U PD=3.9U
* device instance $2 r0 *1 1.025,0.65 NMOS
M$2 4 1 3 4 NMOS L=0.25U W=0.9U AS=0.405P AD=0.405P PS=2.7U PD=2.7U
.ENDS INVERTER_WITH_DIODES