mirror of https://github.com/KLayout/klayout.git
Some refactoring, better templates
1.) tl::Stream now can read from resources
(:<path> URL's)
2.) LVS/DRC templates are kept as resource,
"create_template" uses the URL to read them.
3.) Added samples for LVS
4.) Configured LVS to match sample
This commit is contained in:
parent
ebca5e1ce6
commit
5f27341995
Binary file not shown.
|
|
@ -0,0 +1,27 @@
|
|||
|
||||
.SUBCKT RINGO VSS VDD FB ENABLE OUT
|
||||
X$1 VDD 1 VSS VDD FB ENABLE VSS ND2X1
|
||||
X$2 VDD 2 VSS VDD 1 VSS INVX1
|
||||
X$3 VDD 3 VSS VDD 2 VSS INVX1
|
||||
X$4 VDD 4 VSS VDD 3 VSS INVX1
|
||||
X$5 VDD 5 VSS VDD 4 VSS INVX1
|
||||
X$6 VDD 6 VSS VDD 5 VSS INVX1
|
||||
X$7 VDD 7 VSS VDD 6 VSS INVX1
|
||||
X$8 VDD 8 VSS VDD 7 VSS INVX1
|
||||
X$9 VDD 9 VSS VDD 8 VSS INVX1
|
||||
X$10 VDD 10 VSS VDD 9 VSS INVX1
|
||||
X$11 VDD FB VSS VDD 10 VSS INVX1
|
||||
X$12 VDD OUT VSS VDD FB VSS INVX1
|
||||
.ENDS RINGO
|
||||
|
||||
.SUBCKT ND2X1 VDD OUT VSS NWELL B A BULK
|
||||
M$1 OUT A VDD NWELL PMOS L=0.25U W=1.5U
|
||||
M$2 VDD B OUT NWELL PMOS L=0.25U W=1.5U
|
||||
M$3 VSS A 1 BULK NMOS L=0.25U W=0.95U
|
||||
M$4 1 B OUT BULK NMOS L=0.25U W=0.95U
|
||||
.ENDS ND2X1
|
||||
|
||||
.SUBCKT INVX1 VDD OUT VSS NWELL IN BULK
|
||||
M$1 VDD IN OUT NWELL PMOS L=0.25U W=1.5U
|
||||
M$2 VSS IN OUT BULK NMOS L=0.25U W=0.95U
|
||||
.ENDS INVX1
|
||||
|
|
@ -0,0 +1,303 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-properties>
|
||||
<properties>
|
||||
<frame-color>#c0c0c0</frame-color>
|
||||
<fill-color>#c0c0c0</fill-color>
|
||||
<frame-brightness>0</frame-brightness>
|
||||
<fill-brightness>0</fill-brightness>
|
||||
<dither-pattern>I9</dither-pattern>
|
||||
<line-style>I2</line-style>
|
||||
<valid>true</valid>
|
||||
<visible>true</visible>
|
||||
<transparent>false</transparent>
|
||||
<width>2</width>
|
||||
<marked>false</marked>
|
||||
<xfill>false</xfill>
|
||||
<animation>0</animation>
|
||||
<name>1 - NWELL</name>
|
||||
<source>1/0@1</source>
|
||||
</properties>
|
||||
<properties>
|
||||
<frame-color>#c0c0c0</frame-color>
|
||||
<fill-color>#c0c0c0</fill-color>
|
||||
<frame-brightness>48</frame-brightness>
|
||||
<fill-brightness>48</fill-brightness>
|
||||
<dither-pattern>C0</dither-pattern>
|
||||
<line-style>I4</line-style>
|
||||
<valid>true</valid>
|
||||
<visible>true</visible>
|
||||
<transparent>false</transparent>
|
||||
<width>1</width>
|
||||
<marked>false</marked>
|
||||
<xfill>false</xfill>
|
||||
<animation>0</animation>
|
||||
<name>3 - PPLUS</name>
|
||||
<source>3/0@1</source>
|
||||
</properties>
|
||||
<properties>
|
||||
<frame-color>#c0c0c0</frame-color>
|
||||
<fill-color>#c0c0c0</fill-color>
|
||||
<frame-brightness>48</frame-brightness>
|
||||
<fill-brightness>48</fill-brightness>
|
||||
<dither-pattern>C1</dither-pattern>
|
||||
<line-style>I4</line-style>
|
||||
<valid>true</valid>
|
||||
<visible>true</visible>
|
||||
<transparent>false</transparent>
|
||||
<width>1</width>
|
||||
<marked>false</marked>
|
||||
<xfill>false</xfill>
|
||||
<animation>0</animation>
|
||||
<name>4 - NPLUS</name>
|
||||
<source>4/0@1</source>
|
||||
</properties>
|
||||
<properties>
|
||||
<frame-color>#ff0000</frame-color>
|
||||
<fill-color>#ff9d9d</fill-color>
|
||||
<frame-brightness>-64</frame-brightness>
|
||||
<fill-brightness>-64</fill-brightness>
|
||||
<dither-pattern>I3</dither-pattern>
|
||||
<line-style>I2</line-style>
|
||||
<valid>true</valid>
|
||||
<visible>true</visible>
|
||||
<transparent>false</transparent>
|
||||
<width>2</width>
|
||||
<marked>false</marked>
|
||||
<xfill>false</xfill>
|
||||
<animation>0</animation>
|
||||
<name>2 - DIFF</name>
|
||||
<source>2/0@1</source>
|
||||
</properties>
|
||||
<properties>
|
||||
<frame-color>#91ff00</frame-color>
|
||||
<fill-color>#91ff00</fill-color>
|
||||
<frame-brightness>-48</frame-brightness>
|
||||
<fill-brightness>-48</fill-brightness>
|
||||
<dither-pattern>I8</dither-pattern>
|
||||
<line-style/>
|
||||
<valid>true</valid>
|
||||
<visible>true</visible>
|
||||
<transparent>false</transparent>
|
||||
<width>2</width>
|
||||
<marked>false</marked>
|
||||
<xfill>false</xfill>
|
||||
<animation>0</animation>
|
||||
<name>5 - POLY</name>
|
||||
<source>5/0@1</source>
|
||||
</properties>
|
||||
<properties>
|
||||
<frame-color>#008000</frame-color>
|
||||
<fill-color>#808000</fill-color>
|
||||
<frame-brightness>0</frame-brightness>
|
||||
<fill-brightness>0</fill-brightness>
|
||||
<dither-pattern>I3</dither-pattern>
|
||||
<line-style>I4</line-style>
|
||||
<valid>true</valid>
|
||||
<visible>true</visible>
|
||||
<transparent>false</transparent>
|
||||
<width>1</width>
|
||||
<marked>false</marked>
|
||||
<xfill>false</xfill>
|
||||
<animation>0</animation>
|
||||
<name>6 - THICKOX</name>
|
||||
<source>THICKOX 6/0@1</source>
|
||||
</properties>
|
||||
<properties>
|
||||
<frame-color>#805000</frame-color>
|
||||
<fill-color>#805000</fill-color>
|
||||
<frame-brightness>0</frame-brightness>
|
||||
<fill-brightness>0</fill-brightness>
|
||||
<dither-pattern>I3</dither-pattern>
|
||||
<line-style>I4</line-style>
|
||||
<valid>true</valid>
|
||||
<visible>true</visible>
|
||||
<transparent>false</transparent>
|
||||
<width>1</width>
|
||||
<marked>false</marked>
|
||||
<xfill>false</xfill>
|
||||
<animation>0</animation>
|
||||
<name>7 - POLYRES</name>
|
||||
<source>'7 - SALBL' 7/0@1</source>
|
||||
</properties>
|
||||
<properties>
|
||||
<frame-color>#ff00ff</frame-color>
|
||||
<fill-color>#ffffff</fill-color>
|
||||
<frame-brightness>0</frame-brightness>
|
||||
<fill-brightness>0</fill-brightness>
|
||||
<dither-pattern>I0</dither-pattern>
|
||||
<line-style/>
|
||||
<valid>true</valid>
|
||||
<visible>true</visible>
|
||||
<transparent>false</transparent>
|
||||
<width>2</width>
|
||||
<marked>false</marked>
|
||||
<xfill>true</xfill>
|
||||
<animation>0</animation>
|
||||
<name>8 - CONTACT</name>
|
||||
<source>8/0@1</source>
|
||||
</properties>
|
||||
<properties>
|
||||
<frame-color>#8000ff</frame-color>
|
||||
<fill-color>#9580ff</fill-color>
|
||||
<frame-brightness>0</frame-brightness>
|
||||
<fill-brightness>0</fill-brightness>
|
||||
<dither-pattern>I4</dither-pattern>
|
||||
<line-style/>
|
||||
<valid>true</valid>
|
||||
<visible>true</visible>
|
||||
<transparent>false</transparent>
|
||||
<width>2</width>
|
||||
<marked>false</marked>
|
||||
<xfill>false</xfill>
|
||||
<animation>0</animation>
|
||||
<name>9 - METAL1</name>
|
||||
<source>9/0@1</source>
|
||||
</properties>
|
||||
<properties>
|
||||
<frame-color>#e872ff</frame-color>
|
||||
<fill-color>#e872ff</fill-color>
|
||||
<frame-brightness>-48</frame-brightness>
|
||||
<fill-brightness>-48</fill-brightness>
|
||||
<dither-pattern>I1</dither-pattern>
|
||||
<line-style/>
|
||||
<valid>true</valid>
|
||||
<visible>true</visible>
|
||||
<transparent>false</transparent>
|
||||
<width>2</width>
|
||||
<marked>false</marked>
|
||||
<xfill>true</xfill>
|
||||
<animation>0</animation>
|
||||
<name>10 - VIA</name>
|
||||
<source>10/0@1</source>
|
||||
</properties>
|
||||
<properties>
|
||||
<frame-color>#0000ff</frame-color>
|
||||
<fill-color>#8086ff</fill-color>
|
||||
<frame-brightness>0</frame-brightness>
|
||||
<fill-brightness>0</fill-brightness>
|
||||
<dither-pattern>I8</dither-pattern>
|
||||
<line-style/>
|
||||
<valid>true</valid>
|
||||
<visible>true</visible>
|
||||
<transparent>false</transparent>
|
||||
<width>2</width>
|
||||
<marked>false</marked>
|
||||
<xfill>false</xfill>
|
||||
<animation>0</animation>
|
||||
<name>11 - METAL2</name>
|
||||
<source>11/0@1</source>
|
||||
</properties>
|
||||
<properties>
|
||||
<frame-color>#808080</frame-color>
|
||||
<fill-color>#c0c0c0</fill-color>
|
||||
<frame-brightness>0</frame-brightness>
|
||||
<fill-brightness>128</fill-brightness>
|
||||
<dither-pattern>I43</dither-pattern>
|
||||
<line-style/>
|
||||
<valid>true</valid>
|
||||
<visible>true</visible>
|
||||
<transparent>true</transparent>
|
||||
<width>1</width>
|
||||
<marked>false</marked>
|
||||
<xfill>false</xfill>
|
||||
<animation>0</animation>
|
||||
<name>12 - PAD</name>
|
||||
<source>12/0@1</source>
|
||||
</properties>
|
||||
<properties>
|
||||
<frame-color>#c0c0c0</frame-color>
|
||||
<fill-color>#c0c0c0</fill-color>
|
||||
<frame-brightness>0</frame-brightness>
|
||||
<fill-brightness>0</fill-brightness>
|
||||
<dither-pattern>I1</dither-pattern>
|
||||
<line-style>I4</line-style>
|
||||
<valid>true</valid>
|
||||
<visible>true</visible>
|
||||
<transparent>false</transparent>
|
||||
<width>1</width>
|
||||
<marked>false</marked>
|
||||
<xfill>false</xfill>
|
||||
<animation>0</animation>
|
||||
<name>13 - BORDER</name>
|
||||
<source>13/0@1</source>
|
||||
</properties>
|
||||
<properties>
|
||||
<frame-color>#606060</frame-color>
|
||||
<fill-color>#606060</fill-color>
|
||||
<frame-brightness>0</frame-brightness>
|
||||
<fill-brightness>0</fill-brightness>
|
||||
<dither-pattern>I1</dither-pattern>
|
||||
<line-style>I2</line-style>
|
||||
<valid>true</valid>
|
||||
<visible>true</visible>
|
||||
<transparent>false</transparent>
|
||||
<width>1</width>
|
||||
<marked>false</marked>
|
||||
<xfill>true</xfill>
|
||||
<animation>0</animation>
|
||||
<name>1000 - MARKING 1</name>
|
||||
<source>1000/0@1</source>
|
||||
</properties>
|
||||
<properties>
|
||||
<frame-color>#000000</frame-color>
|
||||
<fill-color>#000000</fill-color>
|
||||
<frame-brightness>0</frame-brightness>
|
||||
<fill-brightness>0</fill-brightness>
|
||||
<dither-pattern>I1</dither-pattern>
|
||||
<line-style>I2</line-style>
|
||||
<valid>true</valid>
|
||||
<visible>true</visible>
|
||||
<transparent>false</transparent>
|
||||
<width>1</width>
|
||||
<marked>false</marked>
|
||||
<xfill>false</xfill>
|
||||
<animation>0</animation>
|
||||
<name>1001 - MARKING 2</name>
|
||||
<source>1001/0@1</source>
|
||||
</properties>
|
||||
<name/>
|
||||
<custom-dither-pattern>
|
||||
<pattern>
|
||||
<line>................</line>
|
||||
<line>...*............</line>
|
||||
<line>...*............</line>
|
||||
<line>...*............</line>
|
||||
<line>*******.........</line>
|
||||
<line>...*............</line>
|
||||
<line>...*............</line>
|
||||
<line>...*............</line>
|
||||
<line>................</line>
|
||||
<line>...........*....</line>
|
||||
<line>...........*....</line>
|
||||
<line>...........*....</line>
|
||||
<line>........*******.</line>
|
||||
<line>...........*....</line>
|
||||
<line>...........*....</line>
|
||||
<line>...........*....</line>
|
||||
</pattern>
|
||||
<order>1</order>
|
||||
<name>custom plus</name>
|
||||
</custom-dither-pattern>
|
||||
<custom-dither-pattern>
|
||||
<pattern>
|
||||
<line>................</line>
|
||||
<line>................</line>
|
||||
<line>................</line>
|
||||
<line>................</line>
|
||||
<line>*******.........</line>
|
||||
<line>................</line>
|
||||
<line>................</line>
|
||||
<line>................</line>
|
||||
<line>................</line>
|
||||
<line>................</line>
|
||||
<line>................</line>
|
||||
<line>................</line>
|
||||
<line>........*******.</line>
|
||||
<line>................</line>
|
||||
<line>................</line>
|
||||
<line>................</line>
|
||||
</pattern>
|
||||
<order>2</order>
|
||||
<name/>
|
||||
</custom-dither-pattern>
|
||||
</layer-properties>
|
||||
|
|
@ -68,13 +68,7 @@ module DRC
|
|||
register("drc-dsl-xml")
|
||||
|
||||
# create a template for the macro editor:
|
||||
mt = create_template("drc")
|
||||
mt.text = "# Read about DRC scripts in the User Manual under \"Design Rule Check (DRC)\"\n# This is a sample:\n\npoly = input(6)\nactive = input(1)\ngate = poly & active\ngate.width(0.25.micron).output(100, 0)"
|
||||
mt.show_in_menu = true
|
||||
mt.menu_path = "tools_menu.drc.end"
|
||||
mt.group_name = "drc_scripts"
|
||||
mt.description = "General;;DRC script (*.lydrc)\nA DRC script using KLayout's DRC language"
|
||||
mt.category = "drc"
|
||||
create_template(":/drc-templates/drc.lym")
|
||||
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -9,4 +9,7 @@
|
|||
<file alias="drc_interpreters.lym">built-in-macros/drc_interpreters.lym</file>
|
||||
<file alias="drc_install.lym">built-in-macros/drc_install.lym</file>
|
||||
</qresource>
|
||||
<qresource prefix="/drc-templates">
|
||||
<file alias="drc.lym">templates/drc.lym</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<klayout-macro>
|
||||
<description>General;;DRC script (*.lydrc)\nA DRC script using KLayout's DRC language</description>
|
||||
<version/>
|
||||
<category>drc</category>
|
||||
<prolog/>
|
||||
<epilog/>
|
||||
<doc/>
|
||||
<autorun>false</autorun>
|
||||
<autorun-early>false</autorun-early>
|
||||
<shortcut/>
|
||||
<show-in-menu>true</show-in-menu>
|
||||
<group-name>drc_scripts</group-name>
|
||||
<menu-path>tools_menu.drc.end</menu-path>
|
||||
<interpreter>ruby</interpreter>
|
||||
<dsl-interpreter-name/>
|
||||
<text>
|
||||
# Read about DRC scripts in the User Manual in "Design Rule Check (DRC)"
|
||||
|
||||
# This is a sample:
|
||||
|
||||
poly = input(6)
|
||||
active = input(1)
|
||||
gate = poly & active
|
||||
gate.width(0.25.micron).output(100, 0)
|
||||
</text>
|
||||
</klayout-macro>
|
||||
|
||||
|
|
@ -43,6 +43,7 @@
|
|||
#include "tlString.h"
|
||||
#include "tlClassRegistry.h"
|
||||
#include "tlExceptions.h"
|
||||
#include "tlFileUtils.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <limits>
|
||||
|
|
@ -487,21 +488,12 @@ MacroEditorDialog::MacroEditorDialog (lay::PluginRoot *pr, lym::MacroCollection
|
|||
}
|
||||
|
||||
std::string url = ":/macro-templates/" + ll;
|
||||
QResource res (tl::to_qstring (url));
|
||||
if (res.size () > 0) {
|
||||
|
||||
QByteArray data;
|
||||
if (res.isCompressed ()) {
|
||||
data = qUncompress ((const unsigned char *)res.data (), (int)res.size ());
|
||||
} else {
|
||||
data = QByteArray ((const char *)res.data (), (int)res.size ());
|
||||
}
|
||||
|
||||
lym::Macro *m = new lym::Macro ();
|
||||
try {
|
||||
|
||||
m->rename (tl::to_string (QFileInfo (QUrl (tl::to_qstring (url)).path ()).baseName ()));
|
||||
m->load_from_string (std::string (data.constData (), data.size ()), url);
|
||||
m->rename (tl::basename (url));
|
||||
m->load_from (url);
|
||||
if (! description.empty ()) {
|
||||
m->set_description (description_prefix + description);
|
||||
} else {
|
||||
|
|
@ -522,10 +514,6 @@ MacroEditorDialog::MacroEditorDialog (lay::PluginRoot *pr, lym::MacroCollection
|
|||
tl::error << "Reading " << url << ": " << ex.msg ();
|
||||
}
|
||||
|
||||
} else {
|
||||
tl::error << "Macro template resource " << url << " not found";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,101 +68,7 @@ module LVS
|
|||
register("lvs-dsl-xml")
|
||||
|
||||
# create a template for the macro editor:
|
||||
mt = create_template("lvs")
|
||||
mt.text = <<"END"
|
||||
# Try this sample script with this layout:
|
||||
# https://github.com/KLayout/klayout/tree/master/samples/lvs/ringo.gds
|
||||
# and this schematic:
|
||||
# https://github.com/KLayout/klayout/tree/master/samples/lvs/schematic.cir
|
||||
|
||||
# Reference schematic (if not absolute: path relative to original layout)
|
||||
schematic("schematic.cir")
|
||||
|
||||
# Tip: you can also use:
|
||||
# schematic(source.path.sub(/\.(oas|gds)/, ".cir"))
|
||||
# to derive the schematic name from the layout file's name
|
||||
# by substituting .oas or .gsd with .cir.
|
||||
|
||||
# Enable hierarchical mode
|
||||
deep
|
||||
|
||||
# Produce LVS report
|
||||
report_lvs
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# Layers
|
||||
|
||||
# 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) # includes labels
|
||||
via1 = input(10, 0)
|
||||
metal2 = input(11, 0) # includes labels
|
||||
|
||||
# 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 })
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# Connectivity
|
||||
|
||||
# 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")
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# Netlist and compare
|
||||
|
||||
# Netlist normalization
|
||||
netlist.simplify
|
||||
|
||||
# Netlist vs. netlist
|
||||
compare
|
||||
|
||||
END
|
||||
mt.show_in_menu = true
|
||||
mt.menu_path = "tools_menu.lvs.end"
|
||||
mt.group_name = "lvs_scripts"
|
||||
mt.description = "General;;LVS script (*.lylvs)\nA LVS script using KLayout's LVS language"
|
||||
mt.category = "lvs"
|
||||
create_template(":/lvs-templates/lvs.lym")
|
||||
|
||||
# if available, create a menu branch
|
||||
if RBA::Application::instance && RBA::Application::instance.main_window
|
||||
|
|
|
|||
|
|
@ -5,4 +5,7 @@
|
|||
<file alias="lvs_interpreters.lym">built-in-macros/lvs_interpreters.lym</file>
|
||||
<file alias="lvs_install.lym">built-in-macros/lvs_install.lym</file>
|
||||
</qresource>
|
||||
<qresource prefix="/lvs-templates">
|
||||
<file alias="lvs.lym">templates/lvs.lym</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,108 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<klayout-macro>
|
||||
<description>General;;LVS script (*.lylvs)\nA LVS script using KLayout's LVS language</description>
|
||||
<version/>
|
||||
<category>lvs</category>
|
||||
<prolog/>
|
||||
<epilog/>
|
||||
<doc/>
|
||||
<autorun>false</autorun>
|
||||
<autorun-early>false</autorun-early>
|
||||
<shortcut/>
|
||||
<show-in-menu>true</show-in-menu>
|
||||
<group-name>lvs_scripts</group-name>
|
||||
<menu-path>tools_menu.lvs.end</menu-path>
|
||||
<interpreter></interpreter>
|
||||
<dsl-interpreter-name/>
|
||||
<text>
|
||||
# Read about LVS scripts in the User Manual in "Layout vs. Schematic (LVS)"
|
||||
|
||||
# Try this sample script with this layout:
|
||||
# https://github.com/KLayout/klayout/tree/master/samples/lvs/ringo.gds
|
||||
# and this schematic:
|
||||
# https://github.com/KLayout/klayout/tree/master/samples/lvs/schematic.cir
|
||||
|
||||
# Reference schematic (if not absolute: path relative to original layout)
|
||||
schematic("schematic.cir")
|
||||
|
||||
# Tip: you can also use:
|
||||
# schematic(source.path.sub(/\.(oas|gds)/, ".cir"))
|
||||
# to derive the schematic name from the layout file's name
|
||||
# by substituting .oas or .gsd with .cir.
|
||||
|
||||
# Enable hierarchical mode
|
||||
deep
|
||||
|
||||
# Produce LVS report
|
||||
report_lvs
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# Layers
|
||||
|
||||
# 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) # includes labels
|
||||
via1 = input(10, 0)
|
||||
metal2 = input(11, 0) # includes labels
|
||||
|
||||
# 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 })
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# Connectivity
|
||||
|
||||
# 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")
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# Netlist and compare
|
||||
|
||||
# Netlist normalization
|
||||
netlist.simplify
|
||||
|
||||
# Netlist vs. netlist
|
||||
compare
|
||||
</text>
|
||||
</klayout-macro>
|
||||
|
||||
|
|
@ -29,6 +29,7 @@
|
|||
#include "rba.h"
|
||||
|
||||
#include "tlClassRegistry.h"
|
||||
#include "tlFileUtils.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
|
|
@ -189,15 +190,19 @@ public:
|
|||
return m_suffix;
|
||||
}
|
||||
|
||||
lym::Macro *create_template (const std::string &name)
|
||||
lym::Macro *create_template (const std::string &url)
|
||||
{
|
||||
if (! mp_registration) {
|
||||
throw std::runtime_error (tl::to_string (QObject::tr ("MacroInterpreter::create_template must be called after register")));
|
||||
}
|
||||
|
||||
lym::Macro *m = new lym::Macro ();
|
||||
if (! url.empty ()) {
|
||||
m->load_from (url);
|
||||
}
|
||||
|
||||
m->rename (tl::basename (url));
|
||||
|
||||
m->rename (name);
|
||||
m->set_readonly (true);
|
||||
m->set_dsl_interpreter (m_name);
|
||||
m->set_interpreter (lym::Macro::DSLInterpreter);
|
||||
|
|
@ -281,10 +286,9 @@ Class<gsi::MacroInterpreter> decl_MacroInterpreter ("lay", "MacroInterpreter",
|
|||
"is set to 'dsl' can use this object to run the script. For executing a script, the system will "
|
||||
"call the interpreter's \\execute method.\n"
|
||||
) +
|
||||
gsi::method ("create_template", &MacroInterpreter::create_template,
|
||||
gsi::method ("create_template", &MacroInterpreter::create_template, gsi::arg ("url"),
|
||||
"@brief Creates a new macro template\n"
|
||||
"@args name\n"
|
||||
"@param name The template name. This is an arbitrary string which should be unique.\n"
|
||||
"@url The template will be initialized from that URL.\n"
|
||||
"\n"
|
||||
"This method will create a register a new macro template. It returns a \\Macro object which "
|
||||
"can be modified in order to adjust the template (for example to set description, add a content, "
|
||||
|
|
|
|||
|
|
@ -44,6 +44,11 @@
|
|||
#include "tlString.h"
|
||||
#include "tlUri.h"
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
# include <QByteArray>
|
||||
# include <QResource>
|
||||
#endif
|
||||
|
||||
namespace tl
|
||||
{
|
||||
|
||||
|
|
@ -155,9 +160,34 @@ InputStream::InputStream (const std::string &abstract_path)
|
|||
{
|
||||
m_bcap = 4096; // initial buffer capacity
|
||||
m_blen = 0;
|
||||
mp_buffer = new char [m_bcap];
|
||||
mp_buffer = 0;
|
||||
|
||||
tl::Extractor ex (abstract_path.c_str ());
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
if (ex.test (":")) {
|
||||
|
||||
QResource res (tl::to_qstring (abstract_path));
|
||||
if (res.size () > 0) {
|
||||
|
||||
QByteArray data;
|
||||
if (res.isCompressed ()) {
|
||||
data = qUncompress ((const unsigned char *)res.data (), (int)res.size ());
|
||||
} else {
|
||||
data = QByteArray ((const char *)res.data (), (int)res.size ());
|
||||
}
|
||||
|
||||
mp_buffer = new char[data.size ()];
|
||||
memcpy (mp_buffer, data.constData (), data.size ());
|
||||
|
||||
mp_bptr = mp_buffer;
|
||||
m_bcap = data.size ();
|
||||
m_blen = m_bcap;
|
||||
|
||||
}
|
||||
|
||||
} else
|
||||
#endif
|
||||
#if defined(HAVE_CURL) || defined(HAVE_QT)
|
||||
if (ex.test ("http:") || ex.test ("https:")) {
|
||||
mp_delegate = new InputHttpStream (abstract_path);
|
||||
|
|
@ -165,15 +195,17 @@ InputStream::InputStream (const std::string &abstract_path)
|
|||
#endif
|
||||
if (ex.test ("pipe:")) {
|
||||
mp_delegate = new InputPipe (ex.get ());
|
||||
} else
|
||||
if (ex.test ("file:")) {
|
||||
} else if (ex.test ("file:")) {
|
||||
tl::URI uri (abstract_path);
|
||||
mp_delegate = new InputZLibFile (uri.path ());
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
mp_delegate = new InputZLibFile (abstract_path);
|
||||
}
|
||||
|
||||
if (! mp_buffer) {
|
||||
mp_buffer = new char [m_bcap];
|
||||
}
|
||||
|
||||
m_owns_delegate = true;
|
||||
}
|
||||
|
||||
|
|
@ -182,9 +214,17 @@ std::string InputStream::absolute_path (const std::string &abstract_path)
|
|||
// TODO: align this implementation with InputStream ctor
|
||||
|
||||
tl::Extractor ex (abstract_path.c_str ());
|
||||
#if defined(HAVE_QT)
|
||||
if (ex.test (":")) {
|
||||
return abstract_path;
|
||||
} else
|
||||
#endif
|
||||
#if defined(HAVE_CURL) || defined(HAVE_QT)
|
||||
if (ex.test ("http:") || ex.test ("https:")) {
|
||||
return abstract_path;
|
||||
} else if (ex.test ("pipe:")) {
|
||||
} else
|
||||
#endif
|
||||
if (ex.test ("pipe:")) {
|
||||
return abstract_path;
|
||||
} else if (ex.test ("file:")) {
|
||||
tl::URI uri (abstract_path);
|
||||
|
|
@ -247,7 +287,9 @@ InputStream::get (size_t n, bool bypass_inflate)
|
|||
memmove (mp_buffer, mp_bptr, m_blen);
|
||||
}
|
||||
|
||||
if (mp_delegate) {
|
||||
m_blen += mp_delegate->read (mp_buffer + m_blen, m_bcap - m_blen);
|
||||
}
|
||||
mp_bptr = mp_buffer;
|
||||
|
||||
}
|
||||
|
|
@ -308,12 +350,12 @@ InputStream::read_all ()
|
|||
return str;
|
||||
}
|
||||
|
||||
void InputStream::copy_to(tl::OutputStream &os)
|
||||
void InputStream::copy_to (tl::OutputStream &os)
|
||||
{
|
||||
const size_t chunk = 65536;
|
||||
char b [chunk];
|
||||
size_t read;
|
||||
while ((read = mp_delegate->read (b, sizeof (b))) > 0) {
|
||||
while (mp_delegate && (read = mp_delegate->read (b, sizeof (b))) > 0) {
|
||||
os.put (b, read);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue