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")
|
register("drc-dsl-xml")
|
||||||
|
|
||||||
# create a template for the macro editor:
|
# create a template for the macro editor:
|
||||||
mt = create_template("drc")
|
create_template(":/drc-templates/drc.lym")
|
||||||
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"
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,4 +9,7 @@
|
||||||
<file alias="drc_interpreters.lym">built-in-macros/drc_interpreters.lym</file>
|
<file alias="drc_interpreters.lym">built-in-macros/drc_interpreters.lym</file>
|
||||||
<file alias="drc_install.lym">built-in-macros/drc_install.lym</file>
|
<file alias="drc_install.lym">built-in-macros/drc_install.lym</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
|
<qresource prefix="/drc-templates">
|
||||||
|
<file alias="drc.lym">templates/drc.lym</file>
|
||||||
|
</qresource>
|
||||||
</RCC>
|
</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 "tlString.h"
|
||||||
#include "tlClassRegistry.h"
|
#include "tlClassRegistry.h"
|
||||||
#include "tlExceptions.h"
|
#include "tlExceptions.h"
|
||||||
|
#include "tlFileUtils.h"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
@ -487,21 +488,12 @@ MacroEditorDialog::MacroEditorDialog (lay::PluginRoot *pr, lym::MacroCollection
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string url = ":/macro-templates/" + ll;
|
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 ();
|
lym::Macro *m = new lym::Macro ();
|
||||||
try {
|
try {
|
||||||
|
|
||||||
m->rename (tl::to_string (QFileInfo (QUrl (tl::to_qstring (url)).path ()).baseName ()));
|
m->rename (tl::basename (url));
|
||||||
m->load_from_string (std::string (data.constData (), data.size ()), url);
|
m->load_from (url);
|
||||||
if (! description.empty ()) {
|
if (! description.empty ()) {
|
||||||
m->set_description (description_prefix + description);
|
m->set_description (description_prefix + description);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -522,10 +514,6 @@ MacroEditorDialog::MacroEditorDialog (lay::PluginRoot *pr, lym::MacroCollection
|
||||||
tl::error << "Reading " << url << ": " << ex.msg ();
|
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")
|
register("lvs-dsl-xml")
|
||||||
|
|
||||||
# create a template for the macro editor:
|
# create a template for the macro editor:
|
||||||
mt = create_template("lvs")
|
create_template(":/lvs-templates/lvs.lym")
|
||||||
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"
|
|
||||||
|
|
||||||
# if available, create a menu branch
|
# if available, create a menu branch
|
||||||
if RBA::Application::instance && RBA::Application::instance.main_window
|
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_interpreters.lym">built-in-macros/lvs_interpreters.lym</file>
|
||||||
<file alias="lvs_install.lym">built-in-macros/lvs_install.lym</file>
|
<file alias="lvs_install.lym">built-in-macros/lvs_install.lym</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
|
<qresource prefix="/lvs-templates">
|
||||||
|
<file alias="lvs.lym">templates/lvs.lym</file>
|
||||||
|
</qresource>
|
||||||
</RCC>
|
</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 "rba.h"
|
||||||
|
|
||||||
#include "tlClassRegistry.h"
|
#include "tlClassRegistry.h"
|
||||||
|
#include "tlFileUtils.h"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
|
|
@ -189,15 +190,19 @@ public:
|
||||||
return m_suffix;
|
return m_suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
lym::Macro *create_template (const std::string &name)
|
lym::Macro *create_template (const std::string &url)
|
||||||
{
|
{
|
||||||
if (! mp_registration) {
|
if (! mp_registration) {
|
||||||
throw std::runtime_error (tl::to_string (QObject::tr ("MacroInterpreter::create_template must be called after register")));
|
throw std::runtime_error (tl::to_string (QObject::tr ("MacroInterpreter::create_template must be called after register")));
|
||||||
}
|
}
|
||||||
|
|
||||||
lym::Macro *m = new lym::Macro ();
|
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_readonly (true);
|
||||||
m->set_dsl_interpreter (m_name);
|
m->set_dsl_interpreter (m_name);
|
||||||
m->set_interpreter (lym::Macro::DSLInterpreter);
|
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 "
|
"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"
|
"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"
|
"@brief Creates a new macro template\n"
|
||||||
"@args name\n"
|
"@url The template will be initialized from that URL.\n"
|
||||||
"@param name The template name. This is an arbitrary string which should be unique.\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"This method will create a register a new macro template. It returns a \\Macro object which "
|
"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, "
|
"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 "tlString.h"
|
||||||
#include "tlUri.h"
|
#include "tlUri.h"
|
||||||
|
|
||||||
|
#if defined(HAVE_QT)
|
||||||
|
# include <QByteArray>
|
||||||
|
# include <QResource>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace tl
|
namespace tl
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -155,9 +160,34 @@ InputStream::InputStream (const std::string &abstract_path)
|
||||||
{
|
{
|
||||||
m_bcap = 4096; // initial buffer capacity
|
m_bcap = 4096; // initial buffer capacity
|
||||||
m_blen = 0;
|
m_blen = 0;
|
||||||
mp_buffer = new char [m_bcap];
|
mp_buffer = 0;
|
||||||
|
|
||||||
tl::Extractor ex (abstract_path.c_str ());
|
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 defined(HAVE_CURL) || defined(HAVE_QT)
|
||||||
if (ex.test ("http:") || ex.test ("https:")) {
|
if (ex.test ("http:") || ex.test ("https:")) {
|
||||||
mp_delegate = new InputHttpStream (abstract_path);
|
mp_delegate = new InputHttpStream (abstract_path);
|
||||||
|
|
@ -165,15 +195,17 @@ InputStream::InputStream (const std::string &abstract_path)
|
||||||
#endif
|
#endif
|
||||||
if (ex.test ("pipe:")) {
|
if (ex.test ("pipe:")) {
|
||||||
mp_delegate = new InputPipe (ex.get ());
|
mp_delegate = new InputPipe (ex.get ());
|
||||||
} else
|
} else if (ex.test ("file:")) {
|
||||||
if (ex.test ("file:")) {
|
|
||||||
tl::URI uri (abstract_path);
|
tl::URI uri (abstract_path);
|
||||||
mp_delegate = new InputZLibFile (uri.path ());
|
mp_delegate = new InputZLibFile (uri.path ());
|
||||||
} else
|
} else {
|
||||||
{
|
|
||||||
mp_delegate = new InputZLibFile (abstract_path);
|
mp_delegate = new InputZLibFile (abstract_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! mp_buffer) {
|
||||||
|
mp_buffer = new char [m_bcap];
|
||||||
|
}
|
||||||
|
|
||||||
m_owns_delegate = true;
|
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
|
// TODO: align this implementation with InputStream ctor
|
||||||
|
|
||||||
tl::Extractor ex (abstract_path.c_str ());
|
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:")) {
|
if (ex.test ("http:") || ex.test ("https:")) {
|
||||||
return abstract_path;
|
return abstract_path;
|
||||||
} else if (ex.test ("pipe:")) {
|
} else
|
||||||
|
#endif
|
||||||
|
if (ex.test ("pipe:")) {
|
||||||
return abstract_path;
|
return abstract_path;
|
||||||
} else if (ex.test ("file:")) {
|
} else if (ex.test ("file:")) {
|
||||||
tl::URI uri (abstract_path);
|
tl::URI uri (abstract_path);
|
||||||
|
|
@ -247,7 +287,9 @@ InputStream::get (size_t n, bool bypass_inflate)
|
||||||
memmove (mp_buffer, mp_bptr, m_blen);
|
memmove (mp_buffer, mp_bptr, m_blen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mp_delegate) {
|
||||||
m_blen += mp_delegate->read (mp_buffer + m_blen, m_bcap - m_blen);
|
m_blen += mp_delegate->read (mp_buffer + m_blen, m_bcap - m_blen);
|
||||||
|
}
|
||||||
mp_bptr = mp_buffer;
|
mp_bptr = mp_buffer;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -313,7 +355,7 @@ void InputStream::copy_to(tl::OutputStream &os)
|
||||||
const size_t chunk = 65536;
|
const size_t chunk = 65536;
|
||||||
char b [chunk];
|
char b [chunk];
|
||||||
size_t read;
|
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);
|
os.put (b, read);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue