diff --git a/src/lvs/unit_tests/lvsSimpleTests.cc b/src/lvs/unit_tests/lvsSimpleTests.cc index 050f039eb..6ed065c3d 100644 --- a/src/lvs/unit_tests/lvsSimpleTests.cc +++ b/src/lvs/unit_tests/lvsSimpleTests.cc @@ -339,14 +339,21 @@ TEST(55_SoftConnectionSecondLevel) run_test (_this, "soft_connect6", "soft_connect6.gds", true, false /*no LVS*/); } -// Issue #1719, part 2 +// Issue #1719, part 2 (ignore stray texts) TEST(60_StrayTextsDoNotMakeNets) { run_test (_this, "stray_texts1", "stray_texts.gds", true, false /*no LVS*/); } -// Issue #1719, part 2 +// Issue #1719, part 2 (ignore stray texts) TEST(61_StrayTextsDoNotMakeNets) { run_test (_this, "stray_texts2", "stray_texts.gds", true, false /*no LVS*/); } + +// Issue #1719, part 3 (layer naming) +TEST(62_LayerNames) +{ + run_test (_this, "layer_names", "layer_names.gds", false, true, "TOP"); +} + diff --git a/testdata/lvs/layer_names.cir b/testdata/lvs/layer_names.cir new file mode 100644 index 000000000..9acc99ffe --- /dev/null +++ b/testdata/lvs/layer_names.cir @@ -0,0 +1,50 @@ +* Extracted by KLayout + +* cell TOP +* pin A +* pin C +* pin SUBSTRATE +.SUBCKT TOP 2 3 4 +* net 2 A +* net 3 C +* net 4 SUBSTRATE +* cell instance $1 r0 *1 0,0 +X$1 2 3 1 6 4 DINV +* cell instance $2 r0 *1 3.6,0 +X$2 5 6 1 4 INVX1 +.ENDS TOP + +* cell DINV +* pin A<1> +* pin A<2> +* pin B<2> +* pin VDD +* pin VSS +.SUBCKT DINV 1 2 3 5 6 +* net 1 A<1> +* net 2 A<2> +* net 3 B<2> +* net 4 B<1> +* net 5 VDD +* net 6 VSS +* cell instance $1 r0 *1 0,0 +X$1 4 5 1 6 INVX1 +* cell instance $2 r0 *1 1.8,0 +X$2 3 5 2 6 INVX1 +.ENDS DINV + +* cell INVX1 +* pin OUT +* pin VDD +* pin IN +* pin VSS +.SUBCKT INVX1 1 2 3 4 +* net 1 OUT +* net 2 VDD +* net 3 IN +* net 4 VSS +* device instance $1 r0 *1 0.85,5.8 PMOS +M$1 1 3 2 2 PMOS L=0.25U W=1.5U AS=0.6375P AD=0.6375P PS=3.85U PD=3.85U +* device instance $2 r0 *1 0.85,2.135 NMOS +M$2 1 3 4 4 NMOS L=0.25U W=0.95U AS=0.40375P AD=0.40375P PS=2.75U PD=2.75U +.ENDS INVX1 diff --git a/testdata/lvs/layer_names.gds b/testdata/lvs/layer_names.gds new file mode 100644 index 000000000..3329c14d1 Binary files /dev/null and b/testdata/lvs/layer_names.gds differ diff --git a/testdata/lvs/layer_names.lvs b/testdata/lvs/layer_names.lvs new file mode 100644 index 000000000..9ea2cf9ca --- /dev/null +++ b/testdata/lvs/layer_names.lvs @@ -0,0 +1,105 @@ + +source($lvs_test_source, $lvs_test_top) + +report_lvs($lvs_test_target_lvsdb, true) + +target_netlist($lvs_test_target_cir, write_spice, "Extracted by KLayout") + +schematic("floating_ref.cir") + +deep + +# Drawing layers + +nwell = input(1, 0) +active = input(2, 0) +pplus = input(3, 0) +nplus = input(4, 0) +poly = input(5, 0) +contact = input(8, 0) +metal1 = input(9, 0) +via1 = input(10, 0) +metal2 = input(11, 0) + +# try layer names with nwell +name(nwell, "nwell") + +# same name - not an error +name(nwell, "nwell") + +ok = true +begin + name(nwell, "nwell2") + ok = false +rescue => ex +end +ok || raise("nwell layer is already named - this is an error") + +# Bulk layer for terminal provisioning + +bulk = polygon_layer + +# Computed layers + +active_in_nwell = active & nwell +pactive = active_in_nwell & pplus +pgate = pactive & poly +psd = pactive - pgate +ntie = active_in_nwell & nplus + +active_outside_nwell = active - nwell +nactive = active_outside_nwell & nplus +ngate = nactive & poly +nsd = nactive - ngate +ptie = active_outside_nwell & pplus + +# Layer names for all other layers + +%w(bulk pactive pgate psd ntie nactive ngate nsd poly contact metal1 via1 metal2).each do |v| + name(eval(v), v) +end + +# Device extraction + +# PMOS transistor device extraction +extract_devices(mos4("PMOS"), { "SD" => psd, "G" => pgate, "W" => nwell, + "tS" => psd, "tD" => psd, "tG" => poly, "tW" => nwell }) + +# NMOS transistor device extraction +extract_devices(mos4("NMOS"), { "SD" => nsd, "G" => ngate, "W" => bulk, + "tS" => nsd, "tD" => nsd, "tG" => poly, "tW" => bulk }) + +# Define connectivity for netlist extraction + +# Inter-layer +connect(psd, contact) +connect(nsd, contact) +connect(poly, contact) +connect(ntie, contact) +connect(nwell, ntie) +connect(ptie, contact) +connect(contact, metal1) +connect(metal1, via1) +connect(via1, metal2) + +# Global +connect_global(bulk, "SUBSTRATE") +connect_global(ptie, "SUBSTRATE") + +ok = true +begin + name(ptie, "ptie") + ok = false +rescue => ex +end +ok || raise("ptie layer already used - this is an error") + +# Compare section + +netlist.simplify +align + +consider_net_names(false) + +compare + diff --git a/testdata/lvs/layer_names.lvsdb b/testdata/lvs/layer_names.lvsdb new file mode 100644 index 000000000..1a9df5bf6 --- /dev/null +++ b/testdata/lvs/layer_names.lvsdb @@ -0,0 +1,434 @@ +#%lvsdb-klayout + +# Layout +layout( + top(TOP) + unit(0.001) + + # Layer section + # This section lists the mask layers (drawing or derived) and their connections. + + # Mask layers + layer(nwell '1/0') + layer(poly '5/0') + layer(contact '8/0') + layer(metal1 '9/0') + layer(via1) + layer(metal2) + layer(bulk) + layer(psd) + layer(ntie) + layer(nsd) + layer(l1) + + # Mask layer connectivity + connect(nwell nwell ntie) + connect(poly poly contact) + connect(contact poly contact metal1 psd ntie nsd l1) + connect(metal1 contact metal1 via1) + connect(via1 metal1 via1 metal2) + connect(metal2 via1 metal2) + connect(bulk bulk) + connect(psd contact psd) + connect(ntie nwell contact ntie) + connect(nsd contact nsd) + connect(l1 contact l1) + + # Global nets and connectivity + global(bulk SUBSTRATE) + global(l1 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(psd (-550 -750) (425 1500)) + ) + terminal(G + rect(poly (-125 -750) (250 1500)) + ) + terminal(D + rect(psd (125 -750) (425 1500)) + ) + terminal(B + rect(nwell (-125 -750) (250 1500)) + ) + ) + device(D$NMOS NMOS + terminal(S + rect(nsd (-550 -475) (425 950)) + ) + terminal(G + rect(poly (-125 -475) (250 950)) + ) + terminal(D + rect(nsd (125 -475) (425 950)) + ) + terminal(B + rect(bulk (-125 -475) (250 950)) + ) + ) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(INVX1 + + # Circuit boundary + rect((-100 400) (2000 7600)) + + # Nets with their geometries + net(1 name(OUT) + rect(contact (1110 5160) (180 180)) + rect(contact (-180 920) (180 180)) + rect(contact (-180 -730) (180 180)) + rect(contact (-180 -4120) (180 180)) + rect(contact (-180 370) (180 180)) + rect(metal1 (-240 -790) (300 4790)) + rect(metal1 (-150 -2500) (0 0)) + rect(psd (-225 1050) (425 1500)) + rect(nsd (-425 -4890) (425 950)) + ) + net(2 name(VDD) + rect(nwell (-100 4500) (2000 3500)) + rect(contact (-1090 -890) (180 180)) + rect(contact (-580 -1030) (180 180)) + rect(contact (-180 -730) (180 180)) + rect(contact (-180 -730) (180 180)) + rect(metal1 (-590 1460) (1800 800)) + rect(metal1 (-1050 -550) (300 300)) + rect(metal1 (-700 -850) (300 300)) + rect(metal1 (300 500) (0 0)) + rect(metal1 (-600 -2200) (300 1400)) + rect(psd (-350 -1450) (425 1500)) + rect(ntie (-75 450) (500 500)) + ) + net(3 name(IN) + rect(poly (725 2860) (250 1940)) + rect(poly (-525 -1850) (300 300)) + rect(poly (-25 -1840) (250 1450)) + rect(poly (-250 1940) (250 2000)) + rect(poly (-250 -2000) (250 2000)) + rect(contact (-465 -3790) (180 180)) + rect(metal1 (-90 -90) (0 0)) + rect(metal1 (-150 -150) (300 300)) + ) + net(4 name(VSS) + rect(contact (810 710) (180 180)) + rect(contact (-580 880) (180 180)) + rect(contact (-180 370) (180 180)) + rect(metal1 (-590 -2100) (1800 800)) + rect(metal1 (-1050 -550) (300 300)) + rect(metal1 (-100 -150) (0 0)) + rect(metal1 (-600 400) (300 1360)) + rect(nsd (-350 -900) (425 950)) + rect(l1 (-75 -2010) (500 400)) + ) + + # Outgoing pins and their connections to nets + pin(1 name(OUT)) + pin(2 name(VDD)) + pin(3 name(IN)) + pin(4 name(VSS)) + + # Devices and their connections + device(1 D$PMOS + location(850 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.6375) + param(AD 0.6375) + param(PS 3.85) + param(PD 3.85) + terminal(S 2) + terminal(G 3) + terminal(D 1) + terminal(B 2) + ) + device(2 D$NMOS + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.40375) + param(PS 2.75) + param(PD 2.75) + terminal(S 4) + terminal(G 3) + terminal(D 1) + terminal(B 4) + ) + + ) + circuit(DINV + + # Circuit boundary + rect((-100 400) (3800 7600)) + + # Nets with their geometries + net(1 name('A<1>') + rect(metal1 (600 3100) (0 0)) + ) + net(2 name('A<2>') + rect(metal1 (2400 3100) (0 0)) + ) + net(3 name('B<2>') + rect(metal1 (3000 4000) (0 0)) + ) + net(4 name('B<1>') + rect(metal1 (1200 4000) (0 0)) + ) + net(5 name(VDD) + rect(metal1 (1800 7200) (0 0)) + ) + net(6 name(VSS) + rect(metal1 (1800 800) (0 0)) + ) + + # Outgoing pins and their connections to nets + pin(1 name('A<1>')) + pin(2 name('A<2>')) + pin(3 name('B<2>')) + pin(5 name(VDD)) + pin(6 name(VSS)) + + # Subcircuits and their connections + circuit(1 INVX1 location(0 0) + pin(0 4) + pin(1 5) + pin(2 1) + pin(3 6) + ) + circuit(2 INVX1 location(1800 0) + pin(0 3) + pin(1 5) + pin(2 2) + pin(3 6) + ) + + ) + circuit(TOP + + # Circuit boundary + rect((-100 400) (5600 7600)) + + # Nets with their geometries + net(1 + rect(metal1 (3100 2950) (950 300)) + ) + net(2 name(A) + rect(metal1 (600 3100) (0 0)) + ) + net(3 name(C) + rect(metal1 (2400 3100) (0 0)) + ) + net(4 name(SUBSTRATE)) + net(5) + net(6) + + # Outgoing pins and their connections to nets + pin(2 name(A)) + pin(3 name(C)) + pin(4 name(SUBSTRATE)) + + # Subcircuits and their connections + circuit(1 DINV location(0 0) + pin(0 2) + pin(1 3) + pin(2 1) + pin(3 6) + pin(4 4) + ) + circuit(2 INVX1 location(3600 0) + pin(0 5) + pin(1 6) + pin(2 1) + pin(3 4) + ) + + ) +) + +# Reference netlist +reference( + + # Device class section + class(NMOS MOS4) + class(PMOS MOS4) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(INVX1 + + # Nets + net(1 name(A)) + net(2 name(Z)) + net(3 name(VSS)) + net(4 name(VDD)) + + # Outgoing pins and their connections to nets + pin(1 name(A)) + pin(2 name(Z)) + pin(4 name(VDD)) + pin(3 name(VSS)) + + # Devices and their connections + device(1 NMOS + name('0') + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 3) + terminal(G 1) + terminal(D 2) + terminal(B 3) + ) + device(2 PMOS + name('1') + 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 1) + terminal(D 2) + terminal(B 4) + ) + + ) + circuit(DINV + + # Nets + net(1 name('A<1>')) + net(2 name('A<2>')) + net(3 name('B<1>')) + net(4 name('B<2>')) + net(5 name(VDD)) + net(6 name(VSS)) + + # Outgoing pins and their connections to nets + pin(1 name('A<1>')) + pin(2 name('A<2>')) + pin(3 name('B<1>')) + pin(4 name('B<2>')) + pin(5 name(VDD)) + pin(6 name(VSS)) + + # Subcircuits and their connections + circuit(1 INVX1 name(A) + pin(0 1) + pin(1 3) + pin(2 5) + pin(3 6) + ) + circuit(2 INVX1 name(B) + pin(0 2) + pin(1 4) + pin(2 5) + pin(3 6) + ) + + ) + circuit(TOP + + # Nets + net(1 name(A)) + net(2 name(C)) + net(3 name(D)) + net(4 name(B)) + net(5 name(E)) + net(6 name(VDD)) + net(7 name(VSS)) + + # Outgoing pins and their connections to nets + pin(1 name(A)) + pin(2 name(C)) + pin(3 name(D)) + pin(6 name(VDD)) + pin(7 name(VSS)) + + # Subcircuits and their connections + circuit(1 DINV name('0') + pin(0 1) + pin(1 2) + pin(2 4) + pin(3 5) + pin(4 6) + pin(5 7) + ) + circuit(2 INVX1 name('1') + pin(0 5) + pin(1 3) + pin(2 6) + pin(3 7) + ) + + ) +) + +# Cross reference +xref( + circuit(DINV DINV match + log( + entry(warning description('Matching nets B<1> from an ambiguous group of nets')) + entry(warning description('Matching nets B<2> from an ambiguous group of nets')) + entry(info description('Matching nets A<1> following an ambiguous match')) + entry(info description('Matching nets A<2> following an ambiguous match')) + ) + xref( + net(1 1 match) + net(2 2 match) + net(4 3 warning) + net(3 4 warning) + net(5 5 match) + net(6 6 match) + pin(() 2 match) + pin(0 0 match) + pin(1 1 match) + pin(2 3 match) + pin(3 4 match) + pin(4 5 match) + circuit(1 1 match) + circuit(2 2 match) + ) + ) + circuit(INVX1 INVX1 match + xref( + net(3 1 match) + net(1 2 match) + net(2 4 match) + net(4 3 match) + pin(2 0 match) + pin(0 1 match) + pin(1 2 match) + pin(3 3 match) + device(2 1 match) + device(1 2 match) + ) + ) + circuit(TOP TOP match + xref( + net(5 3 match) + net(1 5 match) + net(6 6 match) + net(2 1 match) + net(3 2 match) + net(4 7 match) + pin(() 2 match) + pin(() 3 match) + pin(0 0 match) + pin(1 1 match) + pin(2 4 match) + circuit(1 1 match) + circuit(2 2 match) + ) + ) +)