diff --git a/src/lay/lay/doc/manual/lvs_intro.xml b/src/lay/lay/doc/manual/lvs_intro.xml index dde228b35..d8a0ecc7e 100644 --- a/src/lay/lay/doc/manual/lvs_intro.xml +++ b/src/lay/lay/doc/manual/lvs_intro.xml @@ -83,7 +83,7 @@ Mn OUT IN VSS SUBSTRATE NMOS W=0.9U L=0.25U

Sample LVS script

- The LVS script to compare the layout above and the schematic now is this: + The LVS script to compare the layout above and the schematic now is this (for more details see ):

# LVS script (demo technology, KLayout manual)
@@ -175,7 +175,7 @@ compare
The first and important statement of a LVS script should be the "deep" switch which enables hierarchical mode. Without hierarchical mode, the netlist is produced without subcircuits. Such flat netlist are inefficient to compare and hard to debug. Hence we switch to - hierarchical mode with the "deep" statement: + hierarchical mode with the "deep" statement (see ):

deep
@@ -188,7 +188,7 @@ compare
report_lvs

- We can also write the report to a file if we want: + We can also write the report to a file if we want (see ):

report_lvs("inv.lvsdb")
@@ -214,7 +214,7 @@ metal2_lbl = labels(9, 1) (the layout source is - as in DRC - usually the current layout). While "input" pulls all kind of shapes, "labels" will only pull texts. We use "labels" to pull labels for first metal from GDS layer 7, datatype 1 and - labels for second metal from GDS layer 9, datatype 1. + labels for second metal from GDS layer 9, datatype 1. For details see .

@@ -245,7 +245,12 @@ nsd = nactive - ngate Hence "active_in_nwell" is the part of "ACTIVE" which is inside "NWELL" while "active_outside_nwell" is the part of "ACTIVE" outside it. The main purpose of these formulas is to separate source and drain regions but cutting away the gate area from the "ACTIVE" area. This renders "psd" and "nsd" (PMOS and NMOS source/drain). - We also separate gate regions for PMOS (pgate) and NMOS transistors (ngate). With these ingredients we are + The boolean operations are part of the DRC feature set. For more functions and detailed descriptions see + . +

+ +

+ We also separate gate regions for PMOS (pgate) and NMOS transistors (ngate) and with these ingredients we are ready to move to device extraction:

@@ -253,7 +258,8 @@ nsd = nactive - ngate "tS" => psd, "tD" => psd, "tG" => poly, "tW" => nwell })

- The first argument of "extract_devices" is the device extractor. The device extractor is an object + The first argument of "extract_devices" (see ) is the device extractor. + The device extractor is an object responsible for the actual extraction of a certain device type. In our case the template is "MOS4" and we want to produce a new class of devices called "PMOS". mos4("PMOS") will create a new device extractor which produces devices of "MOS4" kind with class name "PMOS". @@ -283,7 +289,7 @@ nsd = nactive - ngate "tS" => nsd, "tD" => nsd, "tG" => poly, "tW" => bulk })

- Having the devices is already half the work. We now need to supply the connectivity: + Having the devices is already half the work. We now need to supply the connectivity (see ):

connect(psd,        contact)
@@ -340,7 +346,7 @@ connect_global(nwell, "NWELL")
compare

- If we insert a netlist write statement at the beginning of the script, we can obtain + If we insert a netlist write statement (see ) at the beginning of the script, we can obtain a SPICE version of the extracted netlist:

diff --git a/testdata/lvs/inv.lvs b/testdata/lvs/inv.lvs new file mode 100644 index 000000000..13de121de --- /dev/null +++ b/testdata/lvs/inv.lvs @@ -0,0 +1,75 @@ + +source("inv.oas", "INVERTER") + +deep + +# Reports generated + +# LVS report to inv.lvsdb +report_lvs("inv.lvsdb") + +# Write extracted netlist to inv_extracted.cir +target_netlist("inv_extracted.cir", write_spice, "Extracted by KLayout") + +# Drawing layers + +nwell = input(1, 0) +active = input(2, 0) +pplus = input(3, 0) +nplus = input(4, 0) +poly = input(5, 0) +contact = input(6, 0) +metal1 = input(7, 0) +metal1_lbl = labels(7, 1) +via1 = input(8, 0) +metal2 = input(9, 0) +metal2_lbl = labels(9, 1) + +# 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 + +active_outside_nwell = active - nwell +nactive = active_outside_nwell & nplus +ngate = nactive & poly +nsd = nactive - ngate + +# 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(contact, metal1) +connect(metal1, metal1_lbl) # attaches labels +connect(metal1, via1) +connect(via1, metal2) +connect(metal2, metal2_lbl) # attaches labels + +# Global +connect_global(bulk, "SUBSTRATE") +connect_global(nwell, "NWELL") + +# Compare section + +schematic("inv.cir") + +compare + diff --git a/testdata/lvs/inv2.cir b/testdata/lvs/inv2.cir new file mode 100644 index 000000000..d32266ee6 --- /dev/null +++ b/testdata/lvs/inv2.cir @@ -0,0 +1,8 @@ + +* Simple CMOS inverer circuit + +.SUBCKT INVERTER_WITH_DIODES VSS IN OUT VDD +Mp VDD IN OUT VDD PMOS W=1.5U L=0.25U +Mn OUT IN VSS VSS NMOS W=0.9U L=0.25U +.ENDS + diff --git a/testdata/lvs/inv2.lvs b/testdata/lvs/inv2.lvs new file mode 100644 index 000000000..d8d372ae3 --- /dev/null +++ b/testdata/lvs/inv2.lvs @@ -0,0 +1,80 @@ + +source("inv.oas", "INVERTER_WITH_DIODES") + +deep + +# Reports generated + +# LVS report to inv.lvsdb +report_lvs("inv.lvsdb") + +# Write extracted netlist to inv_extracted.cir +target_netlist("inv_extracted.cir", write_spice, "Extracted by KLayout") + +# Drawing layers + +nwell = input(1, 0) +active = input(2, 0) +pplus = input(3, 0) +nplus = input(4, 0) +poly = input(5, 0) +contact = input(6, 0) +metal1 = input(7, 0) +metal1_lbl = labels(7, 1) +via1 = input(8, 0) +metal2 = input(9, 0) +metal2_lbl = labels(9, 1) + +# 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 + +# 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, metal1_lbl) # attaches labels +connect(metal1, via1) +connect(via1, metal2) +connect(metal2, metal2_lbl) # attaches labels + +# Global +connect_global(bulk, "SUBSTRATE") +connect_global(ptie, "SUBSTRATE") + +# Compare section + +schematic("inv2.cir") + +compare + diff --git a/testdata/lvs/inv2.oas b/testdata/lvs/inv2.oas new file mode 100644 index 000000000..c40f14de0 Binary files /dev/null and b/testdata/lvs/inv2.oas differ