diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 00000000..3d3c5e69
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "ihp-sg13g2/libs.tech/digital"]
+ path = ihp-sg13g2/libs.tech/digital
+ url = git@github.com:hneemann/IHP130.git
diff --git a/README.md b/README.md
index 6ce32e99..7dc89ce6 100644
--- a/README.md
+++ b/README.md
@@ -39,10 +39,12 @@ backend option offers 5 thin metal layers, two thick metal layers (2 and 3 μm t
* SPICE Netlist
* Verilog
* IO cellset
+ * CDL
* GDSII
* LEF
- * Liberty (dummy)
+ * Liberty
* SPICE Netlist
+ * Verilog
* SRAM cellset
* CDL
* GDSII
@@ -53,13 +55,13 @@ backend option offers 5 thin metal layers, two thick metal layers (2 and 3 μm t
* GDSII
* KLayout tool data:
* layer property and tech files
- * DRC rules (minimal set)
- * PyCells
- * initial version of the wrapper API
- * sample cells
-* Pcells (for reference only) `libs.tech/pycell`
+ * DRC rules (minimal/maximal set)
+ * LVS rules
+ * PyCells (1st priority)
* MOS/HBT/Passive device models for ngspice/Xyce
* xschem: primitive device symbols, settings and testbenches
+* Qucs-S: primitive device symbols, settings and testbenches
+* Digital: stdcells
* OpenEMS: tutorials, scripts, documentation
* SG13G2 Process specification & Layout Rules
* MOS/HBT Measurements in MDM format
@@ -83,6 +85,10 @@ backend option offers 5 thin metal layers, two thick metal layers (2 and 3 μm t
* Source: https://github.com/KLayout/klayout
* OpenEMS
* Source: https://github.com/thliebig/openEMS-Project
+* OpenROAD
+ * Source: https://github.com/The-OpenROAD-Project/OpenROAD
+* OpenROAD-flow-scripts
+ * Source: https://github.com/The-OpenROAD-Project/OpenROAD-flow-scripts
## Contributing
diff --git a/ihp-sg13g2/libs.doc/doc/SG13G2_os_layout_rules.pdf b/ihp-sg13g2/libs.doc/doc/SG13G2_os_layout_rules.pdf
index 82d83d7b..8bd0fa79 100644
Binary files a/ihp-sg13g2/libs.doc/doc/SG13G2_os_layout_rules.pdf and b/ihp-sg13g2/libs.doc/doc/SG13G2_os_layout_rules.pdf differ
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/cdl/sg13g2_iocell.cdl b/ihp-sg13g2/libs.ref/sg13g2_io/cdl/sg13g2_io.cdl
similarity index 96%
rename from ihp-sg13g2/libs.ref/sg13g2_io/cdl/sg13g2_iocell.cdl
rename to ihp-sg13g2/libs.ref/sg13g2_io/cdl/sg13g2_io.cdl
index b01deb72..65b4f4c5 100644
--- a/ihp-sg13g2/libs.ref/sg13g2_io/cdl/sg13g2_iocell.cdl
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/cdl/sg13g2_io.cdl
@@ -28,7 +28,7 @@
.PARAM
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: DCNDiode
* View Name: schematic
************************************************************************
@@ -39,7 +39,7 @@ DD0 anode cathode dantenna m=1 w=1.26u l=27.78u a=35.003p p=58.08u
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: DCPDiode
* View Name: schematic
************************************************************************
@@ -50,7 +50,7 @@ DD0 anode cathode dpantenna m=1 w=1.26u l=27.78u a=35.003p p=58.08u
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: inv_x1
* View Name: schematic
************************************************************************
@@ -62,7 +62,7 @@ MP0 nq i vdd vdd sg13_lv_pmos m=1 w=4.41u l=130.00n ng=1
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: LevelUp
* View Name: schematic
************************************************************************
@@ -80,7 +80,7 @@ MP1 net4 net3 iovdd iovdd sg13_hv_pmos m=1 w=300.0n l=450.00n ng=1
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: nor2_x1
* View Name: schematic
************************************************************************
@@ -94,7 +94,7 @@ MP0 nq i1 net1 vdd sg13_lv_pmos m=1 w=4.41u l=130.00n ng=1
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: nand2_x1
* View Name: schematic
************************************************************************
@@ -108,7 +108,7 @@ MN0 nq i1 net1 vss sg13_lv_nmos m=1 w=3.93u l=130.00n ng=1
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: GateDecode
* View Name: schematic
************************************************************************
@@ -123,7 +123,7 @@ XI1 core en net2 vdd vss / nand2_x1
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: SecondaryProtection
* View Name: schematic
************************************************************************
@@ -136,7 +136,7 @@ DD1 core plus dpantenna m=1 w=780.00n l=4.98u a=3.884p p=11.52u
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: LevelDown
* View Name: schematic
************************************************************************
@@ -151,7 +151,7 @@ MP1 core net2 vdd vdd sg13_lv_pmos m=1 w=4.75u l=130.00n ng=1
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: sg13g2_IOPadInOut30mA
* View Name: schematic
************************************************************************
@@ -167,7 +167,7 @@ XI1 p2c iovdd iovss pad vdd vss / LevelDown
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: LevelUpInv
* View Name: schematic
************************************************************************
@@ -185,7 +185,7 @@ MP1 net4 net3 iovdd iovdd sg13_hv_pmos m=1 w=300.0n l=450.00n ng=1
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: GateLevelUpInv
* View Name: schematic
************************************************************************
@@ -197,7 +197,7 @@ XI0 core iovdd ngate vdd vss / LevelUpInv
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: sg13g2_IOPadOut4mA
* View Name: schematic
************************************************************************
@@ -212,7 +212,7 @@ XI3 iovss pad iovdd / DCNDiode
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: sg13g2_Filler10000
* View Name: schematic
************************************************************************
@@ -222,7 +222,7 @@ XI3 iovss pad iovdd / DCNDiode
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: sg13g2_IOPadVss
* View Name: schematic
************************************************************************
@@ -234,7 +234,7 @@ XI1 iovss vss iovss / DCNDiode
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: sg13g2_IOPadIOVss
* View Name: schematic
************************************************************************
@@ -246,7 +246,7 @@ DD1 iovss iovdd dpantenna m=1 w=1.26u l=27.78u a=35.003p p=58.08u
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: sg13g2_IOPadOut16mA
* View Name: schematic
************************************************************************
@@ -261,7 +261,7 @@ XI3 iovss pad iovdd / DCNDiode
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: RCClampResistor
* View Name: schematic
************************************************************************
@@ -331,7 +331,7 @@ RR0 pin1 net1 rppd 5.239K m=1 l=20u w=1u ps=180n trise=0.0
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: Clamp_N43N43D4R
* View Name: schematic
************************************************************************
@@ -513,7 +513,7 @@ MN0<172> pad gate tie tie sg13_hv_nmos m=1 w=4.4u l=600.0n ng=1
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: RCClampInverter
* View Name: schematic
************************************************************************
@@ -526,7 +526,7 @@ MP0 out in supply supply sg13_hv_pmos m=1 w=350.000u l=500.0n ng=50
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: sg13g2_IOPadIOVdd
* View Name: schematic
************************************************************************
@@ -539,7 +539,7 @@ XI1 net1 iovss net2 iovdd / RCClampInverter
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: sg13g2_IOPadTriOut30mA
* View Name: schematic
************************************************************************
@@ -554,7 +554,7 @@ XI3 iovss pad iovdd / DCNDiode
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: sg13g2_IOPadTriOut16mA
* View Name: schematic
************************************************************************
@@ -569,7 +569,7 @@ XI3 iovss pad iovdd / DCNDiode
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: sg13g2_IOPadInOut16mA
* View Name: schematic
************************************************************************
@@ -585,7 +585,7 @@ XI1 p2c iovdd iovss pad vdd vss / LevelDown
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: sg13g2_Filler200
* View Name: schematic
************************************************************************
@@ -595,7 +595,7 @@ XI1 p2c iovdd iovss pad vdd vss / LevelDown
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: sg13g2_Filler2000
* View Name: schematic
************************************************************************
@@ -605,7 +605,7 @@ XI1 p2c iovdd iovss pad vdd vss / LevelDown
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: sg13g2_IOPadOut30mA
* View Name: schematic
************************************************************************
@@ -620,7 +620,7 @@ XI3 iovss pad iovdd / DCNDiode
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: sg13g2_IOPadInOut4mA
* View Name: schematic
************************************************************************
@@ -636,7 +636,7 @@ XI1 p2c iovdd iovss pad vdd vss / LevelDown
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: Clamp_N20N0D
* View Name: schematic
************************************************************************
@@ -649,7 +649,7 @@ RR1 iovss net2 rppd 1.959K m=1 l=3.54u w=500n ps=180n
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: Clamp_P20N0D
* View Name: schematic
************************************************************************
@@ -662,7 +662,7 @@ RR0 net2 iovdd rppd 6.768K m=1 l=12.9u w=500n ps=180n
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: sg13g2_IOPadAnalog
* View Name: schematic
************************************************************************
@@ -677,7 +677,7 @@ XI6 padres iovss pad iovdd / SecondaryProtection
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: sg13g2_Filler4000
* View Name: schematic
************************************************************************
@@ -687,7 +687,7 @@ XI6 padres iovss pad iovdd / SecondaryProtection
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: sg13g2_Corner
* View Name: schematic
************************************************************************
@@ -697,7 +697,7 @@ XI6 padres iovss pad iovdd / SecondaryProtection
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: sg13g2_Filler400
* View Name: schematic
************************************************************************
@@ -707,7 +707,7 @@ XI6 padres iovss pad iovdd / SecondaryProtection
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: sg13g2_IOPadTriOut4mA
* View Name: schematic
************************************************************************
@@ -722,7 +722,7 @@ XI3 iovss pad iovdd / DCNDiode
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: sg13g2_IOPadIn
* View Name: schematic
************************************************************************
@@ -735,7 +735,7 @@ XI3 iovss pad iovdd / DCNDiode
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: sg13g2_IOPadVdd
* View Name: schematic
************************************************************************
@@ -747,7 +747,7 @@ DD0 iovss vdd dantenna m=1 w=1.26u l=27.78u a=35.003p p=58.08u
.ENDS
************************************************************************
-* Library Name: sg13g2_iocell
+* Library Name: sg13g2_io
* Cell Name: sg13g2_Filler1000
* View Name: schematic
************************************************************************
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/doc/README.md b/ihp-sg13g2/libs.ref/sg13g2_io/doc/README.md
index 7d4e03b8..e31ab247 100644
--- a/ihp-sg13g2/libs.ref/sg13g2_io/doc/README.md
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/doc/README.md
@@ -14,7 +14,7 @@ This is the sg13g2_io library. The following files are included in this library:
These files are generated from python scripts of the Chips4Makers based IHP SG13G2
PDK. The code can be found in the
[c4m-pdk-ihpsg13g2](https://gitlab.com/Chips4Makers/c4m-pdk-ihpsg13g2.git) repo.
-This library is built from version `0.0.3` of that source code.
+This library is built from version `0.0.4` of that source code.
The `README.md` file of this project explains how to use the code in there. The whole
build of the files plus preparation of the files described above for upstreaming can be
generated with the command `pdm doit patch4upstream`.
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/gds/sg13g2_io.gds b/ihp-sg13g2/libs.ref/sg13g2_io/gds/sg13g2_io.gds
index efc29676..fc12e448 100644
Binary files a/ihp-sg13g2/libs.ref/sg13g2_io/gds/sg13g2_io.gds and b/ihp-sg13g2/libs.ref/sg13g2_io/gds/sg13g2_io.gds differ
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/liberty/sg13g2_io_dummy.lib b/ihp-sg13g2/libs.ref/sg13g2_io/lib/sg13g2_io_dummy.lib
similarity index 100%
rename from ihp-sg13g2/libs.ref/sg13g2_io/liberty/sg13g2_io_dummy.lib
rename to ihp-sg13g2/libs.ref/sg13g2_io/lib/sg13g2_io_dummy.lib
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/liberty/sg13g2_iocell_fast_1p32V_3p6V_m40C.lib b/ihp-sg13g2/libs.ref/sg13g2_io/lib/sg13g2_io_fast_1p32V_3p6V_m40C.lib
similarity index 99%
rename from ihp-sg13g2/libs.ref/sg13g2_io/liberty/sg13g2_iocell_fast_1p32V_3p6V_m40C.lib
rename to ihp-sg13g2/libs.ref/sg13g2_io/lib/sg13g2_io_fast_1p32V_3p6V_m40C.lib
index e14472e7..c42ff8c0 100644
--- a/ihp-sg13g2/libs.ref/sg13g2_io/liberty/sg13g2_iocell_fast_1p32V_3p6V_m40C.lib
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/lib/sg13g2_io_fast_1p32V_3p6V_m40C.lib
@@ -16,7 +16,7 @@
************************************************************************/
-library (sg13g2_iocell_fast_1p32V_3p6V_m40C) {
+library (sg13g2_io_fast_1p32V_3p6V_m40C) {
comment : "IHP Microelectronics GmbH, 2024";
date : "$Date: Wed May 8 12:23:04 2024 $";
revision : "$Revision: 0.0.1 $";
@@ -60,7 +60,7 @@ library (sg13g2_iocell_fast_1p32V_3p6V_m40C) {
slew_lower_threshold_pct_rise : 10;
slew_upper_threshold_pct_fall : 90;
slew_upper_threshold_pct_rise : 90;
- operating_conditions (sg13g2_iocell_fast_1p32V_3p6V_m40C) {
+ operating_conditions (sg13g2_io_fast_1p32V_3p6V_m40C) {
process : 1;
temperature : -40;
voltage : 1.32;
@@ -211,7 +211,7 @@ library (sg13g2_iocell_fast_1p32V_3p6V_m40C) {
wire_load_from_area (1.27008e+06, 3.1752e+06, 500k);
}
default_wire_load : "1k";
- default_operating_conditions : sg13g2_iocell_fast_1p32V_3p6V_m40C;
+ default_operating_conditions : sg13g2_io_fast_1p32V_3p6V_m40C;
default_wire_load_selection : "4_metls_routing";
lu_table_template (delay_template_7x6_16) {
variable_1 : input_net_transition;
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/liberty/sg13g2_iocell_fast_1p65V_3p6V_m40C.lib b/ihp-sg13g2/libs.ref/sg13g2_io/lib/sg13g2_io_fast_1p65V_3p6V_m40C.lib
similarity index 99%
rename from ihp-sg13g2/libs.ref/sg13g2_io/liberty/sg13g2_iocell_fast_1p65V_3p6V_m40C.lib
rename to ihp-sg13g2/libs.ref/sg13g2_io/lib/sg13g2_io_fast_1p65V_3p6V_m40C.lib
index 0dec04d2..a8d38e28 100644
--- a/ihp-sg13g2/libs.ref/sg13g2_io/liberty/sg13g2_iocell_fast_1p65V_3p6V_m40C.lib
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/lib/sg13g2_io_fast_1p65V_3p6V_m40C.lib
@@ -16,7 +16,7 @@
************************************************************************/
-library (sg13g2_iocell_fast_1p65V_3p6V_m40C) {
+library (sg13g2_io_fast_1p65V_3p6V_m40C) {
comment : "IHP Microelectronics GmbH, 2024";
date : "$Date: Wed May 8 12:28:37 2024 $";
revision : "$Revision: 0.0.1 $";
@@ -60,7 +60,7 @@ library (sg13g2_iocell_fast_1p65V_3p6V_m40C) {
slew_lower_threshold_pct_rise : 10;
slew_upper_threshold_pct_fall : 90;
slew_upper_threshold_pct_rise : 90;
- operating_conditions (sg13g2_iocell_fast_1p65V_3p6V_m40C) {
+ operating_conditions (sg13g2_io_fast_1p65V_3p6V_m40C) {
process : 1;
temperature : -40;
voltage : 1.65;
@@ -211,7 +211,7 @@ library (sg13g2_iocell_fast_1p65V_3p6V_m40C) {
wire_load_from_area (1.27008e+06, 3.1752e+06, 500k);
}
default_wire_load : "1k";
- default_operating_conditions : sg13g2_iocell_fast_1p65V_3p6V_m40C;
+ default_operating_conditions : sg13g2_io_fast_1p65V_3p6V_m40C;
default_wire_load_selection : "4_metls_routing";
lu_table_template (delay_template_7x6_16) {
variable_1 : input_net_transition;
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/liberty/sg13g2_iocell_slow_1p08V_3p0V_125C.lib b/ihp-sg13g2/libs.ref/sg13g2_io/lib/sg13g2_io_slow_1p08V_3p0V_125C.lib
similarity index 99%
rename from ihp-sg13g2/libs.ref/sg13g2_io/liberty/sg13g2_iocell_slow_1p08V_3p0V_125C.lib
rename to ihp-sg13g2/libs.ref/sg13g2_io/lib/sg13g2_io_slow_1p08V_3p0V_125C.lib
index c38f5a01..64cb1db0 100644
--- a/ihp-sg13g2/libs.ref/sg13g2_io/liberty/sg13g2_iocell_slow_1p08V_3p0V_125C.lib
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/lib/sg13g2_io_slow_1p08V_3p0V_125C.lib
@@ -16,7 +16,7 @@
************************************************************************/
-library (sg13g2_iocell_slow_1p08V_3p0V_125C) {
+library (sg13g2_io_slow_1p08V_3p0V_125C) {
comment : "IHP Microelectronics GmbH, 2024";
date : "$Date: Wed May 8 12:21:14 2024 $";
revision : "$Revision: 0.0.1 $";
@@ -60,7 +60,7 @@ library (sg13g2_iocell_slow_1p08V_3p0V_125C) {
slew_lower_threshold_pct_rise : 10;
slew_upper_threshold_pct_fall : 90;
slew_upper_threshold_pct_rise : 90;
- operating_conditions (sg13g2_iocell_slow_1p08V_3p0V_125C) {
+ operating_conditions (sg13g2_io_slow_1p08V_3p0V_125C) {
process : 1;
temperature : 125;
voltage : 1.08;
@@ -211,7 +211,7 @@ library (sg13g2_iocell_slow_1p08V_3p0V_125C) {
wire_load_from_area (1.27008e+06, 3.1752e+06, 500k);
}
default_wire_load : "1k";
- default_operating_conditions : sg13g2_iocell_slow_1p08V_3p0V_125C;
+ default_operating_conditions : sg13g2_io_slow_1p08V_3p0V_125C;
default_wire_load_selection : "4_metls_routing";
lu_table_template (delay_template_7x6_16) {
variable_1 : input_net_transition;
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/liberty/sg13g2_iocell_slow_1p35V_3p0V_125C.lib b/ihp-sg13g2/libs.ref/sg13g2_io/lib/sg13g2_io_slow_1p35V_3p0V_125C.lib
similarity index 99%
rename from ihp-sg13g2/libs.ref/sg13g2_io/liberty/sg13g2_iocell_slow_1p35V_3p0V_125C.lib
rename to ihp-sg13g2/libs.ref/sg13g2_io/lib/sg13g2_io_slow_1p35V_3p0V_125C.lib
index 873c69b2..4f59f148 100644
--- a/ihp-sg13g2/libs.ref/sg13g2_io/liberty/sg13g2_iocell_slow_1p35V_3p0V_125C.lib
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/lib/sg13g2_io_slow_1p35V_3p0V_125C.lib
@@ -16,7 +16,7 @@
************************************************************************/
-library (sg13g2_iocell_slow_1p35V_3p0V_125C) {
+library (sg13g2_io_slow_1p35V_3p0V_125C) {
comment : "IHP Microelectronics GmbH, 2024";
date : "$Date: Wed May 8 12:26:45 2024 $";
revision : "$Revision: 0.0.1 $";
@@ -60,7 +60,7 @@ library (sg13g2_iocell_slow_1p35V_3p0V_125C) {
slew_lower_threshold_pct_rise : 10;
slew_upper_threshold_pct_fall : 90;
slew_upper_threshold_pct_rise : 90;
- operating_conditions (sg13g2_iocell_slow_1p35V_3p0V_125C) {
+ operating_conditions (sg13g2_io_slow_1p35V_3p0V_125C) {
process : 1;
temperature : 125;
voltage : 1.35;
@@ -211,7 +211,7 @@ library (sg13g2_iocell_slow_1p35V_3p0V_125C) {
wire_load_from_area (1.27008e+06, 3.1752e+06, 500k);
}
default_wire_load : "1k";
- default_operating_conditions : sg13g2_iocell_slow_1p35V_3p0V_125C;
+ default_operating_conditions : sg13g2_io_slow_1p35V_3p0V_125C;
default_wire_load_selection : "4_metls_routing";
lu_table_template (delay_template_7x6_16) {
variable_1 : input_net_transition;
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/liberty/sg13g2_iocell_typ_1p2V_3p3V_25C.lib b/ihp-sg13g2/libs.ref/sg13g2_io/lib/sg13g2_io_typ_1p2V_3p3V_25C.lib
similarity index 99%
rename from ihp-sg13g2/libs.ref/sg13g2_io/liberty/sg13g2_iocell_typ_1p2V_3p3V_25C.lib
rename to ihp-sg13g2/libs.ref/sg13g2_io/lib/sg13g2_io_typ_1p2V_3p3V_25C.lib
index 95d0b633..ba6b43f6 100644
--- a/ihp-sg13g2/libs.ref/sg13g2_io/liberty/sg13g2_iocell_typ_1p2V_3p3V_25C.lib
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/lib/sg13g2_io_typ_1p2V_3p3V_25C.lib
@@ -16,7 +16,7 @@
************************************************************************/
-library (sg13g2_iocell_typ_1p2V_3p3V_25C) {
+library (sg13g2_io_typ_1p2V_3p3V_25C) {
comment : "IHP Microelectronics GmbH, 2024";
date : "$Date: Wed May 8 12:19:26 2024 $";
revision : "$Revision: 0.0.1 $";
@@ -60,7 +60,7 @@ library (sg13g2_iocell_typ_1p2V_3p3V_25C) {
slew_lower_threshold_pct_rise : 10;
slew_upper_threshold_pct_fall : 90;
slew_upper_threshold_pct_rise : 90;
- operating_conditions (sg13g2_iocell_typ_1p2V_3p3V_25C) {
+ operating_conditions (sg13g2_io_typ_1p2V_3p3V_25C) {
process : 1;
temperature : 25;
voltage : 1.2;
@@ -211,7 +211,7 @@ library (sg13g2_iocell_typ_1p2V_3p3V_25C) {
wire_load_from_area (1.27008e+06, 3.1752e+06, 500k);
}
default_wire_load : "1k";
- default_operating_conditions : sg13g2_iocell_typ_1p2V_3p3V_25C;
+ default_operating_conditions : sg13g2_io_typ_1p2V_3p3V_25C;
default_wire_load_selection : "4_metls_routing";
lu_table_template (delay_template_7x6_16) {
variable_1 : input_net_transition;
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/liberty/sg13g2_iocell_typ_1p5V_3p3V_25C.lib b/ihp-sg13g2/libs.ref/sg13g2_io/lib/sg13g2_io_typ_1p5V_3p3V_25C.lib
similarity index 99%
rename from ihp-sg13g2/libs.ref/sg13g2_io/liberty/sg13g2_iocell_typ_1p5V_3p3V_25C.lib
rename to ihp-sg13g2/libs.ref/sg13g2_io/lib/sg13g2_io_typ_1p5V_3p3V_25C.lib
index dc44abb4..73e301b7 100644
--- a/ihp-sg13g2/libs.ref/sg13g2_io/liberty/sg13g2_iocell_typ_1p5V_3p3V_25C.lib
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/lib/sg13g2_io_typ_1p5V_3p3V_25C.lib
@@ -16,7 +16,7 @@
************************************************************************/
-library (sg13g2_iocell_typ_1p5V_3p3V_25C) {
+library (sg13g2_io_typ_1p5V_3p3V_25C) {
comment : "IHP Microelectronics GmbH, 2024";
date : "$Date: Wed May 8 12:24:55 2024 $";
revision : "$Revision: 0.0.1 $";
@@ -60,7 +60,7 @@ library (sg13g2_iocell_typ_1p5V_3p3V_25C) {
slew_lower_threshold_pct_rise : 10;
slew_upper_threshold_pct_fall : 90;
slew_upper_threshold_pct_rise : 90;
- operating_conditions (sg13g2_iocell_typ_1p5V_3p3V_25C) {
+ operating_conditions (sg13g2_io_typ_1p5V_3p3V_25C) {
process : 1;
temperature : 25;
voltage : 1.5;
@@ -211,7 +211,7 @@ library (sg13g2_iocell_typ_1p5V_3p3V_25C) {
wire_load_from_area (1.27008e+06, 3.1752e+06, 500k);
}
default_wire_load : "1k";
- default_operating_conditions : sg13g2_iocell_typ_1p5V_3p3V_25C;
+ default_operating_conditions : sg13g2_io_typ_1p5V_3p3V_25C;
default_wire_load_selection : "4_metls_routing";
lu_table_template (delay_template_7x6_16) {
variable_1 : input_net_transition;
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/spice/sg13g2_io.spi b/ihp-sg13g2/libs.ref/sg13g2_io/spice/sg13g2_io.spi
index 254f4b0f..eda69a71 100644
--- a/ihp-sg13g2/libs.ref/sg13g2_io/spice/sg13g2_io.spi
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/spice/sg13g2_io.spi
@@ -1,7 +1,7 @@
* sg13g2_io
* Autogenerated file; please don't edit
-* date: 2024-05-06 15:00:13.438920
+* date: 2024-05-27 14:30:57.050559
************************************************************************
*
@@ -356,7 +356,7 @@ Xclamp_g42_r2 iovss gate pad iovss sg13_hv_nmos l=0.6um w=4.4um
Xclamp_g42_r3 iovss gate pad iovss sg13_hv_nmos l=0.6um w=4.4um
XOuterRing iovdd sg13g2_GuardRing_N16000W4884HFF
XInnerRing iovss sg13g2_GuardRing_P15280W4164HFF
-XDGATE iovss gate dantenna l=0.64um w=0.3um
+XDGATE iovss gate dantenna l=0.64um w=0.48um
.ends sg13g2_Clamp_N43N43D4R
* sg13g2_RCClampResistor
@@ -481,11 +481,17 @@ Xpmos49_r0 out in supply supply sg13_hv_pmos l=0.5um w=7.0um
Xpmosguardring supply sg13g2_GuardRing_N9472W2216HTT
.ends sg13g2_RCClampInverter
+* sg13g2_GuardRing_N16000W6624HFF
+.subckt sg13g2_GuardRing_N16000W6624HFF conn
+
+.ends sg13g2_GuardRing_N16000W6624HFF
+
* sg13g2_IOPadVdd
.subckt sg13g2_IOPadVdd vss vdd iovss iovdd
Xnclamp iovss iovdd vdd ngate sg13g2_Clamp_N43N43D4R
Xrcres vdd res_cap sg13g2_RCClampResistor
Xrcinv vdd iovss res_cap ngate sg13g2_RCClampInverter
+Xpad_guard iovss sg13g2_GuardRing_N16000W6624HFF
.ends sg13g2_IOPadVdd
* sg13g2_IOPadIn
@@ -511,7 +517,7 @@ Xclamp_g0 iovss gate pad iovss sg13_hv_nmos l=0.6um w=4.4um
Xclamp_g1 pad gate iovss iovss sg13_hv_nmos l=0.6um w=4.4um
XOuterRing iovdd sg13g2_GuardRing_N16000W1980HFF
XInnerRing iovss sg13g2_GuardRing_P15280W1260HFF
-XDGATE iovss gate dantenna l=0.64um w=0.3um
+XDGATE iovss gate dantenna l=0.64um w=0.48um
.ends sg13g2_Clamp_N2N2D
* sg13g2_GuardRing_P16000W3852HFF
@@ -532,7 +538,7 @@ Xclamp_g1_r0 pad gate iovdd iovdd sg13_hv_pmos l=0.6um w=6.66um
Xclamp_g1_r1 pad gate iovdd iovdd sg13_hv_pmos l=0.6um w=6.66um
XOuterRing iovss sg13g2_GuardRing_P16000W3852HFF
XInnerRing iovdd sg13g2_GuardRing_N15280W3132HTF
-XDGATE gate iovdd dpantenna l=0.64um w=0.3um
+XDGATE gate iovdd dpantenna l=0.64um w=0.48um
.ends sg13g2_Clamp_P2N2D
* sg13g2_LevelUpInv
@@ -574,7 +580,7 @@ Xclamp_g6 iovss gate pad iovss sg13_hv_nmos l=0.6um w=4.4um
Xclamp_g7 pad gate iovss iovss sg13_hv_nmos l=0.6um w=4.4um
XOuterRing iovdd sg13g2_GuardRing_N16000W1980HFF
XInnerRing iovss sg13g2_GuardRing_P15280W1260HFF
-XDGATE iovss gate dantenna l=0.64um w=0.3um
+XDGATE iovss gate dantenna l=0.64um w=0.48um
.ends sg13g2_Clamp_N8N8D
* sg13g2_Clamp_P8N8D
@@ -597,7 +603,7 @@ Xclamp_g7_r0 pad gate iovdd iovdd sg13_hv_pmos l=0.6um w=6.66um
Xclamp_g7_r1 pad gate iovdd iovdd sg13_hv_pmos l=0.6um w=6.66um
XOuterRing iovss sg13g2_GuardRing_P16000W3852HFF
XInnerRing iovdd sg13g2_GuardRing_N15280W3132HTF
-XDGATE gate iovdd dpantenna l=0.64um w=0.3um
+XDGATE gate iovdd dpantenna l=0.64um w=0.48um
.ends sg13g2_Clamp_P8N8D
* sg13g2_IOPadOut16mA
@@ -628,7 +634,7 @@ Xclamp_g13 pad gate iovss iovss sg13_hv_nmos l=0.6um w=4.4um
Xclamp_g14 iovss gate pad iovss sg13_hv_nmos l=0.6um w=4.4um
XOuterRing iovdd sg13g2_GuardRing_N16000W1980HFF
XInnerRing iovss sg13g2_GuardRing_P15280W1260HFF
-XDGATE iovss gate dantenna l=0.64um w=0.3um
+XDGATE iovss gate dantenna l=0.64um w=0.48um
.ends sg13g2_Clamp_N15N15D
* sg13g2_Clamp_P15N15D
@@ -665,7 +671,7 @@ Xclamp_g14_r0 iovdd gate pad iovdd sg13_hv_pmos l=0.6um w=6.66um
Xclamp_g14_r1 iovdd gate pad iovdd sg13_hv_pmos l=0.6um w=6.66um
XOuterRing iovss sg13g2_GuardRing_P16000W3852HFF
XInnerRing iovdd sg13g2_GuardRing_N15280W3132HTF
-XDGATE gate iovdd dpantenna l=0.64um w=0.3um
+XDGATE gate iovdd dpantenna l=0.64um w=0.48um
.ends sg13g2_Clamp_P15N15D
* sg13g2_IOPadOut30mA
@@ -740,11 +746,6 @@ Xdcndiode iovss iovss iovdd sg13g2_DCNDiode
Xdcpdiode iovss iovdd iovss sg13g2_DCPDiode
.ends sg13g2_IOPadIOVss
-* sg13g2_GuardRing_N16000W6624HFF
-.subckt sg13g2_GuardRing_N16000W6624HFF conn
-
-.ends sg13g2_GuardRing_N16000W6624HFF
-
* sg13g2_IOPadIOVdd
.subckt sg13g2_IOPadIOVdd vss vdd iovss iovdd
Xnclamp iovss iovdd iovdd ngate sg13g2_Clamp_N43N43D4R
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N15N15D.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N15N15D.sch
new file mode 100644
index 00000000..071c6cda
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N15N15D.sch
@@ -0,0 +1,425 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N -240 -590 -240 -560 {
+lab=xxx}
+N 1480 -560 1580 -560 {
+lab=xxx}
+N 1580 -590 1580 -560 {
+lab=xxx}
+N -110 -590 -110 -560 {
+lab=xxx}
+N -210 -560 -110 -560 {
+lab=xxx}
+N 20 -590 20 -560 {
+lab=xxx}
+N -80 -560 20 -560 {
+lab=xxx}
+N 150 -590 150 -560 {
+lab=xxx}
+N 50 -560 150 -560 {
+lab=xxx}
+N 280 -590 280 -560 {
+lab=xxx}
+N 210 -560 280 -560 {
+lab=xxx}
+N 410 -590 410 -560 {
+lab=xxx}
+N 310 -560 410 -560 {
+lab=xxx}
+N 540 -590 540 -560 {
+lab=xxx}
+N 440 -560 540 -560 {
+lab=xxx}
+N 670 -590 670 -560 {
+lab=xxx}
+N 570 -560 670 -560 {
+lab=xxx}
+N 800 -590 800 -560 {
+lab=xxx}
+N 700 -560 800 -560 {
+lab=xxx}
+N 930 -590 930 -560 {
+lab=xxx}
+N 830 -560 930 -560 {
+lab=xxx}
+N 1060 -590 1060 -560 {
+lab=xxx}
+N 960 -560 1060 -560 {
+lab=xxx}
+N 1190 -590 1190 -560 {
+lab=xxx}
+N 1090 -560 1190 -560 {
+lab=xxx}
+N 1320 -590 1320 -560 {
+lab=xxx}
+N 1220 -560 1320 -560 {
+lab=xxx}
+N 1450 -590 1450 -560 {
+lab=xxx}
+N 1350 -560 1450 -560 {
+lab=xxx}
+N -240 -620 -210 -620 {
+lab=xxx}
+N -210 -620 -210 -560 {
+lab=xxx}
+N -240 -560 -210 -560 {
+lab=xxx}
+N -110 -620 -80 -620 {
+lab=xxx}
+N -80 -620 -80 -560 {
+lab=xxx}
+N -110 -560 -80 -560 {
+lab=xxx}
+N 20 -620 50 -620 {
+lab=xxx}
+N 50 -620 50 -560 {
+lab=xxx}
+N 20 -560 50 -560 {
+lab=xxx}
+N 150 -620 180 -620 {
+lab=xxx}
+N 180 -620 180 -560 {
+lab=xxx}
+N 150 -560 180 -560 {
+lab=xxx}
+N 280 -620 310 -620 {
+lab=xxx}
+N 310 -620 310 -560 {
+lab=xxx}
+N 280 -560 310 -560 {
+lab=xxx}
+N 410 -620 440 -620 {
+lab=xxx}
+N 440 -620 440 -560 {
+lab=xxx}
+N 410 -560 440 -560 {
+lab=xxx}
+N 540 -620 570 -620 {
+lab=xxx}
+N 570 -620 570 -560 {
+lab=xxx}
+N 540 -560 570 -560 {
+lab=xxx}
+N 1580 -620 1610 -620 {
+lab=xxx}
+N 1610 -620 1610 -560 {
+lab=xxx}
+N 1580 -560 1610 -560 {
+lab=xxx}
+N 1450 -620 1480 -620 {
+lab=xxx}
+N 1480 -620 1480 -560 {
+lab=xxx}
+N 1450 -560 1480 -560 {
+lab=xxx}
+N 1320 -620 1350 -620 {
+lab=xxx}
+N 1350 -620 1350 -560 {
+lab=xxx}
+N 1320 -560 1350 -560 {
+lab=xxx}
+N 1190 -620 1220 -620 {
+lab=xxx}
+N 1220 -620 1220 -560 {
+lab=xxx}
+N 1190 -560 1220 -560 {
+lab=xxx}
+N 1060 -620 1090 -620 {
+lab=xxx}
+N 1090 -620 1090 -560 {
+lab=xxx}
+N 1060 -560 1090 -560 {
+lab=xxx}
+N 930 -620 960 -620 {
+lab=xxx}
+N 960 -620 960 -560 {
+lab=xxx}
+N 930 -560 960 -560 {
+lab=xxx}
+N 800 -620 830 -620 {
+lab=xxx}
+N 830 -620 830 -560 {
+lab=xxx}
+N 800 -560 830 -560 {
+lab=xxx}
+N 670 -620 700 -620 {
+lab=xxx}
+N 700 -620 700 -560 {
+lab=xxx}
+N 670 -560 700 -560 {
+lab=xxx}
+N -240 -690 -240 -650 {
+lab=pad}
+N 1450 -690 1580 -690 {
+lab=pad}
+N 1580 -690 1580 -650 {
+lab=pad}
+N 1450 -690 1450 -650 {
+lab=pad}
+N 1320 -690 1450 -690 {
+lab=pad}
+N 1320 -690 1320 -650 {
+lab=pad}
+N 1190 -690 1320 -690 {
+lab=pad}
+N 1190 -690 1190 -650 {
+lab=pad}
+N 1060 -690 1190 -690 {
+lab=pad}
+N 1060 -690 1060 -650 {
+lab=pad}
+N 930 -690 1060 -690 {
+lab=pad}
+N 930 -690 930 -650 {
+lab=pad}
+N 800 -690 930 -690 {
+lab=pad}
+N 800 -690 800 -650 {
+lab=pad}
+N 670 -690 800 -690 {
+lab=pad}
+N 670 -690 670 -650 {
+lab=pad}
+N 540 -690 670 -690 {
+lab=pad}
+N 540 -690 540 -650 {
+lab=pad}
+N 410 -690 540 -690 {
+lab=pad}
+N 410 -690 410 -650 {
+lab=pad}
+N 280 -690 410 -690 {
+lab=pad}
+N 280 -690 280 -650 {
+lab=pad}
+N 150 -690 280 -690 {
+lab=pad}
+N 150 -690 150 -650 {
+lab=pad}
+N 130 -690 150 -690 {
+lab=pad}
+N -320 -620 -280 -620 {
+lab=gate}
+N -320 -620 -320 -500 {
+lab=gate}
+N -400 -620 -320 -620 {
+lab=gate}
+N 1410 -500 1540 -500 {
+lab=gate}
+N 1540 -620 1540 -500 {
+lab=gate}
+N 1410 -620 1410 -500 {
+lab=gate}
+N 1280 -500 1410 -500 {
+lab=gate}
+N 1280 -620 1280 -500 {
+lab=gate}
+N 1150 -500 1280 -500 {
+lab=gate}
+N 1150 -620 1150 -500 {
+lab=gate}
+N 1020 -500 1150 -500 {
+lab=gate}
+N 1020 -620 1020 -500 {
+lab=gate}
+N 890 -500 1020 -500 {
+lab=gate}
+N 890 -620 890 -500 {
+lab=gate}
+N 760 -500 890 -500 {
+lab=gate}
+N 760 -620 760 -500 {
+lab=gate}
+N 630 -500 760 -500 {
+lab=gate}
+N 630 -620 630 -500 {
+lab=gate}
+N 500 -500 630 -500 {
+lab=gate}
+N 500 -620 500 -500 {
+lab=gate}
+N 370 -500 500 -500 {
+lab=gate}
+N 370 -620 370 -500 {
+lab=gate}
+N 240 -500 370 -500 {
+lab=gate}
+N 240 -620 240 -500 {
+lab=gate}
+N 140 -500 240 -500 {
+lab=gate}
+N 110 -620 110 -500 {
+lab=gate}
+N -20 -500 110 -500 {
+lab=gate}
+N -20 -620 -20 -500 {
+lab=gate}
+N -150 -500 -20 -500 {
+lab=gate}
+N -150 -620 -150 -500 {
+lab=gate}
+N -320 -500 -150 -500 {
+lab=gate}
+N -110 -690 -110 -650 {
+lab=pad}
+N -240 -690 -110 -690 {
+lab=pad}
+N 20 -690 20 -650 {
+lab=pad}
+N -110 -690 20 -690 {
+lab=pad}
+N 130 -810 130 -690 {
+lab=pad}
+N 20 -690 130 -690 {
+lab=pad}
+N 210 -380 210 -340 {
+lab=xxx}
+N 180 -560 210 -560 {
+lab=xxx}
+N 140 -410 140 -380 {
+lab=xxx}
+N 140 -380 210 -380 {
+lab=xxx}
+N 210 -560 210 -380 {
+lab=xxx}
+N 140 -500 140 -470 {
+lab=gate}
+N 110 -500 140 -500 {
+lab=gate}
+N 340 -810 340 -760 {
+lab=iovdd}
+C {sg13g2_pr/sg13_hv_nmos.sym} 520 -620 2 1 {name=M1
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 650 -620 2 1 {name=M2
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 780 -620 2 1 {name=M3
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 910 -620 2 1 {name=M4
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 390 -620 2 1 {name=M5
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1170 -620 2 1 {name=M6
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1300 -620 2 1 {name=M7
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1430 -620 2 1 {name=M8
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1560 -620 2 1 {name=M9
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1040 -620 2 1 {name=M10
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -130 -620 2 1 {name=M11
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 0 -620 2 1 {name=M12
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 130 -620 2 1 {name=M13
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 260 -620 2 1 {name=M14
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -260 -620 2 1 {name=M15
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/dantenna.sym} 140 -440 0 0 {name=D1
+model=dantenna
+l=0.64u
+w=0.3u
+spiceprefix=X
+}
+C {devices/iopin.sym} 210 -340 1 0 {name=iovss lab=iovss}
+C {devices/iopin.sym} -400 -620 2 0 {name=gate lab=gate}
+C {devices/iopin.sym} 130 -810 3 0 {name=pad lab=pad}
+C {devices/iopin.sym} 340 -810 3 0 {name=iovdd lab=iovdd}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N15N15D.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N15N15D.sym
new file mode 100644
index 00000000..8b486b84
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N15N15D.sym
@@ -0,0 +1,28 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -40 130 -40 {}
+L 4 -130 40 130 40 {}
+L 4 -130 -40 -130 40 {}
+L 4 130 -40 130 40 {}
+L 7 0 -60 0 -40 {}
+L 7 130 0 150 0 {}
+L 7 -150 0 -130 0 {}
+L 7 0 40 0 60 {}
+B 5 -2.5 -62.5 2.5 -57.5 {name=iovdd dir=inout}
+B 5 147.5 -2.5 152.5 2.5 {name=pad dir=inout}
+B 5 -152.5 -2.5 -147.5 2.5 {name=gate dir=inout}
+B 5 -2.5 57.5 2.5 62.5 {name=iovss dir=inout}
+T {sg13g2_Clamp_N15N15D} -68 -6 0 0 0.2 0.2 {}
+T {@name} 135 -52 0 0 0.2 0.2 {}
+T {iovdd} 15 -34 0 1 0.2 0.2 {}
+T {pad} 125 -4 0 1 0.2 0.2 {}
+T {gate} -105 -4 0 1 0.2 0.2 {}
+T {iovss} 15 26 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N20N0D.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N20N0D.sch
new file mode 100644
index 00000000..0387d50c
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N20N0D.sch
@@ -0,0 +1,592 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 1670 -70 1670 -40 {
+lab=iovss}
+N 4010 -40 4140 -40 {
+lab=iovss}
+N 4140 -60 4140 -40 {
+lab=iovss}
+N 4140 -120 4170 -120 {
+lab=iovss}
+N 4170 -120 4170 -60 {
+lab=iovss}
+N 4140 -60 4170 -60 {
+lab=iovss}
+N 4140 -90 4140 -60 {
+lab=iovss}
+N 4010 -70 4010 -40 {
+lab=iovss}
+N 3870 -40 4010 -40 {
+lab=iovss}
+N 4010 -120 4040 -120 {
+lab=iovss}
+N 4040 -120 4040 -70 {
+lab=iovss}
+N 4010 -70 4040 -70 {
+lab=iovss}
+N 4010 -90 4010 -70 {
+lab=iovss}
+N 3870 -70 3870 -40 {
+lab=iovss}
+N 3750 -40 3870 -40 {
+lab=iovss}
+N 3870 -120 3900 -120 {
+lab=iovss}
+N 3900 -120 3900 -70 {
+lab=iovss}
+N 3870 -70 3900 -70 {
+lab=iovss}
+N 3870 -90 3870 -70 {
+lab=iovss}
+N 3750 -60 3750 -40 {
+lab=iovss}
+N 3620 -40 3750 -40 {
+lab=iovss}
+N 3750 -120 3780 -120 {
+lab=iovss}
+N 3780 -120 3780 -60 {
+lab=iovss}
+N 3750 -60 3780 -60 {
+lab=iovss}
+N 3750 -90 3750 -60 {
+lab=iovss}
+N 3620 -70 3620 -40 {
+lab=iovss}
+N 3490 -40 3620 -40 {
+lab=iovss}
+N 3620 -120 3650 -120 {
+lab=iovss}
+N 3650 -120 3650 -70 {
+lab=iovss}
+N 3620 -70 3650 -70 {
+lab=iovss}
+N 3620 -90 3620 -70 {
+lab=iovss}
+N 3490 -70 3490 -40 {
+lab=iovss}
+N 3360 -40 3490 -40 {
+lab=iovss}
+N 3490 -120 3520 -120 {
+lab=iovss}
+N 3520 -120 3520 -70 {
+lab=iovss}
+N 3490 -70 3520 -70 {
+lab=iovss}
+N 3490 -90 3490 -70 {
+lab=iovss}
+N 3360 -60 3360 -40 {
+lab=iovss}
+N 3230 -40 3360 -40 {
+lab=iovss}
+N 3360 -120 3380 -120 {
+lab=iovss}
+N 3380 -120 3380 -60 {
+lab=iovss}
+N 3360 -60 3380 -60 {
+lab=iovss}
+N 3360 -90 3360 -60 {
+lab=iovss}
+N 3230 -70 3230 -40 {
+lab=iovss}
+N 3100 -40 3230 -40 {
+lab=iovss}
+N 3230 -120 3260 -120 {
+lab=iovss}
+N 3260 -120 3260 -70 {
+lab=iovss}
+N 3230 -70 3260 -70 {
+lab=iovss}
+N 3230 -90 3230 -70 {
+lab=iovss}
+N 3100 -60 3100 -40 {
+lab=iovss}
+N 2970 -40 3100 -40 {
+lab=iovss}
+N 3100 -120 3130 -120 {
+lab=iovss}
+N 3130 -120 3130 -60 {
+lab=iovss}
+N 3100 -60 3130 -60 {
+lab=iovss}
+N 3100 -90 3100 -60 {
+lab=iovss}
+N 2970 -70 2970 -40 {
+lab=iovss}
+N 2840 -40 2970 -40 {
+lab=iovss}
+N 2970 -120 3000 -120 {
+lab=iovss}
+N 3000 -120 3000 -70 {
+lab=iovss}
+N 2970 -70 3000 -70 {
+lab=iovss}
+N 2970 -90 2970 -70 {
+lab=iovss}
+N 1800 -60 1800 -40 {
+lab=iovss}
+N 1730 -40 1800 -40 {
+lab=iovss}
+N 1800 -120 1830 -120 {
+lab=iovss}
+N 1830 -120 1830 -60 {
+lab=iovss}
+N 1800 -60 1830 -60 {
+lab=iovss}
+N 1800 -90 1800 -60 {
+lab=iovss}
+N 1930 -60 1930 -40 {
+lab=iovss}
+N 1800 -40 1930 -40 {
+lab=iovss}
+N 1930 -120 1960 -120 {
+lab=iovss}
+N 1960 -120 1960 -60 {
+lab=iovss}
+N 1930 -60 1960 -60 {
+lab=iovss}
+N 1930 -90 1930 -60 {
+lab=iovss}
+N 2060 -70 2060 -40 {
+lab=iovss}
+N 1930 -40 2060 -40 {
+lab=iovss}
+N 2060 -120 2090 -120 {
+lab=iovss}
+N 2090 -120 2090 -70 {
+lab=iovss}
+N 2060 -70 2090 -70 {
+lab=iovss}
+N 2060 -90 2060 -70 {
+lab=iovss}
+N 2190 -70 2190 -40 {
+lab=iovss}
+N 2060 -40 2190 -40 {
+lab=iovss}
+N 2190 -120 2220 -120 {
+lab=iovss}
+N 2220 -120 2220 -70 {
+lab=iovss}
+N 2190 -70 2220 -70 {
+lab=iovss}
+N 2190 -90 2190 -70 {
+lab=iovss}
+N 2320 -70 2320 -40 {
+lab=iovss}
+N 2190 -40 2320 -40 {
+lab=iovss}
+N 2320 -120 2340 -120 {
+lab=iovss}
+N 2340 -120 2340 -70 {
+lab=iovss}
+N 2320 -70 2340 -70 {
+lab=iovss}
+N 2320 -90 2320 -70 {
+lab=iovss}
+N 2450 -70 2450 -40 {
+lab=iovss}
+N 2320 -40 2450 -40 {
+lab=iovss}
+N 2450 -120 2470 -120 {
+lab=iovss}
+N 2470 -120 2470 -70 {
+lab=iovss}
+N 2450 -70 2470 -70 {
+lab=iovss}
+N 2450 -90 2450 -70 {
+lab=iovss}
+N 2570 -90 2570 -40 {
+lab=iovss}
+N 2450 -40 2570 -40 {
+lab=iovss}
+N 2570 -120 2610 -120 {
+lab=iovss}
+N 2610 -120 2610 -40 {
+lab=iovss}
+N 2570 -40 2610 -40 {
+lab=iovss}
+N 2710 -60 2710 -40 {
+lab=iovss}
+N 2610 -40 2710 -40 {
+lab=iovss}
+N 2710 -120 2740 -120 {
+lab=iovss}
+N 2740 -120 2740 -60 {
+lab=iovss}
+N 2710 -60 2740 -60 {
+lab=iovss}
+N 2710 -90 2710 -60 {
+lab=iovss}
+N 2840 -80 2840 -40 {
+lab=iovss}
+N 2710 -40 2840 -40 {
+lab=iovss}
+N 2840 -120 2870 -120 {
+lab=iovss}
+N 2870 -120 2870 -80 {
+lab=iovss}
+N 2840 -80 2870 -80 {
+lab=iovss}
+N 2840 -90 2840 -80 {
+lab=iovss}
+N 4140 -190 4140 -150 {
+lab=pad}
+N 4010 -190 4140 -190 {
+lab=pad}
+N 1670 -190 1670 -150 {
+lab=pad}
+N 1800 -190 1800 -150 {
+lab=pad}
+N 1670 -190 1800 -190 {
+lab=pad}
+N 1930 -190 1930 -150 {
+lab=pad}
+N 1800 -190 1930 -190 {
+lab=pad}
+N 2060 -190 2060 -150 {
+lab=pad}
+N 1930 -190 2060 -190 {
+lab=pad}
+N 2190 -190 2190 -150 {
+lab=pad}
+N 2060 -190 2190 -190 {
+lab=pad}
+N 2320 -190 2320 -150 {
+lab=pad}
+N 2280 -190 2320 -190 {
+lab=pad}
+N 2450 -190 2450 -150 {
+lab=pad}
+N 2320 -190 2450 -190 {
+lab=pad}
+N 2570 -190 2570 -150 {
+lab=pad}
+N 2450 -190 2570 -190 {
+lab=pad}
+N 2710 -190 2710 -150 {
+lab=pad}
+N 2570 -190 2710 -190 {
+lab=pad}
+N 2840 -190 2840 -150 {
+lab=pad}
+N 2710 -190 2840 -190 {
+lab=pad}
+N 2970 -190 2970 -150 {
+lab=pad}
+N 2840 -190 2970 -190 {
+lab=pad}
+N 3100 -190 3100 -150 {
+lab=pad}
+N 2970 -190 3100 -190 {
+lab=pad}
+N 3230 -190 3230 -150 {
+lab=pad}
+N 3100 -190 3230 -190 {
+lab=pad}
+N 3360 -190 3360 -150 {
+lab=pad}
+N 3230 -190 3360 -190 {
+lab=pad}
+N 3490 -190 3490 -150 {
+lab=pad}
+N 3360 -190 3490 -190 {
+lab=pad}
+N 3620 -190 3620 -150 {
+lab=pad}
+N 3490 -190 3620 -190 {
+lab=pad}
+N 3750 -190 3750 -150 {
+lab=pad}
+N 3620 -190 3750 -190 {
+lab=pad}
+N 3870 -190 3870 -150 {
+lab=pad}
+N 3750 -190 3870 -190 {
+lab=pad}
+N 4010 -190 4010 -150 {
+lab=pad}
+N 3870 -190 4010 -190 {
+lab=pad}
+N 1580 -120 1630 -120 {
+lab=#net1}
+N 1580 -120 1580 50 {
+lab=#net1}
+N 4100 -120 4100 50 {
+lab=#net1}
+N 3970 50 4100 50 {
+lab=#net1}
+N 1670 -120 1710 -120 {
+lab=iovss}
+N 1710 -120 1710 -70 {
+lab=iovss}
+N 1670 -70 1710 -70 {
+lab=iovss}
+N 1670 -90 1670 -70 {
+lab=iovss}
+N 1760 -120 1760 50 {
+lab=#net1}
+N 1580 50 1760 50 {
+lab=#net1}
+N 1890 -120 1890 50 {
+lab=#net1}
+N 1760 50 1890 50 {
+lab=#net1}
+N 2020 -120 2020 50 {
+lab=#net1}
+N 1890 50 2020 50 {
+lab=#net1}
+N 2150 -120 2150 50 {
+lab=#net1}
+N 2020 50 2150 50 {
+lab=#net1}
+N 2280 -120 2280 50 {
+lab=#net1}
+N 2150 50 2280 50 {
+lab=#net1}
+N 2410 -120 2410 50 {
+lab=#net1}
+N 2280 50 2410 50 {
+lab=#net1}
+N 2530 -120 2530 50 {
+lab=#net1}
+N 2410 50 2530 50 {
+lab=#net1}
+N 2670 -120 2670 50 {
+lab=#net1}
+N 2530 50 2670 50 {
+lab=#net1}
+N 2800 -120 2800 50 {
+lab=#net1}
+N 2670 50 2800 50 {
+lab=#net1}
+N 2930 -120 2930 50 {
+lab=#net1}
+N 2800 50 2930 50 {
+lab=#net1}
+N 3060 -120 3060 50 {
+lab=#net1}
+N 2930 50 3060 50 {
+lab=#net1}
+N 3190 -120 3190 50 {
+lab=#net1}
+N 3060 50 3190 50 {
+lab=#net1}
+N 3320 -120 3320 50 {
+lab=#net1}
+N 3190 50 3320 50 {
+lab=#net1}
+N 3450 -120 3450 50 {
+lab=#net1}
+N 3320 50 3450 50 {
+lab=#net1}
+N 3580 -120 3580 50 {
+lab=#net1}
+N 3450 50 3580 50 {
+lab=#net1}
+N 3710 -120 3710 50 {
+lab=#net1}
+N 3580 50 3710 50 {
+lab=#net1}
+N 3830 -120 3830 50 {
+lab=#net1}
+N 3710 50 3830 50 {
+lab=#net1}
+N 3970 -120 3970 50 {
+lab=#net1}
+N 3830 50 3970 50 {
+lab=#net1}
+N 1730 180 1730 230 {
+lab=iovss}
+N 1670 -40 1730 -40 {
+lab=iovss}
+N 1490 120 1490 180 {
+lab=iovss}
+N 1490 180 1730 180 {
+lab=iovss}
+N 1730 -40 1730 180 {
+lab=iovss}
+N 1490 -120 1490 60 {
+lab=#net1}
+N 1490 -120 1580 -120 {
+lab=#net1}
+N 2280 -300 2280 -190 {
+lab=pad}
+N 2190 -190 2280 -190 {
+lab=pad}
+N 2630 -300 2630 -260 {
+lab=iovdd}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1650 -120 2 1 {name=M1
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1780 -120 2 1 {name=M2
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1910 -120 2 1 {name=M3
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 2040 -120 2 1 {name=M4
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 2170 -120 2 1 {name=M5
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 2300 -120 2 1 {name=M6
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 2430 -120 2 1 {name=M7
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 2550 -120 2 1 {name=M8
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 2690 -120 2 1 {name=M9
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 2820 -120 2 1 {name=M10
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 2950 -120 2 1 {name=M11
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 3080 -120 2 1 {name=M12
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 3210 -120 2 1 {name=M13
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 3340 -120 2 1 {name=M14
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 3470 -120 2 1 {name=M15
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 3600 -120 2 1 {name=M16
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 3730 -120 2 1 {name=M17
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 3850 -120 2 1 {name=M18
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 3990 -120 2 1 {name=M19
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 4120 -120 2 1 {name=M20
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/rppd.sym} 1490 90 0 0 {name=R1
+w=0.5e-6
+l=3.54e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {devices/iopin.sym} 1730 230 1 0 {name=iovss lab=iovss}
+C {devices/iopin.sym} 2280 -300 3 0 {name=pad lab=pad}
+C {devices/iopin.sym} 2630 -300 3 0 {name=iovdd lab=iovdd}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N20N0D.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N20N0D.sym
new file mode 100644
index 00000000..9c2a91ff
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N20N0D.sym
@@ -0,0 +1,25 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -30 130 -30 {}
+L 4 -130 30 130 30 {}
+L 4 -130 -30 -130 30 {}
+L 4 130 -30 130 30 {}
+L 7 130 0 150 0 {}
+L 7 0 -50 0 -30 {}
+L 7 0 30 0 50 {}
+B 5 147.5 -2.5 152.5 2.5 {name=pad dir=inout}
+B 5 -2.5 -52.5 2.5 -47.5 {name=iovdd dir=inout}
+B 5 -2.5 47.5 2.5 52.5 {name=iovss dir=inout}
+T {sg13g2_Clamp_N20N0D} -73.5 -6 0 0 0.2 0.2 {}
+T {@name} 135 -42 0 0 0.2 0.2 {}
+T {pad} 125 -4 0 1 0.2 0.2 {}
+T {iovdd} 15 -24 0 1 0.2 0.2 {}
+T {iovss} 15 16 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N2N2D.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N2N2D.sch
new file mode 100644
index 00000000..97c698cc
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N2N2D.sch
@@ -0,0 +1,91 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 900 -330 900 -300 {
+lab=pad}
+N 990 -330 1090 -330 {
+lab=pad}
+N 1090 -330 1090 -300 {
+lab=pad}
+N 900 -230 900 -200 {
+lab=iovss}
+N 990 -200 1090 -200 {
+lab=iovss}
+N 1090 -220 1090 -200 {
+lab=iovss}
+N 1090 -270 1140 -270 {
+lab=iovss}
+N 1140 -270 1140 -220 {
+lab=iovss}
+N 1090 -220 1140 -220 {
+lab=iovss}
+N 1090 -240 1090 -220 {
+lab=iovss}
+N 900 -270 930 -270 {
+lab=iovss}
+N 930 -270 930 -230 {
+lab=iovss}
+N 900 -230 930 -230 {
+lab=iovss}
+N 900 -240 900 -230 {
+lab=iovss}
+N 990 -160 990 -120 {
+lab=iovss}
+N 900 -200 990 -200 {
+lab=iovss}
+N 990 -370 990 -330 {
+lab=pad}
+N 900 -330 990 -330 {
+lab=pad}
+N 830 -270 860 -270 {
+lab=gate}
+N 830 -310 830 -270 {
+lab=gate}
+N 830 -310 1050 -310 {
+lab=gate}
+N 1050 -310 1050 -270 {
+lab=gate}
+N 780 -270 830 -270 {
+lab=gate}
+N 780 -270 780 -250 {
+lab=gate}
+N 690 -270 780 -270 {
+lab=gate}
+N 780 -190 780 -160 {
+lab=iovss}
+N 780 -160 990 -160 {
+lab=iovss}
+N 990 -200 990 -160 {
+lab=iovss}
+N 850 -380 850 -350 {
+lab=iovss}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1070 -270 2 1 {name=M1
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 880 -270 2 1 {name=M2
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/dantenna.sym} 780 -220 0 0 {name=D1
+model=dantenna
+l=0.64u
+w=0.3u
+spiceprefix=X
+}
+C {devices/iopin.sym} 990 -120 1 0 {name=iovss lab=iovss}
+C {devices/iopin.sym} 690 -270 2 0 {name=gate lab=gate}
+C {devices/iopin.sym} 990 -370 3 0 {name=pad lab=pad}
+C {devices/iopin.sym} 850 -380 3 0 {name=iovdd lab=iovdd}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N2N2D.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N2N2D.sym
new file mode 100644
index 00000000..a2b7bcfb
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N2N2D.sym
@@ -0,0 +1,28 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -40 130 -40 {}
+L 4 -130 40 130 40 {}
+L 4 -130 -40 -130 40 {}
+L 4 130 -40 130 40 {}
+L 7 -30 -60 -30 -40 {}
+L 7 130 0 150 0 {}
+L 7 -150 0 -130 0 {}
+L 7 -30 40 -30 60 {}
+B 5 -32.5 -62.5 -27.5 -57.5 {name=iovdd dir=inout}
+B 5 147.5 -2.5 152.5 2.5 {name=pad dir=inout}
+B 5 -152.5 -2.5 -147.5 2.5 {name=gate dir=inout}
+B 5 -32.5 57.5 -27.5 62.5 {name=iovss dir=inout}
+T {sg13g2_Clamp_N2N2D} -99 -6 0 0 0.2 0.2 {}
+T {@name} 135 -52 0 0 0.2 0.2 {}
+T {iovdd} -35 -54 0 1 0.2 0.2 {}
+T {pad} 125 -4 0 1 0.2 0.2 {}
+T {gate} -135 6 0 1 0.2 0.2 {}
+T {iovss} -35 46 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N43N43D4R.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N43N43D4R.sch
new file mode 100644
index 00000000..32616ccd
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N43N43D4R.sch
@@ -0,0 +1,2428 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 1480 -920 1580 -920 {}
+N 1490 -770 1580 -770 {}
+N 1580 -920 1580 -770 {}
+N -1180 70 -1180 90 {}
+N 1530 90 1580 90 {}
+N 1580 -80 1580 90 {}
+N -1070 70 -1070 90 {}
+N -1150 90 -1070 90 {}
+N -940 70 -940 90 {}
+N -1050 90 -940 90 {}
+N -800 70 -800 90 {}
+N -910 90 -800 90 {}
+N -660 70 -660 90 {}
+N -780 90 -660 90 {}
+N -540 70 -540 90 {}
+N -640 90 -540 90 {}
+N -430 70 -430 90 {}
+N -520 90 -430 90 {}
+N -290 70 -290 90 {}
+N -400 90 -290 90 {}
+N -150 70 -150 90 {}
+N -270 90 -150 90 {}
+N -10 70 -10 90 {}
+N -130 90 -10 90 {}
+N 110 70 110 90 {}
+N 10 90 110 90 {}
+N 220 70 220 90 {}
+N 130 90 220 90 {}
+N 350 70 350 90 {}
+N 490 70 490 90 {}
+N 370 90 490 90 {}
+N 630 70 630 90 {}
+N 510 90 630 90 {}
+N 750 70 750 90 {}
+N 660 90 750 90 {}
+N 860 70 860 90 {}
+N 770 90 860 90 {}
+N 1000 70 1000 90 {}
+N 890 90 1000 90 {}
+N 1140 70 1140 90 {}
+N 1020 90 1140 90 {}
+N 1280 70 1280 90 {}
+N 1170 90 1280 90 {}
+N 1400 70 1400 90 {}
+N 1310 90 1400 90 {}
+N 1510 70 1510 90 {}
+N 1430 90 1510 90 {}
+N -1170 250 -1170 290 {}
+N 1540 290 1580 290 {}
+N 1580 90 1580 290 {}
+N 640 250 640 290 {}
+N 530 290 640 290 {}
+N 760 250 760 290 {}
+N 670 290 760 290 {}
+N 870 250 870 290 {}
+N 790 290 870 290 {}
+N 1010 250 1010 290 {}
+N 900 290 1010 290 {}
+N 1150 250 1150 290 {}
+N 1040 290 1150 290 {}
+N 1290 250 1290 290 {}
+N 1180 290 1290 290 {}
+N 1410 250 1410 290 {}
+N 1320 290 1410 290 {}
+N 1520 250 1520 290 {}
+N 1430 290 1520 290 {}
+N -1060 250 -1060 290 {}
+N -1140 290 -1060 290 {}
+N -930 250 -930 290 {}
+N -1040 290 -930 290 {}
+N -790 250 -790 290 {}
+N -910 290 -790 290 {}
+N -650 250 -650 290 {}
+N -770 290 -650 290 {}
+N -530 250 -530 290 {}
+N -630 290 -530 290 {}
+N -420 250 -420 290 {}
+N -510 290 -420 290 {}
+N -280 250 -280 290 {}
+N -400 290 -280 290 {}
+N -140 250 -140 290 {}
+N -260 290 -140 290 {}
+N 0 250 0 290 {}
+N -120 290 0 290 {}
+N 120 250 120 290 {}
+N 20 290 120 290 {}
+N 230 250 230 290 {}
+N 140 290 230 290 {}
+N 360 250 360 290 {}
+N 280 290 360 290 {}
+N 500 250 500 290 {}
+N 380 290 500 290 {}
+N -1200 -100 -1200 -80 {}
+N 1520 -80 1580 -80 {}
+N 1580 -250 1580 -80 {}
+N -1090 -100 -1090 -80 {}
+N -1170 -80 -1090 -80 {}
+N -960 -100 -960 -80 {}
+N -1060 -80 -960 -80 {}
+N -820 -100 -820 -80 {}
+N -940 -80 -820 -80 {}
+N -680 -100 -680 -80 {}
+N -790 -80 -680 -80 {}
+N -560 -100 -560 -80 {}
+N -650 -80 -560 -80 {}
+N -450 -100 -450 -80 {}
+N -530 -80 -450 -80 {}
+N -310 -100 -310 -80 {}
+N -420 -80 -310 -80 {}
+N -170 -100 -170 -80 {}
+N -280 -80 -170 -80 {}
+N -30 -100 -30 -80 {}
+N -140 -80 -30 -80 {}
+N 90 -100 90 -80 {}
+N 0 -80 90 -80 {}
+N 200 -100 200 -80 {}
+N 330 -100 330 -80 {}
+N 230 -80 330 -80 {}
+N 470 -100 470 -80 {}
+N 360 -80 470 -80 {}
+N 610 -100 610 -80 {}
+N 500 -80 610 -80 {}
+N 730 -100 730 -80 {}
+N 630 -80 730 -80 {}
+N 840 -100 840 -80 {}
+N 760 -80 840 -80 {}
+N 1580 -420 1580 -250 {}
+N 980 -100 980 -80 {}
+N 870 -80 980 -80 {}
+N 1120 -100 1120 -80 {}
+N 1010 -80 1120 -80 {}
+N 1260 -100 1260 -80 {}
+N 1150 -80 1260 -80 {}
+N 1380 -100 1380 -80 {}
+N 1290 -80 1380 -80 {}
+N 1490 -100 1490 -80 {}
+N 1410 -80 1490 -80 {}
+N 1510 -250 1580 -250 {}
+N 1520 -420 1580 -420 {}
+N 1580 -600 1580 -420 {}
+N 1510 -600 1580 -600 {}
+N 1580 -770 1580 -600 {}
+N 280 370 280 390 {}
+N 250 290 280 290 {}
+N -1170 190 1550 190 {}
+N 1550 10 1550 190 {}
+N 80 -980 1550 -980 {}
+N -1180 10 1550 10 {}
+N 1550 -160 1550 10 {}
+N -1200 -160 1550 -160 {}
+N 1550 -310 1550 -160 {}
+N -1200 -310 1550 -310 {}
+N 1550 -480 1550 -310 {}
+N -1220 -480 1550 -480 {}
+N 1550 -660 1550 -480 {}
+N -1230 -660 1550 -660 {}
+N 1550 -830 1550 -660 {}
+N -1250 -830 1550 -830 {}
+N 1550 -980 1550 -830 {}
+N -1290 130 -1290 220 {}
+N -1290 220 -1210 220 {}
+N -1290 40 -1220 40 {}
+N -1290 -40 -1290 40 {}
+N -1290 -130 -1240 -130 {}
+N -1290 -210 -1290 -130 {}
+N -1290 -280 -1240 -280 {}
+N -1290 -340 -1290 -280 {}
+N -1290 -450 -1260 -450 {}
+N -1290 -550 -1290 -450 {}
+N -1290 -630 -1270 -630 {}
+N 80 -1070 80 -980 {}
+N -1250 -980 80 -980 {}
+N 1280 -870 1420 -870 {}
+N -1290 -950 -1290 -870 {}
+N 1420 -950 1420 -870 {}
+N 1280 -950 1280 -870 {}
+N 1140 -870 1280 -870 {}
+N 1140 -950 1140 -870 {}
+N 1000 -870 1140 -870 {}
+N 1000 -950 1000 -870 {}
+N 890 -870 1000 -870 {}
+N 890 -950 890 -870 {}
+N 770 -870 890 -870 {}
+N 770 -950 770 -870 {}
+N 630 -870 770 -870 {}
+N 630 -950 630 -870 {}
+N 490 -870 630 -870 {}
+N 490 -950 490 -870 {}
+N 330 -870 490 -870 {}
+N 330 -950 330 -870 {}
+N 220 -870 330 -870 {}
+N 220 -950 220 -870 {}
+N 100 -870 220 -870 {}
+N 100 -950 100 -870 {}
+N -40 -870 100 -870 {}
+N -40 -950 -40 -870 {}
+N -180 -870 -40 -870 {}
+N -0 -950 20 -950 {}
+N 20 -950 20 -920 {}
+N -120 -920 20 -920 {}
+N 140 -950 160 -950 {}
+N 160 -950 160 -920 {}
+N 20 -920 160 -920 {}
+N 260 -950 280 -950 {}
+N 280 -950 280 -920 {}
+N 160 -920 280 -920 {}
+N 370 -950 390 -950 {}
+N 390 -950 390 -920 {}
+N 280 -920 390 -920 {}
+N 530 -950 550 -950 {}
+N 550 -950 550 -920 {}
+N 390 -920 550 -920 {}
+N 670 -950 690 -950 {}
+N 690 -950 690 -920 {}
+N 550 -920 690 -920 {}
+N 810 -950 840 -950 {}
+N 840 -950 840 -920 {}
+N 690 -920 840 -920 {}
+N 930 -950 960 -950 {}
+N 960 -950 960 -920 {}
+N 840 -920 960 -920 {}
+N 1040 -950 1060 -950 {}
+N 1060 -950 1060 -920 {}
+N 960 -920 1060 -920 {}
+N 1180 -950 1200 -950 {}
+N 1200 -950 1200 -920 {}
+N 1060 -920 1200 -920 {}
+N 1320 -950 1340 -950 {}
+N 1340 -950 1340 -920 {}
+N 1200 -920 1340 -920 {}
+N 1460 -950 1480 -950 {}
+N 1480 -950 1480 -920 {}
+N 1340 -920 1480 -920 {}
+N -0 -800 20 -800 {}
+N 20 -800 20 -770 {}
+N -110 -770 20 -770 {}
+N 140 -800 160 -800 {}
+N 160 -800 160 -770 {}
+N 20 -770 160 -770 {}
+N 260 -800 280 -800 {}
+N 280 -800 280 -770 {}
+N 160 -770 280 -770 {}
+N 370 -800 400 -800 {}
+N 400 -800 400 -770 {}
+N 280 -770 400 -770 {}
+N 530 -800 560 -800 {}
+N 560 -800 560 -770 {}
+N 400 -770 560 -770 {}
+N 670 -800 690 -800 {}
+N 690 -800 690 -770 {}
+N 560 -770 690 -770 {}
+N 810 -800 830 -800 {}
+N 830 -800 830 -770 {}
+N 690 -770 830 -770 {}
+N 930 -800 960 -800 {}
+N 960 -800 960 -770 {}
+N 830 -770 960 -770 {}
+N 1040 -800 1070 -800 {}
+N 1070 -800 1070 -770 {}
+N 960 -770 1070 -770 {}
+N 1180 -800 1210 -800 {}
+N 1210 -800 1210 -770 {}
+N 1070 -770 1210 -770 {}
+N 1320 -800 1350 -800 {}
+N 1350 -800 1350 -770 {}
+N 1210 -770 1350 -770 {}
+N 1460 -800 1490 -800 {}
+N 1490 -800 1490 -770 {}
+N 1350 -770 1490 -770 {}
+N 20 -630 50 -630 {}
+N 50 -630 50 -600 {}
+N -100 -600 50 -600 {}
+N 160 -630 180 -630 {}
+N 180 -630 180 -600 {}
+N 50 -600 180 -600 {}
+N 280 -630 310 -630 {}
+N 310 -630 310 -600 {}
+N 180 -600 310 -600 {}
+N 390 -630 420 -630 {}
+N 420 -630 420 -600 {}
+N 310 -600 420 -600 {}
+N 550 -630 580 -630 {}
+N 580 -630 580 -600 {}
+N 420 -600 580 -600 {}
+N 690 -630 720 -630 {}
+N 720 -630 720 -600 {}
+N 580 -600 720 -600 {}
+N 830 -630 860 -630 {}
+N 860 -630 860 -600 {}
+N 720 -600 860 -600 {}
+N 950 -630 980 -630 {}
+N 980 -630 980 -600 {}
+N 860 -600 980 -600 {}
+N 1060 -630 1090 -630 {}
+N 1090 -630 1090 -600 {}
+N 980 -600 1090 -600 {}
+N 1200 -630 1230 -630 {}
+N 1230 -630 1230 -600 {}
+N 1090 -600 1230 -600 {}
+N 1340 -630 1370 -630 {}
+N 1370 -630 1370 -600 {}
+N 1230 -600 1370 -600 {}
+N 1480 -630 1510 -630 {}
+N 1510 -630 1510 -600 {}
+N 1370 -600 1510 -600 {}
+N 30 -450 60 -450 {}
+N 60 -450 60 -420 {}
+N -80 -420 60 -420 {}
+N 170 -450 190 -450 {}
+N 190 -450 190 -420 {}
+N 60 -420 190 -420 {}
+N 290 -450 310 -450 {}
+N 310 -450 310 -420 {}
+N 190 -420 310 -420 {}
+N 400 -450 420 -450 {}
+N 420 -450 420 -420 {}
+N 310 -420 420 -420 {}
+N 560 -450 590 -450 {}
+N 590 -450 590 -420 {}
+N 420 -420 590 -420 {}
+N 700 -450 730 -450 {}
+N 730 -450 730 -420 {}
+N 590 -420 730 -420 {}
+N 840 -450 870 -450 {}
+N 870 -450 870 -420 {}
+N 730 -420 870 -420 {}
+N 960 -450 990 -450 {}
+N 990 -450 990 -420 {}
+N 870 -420 990 -420 {}
+N 1070 -450 1100 -450 {}
+N 1100 -450 1100 -420 {}
+N 990 -420 1100 -420 {}
+N 1210 -450 1240 -450 {}
+N 1240 -450 1240 -420 {}
+N 1100 -420 1240 -420 {}
+N 1350 -450 1380 -450 {}
+N 1380 -450 1380 -420 {}
+N 1240 -420 1380 -420 {}
+N 1490 -450 1520 -450 {}
+N 1520 -450 1520 -420 {}
+N 1380 -420 1520 -420 {}
+N -1290 -720 -1290 -630 {}
+N 1420 -800 1420 -720 {}
+N 1280 -720 1420 -720 {}
+N -1290 -870 -1290 -720 {}
+N 1440 -630 1440 -550 {}
+N 1300 -550 1440 -550 {}
+N -1290 -630 -1290 -550 {}
+N 1450 -450 1450 -380 {}
+N 1310 -380 1450 -380 {}
+N -1290 -450 -1290 -380 {}
+N 1450 -280 1450 -210 {}
+N 1340 -210 1450 -210 {}
+N -1290 -280 -1290 -210 {}
+N 1450 -130 1450 -40 {}
+N -1290 -130 -1290 -40 {}
+N 1470 40 1470 130 {}
+N 1360 130 1470 130 {}
+N -1290 40 -1290 130 {}
+N 1480 220 1480 330 {}
+N 1370 330 1480 330 {}
+N -1290 220 -1290 330 {}
+N -180 -950 -180 -870 {}
+N -320 -870 -180 -870 {}
+N -320 -950 -320 -870 {}
+N -430 -870 -320 -870 {}
+N -430 -950 -430 -870 {}
+N -550 -870 -430 -870 {}
+N -550 -950 -550 -870 {}
+N -690 -870 -550 -870 {}
+N -690 -950 -690 -870 {}
+N -830 -870 -690 -870 {}
+N -830 -950 -830 -870 {}
+N -1010 -870 -830 -870 {}
+N -1010 -950 -1010 -870 {}
+N -1150 -870 -1010 -870 {}
+N -1150 -950 -1150 -870 {}
+N -1290 -870 -1150 -870 {}
+N -1250 -950 -1220 -950 {}
+N -1220 -950 -1220 -920 {}
+N -1250 -920 -1220 -920 {}
+N -1110 -950 -1080 -950 {}
+N -1080 -950 -1080 -920 {}
+N -1220 -920 -1080 -920 {}
+N -970 -950 -940 -950 {}
+N -940 -950 -940 -920 {}
+N -1080 -920 -940 -920 {}
+N -790 -950 -760 -950 {}
+N -760 -950 -760 -920 {}
+N -940 -920 -760 -920 {}
+N -650 -950 -620 -950 {}
+N -620 -950 -620 -920 {}
+N -760 -920 -620 -920 {}
+N -510 -950 -480 -950 {}
+N -480 -950 -480 -920 {}
+N -620 -920 -480 -920 {}
+N -390 -950 -370 -950 {}
+N -370 -950 -370 -920 {}
+N -480 -920 -370 -920 {}
+N -280 -950 -260 -950 {}
+N -260 -950 -260 -920 {}
+N -370 -920 -260 -920 {}
+N -140 -950 -120 -950 {}
+N -120 -950 -120 -920 {}
+N -260 -920 -120 -920 {}
+N -1250 -800 -1220 -800 {}
+N -1220 -800 -1220 -770 {}
+N -1250 -770 -1220 -770 {}
+N -1110 -800 -1080 -800 {}
+N -1080 -800 -1080 -770 {}
+N -970 -800 -940 -800 {}
+N -940 -800 -940 -770 {}
+N -1080 -770 -940 -770 {}
+N -790 -800 -760 -800 {}
+N -760 -800 -760 -770 {}
+N -940 -770 -760 -770 {}
+N -650 -800 -620 -800 {}
+N -620 -800 -620 -770 {}
+N -760 -770 -620 -770 {}
+N -510 -800 -490 -800 {}
+N -490 -800 -490 -770 {}
+N -620 -770 -490 -770 {}
+N -390 -800 -360 -800 {}
+N -360 -800 -360 -770 {}
+N -490 -770 -360 -770 {}
+N -280 -800 -250 -800 {}
+N -250 -800 -250 -770 {}
+N -360 -770 -250 -770 {}
+N -140 -800 -110 -800 {}
+N -110 -800 -110 -770 {}
+N -250 -770 -110 -770 {}
+N -1220 -770 -1080 -770 {}
+N -1150 -800 -1150 -720 {}
+N -1290 -720 -1150 -720 {}
+N -1010 -800 -1010 -720 {}
+N -1150 -720 -1010 -720 {}
+N -830 -800 -830 -720 {}
+N -1010 -720 -830 -720 {}
+N -690 -800 -690 -720 {}
+N -830 -720 -690 -720 {}
+N -550 -800 -550 -720 {}
+N -690 -720 -550 -720 {}
+N -430 -800 -430 -720 {}
+N -550 -720 -430 -720 {}
+N -320 -800 -320 -720 {}
+N -430 -720 -320 -720 {}
+N -180 -800 -180 -720 {}
+N -320 -720 -180 -720 {}
+N -40 -800 -40 -720 {}
+N -180 -720 -40 -720 {}
+N 100 -800 100 -720 {}
+N -40 -720 100 -720 {}
+N 220 -800 220 -720 {}
+N 100 -720 220 -720 {}
+N 330 -800 330 -720 {}
+N 220 -720 330 -720 {}
+N 490 -800 490 -720 {}
+N 330 -720 490 -720 {}
+N -1130 -630 -1130 -550 {}
+N -1290 -550 -1130 -550 {}
+N -990 -630 -990 -550 {}
+N -1130 -550 -990 -550 {}
+N -810 -630 -810 -550 {}
+N -990 -550 -810 -550 {}
+N -670 -630 -670 -550 {}
+N -810 -550 -670 -550 {}
+N -530 -630 -530 -550 {}
+N -670 -550 -530 -550 {}
+N -410 -630 -410 -550 {}
+N -530 -550 -410 -550 {}
+N -300 -630 -300 -550 {}
+N -410 -550 -300 -550 {}
+N -160 -630 -160 -550 {}
+N -300 -550 -160 -550 {}
+N -20 -630 -20 -550 {}
+N -160 -550 -20 -550 {}
+N 120 -630 120 -550 {}
+N -20 -550 120 -550 {}
+N 240 -630 240 -550 {}
+N 120 -550 240 -550 {}
+N 350 -630 350 -550 {}
+N 240 -550 350 -550 {}
+N 510 -630 510 -550 {}
+N 350 -550 510 -550 {}
+N -1230 -630 -1200 -630 {}
+N -1200 -630 -1200 -600 {}
+N -1230 -600 -1200 -600 {}
+N -1090 -630 -1060 -630 {}
+N -1060 -630 -1060 -600 {}
+N -1200 -600 -1060 -600 {}
+N -950 -630 -920 -630 {}
+N -920 -630 -920 -600 {}
+N -1060 -600 -920 -600 {}
+N -770 -630 -750 -630 {}
+N -750 -630 -750 -600 {}
+N -920 -600 -750 -600 {}
+N -630 -630 -600 -630 {}
+N -600 -630 -600 -600 {}
+N -750 -600 -600 -600 {}
+N -490 -630 -460 -630 {}
+N -460 -630 -460 -600 {}
+N -600 -600 -460 -600 {}
+N -370 -630 -340 -630 {}
+N -340 -630 -340 -600 {}
+N -460 -600 -340 -600 {}
+N -260 -630 -230 -630 {}
+N -230 -630 -230 -600 {}
+N -340 -600 -230 -600 {}
+N -120 -630 -100 -630 {}
+N -100 -630 -100 -600 {}
+N -230 -600 -100 -600 {}
+N -1120 -450 -1120 -380 {}
+N -1290 -380 -1120 -380 {}
+N -980 -450 -980 -380 {}
+N -1120 -380 -980 -380 {}
+N -800 -450 -800 -380 {}
+N -980 -380 -800 -380 {}
+N -660 -450 -660 -380 {}
+N -800 -380 -660 -380 {}
+N -520 -450 -520 -380 {}
+N -660 -380 -520 -380 {}
+N -400 -450 -400 -380 {}
+N -520 -380 -400 -380 {}
+N -290 -450 -290 -380 {}
+N -400 -380 -290 -380 {}
+N 520 -450 520 -380 {}
+N 360 -380 520 -380 {}
+N 360 -450 360 -380 {}
+N 250 -380 360 -380 {}
+N 250 -450 250 -380 {}
+N 130 -380 250 -380 {}
+N 130 -450 130 -380 {}
+N -10 -380 130 -380 {}
+N -10 -450 -10 -380 {}
+N -150 -380 -10 -380 {}
+N -150 -450 -150 -380 {}
+N -290 -380 -150 -380 {}
+N -1130 -280 -1130 -210 {}
+N -1290 -210 -1130 -210 {}
+N -1000 -280 -1000 -210 {}
+N -1130 -210 -1000 -210 {}
+N -860 -280 -860 -210 {}
+N -1000 -210 -860 -210 {}
+N -720 -280 -720 -210 {}
+N -860 -210 -720 -210 {}
+N -600 -280 -600 -210 {}
+N -720 -210 -600 -210 {}
+N -490 -280 -490 -210 {}
+N -600 -210 -490 -210 {}
+N -350 -280 -350 -210 {}
+N -490 -210 -350 -210 {}
+N -210 -280 -210 -210 {}
+N -350 -210 -210 -210 {}
+N -70 -280 -70 -210 {}
+N -210 -210 -70 -210 {}
+N 50 -280 50 -210 {}
+N -70 -210 50 -210 {}
+N 160 -280 160 -210 {}
+N 50 -210 160 -210 {}
+N 290 -280 290 -210 {}
+N 160 -210 290 -210 {}
+N 430 -280 430 -210 {}
+N 290 -210 430 -210 {}
+N 570 -280 570 -210 {}
+N 430 -210 570 -210 {}
+N -1130 -130 -1130 -40 {}
+N -1290 -40 -1130 -40 {}
+N 1340 -40 1450 -40 {}
+N -860 -130 -860 -40 {}
+N -1000 -40 -860 -40 {}
+N -1000 -130 -1000 -40 {}
+N -1130 -40 -1000 -40 {}
+N -720 -130 -720 -40 {}
+N -860 -40 -720 -40 {}
+N -600 -130 -600 -40 {}
+N -720 -40 -600 -40 {}
+N -490 -130 -490 -40 {}
+N -600 -40 -490 -40 {}
+N -350 -130 -350 -40 {}
+N -490 -40 -350 -40 {}
+N -210 -130 -210 -40 {}
+N -350 -40 -210 -40 {}
+N -70 -130 -70 -40 {}
+N -210 -40 -70 -40 {}
+N 50 -130 50 -40 {}
+N -70 -40 50 -40 {}
+N 110 -80 200 -80 {}
+N 570 -130 570 -40 {}
+N 430 -40 570 -40 {}
+N 430 -130 430 -40 {}
+N 290 -40 430 -40 {}
+N 290 -130 290 -40 {}
+N 160 -40 290 -40 {}
+N 160 -130 160 -40 {}
+N 50 -40 160 -40 {}
+N -1220 -450 -1190 -450 {}
+N -1190 -450 -1190 -420 {}
+N -1220 -420 -1190 -420 {}
+N -1080 -450 -1050 -450 {}
+N -1050 -450 -1050 -420 {}
+N -1190 -420 -1050 -420 {}
+N -940 -450 -910 -450 {}
+N -910 -450 -910 -420 {}
+N -1050 -420 -910 -420 {}
+N -760 -450 -730 -450 {}
+N -730 -450 -730 -420 {}
+N -910 -420 -730 -420 {}
+N -620 -450 -590 -450 {}
+N -590 -450 -590 -420 {}
+N -730 -420 -590 -420 {}
+N -480 -450 -450 -450 {}
+N -450 -450 -450 -420 {}
+N -590 -420 -450 -420 {}
+N -360 -450 -330 -450 {}
+N -330 -450 -330 -420 {}
+N -450 -420 -330 -420 {}
+N -110 -450 -80 -450 {}
+N -80 -450 -80 -420 {}
+N -220 -420 -80 -420 {}
+N -250 -450 -220 -450 {}
+N -220 -450 -220 -420 {}
+N -330 -420 -220 -420 {}
+N -1200 -280 -1180 -280 {}
+N -1180 -280 -1180 -250 {}
+N -1200 -250 -1180 -250 {}
+N -1090 -280 -1060 -280 {}
+N -1060 -280 -1060 -250 {}
+N -1180 -250 -1060 -250 {}
+N -960 -280 -930 -280 {}
+N -930 -280 -930 -250 {}
+N -1060 -250 -930 -250 {}
+N -820 -280 -790 -280 {}
+N -790 -280 -790 -250 {}
+N -930 -250 -790 -250 {}
+N -680 -280 -650 -280 {}
+N -650 -280 -650 -250 {}
+N -790 -250 -650 -250 {}
+N -560 -280 -530 -280 {}
+N -530 -280 -530 -250 {}
+N -650 -250 -530 -250 {}
+N -450 -280 -420 -280 {}
+N -420 -280 -420 -250 {}
+N -530 -250 -420 -250 {}
+N -310 -280 -280 -280 {}
+N -280 -280 -280 -250 {}
+N -420 -250 -280 -250 {}
+N -170 -280 -140 -280 {}
+N -140 -280 -140 -250 {}
+N -280 -250 -140 -250 {}
+N -30 -280 -0 -280 {}
+N -0 -280 0 -250 {}
+N -140 -250 0 -250 {}
+N 90 -280 110 -280 {}
+N 110 -280 110 -250 {}
+N 0 -250 110 -250 {}
+N 200 -280 230 -280 {}
+N 230 -280 230 -250 {}
+N 110 -250 230 -250 {}
+N 330 -280 350 -280 {}
+N 350 -280 350 -250 {}
+N 230 -250 350 -250 {}
+N 470 -280 500 -280 {}
+N 500 -280 500 -250 {}
+N 350 -250 500 -250 {}
+N -1200 -130 -1170 -130 {}
+N -1170 -130 -1170 -80 {}
+N -1200 -80 -1170 -80 {}
+N -1090 -130 -1060 -130 {}
+N -1060 -130 -1060 -80 {}
+N -1090 -80 -1060 -80 {}
+N -960 -130 -940 -130 {}
+N -940 -130 -940 -80 {}
+N -960 -80 -940 -80 {}
+N -820 -130 -790 -130 {}
+N -790 -130 -790 -80 {}
+N -820 -80 -790 -80 {}
+N -680 -130 -650 -130 {}
+N -650 -130 -650 -80 {}
+N -680 -80 -650 -80 {}
+N -560 -130 -530 -130 {}
+N -530 -130 -530 -80 {}
+N -560 -80 -530 -80 {}
+N -450 -130 -420 -130 {}
+N -420 -130 -420 -80 {}
+N -450 -80 -420 -80 {}
+N -310 -130 -280 -130 {}
+N -280 -130 -280 -80 {}
+N -310 -80 -280 -80 {}
+N -170 -130 -140 -130 {}
+N -140 -130 -140 -80 {}
+N -170 -80 -140 -80 {}
+N -30 -130 -0 -130 {}
+N -0 -130 0 -80 {}
+N -30 -80 0 -80 {}
+N 90 -130 110 -130 {}
+N 110 -130 110 -80 {}
+N 90 -80 110 -80 {}
+N 200 -130 230 -130 {}
+N 230 -130 230 -80 {}
+N 200 -80 230 -80 {}
+N 330 -130 360 -130 {}
+N 360 -130 360 -80 {}
+N 330 -80 360 -80 {}
+N 470 -130 500 -130 {}
+N 500 -130 500 -80 {}
+N 470 -80 500 -80 {}
+N 610 -130 630 -130 {}
+N 630 -130 630 -80 {}
+N 610 -80 630 -80 {}
+N 630 -800 630 -720 {}
+N 490 -720 630 -720 {}
+N 770 -800 770 -720 {}
+N 630 -720 770 -720 {}
+N 890 -800 890 -720 {}
+N 770 -720 890 -720 {}
+N 1000 -800 1000 -720 {}
+N 890 -720 1000 -720 {}
+N 1140 -800 1140 -720 {}
+N 1000 -720 1140 -720 {}
+N 1280 -800 1280 -720 {}
+N 1140 -720 1280 -720 {}
+N 650 -630 650 -550 {}
+N 510 -550 650 -550 {}
+N 790 -630 790 -550 {}
+N 650 -550 790 -550 {}
+N 910 -630 910 -550 {}
+N 790 -550 910 -550 {}
+N 1020 -630 1020 -550 {}
+N 910 -550 1020 -550 {}
+N 1160 -630 1160 -550 {}
+N 1020 -550 1160 -550 {}
+N 1300 -630 1300 -550 {}
+N 1160 -550 1300 -550 {}
+N 660 -450 660 -380 {}
+N 520 -380 660 -380 {}
+N 800 -450 800 -380 {}
+N 660 -380 800 -380 {}
+N 920 -450 920 -380 {}
+N 800 -380 920 -380 {}
+N 1030 -450 1030 -380 {}
+N 920 -380 1030 -380 {}
+N 1170 -450 1170 -380 {}
+N 1030 -380 1170 -380 {}
+N 1310 -450 1310 -380 {}
+N 1170 -380 1310 -380 {}
+N 690 -280 690 -210 {}
+N 570 -210 690 -210 {}
+N 800 -280 800 -210 {}
+N 690 -210 800 -210 {}
+N 940 -280 940 -210 {}
+N 800 -210 940 -210 {}
+N 1080 -280 1080 -210 {}
+N 940 -210 1080 -210 {}
+N 1220 -280 1220 -210 {}
+N 1080 -210 1220 -210 {}
+N 1340 -280 1340 -210 {}
+N 1220 -210 1340 -210 {}
+N 610 -280 640 -280 {}
+N 640 -280 640 -250 {}
+N 500 -250 640 -250 {}
+N 730 -280 750 -280 {}
+N 750 -280 750 -250 {}
+N 640 -250 750 -250 {}
+N 840 -280 870 -280 {}
+N 870 -280 870 -250 {}
+N 750 -250 870 -250 {}
+N 980 -280 1000 -280 {}
+N 1000 -280 1000 -250 {}
+N 870 -250 1000 -250 {}
+N 1120 -280 1150 -280 {}
+N 1150 -280 1150 -250 {}
+N 1000 -250 1150 -250 {}
+N 1260 -280 1280 -280 {}
+N 1280 -280 1280 -250 {}
+N 1150 -250 1280 -250 {}
+N 1380 -280 1400 -280 {}
+N 1400 -280 1400 -250 {}
+N 1280 -250 1400 -250 {}
+N 1490 -280 1510 -280 {}
+N 1510 -280 1510 -250 {}
+N 1400 -250 1510 -250 {}
+N 690 -130 690 -40 {}
+N 570 -40 690 -40 {}
+N 800 -130 800 -40 {}
+N 690 -40 800 -40 {}
+N 940 -130 940 -40 {}
+N 800 -40 940 -40 {}
+N 1080 -130 1080 -40 {}
+N 940 -40 1080 -40 {}
+N 1220 -130 1220 -40 {}
+N 1080 -40 1220 -40 {}
+N 1340 -130 1340 -40 {}
+N 1220 -40 1340 -40 {}
+N 730 -130 760 -130 {}
+N 760 -130 760 -80 {}
+N 730 -80 760 -80 {}
+N 840 -130 870 -130 {}
+N 870 -130 870 -80 {}
+N 840 -80 870 -80 {}
+N 980 -130 1010 -130 {}
+N 1010 -130 1010 -80 {}
+N 980 -80 1010 -80 {}
+N 1120 -130 1150 -130 {}
+N 1150 -130 1150 -80 {}
+N 1120 -80 1150 -80 {}
+N 1260 -130 1290 -130 {}
+N 1290 -130 1290 -80 {}
+N 1260 -80 1290 -80 {}
+N 1380 -130 1410 -130 {}
+N 1410 -130 1410 -80 {}
+N 1380 -80 1410 -80 {}
+N 1490 -130 1520 -130 {}
+N 1520 -130 1520 -80 {}
+N 1490 -80 1520 -80 {}
+N -1380 -340 -1290 -340 {}
+N -1290 -380 -1290 -340 {}
+N 200 370 280 370 {}
+N 280 290 280 370 {}
+N 70 370 140 370 {}
+N 70 330 70 370 {}
+N -40 330 70 330 {}
+N -1110 40 -1110 130 {}
+N -1290 130 -1110 130 {}
+N -980 40 -980 130 {}
+N -1110 130 -980 130 {}
+N -840 40 -840 130 {}
+N -980 130 -840 130 {}
+N -700 40 -700 130 {}
+N -840 130 -700 130 {}
+N -580 40 -580 130 {}
+N -700 130 -580 130 {}
+N -470 40 -470 130 {}
+N -580 130 -470 130 {}
+N -330 40 -330 130 {}
+N -470 130 -330 130 {}
+N -190 40 -190 130 {}
+N -330 130 -190 130 {}
+N -50 40 -50 130 {}
+N -190 130 -50 130 {}
+N 70 40 70 130 {}
+N -50 130 70 130 {}
+N 180 40 180 130 {}
+N 70 130 180 130 {}
+N 310 40 310 130 {}
+N 180 130 310 130 {}
+N 450 40 450 130 {}
+N 310 130 450 130 {}
+N -1180 40 -1150 40 {}
+N -1150 40 -1150 90 {}
+N -1180 90 -1150 90 {}
+N -1070 40 -1050 40 {}
+N -1050 40 -1050 90 {}
+N -1070 90 -1050 90 {}
+N -940 40 -910 40 {}
+N -910 40 -910 90 {}
+N -940 90 -910 90 {}
+N -800 40 -780 40 {}
+N -780 40 -780 90 {}
+N -800 90 -780 90 {}
+N -660 40 -640 40 {}
+N -640 40 -640 90 {}
+N -660 90 -640 90 {}
+N -540 40 -520 40 {}
+N -520 40 -520 90 {}
+N -540 90 -520 90 {}
+N -430 40 -400 40 {}
+N -400 40 -400 90 {}
+N -430 90 -400 90 {}
+N -290 40 -270 40 {}
+N -270 40 -270 90 {}
+N -290 90 -270 90 {}
+N -150 40 -130 40 {}
+N -130 40 -130 90 {}
+N -150 90 -130 90 {}
+N -10 40 10 40 {}
+N 10 40 10 90 {}
+N -10 90 10 90 {}
+N 110 40 130 40 {}
+N 130 40 130 90 {}
+N 110 90 130 90 {}
+N 220 40 240 40 {}
+N 240 90 350 90 {}
+N 240 40 240 90 {}
+N 220 90 240 90 {}
+N 350 40 370 40 {}
+N 370 40 370 90 {}
+N 350 90 370 90 {}
+N -1100 220 -1100 330 {}
+N -1290 330 -1100 330 {}
+N -970 220 -970 330 {}
+N -1100 330 -970 330 {}
+N -830 220 -830 330 {}
+N -970 330 -830 330 {}
+N -690 220 -690 330 {}
+N -830 330 -690 330 {}
+N -570 220 -570 330 {}
+N -690 330 -570 330 {}
+N -460 220 -460 330 {}
+N -570 330 -460 330 {}
+N -320 220 -320 330 {}
+N -460 330 -320 330 {}
+N -180 220 -180 330 {}
+N -320 330 -180 330 {}
+N -40 220 -40 330 {}
+N -180 330 -40 330 {}
+N 80 220 80 330 {}
+N 70 330 80 330 {}
+N 190 220 190 330 {}
+N 80 330 190 330 {}
+N 320 220 320 330 {}
+N 190 330 320 330 {}
+N 460 220 460 330 {}
+N 320 330 460 330 {}
+N -1170 220 -1140 220 {}
+N -1140 220 -1140 290 {}
+N -1170 290 -1140 290 {}
+N -1060 220 -1040 220 {}
+N -1040 220 -1040 290 {}
+N -1060 290 -1040 290 {}
+N -930 220 -910 220 {}
+N -910 220 -910 290 {}
+N -930 290 -910 290 {}
+N -790 220 -770 220 {}
+N -770 220 -770 290 {}
+N -790 290 -770 290 {}
+N -650 220 -630 220 {}
+N -630 220 -630 290 {}
+N -650 290 -630 290 {}
+N -530 220 -510 220 {}
+N -510 220 -510 290 {}
+N -530 290 -510 290 {}
+N -420 220 -400 220 {}
+N -400 220 -400 290 {}
+N -420 290 -400 290 {}
+N -280 220 -260 220 {}
+N -260 220 -260 290 {}
+N -280 290 -260 290 {}
+N -140 220 -120 220 {}
+N -120 220 -120 290 {}
+N -140 290 -120 290 {}
+N -0 220 20 220 {}
+N 20 220 20 290 {}
+N 0 290 20 290 {}
+N 120 220 140 220 {}
+N 140 220 140 290 {}
+N 120 290 140 290 {}
+N 230 220 250 220 {}
+N 250 220 250 290 {}
+N 230 290 250 290 {}
+N 360 220 380 220 {}
+N 380 220 380 290 {}
+N 360 290 380 290 {}
+N 590 40 590 130 {}
+N 450 130 590 130 {}
+N 710 40 710 130 {}
+N 590 130 710 130 {}
+N 820 40 820 130 {}
+N 710 130 820 130 {}
+N 960 40 960 130 {}
+N 820 130 960 130 {}
+N 1100 40 1100 130 {}
+N 960 130 1100 130 {}
+N 1240 40 1240 130 {}
+N 1100 130 1240 130 {}
+N 1360 40 1360 130 {}
+N 1240 130 1360 130 {}
+N 600 220 600 330 {}
+N 460 330 600 330 {}
+N 720 220 720 330 {}
+N 600 330 720 330 {}
+N 830 220 830 330 {}
+N 720 330 830 330 {}
+N 970 220 970 330 {}
+N 830 330 970 330 {}
+N 1110 220 1110 330 {}
+N 970 330 1110 330 {}
+N 1250 220 1250 330 {}
+N 1110 330 1250 330 {}
+N 1370 220 1370 330 {}
+N 1250 330 1370 330 {}
+N 500 220 530 220 {}
+N 530 220 530 290 {}
+N 500 290 530 290 {}
+N 640 220 670 220 {}
+N 670 220 670 290 {}
+N 640 290 670 290 {}
+N 760 220 790 220 {}
+N 790 220 790 290 {}
+N 760 290 790 290 {}
+N 870 220 900 220 {}
+N 900 220 900 290 {}
+N 870 290 900 290 {}
+N 1010 220 1040 220 {}
+N 1040 220 1040 290 {}
+N 1010 290 1040 290 {}
+N 1150 220 1180 220 {}
+N 1180 220 1180 290 {}
+N 1150 290 1180 290 {}
+N 1290 220 1320 220 {}
+N 1320 220 1320 290 {}
+N 1290 290 1320 290 {}
+N 1410 220 1430 220 {}
+N 1430 220 1430 290 {}
+N 1410 290 1430 290 {}
+N 1520 220 1540 220 {}
+N 1540 220 1540 290 {}
+N 1520 290 1540 290 {}
+N 860 40 890 40 {}
+N 890 40 890 90 {}
+N 860 90 890 90 {}
+N 490 40 510 40 {}
+N 510 40 510 90 {}
+N 490 90 510 90 {}
+N 630 40 660 40 {}
+N 660 40 660 90 {}
+N 630 90 660 90 {}
+N 750 40 770 40 {}
+N 770 40 770 90 {}
+N 750 90 770 90 {}
+N 1000 40 1020 40 {}
+N 1020 40 1020 90 {}
+N 1000 90 1020 90 {}
+N 1140 40 1170 40 {}
+N 1170 40 1170 90 {}
+N 1140 90 1170 90 {}
+N 1280 40 1310 40 {}
+N 1310 40 1310 90 {}
+N 1280 90 1310 90 {}
+N 1400 40 1430 40 {}
+N 1430 40 1430 90 {}
+N 1400 90 1430 90 {}
+N 1510 40 1530 40 {}
+N 1530 40 1530 90 {}
+N 1510 90 1530 90 {}
+N 510 -1060 610 -1060 {}
+C {sg13g2_pr/sg13_hv_nmos.sym} -30 40 2 1 {name=M1
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 90 40 2 1 {name=M2
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 200 40 2 1 {name=M3
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -170 40 2 1 {name=M4
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -310 40 2 1 {name=M5
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -680 40 2 1 {name=M6
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -560 40 2 1 {name=M7
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -450 40 2 1 {name=M8
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -820 40 2 1 {name=M9
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -960 40 2 1 {name=M10
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1260 40 2 1 {name=M11
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1380 40 2 1 {name=M12
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1490 40 2 1 {name=M13
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1120 40 2 1 {name=M14
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 980 40 2 1 {name=M15
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 610 40 2 1 {name=M16
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 730 40 2 1 {name=M17
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 840 40 2 1 {name=M18
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 470 40 2 1 {name=M19
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 330 40 2 1 {name=M20
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1460 -630 2 1 {name=M21
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -1200 40 2 1 {name=M22
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -1090 40 2 1 {name=M23
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1320 -630 2 1 {name=M24
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1180 -630 2 1 {name=M25
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 810 -630 2 1 {name=M26
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 930 -630 2 1 {name=M27
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1040 -630 2 1 {name=M28
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 670 -630 2 1 {name=M29
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 530 -630 2 1 {name=M30
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 140 -630 2 1 {name=M31
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 260 -630 2 1 {name=M32
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 370 -630 2 1 {name=M33
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 0 -630 2 1 {name=M34
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -140 -630 2 1 {name=M35
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -510 -630 2 1 {name=M36
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -390 -630 2 1 {name=M37
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -280 -630 2 1 {name=M38
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -650 -630 2 1 {name=M39
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -790 -630 2 1 {name=M40
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -970 -630 2 1 {name=M41
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -1110 -630 2 1 {name=M42
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -1250 -630 2 1 {name=M43
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -20 220 2 1 {name=M44
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 100 220 2 1 {name=M45
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 210 220 2 1 {name=M46
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -160 220 2 1 {name=M47
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -300 220 2 1 {name=M48
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -670 220 2 1 {name=M49
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -550 220 2 1 {name=M50
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -440 220 2 1 {name=M51
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -810 220 2 1 {name=M52
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -950 220 2 1 {name=M53
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1270 220 2 1 {name=M54
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1390 220 2 1 {name=M55
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1500 220 2 1 {name=M56
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1130 220 2 1 {name=M57
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 990 220 2 1 {name=M58
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 620 220 2 1 {name=M59
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 740 220 2 1 {name=M60
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 850 220 2 1 {name=M61
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 480 220 2 1 {name=M62
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 340 220 2 1 {name=M63
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1470 -450 2 1 {name=M64
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -1190 220 2 1 {name=M65
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -1080 220 2 1 {name=M66
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1330 -450 2 1 {name=M67
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1190 -450 2 1 {name=M68
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 820 -450 2 1 {name=M69
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 940 -450 2 1 {name=M70
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1050 -450 2 1 {name=M71
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 680 -450 2 1 {name=M72
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 540 -450 2 1 {name=M73
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 150 -450 2 1 {name=M74
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 270 -450 2 1 {name=M75
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 380 -450 2 1 {name=M76
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 10 -450 2 1 {name=M77
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -130 -450 2 1 {name=M78
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -500 -450 2 1 {name=M79
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -380 -450 2 1 {name=M80
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -270 -450 2 1 {name=M81
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -640 -450 2 1 {name=M82
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -780 -450 2 1 {name=M83
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -960 -450 2 1 {name=M84
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -1100 -450 2 1 {name=M85
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -1240 -450 2 1 {name=M86
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -50 -130 2 1 {name=M87
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 70 -130 2 1 {name=M88
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 180 -130 2 1 {name=M89
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -190 -130 2 1 {name=M90
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -330 -130 2 1 {name=M91
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -700 -130 2 1 {name=M92
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -580 -130 2 1 {name=M93
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -470 -130 2 1 {name=M94
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -840 -130 2 1 {name=M95
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -980 -130 2 1 {name=M96
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1240 -130 2 1 {name=M97
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1360 -130 2 1 {name=M98
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1470 -130 2 1 {name=M99
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1100 -130 2 1 {name=M100
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 960 -130 2 1 {name=M101
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 590 -130 2 1 {name=M102
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 710 -130 2 1 {name=M103
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 820 -130 2 1 {name=M104
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 450 -130 2 1 {name=M105
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 310 -130 2 1 {name=M106
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1440 -800 2 1 {name=M107
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -1220 -130 2 1 {name=M108
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -1110 -130 2 1 {name=M109
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1300 -800 2 1 {name=M110
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1160 -800 2 1 {name=M111
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 790 -800 2 1 {name=M112
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 910 -800 2 1 {name=M113
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1020 -800 2 1 {name=M114
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 650 -800 2 1 {name=M115
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 510 -800 2 1 {name=M116
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 120 -800 2 1 {name=M117
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 240 -800 2 1 {name=M118
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 350 -800 2 1 {name=M119
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -20 -800 2 1 {name=M120
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -160 -800 2 1 {name=M121
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -530 -800 2 1 {name=M122
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -410 -800 2 1 {name=M123
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -300 -800 2 1 {name=M124
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -670 -800 2 1 {name=M125
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -810 -800 2 1 {name=M126
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -990 -800 2 1 {name=M127
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -1130 -800 2 1 {name=M128
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -1270 -800 2 1 {name=M129
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -50 -280 2 1 {name=M130
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 70 -280 2 1 {name=M131
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 180 -280 2 1 {name=M132
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -190 -280 2 1 {name=M133
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -330 -280 2 1 {name=M134
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -700 -280 2 1 {name=M135
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -580 -280 2 1 {name=M136
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -470 -280 2 1 {name=M137
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -840 -280 2 1 {name=M138
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -980 -280 2 1 {name=M139
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1240 -280 2 1 {name=M140
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1360 -280 2 1 {name=M141
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1470 -280 2 1 {name=M142
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1100 -280 2 1 {name=M143
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 960 -280 2 1 {name=M144
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 590 -280 2 1 {name=M145
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 710 -280 2 1 {name=M146
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 820 -280 2 1 {name=M147
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 450 -280 2 1 {name=M148
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 310 -280 2 1 {name=M149
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1440 -950 2 1 {name=M150
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -1220 -280 2 1 {name=M151
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -1110 -280 2 1 {name=M152
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1300 -950 2 1 {name=M153
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1160 -950 2 1 {name=M154
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 790 -950 2 1 {name=M155
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 910 -950 2 1 {name=M156
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1020 -950 2 1 {name=M157
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 650 -950 2 1 {name=M158
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 510 -950 2 1 {name=M159
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 120 -950 2 1 {name=M160
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 240 -950 2 1 {name=M161
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 350 -950 2 1 {name=M162
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -20 -950 2 1 {name=M163
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -160 -950 2 1 {name=M164
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -530 -950 2 1 {name=M165
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -410 -950 2 1 {name=M166
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -300 -950 2 1 {name=M167
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -670 -950 2 1 {name=M168
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -810 -950 2 1 {name=M169
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -990 -950 2 1 {name=M170
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -1130 -950 2 1 {name=M171
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -1270 -950 2 1 {name=M172
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {devices/iopin.sym} 80 -1070 0 0 {name=pad lab=pad}
+C {devices/iopin.sym} 280 390 0 0 {name=iovss lab=iovss}
+C {devices/iopin.sym} -1380 -340 0 0 {name=gate lab=gate}
+C {sg13g2_pr/dantenna.sym} 170 370 3 0 {name=D1
+model=dantenna
+l=0.64u
+w=0.48u
+spiceprefix=X
+}
+C {devices/iopin.sym} 610 -1060 0 0 {name=iovdd lab=iovdd}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N43N43D4R.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N43N43D4R.sym
new file mode 100644
index 00000000..0d713842
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N43N43D4R.sym
@@ -0,0 +1,25 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+L 4 -130 -40 130 -40 {}
+L 4 -130 40 130 40 {}
+L 4 -130 -40 -130 40 {}
+L 4 130 -40 130 40 {}
+L 7 130 0 150 0 {}
+L 7 10 -60 10 -40 {}
+L 7 -150 0 -130 0 {}
+L 7 10 40 10 60 {}
+B 5 147.5 -2.5 152.5 2.5 {name=pad dir=inout}
+B 5 7.5 -62.5 12.5 -57.5 {name=iovdd dir=inout}
+B 5 -152.5 -2.5 -147.5 2.5 {name=gate dir=inout}
+B 5 7.5 57.5 12.5 62.5 {name=iovss dir=inout}
+T {sg13g2_Clamp_N43N43D4R} -77 -6 0 0 0.2 0.2 {}
+T {@name} 135 -52 0 0 0.2 0.2 {}
+T {pad} 125 -4 0 1 0.2 0.2 {}
+T {iovdd} 45 -54 0 1 0.2 0.2 {}
+T {gate} -105 -14 0 1 0.2 0.2 {}
+T {iovss} 45 46 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N8N8D.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N8N8D.sch
new file mode 100644
index 00000000..bc73c6cb
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N8N8D.sch
@@ -0,0 +1,241 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 590 -530 590 -510 {
+lab=iovss}
+N 1490 -510 1500 -510 {
+lab=iovss}
+N 1500 -530 1500 -510 {
+lab=iovss}
+N 1370 -530 1370 -510 {
+lab=iovss}
+N 1260 -510 1370 -510 {
+lab=iovss}
+N 1230 -530 1230 -510 {
+lab=iovss}
+N 1130 -510 1230 -510 {
+lab=iovss}
+N 1100 -530 1100 -510 {
+lab=iovss}
+N 1010 -510 1100 -510 {
+lab=iovss}
+N 980 -530 980 -510 {
+lab=iovss}
+N 890 -510 980 -510 {
+lab=iovss}
+N 860 -530 860 -510 {
+lab=iovss}
+N 760 -510 860 -510 {
+lab=iovss}
+N 730 -530 730 -510 {
+lab=iovss}
+N 630 -510 730 -510 {
+lab=iovss}
+N 590 -560 630 -560 {
+lab=iovss}
+N 630 -560 630 -510 {
+lab=iovss}
+N 590 -510 630 -510 {
+lab=iovss}
+N 730 -560 760 -560 {
+lab=iovss}
+N 760 -560 760 -510 {
+lab=iovss}
+N 730 -510 760 -510 {
+lab=iovss}
+N 860 -560 890 -560 {
+lab=iovss}
+N 890 -560 890 -510 {
+lab=iovss}
+N 860 -510 890 -510 {
+lab=iovss}
+N 980 -560 1010 -560 {
+lab=iovss}
+N 1010 -560 1010 -510 {
+lab=iovss}
+N 980 -510 1010 -510 {
+lab=iovss}
+N 1100 -560 1130 -560 {
+lab=iovss}
+N 1130 -560 1130 -510 {
+lab=iovss}
+N 1100 -510 1130 -510 {
+lab=iovss}
+N 1230 -560 1260 -560 {
+lab=iovss}
+N 1260 -560 1260 -510 {
+lab=iovss}
+N 1230 -510 1260 -510 {
+lab=iovss}
+N 1370 -560 1390 -560 {
+lab=iovss}
+N 1390 -560 1390 -510 {
+lab=iovss}
+N 1370 -510 1390 -510 {
+lab=iovss}
+N 1500 -560 1530 -560 {
+lab=iovss}
+N 1530 -560 1530 -510 {
+lab=iovss}
+N 1500 -510 1530 -510 {
+lab=iovss}
+N 590 -640 590 -590 {
+lab=pad}
+N 1370 -640 1500 -640 {
+lab=pad}
+N 1500 -640 1500 -590 {
+lab=pad}
+N 1370 -640 1370 -590 {
+lab=pad}
+N 1230 -640 1370 -640 {
+lab=pad}
+N 1230 -640 1230 -590 {
+lab=pad}
+N 1150 -640 1230 -640 {
+lab=pad}
+N 1100 -640 1100 -590 {
+lab=pad}
+N 980 -640 1100 -640 {
+lab=pad}
+N 980 -640 980 -590 {
+lab=pad}
+N 860 -640 980 -640 {
+lab=pad}
+N 860 -640 860 -590 {
+lab=pad}
+N 730 -640 860 -640 {
+lab=pad}
+N 730 -640 730 -590 {
+lab=pad}
+N 590 -640 730 -640 {
+lab=pad}
+N 530 -560 550 -560 {
+lab=gate}
+N 530 -560 530 -470 {
+lab=gate}
+N 500 -560 530 -560 {
+lab=gate}
+N 1380 -470 1460 -470 {
+lab=gate}
+N 1460 -560 1460 -470 {
+lab=gate}
+N 1330 -560 1330 -470 {
+lab=gate}
+N 1190 -470 1330 -470 {
+lab=gate}
+N 1190 -560 1190 -470 {
+lab=gate}
+N 1060 -470 1190 -470 {
+lab=gate}
+N 1060 -560 1060 -470 {
+lab=gate}
+N 940 -470 1060 -470 {
+lab=gate}
+N 940 -560 940 -470 {
+lab=gate}
+N 820 -470 940 -470 {
+lab=gate}
+N 820 -560 820 -470 {
+lab=gate}
+N 690 -470 820 -470 {
+lab=gate}
+N 690 -560 690 -470 {
+lab=gate}
+N 530 -470 690 -470 {
+lab=gate}
+N 1490 -390 1490 -350 {
+lab=iovss}
+N 1390 -510 1490 -510 {
+lab=iovss}
+N 1150 -700 1150 -640 {
+lab=pad}
+N 1100 -640 1150 -640 {
+lab=pad}
+N 1380 -390 1490 -390 {
+lab=iovss}
+N 1490 -510 1490 -390 {
+lab=iovss}
+N 1380 -470 1380 -450 {
+lab=gate}
+N 1330 -470 1380 -470 {
+lab=gate}
+N 860 -720 860 -690 {
+lab=iovdd}
+C {sg13g2_pr/sg13_hv_nmos.sym} 840 -560 2 1 {name=M1
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 960 -560 2 1 {name=M2
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1080 -560 2 1 {name=M3
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1210 -560 2 1 {name=M4
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1350 -560 2 1 {name=M5
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 710 -560 2 1 {name=M6
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 570 -560 2 1 {name=M7
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1480 -560 2 1 {name=M8
+l=0.6u
+w=4.4u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/dantenna.sym} 1380 -420 0 0 {name=D1
+model=dantenna
+l=0.64u
+w=0.3u
+spiceprefix=X
+}
+C {devices/iopin.sym} 1490 -350 1 0 {name=iovss lab=iovss}
+C {devices/iopin.sym} 1150 -700 3 0 {name=pad lab=pad}
+C {devices/iopin.sym} 500 -560 2 0 {name=gate lab=gate}
+C {devices/iopin.sym} 860 -720 3 0 {name=iovdd lab=iovdd}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N8N8D.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N8N8D.sym
new file mode 100644
index 00000000..b36d60ef
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N8N8D.sym
@@ -0,0 +1,28 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -40 130 -40 {}
+L 4 -130 40 130 40 {}
+L 4 -130 -40 -130 40 {}
+L 4 130 -40 130 40 {}
+L 7 0 -60 0 -40 {}
+L 7 130 0 150 0 {}
+L 7 -150 0 -130 0 {}
+L 7 0 40 0 60 {}
+B 5 -2.5 -62.5 2.5 -57.5 {name=iovdd dir=inout}
+B 5 147.5 -2.5 152.5 2.5 {name=pad dir=inout}
+B 5 -152.5 -2.5 -147.5 2.5 {name=gate dir=inout}
+B 5 -2.5 57.5 2.5 62.5 {name=iovss dir=inout}
+T {sg13g2_Clamp_N8N8D} -59 -6 0 0 0.2 0.2 {}
+T {@name} 135 -52 0 0 0.2 0.2 {}
+T {iovdd} 35 -54 0 1 0.2 0.2 {}
+T {pad} 125 -4 0 1 0.2 0.2 {}
+T {gate} -105 -4 0 1 0.2 0.2 {}
+T {iovss} 35 46 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P15N15D.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P15N15D.sch
new file mode 100644
index 00000000..0d2fa731
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P15N15D.sch
@@ -0,0 +1,795 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 230 -680 230 -640 {
+lab=pad}
+N 1980 -640 2050 -640 {
+lab=pad}
+N 2050 -690 2050 -640 {
+lab=pad}
+N 1920 -690 1920 -640 {
+lab=pad}
+N 1790 -640 1920 -640 {
+lab=pad}
+N 1790 -690 1790 -640 {
+lab=pad}
+N 1660 -640 1790 -640 {
+lab=pad}
+N 1660 -690 1660 -640 {
+lab=pad}
+N 1530 -640 1660 -640 {
+lab=pad}
+N 1530 -690 1530 -640 {
+lab=pad}
+N 1460 -640 1530 -640 {
+lab=pad}
+N 1400 -690 1400 -640 {
+lab=pad}
+N 1270 -640 1400 -640 {
+lab=pad}
+N 1270 -690 1270 -640 {
+lab=pad}
+N 1140 -640 1270 -640 {
+lab=pad}
+N 1140 -690 1140 -640 {
+lab=pad}
+N 1010 -640 1140 -640 {
+lab=pad}
+N 1010 -690 1010 -640 {
+lab=pad}
+N 880 -640 1010 -640 {
+lab=pad}
+N 880 -690 880 -640 {
+lab=pad}
+N 750 -640 880 -640 {
+lab=pad}
+N 750 -680 750 -640 {
+lab=pad}
+N 620 -640 750 -640 {
+lab=pad}
+N 620 -680 620 -640 {
+lab=pad}
+N 490 -640 620 -640 {
+lab=pad}
+N 490 -680 490 -640 {
+lab=pad}
+N 360 -640 490 -640 {
+lab=pad}
+N 360 -680 360 -640 {
+lab=pad}
+N 230 -640 360 -640 {
+lab=pad}
+N 230 -770 230 -740 {
+lab=xxx}
+N 1950 -770 2050 -770 {
+lab=xxx}
+N 2050 -770 2050 -750 {
+lab=xxx}
+N 360 -770 360 -740 {
+lab=xxx}
+N 260 -770 360 -770 {
+lab=xxx}
+N 490 -770 490 -740 {
+lab=xxx}
+N 400 -770 490 -770 {
+lab=xxx}
+N 620 -770 620 -740 {
+lab=xxx}
+N 510 -770 620 -770 {
+lab=xxx}
+N 750 -770 750 -740 {
+lab=xxx}
+N 650 -770 750 -770 {
+lab=xxx}
+N 880 -770 880 -750 {
+lab=xxx}
+N 780 -770 880 -770 {
+lab=xxx}
+N 1010 -770 1010 -750 {
+lab=xxx}
+N 910 -770 1010 -770 {
+lab=xxx}
+N 1140 -770 1140 -750 {
+lab=xxx}
+N 1040 -770 1140 -770 {
+lab=xxx}
+N 1270 -770 1270 -750 {
+lab=xxx}
+N 1170 -770 1270 -770 {
+lab=xxx}
+N 1400 -770 1400 -750 {
+lab=xxx}
+N 1300 -770 1400 -770 {
+lab=xxx}
+N 1530 -770 1530 -750 {
+lab=xxx}
+N 1430 -770 1530 -770 {
+lab=xxx}
+N 1660 -770 1660 -750 {
+lab=xxx}
+N 1560 -770 1660 -770 {
+lab=xxx}
+N 1790 -770 1790 -750 {
+lab=xxx}
+N 1690 -770 1790 -770 {
+lab=xxx}
+N 1920 -770 1920 -750 {
+lab=xxx}
+N 1820 -770 1920 -770 {
+lab=xxx}
+N 360 -710 400 -710 {
+lab=xxx}
+N 400 -770 400 -710 {
+lab=xxx}
+N 360 -770 400 -770 {
+lab=xxx}
+N 490 -710 510 -710 {
+lab=xxx}
+N 510 -770 510 -710 {
+lab=xxx}
+N 490 -770 510 -770 {
+lab=xxx}
+N 620 -710 650 -710 {
+lab=xxx}
+N 650 -770 650 -710 {
+lab=xxx}
+N 620 -770 650 -770 {
+lab=xxx}
+N 750 -710 780 -710 {
+lab=xxx}
+N 780 -770 780 -710 {
+lab=xxx}
+N 750 -770 780 -770 {
+lab=xxx}
+N 880 -720 910 -720 {
+lab=xxx}
+N 910 -770 910 -720 {
+lab=xxx}
+N 880 -770 910 -770 {
+lab=xxx}
+N 1010 -720 1040 -720 {
+lab=xxx}
+N 1040 -770 1040 -720 {
+lab=xxx}
+N 1010 -770 1040 -770 {
+lab=xxx}
+N 1140 -720 1170 -720 {
+lab=xxx}
+N 1170 -770 1170 -720 {
+lab=xxx}
+N 1140 -770 1170 -770 {
+lab=xxx}
+N 1270 -720 1300 -720 {
+lab=xxx}
+N 1300 -770 1300 -720 {
+lab=xxx}
+N 1270 -770 1300 -770 {
+lab=xxx}
+N 1400 -720 1430 -720 {
+lab=xxx}
+N 1430 -770 1430 -720 {
+lab=xxx}
+N 1400 -770 1430 -770 {
+lab=xxx}
+N 1530 -720 1560 -720 {
+lab=xxx}
+N 1560 -770 1560 -720 {
+lab=xxx}
+N 1530 -770 1560 -770 {
+lab=xxx}
+N 1660 -720 1690 -720 {
+lab=xxx}
+N 1690 -770 1690 -720 {
+lab=xxx}
+N 1660 -770 1690 -770 {
+lab=xxx}
+N 1790 -720 1820 -720 {
+lab=xxx}
+N 1820 -770 1820 -720 {
+lab=xxx}
+N 1790 -770 1820 -770 {
+lab=xxx}
+N 1920 -720 1950 -720 {
+lab=xxx}
+N 1950 -770 1950 -720 {
+lab=xxx}
+N 1920 -770 1950 -770 {
+lab=xxx}
+N 2050 -720 2080 -720 {
+lab=xxx}
+N 2080 -770 2080 -720 {
+lab=xxx}
+N 2050 -770 2080 -770 {
+lab=xxx}
+N 230 -710 260 -710 {
+lab=xxx}
+N 260 -770 260 -710 {
+lab=xxx}
+N 230 -770 260 -770 {
+lab=xxx}
+N 230 -840 230 -820 {
+lab=pad}
+N 1980 -820 2050 -820 {
+lab=pad}
+N 2050 -850 2050 -820 {
+lab=pad}
+N 360 -840 360 -820 {
+lab=pad}
+N 230 -820 360 -820 {
+lab=pad}
+N 490 -840 490 -820 {
+lab=pad}
+N 360 -820 490 -820 {
+lab=pad}
+N 620 -840 620 -820 {
+lab=pad}
+N 490 -820 620 -820 {
+lab=pad}
+N 750 -840 750 -820 {
+lab=pad}
+N 620 -820 750 -820 {
+lab=pad}
+N 880 -850 880 -820 {
+lab=pad}
+N 750 -820 880 -820 {
+lab=pad}
+N 1010 -850 1010 -820 {
+lab=pad}
+N 880 -820 1010 -820 {
+lab=pad}
+N 1140 -850 1140 -820 {
+lab=pad}
+N 1010 -820 1140 -820 {
+lab=pad}
+N 1270 -850 1270 -820 {
+lab=pad}
+N 1140 -820 1270 -820 {
+lab=pad}
+N 1400 -850 1400 -820 {
+lab=pad}
+N 1270 -820 1400 -820 {
+lab=pad}
+N 1920 -850 1920 -820 {
+lab=pad}
+N 1790 -820 1920 -820 {
+lab=pad}
+N 1790 -850 1790 -820 {
+lab=pad}
+N 1660 -820 1790 -820 {
+lab=pad}
+N 1660 -850 1660 -820 {
+lab=pad}
+N 1530 -820 1660 -820 {
+lab=pad}
+N 1530 -850 1530 -820 {
+lab=pad}
+N 1400 -820 1530 -820 {
+lab=pad}
+N 230 -940 230 -900 {
+lab=xxx}
+N 1950 -940 2050 -940 {
+lab=xxx}
+N 2050 -940 2050 -910 {
+lab=xxx}
+N 1920 -940 1920 -910 {
+lab=xxx}
+N 1820 -940 1920 -940 {
+lab=xxx}
+N 1790 -940 1790 -910 {
+lab=xxx}
+N 1690 -940 1790 -940 {
+lab=xxx}
+N 1660 -940 1660 -910 {
+lab=xxx}
+N 1560 -940 1660 -940 {
+lab=xxx}
+N 1530 -940 1530 -910 {
+lab=xxx}
+N 1460 -940 1530 -940 {
+lab=xxx}
+N 1400 -940 1400 -910 {
+lab=xxx}
+N 1300 -940 1400 -940 {
+lab=xxx}
+N 1270 -940 1270 -910 {
+lab=xxx}
+N 1140 -940 1140 -910 {
+lab=xxx}
+N 1040 -940 1140 -940 {
+lab=xxx}
+N 1010 -940 1010 -910 {
+lab=xxx}
+N 910 -940 1010 -940 {
+lab=xxx}
+N 880 -940 880 -910 {
+lab=xxx}
+N 780 -940 880 -940 {
+lab=xxx}
+N 750 -940 750 -900 {
+lab=xxx}
+N 650 -940 750 -940 {
+lab=xxx}
+N 620 -940 620 -900 {
+lab=xxx}
+N 520 -940 620 -940 {
+lab=xxx}
+N 490 -940 490 -900 {
+lab=xxx}
+N 380 -940 490 -940 {
+lab=xxx}
+N 360 -940 360 -900 {
+lab=xxx}
+N 250 -940 360 -940 {
+lab=xxx}
+N 230 -870 250 -870 {
+lab=xxx}
+N 250 -940 250 -870 {
+lab=xxx}
+N 230 -940 250 -940 {
+lab=xxx}
+N 360 -870 380 -870 {
+lab=xxx}
+N 380 -940 380 -870 {
+lab=xxx}
+N 360 -940 380 -940 {
+lab=xxx}
+N 490 -870 520 -870 {
+lab=xxx}
+N 520 -940 520 -870 {
+lab=xxx}
+N 490 -940 520 -940 {
+lab=xxx}
+N 620 -870 650 -870 {
+lab=xxx}
+N 650 -940 650 -870 {
+lab=xxx}
+N 620 -940 650 -940 {
+lab=xxx}
+N 750 -870 780 -870 {
+lab=xxx}
+N 780 -940 780 -870 {
+lab=xxx}
+N 750 -940 780 -940 {
+lab=xxx}
+N 880 -880 910 -880 {
+lab=xxx}
+N 910 -940 910 -880 {
+lab=xxx}
+N 880 -940 910 -940 {
+lab=xxx}
+N 1010 -880 1040 -880 {
+lab=xxx}
+N 1040 -940 1040 -880 {
+lab=xxx}
+N 1010 -940 1040 -940 {
+lab=xxx}
+N 1140 -880 1170 -880 {
+lab=xxx}
+N 1170 -940 1270 -940 {
+lab=xxx}
+N 1170 -940 1170 -880 {
+lab=xxx}
+N 1140 -940 1170 -940 {
+lab=xxx}
+N 1270 -880 1300 -880 {
+lab=xxx}
+N 1300 -940 1300 -880 {
+lab=xxx}
+N 1270 -940 1300 -940 {
+lab=xxx}
+N 1400 -880 1430 -880 {
+lab=xxx}
+N 1430 -940 1430 -880 {
+lab=xxx}
+N 1400 -940 1430 -940 {
+lab=xxx}
+N 1530 -880 1560 -880 {
+lab=xxx}
+N 1560 -940 1560 -880 {
+lab=xxx}
+N 1530 -940 1560 -940 {
+lab=xxx}
+N 1660 -880 1690 -880 {
+lab=xxx}
+N 1690 -940 1690 -880 {
+lab=xxx}
+N 1660 -940 1690 -940 {
+lab=xxx}
+N 1790 -880 1820 -880 {
+lab=xxx}
+N 1820 -940 1820 -880 {
+lab=xxx}
+N 1790 -940 1820 -940 {
+lab=xxx}
+N 1920 -880 1950 -880 {
+lab=xxx}
+N 1950 -940 1950 -880 {
+lab=xxx}
+N 1920 -940 1950 -940 {
+lab=xxx}
+N 2050 -880 2090 -880 {
+lab=xxx}
+N 2090 -940 2090 -880 {
+lab=xxx}
+N 2050 -940 2090 -940 {
+lab=xxx}
+N 140 -870 190 -870 {
+lab=gate}
+N 130 -790 130 -710 {
+lab=gate}
+N 130 -710 190 -710 {
+lab=gate}
+N 1880 -790 2010 -790 {
+lab=gate}
+N 130 -830 130 -790 {
+lab=gate}
+N 2010 -880 2010 -790 {
+lab=gate}
+N 2010 -790 2010 -720 {
+lab=gate}
+N 1880 -790 1880 -720 {
+lab=gate}
+N 1750 -790 1880 -790 {
+lab=gate}
+N 1880 -880 1880 -790 {
+lab=gate}
+N 1750 -880 1750 -790 {
+lab=gate}
+N 1620 -790 1750 -790 {
+lab=gate}
+N 1750 -790 1750 -720 {
+lab=gate}
+N 1620 -790 1620 -720 {
+lab=gate}
+N 1490 -790 1620 -790 {
+lab=gate}
+N 1620 -880 1620 -790 {
+lab=gate}
+N 1490 -880 1490 -790 {
+lab=gate}
+N 1360 -790 1490 -790 {
+lab=gate}
+N 1490 -790 1490 -720 {
+lab=gate}
+N 1360 -790 1360 -720 {
+lab=gate}
+N 1230 -790 1360 -790 {
+lab=gate}
+N 1360 -880 1360 -790 {
+lab=gate}
+N 1230 -880 1230 -790 {
+lab=gate}
+N 1100 -790 1230 -790 {
+lab=gate}
+N 1230 -790 1230 -710 {
+lab=gate}
+N 1100 -790 1100 -720 {
+lab=gate}
+N 970 -790 1100 -790 {
+lab=gate}
+N 1100 -880 1100 -790 {
+lab=gate}
+N 970 -880 970 -790 {
+lab=gate}
+N 840 -790 970 -790 {
+lab=gate}
+N 970 -790 970 -720 {
+lab=gate}
+N 840 -880 840 -790 {
+lab=gate}
+N 710 -790 840 -790 {
+lab=gate}
+N 840 -790 840 -720 {
+lab=gate}
+N 710 -870 710 -790 {
+lab=gate}
+N 580 -790 710 -790 {
+lab=gate}
+N 710 -790 710 -710 {
+lab=gate}
+N 580 -870 580 -790 {
+lab=gate}
+N 450 -790 580 -790 {
+lab=gate}
+N 580 -790 580 -710 {
+lab=gate}
+N 450 -870 450 -790 {
+lab=gate}
+N 320 -790 450 -790 {
+lab=gate}
+N 450 -790 450 -710 {
+lab=gate}
+N 320 -870 320 -790 {
+lab=gate}
+N 130 -790 320 -790 {
+lab=gate}
+N 320 -790 320 -710 {
+lab=gate}
+N 1980 -820 1980 -640 {
+lab=pad}
+N 1920 -820 1980 -820 {
+lab=pad}
+N 1920 -640 1980 -640 {
+lab=pad}
+N 2080 -770 2180 -770 {
+lab=xxx}
+N 2180 -940 2180 -770 {
+lab=xxx}
+N 2090 -940 2180 -940 {
+lab=xxx}
+N 1460 -970 1460 -940 {
+lab=xxx}
+N 1430 -940 1460 -940 {
+lab=xxx}
+N 1460 -640 1460 -570 {
+lab=pad}
+N 1400 -640 1460 -640 {
+lab=pad}
+N 60 -830 130 -830 {
+lab=gate}
+N 130 -870 130 -830 {
+lab=gate}
+N 140 -910 140 -870 {
+lab=gate}
+N 130 -870 140 -870 {
+lab=gate}
+N 140 -970 1460 -970 {
+lab=xxx}
+N 1460 -1040 1460 -970 {
+lab=xxx}
+N 1680 -590 1680 -560 {
+lab=iovss}
+C {sg13g2_pr/sg13_hv_pmos.sym} 210 -710 0 0 {name=M1
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 340 -710 0 0 {name=M2
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 470 -710 0 0 {name=M3
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 600 -710 0 0 {name=M4
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 730 -710 0 0 {name=M5
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 860 -720 0 0 {name=M6
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 990 -720 0 0 {name=M7
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1120 -720 0 0 {name=M8
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1250 -720 0 0 {name=M9
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1380 -720 0 0 {name=M10
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1510 -720 0 0 {name=M11
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1640 -720 0 0 {name=M12
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1770 -720 0 0 {name=M13
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1900 -720 0 0 {name=M14
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2030 -720 0 0 {name=M15
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 210 -870 0 0 {name=M16
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 340 -870 0 0 {name=M17
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 470 -870 0 0 {name=M18
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 600 -870 0 0 {name=M19
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 730 -870 0 0 {name=M20
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 860 -880 0 0 {name=M21
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 990 -880 0 0 {name=M22
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1120 -880 0 0 {name=M23
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1250 -880 0 0 {name=M24
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1380 -880 0 0 {name=M25
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1510 -880 0 0 {name=M26
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1640 -880 0 0 {name=M27
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1770 -880 0 0 {name=M28
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1900 -880 0 0 {name=M29
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2030 -880 0 0 {name=M30
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/dpantenna.sym} 140 -940 0 0 {name=D1
+model=dpantenna
+l=0.64u
+w=0.3u
+spiceprefix=X
+}
+C {devices/iopin.sym} 1460 -570 1 0 {name=pad lab=pad}
+C {devices/iopin.sym} 60 -830 2 0 {name=gate lab=gate}
+C {devices/iopin.sym} 1460 -1040 3 0 {name=iovdd lab=iovdd}
+C {devices/iopin.sym} 1680 -560 1 0 {name=iovss lab=iovss}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P15N15D.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P15N15D.sym
new file mode 100644
index 00000000..a23bdeb7
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P15N15D.sym
@@ -0,0 +1,28 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -40 130 -40 {}
+L 4 -130 40 130 40 {}
+L 4 -130 -40 -130 40 {}
+L 4 130 -40 130 40 {}
+L 7 0 -60 0 -40 {}
+L 7 -150 0 -130 0 {}
+L 7 130 0 150 0 {}
+L 7 0 40 0 60 {}
+B 5 -2.5 -62.5 2.5 -57.5 {name=iovdd dir=inout}
+B 5 -152.5 -2.5 -147.5 2.5 {name=gate dir=inout}
+B 5 147.5 -2.5 152.5 2.5 {name=pad dir=inout}
+B 5 -2.5 57.5 2.5 62.5 {name=iovss dir=inout}
+T {sg13g2_Clamp_P15N15D} -48 -6 0 0 0.2 0.2 {}
+T {@name} 135 -52 0 0 0.2 0.2 {}
+T {iovdd} 15 -34 0 1 0.2 0.2 {}
+T {gate} -105 -4 0 1 0.2 0.2 {}
+T {pad} 125 -4 0 1 0.2 0.2 {}
+T {iovss} 15 26 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P20N0D.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P20N0D.sch
new file mode 100644
index 00000000..cd921d29
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P20N0D.sch
@@ -0,0 +1,1034 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 1870 -90 1870 -60 {
+lab=iovdd}
+N 4130 -90 4230 -90 {
+lab=iovdd}
+N 4230 -90 4230 -60 {
+lab=iovdd}
+N 2000 -90 2000 -60 {
+lab=iovdd}
+N 1890 -90 2000 -90 {
+lab=iovdd}
+N 2120 -90 2120 -60 {
+lab=iovdd}
+N 2030 -90 2120 -90 {
+lab=iovdd}
+N 2250 -90 2250 -60 {
+lab=iovdd}
+N 2120 -90 2250 -90 {
+lab=iovdd}
+N 1870 -350 1870 -320 {
+lab=iovdd}
+N 4230 -350 4230 -320 {
+lab=iovdd}
+N 2000 -350 2000 -320 {
+lab=iovdd}
+N 1950 -350 2000 -350 {
+lab=iovdd}
+N 2120 -350 2120 -320 {
+lab=iovdd}
+N 2030 -350 2120 -350 {
+lab=iovdd}
+N 2250 -350 2250 -320 {
+lab=iovdd}
+N 2140 -350 2250 -350 {
+lab=iovdd}
+N 2370 -350 2370 -320 {
+lab=iovdd}
+N 2280 -350 2370 -350 {
+lab=iovdd}
+N 2490 -350 2490 -320 {
+lab=iovdd}
+N 2400 -350 2490 -350 {
+lab=iovdd}
+N 2620 -350 2620 -320 {
+lab=iovdd}
+N 2510 -350 2620 -350 {
+lab=iovdd}
+N 2740 -350 2740 -320 {
+lab=iovdd}
+N 2640 -350 2740 -350 {
+lab=iovdd}
+N 1870 -290 1900 -290 {
+lab=iovdd}
+N 1900 -350 1900 -290 {
+lab=iovdd}
+N 1870 -350 1900 -350 {
+lab=iovdd}
+N 2000 -290 2030 -290 {
+lab=iovdd}
+N 2030 -350 2030 -290 {
+lab=iovdd}
+N 2000 -350 2030 -350 {
+lab=iovdd}
+N 2120 -290 2140 -290 {
+lab=iovdd}
+N 2140 -350 2140 -290 {
+lab=iovdd}
+N 2120 -350 2140 -350 {
+lab=iovdd}
+N 2250 -290 2280 -290 {
+lab=iovdd}
+N 2280 -350 2280 -290 {
+lab=iovdd}
+N 2250 -350 2280 -350 {
+lab=iovdd}
+N 2370 -290 2400 -290 {
+lab=iovdd}
+N 2400 -350 2400 -290 {
+lab=iovdd}
+N 2370 -350 2400 -350 {
+lab=iovdd}
+N 2490 -290 2510 -290 {
+lab=iovdd}
+N 2510 -350 2510 -290 {
+lab=iovdd}
+N 2490 -350 2510 -350 {
+lab=iovdd}
+N 2620 -290 2640 -290 {
+lab=iovdd}
+N 2640 -350 2640 -290 {
+lab=iovdd}
+N 2620 -350 2640 -350 {
+lab=iovdd}
+N 2740 -290 2770 -290 {
+lab=iovdd}
+N 2770 -350 2770 -290 {
+lab=iovdd}
+N 2740 -350 2770 -350 {
+lab=iovdd}
+N 2000 -30 2030 -30 {
+lab=iovdd}
+N 2030 -90 2030 -30 {
+lab=iovdd}
+N 2000 -90 2030 -90 {
+lab=iovdd}
+N 1870 -30 1890 -30 {
+lab=iovdd}
+N 1890 -90 1890 -30 {
+lab=iovdd}
+N 1870 -90 1890 -90 {
+lab=iovdd}
+N 2250 -30 2270 -30 {
+lab=iovdd}
+N 2270 -90 2270 -30 {
+lab=iovdd}
+N 2250 -90 2270 -90 {
+lab=iovdd}
+N 2370 -90 2370 -60 {
+lab=iovdd}
+N 2270 -90 2370 -90 {
+lab=iovdd}
+N 2490 -90 2490 -60 {
+lab=iovdd}
+N 2370 -90 2490 -90 {
+lab=iovdd}
+N 2620 -90 2620 -60 {
+lab=iovdd}
+N 2490 -90 2620 -90 {
+lab=iovdd}
+N 2740 -90 2740 -60 {
+lab=iovdd}
+N 2620 -90 2740 -90 {
+lab=iovdd}
+N 2740 -30 2760 -30 {
+lab=iovdd}
+N 2760 -90 2760 -30 {
+lab=iovdd}
+N 2740 -90 2760 -90 {
+lab=iovdd}
+N 2870 -90 2870 -60 {
+lab=iovdd}
+N 2760 -90 2870 -90 {
+lab=iovdd}
+N 2870 -30 2900 -30 {
+lab=iovdd}
+N 2900 -90 2900 -30 {
+lab=iovdd}
+N 2870 -90 2900 -90 {
+lab=iovdd}
+N 2990 -70 2990 -60 {
+lab=iovdd}
+N 2900 -90 2990 -90 {
+lab=iovdd}
+N 2990 -30 3010 -30 {
+lab=iovdd}
+N 3010 -70 3010 -30 {
+lab=iovdd}
+N 2990 -70 3010 -70 {
+lab=iovdd}
+N 2990 -90 2990 -70 {
+lab=iovdd}
+N 3110 -90 3110 -60 {
+lab=iovdd}
+N 2990 -90 3110 -90 {
+lab=iovdd}
+N 3110 -30 3140 -30 {
+lab=iovdd}
+N 3140 -90 3140 -30 {
+lab=iovdd}
+N 3110 -90 3140 -90 {
+lab=iovdd}
+N 3240 -90 3240 -60 {
+lab=iovdd}
+N 3140 -90 3240 -90 {
+lab=iovdd}
+N 3240 -30 3260 -30 {
+lab=iovdd}
+N 3260 -90 3260 -30 {
+lab=iovdd}
+N 3240 -90 3260 -90 {
+lab=iovdd}
+N 3360 -70 3360 -60 {
+lab=iovdd}
+N 3260 -90 3360 -90 {
+lab=iovdd}
+N 3360 -30 3390 -30 {
+lab=iovdd}
+N 3390 -70 3390 -30 {
+lab=iovdd}
+N 3360 -70 3390 -70 {
+lab=iovdd}
+N 3360 -90 3360 -70 {
+lab=iovdd}
+N 2870 -330 2870 -320 {
+lab=iovdd}
+N 2770 -350 2870 -350 {
+lab=iovdd}
+N 2990 -330 2990 -320 {
+lab=iovdd}
+N 2870 -350 2990 -350 {
+lab=iovdd}
+N 3110 -350 3110 -320 {
+lab=iovdd}
+N 2990 -350 3110 -350 {
+lab=iovdd}
+N 3240 -350 3240 -320 {
+lab=iovdd}
+N 3140 -350 3240 -350 {
+lab=iovdd}
+N 3360 -350 3360 -320 {
+lab=iovdd}
+N 3270 -350 3360 -350 {
+lab=iovdd}
+N 2870 -290 2890 -290 {
+lab=iovdd}
+N 2890 -330 2890 -290 {
+lab=iovdd}
+N 2870 -330 2890 -330 {
+lab=iovdd}
+N 2870 -350 2870 -330 {
+lab=iovdd}
+N 2990 -290 3020 -290 {
+lab=iovdd}
+N 3020 -330 3020 -290 {
+lab=iovdd}
+N 2990 -330 3020 -330 {
+lab=iovdd}
+N 2990 -350 2990 -330 {
+lab=iovdd}
+N 3110 -290 3140 -290 {
+lab=iovdd}
+N 3140 -350 3140 -290 {
+lab=iovdd}
+N 3110 -350 3140 -350 {
+lab=iovdd}
+N 3240 -290 3270 -290 {
+lab=iovdd}
+N 3270 -350 3270 -290 {
+lab=iovdd}
+N 3240 -350 3270 -350 {
+lab=iovdd}
+N 3360 -290 3390 -290 {
+lab=iovdd}
+N 3390 -350 3390 -290 {
+lab=iovdd}
+N 3360 -350 3390 -350 {
+lab=iovdd}
+N 3490 -350 3490 -320 {
+lab=iovdd}
+N 3390 -350 3490 -350 {
+lab=iovdd}
+N 3610 -350 3610 -320 {
+lab=iovdd}
+N 3520 -350 3610 -350 {
+lab=iovdd}
+N 3730 -350 3730 -320 {
+lab=iovdd}
+N 3640 -350 3730 -350 {
+lab=iovdd}
+N 3860 -350 3860 -320 {
+lab=iovdd}
+N 3760 -350 3860 -350 {
+lab=iovdd}
+N 3980 -350 3980 -320 {
+lab=iovdd}
+N 3890 -350 3980 -350 {
+lab=iovdd}
+N 4110 -350 4110 -320 {
+lab=iovdd}
+N 4000 -350 4110 -350 {
+lab=iovdd}
+N 3490 -290 3520 -290 {
+lab=iovdd}
+N 3520 -350 3520 -290 {
+lab=iovdd}
+N 3490 -350 3520 -350 {
+lab=iovdd}
+N 3610 -290 3640 -290 {
+lab=iovdd}
+N 3640 -350 3640 -290 {
+lab=iovdd}
+N 3610 -350 3640 -350 {
+lab=iovdd}
+N 3730 -290 3760 -290 {
+lab=iovdd}
+N 3760 -350 3760 -290 {
+lab=iovdd}
+N 3730 -350 3760 -350 {
+lab=iovdd}
+N 3860 -290 3890 -290 {
+lab=iovdd}
+N 3890 -350 3890 -290 {
+lab=iovdd}
+N 3860 -350 3890 -350 {
+lab=iovdd}
+N 3980 -290 4000 -290 {
+lab=iovdd}
+N 4000 -350 4000 -290 {
+lab=iovdd}
+N 3980 -350 4000 -350 {
+lab=iovdd}
+N 4110 -290 4130 -290 {
+lab=iovdd}
+N 4130 -350 4130 -290 {
+lab=iovdd}
+N 4110 -350 4130 -350 {
+lab=iovdd}
+N 4230 -290 4260 -290 {
+lab=iovdd}
+N 4260 -350 4260 -290 {
+lab=iovdd}
+N 4130 -350 4230 -350 {
+lab=iovdd}
+N 3490 -80 3490 -60 {
+lab=iovdd}
+N 3360 -90 3490 -90 {
+lab=iovdd}
+N 3610 -70 3610 -60 {
+lab=iovdd}
+N 3490 -90 3610 -90 {
+lab=iovdd}
+N 4110 -90 4110 -60 {
+lab=iovdd}
+N 4010 -90 4110 -90 {
+lab=iovdd}
+N 3980 -90 3980 -60 {
+lab=iovdd}
+N 3880 -90 3980 -90 {
+lab=iovdd}
+N 3860 -90 3860 -60 {
+lab=iovdd}
+N 3760 -90 3860 -90 {
+lab=iovdd}
+N 3730 -90 3730 -60 {
+lab=iovdd}
+N 3610 -90 3730 -90 {
+lab=iovdd}
+N 3610 -30 3640 -30 {
+lab=iovdd}
+N 3640 -70 3640 -30 {
+lab=iovdd}
+N 3610 -70 3640 -70 {
+lab=iovdd}
+N 3610 -90 3610 -70 {
+lab=iovdd}
+N 3490 -30 3520 -30 {
+lab=iovdd}
+N 3520 -80 3520 -30 {
+lab=iovdd}
+N 3490 -80 3520 -80 {
+lab=iovdd}
+N 3490 -90 3490 -80 {
+lab=iovdd}
+N 3730 -30 3760 -30 {
+lab=iovdd}
+N 3760 -90 3760 -30 {
+lab=iovdd}
+N 3730 -90 3760 -90 {
+lab=iovdd}
+N 3860 -30 3880 -30 {
+lab=iovdd}
+N 3880 -90 3880 -30 {
+lab=iovdd}
+N 3860 -90 3880 -90 {
+lab=iovdd}
+N 3980 -30 4010 -30 {
+lab=iovdd}
+N 4010 -90 4010 -30 {
+lab=iovdd}
+N 3980 -90 4010 -90 {
+lab=iovdd}
+N 4110 -30 4130 -30 {
+lab=iovdd}
+N 4130 -90 4130 -30 {
+lab=iovdd}
+N 4110 -90 4130 -90 {
+lab=iovdd}
+N 4230 -30 4260 -30 {
+lab=iovdd}
+N 4260 -90 4260 -30 {
+lab=iovdd}
+N 4260 -350 4330 -350 {
+lab=iovdd}
+N 4230 -350 4260 -350 {
+lab=iovdd}
+N 4330 -350 4330 -90 {
+lab=iovdd}
+N 4260 -90 4330 -90 {
+lab=iovdd}
+N 4230 -90 4260 -90 {
+lab=iovdd}
+N 1870 -260 1870 -230 {
+lab=pad}
+N 4230 -260 4230 -230 {
+lab=pad}
+N 4110 -230 4230 -230 {
+lab=pad}
+N 1870 0 1870 30 {
+lab=pad}
+N 4110 30 4230 30 {
+lab=pad}
+N 4230 -0 4230 30 {
+lab=pad}
+N 1780 -290 1830 -290 {
+lab=#net1}
+N 1780 -160 1780 -30 {
+lab=#net1}
+N 1780 -30 1830 -30 {
+lab=#net1}
+N 4070 -160 4190 -160 {
+lab=#net1}
+N 1780 -210 1780 -160 {
+lab=#net1}
+N 4190 -290 4190 -160 {
+lab=#net1}
+N 1700 -210 1780 -210 {
+lab=#net1}
+N 1780 -290 1780 -210 {
+lab=#net1}
+N 1960 -290 1960 -160 {
+lab=#net1}
+N 1780 -160 1960 -160 {
+lab=#net1}
+N 1960 -160 1960 -30 {
+lab=#net1}
+N 2080 -290 2080 -160 {
+lab=#net1}
+N 1960 -160 2080 -160 {
+lab=#net1}
+N 2080 -160 2080 -30 {
+lab=#net1}
+N 2210 -290 2210 -160 {
+lab=#net1}
+N 2080 -160 2210 -160 {
+lab=#net1}
+N 2210 -160 2210 -30 {
+lab=#net1}
+N 2330 -290 2330 -160 {
+lab=#net1}
+N 2210 -160 2330 -160 {
+lab=#net1}
+N 2330 -160 2330 -30 {
+lab=#net1}
+N 2450 -290 2450 -160 {
+lab=#net1}
+N 2330 -160 2450 -160 {
+lab=#net1}
+N 2450 -160 2450 -30 {
+lab=#net1}
+N 2580 -290 2580 -160 {
+lab=#net1}
+N 2450 -160 2580 -160 {
+lab=#net1}
+N 2580 -160 2580 -30 {
+lab=#net1}
+N 2700 -290 2700 -160 {
+lab=#net1}
+N 2580 -160 2700 -160 {
+lab=#net1}
+N 2700 -160 2700 -30 {
+lab=#net1}
+N 2830 -290 2830 -160 {
+lab=#net1}
+N 2700 -160 2830 -160 {
+lab=#net1}
+N 2830 -160 2830 -30 {
+lab=#net1}
+N 2950 -290 2950 -160 {
+lab=#net1}
+N 2830 -160 2950 -160 {
+lab=#net1}
+N 2950 -160 2950 -30 {
+lab=#net1}
+N 3070 -290 3070 -160 {
+lab=#net1}
+N 2950 -160 3070 -160 {
+lab=#net1}
+N 3070 -160 3070 -30 {
+lab=#net1}
+N 3200 -290 3200 -160 {
+lab=#net1}
+N 3070 -160 3200 -160 {
+lab=#net1}
+N 3200 -160 3200 -30 {
+lab=#net1}
+N 3320 -290 3320 -160 {
+lab=#net1}
+N 3200 -160 3320 -160 {
+lab=#net1}
+N 3320 -160 3320 -30 {
+lab=#net1}
+N 3450 -290 3450 -160 {
+lab=#net1}
+N 3320 -160 3450 -160 {
+lab=#net1}
+N 3450 -160 3450 -30 {
+lab=#net1}
+N 3570 -290 3570 -160 {
+lab=#net1}
+N 3450 -160 3570 -160 {
+lab=#net1}
+N 3570 -160 3570 -30 {
+lab=#net1}
+N 3690 -290 3690 -160 {
+lab=#net1}
+N 3570 -160 3690 -160 {
+lab=#net1}
+N 3690 -160 3690 -30 {
+lab=#net1}
+N 3820 -290 3820 -160 {
+lab=#net1}
+N 3690 -160 3820 -160 {
+lab=#net1}
+N 3820 -160 3820 -30 {
+lab=#net1}
+N 3940 -290 3940 -160 {
+lab=#net1}
+N 3820 -160 3940 -160 {
+lab=#net1}
+N 3940 -160 3940 -30 {
+lab=#net1}
+N 4070 -290 4070 -160 {
+lab=#net1}
+N 3940 -160 4070 -160 {
+lab=#net1}
+N 4070 -160 4070 -30 {
+lab=#net1}
+N 4190 -160 4190 -30 {
+lab=#net1}
+N 2000 0 2000 30 {
+lab=pad}
+N 1930 30 2000 30 {
+lab=pad}
+N 2120 -0 2120 30 {
+lab=pad}
+N 2070 30 2120 30 {
+lab=pad}
+N 2250 0 2250 30 {
+lab=pad}
+N 2120 30 2250 30 {
+lab=pad}
+N 2370 0 2370 30 {
+lab=pad}
+N 2250 30 2370 30 {
+lab=pad}
+N 2490 0 2490 30 {
+lab=pad}
+N 2370 30 2490 30 {
+lab=pad}
+N 2620 0 2620 30 {
+lab=pad}
+N 2490 30 2620 30 {
+lab=pad}
+N 2740 0 2740 30 {
+lab=pad}
+N 2620 30 2740 30 {
+lab=pad}
+N 2870 0 2870 30 {
+lab=pad}
+N 2740 30 2870 30 {
+lab=pad}
+N 2990 0 2990 30 {
+lab=pad}
+N 2870 30 2990 30 {
+lab=pad}
+N 3110 0 3110 30 {
+lab=pad}
+N 2990 30 3110 30 {
+lab=pad}
+N 3240 0 3240 30 {
+lab=pad}
+N 3110 30 3240 30 {
+lab=pad}
+N 2000 -260 2000 -230 {
+lab=pad}
+N 1930 -230 2000 -230 {
+lab=pad}
+N 2120 -260 2120 -230 {
+lab=pad}
+N 2000 -230 2120 -230 {
+lab=pad}
+N 2250 -260 2250 -230 {
+lab=pad}
+N 2120 -230 2250 -230 {
+lab=pad}
+N 2370 -260 2370 -230 {
+lab=pad}
+N 2250 -230 2370 -230 {
+lab=pad}
+N 2490 -260 2490 -230 {
+lab=pad}
+N 2370 -230 2490 -230 {
+lab=pad}
+N 2620 -260 2620 -230 {
+lab=pad}
+N 2490 -230 2620 -230 {
+lab=pad}
+N 2740 -260 2740 -230 {
+lab=pad}
+N 2620 -230 2740 -230 {
+lab=pad}
+N 2870 -260 2870 -230 {
+lab=pad}
+N 2740 -230 2870 -230 {
+lab=pad}
+N 2990 -260 2990 -230 {
+lab=pad}
+N 2870 -230 2990 -230 {
+lab=pad}
+N 3110 -260 3110 -230 {
+lab=pad}
+N 2990 -230 3110 -230 {
+lab=pad}
+N 3240 -260 3240 -230 {
+lab=pad}
+N 3110 -230 3240 -230 {
+lab=pad}
+N 3360 -260 3360 -230 {
+lab=pad}
+N 3240 -230 3360 -230 {
+lab=pad}
+N 3360 0 3360 30 {
+lab=pad}
+N 3240 30 3360 30 {
+lab=pad}
+N 3490 -260 3490 -230 {
+lab=pad}
+N 3360 -230 3490 -230 {
+lab=pad}
+N 3490 0 3490 30 {
+lab=pad}
+N 3360 30 3490 30 {
+lab=pad}
+N 3610 -260 3610 -230 {
+lab=pad}
+N 3490 -230 3610 -230 {
+lab=pad}
+N 3610 0 3610 30 {
+lab=pad}
+N 3490 30 3610 30 {
+lab=pad}
+N 3730 -260 3730 -230 {
+lab=pad}
+N 3610 -230 3730 -230 {
+lab=pad}
+N 3730 0 3730 30 {
+lab=pad}
+N 3610 30 3730 30 {
+lab=pad}
+N 3860 0 3860 30 {
+lab=pad}
+N 3730 30 3860 30 {
+lab=pad}
+N 3980 0 3980 30 {
+lab=pad}
+N 3860 30 3980 30 {
+lab=pad}
+N 4110 0 4110 30 {
+lab=pad}
+N 3980 30 4110 30 {
+lab=pad}
+N 4110 -260 4110 -230 {
+lab=pad}
+N 3980 -230 4110 -230 {
+lab=pad}
+N 3980 -260 3980 -230 {
+lab=pad}
+N 3860 -230 3980 -230 {
+lab=pad}
+N 3860 -260 3860 -230 {
+lab=pad}
+N 3730 -230 3860 -230 {
+lab=pad}
+N 1930 -230 1930 30 {
+lab=pad}
+N 1870 -230 1930 -230 {
+lab=pad}
+N 1870 30 1930 30 {
+lab=pad}
+N 1950 -440 1950 -350 {
+lab=iovdd}
+N 1900 -350 1950 -350 {
+lab=iovdd}
+N 1700 -320 1700 -210 {
+lab=#net1}
+N 1700 -440 1700 -380 {
+lab=iovdd}
+N 1700 -440 1950 -440 {
+lab=iovdd}
+N 1950 -540 1950 -440 {
+lab=iovdd}
+N 2070 30 2070 110 {
+lab=pad}
+N 2000 30 2070 30 {
+lab=pad}
+N 2720 60 2720 120 {
+lab=iovss}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1850 -30 0 0 {name=M1
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1980 -30 0 0 {name=M2
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2100 -30 0 0 {name=M3
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2230 -30 0 0 {name=M4
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2350 -30 0 0 {name=M5
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2470 -30 0 0 {name=M6
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2600 -30 0 0 {name=M7
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2720 -30 0 0 {name=M8
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2850 -30 0 0 {name=M9
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2970 -30 0 0 {name=M10
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 3090 -30 0 0 {name=M11
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 3220 -30 0 0 {name=M12
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 3340 -30 0 0 {name=M13
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 3470 -30 0 0 {name=M14
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 3590 -30 0 0 {name=M15
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 3710 -30 0 0 {name=M16
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 3840 -30 0 0 {name=M17
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 3960 -30 0 0 {name=M18
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 4090 -30 0 0 {name=M19
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 4210 -30 0 0 {name=M20
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1850 -290 0 0 {name=M21
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1980 -290 0 0 {name=M22
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2100 -290 0 0 {name=M23
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2230 -290 0 0 {name=M24
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2350 -290 0 0 {name=M25
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2470 -290 0 0 {name=M26
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2600 -290 0 0 {name=M27
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2720 -290 0 0 {name=M28
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2850 -290 0 0 {name=M29
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2970 -290 0 0 {name=M30
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 3090 -290 0 0 {name=M31
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 3220 -290 0 0 {name=M32
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 3340 -290 0 0 {name=M33
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 3470 -290 0 0 {name=M34
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 3590 -290 0 0 {name=M35
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 3710 -290 0 0 {name=M36
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 3840 -290 0 0 {name=M37
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 3960 -290 0 0 {name=M38
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 4090 -290 0 0 {name=M39
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 4210 -290 0 0 {name=M40
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/rppd.sym} 1700 -350 0 0 {name=R1
+w=0.5e-6
+l=12.9e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {devices/iopin.sym} 1950 -540 3 0 {name=iovdd lab=iovdd}
+C {devices/iopin.sym} 2070 110 1 0 {name=pad lab=pad}
+C {devices/iopin.sym} 2720 120 1 0 {name=iovss lab=iovss}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P20N0D.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P20N0D.sym
new file mode 100644
index 00000000..5be4350c
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P20N0D.sym
@@ -0,0 +1,25 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -30 130 -30 {}
+L 4 -130 30 130 30 {}
+L 4 -130 -30 -130 30 {}
+L 4 130 -30 130 30 {}
+L 7 0 -50 0 -30 {}
+L 7 130 0 150 0 {}
+L 7 0 30 0 50 {}
+B 5 -2.5 -52.5 2.5 -47.5 {name=iovdd dir=inout}
+B 5 147.5 -2.5 152.5 2.5 {name=pad dir=inout}
+B 5 -2.5 47.5 2.5 52.5 {name=iovss dir=inout}
+T {sg13g2_Clamp_P20N0D} -73.5 -6 0 0 0.2 0.2 {}
+T {@name} 135 -42 0 0 0.2 0.2 {}
+T {iovdd} 15 -24 0 1 0.2 0.2 {}
+T {pad} 125 -4 0 1 0.2 0.2 {}
+T {iovss} 15 16 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P2N2D.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P2N2D.sch
new file mode 100644
index 00000000..2b39b2aa
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P2N2D.sch
@@ -0,0 +1,139 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 710 -400 710 -370 {
+lab=iovdd}
+N 1030 -400 1140 -400 {
+lab=iovdd}
+N 1140 -400 1140 -370 {
+lab=iovdd}
+N 860 -400 860 -370 {
+lab=iovdd}
+N 740 -400 860 -400 {
+lab=iovdd}
+N 1000 -400 1000 -370 {
+lab=iovdd}
+N 930 -400 1000 -400 {
+lab=iovdd}
+N 710 -340 740 -340 {
+lab=iovdd}
+N 740 -400 740 -340 {
+lab=iovdd}
+N 710 -400 740 -400 {
+lab=iovdd}
+N 860 -340 890 -340 {
+lab=iovdd}
+N 890 -400 890 -340 {
+lab=iovdd}
+N 860 -400 890 -400 {
+lab=iovdd}
+N 1000 -340 1030 -340 {
+lab=iovdd}
+N 1030 -400 1030 -340 {
+lab=iovdd}
+N 1000 -400 1030 -400 {
+lab=iovdd}
+N 1140 -340 1160 -340 {
+lab=iovdd}
+N 1160 -400 1160 -340 {
+lab=iovdd}
+N 1140 -400 1160 -400 {
+lab=iovdd}
+N 710 -310 710 -280 {
+lab=pad}
+N 1000 -280 1140 -280 {
+lab=pad}
+N 1140 -310 1140 -280 {
+lab=pad}
+N 1000 -310 1000 -280 {
+lab=pad}
+N 910 -280 1000 -280 {
+lab=pad}
+N 860 -310 860 -280 {
+lab=pad}
+N 710 -280 860 -280 {
+lab=pad}
+N 640 -340 670 -340 {
+lab=gate}
+N 640 -340 640 -250 {
+lab=gate}
+N 960 -250 1100 -250 {
+lab=gate}
+N 1100 -340 1100 -250 {
+lab=gate}
+N 960 -340 960 -250 {
+lab=gate}
+N 820 -250 960 -250 {
+lab=gate}
+N 820 -340 820 -250 {
+lab=gate}
+N 640 -250 820 -250 {
+lab=gate}
+N 930 -450 930 -400 {
+lab=iovdd}
+N 890 -400 930 -400 {
+lab=iovdd}
+N 620 -340 640 -340 {
+lab=gate}
+N 620 -360 620 -340 {
+lab=gate}
+N 550 -340 620 -340 {
+lab=gate}
+N 620 -450 620 -420 {
+lab=iovdd}
+N 620 -450 930 -450 {
+lab=iovdd}
+N 930 -480 930 -450 {
+lab=iovdd}
+N 910 -280 910 -210 {
+lab=pad}
+N 860 -280 910 -280 {
+lab=pad}
+N 1030 -230 1030 -210 {
+lab=iovdd}
+C {sg13g2_pr/sg13_hv_pmos.sym} 840 -340 0 0 {name=M1
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 980 -340 0 0 {name=M2
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1120 -340 0 0 {name=M3
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 690 -340 0 0 {name=M4
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/dpantenna.sym} 620 -390 0 0 {name=D1
+model=dpantenna
+l=0.64u
+w=0.3u
+spiceprefix=X
+}
+C {devices/iopin.sym} 910 -210 1 0 {name=pad lab=pad}
+C {devices/iopin.sym} 930 -480 3 0 {name=iovdd lab=iovdd}
+C {devices/iopin.sym} 550 -340 2 0 {name=gate lab=gate}
+C {devices/iopin.sym} 1030 -210 1 0 {name=iovss lab=iovss}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P2N2D.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P2N2D.sym
new file mode 100644
index 00000000..2f710c56
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P2N2D.sym
@@ -0,0 +1,28 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -40 130 -40 {}
+L 4 -130 40 130 40 {}
+L 4 -130 -40 -130 40 {}
+L 4 130 -40 130 40 {}
+L 7 -30 -60 -30 -40 {}
+L 7 -150 0 -130 0 {}
+L 7 -30 40 -30 60 {}
+L 7 130 0 150 0 {}
+B 5 -32.5 -62.5 -27.5 -57.5 {name=iovdd dir=inout}
+B 5 -152.5 -2.5 -147.5 2.5 {name=gate dir=inout}
+B 5 -32.5 57.5 -27.5 62.5 {name=iovss dir=inout}
+B 5 147.5 -2.5 152.5 2.5 {name=pad dir=inout}
+T {sg13g2_Clamp_P2N2D} -69 -6 0 0 0.2 0.2 {}
+T {@name} 135 -52 0 0 0.2 0.2 {}
+T {iovdd} -35 -54 0 1 0.2 0.2 {}
+T {gate} -105 -4 0 1 0.2 0.2 {}
+T {iovss} 5 46 0 1 0.2 0.2 {}
+T {pad} 125 -4 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P8N8D.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P8N8D.sch
new file mode 100644
index 00000000..f886aaf3
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P8N8D.sch
@@ -0,0 +1,471 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N -130 -560 -130 -520 {
+lab=pad}
+N 1910 -550 1910 -520 {
+lab=pad}
+N 1780 -550 1780 -520 {
+lab=pad}
+N 1640 -520 1780 -520 {
+lab=pad}
+N 1640 -550 1640 -520 {
+lab=pad}
+N 1500 -520 1640 -520 {
+lab=pad}
+N 1500 -550 1500 -520 {
+lab=pad}
+N 1370 -520 1500 -520 {
+lab=pad}
+N 1370 -550 1370 -520 {
+lab=pad}
+N 1230 -520 1370 -520 {
+lab=pad}
+N 1230 -550 1230 -520 {
+lab=pad}
+N 1090 -520 1230 -520 {
+lab=pad}
+N 1090 -550 1090 -520 {
+lab=pad}
+N 960 -520 1090 -520 {
+lab=pad}
+N 960 -550 960 -520 {
+lab=pad}
+N 820 -520 960 -520 {
+lab=pad}
+N 820 -550 820 -520 {
+lab=pad}
+N 680 -520 820 -520 {
+lab=pad}
+N 680 -550 680 -520 {
+lab=pad}
+N 550 -520 680 -520 {
+lab=pad}
+N 550 -550 550 -520 {
+lab=pad}
+N 410 -520 550 -520 {
+lab=pad}
+N 410 -560 410 -520 {
+lab=pad}
+N 280 -520 410 -520 {
+lab=pad}
+N 280 -560 280 -520 {
+lab=pad}
+N 140 -520 280 -520 {
+lab=pad}
+N 140 -560 140 -520 {
+lab=pad}
+N 0 -520 140 -520 {
+lab=pad}
+N 0 -560 0 -520 {
+lab=pad}
+N -130 -520 0 -520 {
+lab=pad}
+N -130 -660 -130 -620 {
+lab=iovdd}
+N 1780 -660 1910 -660 {
+lab=iovdd}
+N 1910 -640 1910 -610 {
+lab=iovdd}
+N 0 -660 0 -620 {
+lab=iovdd}
+N -60 -660 0 -660 {
+lab=iovdd}
+N -130 -590 -100 -590 {
+lab=iovdd}
+N -100 -660 -100 -590 {
+lab=iovdd}
+N -130 -660 -100 -660 {
+lab=iovdd}
+N -0 -590 30 -590 {
+lab=iovdd}
+N 30 -660 30 -590 {
+lab=iovdd}
+N 0 -660 30 -660 {
+lab=iovdd}
+N 140 -660 140 -620 {
+lab=iovdd}
+N 30 -660 140 -660 {
+lab=iovdd}
+N 140 -590 170 -590 {
+lab=iovdd}
+N 170 -660 170 -590 {
+lab=iovdd}
+N 140 -660 170 -660 {
+lab=iovdd}
+N 280 -660 280 -620 {
+lab=iovdd}
+N 170 -660 280 -660 {
+lab=iovdd}
+N 280 -590 310 -590 {
+lab=iovdd}
+N 310 -660 310 -590 {
+lab=iovdd}
+N 280 -660 310 -660 {
+lab=iovdd}
+N 410 -660 410 -620 {
+lab=iovdd}
+N 310 -660 410 -660 {
+lab=iovdd}
+N 410 -590 440 -590 {
+lab=iovdd}
+N 440 -660 440 -590 {
+lab=iovdd}
+N 410 -660 440 -660 {
+lab=iovdd}
+N 550 -630 550 -610 {
+lab=iovdd}
+N 440 -660 550 -660 {
+lab=iovdd}
+N 550 -580 570 -580 {
+lab=iovdd}
+N 570 -630 570 -580 {
+lab=iovdd}
+N 550 -630 570 -630 {
+lab=iovdd}
+N 550 -660 550 -630 {
+lab=iovdd}
+N 680 -640 680 -610 {
+lab=iovdd}
+N 550 -660 680 -660 {
+lab=iovdd}
+N 680 -580 710 -580 {
+lab=iovdd}
+N 710 -640 710 -580 {
+lab=iovdd}
+N 680 -640 710 -640 {
+lab=iovdd}
+N 680 -660 680 -640 {
+lab=iovdd}
+N 820 -630 820 -610 {
+lab=iovdd}
+N 680 -660 820 -660 {
+lab=iovdd}
+N 820 -580 850 -580 {
+lab=iovdd}
+N 850 -630 850 -580 {
+lab=iovdd}
+N 820 -630 850 -630 {
+lab=iovdd}
+N 820 -660 820 -630 {
+lab=iovdd}
+N 960 -640 960 -610 {
+lab=iovdd}
+N 820 -660 960 -660 {
+lab=iovdd}
+N 960 -580 990 -580 {
+lab=iovdd}
+N 990 -640 990 -580 {
+lab=iovdd}
+N 960 -640 990 -640 {
+lab=iovdd}
+N 960 -660 960 -640 {
+lab=iovdd}
+N 1090 -630 1090 -610 {
+lab=iovdd}
+N 960 -660 1090 -660 {
+lab=iovdd}
+N 1090 -580 1120 -580 {
+lab=iovdd}
+N 1120 -630 1120 -580 {
+lab=iovdd}
+N 1090 -630 1120 -630 {
+lab=iovdd}
+N 1090 -660 1090 -630 {
+lab=iovdd}
+N 1230 -630 1230 -610 {
+lab=iovdd}
+N 1090 -660 1230 -660 {
+lab=iovdd}
+N 1230 -580 1270 -580 {
+lab=iovdd}
+N 1270 -630 1270 -580 {
+lab=iovdd}
+N 1230 -630 1270 -630 {
+lab=iovdd}
+N 1230 -660 1230 -630 {
+lab=iovdd}
+N 1370 -630 1370 -610 {
+lab=iovdd}
+N 1230 -660 1370 -660 {
+lab=iovdd}
+N 1370 -580 1400 -580 {
+lab=iovdd}
+N 1400 -630 1400 -580 {
+lab=iovdd}
+N 1370 -630 1400 -630 {
+lab=iovdd}
+N 1370 -660 1370 -630 {
+lab=iovdd}
+N 1500 -630 1500 -610 {
+lab=iovdd}
+N 1370 -660 1500 -660 {
+lab=iovdd}
+N 1500 -580 1540 -580 {
+lab=iovdd}
+N 1540 -630 1540 -580 {
+lab=iovdd}
+N 1500 -630 1540 -630 {
+lab=iovdd}
+N 1500 -660 1500 -630 {
+lab=iovdd}
+N 1640 -630 1640 -610 {
+lab=iovdd}
+N 1500 -660 1640 -660 {
+lab=iovdd}
+N 1640 -580 1670 -580 {
+lab=iovdd}
+N 1670 -630 1670 -580 {
+lab=iovdd}
+N 1640 -630 1670 -630 {
+lab=iovdd}
+N 1640 -660 1640 -630 {
+lab=iovdd}
+N 1780 -630 1780 -610 {
+lab=iovdd}
+N 1640 -660 1780 -660 {
+lab=iovdd}
+N 1780 -580 1810 -580 {
+lab=iovdd}
+N 1810 -630 1810 -580 {
+lab=iovdd}
+N 1780 -630 1810 -630 {
+lab=iovdd}
+N 1780 -660 1780 -630 {
+lab=iovdd}
+N 1910 -580 1940 -580 {
+lab=iovdd}
+N 1940 -640 1940 -580 {
+lab=iovdd}
+N 1910 -640 1940 -640 {
+lab=iovdd}
+N 1910 -660 1910 -640 {
+lab=iovdd}
+N -200 -590 -170 -590 {
+lab=gate}
+N -210 -590 -210 -450 {
+lab=gate}
+N -250 -590 -210 -590 {
+lab=gate}
+N 1740 -450 1870 -450 {
+lab=gate}
+N 1870 -580 1870 -450 {
+lab=gate}
+N -40 -590 -40 -450 {
+lab=gate}
+N -210 -450 -40 -450 {
+lab=gate}
+N 100 -590 100 -450 {
+lab=gate}
+N -40 -450 100 -450 {
+lab=gate}
+N 240 -590 240 -450 {
+lab=gate}
+N 100 -450 240 -450 {
+lab=gate}
+N 370 -590 370 -450 {
+lab=gate}
+N 240 -450 370 -450 {
+lab=gate}
+N 510 -580 510 -450 {
+lab=gate}
+N 370 -450 510 -450 {
+lab=gate}
+N 640 -580 640 -450 {
+lab=gate}
+N 510 -450 640 -450 {
+lab=gate}
+N 780 -580 780 -450 {
+lab=gate}
+N 640 -450 780 -450 {
+lab=gate}
+N 920 -580 920 -450 {
+lab=gate}
+N 780 -450 920 -450 {
+lab=gate}
+N 1050 -580 1050 -450 {
+lab=gate}
+N 920 -450 1050 -450 {
+lab=gate}
+N 1190 -580 1190 -450 {
+lab=gate}
+N 1050 -450 1190 -450 {
+lab=gate}
+N 1330 -580 1330 -450 {
+lab=gate}
+N 1190 -450 1330 -450 {
+lab=gate}
+N 1460 -580 1460 -450 {
+lab=gate}
+N 1330 -450 1460 -450 {
+lab=gate}
+N 1600 -580 1600 -450 {
+lab=gate}
+N 1460 -450 1600 -450 {
+lab=gate}
+N 1740 -580 1740 -450 {
+lab=gate}
+N 1600 -450 1740 -450 {
+lab=gate}
+N 1890 -520 1910 -520 {
+lab=pad}
+N 1890 -520 1890 -370 {
+lab=pad}
+N 1780 -520 1890 -520 {
+lab=pad}
+N -200 -630 -200 -590 {
+lab=gate}
+N -210 -590 -200 -590 {
+lab=gate}
+N -200 -690 -60 -690 {
+lab=iovdd}
+N -60 -690 -60 -660 {
+lab=iovdd}
+N -100 -660 -60 -660 {
+lab=iovdd}
+N -60 -740 -60 -690 {
+lab=iovdd}
+N 720 -390 720 -350 {
+lab=pad}
+C {sg13g2_pr/sg13_hv_pmos.sym} 530 -580 0 0 {name=M1
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 660 -580 0 0 {name=M2
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 800 -580 0 0 {name=M3
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 940 -580 0 0 {name=M4
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1070 -580 0 0 {name=M5
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1210 -580 0 0 {name=M6
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} -150 -590 0 0 {name=M7
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} -20 -590 0 0 {name=M8
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 120 -590 0 0 {name=M9
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 260 -590 0 0 {name=M10
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 390 -590 0 0 {name=M11
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1350 -580 0 0 {name=M12
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1480 -580 0 0 {name=M13
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1620 -580 0 0 {name=M14
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1760 -580 0 0 {name=M15
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1890 -580 0 0 {name=M16
+l=0.6u
+w=6.66u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/dpantenna.sym} -200 -660 0 0 {name=D1
+model=dpantenna
+l=0.64u
+w=0.3u
+spiceprefix=X
+}
+C {devices/iopin.sym} -60 -740 3 0 {name=iovdd lab=iovdd}
+C {devices/iopin.sym} -250 -590 2 0 {name=gate lab=gate}
+C {devices/iopin.sym} 1890 -370 1 0 {name=pad lab=pad}
+C {devices/iopin.sym} 720 -350 1 0 {name=iovss lab=iovss}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P8N8D.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P8N8D.sym
new file mode 100644
index 00000000..4169e96d
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P8N8D.sym
@@ -0,0 +1,28 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -40 130 -40 {}
+L 4 -130 40 130 40 {}
+L 4 -130 -40 -130 40 {}
+L 4 130 -40 130 40 {}
+L 7 0 -60 0 -40 {}
+L 7 -150 0 -130 0 {}
+L 7 130 0 150 0 {}
+L 7 0 40 0 60 {}
+B 5 -2.5 -62.5 2.5 -57.5 {name=iovdd dir=inout}
+B 5 -152.5 -2.5 -147.5 2.5 {name=gate dir=inout}
+B 5 147.5 -2.5 152.5 2.5 {name=pad dir=inout}
+B 5 -2.5 57.5 2.5 62.5 {name=iovss dir=inout}
+T {sg13g2_Clamp_P8N8D} -99 -6 0 0 0.2 0.2 {}
+T {@name} 135 -52 0 0 0.2 0.2 {}
+T {iovdd} 35 -54 0 1 0.2 0.2 {}
+T {gate} -135 6 0 1 0.2 0.2 {}
+T {pad} 125 -4 0 1 0.2 0.2 {}
+T {iovss} 35 46 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCNDiode.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCNDiode.sch
new file mode 100644
index 00000000..21e830af
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCNDiode.sch
@@ -0,0 +1,46 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N -40 -20 10 -20 {
+lab=cathode}
+N 10 30 10 90 {
+lab=cathode}
+N -50 90 10 90 {
+lab=cathode}
+N -140 -20 -100 -20 {
+lab=anode}
+N -140 30 -140 90 {
+lab=anode}
+N -140 90 -110 90 {
+lab=anode}
+N 10 30 50 30 {
+lab=cathode}
+N 10 -20 10 30 {
+lab=cathode}
+N -180 30 -140 30 {
+lab=anode}
+N -140 -20 -140 30 {
+lab=anode}
+N -20 140 40 140 {
+lab=xxx}
+N -180 30 -180 50 {
+lab=anode}
+C {sg13g2_pr/dantenna.sym} -70 -20 1 0 {name=D1
+model=dantenna
+l=1.26u
+w=27.78u
+spiceprefix=X
+}
+C {sg13g2_pr/dantenna.sym} -80 90 1 0 {name=D2
+model=dantenna
+l=1.26u
+w=27.78u
+spiceprefix=X
+}
+C {devices/iopin.sym} 50 30 0 0 {name=cathode lab=cathode}
+C {devices/iopin.sym} -180 50 0 0 {name=anode lab=anode}
+C {devices/iopin.sym} 40 140 0 0 {name=guard lab=guard}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCNDiode.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCNDiode.sym
new file mode 100644
index 00000000..480e767e
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCNDiode.sym
@@ -0,0 +1,25 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -30 130 -30 {}
+L 4 -130 30 130 30 {}
+L 4 -130 -30 -130 30 {}
+L 4 130 -30 130 30 {}
+L 7 130 -20 150 -20 {}
+L 7 -150 0 -130 0 {}
+L 7 130 20 150 20 {}
+B 5 147.5 -22.5 152.5 -17.5 {name=cathode dir=inout}
+B 5 -152.5 -2.5 -147.5 2.5 {name=anode dir=inout}
+B 5 147.5 17.5 152.5 22.5 {name=guard dir=inout}
+T {sg13g2_DCNDiode} -85.5 -6 0 0 0.3 0.3 {}
+T {@name} 135 -42 0 0 0.2 0.2 {}
+T {cathode} 125 -24 0 1 0.2 0.2 {}
+T {anode} -95 -14 0 1 0.2 0.2 {}
+T {guard} 125 16 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCPDiode.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCPDiode.sch
new file mode 100644
index 00000000..47065d07
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCPDiode.sch
@@ -0,0 +1,46 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N -40 -20 10 -20 {
+lab=cathode}
+N 10 30 10 90 {
+lab=cathode}
+N -50 90 10 90 {
+lab=cathode}
+N -140 -20 -100 -20 {
+lab=anode}
+N -140 30 -140 90 {
+lab=anode}
+N -140 90 -110 90 {
+lab=anode}
+N 10 30 50 30 {
+lab=cathode}
+N 10 -20 10 30 {
+lab=cathode}
+N -180 30 -140 30 {
+lab=anode}
+N -140 -20 -140 30 {
+lab=anode}
+N -20 140 40 140 {
+lab=guard}
+N -180 30 -180 50 {
+lab=anode}
+C {devices/iopin.sym} 50 30 0 0 {name=cathode lab=cathode}
+C {devices/iopin.sym} -180 50 0 0 {name=anode lab=anode}
+C {devices/iopin.sym} 40 140 0 0 {name=guard lab=guard}
+C {sg13g2_pr/dpantenna.sym} -80 90 1 0 {name=D1
+model=dpantenna
+l=1.26u
+w=27.78u
+spiceprefix=X
+}
+C {sg13g2_pr/dpantenna.sym} -70 -20 1 0 {name=D2
+model=dpantenna
+l=1.26u
+w=27.78u
+spiceprefix=X
+}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCPDiode.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCPDiode.sym
new file mode 100644
index 00000000..9e20980c
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCPDiode.sym
@@ -0,0 +1,25 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -30 130 -30 {}
+L 4 -130 30 130 30 {}
+L 4 -130 -30 -130 30 {}
+L 4 130 -30 130 30 {}
+L 7 130 -20 150 -20 {}
+L 7 -150 0 -130 0 {}
+L 7 130 20 150 20 {}
+B 5 147.5 -22.5 152.5 -17.5 {name=cathode dir=inout}
+B 5 -152.5 -2.5 -147.5 2.5 {name=anode dir=inout}
+B 5 147.5 17.5 152.5 22.5 {name=guard dir=inout}
+T {sg13g2_DCPDiode} -85.5 -6 0 0 0.2 0.2 {}
+T {@name} 135 -42 0 0 0.2 0.2 {}
+T {cathode} 125 -24 0 1 0.2 0.2 {}
+T {anode} -95 -14 0 1 0.2 0.2 {}
+T {guard} 125 16 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Gallery.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Gallery.sch
new file mode 100644
index 00000000..5c74d6e7
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Gallery.sch
@@ -0,0 +1,414 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 2570 -490 2570 -430 {
+lab=vss}
+N 4170 -430 4210 -430 {
+lab=vss}
+N 4210 -470 4210 -430 {
+lab=vss}
+N 4170 -470 4170 -430 {
+lab=vss}
+N 3830 -430 4170 -430 {
+lab=vss}
+N 3830 -470 3830 -430 {
+lab=vss}
+N 3770 -430 3830 -430 {
+lab=vss}
+N 3770 -470 3770 -430 {
+lab=vss}
+N 3410 -430 3770 -430 {
+lab=vss}
+N 3410 -470 3410 -430 {
+lab=vss}
+N 3350 -430 3410 -430 {
+lab=vss}
+N 3350 -470 3350 -430 {
+lab=vss}
+N 3000 -430 3350 -430 {
+lab=vss}
+N 3000 -490 3000 -430 {
+lab=vss}
+N 2940 -430 3000 -430 {
+lab=vss}
+N 2940 -490 2940 -430 {
+lab=vss}
+N 2610 -430 2940 -430 {
+lab=vss}
+N 2570 -710 2570 -610 {
+lab=vdd}
+N 3770 -710 4210 -710 {
+lab=vdd}
+N 4210 -710 4210 -630 {
+lab=vdd}
+N 3770 -710 3770 -630 {
+lab=vdd}
+N 3350 -710 3770 -710 {
+lab=vdd}
+N 3350 -710 3350 -630 {
+lab=vdd}
+N 2940 -710 3350 -710 {
+lab=vdd}
+N 2940 -710 2940 -610 {
+lab=vdd}
+N 2870 -710 2940 -710 {
+lab=vdd}
+N 2610 -690 2610 -610 {
+lab=iovdd}
+N 3830 -690 4170 -690 {
+lab=iovdd}
+N 4170 -690 4170 -630 {
+lab=iovdd}
+N 3830 -690 3830 -630 {
+lab=iovdd}
+N 3410 -690 3830 -690 {
+lab=iovdd}
+N 3410 -690 3410 -630 {
+lab=iovdd}
+N 3170 -690 3410 -690 {
+lab=iovdd}
+N 3000 -690 3000 -610 {
+lab=iovdd}
+N 2610 -690 3000 -690 {
+lab=iovdd}
+N 3230 -930 3230 -550 {
+lab=iopadout4ma_c2p}
+N 3650 -880 3650 -550 {
+lab=iopadout16ma_c2p}
+N 4040 -860 4040 -550 {
+lab=iopadout30ma_c2p}
+N 4860 -430 4900 -430 {
+lab=vss}
+N 4900 -500 4900 -430 {
+lab=vss}
+N 4860 -500 4860 -430 {
+lab=vss}
+N 4570 -430 4860 -430 {
+lab=vss}
+N 4570 -490 4570 -430 {
+lab=vss}
+N 4530 -430 4570 -430 {
+lab=vss}
+N 4530 -500 4530 -430 {
+lab=vss}
+N 4210 -430 4530 -430 {
+lab=vss}
+N 5210 -490 5210 -430 {
+lab=vss}
+N 5150 -430 5210 -430 {
+lab=vss}
+N 5150 -490 5150 -430 {
+lab=vss}
+N 4900 -430 5150 -430 {
+lab=vss}
+N 4860 -710 5150 -710 {
+lab=vdd}
+N 5150 -710 5150 -650 {
+lab=vdd}
+N 4860 -710 4860 -620 {
+lab=vdd}
+N 4530 -710 4860 -710 {
+lab=vdd}
+N 4530 -710 4530 -620 {
+lab=vdd}
+N 4210 -710 4530 -710 {
+lab=vdd}
+N 4900 -690 5210 -690 {
+lab=iovdd}
+N 5210 -690 5210 -650 {
+lab=iovdd}
+N 4900 -690 4900 -620 {
+lab=iovdd}
+N 4570 -690 4900 -690 {
+lab=iovdd}
+N 4570 -690 4570 -620 {
+lab=iovdd}
+N 4170 -690 4570 -690 {
+lab=iovdd}
+N 2620 -100 2620 -60 {
+lab=vss}
+N 4790 -60 4850 -60 {
+lab=vss}
+N 4850 -100 4850 -60 {
+lab=vss}
+N 2680 -100 2680 -60 {
+lab=vss}
+N 2620 -60 2680 -60 {
+lab=vss}
+N 3070 -100 3070 -60 {
+lab=vss}
+N 2680 -60 3070 -60 {
+lab=vss}
+N 3130 -100 3130 -60 {
+lab=vss}
+N 3070 -60 3130 -60 {
+lab=vss}
+N 3490 -100 3490 -60 {
+lab=vss}
+N 3390 -60 3490 -60 {
+lab=vss}
+N 3550 -100 3550 -60 {
+lab=vss}
+N 3490 -60 3550 -60 {
+lab=vss}
+N 4400 -90 4400 -60 {
+lab=vss}
+N 4020 -60 4400 -60 {
+lab=vss}
+N 4440 -90 4440 -60 {
+lab=vss}
+N 4400 -60 4440 -60 {
+lab=vss}
+N 4790 -100 4790 -60 {
+lab=vss}
+N 4440 -60 4790 -60 {
+lab=vss}
+N 3960 -90 4020 -90 {
+lab=vss}
+N 4020 -90 4020 -60 {
+lab=vss}
+N 3960 -60 4020 -60 {
+lab=vss}
+N 3960 -90 3960 -60 {
+lab=vss}
+N 3550 -60 3960 -60 {
+lab=vss}
+N 4850 -60 5210 -60 {
+lab=vss}
+N 5210 -430 5210 -60 {
+lab=vss}
+N 2620 -310 2620 -280 {
+lab=vdd}
+N 4400 -310 4790 -310 {
+lab=vdd}
+N 4790 -310 4790 -300 {
+lab=vdd}
+N 4400 -310 4400 -290 {
+lab=vdd}
+N 3960 -310 4400 -310 {
+lab=vdd}
+N 3960 -290 3970 -290 {
+lab=vdd}
+N 3960 -310 3960 -290 {
+lab=vdd}
+N 3490 -310 3960 -310 {
+lab=vdd}
+N 3490 -310 3490 -280 {
+lab=vdd}
+N 3070 -310 3490 -310 {
+lab=vdd}
+N 3070 -310 3070 -280 {
+lab=vdd}
+N 2780 -310 3070 -310 {
+lab=vdd}
+N 2680 -330 2680 -280 {
+lab=iovdd}
+N 4440 -330 4850 -330 {
+lab=iovdd}
+N 4850 -330 4850 -290 {
+lab=iovdd}
+N 4440 -330 4440 -290 {
+lab=iovdd}
+N 4010 -330 4440 -330 {
+lab=iovdd}
+N 4010 -290 4020 -290 {
+lab=iovdd}
+N 4010 -330 4010 -290 {
+lab=iovdd}
+N 3550 -330 4010 -330 {
+lab=iovdd}
+N 3550 -330 3550 -280 {
+lab=iovdd}
+N 3170 -330 3550 -330 {
+lab=iovdd}
+N 3130 -330 3130 -280 {
+lab=iovdd}
+N 2680 -330 3130 -330 {
+lab=iovdd}
+N 3170 -690 3170 -330 {
+lab=iovdd}
+N 3080 -690 3170 -690 {
+lab=iovdd}
+N 3130 -330 3170 -330 {
+lab=iovdd}
+N 2780 -710 2780 -310 {
+lab=vdd}
+N 2570 -710 2780 -710 {
+lab=vdd}
+N 2620 -310 2780 -310 {
+lab=vdd}
+N 2610 -490 2610 -430 {
+lab=vss}
+N 2570 -430 2610 -430 {
+lab=vss}
+N 3390 -60 3390 20 {
+lab=vss}
+N 3130 -60 3390 -60 {
+lab=vss}
+N 3080 -770 3080 -690 {
+lab=iovdd}
+N 3000 -690 3080 -690 {
+lab=iovdd}
+N 2870 -770 2870 -710 {
+lab=vdd}
+N 2780 -710 2870 -710 {
+lab=vdd}
+N 2640 -780 2640 -760 {
+lab=vss}
+N 2640 -760 2700 -760 {
+lab=vss}
+N 2700 -780 2700 -760 {
+lab=vss}
+N 2430 -760 2640 -760 {
+lab=vss}
+N 2430 -430 2570 -430 {
+lab=vss}
+N 2430 -760 2430 -430 {
+lab=vss}
+N 2700 -940 3000 -940 {
+lab=iovdd}
+N 3000 -940 3000 -770 {
+lab=iovdd}
+N 3000 -770 3080 -770 {
+lab=iovdd}
+N 3080 -830 3080 -770 {
+lab=iovdd}
+N 2640 -960 2640 -940 {
+lab=vdd}
+N 2640 -960 2920 -960 {
+lab=vdd}
+N 2920 -960 2920 -770 {
+lab=vdd}
+N 2870 -770 2920 -770 {
+lab=vdd}
+N 2870 -820 2870 -770 {
+lab=vdd}
+N 2470 -860 2520 -860 {
+lab=iopadin_p2c}
+N 2820 -860 2850 -860 {
+lab=iopadin_pad}
+N 2850 -990 2850 -860 {
+lab=iopadin_pad}
+N 3530 -850 3530 -550 {
+lab=iopadout4ma_pad}
+N 3950 -800 3950 -550 {
+lab=iopadout16ma_pad}
+N 4340 -830 4340 -550 {
+lab=iopadout30ma_pad}
+N 2800 -190 2800 -0 {
+lab=iopadtriout4ma_pad}
+N 3250 -190 3250 -0 {
+lab=iopadtriout16ma_pad}
+N 3670 -190 3670 0 {
+lab=iopadtriout30ma_pad}
+N 4140 -220 4170 -220 {
+lab=iopadinout4ma_pad}
+N 4170 -220 4170 0 {
+lab=iopadinout4ma_pad}
+N 4570 -220 4610 -220 {
+lab=iopadinout16ma_pad}
+N 4610 -220 4610 0 {
+lab=iopadinout16ma_pad}
+N 4970 -230 5030 -230 {
+lab=iopadinout30ma_pad}
+N 5030 -230 5030 0 {
+lab=iopadinout30ma_pad}
+N 4140 -160 4140 0 {
+lab=iopadinout4ma_p2c}
+N 4570 -160 4570 -0 {
+lab=iopadinout16ma_p2c}
+N 4970 -170 4970 0 {
+lab=iopadinout30ma_p2c}
+N 2500 -170 2500 0 {
+lab=iopadtriout4ma_c2p}
+N 2460 -210 2500 -210 {
+lab=iopadtriout4ma_c2p_en}
+N 2460 -210 2460 0 {
+lab=iopadtriout4ma_c2p_en}
+N 2950 -170 2950 0 {
+lab=iopadtriout16ma_c2p}
+N 2900 -210 2950 -210 {
+lab=iopadtriout16ma_c2p_en}
+N 2900 -210 2900 0 {
+lab=iopadtriout16ma_c2p_en}
+N 3370 -170 3370 -0 {
+lab=iopadtriout30ma_c2p}
+N 3320 -210 3370 -210 {
+lab=iopadtriout30ma_c2p_en}
+N 3320 -210 3320 0 {
+lab=iopadtriout30ma_c2p_en}
+N 3840 -170 3840 0 {
+lab=iopadinout4ma_c2p}
+N 3780 -210 3840 -210 {
+lab=iopadinout4ma_c2p_en}
+N 3780 -210 3780 0 {
+lab=iopadinout4ma_c2p_en}
+N 4270 -170 4270 0 {
+lab=iopadinout16ma_c2p}
+N 4220 -210 4270 -210 {
+lab=iopadinout16ma_c2p_en}
+N 4220 -210 4220 0 {
+lab=iopadinout16ma_c2p_en}
+N 4670 -180 4670 0 {
+lab=iopadinout30ma_c2p}
+N 4640 -220 4670 -220 {
+lab=iopadinout30ma_c2p_en}
+N 4640 -220 4640 0 {
+lab=iopadinout30ma_c2p_en}
+N 5330 -580 5430 -580 {
+lab=ana_out}
+N 5330 -560 5430 -560 {
+lab=ana_out}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadVSS.sym} 2590 -550 0 0 {name=x1}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadVdd.sym} 2970 -550 0 0 {name=x2}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadOut4mA.sym} 3380 -550 0 0 {name=x3}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadOut16mA.sym} 3800 -550 0 0 {name=x4}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadOut30mA.sym} 4190 -550 0 0 {name=x5}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadTriOut4mA.sym} 2650 -190 0 0 {name=x6}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadTriOut16mA.sym} 3100 -190 0 0 {name=x7}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadTriOut30mA.sym} 3520 -190 0 0 {name=x8}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadInOut4mA.sym} 3990 -190 0 0 {name=x9}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadInOut16mA.sym} 4420 -190 0 0 {name=x10}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadInOut30mA.sym} 4820 -200 0 0 {name=x11}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadIOVss.sym} 4550 -560 0 0 {name=x12}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadIOVdd.sym} 4880 -560 0 0 {name=x13}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadAnalog.sym} 5180 -570 0 0 {name=x14}
+C {devices/iopin.sym} 2870 -820 3 0 {name=vdd lab=vdd}
+C {devices/iopin.sym} 3080 -830 3 0 {name=iovdd lab=iovdd}
+C {devices/iopin.sym} 3390 20 1 0 {name=vss lab=vss}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadIn.sym} 2670 -860 0 0 {name=x15}
+C {devices/iopin.sym} 2850 -990 3 0 {name=iopadin_pad lab=iopadin_pad}
+C {devices/iopin.sym} 3530 -850 3 0 {name=iopadout4ma_pad lab=iopadout4ma_pad}
+C {devices/iopin.sym} 3950 -800 3 0 {name=iopadout16ma_pad lab=iopadout16ma_pad}
+C {devices/iopin.sym} 4340 -830 3 0 {name=iopadout30ma_pad lab=iopadout30ma_pad}
+C {devices/iopin.sym} 2800 0 1 0 {name=iopadtriout4ma_pad lab=iopadtriout4ma_pad}
+C {devices/iopin.sym} 3250 0 1 0 {name=iopadtriout16ma_pad lab=iopadtriout16ma_pad}
+C {devices/iopin.sym} 3670 0 1 0 {name=iopadtriout30ma_pad lab=iopadtriout30ma_pad}
+C {devices/iopin.sym} 4170 0 1 0 {name=iopadinout4ma_pad lab=iopadinout4ma_pad}
+C {devices/iopin.sym} 4610 0 1 0 {name=iopadinout16ma_pad lab=iopadinout16ma_pad}
+C {devices/iopin.sym} 5030 0 1 0 {name=iopadinout30ma_pad lab=iopadinout30ma_pad}
+C {devices/iopin.sym} 2470 -860 2 0 {name=iopadin_p2c lab=iopadin_p2c}
+C {devices/iopin.sym} 3230 -930 3 0 {name=iopadout4ma_c2p lab=iopadout4ma_c2p}
+C {devices/iopin.sym} 3650 -880 3 0 {name=iopadout16ma_c2p lab=iopadout16ma_c2p}
+C {devices/iopin.sym} 4040 -860 3 0 {name=iopadout30ma_c2p lab=iopadout30ma_c2p}
+C {devices/iopin.sym} 4140 0 1 0 {name=iopadinout4ma_p2c lab=iopadinout4ma_p2c}
+C {devices/iopin.sym} 4570 0 1 0 {name=iopadinout16ma_p2c lab=iopadinout16ma_p2c}
+C {devices/iopin.sym} 4970 0 1 0 {name=iopadinout30ma_p2c lab=iopadinout30ma_p2c}
+C {devices/iopin.sym} 2500 0 1 0 {name=iopadtriout4ma_c2p lab=iopadtriout4ma_c2p}
+C {devices/iopin.sym} 2460 0 1 0 {name=iopadtriout4ma_c2p_en lab=iopadtriout4ma_c2p_en}
+C {devices/iopin.sym} 2950 0 1 0 {name=iopadtriout16ma_c2p lab=iopadtriout16ma_c2p}
+C {devices/iopin.sym} 2900 0 1 0 {name=iopadtriout16ma_c2p_en lab=iopadtriout16ma_c2p_en}
+C {devices/iopin.sym} 3370 0 1 0 {name=iopadtriout30ma_c2p lab=iopadtriout30ma_c2p}
+C {devices/iopin.sym} 3320 0 1 0 {name=iopadtriout30ma_c2p_en lab=iopadtriout30ma_c2p_en}
+C {devices/iopin.sym} 3840 0 1 0 {name=iopadinout4ma_c2p lab=iopadinout4ma_c2p}
+C {devices/iopin.sym} 3780 0 1 0 {name=iopadinout4ma_c2p_en lab=iopadinout4ma_c2p_en}
+C {devices/iopin.sym} 4270 0 1 0 {name=iopadinout16ma_c2p lab=iopadinout16ma_c2p}
+C {devices/iopin.sym} 4220 0 1 0 {name=iopadinout16ma_c2p_en lab=iopadinout16ma_c2p_en}
+C {devices/iopin.sym} 4670 0 1 0 {name=iopadinout30ma_c2p lab=iopadinout30ma_c2p}
+C {devices/iopin.sym} 4640 0 1 0 {name=iopadinout30ma_c2p_en lab=iopadinout30ma_c2p_en}
+C {devices/iopin.sym} 5430 -580 0 0 {name=ana_out lab=ana_out}
+C {devices/iopin.sym} 5430 -560 0 0 {name=ana_outres lab=ana_outres}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Gallery.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Gallery.sym
new file mode 100644
index 00000000..1b7fb7cc
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Gallery.sym
@@ -0,0 +1,118 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -340 130 -340 {}
+L 4 -130 340 130 340 {}
+L 4 -130 -340 -130 340 {}
+L 4 130 -340 130 340 {}
+L 7 130 -270 150 -270 {}
+L 7 -150 -270 -130 -270 {}
+L 7 -150 -240 -130 -240 {}
+L 7 -150 -200 -130 -200 {}
+L 7 130 -240 150 -240 {}
+L 7 130 -200 150 -200 {}
+L 7 130 -160 150 -160 {}
+L 7 30 -360 30 -340 {}
+L 7 -40 -360 -40 -340 {}
+L 7 130 -120 150 -120 {}
+L 7 130 0 150 0 {}
+L 7 130 -40 150 -40 {}
+L 7 -150 0 -130 0 {}
+L 7 -150 -120 -130 -120 {}
+L 7 -150 -40 -130 -40 {}
+L 7 -150 280 -130 280 {}
+L 7 -150 240 -130 240 {}
+L 7 130 -80 150 -80 {}
+L 7 130 40 150 40 {}
+L 7 -150 120 -130 120 {}
+L 7 -150 200 -130 200 {}
+L 7 130 80 150 80 {}
+L 7 -150 80 -130 80 {}
+L 7 -150 160 -130 160 {}
+L 7 130 120 150 120 {}
+L 7 -150 -160 -130 -160 {}
+L 7 130 160 150 160 {}
+L 7 130 190 150 190 {}
+L 7 130 220 150 220 {}
+L 7 -150 -80 -130 -80 {}
+L 7 -150 40 -130 40 {}
+L 7 130 260 150 260 {}
+L 7 130 290 150 290 {}
+L 7 0 340 0 360 {}
+B 5 147.5 -272.5 152.5 -267.5 {name=iopadin_pad dir=inout}
+B 5 -152.5 -272.5 -147.5 -267.5 {name=iopadout4ma_c2p dir=inout}
+B 5 -152.5 -242.5 -147.5 -237.5 {name=iopadout16ma_c2p dir=inout}
+B 5 -152.5 -202.5 -147.5 -197.5 {name=iopadout30ma_c2p dir=inout}
+B 5 147.5 -242.5 152.5 -237.5 {name=iopadin_p2c dir=inout}
+B 5 147.5 -202.5 152.5 -197.5 {name=iopadout4ma_pad dir=inout}
+B 5 147.5 -162.5 152.5 -157.5 {name=iopadout30ma_pad dir=inout}
+B 5 27.5 -362.5 32.5 -357.5 {name=iovdd dir=inout}
+B 5 -42.5 -362.5 -37.5 -357.5 {name=vdd dir=inout}
+B 5 147.5 -122.5 152.5 -117.5 {name=iopadout16ma_pad dir=inout}
+B 5 147.5 -2.5 152.5 2.5 {name=ana_out dir=inout}
+B 5 147.5 -42.5 152.5 -37.5 {name=ana_outres dir=inout}
+B 5 -152.5 -2.5 -147.5 2.5 {name=iopadinout16ma_c2p_en dir=inout}
+B 5 -152.5 -122.5 -147.5 -117.5 {name=iopadinout16ma_c2p dir=inout}
+B 5 -152.5 -42.5 -147.5 -37.5 {name=iopadinout4ma_c2p_en dir=inout}
+B 5 -152.5 277.5 -147.5 282.5 {name=iopadtriout30ma_c2p_en dir=inout}
+B 5 -152.5 237.5 -147.5 242.5 {name=iopadtriout16ma_c2p_en dir=inout}
+B 5 147.5 -82.5 152.5 -77.5 {name=iopadinout30ma_pad dir=inout}
+B 5 147.5 37.5 152.5 42.5 {name=iopadinout16ma_pad dir=inout}
+B 5 -152.5 117.5 -147.5 122.5 {name=iopadtriout16ma_c2p dir=inout}
+B 5 -152.5 197.5 -147.5 202.5 {name=iopadtriout4ma_c2p_en dir=inout}
+B 5 147.5 77.5 152.5 82.5 {name=iopadinout4ma_pad dir=inout}
+B 5 -152.5 77.5 -147.5 82.5 {name=iopadtriout4ma_c2p dir=inout}
+B 5 -152.5 157.5 -147.5 162.5 {name=iopadtriout30ma_c2p dir=inout}
+B 5 147.5 117.5 152.5 122.5 {name=iopadinout30ma_p2c dir=inout}
+B 5 -152.5 -162.5 -147.5 -157.5 {name=iopadinout4ma_c2p dir=inout}
+B 5 147.5 157.5 152.5 162.5 {name=iopadtriout30ma_pad dir=inout}
+B 5 147.5 187.5 152.5 192.5 {name=iopadinout16ma_p2c dir=inout}
+B 5 147.5 217.5 152.5 222.5 {name=iopadinout4ma_p2c dir=inout}
+B 5 -152.5 -82.5 -147.5 -77.5 {name=iopadinout30ma_c2p dir=inout}
+B 5 -152.5 37.5 -147.5 42.5 {name=iopadinout30ma_c2p_en dir=inout}
+B 5 147.5 257.5 152.5 262.5 {name=iopadtriout16ma_pad dir=inout}
+B 5 147.5 287.5 152.5 292.5 {name=iopadtriout4ma_pad dir=inout}
+B 5 -2.5 357.5 2.5 362.5 {name=vss dir=inout}
+T {sg13g2_Gallery} -21 -26 0 0 0.2 0.2 {}
+T {@name} 135 -352 0 0 0.2 0.2 {}
+T {iopadin_pad} 125 -274 0 1 0.2 0.2 {}
+T {iopadout4ma_c2p} -35 -274 0 1 0.2 0.2 {}
+T {iopadout16ma_c2p} -25 -244 0 1 0.2 0.2 {}
+T {iopadout30ma_c2p} -25 -204 0 1 0.2 0.2 {}
+T {iopadin_p2c} 125 -244 0 1 0.2 0.2 {}
+T {iopadout4ma_pad} 125 -204 0 1 0.2 0.2 {}
+T {iopadout30ma_pad} 125 -164 0 1 0.2 0.2 {}
+T {iovdd} 45 -334 0 1 0.2 0.2 {}
+T {vdd} -35 -334 0 1 0.2 0.2 {}
+T {iopadout16ma_pad} 125 -124 0 1 0.2 0.2 {}
+T {ana_out} 125 -4 0 1 0.2 0.2 {}
+T {ana_outres} 125 -44 0 1 0.2 0.2 {}
+T {iopadinout16ma_c2p_en} 5 -4 0 1 0.2 0.2 {}
+T {iopadinout16ma_c2p} -15 -124 0 1 0.2 0.2 {}
+T {iopadinout4ma_c2p_en} -5 -44 0 1 0.2 0.2 {}
+T {iopadtriout30ma_c2p_en} 5 276 0 1 0.2 0.2 {}
+T {iopadtriout16ma_c2p_en} 5 236 0 1 0.2 0.2 {}
+T {iopadinout30ma_pad} 125 -84 0 1 0.2 0.2 {}
+T {iopadinout16ma_pad} 125 36 0 1 0.2 0.2 {}
+T {iopadtriout16ma_c2p} -15 116 0 1 0.2 0.2 {}
+T {iopadtriout4ma_c2p_en} 5 196 0 1 0.2 0.2 {}
+T {iopadinout4ma_pad} 125 76 0 1 0.2 0.2 {}
+T {iopadtriout4ma_c2p} -15 76 0 1 0.2 0.2 {}
+T {iopadtriout30ma_c2p} -15 156 0 1 0.2 0.2 {}
+T {iopadinout30ma_p2c} 125 116 0 1 0.2 0.2 {}
+T {iopadinout4ma_c2p} -15 -164 0 1 0.2 0.2 {}
+T {iopadtriout30ma_pad} 125 156 0 1 0.2 0.2 {}
+T {iopadinout16ma_p2c} 125 186 0 1 0.2 0.2 {}
+T {iopadinout4ma_p2c} 125 216 0 1 0.2 0.2 {}
+T {iopadinout30ma_c2p} -15 -84 0 1 0.2 0.2 {}
+T {iopadinout30ma_c2p_en} 5 36 0 1 0.2 0.2 {}
+T {iopadtriout16ma_pad} 125 256 0 1 0.2 0.2 {}
+T {iopadtriout4ma_pad} 125 286 0 1 0.2 0.2 {}
+T {vss} 5 326 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_GateDecode.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_GateDecode.sch
new file mode 100644
index 00000000..f8f02bdd
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_GateDecode.sch
@@ -0,0 +1,107 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N -360 -210 -260 -210 {
+lab=#net1}
+N -80 -200 60 -200 {
+lab=#net2}
+N -320 20 -130 20 {
+lab=#net3}
+N 170 20 460 20 {
+lab=pgate}
+N 360 -200 450 -200 {
+lab=ngate}
+N -670 -210 -600 -210 {
+lab=en}
+N -670 -210 -670 0 {
+lab=en}
+N -720 -210 -670 -210 {
+lab=en}
+N -670 0 -560 -0 {
+lab=en}
+N -610 40 -560 40 {
+lab=core}
+N -610 -100 -610 40 {
+lab=core}
+N -740 40 -610 40 {
+lab=core}
+N -610 -100 -260 -100 {
+lab=core}
+N -260 -190 -260 -100 {
+lab=core}
+N -490 -170 -490 -120 {
+lab=vss}
+N -170 -120 200 -120 {
+lab=vss}
+N 200 -140 200 -120 {
+lab=vss}
+N -210 -140 -210 -120 {
+lab=vss}
+N -490 -120 -210 -120 {
+lab=vss}
+N -460 100 -460 140 {
+lab=vss}
+N -170 140 10 140 {
+lab=vss}
+N 10 80 10 140 {
+lab=vss}
+N -170 -120 -170 140 {
+lab=vss}
+N -210 -120 -170 -120 {
+lab=vss}
+N -220 140 -170 140 {
+lab=vss}
+N -490 -340 -490 -260 {
+lab=vdd}
+N -30 -340 200 -340 {
+lab=vdd}
+N 200 -340 200 -260 {
+lab=vdd}
+N -210 -340 -210 -260 {
+lab=vdd}
+N -490 -340 -210 -340 {
+lab=vdd}
+N -460 -80 -460 -60 {
+lab=vdd}
+N -30 -80 10 -80 {
+lab=vdd}
+N 10 -80 10 -40 {
+lab=vdd}
+N -30 -340 -30 -80 {
+lab=vdd}
+N -120 -340 -30 -340 {
+lab=vdd}
+N -460 -80 -30 -80 {
+lab=vdd}
+N 70 -280 70 -40 {
+lab=iovdd}
+N 70 -280 260 -280 {
+lab=iovdd}
+N 260 -280 260 -260 {
+lab=iovdd}
+N -220 140 -220 200 {
+lab=vss}
+N -460 140 -220 140 {
+lab=vss}
+N -120 -390 -120 -340 {
+lab=vdd}
+N -210 -340 -120 -340 {
+lab=vdd}
+N 260 -350 260 -280 {
+lab=iovdd}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_inv_x1.sym} -450 -210 0 0 {name=x1}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_nor2_x1.sym} -120 -200 0 0 {name=x2}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelUp.sym} 20 20 0 0 {name=x3}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_nand2_x1.sym} -410 20 0 0 {name=x4}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelUp.sym} 210 -200 0 0 {name=x5}
+C {devices/ipin.sym} -720 -210 0 0 {name=en lab=en}
+C {devices/ipin.sym} -740 40 0 0 {name=core lab=core}
+C {devices/iopin.sym} -220 200 0 0 {name=vss lab=vss}
+C {devices/iopin.sym} -120 -390 0 0 {name=vdd lab=vdd}
+C {devices/iopin.sym} 260 -350 0 0 {name=iovdd lab=iovdd}
+C {devices/opin.sym} 450 -200 0 0 {name=ngate lab=ngate}
+C {devices/opin.sym} 460 20 0 0 {name=pgate lab=pgate}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_GateDecode.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_GateDecode.sym
new file mode 100644
index 00000000..8a65f84c
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_GateDecode.sym
@@ -0,0 +1,37 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -50 130 -50 {}
+L 4 -130 50 130 50 {}
+L 4 -130 -50 -130 50 {}
+L 4 130 -50 130 50 {}
+L 4 -150 -20 -130 -20 {}
+L 4 130 -20 150 -20 {}
+L 4 130 20 150 20 {}
+L 4 -150 20 -130 20 {}
+L 7 -20 -70 -20 -50 {}
+L 7 20 -70 20 -50 {}
+L 7 -20 50 -20 70 {}
+B 5 -22.5 -72.5 -17.5 -67.5 {name=vdd dir=inout}
+B 5 17.5 -72.5 22.5 -67.5 {name=iovdd dir=inout}
+B 5 -152.5 -22.5 -147.5 -17.5 {name=en dir=in}
+B 5 147.5 -22.5 152.5 -17.5 {name=ngate dir=out}
+B 5 147.5 17.5 152.5 22.5 {name=pgate dir=out}
+B 5 -152.5 17.5 -147.5 22.5 {name=core dir=in}
+B 5 -22.5 67.5 -17.5 72.5 {name=vss dir=inout}
+T {@symname} -94.5 -6 0 0 0.3 0.3 {}
+T {@name} 135 -62 0 0 0.2 0.2 {}
+T {vdd} -15 -44 0 1 0.2 0.2 {}
+T {iovdd} 35 -44 0 1 0.2 0.2 {}
+T {en} -125 -24 0 0 0.2 0.2 {}
+T {ngate} 125 -24 0 1 0.2 0.2 {}
+T {pgate} 125 16 0 1 0.2 0.2 {}
+T {core} -125 16 0 0 0.2 0.2 {}
+T {vss} -15 36 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_GateLevelUpInv.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_GateLevelUpInv.sch
new file mode 100644
index 00000000..d401cbf0
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_GateLevelUpInv.sch
@@ -0,0 +1,59 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 1030 -440 1030 -400 {
+lab=vss}
+N 1410 -400 1500 -400 {
+lab=vss}
+N 1500 -440 1500 -400 {
+lab=vss}
+N 1080 -610 1080 -580 {
+lab=iovdd}
+N 1530 -610 1550 -610 {
+lab=iovdd}
+N 1550 -610 1550 -580 {
+lab=iovdd}
+N 1500 -640 1500 -580 {
+lab=vdd}
+N 1180 -640 1500 -640 {
+lab=vdd}
+N 1030 -640 1030 -580 {
+lab=vdd}
+N 860 -510 900 -510 {
+lab=core}
+N 860 -510 860 -340 {
+lab=core}
+N 810 -510 860 -510 {
+lab=core}
+N 860 -340 1370 -340 {
+lab=core}
+N 1370 -510 1370 -340 {
+lab=core}
+N 1200 -510 1250 -510 {
+lab=#net1}
+N 1670 -510 1710 -510 {
+lab=pgate}
+N 1180 -690 1180 -640 {
+lab=vdd}
+N 1030 -640 1180 -640 {
+lab=vdd}
+N 1530 -680 1530 -610 {
+lab=iovdd}
+N 1080 -610 1530 -610 {
+lab=iovdd}
+N 1410 -400 1410 -310 {
+lab=vss}
+N 1030 -400 1410 -400 {
+lab=vss}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelUpInv.sym} 1050 -510 0 0 {name=x1}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelUpInv.sym} 1520 -510 0 0 {name=x2}
+C {devices/iopin.sym} 1180 -690 3 0 {name=vdd lab=vdd}
+C {devices/iopin.sym} 1530 -680 3 0 {name=iovdd lab=iovdd}
+C {devices/iopin.sym} 810 -510 2 0 {name=core lab=core}
+C {devices/iopin.sym} 1410 -310 1 0 {name=vss lab=vss}
+C {devices/iopin.sym} 1710 -510 0 0 {name=pgate lab=pgate}
+C {devices/iopin.sym} 1250 -510 0 0 {name=ngate lab=ngate}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_GateLevelUpInv.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_GateLevelUpInv.sym
new file mode 100644
index 00000000..266bbd3c
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_GateLevelUpInv.sym
@@ -0,0 +1,34 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -60 130 -60 {}
+L 4 -130 60 130 60 {}
+L 4 -130 -60 -130 60 {}
+L 4 130 -60 130 60 {}
+L 7 -30 -80 -30 -60 {}
+L 7 20 -80 20 -60 {}
+L 7 130 -20 150 -20 {}
+L 7 130 20 150 20 {}
+L 7 -150 0 -130 0 {}
+L 7 0 60 0 80 {}
+B 5 -32.5 -82.5 -27.5 -77.5 {name=vdd dir=inout}
+B 5 17.5 -82.5 22.5 -77.5 {name=iovdd dir=inout}
+B 5 147.5 -22.5 152.5 -17.5 {name=ngate dir=inout}
+B 5 147.5 17.5 152.5 22.5 {name=pgate dir=inout}
+B 5 -152.5 -2.5 -147.5 2.5 {name=core dir=inout}
+B 5 -2.5 77.5 2.5 82.5 {name=vss dir=inout}
+T {sg13g2_GateLevelUpInv} -72.5 -6 0 0 0.2 0.2 {}
+T {@name} 135 -72 0 0 0.2 0.2 {}
+T {vdd} -45 -74 0 1 0.2 0.2 {}
+T {iovdd} 55 -74 0 1 0.2 0.2 {}
+T {ngate} 125 -24 0 1 0.2 0.2 {}
+T {pgate} 125 16 0 1 0.2 0.2 {}
+T {core} -105 -4 0 1 0.2 0.2 {}
+T {vss} 25 66 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadAnalog.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadAnalog.sch
new file mode 100644
index 00000000..c9bdc664
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadAnalog.sch
@@ -0,0 +1,104 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 2660 -380 2660 -330 {
+lab=iovss}
+N 2810 -530 2860 -530 {
+lab=pad}
+N 2860 -310 2860 -280 {
+lab=pad}
+N 2810 -280 2860 -280 {
+lab=pad}
+N 2660 -600 2660 -580 {
+lab=iovdd}
+N 2490 -600 2660 -600 {
+lab=iovdd}
+N 2490 -600 2490 -190 {
+lab=iovdd}
+N 2490 -190 2660 -190 {
+lab=iovdd}
+N 2660 -230 2660 -190 {
+lab=iovdd}
+N 2660 -430 2940 -430 {
+lab=iovss}
+N 2660 -480 2660 -430 {
+lab=iovss}
+N 3240 -480 3240 -450 {
+lab=pad}
+N 2860 -500 3240 -500 {
+lab=pad}
+N 2860 -530 2860 -500 {
+lab=pad}
+N 3240 -410 3280 -410 {
+lab=iovdd}
+N 3280 -600 3280 -410 {
+lab=iovdd}
+N 3090 -600 3280 -600 {
+lab=iovdd}
+N 2860 -310 2940 -310 {
+lab=pad}
+N 2860 -500 2860 -310 {
+lab=pad}
+N 3240 -330 3280 -330 {
+lab=iovdd}
+N 3280 -410 3280 -330 {
+lab=iovdd}
+N 3540 -600 3540 -450 {
+lab=iovdd}
+N 3280 -600 3540 -600 {
+lab=iovdd}
+N 3540 -330 3540 -290 {
+lab=iovss}
+N 3390 -290 3540 -290 {
+lab=iovss}
+N 2660 -380 2900 -380 {
+lab=iovss}
+N 2660 -430 2660 -380 {
+lab=iovss}
+N 2900 -380 2900 -250 {
+lab=iovss}
+N 3230 -250 3390 -250 {
+lab=iovss}
+N 3390 -290 3390 -250 {
+lab=iovss}
+N 3240 -290 3390 -290 {
+lab=iovss}
+N 3230 -250 3230 -170 {
+lab=iovss}
+N 2900 -250 3230 -250 {
+lab=iovss}
+N 3090 -670 3090 -600 {
+lab=iovdd}
+N 2660 -600 3090 -600 {
+lab=iovdd}
+N 3350 -480 3380 -480 {
+lab=pad}
+N 3240 -500 3240 -480 {
+lab=pad}
+N 3380 -480 3380 -390 {
+lab=pad}
+N 3680 -380 3740 -380 {
+lab=padres}
+N 3350 -530 3350 -480 {
+lab=pad}
+N 3240 -480 3350 -480 {
+lab=pad}
+N 3220 -670 3220 -630 {
+lab=vdd}
+N 3340 -200 3340 -170 {
+lab=iovss}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCNDiode.sym} 3090 -430 0 0 {name=x3}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCPDiode.sym} 3090 -310 0 0 {name=x4}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_SecondaryProtection.sym} 3530 -390 0 0 {}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N20N0D.sym} 2660 -530 0 0 {name=x1}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P20N0D.sym} 2660 -280 2 1 {name=x2}
+C {devices/iopin.sym} 3740 -380 0 0 {name=padres lab=padres}
+C {devices/iopin.sym} 3230 -170 1 0 {name=iovss lab=iovss}
+C {devices/iopin.sym} 3090 -670 3 0 {name=iovdd lab=iovdd}
+C {devices/iopin.sym} 3350 -530 3 0 {name=pad lab=pad}
+C {devices/iopin.sym} 3220 -670 3 0 {name=vdd lab=vdd}
+C {devices/iopin.sym} 3340 -170 1 0 {name=vss lab=vss}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadAnalog.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadAnalog.sym
new file mode 100644
index 00000000..b4e02a17
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadAnalog.sym
@@ -0,0 +1,34 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -60 130 -60 {}
+L 4 -130 60 130 60 {}
+L 4 -130 -60 -130 60 {}
+L 4 130 -60 130 60 {}
+L 7 -30 -80 -30 -60 {}
+L 7 30 -80 30 -60 {}
+L 7 130 -10 150 -10 {}
+L 7 130 10 150 10 {}
+L 7 -30 60 -30 80 {}
+L 7 30 60 30 80 {}
+B 5 -32.5 -82.5 -27.5 -77.5 {name=vdd dir=inout}
+B 5 27.5 -82.5 32.5 -77.5 {name=iovdd dir=inout}
+B 5 147.5 -12.5 152.5 -7.5 {name=pad dir=inout}
+B 5 147.5 7.5 152.5 12.5 {name=padres dir=inout}
+B 5 -32.5 77.5 -27.5 82.5 {name=vss dir=inout}
+B 5 27.5 77.5 32.5 82.5 {name=iovss dir=inout}
+T {sg13g2_IOPadAnalog} -69 -6 0 0 0.2 0.2 {}
+T {@name} 135 -72 0 0 0.2 0.2 {}
+T {vdd} -15 -54 0 1 0.2 0.2 {}
+T {iovdd} 45 -54 0 1 0.2 0.2 {}
+T {pad} 125 -14 0 1 0.2 0.2 {}
+T {padres} 125 6 0 1 0.2 0.2 {}
+T {vss} -25 46 0 1 0.2 0.2 {}
+T {iovss} 45 46 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadIOVdd.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadIOVdd.sch
new file mode 100644
index 00000000..30ecb0fd
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadIOVdd.sch
@@ -0,0 +1,54 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 1750 -150 1810 -150 {
+lab=#net1}
+N 1610 -250 1610 -200 {
+lab=iovdd}
+N 1970 -250 1970 -210 {
+lab=iovdd}
+N 1610 -100 1610 -50 {
+lab=iovss}
+N 1910 -50 1970 -50 {
+lab=iovss}
+N 1970 -90 1970 -50 {
+lab=iovss}
+N 2150 -150 2180 -150 {
+lab=iovdd}
+N 2150 -250 2150 -150 {
+lab=iovdd}
+N 2110 -150 2150 -150 {
+lab=iovdd}
+N 1970 -250 2150 -250 {
+lab=iovdd}
+N 1890 -250 1970 -250 {
+lab=iovdd}
+N 2180 -150 2180 -30 {
+lab=iovdd}
+N 2180 -170 2180 -150 {
+lab=iovdd}
+N 1450 -30 2180 -30 {
+lab=iovdd}
+N 1450 -150 1450 -30 {
+lab=iovdd}
+N 1890 -320 1890 -250 {
+lab=iovdd}
+N 1610 -250 1890 -250 {
+lab=iovdd}
+N 1910 -50 1910 30 {
+lab=iovss}
+N 1610 -50 1910 -50 {
+lab=iovss}
+N 1990 -320 1990 -290 {}
+N 2030 0 2030 30 {}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N43N43D4R.sym} 1960 -150 0 0 {}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_RCClampResistor.sym} 2330 -160 0 1 {name=x1}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_RCClampInverter.sym} 1600 -150 0 0 {name=x2}
+C {devices/iopin.sym} 1910 30 1 0 {name=iovss lab=iovss}
+C {devices/iopin.sym} 1890 -320 3 0 {name=iovdd lab=iovdd}
+C {devices/iopin.sym} 2030 30 1 0 {name=vss lab=vss}
+C {devices/iopin.sym} 1990 -320 3 0 {name=vdd lab=vdd}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadIOVdd.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadIOVdd.sym
new file mode 100644
index 00000000..46435bb6
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadIOVdd.sym
@@ -0,0 +1,28 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -40 130 -40 {}
+L 4 -130 40 130 40 {}
+L 4 -130 -40 -130 40 {}
+L 4 130 -40 130 40 {}
+L 7 20 -60 20 -40 {}
+L 7 -20 -60 -20 -40 {}
+L 7 -20 40 -20 60 {}
+L 7 20 40 20 60 {}
+B 5 17.5 -62.5 22.5 -57.5 {name=iovdd dir=inout}
+B 5 -22.5 -62.5 -17.5 -57.5 {name=vdd dir=inout}
+B 5 -22.5 57.5 -17.5 62.5 {name=vss dir=inout}
+B 5 17.5 57.5 22.5 62.5 {name=iovss dir=inout}
+T {sg13g2_IOPadIOVdd} -54.5 -6 0 0 0.2 0.2 {}
+T {@name} 135 -52 0 0 0.2 0.2 {}
+T {iovdd} 35 -34 0 1 0.2 0.2 {}
+T {vdd} -15 -34 0 1 0.2 0.2 {}
+T {vss} -15 26 0 1 0.2 0.2 {}
+T {iovss} 35 26 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadIOVss.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadIOVss.sch
new file mode 100644
index 00000000..92cdce50
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadIOVss.sch
@@ -0,0 +1,45 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 2010 -220 2010 -150 {
+lab=iovss}
+N 1670 -130 1710 -130 {
+lab=iovss}
+N 1670 30 1690 30 {
+lab=iovss}
+N 1670 130 1670 170 {
+lab=iovss}
+N 1670 -130 1670 30 {
+lab=iovss}
+N 1990 10 2100 10 {
+lab=iovdd}
+N 2100 -110 2100 10 {
+lab=iovdd}
+N 2010 -110 2100 -110 {
+lab=iovdd}
+N 1990 50 1990 130 {
+lab=iovss}
+N 1670 130 1990 130 {
+lab=iovss}
+N 1670 30 1670 130 {
+lab=iovss}
+N 1670 -220 1670 -130 {
+lab=iovss}
+N 1670 -220 2010 -220 {
+lab=iovss}
+N 2100 -270 2100 -110 {
+lab=iovdd}
+N 1780 -320 1780 -270 {
+lab=vdd}
+N 1850 150 1850 200 {
+lab=vdd}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCNDiode.sym} 1860 -130 0 0 {name=x8}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCPDiode.sym} 1840 30 0 0 {name=x9}
+C {devices/iopin.sym} 1670 170 1 0 {name=iovss lab=iovss}
+C {devices/iopin.sym} 2100 -270 3 0 {name=iovdd lab=iovdd}
+C {devices/iopin.sym} 1780 -320 3 0 {name=vdd lab=vdd}
+C {devices/iopin.sym} 1850 200 1 0 {name=vss lab=vss}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadIOVss.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadIOVss.sym
new file mode 100644
index 00000000..a9a95fd5
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadIOVss.sym
@@ -0,0 +1,28 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -40 130 -40 {}
+L 4 -130 40 130 40 {}
+L 4 -130 -40 -130 40 {}
+L 4 130 -40 130 40 {}
+L 7 -20 -60 -20 -40 {}
+L 7 20 -60 20 -40 {}
+L 7 20 40 20 60 {}
+L 7 -20 40 -20 60 {}
+B 5 -22.5 -62.5 -17.5 -57.5 {name=vdd dir=inout}
+B 5 17.5 -62.5 22.5 -57.5 {name=iovdd dir=inout}
+B 5 17.5 57.5 22.5 62.5 {name=iovss dir=inout}
+B 5 -22.5 57.5 -17.5 62.5 {name=vss dir=inout}
+T {sg13g2_IOPadIOVss} -64.5 -6 0 0 0.2 0.2 {}
+T {@name} 135 -52 0 0 0.2 0.2 {}
+T {vdd} -15 -34 0 1 0.2 0.2 {}
+T {iovdd} 35 -34 0 1 0.2 0.2 {}
+T {iovss} 35 26 0 1 0.2 0.2 {}
+T {vss} -15 26 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadIn.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadIn.sch
new file mode 100644
index 00000000..be2a1f27
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadIn.sch
@@ -0,0 +1,58 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 910 -360 940 -360 {
+lab=vdd}
+N 820 -320 860 -320 {
+lab=#net1}
+N 860 -460 860 -320 {
+lab=#net1}
+N 860 -460 1300 -460 {
+lab=#net1}
+N 1300 -460 1300 -380 {
+lab=#net1}
+N 1240 -380 1300 -380 {
+lab=#net1}
+N 1240 -340 1360 -340 {
+lab=#net2}
+N 1360 -500 1360 -340 {
+lab=#net2}
+N 500 -500 1360 -500 {
+lab=#net2}
+N 500 -500 500 -340 {
+lab=#net2}
+N 500 -340 520 -340 {
+lab=#net2}
+N 860 -180 910 -180 {
+lab=vdd}
+N 910 -250 910 -180 {
+lab=vdd}
+N 820 -360 910 -360 {
+lab=vdd}
+N 510 -180 560 -180 {
+lab=p2c}
+N 670 -100 670 -60 {
+lab=vss}
+N 750 -100 750 -60 {
+lab=iovss}
+N 670 -290 670 -260 {
+lab=vdd}
+N 750 -290 750 -260 {
+lab=iovdd}
+N 910 -250 990 -250 {
+lab=vdd}
+N 910 -360 910 -250 {
+lab=vdd}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCNDiode.sym} 670 -340 0 0 {name=x1}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCPDiode.sym} 1090 -360 0 0 {name=x2}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelDown.sym} 710 -180 0 0 {name=x3}
+C {devices/iopin.sym} 750 -290 0 0 {name=iovdd lab=iovdd}
+C {devices/iopin.sym} 670 -290 0 0 {name=vdd lab=vdd}
+C {devices/iopin.sym} 670 -60 0 0 {name=vss lab=vss}
+C {devices/iopin.sym} 750 -60 0 0 {name=iovss lab=iovss}
+C {devices/iopin.sym} 510 -180 2 0 {name=p2c lab=p2c}
+C {devices/iopin.sym} 990 -250 0 0 {name=pad lab=pad}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadIn.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadIn.sym
new file mode 100644
index 00000000..e16e1810
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadIn.sym
@@ -0,0 +1,34 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -60 130 -60 {}
+L 4 -130 60 130 60 {}
+L 4 -130 -60 -130 60 {}
+L 4 130 -60 130 60 {}
+L 7 30 -80 30 -60 {}
+L 7 -30 -80 -30 -60 {}
+L 7 130 0 150 0 {}
+L 7 -150 0 -130 0 {}
+L 7 30 60 30 80 {}
+L 7 -30 60 -30 80 {}
+B 5 27.5 -82.5 32.5 -77.5 {name=iovdd dir=inout}
+B 5 -32.5 -82.5 -27.5 -77.5 {name=vdd dir=inout}
+B 5 147.5 -2.5 152.5 2.5 {name=pad dir=inout}
+B 5 -152.5 -2.5 -147.5 2.5 {name=p2c dir=inout}
+B 5 27.5 77.5 32.5 82.5 {name=iovss dir=inout}
+B 5 -32.5 77.5 -27.5 82.5 {name=vss dir=inout}
+T {sg13g2_IOPadIn} -51 -6 0 0 0.2 0.2 {}
+T {@name} 135 -72 0 0 0.2 0.2 {}
+T {iovdd} 65 -74 0 1 0.2 0.2 {}
+T {vdd} -35 -74 0 1 0.2 0.2 {}
+T {pad} 125 -4 0 1 0.2 0.2 {}
+T {p2c} -105 -4 0 1 0.2 0.2 {}
+T {iovss} 65 66 0 1 0.2 0.2 {}
+T {vss} -35 66 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadInOut16mA.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadInOut16mA.sch
new file mode 100644
index 00000000..163ffd0e
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadInOut16mA.sch
@@ -0,0 +1,135 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 1630 -170 1700 -170 {
+lab=pad}
+N 1630 50 1700 50 {
+lab=pad}
+N 1770 -110 1900 -110 {
+lab=iovss}
+N 2200 -170 2200 -130 {
+lab=pad}
+N 1700 -190 2200 -190 {
+lab=pad}
+N 1700 -170 1700 50 {
+lab=pad}
+N 1700 -190 1700 -170 {
+lab=pad}
+N 2200 -90 2200 -40 {
+lab=iovdd}
+N 1700 50 1880 50 {
+lab=pad}
+N 2180 30 2200 30 {
+lab=iovdd}
+N 2200 -40 2200 30 {
+lab=iovdd}
+N 1860 130 2180 130 {
+lab=iovss}
+N 2180 70 2180 130 {
+lab=iovss}
+N 1250 -50 1250 50 {
+lab=#net1}
+N 1250 50 1330 50 {
+lab=#net1}
+N 1250 -170 1250 -90 {
+lab=#net2}
+N 1250 -170 1330 -170 {
+lab=#net2}
+N 1080 60 1080 90 {
+lab=vss}
+N 1080 -180 1080 -140 {
+lab=vdd}
+N 1300 -250 1300 -40 {
+lab=iovdd}
+N 1120 -250 1300 -250 {
+lab=iovdd}
+N 850 -50 950 -50 {
+lab=c2p}
+N 1360 -310 1360 -250 {
+lab=iovdd}
+N 1300 -250 1360 -250 {
+lab=iovdd}
+N 1770 -110 1770 130 {
+lab=iovss}
+N 1860 130 1860 190 {
+lab=iovss}
+N 1770 130 1860 130 {
+lab=iovss}
+N 2260 -170 2290 -170 {
+lab=pad}
+N 2200 -190 2200 -170 {
+lab=pad}
+N 1360 -250 1480 -250 {
+lab=iovdd}
+N 1480 -40 2200 -40 {
+lab=iovdd}
+N 1480 130 1770 130 {
+lab=iovss}
+N 860 -90 950 -90 {
+lab=c2p_en}
+N 1120 -250 1120 -140 {
+lab=iovdd}
+N 1480 -250 1480 -230 {
+lab=iovdd}
+N 1480 -110 1770 -110 {
+lab=iovss}
+N 1480 -40 1480 -10 {
+lab=iovdd}
+N 1300 -40 1480 -40 {
+lab=iovdd}
+N 1480 110 1480 130 {
+lab=iovss}
+N 2260 -170 2260 -30 {
+lab=pad}
+N 2200 -170 2260 -170 {
+lab=pad}
+N 2260 -30 2340 -30 {
+lab=pad}
+N 2450 50 2450 130 {
+lab=iovss}
+N 2180 130 2450 130 {
+lab=iovss}
+N 1480 -250 2450 -250 {
+lab=iovdd}
+N 2450 -250 2450 -110 {
+lab=iovdd}
+N 2530 50 2530 270 {
+lab=vss}
+N 1180 270 2530 270 {
+lab=vss}
+N 1180 60 1180 270 {
+lab=vss}
+N 1080 60 1180 60 {
+lab=vss}
+N 1080 0 1080 60 {
+lab=vss}
+N 2530 -340 2530 -110 {
+lab=vdd}
+N 1030 -340 2530 -340 {
+lab=vdd}
+N 1030 -340 1030 -180 {
+lab=vdd}
+N 1030 -180 1080 -180 {
+lab=vdd}
+N 1080 -230 1080 -180 {
+lab=vdd}
+N 2640 -30 2740 -30 {
+lab=c2p}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCNDiode.sym} 2050 -110 0 0 {name=x8}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCPDiode.sym} 2030 50 0 0 {name=x9}
+C {devices/iopin.sym} 1860 190 1 0 {name=iovss lab=iovss}
+C {devices/iopin.sym} 2290 -170 0 0 {name=pad lab=pad}
+C {devices/iopin.sym} 1080 90 1 0 {name=vss lab=vss}
+C {devices/iopin.sym} 850 -50 2 0 {name=c2p lab=c2p}
+C {devices/iopin.sym} 1080 -230 3 0 {name=vdd lab=vdd}
+C {devices/iopin.sym} 1360 -310 3 0 {name=iovdd lab=iovdd}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_GateDecode.sym} 1100 -70 0 0 {name=x1}
+C {devices/iopin.sym} 860 -90 2 0 {name=c2p_en lab=c2p_en}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N8N8D.sym} 1480 -170 0 0 {name=x2}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P8N8D.sym} 1480 50 0 0 {name=x3}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelDown.sym} 2490 -30 0 1 {name=x4}
+C {devices/iopin.sym} 2740 -30 0 0 {name=p2c lab=p2c}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadInOut16mA.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadInOut16mA.sym
new file mode 100644
index 00000000..2096224c
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadInOut16mA.sym
@@ -0,0 +1,40 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -80 130 -80 {}
+L 4 -130 80 130 80 {}
+L 4 -130 -80 -130 80 {}
+L 4 130 -80 130 80 {}
+L 7 20 -100 20 -80 {}
+L 7 -20 -100 -20 -80 {}
+L 7 130 -30 150 -30 {}
+L 7 -150 -20 -130 -20 {}
+L 7 -150 20 -130 20 {}
+L 7 130 30 150 30 {}
+L 7 -20 80 -20 100 {}
+L 7 20 80 20 100 {}
+B 5 17.5 -102.5 22.5 -97.5 {name=iovdd dir=inout}
+B 5 -22.5 -102.5 -17.5 -97.5 {name=vdd dir=inout}
+B 5 147.5 -32.5 152.5 -27.5 {name=pad dir=inout}
+B 5 -152.5 -22.5 -147.5 -17.5 {name=c2p_en dir=inout}
+B 5 -152.5 17.5 -147.5 22.5 {name=c2p dir=inout}
+B 5 147.5 27.5 152.5 32.5 {name=p2c dir=inout}
+B 5 -22.5 97.5 -17.5 102.5 {name=vss dir=inout}
+B 5 17.5 97.5 22.5 102.5 {name=iovss dir=inout}
+T {sg13g2_IOPadInOut16mA} -62.5 -6 0 0 0.2 0.2 {}
+T {@name} 135 -92 0 0 0.2 0.2 {}
+T {iovdd} 35 -74 0 1 0.2 0.2 {}
+T {vdd} -15 -74 0 1 0.2 0.2 {}
+T {pad} 125 -34 0 1 0.2 0.2 {}
+T {c2p_en} -85 -24 0 1 0.2 0.2 {}
+T {c2p} -105 16 0 1 0.2 0.2 {}
+T {p2c} 125 26 0 1 0.2 0.2 {}
+T {vss} -15 66 0 1 0.2 0.2 {}
+T {iovss} 35 66 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadInOut30mA.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadInOut30mA.sch
new file mode 100644
index 00000000..9fe544bb
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadInOut30mA.sch
@@ -0,0 +1,135 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 1440 -190 1510 -190 {
+lab=pad}
+N 1440 30 1510 30 {
+lab=pad}
+N 1580 -130 1710 -130 {
+lab=iovss}
+N 2010 -190 2010 -150 {
+lab=pad}
+N 1510 -210 2010 -210 {
+lab=pad}
+N 1510 -190 1510 30 {
+lab=pad}
+N 1510 -210 1510 -190 {
+lab=pad}
+N 2010 -110 2010 -60 {
+lab=iovdd}
+N 1510 30 1690 30 {
+lab=pad}
+N 1990 10 2010 10 {
+lab=iovdd}
+N 2010 -60 2010 10 {
+lab=iovdd}
+N 1670 110 1990 110 {
+lab=iovss}
+N 1990 50 1990 110 {
+lab=iovss}
+N 1060 -70 1060 30 {
+lab=#net1}
+N 1060 30 1140 30 {
+lab=#net1}
+N 1060 -190 1060 -110 {
+lab=#net2}
+N 1060 -190 1140 -190 {
+lab=#net2}
+N 890 40 890 70 {
+lab=vss}
+N 890 -200 890 -160 {
+lab=vdd}
+N 1110 -270 1110 -60 {
+lab=iovdd}
+N 930 -270 1110 -270 {
+lab=iovdd}
+N 660 -70 760 -70 {
+lab=c2p}
+N 1170 -330 1170 -270 {
+lab=iovdd}
+N 1110 -270 1170 -270 {
+lab=iovdd}
+N 1580 -130 1580 110 {
+lab=iovss}
+N 1670 110 1670 170 {
+lab=iovss}
+N 1580 110 1670 110 {
+lab=iovss}
+N 2070 -190 2100 -190 {
+lab=pad}
+N 2010 -210 2010 -190 {
+lab=pad}
+N 1170 -270 1290 -270 {
+lab=iovdd}
+N 1290 -60 2010 -60 {
+lab=iovdd}
+N 1290 110 1580 110 {
+lab=iovss}
+N 670 -110 760 -110 {
+lab=c2p_en}
+N 930 -270 930 -160 {
+lab=iovdd}
+N 1290 -270 1290 -250 {
+lab=iovdd}
+N 1290 -130 1580 -130 {
+lab=iovss}
+N 1290 -60 1290 -30 {
+lab=iovdd}
+N 1110 -60 1290 -60 {
+lab=iovdd}
+N 1290 90 1290 110 {
+lab=iovss}
+N 2070 -190 2070 -50 {
+lab=pad}
+N 2010 -190 2070 -190 {
+lab=pad}
+N 2070 -50 2150 -50 {
+lab=pad}
+N 2260 30 2260 110 {
+lab=iovss}
+N 1990 110 2260 110 {
+lab=iovss}
+N 1290 -270 2260 -270 {
+lab=iovdd}
+N 2260 -270 2260 -130 {
+lab=iovdd}
+N 2340 30 2340 250 {
+lab=vss}
+N 990 250 2340 250 {
+lab=vss}
+N 990 40 990 250 {
+lab=vss}
+N 890 40 990 40 {
+lab=vss}
+N 890 -20 890 40 {
+lab=vss}
+N 2340 -360 2340 -130 {
+lab=vdd}
+N 840 -360 2340 -360 {
+lab=vdd}
+N 840 -360 840 -200 {
+lab=vdd}
+N 840 -200 890 -200 {
+lab=vdd}
+N 890 -250 890 -200 {
+lab=vdd}
+N 2450 -50 2550 -50 {
+lab=p2c}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCNDiode.sym} 1860 -130 0 0 {name=x8}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCPDiode.sym} 1840 30 0 0 {name=x9}
+C {devices/iopin.sym} 1670 170 1 0 {name=iovss lab=iovss}
+C {devices/iopin.sym} 2100 -190 0 0 {name=pad lab=pad}
+C {devices/iopin.sym} 890 70 1 0 {name=vss lab=vss}
+C {devices/iopin.sym} 660 -70 2 0 {name=c2p lab=c2p}
+C {devices/iopin.sym} 890 -250 3 0 {name=vdd lab=vdd}
+C {devices/iopin.sym} 1170 -330 3 0 {name=iovdd lab=iovdd}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_GateDecode.sym} 910 -90 0 0 {name=x1}
+C {devices/iopin.sym} 670 -110 2 0 {name=c2p_en lab=c2p_en}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelDown.sym} 2300 -50 0 1 {name=x4}
+C {devices/iopin.sym} 2550 -50 0 0 {name=p2c lab=p2c}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N15N15D.sym} 1290 -190 0 0 {name=x5}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P15N15D.sym} 1290 30 0 0 {name=x6}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadInOut30mA.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadInOut30mA.sym
new file mode 100644
index 00000000..00fd8300
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadInOut30mA.sym
@@ -0,0 +1,40 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -80 130 -80 {}
+L 4 -130 80 130 80 {}
+L 4 -130 -80 -130 80 {}
+L 4 130 -80 130 80 {}
+L 7 30 -100 30 -80 {}
+L 7 -30 -100 -30 -80 {}
+L 7 130 -30 150 -30 {}
+L 7 -150 -20 -130 -20 {}
+L 7 -150 20 -130 20 {}
+L 7 130 30 150 30 {}
+L 7 -30 80 -30 100 {}
+L 7 30 80 30 100 {}
+B 5 27.5 -102.5 32.5 -97.5 {name=iovdd dir=inout}
+B 5 -32.5 -102.5 -27.5 -97.5 {name=vdd dir=inout}
+B 5 147.5 -32.5 152.5 -27.5 {name=pad dir=inout}
+B 5 -152.5 -22.5 -147.5 -17.5 {name=c2p_en dir=inout}
+B 5 -152.5 17.5 -147.5 22.5 {name=c2p dir=inout}
+B 5 147.5 27.5 152.5 32.5 {name=p2c dir=inout}
+B 5 -32.5 97.5 -27.5 102.5 {name=vss dir=inout}
+B 5 27.5 97.5 32.5 102.5 {name=iovss dir=inout}
+T {sg13g2_IOPadInOut30mA} -52.5 -6 0 0 0.2 0.2 {}
+T {@name} 135 -92 0 0 0.2 0.2 {}
+T {iovdd} 45 -74 0 1 0.2 0.2 {}
+T {vdd} -25 -74 0 1 0.2 0.2 {}
+T {pad} 125 -34 0 1 0.2 0.2 {}
+T {c2p_en} -85 -24 0 1 0.2 0.2 {}
+T {c2p} -105 16 0 1 0.2 0.2 {}
+T {p2c} 125 26 0 1 0.2 0.2 {}
+T {vss} -15 66 0 1 0.2 0.2 {}
+T {iovss} 45 66 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadInOut4mA.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadInOut4mA.sch
new file mode 100644
index 00000000..242b65bb
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadInOut4mA.sch
@@ -0,0 +1,135 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 1630 -170 1700 -170 {
+lab=pad}
+N 1630 50 1700 50 {
+lab=pad}
+N 1770 -110 1900 -110 {
+lab=iovss}
+N 2200 -170 2200 -130 {
+lab=pad}
+N 1700 -190 2200 -190 {
+lab=pad}
+N 1700 -170 1700 50 {
+lab=pad}
+N 1700 -190 1700 -170 {
+lab=pad}
+N 2200 -90 2200 -40 {
+lab=iovdd}
+N 1700 50 1880 50 {
+lab=pad}
+N 2180 30 2200 30 {
+lab=iovdd}
+N 2200 -40 2200 30 {
+lab=iovdd}
+N 1860 130 2180 130 {
+lab=iovss}
+N 2180 70 2180 130 {
+lab=iovss}
+N 1250 -50 1250 50 {
+lab=#net1}
+N 1250 50 1330 50 {
+lab=#net1}
+N 1250 -170 1250 -90 {
+lab=#net2}
+N 1250 -170 1330 -170 {
+lab=#net2}
+N 1080 50 1080 90 {
+lab=vss}
+N 1080 -190 1080 -140 {
+lab=vdd}
+N 1450 -40 2200 -40 {
+lab=iovdd}
+N 1300 -250 1300 -40 {
+lab=iovdd}
+N 1120 -250 1300 -250 {
+lab=iovdd}
+N 850 -50 950 -50 {
+lab=c2p}
+N 1360 -310 1360 -250 {
+lab=iovdd}
+N 1300 -250 1360 -250 {
+lab=iovdd}
+N 1770 -110 1770 130 {
+lab=iovss}
+N 1860 130 1860 190 {
+lab=iovss}
+N 1770 130 1860 130 {
+lab=iovss}
+N 2250 -170 2290 -170 {
+lab=pad}
+N 2200 -190 2200 -170 {
+lab=pad}
+N 1450 -110 1770 -110 {
+lab=iovss}
+N 1450 -250 1450 -230 {
+lab=iovdd}
+N 1360 -250 1450 -250 {
+lab=iovdd}
+N 1450 -40 1450 -10 {
+lab=iovdd}
+N 1300 -40 1450 -40 {
+lab=iovdd}
+N 1450 110 1450 130 {
+lab=iovss}
+N 1450 130 1770 130 {
+lab=iovss}
+N 860 -90 950 -90 {
+lab=c2p_en}
+N 1120 -250 1120 -140 {
+lab=iovdd}
+N 2250 -170 2250 -30 {
+lab=pad}
+N 2200 -170 2250 -170 {
+lab=pad}
+N 2250 -30 2340 -30 {
+lab=pad}
+N 2450 50 2450 130 {
+lab=iovss}
+N 2180 130 2450 130 {
+lab=iovss}
+N 2450 -250 2450 -110 {
+lab=iovdd}
+N 1450 -250 2450 -250 {
+lab=iovdd}
+N 2530 50 2530 280 {
+lab=vss}
+N 1170 280 2530 280 {
+lab=vss}
+N 1170 50 1170 280 {
+lab=vss}
+N 1080 50 1170 50 {
+lab=vss}
+N 1080 0 1080 50 {
+lab=vss}
+N 2530 -370 2530 -110 {
+lab=vdd}
+N 990 -370 2530 -370 {
+lab=vdd}
+N 990 -370 990 -190 {
+lab=vdd}
+N 990 -190 1080 -190 {
+lab=vdd}
+N 1080 -230 1080 -190 {
+lab=vdd}
+N 2640 -30 2750 -30 {
+lab=c2p}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCNDiode.sym} 2050 -110 0 0 {name=x8}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCPDiode.sym} 2030 50 0 0 {name=x9}
+C {devices/iopin.sym} 1860 190 1 0 {name=iovss lab=iovss}
+C {devices/iopin.sym} 2290 -170 0 0 {name=pad lab=pad}
+C {devices/iopin.sym} 1080 90 1 0 {name=vss lab=vss}
+C {devices/iopin.sym} 850 -50 2 0 {name=c2p lab=c2p}
+C {devices/iopin.sym} 1080 -230 3 0 {name=vdd lab=vdd}
+C {devices/iopin.sym} 1360 -310 3 0 {name=iovdd lab=iovdd}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N2N2D.sym} 1480 -170 0 0 {name=x4}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P2N2D.sym} 1480 50 0 0 {name=x5}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_GateDecode.sym} 1100 -70 0 0 {name=x1}
+C {devices/iopin.sym} 860 -90 2 0 {name=c2p_en lab=c2p_en}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelDown.sym} 2490 -30 0 1 {name=x3}
+C {devices/iopin.sym} 2750 -30 0 0 {name=p2c lab=p2c}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadInOut4mA.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadInOut4mA.sym
new file mode 100644
index 00000000..49d028da
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadInOut4mA.sym
@@ -0,0 +1,40 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -80 130 -80 {}
+L 4 -130 80 130 80 {}
+L 4 -130 -80 -130 80 {}
+L 4 130 -80 130 80 {}
+L 7 25 -100 25 -80 {}
+L 7 -25 -100 -25 -80 {}
+L 7 130 -30 150 -30 {}
+L 7 -150 -20 -130 -20 {}
+L 7 -150 20 -130 20 {}
+L 7 130 30 150 30 {}
+L 7 -25 80 -25 100 {}
+L 7 25 80 25 100 {}
+B 5 22.5 -102.5 27.5 -97.5 {name=iovdd dir=inout}
+B 5 -27.5 -102.5 -22.5 -97.5 {name=vdd dir=inout}
+B 5 147.5 -32.5 152.5 -27.5 {name=pad dir=inout}
+B 5 -152.5 -22.5 -147.5 -17.5 {name=c2p_en dir=inout}
+B 5 -152.5 17.5 -147.5 22.5 {name=c2p dir=inout}
+B 5 147.5 27.5 152.5 32.5 {name=p2c dir=inout}
+B 5 -27.5 97.5 -22.5 102.5 {name=vss dir=inout}
+B 5 22.5 97.5 27.5 102.5 {name=iovss dir=inout}
+T {sg13g2_IOPadInOut4mA} -48 -11 0 0 0.2 0.2 {}
+T {@name} 135 -92 0 0 0.2 0.2 {}
+T {iovdd} 40 -79 0 1 0.2 0.2 {}
+T {vdd} -15 -79 0 1 0.2 0.2 {}
+T {pad} 125 -34 0 1 0.2 0.2 {}
+T {c2p_en} -90 -24 0 1 0.2 0.2 {}
+T {c2p} -105 11 0 1 0.2 0.2 {}
+T {p2c} 125 26 0 1 0.2 0.2 {}
+T {vss} -15 66 0 1 0.2 0.2 {}
+T {iovss} 40 66 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadOut16mA.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadOut16mA.sch
new file mode 100644
index 00000000..e1368169
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadOut16mA.sch
@@ -0,0 +1,94 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 700 -720 770 -720 {
+lab=pad}
+N 700 -500 770 -500 {
+lab=pad}
+N 840 -660 970 -660 {
+lab=iovss}
+N 1270 -720 1270 -680 {
+lab=pad}
+N 770 -740 1270 -740 {
+lab=pad}
+N 770 -720 770 -500 {
+lab=pad}
+N 770 -740 770 -720 {
+lab=pad}
+N 550 -590 550 -560 {
+lab=iovdd}
+N 550 -590 1270 -590 {
+lab=iovdd}
+N 1270 -640 1270 -590 {
+lab=iovdd}
+N 770 -500 950 -500 {
+lab=pad}
+N 1250 -520 1270 -520 {
+lab=iovdd}
+N 1270 -590 1270 -520 {
+lab=iovdd}
+N 550 -440 550 -420 {
+lab=iovss}
+N 930 -420 1250 -420 {
+lab=iovss}
+N 1250 -480 1250 -420 {
+lab=iovss}
+N 320 -600 320 -500 {
+lab=#net1}
+N 320 -500 400 -500 {
+lab=#net1}
+N 320 -720 320 -640 {
+lab=#net2}
+N 320 -720 400 -720 {
+lab=#net2}
+N 170 -540 170 -450 {
+lab=vss}
+N 140 -790 140 -700 {
+lab=vdd}
+N 190 -800 190 -700 {
+lab=iovdd}
+N 430 -800 550 -800 {
+lab=iovdd}
+N 550 -800 550 -780 {
+lab=iovdd}
+N 370 -590 550 -590 {
+lab=iovdd}
+N 370 -800 370 -590 {
+lab=iovdd}
+N 190 -800 370 -800 {
+lab=iovdd}
+N -80 -620 20 -620 {
+lab=c2p}
+N 430 -860 430 -800 {
+lab=iovdd}
+N 370 -800 430 -800 {
+lab=iovdd}
+N 840 -660 840 -420 {
+lab=iovss}
+N 550 -660 840 -660 {
+lab=iovss}
+N 550 -420 840 -420 {
+lab=iovss}
+N 930 -420 930 -360 {
+lab=iovss}
+N 840 -420 930 -420 {
+lab=iovss}
+N 1270 -720 1360 -720 {
+lab=pad}
+N 1270 -740 1270 -720 {
+lab=pad}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N8N8D.sym} 550 -720 0 0 {name=x1}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCNDiode.sym} 1120 -660 0 0 {name=x3}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCPDiode.sym} 1100 -500 0 0 {name=x4}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_GateLevelUpInv.sym} 170 -620 0 0 {name=x5}
+C {devices/iopin.sym} 930 -360 1 0 {name=iovss lab=iovss}
+C {devices/iopin.sym} 1360 -720 0 0 {name=pad lab=pad}
+C {devices/iopin.sym} 170 -450 1 0 {name=vss lab=vss}
+C {devices/iopin.sym} -80 -620 2 0 {name=c2p lab=c2p}
+C {devices/iopin.sym} 140 -790 3 0 {name=vdd lab=vdd}
+C {devices/iopin.sym} 430 -860 3 0 {name=iovdd lab=iovdd}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P8N8D.sym} 550 -500 0 0 {name=x2}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadOut16mA.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadOut16mA.sym
new file mode 100644
index 00000000..241a8661
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadOut16mA.sym
@@ -0,0 +1,34 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -60 130 -60 {}
+L 4 -130 60 130 60 {}
+L 4 -130 -60 -130 60 {}
+L 4 130 -60 130 60 {}
+L 7 30 -80 30 -60 {}
+L 7 -30 -80 -30 -60 {}
+L 7 130 0 150 0 {}
+L 7 -150 0 -130 0 {}
+L 7 -30 60 -30 80 {}
+L 7 30 60 30 80 {}
+B 5 27.5 -82.5 32.5 -77.5 {name=iovdd dir=inout}
+B 5 -32.5 -82.5 -27.5 -77.5 {name=vdd dir=inout}
+B 5 147.5 -2.5 152.5 2.5 {name=pad dir=inout}
+B 5 -152.5 -2.5 -147.5 2.5 {name=c2p dir=inout}
+B 5 -32.5 77.5 -27.5 82.5 {name=vss dir=inout}
+B 5 27.5 77.5 32.5 82.5 {name=iovss dir=inout}
+T {sg13g2_IOPadOut16mA} -53.5 -6 0 0 0.2 0.2 {}
+T {@name} 135 -72 0 0 0.2 0.2 {}
+T {iovdd} 45 -54 0 1 0.2 0.2 {}
+T {vdd} -15 -54 0 1 0.2 0.2 {}
+T {pad} 125 -4 0 1 0.2 0.2 {}
+T {c2p} -105 -4 0 1 0.2 0.2 {}
+T {vss} -25 46 0 1 0.2 0.2 {}
+T {iovss} 45 46 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadOut30mA.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadOut30mA.sch
new file mode 100644
index 00000000..41aac99f
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadOut30mA.sch
@@ -0,0 +1,94 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 1630 -170 1700 -170 {
+lab=pad}
+N 1630 50 1700 50 {
+lab=pad}
+N 1770 -110 1900 -110 {
+lab=iovss}
+N 2200 -170 2200 -130 {
+lab=pad}
+N 1700 -190 2200 -190 {
+lab=pad}
+N 1700 -170 1700 50 {
+lab=pad}
+N 1700 -190 1700 -170 {
+lab=pad}
+N 1480 -40 1480 -10 {
+lab=iovdd}
+N 1480 -40 2200 -40 {
+lab=iovdd}
+N 2200 -90 2200 -40 {
+lab=iovdd}
+N 1700 50 1880 50 {
+lab=pad}
+N 2180 30 2200 30 {
+lab=iovdd}
+N 2200 -40 2200 30 {
+lab=iovdd}
+N 1480 110 1480 130 {
+lab=iovss}
+N 1860 130 2180 130 {
+lab=iovss}
+N 2180 70 2180 130 {
+lab=iovss}
+N 1250 -50 1250 50 {
+lab=#net1}
+N 1250 50 1330 50 {
+lab=#net1}
+N 1250 -170 1250 -90 {
+lab=#net2}
+N 1250 -170 1330 -170 {
+lab=#net2}
+N 1100 10 1100 100 {
+lab=vss}
+N 1070 -240 1070 -150 {
+lab=vdd}
+N 1120 -250 1120 -150 {
+lab=iovdd}
+N 1360 -250 1480 -250 {
+lab=iovdd}
+N 1480 -250 1480 -230 {
+lab=iovdd}
+N 1300 -40 1480 -40 {
+lab=iovdd}
+N 1300 -250 1300 -40 {
+lab=iovdd}
+N 1120 -250 1300 -250 {
+lab=iovdd}
+N 850 -70 950 -70 {
+lab=c2p}
+N 1360 -310 1360 -250 {
+lab=iovdd}
+N 1300 -250 1360 -250 {
+lab=iovdd}
+N 1770 -110 1770 130 {
+lab=iovss}
+N 1480 -110 1770 -110 {
+lab=iovss}
+N 1480 130 1770 130 {
+lab=iovss}
+N 1860 130 1860 190 {
+lab=iovss}
+N 1770 130 1860 130 {
+lab=iovss}
+N 2200 -170 2290 -170 {
+lab=pad}
+N 2200 -190 2200 -170 {
+lab=pad}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N15N15D.sym} 1480 -170 0 0 {name=x1}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P15N15D.sym} 1480 50 0 0 {name=x2}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCNDiode.sym} 2050 -110 0 0 {name=x8}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCPDiode.sym} 2030 50 0 0 {name=x9}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_GateLevelUpInv.sym} 1100 -70 0 0 {name=x10}
+C {devices/iopin.sym} 1860 190 1 0 {name=iovss lab=iovss}
+C {devices/iopin.sym} 2290 -170 0 0 {name=pad lab=pad}
+C {devices/iopin.sym} 1100 100 1 0 {name=vss lab=vss}
+C {devices/iopin.sym} 850 -70 2 0 {name=c2p lab=c2p}
+C {devices/iopin.sym} 1070 -240 3 0 {name=vdd lab=vdd}
+C {devices/iopin.sym} 1360 -310 3 0 {name=iovdd lab=iovdd}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadOut30mA.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadOut30mA.sym
new file mode 100644
index 00000000..e3b9a95d
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadOut30mA.sym
@@ -0,0 +1,34 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -60 130 -60 {}
+L 4 -130 60 130 60 {}
+L 4 -130 -60 -130 60 {}
+L 4 130 -60 130 60 {}
+L 7 -20 -80 -20 -60 {}
+L 7 20 -80 20 -60 {}
+L 7 130 0 150 0 {}
+L 7 -150 0 -130 0 {}
+L 7 20 60 20 80 {}
+L 7 -20 60 -20 80 {}
+B 5 -22.5 -82.5 -17.5 -77.5 {name=iovdd dir=inout}
+B 5 17.5 -82.5 22.5 -77.5 {name=vdd dir=inout}
+B 5 147.5 -2.5 152.5 2.5 {name=pad dir=inout}
+B 5 -152.5 -2.5 -147.5 2.5 {name=c2p dir=inout}
+B 5 17.5 77.5 22.5 82.5 {name=vss dir=inout}
+B 5 -22.5 77.5 -17.5 82.5 {name=iovss dir=inout}
+T {sg13g2_IOPadOut30mA} -53.5 -6 0 0 0.2 0.2 {}
+T {@name} 135 -72 0 0 0.2 0.2 {}
+T {iovdd} -5 -54 0 1 0.2 0.2 {}
+T {vdd} 35 -54 0 1 0.2 0.2 {}
+T {pad} 125 -4 0 1 0.2 0.2 {}
+T {c2p} -105 -4 0 1 0.2 0.2 {}
+T {vss} 25 46 0 1 0.2 0.2 {}
+T {iovss} -5 46 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadOut4mA.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadOut4mA.sch
new file mode 100644
index 00000000..695267f4
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadOut4mA.sch
@@ -0,0 +1,108 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 820 -500 870 -500 {
+lab=#net1}
+N 870 -570 870 -500 {
+lab=#net1}
+N 870 -570 1000 -570 {
+lab=#net1}
+N 820 -460 870 -460 {
+lab=#net2}
+N 870 -460 870 -410 {
+lab=#net2}
+N 870 -410 1000 -410 {
+lab=#net2}
+N 690 -730 690 -560 {
+lab=iovdd}
+N 950 -730 1120 -730 {
+lab=iovdd}
+N 1120 -730 1120 -630 {
+lab=iovdd}
+N 950 -470 1120 -470 {
+lab=iovdd}
+N 950 -730 950 -470 {
+lab=iovdd}
+N 690 -730 950 -730 {
+lab=iovdd}
+N 910 -510 1120 -510 {
+lab=iovss}
+N 910 -510 910 -280 {
+lab=iovss}
+N 910 -280 1120 -280 {
+lab=iovss}
+N 1120 -350 1120 -280 {
+lab=iovss}
+N 1410 -410 1410 -280 {
+lab=iovss}
+N 1290 -280 1410 -280 {
+lab=iovss}
+N 1300 -570 1350 -570 {
+lab=xxx}
+N 1350 -510 1350 -410 {
+lab=xxx}
+N 1300 -410 1350 -410 {
+lab=xxx}
+N 1710 -490 1710 -430 {
+lab=xxx}
+N 1460 -510 1710 -510 {
+lab=xxx}
+N 1350 -570 1350 -510 {
+lab=xxx}
+N 1710 -390 1790 -390 {
+lab=iovdd}
+N 1790 -530 1790 -390 {
+lab=iovdd}
+N 1390 -530 1790 -530 {
+lab=iovdd}
+N 1390 -730 1390 -530 {
+lab=iovdd}
+N 1260 -730 1390 -730 {
+lab=iovdd}
+N 1460 -650 1460 -510 {
+lab=xxx}
+N 1350 -510 1460 -510 {
+lab=xxx}
+N 1760 -730 1760 -670 {
+lab=iovdd}
+N 1390 -730 1760 -730 {
+lab=iovdd}
+N 1760 -630 1820 -630 {
+lab=iovss}
+N 1820 -630 1820 -280 {
+lab=iovss}
+N 1410 -280 1820 -280 {
+lab=iovss}
+N 670 -400 670 -290 {
+lab=vss}
+N 640 -640 640 -560 {
+lab=vdd}
+N 450 -480 520 -480 {
+lab=c2p}
+N 1290 -280 1290 -250 {
+lab=iovss}
+N 1120 -280 1290 -280 {
+lab=iovss}
+N 1260 -780 1260 -730 {
+lab=iovdd}
+N 1120 -730 1260 -730 {
+lab=iovdd}
+N 1710 -490 1730 -490 {
+lab=xxx}
+N 1710 -510 1710 -490 {
+lab=xxx}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N2N2D.sym} 1150 -570 0 0 {name=x1}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P2N2D.sym} 1150 -410 0 0 {name=x2}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCNDiode.sym} 1610 -650 0 0 {name=x3}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCPDiode.sym} 1560 -410 0 0 {name=x4}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_GateLevelUpInv.sym} 670 -480 0 0 {name=x5}
+C {devices/iopin.sym} 640 -640 3 0 {name=vdd lab=vdd}
+C {devices/iopin.sym} 670 -290 1 0 {name=vss lab=vss}
+C {devices/iopin.sym} 1290 -250 1 0 {name=iovss lab=iovss}
+C {devices/iopin.sym} 1260 -780 3 0 {name=iovdd lab=iovdd}
+C {devices/iopin.sym} 450 -480 2 0 {name=c2p lab=c2p}
+C {devices/iopin.sym} 1730 -490 0 0 {name=pad lab=pad}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadOut4mA.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadOut4mA.sym
new file mode 100644
index 00000000..b82b05f4
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadOut4mA.sym
@@ -0,0 +1,34 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -60 130 -60 {}
+L 4 -130 60 130 60 {}
+L 4 -130 -60 -130 60 {}
+L 4 130 -60 130 60 {}
+L 7 30 -80 30 -60 {}
+L 7 -30 -80 -30 -60 {}
+L 7 130 0 150 0 {}
+L 7 -150 0 -130 0 {}
+L 7 -30 60 -30 80 {}
+L 7 30 60 30 80 {}
+B 5 27.5 -82.5 32.5 -77.5 {name=iovdd dir=inout}
+B 5 -32.5 -82.5 -27.5 -77.5 {name=vdd dir=inout}
+B 5 147.5 -2.5 152.5 2.5 {name=pad dir=inout}
+B 5 -152.5 -2.5 -147.5 2.5 {name=c2p dir=inout}
+B 5 -32.5 77.5 -27.5 82.5 {name=vss dir=inout}
+B 5 27.5 77.5 32.5 82.5 {name=iovss dir=inout}
+T {sg13g2_IOPadOut4mA} -59 -6 0 0 0.2 0.2 {}
+T {@name} 135 -72 0 0 0.2 0.2 {}
+T {iovdd} 65 -74 0 1 0.2 0.2 {}
+T {vdd} -35 -74 0 1 0.2 0.2 {}
+T {pad} 125 -4 0 1 0.2 0.2 {}
+T {c2p} -135 -24 0 1 0.2 0.2 {}
+T {vss} -45 66 0 1 0.2 0.2 {}
+T {iovss} 65 66 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadTriOut16mA.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadTriOut16mA.sch
new file mode 100644
index 00000000..712e1006
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadTriOut16mA.sch
@@ -0,0 +1,93 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 1810 -120 1880 -120 {
+lab=pad}
+N 1810 100 1880 100 {
+lab=pad}
+N 1950 -60 2080 -60 {
+lab=iovss}
+N 2380 -120 2380 -80 {
+lab=pad}
+N 1880 -140 2380 -140 {
+lab=pad}
+N 1880 -120 1880 100 {
+lab=pad}
+N 1880 -140 1880 -120 {
+lab=pad}
+N 2380 -40 2380 10 {
+lab=iovdd}
+N 1880 100 2060 100 {
+lab=pad}
+N 2360 80 2380 80 {
+lab=iovdd}
+N 2380 10 2380 80 {
+lab=iovdd}
+N 2040 180 2360 180 {
+lab=iovss}
+N 2360 120 2360 180 {
+lab=iovss}
+N 1430 0 1430 100 {
+lab=#net1}
+N 1430 100 1510 100 {
+lab=#net1}
+N 1430 -120 1430 -40 {
+lab=#net2}
+N 1430 -120 1510 -120 {
+lab=#net2}
+N 1260 50 1260 140 {
+lab=vss}
+N 1260 -180 1260 -90 {
+lab=vdd}
+N 1480 -200 1480 10 {
+lab=iovdd}
+N 1300 -200 1480 -200 {
+lab=iovdd}
+N 1030 0 1130 0 {
+lab=c2p}
+N 1540 -260 1540 -200 {
+lab=iovdd}
+N 1480 -200 1540 -200 {
+lab=iovdd}
+N 1950 -60 1950 180 {
+lab=iovss}
+N 2040 180 2040 240 {
+lab=iovss}
+N 1950 180 2040 180 {
+lab=iovss}
+N 2380 -120 2470 -120 {
+lab=pad}
+N 2380 -140 2380 -120 {
+lab=pad}
+N 1540 -200 1660 -200 {
+lab=iovdd}
+N 1660 10 2380 10 {
+lab=iovdd}
+N 1660 180 1950 180 {
+lab=iovss}
+N 1040 -40 1130 -40 {
+lab=c2p_en}
+N 1300 -200 1300 -90 {
+lab=iovdd}
+N 1660 160 1660 180 {}
+N 1660 10 1660 40 {}
+N 1480 10 1660 10 {
+lab=iovdd}
+N 1660 -60 1950 -60 {}
+N 1660 -200 1660 -180 {}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCNDiode.sym} 2230 -60 0 0 {name=x8}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCPDiode.sym} 2210 100 0 0 {name=x9}
+C {devices/iopin.sym} 2040 240 1 0 {name=iovss lab=iovss}
+C {devices/iopin.sym} 2470 -120 0 0 {name=pad lab=pad}
+C {devices/iopin.sym} 1260 140 1 0 {name=vss lab=vss}
+C {devices/iopin.sym} 1030 0 2 0 {name=c2p lab=c2p}
+C {devices/iopin.sym} 1260 -180 3 0 {name=vdd lab=vdd}
+C {devices/iopin.sym} 1540 -260 3 0 {name=iovdd lab=iovdd}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_GateDecode.sym} 1280 -20 0 0 {name=x1}
+C {devices/iopin.sym} 1040 -40 2 0 {name=c2p_en lab=c2p_en}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N8N8D.sym} 1660 -120 0 0 {name=x2}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P8N8D.sym} 1660 100 0 0 {name=x3}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadTriOut16mA.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadTriOut16mA.sym
new file mode 100644
index 00000000..07b782f3
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadTriOut16mA.sym
@@ -0,0 +1,37 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -70 130 -70 {}
+L 4 -130 70 130 70 {}
+L 4 -130 -70 -130 70 {}
+L 4 130 -70 130 70 {}
+L 7 30 -90 30 -70 {}
+L 7 -30 -90 -30 -70 {}
+L 7 130 0 150 0 {}
+L 7 -150 -20 -130 -20 {}
+L 7 -150 20 -130 20 {}
+L 7 -30 70 -30 90 {}
+L 7 30 70 30 90 {}
+B 5 27.5 -92.5 32.5 -87.5 {name=iovdd dir=inout}
+B 5 -32.5 -92.5 -27.5 -87.5 {name=vdd dir=inout}
+B 5 147.5 -2.5 152.5 2.5 {name=pad dir=inout}
+B 5 -152.5 -22.5 -147.5 -17.5 {name=c2p_en dir=inout}
+B 5 -152.5 17.5 -147.5 22.5 {name=c2p dir=inout}
+B 5 -32.5 87.5 -27.5 92.5 {name=vss dir=inout}
+B 5 27.5 87.5 32.5 92.5 {name=iovss dir=inout}
+T {sg13g2_IOPadTriOut16mA} -67 -6 0 0 0.2 0.2 {}
+T {@name} 135 -82 0 0 0.2 0.2 {}
+T {iovdd} 45 -64 0 1 0.2 0.2 {}
+T {vdd} -25 -64 0 1 0.2 0.2 {}
+T {pad} 125 -4 0 1 0.2 0.2 {}
+T {c2p_en} -85 -24 0 1 0.2 0.2 {}
+T {c2p} -105 16 0 1 0.2 0.2 {}
+T {vss} -25 56 0 1 0.2 0.2 {}
+T {iovss} 45 56 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadTriOut30mA.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadTriOut30mA.sch
new file mode 100644
index 00000000..f9a83f9f
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadTriOut30mA.sch
@@ -0,0 +1,97 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 1620 -190 1690 -190 {
+lab=pad}
+N 1620 30 1690 30 {
+lab=pad}
+N 1760 -130 1890 -130 {
+lab=iovss}
+N 2190 -190 2190 -150 {
+lab=pad}
+N 1690 -210 2190 -210 {
+lab=pad}
+N 1690 -190 1690 30 {
+lab=pad}
+N 1690 -210 1690 -190 {
+lab=pad}
+N 2190 -110 2190 -60 {
+lab=iovdd}
+N 1690 30 1870 30 {
+lab=pad}
+N 2170 10 2190 10 {
+lab=iovdd}
+N 2190 -60 2190 10 {
+lab=iovdd}
+N 1850 110 2170 110 {
+lab=iovss}
+N 2170 50 2170 110 {
+lab=iovss}
+N 1240 -70 1240 30 {
+lab=#net1}
+N 1240 30 1320 30 {
+lab=#net1}
+N 1240 -190 1240 -110 {
+lab=#net2}
+N 1240 -190 1320 -190 {
+lab=#net2}
+N 1070 -20 1070 70 {
+lab=vss}
+N 1070 -250 1070 -160 {
+lab=vdd}
+N 1290 -270 1290 -60 {
+lab=iovdd}
+N 1110 -270 1290 -270 {
+lab=iovdd}
+N 840 -70 940 -70 {
+lab=c2p}
+N 1350 -330 1350 -270 {
+lab=iovdd}
+N 1290 -270 1350 -270 {
+lab=iovdd}
+N 1760 -130 1760 110 {
+lab=iovss}
+N 1850 110 1850 170 {
+lab=iovss}
+N 1760 110 1850 110 {
+lab=iovss}
+N 2190 -190 2280 -190 {
+lab=pad}
+N 2190 -210 2190 -190 {
+lab=pad}
+N 1350 -270 1470 -270 {
+lab=iovdd}
+N 1470 -60 2190 -60 {
+lab=iovdd}
+N 1470 110 1760 110 {
+lab=iovss}
+N 850 -110 940 -110 {
+lab=c2p_en}
+N 1110 -270 1110 -160 {
+lab=iovdd}
+N 1470 90 1470 110 {
+lab=iovss}
+N 1470 -60 1470 -30 {
+lab=iovdd}
+N 1290 -60 1470 -60 {
+lab=iovdd}
+N 1470 -130 1760 -130 {
+lab=iovss}
+N 1470 -270 1470 -250 {
+lab=iovdd}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCNDiode.sym} 2040 -130 0 0 {name=x8}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCPDiode.sym} 2020 30 0 0 {name=x9}
+C {devices/iopin.sym} 1850 170 1 0 {name=iovss lab=iovss}
+C {devices/iopin.sym} 2280 -190 0 0 {name=pad lab=pad}
+C {devices/iopin.sym} 1070 70 1 0 {name=vss lab=vss}
+C {devices/iopin.sym} 840 -70 2 0 {name=c2p lab=c2p}
+C {devices/iopin.sym} 1070 -250 3 0 {name=vdd lab=vdd}
+C {devices/iopin.sym} 1350 -330 3 0 {name=iovdd lab=iovdd}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_GateDecode.sym} 1090 -90 0 0 {name=x1}
+C {devices/iopin.sym} 850 -110 2 0 {name=c2p_en lab=c2p_en}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N15N15D.sym} 1470 -190 0 0 {name=x2}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P15N15D.sym} 1470 30 0 0 {name=x3}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadTriOut30mA.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadTriOut30mA.sym
new file mode 100644
index 00000000..1efa2d8e
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadTriOut30mA.sym
@@ -0,0 +1,37 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -70 130 -70 {}
+L 4 -130 70 130 70 {}
+L 4 -130 -70 -130 70 {}
+L 4 130 -70 130 70 {}
+L 7 30 -90 30 -70 {}
+L 7 -30 -90 -30 -70 {}
+L 7 130 0 150 0 {}
+L 7 -150 -20 -130 -20 {}
+L 7 -150 20 -130 20 {}
+L 7 -30 70 -30 90 {}
+L 7 30 70 30 90 {}
+B 5 27.5 -92.5 32.5 -87.5 {name=iovdd dir=inout}
+B 5 -32.5 -92.5 -27.5 -87.5 {name=vdd dir=inout}
+B 5 147.5 -2.5 152.5 2.5 {name=pad dir=inout}
+B 5 -152.5 -22.5 -147.5 -17.5 {name=c2p_en dir=inout}
+B 5 -152.5 17.5 -147.5 22.5 {name=c2p dir=inout}
+B 5 -32.5 87.5 -27.5 92.5 {name=vss dir=inout}
+B 5 27.5 87.5 32.5 92.5 {name=iovss dir=inout}
+T {sg13g2_IOPadTriOut30mA} -57 -6 0 0 0.2 0.2 {}
+T {@name} 135 -82 0 0 0.2 0.2 {}
+T {iovdd} 45 -64 0 1 0.2 0.2 {}
+T {vdd} -25 -64 0 1 0.2 0.2 {}
+T {pad} 125 -4 0 1 0.2 0.2 {}
+T {c2p_en} -85 -24 0 1 0.2 0.2 {}
+T {c2p} -105 16 0 1 0.2 0.2 {}
+T {vss} -25 56 0 1 0.2 0.2 {}
+T {iovss} 45 56 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadTriOut4mA.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadTriOut4mA.sch
new file mode 100644
index 00000000..4ba3fdf2
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadTriOut4mA.sch
@@ -0,0 +1,97 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 1630 -170 1700 -170 {
+lab=pad}
+N 1630 50 1700 50 {
+lab=pad}
+N 1770 -110 1900 -110 {
+lab=iovss}
+N 2200 -170 2200 -130 {
+lab=pad}
+N 1700 -190 2200 -190 {
+lab=pad}
+N 1700 -170 1700 50 {
+lab=pad}
+N 1700 -190 1700 -170 {
+lab=pad}
+N 2200 -90 2200 -40 {
+lab=iovdd}
+N 1700 50 1880 50 {
+lab=pad}
+N 2180 30 2200 30 {
+lab=iovdd}
+N 2200 -40 2200 30 {
+lab=iovdd}
+N 1860 130 2180 130 {
+lab=iovss}
+N 2180 70 2180 130 {
+lab=iovss}
+N 1250 -50 1250 50 {
+lab=#net1}
+N 1250 50 1330 50 {
+lab=#net1}
+N 1250 -170 1250 -90 {
+lab=#net2}
+N 1250 -170 1330 -170 {
+lab=#net2}
+N 1080 0 1080 90 {
+lab=vss}
+N 1080 -230 1080 -140 {
+lab=vdd}
+N 1450 -40 2200 -40 {
+lab=iovdd}
+N 1300 -250 1300 -40 {
+lab=iovdd}
+N 1120 -250 1300 -250 {
+lab=iovdd}
+N 850 -50 950 -50 {
+lab=c2p}
+N 1360 -310 1360 -250 {
+lab=iovdd}
+N 1300 -250 1360 -250 {
+lab=iovdd}
+N 1770 -110 1770 130 {
+lab=iovss}
+N 1860 130 1860 190 {
+lab=iovss}
+N 1770 130 1860 130 {
+lab=iovss}
+N 2200 -170 2290 -170 {
+lab=pad}
+N 2200 -190 2200 -170 {
+lab=pad}
+N 1450 -110 1770 -110 {
+lab=iovss}
+N 1450 -250 1450 -230 {
+lab=iovdd}
+N 1360 -250 1450 -250 {
+lab=iovdd}
+N 1450 -40 1450 -10 {
+lab=iovdd}
+N 1300 -40 1450 -40 {
+lab=iovdd}
+N 1450 110 1450 130 {
+lab=iovss}
+N 1450 130 1770 130 {
+lab=iovss}
+N 860 -90 950 -90 {
+lab=c2p_en}
+N 1120 -250 1120 -140 {
+lab=iovdd}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCNDiode.sym} 2050 -110 0 0 {name=x8}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCPDiode.sym} 2030 50 0 0 {name=x9}
+C {devices/iopin.sym} 1860 190 1 0 {name=iovss lab=iovss}
+C {devices/iopin.sym} 2290 -170 0 0 {name=pad lab=pad}
+C {devices/iopin.sym} 1080 90 1 0 {name=vss lab=vss}
+C {devices/iopin.sym} 850 -50 2 0 {name=c2p lab=c2p}
+C {devices/iopin.sym} 1080 -230 3 0 {name=vdd lab=vdd}
+C {devices/iopin.sym} 1360 -310 3 0 {name=iovdd lab=iovdd}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N2N2D.sym} 1480 -170 0 0 {name=x4}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_P2N2D.sym} 1480 50 0 0 {name=x5}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_GateDecode.sym} 1100 -70 0 0 {name=x1}
+C {devices/iopin.sym} 860 -90 2 0 {name=c2p_en lab=c2p_en}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadTriOut4mA.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadTriOut4mA.sym
new file mode 100644
index 00000000..9f7c6b82
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadTriOut4mA.sym
@@ -0,0 +1,37 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -70 130 -70 {}
+L 4 -130 70 130 70 {}
+L 4 -130 -70 -130 70 {}
+L 4 130 -70 130 70 {}
+L 7 30 -90 30 -70 {}
+L 7 -30 -90 -30 -70 {}
+L 7 130 0 150 0 {}
+L 7 -150 -20 -130 -20 {}
+L 7 -150 20 -130 20 {}
+L 7 -30 70 -30 90 {}
+L 7 30 70 30 90 {}
+B 5 27.5 -92.5 32.5 -87.5 {name=iovdd dir=inout}
+B 5 -32.5 -92.5 -27.5 -87.5 {name=vdd dir=inout}
+B 5 147.5 -2.5 152.5 2.5 {name=pad dir=inout}
+B 5 -152.5 -22.5 -147.5 -17.5 {name=c2p_en dir=inout}
+B 5 -152.5 17.5 -147.5 22.5 {name=c2p dir=inout}
+B 5 -32.5 87.5 -27.5 92.5 {name=vss dir=inout}
+B 5 27.5 87.5 32.5 92.5 {name=iovss dir=inout}
+T {sg13g2_IOPadTriOut4mA} -52.5 -6 0 0 0.2 0.2 {}
+T {@name} 135 -82 0 0 0.2 0.2 {}
+T {iovdd} 45 -64 0 1 0.2 0.2 {}
+T {vdd} -15 -64 0 1 0.2 0.2 {}
+T {pad} 125 -4 0 1 0.2 0.2 {}
+T {c2p_en} -85 -24 0 1 0.2 0.2 {}
+T {c2p} -105 16 0 1 0.2 0.2 {}
+T {vss} -25 56 0 1 0.2 0.2 {}
+T {iovss} 45 56 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadVSS.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadVSS.sch
new file mode 100644
index 00000000..f860ee6c
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadVSS.sch
@@ -0,0 +1,43 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 10 30 50 30 {
+lab=vss}
+N 50 -10 360 -10 {
+lab=iovdd}
+N 360 -10 360 10 {
+lab=iovdd}
+N 350 10 360 10 {
+lab=iovdd}
+N 350 50 430 50 {
+lab=iovss}
+N -350 10 -320 10 {
+lab=iovss}
+N 50 -60 50 -10 {
+lab=iovdd}
+N -20 -10 50 -10 {
+lab=iovdd}
+N 10 30 10 90 {
+lab=vss}
+N -20 30 10 30 {
+lab=vss}
+N 430 50 430 160 {
+lab=iovss}
+N -350 160 430 160 {
+lab=iovss}
+N -350 10 -350 160 {
+lab=iovss}
+N -400 10 -350 10 {
+lab=iovss}
+N 150 -120 240 -120 {
+lab=xxx}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCNDiode.sym} -170 10 2 1 {name=x1}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_DCPDiode.sym} 200 30 0 0 {name=x2}
+C {devices/iopin.sym} -400 10 0 0 {name=iovss lab=iovss}
+C {devices/iopin.sym} 50 -60 0 0 {name=iovdd lab=iovdd}
+C {devices/iopin.sym} 10 90 0 0 {name=vss lab=vss}
+C {devices/iopin.sym} 240 -120 0 0 {name=vdd lab=vdd}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadVSS.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadVSS.sym
new file mode 100644
index 00000000..0f604f5a
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadVSS.sym
@@ -0,0 +1,28 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -40 130 -40 {}
+L 4 -130 40 130 40 {}
+L 4 -130 -40 -130 40 {}
+L 4 130 -40 130 40 {}
+L 7 -20 -60 -20 -40 {}
+L 7 20 -60 20 -40 {}
+L 7 20 40 20 60 {}
+L 7 -20 40 -20 60 {}
+B 5 -22.5 -62.5 -17.5 -57.5 {name=vdd dir=inout}
+B 5 17.5 -62.5 22.5 -57.5 {name=iovdd dir=inout}
+B 5 17.5 57.5 22.5 62.5 {name=iovss dir=inout}
+B 5 -22.5 57.5 -17.5 62.5 {name=vss dir=inout}
+T {sg13g2_IOPadVSS} -45.5 -6 0 0 0.2 0.2 {}
+T {@name} 135 -52 0 0 0.2 0.2 {}
+T {vdd} -15 -34 0 1 0.2 0.2 {}
+T {iovdd} 35 -34 0 1 0.2 0.2 {}
+T {iovss} 35 26 0 1 0.2 0.2 {}
+T {vss} -15 26 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadVdd.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadVdd.sch
new file mode 100644
index 00000000..0063359b
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadVdd.sch
@@ -0,0 +1,46 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 70 -160 70 -60 {
+lab=vdd}
+N 680 -190 680 -100 {
+lab=iovdd}
+N 680 20 680 80 {
+lab=iovss}
+N 430 -40 520 -40 {
+lab=#net1}
+N 70 -40 130 -40 {
+lab=#net2}
+N 280 -90 320 -90 {
+lab=vdd}
+N 320 -160 320 -90 {
+lab=vdd}
+N 300 -160 320 -160 {
+lab=vdd}
+N 820 -250 820 -40 {
+lab=vdd}
+N 520 -250 820 -250 {
+lab=vdd}
+N 300 -250 300 -160 {
+lab=vdd}
+N 70 -160 300 -160 {
+lab=vdd}
+N 280 10 320 10 {
+lab=vss}
+N 320 10 320 60 {
+lab=vss}
+N 520 -290 520 -250 {
+lab=vdd}
+N 300 -250 520 -250 {
+lab=vdd}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_Clamp_N43N43D4R.sym} 670 -40 0 0 {}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_RCClampResistor.sym} -80 -50 0 0 {name=x6}
+C {devices/iopin.sym} 520 -290 0 0 {name=vdd lab=vdd}
+C {devices/iopin.sym} 680 -190 0 0 {name=iovdd lab=iovdd}
+C {devices/iopin.sym} 320 60 0 0 {name=vss lab=vss}
+C {devices/iopin.sym} 680 80 0 0 {name=iovss lab=iovss}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_RCClampInverter.sym} 280 -40 0 0 {name=x1}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadVdd.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadVdd.sym
new file mode 100644
index 00000000..0f9cf86a
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_IOPadVdd.sym
@@ -0,0 +1,28 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -40 130 -40 {}
+L 4 -130 40 130 40 {}
+L 4 -130 -40 -130 40 {}
+L 4 130 -40 130 40 {}
+L 7 -30 -60 -30 -40 {}
+L 7 30 -60 30 -40 {}
+L 7 -30 40 -30 60 {}
+L 7 30 40 30 60 {}
+B 5 -32.5 -62.5 -27.5 -57.5 {name=vdd dir=inout}
+B 5 27.5 -62.5 32.5 -57.5 {name=iovdd dir=inout}
+B 5 -32.5 57.5 -27.5 62.5 {name=vss dir=inout}
+B 5 27.5 57.5 32.5 62.5 {name=iovss dir=inout}
+T {sg13g2_IOPadVdd} -55.5 -6 0 0 0.2 0.2 {}
+T {@name} 135 -52 0 0 0.2 0.2 {}
+T {vdd} -25 -34 0 1 0.2 0.2 {}
+T {iovdd} 45 -34 0 1 0.2 0.2 {}
+T {vss} -25 26 0 1 0.2 0.2 {}
+T {iovss} 45 26 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelDown.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelDown.sch
new file mode 100644
index 00000000..2937be54
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelDown.sch
@@ -0,0 +1,115 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 110 -60 130 -60 {
+lab=#net1}
+N 110 10 110 50 {
+lab=#net1}
+N -0 10 110 10 {
+lab=#net1}
+N -0 -30 -0 10 {
+lab=#net1}
+N 110 -60 110 10 {
+lab=#net1}
+N -60 -60 -40 -60 {
+lab=#net2}
+N -60 -10 -60 60 {
+lab=#net2}
+N 80 110 170 110 {
+lab=vss}
+N -0 -110 -0 -90 {
+lab=vdd}
+N 80 -110 170 -110 {
+lab=vdd}
+N 170 -110 170 -90 {
+lab=vdd}
+N 80 -140 80 -110 {
+lab=vdd}
+N 30 -110 80 -110 {
+lab=vdd}
+N 80 110 80 140 {
+lab=vss}
+N 30 110 80 110 {
+lab=vss}
+N -130 -10 -60 -10 {
+lab=#net2}
+N -60 -60 -60 -10 {
+lab=#net2}
+N -490 -20 -430 -20 {
+lab=pad}
+N -270 40 -270 80 {
+lab=iovss}
+N -270 -130 -270 -80 {
+lab=iovdd}
+N -490 -20 -490 40 {
+lab=pad}
+N 170 -0 270 0 {
+lab=core}
+N 170 -30 170 -0 {
+lab=core}
+N 170 80 170 110 {
+lab=vss}
+N 170 -0 170 20 {
+lab=core}
+N 110 50 130 50 {
+lab=#net1}
+N 0 90 0 110 {}
+N 0 10 -0 30 {}
+N -60 60 -40 60 {}
+N -0 60 30 60 {}
+N 30 60 30 110 {}
+N 0 110 30 110 {
+lab=vss}
+N 170 50 200 50 {}
+N 200 50 200 110 {}
+N 170 110 200 110 {}
+N -0 -60 30 -60 {}
+N 30 -110 30 -60 {}
+N -0 -110 30 -110 {
+lab=vdd}
+N 170 -60 200 -60 {}
+N 200 -110 200 -60 {}
+N 170 -110 200 -110 {}
+C {sg13g2_pr/sg13_hv_nmos.sym} -20 60 2 1 {name=M1
+l=0.45u
+w=2.65u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} -20 -60 0 0 {name=M2
+l=0.45u
+w=4.65u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_lv_nmos.sym} 150 50 2 1 {name=M3
+l=0.13u
+w=2.75u
+ng=1
+m=1
+model=sg13_lv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_lv_pmos.sym} 150 -60 0 0 {name=M4
+l=0.13u
+w=4.75u
+ng=1
+m=1
+model=sg13_lv_pmos
+spiceprefix=X
+}
+C {/home/prabhat.dubey/OPEN_Source_IHP_PDK/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_SecondaryProtection.sym} -280 -20 0 0 {}
+C {devices/iopin.sym} 80 -140 0 0 {name=vdd lab=vdd}
+C {devices/iopin.sym} 80 140 0 0 {name=vss lab=vss}
+C {devices/iopin.sym} -270 -130 0 0 {name=iovdd lab=iovdd}
+C {devices/iopin.sym} -270 80 0 0 {name=iovss lab=iovss}
+C {devices/iopin.sym} -490 40 0 0 {name=pad lab=pad}
+C {devices/iopin.sym} 270 0 0 0 {name=core lab=core}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelDown.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelDown.sym
new file mode 100644
index 00000000..4c54a946
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelDown.sym
@@ -0,0 +1,34 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -60 130 -60 {}
+L 4 -130 60 130 60 {}
+L 4 -130 -60 -130 60 {}
+L 4 130 -60 130 60 {}
+L 7 -40 -80 -40 -60 {}
+L 7 40 -80 40 -60 {}
+L 7 -150 0 -130 0 {}
+L 7 130 0 150 0 {}
+L 7 40 60 40 80 {}
+L 7 -40 60 -40 80 {}
+B 5 -42.5 -82.5 -37.5 -77.5 {name=vdd dir=inout}
+B 5 37.5 -82.5 42.5 -77.5 {name=iovdd dir=inout}
+B 5 -152.5 -2.5 -147.5 2.5 {name=core dir=inout}
+B 5 147.5 -2.5 152.5 2.5 {name=pad dir=inout}
+B 5 37.5 77.5 42.5 82.5 {name=iovss dir=inout}
+B 5 -42.5 77.5 -37.5 82.5 {name=vss dir=inout}
+T {sg13g2_LevelDown} -50 -6 0 0 0.2 0.2 {}
+T {@name} 135 -72 0 0 0.2 0.2 {}
+T {vdd} -15 -74 0 1 0.2 0.2 {}
+T {iovdd} 75 -74 0 1 0.2 0.2 {}
+T {core} -135 -24 0 1 0.2 0.2 {}
+T {pad} 155 -24 0 1 0.2 0.2 {}
+T {iovss} 75 66 0 1 0.2 0.2 {}
+T {vss} -45 66 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelUp.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelUp.sch
new file mode 100644
index 00000000..ebd32ca8
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelUp.sch
@@ -0,0 +1,213 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N -90 -10 -90 10 {
+lab=i_n}
+N -160 -60 -130 -60 {
+lab=i}
+N -160 -10 -160 40 {
+lab=i}
+N -160 40 -130 40 {
+lab=i}
+N -200 -10 -160 -10 {
+lab=i}
+N -160 -60 -160 -10 {
+lab=i}
+N -90 -120 -90 -90 {
+lab=vdd}
+N -90 70 -90 110 {
+lab=vss}
+N 70 -10 70 20 {
+lab=lvld}
+N 220 -0 220 20 {
+lab=#net1}
+N 390 -10 390 20 {
+lab=o}
+N -90 -10 -0 -10 {
+lab=i_n}
+N -90 -30 -90 -10 {
+lab=i_n}
+N -0 -10 0 50 {
+lab=i_n}
+N 0 50 30 50 {
+lab=i_n}
+N 260 110 390 110 {
+lab=vss}
+N 390 80 390 110 {
+lab=vss}
+N 70 80 70 110 {
+lab=vss}
+N -90 110 70 110 {
+lab=vss}
+N 220 80 220 110 {
+lab=vss}
+N 180 110 220 110 {
+lab=vss}
+N 70 50 110 50 {
+lab=vss}
+N 110 50 110 110 {
+lab=vss}
+N 70 110 110 110 {
+lab=vss}
+N 220 50 260 50 {
+lab=vss}
+N 260 50 260 110 {
+lab=vss}
+N 220 110 260 110 {
+lab=vss}
+N 390 50 430 50 {
+lab=vss}
+N 430 50 430 110 {
+lab=vss}
+N 390 110 430 110 {
+lab=vss}
+N 70 -140 70 -110 {
+lab=iovdd}
+N 250 -140 390 -140 {
+lab=iovdd}
+N 390 -140 390 -100 {
+lab=iovdd}
+N 220 -140 220 -110 {
+lab=iovdd}
+N 180 -140 220 -140 {
+lab=iovdd}
+N 70 -80 110 -80 {
+lab=iovdd}
+N 110 -140 110 -80 {
+lab=iovdd}
+N 70 -140 110 -140 {
+lab=iovdd}
+N 220 -80 250 -80 {
+lab=iovdd}
+N 250 -140 250 -80 {
+lab=iovdd}
+N 220 -140 250 -140 {
+lab=iovdd}
+N 390 -70 430 -70 {
+lab=iovdd}
+N 430 -140 430 -70 {
+lab=iovdd}
+N 390 -140 430 -140 {
+lab=iovdd}
+N 320 -70 350 -70 {
+lab=#net1}
+N 320 0 320 50 {
+lab=#net1}
+N 320 50 350 50 {
+lab=#net1}
+N 220 -0 320 0 {
+lab=#net1}
+N 220 -30 220 -0 {
+lab=#net1}
+N 320 -70 320 0 {
+lab=#net1}
+N 10 -80 30 -80 {
+lab=#net1}
+N 10 -80 10 -30 {
+lab=#net1}
+N 10 -30 220 -30 {
+lab=#net1}
+N 220 -50 220 -30 {
+lab=#net1}
+N 70 -10 150 -10 {
+lab=lvld}
+N 70 -50 70 -10 {
+lab=lvld}
+N 150 -80 150 -10 {
+lab=lvld}
+N 150 -80 180 -80 {
+lab=lvld}
+N 390 -10 470 -10 {
+lab=o}
+N 390 -40 390 -10 {
+lab=o}
+N 180 110 180 150 {
+lab=vss}
+N 110 110 180 110 {
+lab=vss}
+N 180 -180 180 -140 {
+lab=iovdd}
+N 110 -140 180 -140 {
+lab=iovdd}
+N -160 40 -160 100 {
+lab=i}
+N -160 100 180 100 {
+lab=i}
+N 180 50 180 100 {
+lab=i}
+C {sg13g2_pr/sg13_lv_nmos.sym} -110 40 2 1 {name=M1
+l=0.13u
+w=2.75u
+ng=1
+m=1
+model=sg13_lv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_lv_pmos.sym} -110 -60 0 0 {name=M2
+l=0.13u
+w=4.75u
+ng=1
+m=1
+model=sg13_lv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 50 50 0 0 {name=M3
+l=0.45u
+w=1.9u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 200 50 0 0 {name=M4
+l=0.45u
+w=1.9u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 370 50 0 0 {name=M5
+l=0.45u
+w=1.9u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 50 -80 0 0 {name=M6
+l=0.45u
+w=0.3u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 200 -80 0 0 {name=M7
+l=0.45u
+w=0.3u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 370 -70 0 0 {name=M8
+l=0.45u
+w=3.9u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {devices/iopin.sym} 180 150 0 0 {name=vss lab=vss}
+C {devices/iopin.sym} 180 -180 0 0 {name=iovdd lab=iovdd}
+C {devices/iopin.sym} -90 -120 0 0 {name=vdd lab=vdd}
+C {devices/ipin.sym} -200 -10 0 0 {name=i lab=i}
+C {devices/opin.sym} 470 -10 0 0 {name=o lab=o}
+C {devices/lab_pin.sym} -50 -10 0 0 {name=p1 sig_type=std_logic lab=i_n}
+C {devices/lab_pin.sym} 100 -10 0 0 {name=p2 sig_type=std_logic lab=lvld}
+C {devices/lab_pin.sym} 220 -20 0 0 {name=p3 sig_type=std_logic lab=lvld_n}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelUp.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelUp.sym
new file mode 100644
index 00000000..0ee47ed3
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelUp.sym
@@ -0,0 +1,31 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -40 130 -40 {}
+L 4 -130 40 130 40 {}
+L 4 -130 -40 -130 40 {}
+L 4 130 -40 130 40 {}
+L 4 -150 0 -130 0 {}
+L 4 130 0 150 0 {}
+L 7 50 -60 50 -40 {}
+L 7 -10 -60 -10 -40 {}
+L 7 -10 40 -10 60 {}
+B 5 47.5 -62.5 52.5 -57.5 {name=iovdd dir=inout}
+B 5 -12.5 -62.5 -7.5 -57.5 {name=vdd dir=inout}
+B 5 -152.5 -2.5 -147.5 2.5 {name=i dir=in}
+B 5 147.5 -2.5 152.5 2.5 {name=o dir=out}
+B 5 -12.5 57.5 -7.5 62.5 {name=vss dir=inout}
+T {sg13g2_io_inv_x1} -81 -6 0 0 0.3 0.3 {}
+T {@name} 135 -52 0 0 0.2 0.2 {}
+T {iovdd} 45 -54 0 1 0.2 0.2 {}
+T {vdd} -15 -54 0 1 0.2 0.2 {}
+T {i} -145 -14 0 0 0.2 0.2 {}
+T {o} 145 -14 0 1 0.2 0.2 {}
+T {vss} -15 46 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelUpInv.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelUpInv.sch
new file mode 100644
index 00000000..c8a8d363
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelUpInv.sch
@@ -0,0 +1,228 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+T {i_n} 970 -410 0 0 0.2 0.2 {}
+T {lvld_n} 1080 -390 0 0 0.2 0.2 {}
+T {lvld} 1230 -380 0 0 0.2 0.2 {}
+N 870 -520 870 -480 {
+lab=vdd}
+N 870 -450 910 -450 {
+lab=vdd}
+N 910 -520 910 -450 {
+lab=vdd}
+N 870 -520 910 -520 {
+lab=vdd}
+N 870 -570 870 -520 {
+lab=vdd}
+N 870 -250 870 -220 {
+lab=vss}
+N 870 -340 910 -340 {
+lab=vss}
+N 910 -340 910 -270 {
+lab=vss}
+N 870 -270 910 -270 {
+lab=vss}
+N 870 -310 870 -270 {
+lab=vss}
+N 870 -390 870 -370 {
+lab=#net1}
+N 780 -450 830 -450 {
+lab=i}
+N 780 -400 780 -340 {
+lab=i}
+N 780 -340 830 -340 {
+lab=i}
+N 720 -400 780 -400 {
+lab=i}
+N 780 -450 780 -400 {
+lab=i}
+N 1110 -250 1250 -250 {
+lab=vss}
+N 870 -270 870 -250 {
+lab=vss}
+N 1250 -280 1250 -250 {
+lab=vss}
+N 1250 -330 1280 -330 {
+lab=vss}
+N 1280 -330 1280 -280 {
+lab=vss}
+N 1250 -280 1280 -280 {
+lab=vss}
+N 1250 -300 1250 -280 {
+lab=vss}
+N 1110 -280 1110 -250 {
+lab=vss}
+N 870 -250 1110 -250 {
+lab=vss}
+N 1110 -330 1140 -330 {
+lab=vss}
+N 1140 -330 1140 -280 {
+lab=vss}
+N 1110 -280 1140 -280 {
+lab=vss}
+N 1110 -300 1110 -280 {
+lab=vss}
+N 870 -390 1010 -390 {
+lab=#net1}
+N 870 -420 870 -390 {
+lab=#net1}
+N 1010 -390 1010 -330 {
+lab=#net1}
+N 1010 -330 1070 -330 {
+lab=#net1}
+N 1110 -390 1110 -360 {
+lab=#net2}
+N 1250 -410 1250 -360 {
+lab=#net3}
+N 1070 -410 1250 -410 {
+lab=#net3}
+N 1250 -460 1250 -410 {
+lab=#net3}
+N 1070 -490 1070 -410 {
+lab=#net3}
+N 1110 -430 1210 -430 {
+lab=#net2}
+N 1110 -460 1110 -430 {
+lab=#net2}
+N 1210 -490 1210 -430 {
+lab=#net2}
+N 1110 -560 1110 -520 {
+lab=iovdd}
+N 1190 -560 1250 -560 {
+lab=iovdd}
+N 1250 -560 1250 -520 {
+lab=iovdd}
+N 1250 -490 1290 -490 {
+lab=iovdd}
+N 1290 -560 1290 -490 {
+lab=iovdd}
+N 1250 -560 1290 -560 {
+lab=iovdd}
+N 1110 -490 1150 -490 {
+lab=iovdd}
+N 1150 -560 1150 -490 {
+lab=iovdd}
+N 1110 -560 1150 -560 {
+lab=iovdd}
+N 1190 -600 1190 -560 {
+lab=iovdd}
+N 1150 -560 1190 -560 {
+lab=iovdd}
+N 1460 -410 1460 -360 {
+lab=xxx}
+N 1370 -490 1420 -490 {
+lab=#net4}
+N 1370 -390 1370 -330 {
+lab=#net4}
+N 1370 -330 1420 -330 {
+lab=#net4}
+N 1460 -410 1550 -410 {
+lab=xxx}
+N 1460 -460 1460 -410 {
+lab=xxx}
+N 1460 -270 1460 -250 {
+lab=vss}
+N 1250 -250 1460 -250 {
+lab=vss}
+N 1460 -330 1490 -330 {
+lab=vss}
+N 1490 -330 1490 -270 {
+lab=vss}
+N 1460 -270 1490 -270 {
+lab=vss}
+N 1460 -300 1460 -270 {
+lab=vss}
+N 1460 -540 1460 -520 {
+lab=iovdd}
+N 1290 -560 1460 -560 {
+lab=iovdd}
+N 1460 -490 1490 -490 {
+lab=iovdd}
+N 1490 -540 1490 -490 {
+lab=iovdd}
+N 1460 -540 1490 -540 {
+lab=iovdd}
+N 1460 -560 1460 -540 {
+lab=iovdd}
+N 780 -340 780 -160 {}
+N 780 -160 1200 -160 {}
+N 1200 -330 1200 -160 {}
+N 1200 -330 1210 -330 {}
+N 1110 -390 1370 -390 {}
+N 1110 -430 1110 -390 {
+lab=#net2}
+N 1370 -490 1370 -390 {
+lab=#net4}
+C {sg13g2_pr/sg13_lv_nmos.sym} 850 -340 2 1 {name=M1
+l=0.13u
+w=2.75u
+ng=1
+m=1
+model=sg13_lv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_lv_pmos.sym} 850 -450 0 0 {name=M2
+l=0.13u
+w=4.75u
+ng=1
+m=1
+model=sg13_lv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1090 -330 2 1 {name=M3
+l=0.45u
+w=1.9u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1230 -330 2 1 {name=M4
+l=0.45u
+w=1.9u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1090 -490 0 0 {name=M5
+l=0.45u
+w=0.3u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1230 -490 0 0 {name=M6
+l=0.45u
+w=0.3u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1440 -330 0 0 {name=M7
+l=0.45u
+w=1.9u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1440 -490 0 0 {name=M8
+l=0.45u
+w=3.9u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {devices/iopin.sym} 720 -400 2 0 {name=i lab=i}
+C {devices/iopin.sym} 870 -220 1 0 {name=vss lab=vss}
+C {devices/iopin.sym} 870 -570 3 0 {name=vdd lab=vdd}
+C {devices/iopin.sym} 1190 -600 3 0 {name=iovdd lab=iovdd}
+C {devices/iopin.sym} 1550 -410 0 0 {name=o lab=o}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelUpInv.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelUpInv.sym
new file mode 100644
index 00000000..671011f5
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_LevelUpInv.sym
@@ -0,0 +1,31 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -50 130 -50 {}
+L 4 -130 50 130 50 {}
+L 4 -130 -50 -130 50 {}
+L 4 130 -50 130 50 {}
+L 7 30 -70 30 -50 {}
+L 7 -20 -70 -20 -50 {}
+L 7 130 0 150 0 {}
+L 7 -150 0 -130 0 {}
+L 7 -20 50 -20 70 {}
+B 5 27.5 -72.5 32.5 -67.5 {name=iovdd dir=inout}
+B 5 -22.5 -72.5 -17.5 -67.5 {name=vdd dir=inout}
+B 5 147.5 -2.5 152.5 2.5 {name=o dir=inout}
+B 5 -152.5 -2.5 -147.5 2.5 {name=i dir=inout}
+B 5 -22.5 67.5 -17.5 72.5 {name=vss dir=inout}
+T {sg13g2_LevelUpInv} -54.5 -6 0 0 0.2 0.2 {}
+T {@name} 135 -62 0 0 0.2 0.2 {}
+T {iovdd} 65 -64 0 1 0.2 0.2 {}
+T {vdd} -25 -64 0 1 0.2 0.2 {}
+T {o} 125 -4 0 1 0.2 0.2 {}
+T {i} -125 -14 0 1 0.2 0.2 {}
+T {vss} -35 56 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_RCClampInverter.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_RCClampInverter.sch
new file mode 100644
index 00000000..90f00c9a
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_RCClampInverter.sch
@@ -0,0 +1,1809 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N -400 100 -400 120 {
+lab=ground}
+N -405 50 -370 50 {
+lab=ground}
+N -370 50 -370 100 {
+lab=ground}
+N -400 100 -370 100 {
+lab=ground}
+N -400 80 -400 100 {
+lab=ground}
+N -370 10 -370 50 {
+lab=ground}
+N -400 10 -370 10 {
+lab=ground}
+N -400 10 -400 20 {
+lab=ground}
+N -280 90 -280 120 {
+lab=ground}
+N 180 120 300 120 {
+lab=ground}
+N -400 120 -280 120 {
+lab=ground}
+N 300 90 300 120 {
+lab=ground}
+N -285 40 -245 40 {
+lab=ground}
+N -245 40 -245 90 {
+lab=ground}
+N -280 90 -245 90 {
+lab=ground}
+N -280 70 -280 90 {
+lab=ground}
+N -280 10 -245 10 {
+lab=ground}
+N -245 10 -245 40 {
+lab=ground}
+N -140 90 -140 120 {
+lab=ground}
+N -210 120 -140 120 {
+lab=ground}
+N -145 40 -120 40 {
+lab=ground}
+N -120 40 -120 90 {
+lab=ground}
+N -140 90 -120 90 {
+lab=ground}
+N -140 70 -140 90 {
+lab=ground}
+N -140 10 -120 10 {
+lab=ground}
+N -120 10 -120 40 {
+lab=ground}
+N -35 40 -15 40 {
+lab=ground}
+N -30 80 -30 120 {
+lab=ground}
+N -140 120 -30 120 {
+lab=ground}
+N -30 80 -15 80 {
+lab=ground}
+N -30 70 -30 80 {
+lab=ground}
+N -30 10 -15 10 {
+lab=ground}
+N -15 40 -15 80 {
+lab=ground}
+N -15 10 -15 40 {
+lab=ground}
+N 80 90 80 120 {
+lab=ground}
+N -30 120 80 120 {
+lab=ground}
+N 75 40 100 40 {
+lab=ground}
+N 80 90 100 90 {
+lab=ground}
+N 80 70 80 90 {
+lab=ground}
+N 80 10 100 10 {
+lab=ground}
+N 100 40 100 90 {
+lab=ground}
+N 100 10 100 40 {
+lab=ground}
+N 180 85 180 120 {
+lab=ground}
+N 80 120 180 120 {
+lab=ground}
+N 175 40 200 40 {
+lab=ground}
+N 180 85 200 85 {
+lab=ground}
+N 180 70 180 85 {
+lab=ground}
+N 300 40 325 40 {
+lab=ground}
+N 300 90 325 90 {
+lab=ground}
+N 300 70 300 90 {
+lab=ground}
+N 300 10 325 10 {
+lab=ground}
+N 325 40 325 90 {
+lab=ground}
+N 325 10 325 40 {
+lab=ground}
+N 180 10 200 10 {
+lab=ground}
+N 200 40 200 85 {
+lab=ground}
+N 200 10 200 40 {
+lab=ground}
+N -410 -60 -410 -40 {
+lab=ground}
+N -415 -110 -380 -110 {
+lab=ground}
+N -380 -110 -380 -60 {
+lab=ground}
+N -410 -60 -380 -60 {
+lab=ground}
+N -410 -80 -410 -60 {
+lab=ground}
+N -380 -150 -380 -110 {
+lab=ground}
+N -410 -150 -380 -150 {
+lab=ground}
+N -410 -150 -410 -140 {
+lab=ground}
+N -290 -70 -290 -40 {
+lab=ground}
+N 170 -40 290 -40 {
+lab=ground}
+N -410 -40 -290 -40 {
+lab=ground}
+N 290 -70 290 -40 {
+lab=ground}
+N -295 -120 -255 -120 {
+lab=ground}
+N -255 -120 -255 -70 {
+lab=ground}
+N -290 -70 -255 -70 {
+lab=ground}
+N -290 -90 -290 -70 {
+lab=ground}
+N -290 -150 -255 -150 {
+lab=ground}
+N -255 -150 -255 -120 {
+lab=ground}
+N -150 -70 -150 -40 {
+lab=ground}
+N -210 -40 -150 -40 {
+lab=ground}
+N -155 -120 -130 -120 {
+lab=ground}
+N -130 -120 -130 -70 {
+lab=ground}
+N -150 -70 -130 -70 {
+lab=ground}
+N -150 -90 -150 -70 {
+lab=ground}
+N -150 -150 -130 -150 {
+lab=ground}
+N -130 -150 -130 -120 {
+lab=ground}
+N -45 -120 -25 -120 {
+lab=ground}
+N -40 -80 -40 -40 {
+lab=ground}
+N -150 -40 -40 -40 {
+lab=ground}
+N -40 -80 -25 -80 {
+lab=ground}
+N -40 -90 -40 -80 {
+lab=ground}
+N -40 -150 -25 -150 {
+lab=ground}
+N -25 -120 -25 -80 {
+lab=ground}
+N -25 -150 -25 -120 {
+lab=ground}
+N 70 -70 70 -40 {
+lab=ground}
+N -40 -40 70 -40 {
+lab=ground}
+N 65 -120 90 -120 {
+lab=ground}
+N 70 -70 90 -70 {
+lab=ground}
+N 70 -90 70 -70 {
+lab=ground}
+N 70 -150 90 -150 {
+lab=ground}
+N 90 -120 90 -70 {
+lab=ground}
+N 90 -150 90 -120 {
+lab=ground}
+N 170 -75 170 -40 {
+lab=ground}
+N 70 -40 170 -40 {
+lab=ground}
+N 165 -120 190 -120 {
+lab=ground}
+N 170 -75 190 -75 {
+lab=ground}
+N 170 -90 170 -75 {
+lab=ground}
+N 290 -120 315 -120 {
+lab=ground}
+N 290 -70 315 -70 {
+lab=ground}
+N 290 -90 290 -70 {
+lab=ground}
+N 290 -150 315 -150 {
+lab=ground}
+N 315 -120 315 -70 {
+lab=ground}
+N 315 -150 315 -120 {
+lab=ground}
+N 170 -150 190 -150 {
+lab=ground}
+N 190 -120 190 -75 {
+lab=ground}
+N 190 -150 190 -120 {
+lab=ground}
+N -210 -40 -210 120 {
+lab=ground}
+N -290 -40 -210 -40 {
+lab=ground}
+N -280 120 -210 120 {
+lab=ground}
+N 1800 80 1945 80 {
+lab=ground}
+N 390 120 545 120 {
+lab=ground}
+N 545 80 545 120 {
+lab=ground}
+N 495 80 545 80 {
+lab=ground}
+N 465 50 495 50 {
+lab=ground}
+N 495 50 495 80 {
+lab=ground}
+N 465 80 495 80 {
+lab=ground}
+N 585 50 615 50 {
+lab=ground}
+N 615 50 615 80 {
+lab=ground}
+N 545 80 615 80 {
+lab=ground}
+N 710 50 745 50 {
+lab=ground}
+N 745 50 745 80 {
+lab=ground}
+N 615 80 745 80 {
+lab=ground}
+N 830 50 865 50 {
+lab=ground}
+N 865 50 865 80 {
+lab=ground}
+N 745 80 865 80 {
+lab=ground}
+N 975 50 1010 50 {
+lab=ground}
+N 1010 50 1010 80 {
+lab=ground}
+N 865 80 1010 80 {
+lab=ground}
+N 1130 50 1150 50 {
+lab=ground}
+N 1150 50 1150 80 {
+lab=ground}
+N 1010 80 1150 80 {
+lab=ground}
+N 1265 50 1295 50 {
+lab=ground}
+N 1295 50 1295 80 {
+lab=ground}
+N 1150 80 1295 80 {
+lab=ground}
+N 1385 50 1410 50 {
+lab=ground}
+N 1410 50 1410 80 {
+lab=ground}
+N 1295 80 1410 80 {
+lab=ground}
+N 1510 50 1530 50 {
+lab=ground}
+N 1530 50 1530 80 {
+lab=ground}
+N 1410 80 1530 80 {
+lab=ground}
+N 1635 50 1665 50 {
+lab=ground}
+N 1665 50 1665 80 {
+lab=ground}
+N 1530 80 1665 80 {
+lab=ground}
+N 1780 50 1800 50 {
+lab=ground}
+N 1800 50 1800 80 {
+lab=ground}
+N 1665 80 1800 80 {
+lab=ground}
+N 1920 50 1945 50 {
+lab=ground}
+N 1945 50 1945 80 {
+lab=ground}
+N -395 -520 -395 -500 {
+lab=supply}
+N 2655 -540 2680 -540 {
+lab=supply}
+N 2655 -540 2655 -495 {
+lab=supply}
+N 2515 -540 2655 -540 {
+lab=supply}
+N 2650 -470 2680 -470 {
+lab=supply}
+N 2680 -540 2680 -470 {
+lab=supply}
+N -395 -470 -370 -470 {
+lab=supply}
+N -370 -520 -370 -470 {
+lab=supply}
+N -395 -520 -370 -520 {
+lab=supply}
+N -395 -540 -395 -520 {
+lab=supply}
+N -255 -515 -255 -500 {
+lab=supply}
+N -395 -540 -255 -540 {
+lab=supply}
+N -260 -470 -230 -470 {
+lab=supply}
+N -230 -515 -230 -470 {
+lab=supply}
+N -255 -515 -230 -515 {
+lab=supply}
+N -255 -540 -255 -515 {
+lab=supply}
+N -130 -515 -130 -500 {
+lab=supply}
+N -255 -540 -130 -540 {
+lab=supply}
+N -135 -470 -105 -470 {
+lab=supply}
+N -105 -515 -105 -470 {
+lab=supply}
+N -130 -515 -105 -515 {
+lab=supply}
+N -130 -540 -130 -515 {
+lab=supply}
+N 0 -515 0 -500 {
+lab=supply}
+N -130 -540 0 -540 {
+lab=supply}
+N -5 -470 25 -470 {
+lab=supply}
+N 25 -515 25 -470 {
+lab=supply}
+N 0 -515 25 -515 {
+lab=supply}
+N 0 -540 0 -515 {
+lab=supply}
+N 120 -515 120 -500 {
+lab=supply}
+N 0 -540 120 -540 {
+lab=supply}
+N 115 -470 140 -470 {
+lab=supply}
+N 140 -515 140 -470 {
+lab=supply}
+N 120 -515 140 -515 {
+lab=supply}
+N 120 -540 120 -515 {
+lab=supply}
+N 260 -520 260 -500 {
+lab=supply}
+N 120 -540 260 -540 {
+lab=supply}
+N 255 -470 285 -470 {
+lab=supply}
+N 285 -520 285 -470 {
+lab=supply}
+N 260 -520 285 -520 {
+lab=supply}
+N 260 -540 260 -520 {
+lab=supply}
+N 380 -515 380 -500 {
+lab=supply}
+N 260 -540 380 -540 {
+lab=supply}
+N 375 -470 415 -470 {
+lab=supply}
+N 415 -515 415 -470 {
+lab=supply}
+N 380 -515 415 -515 {
+lab=supply}
+N 380 -540 380 -515 {
+lab=supply}
+N 500 -515 500 -500 {
+lab=supply}
+N 380 -540 500 -540 {
+lab=supply}
+N 500 -470 525 -470 {
+lab=supply}
+N 525 -515 525 -470 {
+lab=supply}
+N 500 -515 525 -515 {
+lab=supply}
+N 500 -540 500 -515 {
+lab=supply}
+N 620 -510 620 -500 {
+lab=supply}
+N 500 -540 620 -540 {
+lab=supply}
+N 615 -470 635 -470 {
+lab=supply}
+N 635 -510 635 -470 {
+lab=supply}
+N 620 -510 635 -510 {
+lab=supply}
+N 620 -540 620 -510 {
+lab=supply}
+N 760 -515 760 -500 {
+lab=supply}
+N 620 -540 760 -540 {
+lab=supply}
+N 755 -470 785 -470 {
+lab=supply}
+N 785 -515 785 -470 {
+lab=supply}
+N 760 -515 785 -515 {
+lab=supply}
+N 760 -540 760 -515 {
+lab=supply}
+N 875 -515 875 -500 {
+lab=supply}
+N 825 -540 875 -540 {
+lab=supply}
+N 870 -470 895 -470 {
+lab=supply}
+N 895 -515 895 -470 {
+lab=supply}
+N 875 -515 895 -515 {
+lab=supply}
+N 875 -540 875 -515 {
+lab=supply}
+N 1015 -520 1015 -500 {
+lab=supply}
+N 875 -540 1015 -540 {
+lab=supply}
+N 1010 -470 1040 -470 {
+lab=supply}
+N 1040 -520 1040 -470 {
+lab=supply}
+N 1015 -520 1040 -520 {
+lab=supply}
+N 1015 -540 1015 -520 {
+lab=supply}
+N 1140 -520 1140 -500 {
+lab=supply}
+N 1015 -540 1140 -540 {
+lab=supply}
+N 1135 -470 1155 -470 {
+lab=supply}
+N 1155 -520 1155 -470 {
+lab=supply}
+N 1140 -520 1155 -520 {
+lab=supply}
+N 1140 -540 1140 -520 {
+lab=supply}
+N 1270 -515 1270 -500 {
+lab=supply}
+N 1140 -540 1270 -540 {
+lab=supply}
+N 1265 -470 1285 -470 {
+lab=supply}
+N 1285 -515 1285 -470 {
+lab=supply}
+N 1270 -515 1285 -515 {
+lab=supply}
+N 1270 -540 1270 -515 {
+lab=supply}
+N 1390 -520 1390 -500 {
+lab=supply}
+N 1270 -540 1390 -540 {
+lab=supply}
+N 1385 -470 1410 -470 {
+lab=supply}
+N 1410 -520 1410 -470 {
+lab=supply}
+N 1390 -520 1410 -520 {
+lab=supply}
+N 1390 -540 1390 -520 {
+lab=supply}
+N 1530 -520 1530 -500 {
+lab=supply}
+N 1390 -540 1530 -540 {
+lab=supply}
+N 1525 -470 1565 -470 {
+lab=supply}
+N 1565 -520 1565 -470 {
+lab=supply}
+N 1530 -520 1565 -520 {
+lab=supply}
+N 1530 -540 1530 -520 {
+lab=supply}
+N 1650 -515 1650 -500 {
+lab=supply}
+N 1530 -540 1650 -540 {
+lab=supply}
+N 1650 -470 1675 -470 {
+lab=supply}
+N 1675 -515 1675 -470 {
+lab=supply}
+N 1650 -515 1675 -515 {
+lab=supply}
+N 1650 -540 1650 -515 {
+lab=supply}
+N 1770 -515 1770 -500 {
+lab=supply}
+N 1650 -540 1770 -540 {
+lab=supply}
+N 1765 -470 1800 -470 {
+lab=supply}
+N 1800 -515 1800 -470 {
+lab=supply}
+N 1770 -515 1800 -515 {
+lab=supply}
+N 1770 -540 1770 -515 {
+lab=supply}
+N 1890 -520 1890 -500 {
+lab=supply}
+N 1770 -540 1890 -540 {
+lab=supply}
+N 1885 -470 1910 -470 {
+lab=supply}
+N 1910 -520 1910 -470 {
+lab=supply}
+N 1890 -520 1910 -520 {
+lab=supply}
+N 1890 -540 1890 -520 {
+lab=supply}
+N 2030 -520 2030 -500 {
+lab=supply}
+N 1890 -540 2030 -540 {
+lab=supply}
+N 2025 -470 2055 -470 {
+lab=supply}
+N 2055 -520 2055 -470 {
+lab=supply}
+N 2030 -520 2055 -520 {
+lab=supply}
+N 2030 -540 2030 -520 {
+lab=supply}
+N 2155 -520 2155 -500 {
+lab=supply}
+N 2030 -540 2155 -540 {
+lab=supply}
+N 2150 -470 2180 -470 {
+lab=supply}
+N 2180 -520 2180 -470 {
+lab=supply}
+N 2155 -520 2180 -520 {
+lab=supply}
+N 2155 -540 2155 -520 {
+lab=supply}
+N 2275 -520 2275 -500 {
+lab=supply}
+N 2155 -540 2275 -540 {
+lab=supply}
+N 2270 -470 2300 -470 {
+lab=supply}
+N 2300 -520 2300 -470 {
+lab=supply}
+N 2275 -520 2300 -520 {
+lab=supply}
+N 2275 -540 2275 -520 {
+lab=supply}
+N 2395 -520 2395 -500 {
+lab=supply}
+N 2275 -540 2395 -540 {
+lab=supply}
+N 2390 -470 2420 -470 {
+lab=supply}
+N 2420 -520 2420 -470 {
+lab=supply}
+N 2395 -520 2420 -520 {
+lab=supply}
+N 2395 -540 2395 -520 {
+lab=supply}
+N 2515 -520 2515 -500 {
+lab=supply}
+N 2395 -540 2515 -540 {
+lab=supply}
+N 2515 -470 2540 -470 {
+lab=supply}
+N 2540 -520 2540 -470 {
+lab=supply}
+N 2515 -520 2540 -520 {
+lab=supply}
+N 2515 -540 2515 -520 {
+lab=supply}
+N 2535 -370 2680 -370 {
+lab=supply}
+N -400 -340 -350 -340 {
+lab=supply}
+N -350 -370 -350 -340 {
+lab=supply}
+N -400 -370 -350 -370 {
+lab=supply}
+N -260 -340 -235 -340 {
+lab=supply}
+N -235 -370 -235 -340 {
+lab=supply}
+N -350 -370 -235 -370 {
+lab=supply}
+N -135 -340 -100 -340 {
+lab=supply}
+N -100 -370 -100 -340 {
+lab=supply}
+N -235 -370 -100 -370 {
+lab=supply}
+N -5 -340 25 -340 {
+lab=supply}
+N 25 -370 25 -340 {
+lab=supply}
+N -100 -370 25 -370 {
+lab=supply}
+N 110 -340 150 -340 {
+lab=supply}
+N 150 -370 150 -340 {
+lab=supply}
+N 25 -370 150 -370 {
+lab=supply}
+N 255 -340 275 -340 {
+lab=supply}
+N 275 -370 275 -340 {
+lab=supply}
+N 150 -370 275 -370 {
+lab=supply}
+N 370 -340 410 -340 {
+lab=supply}
+N 410 -370 410 -340 {
+lab=supply}
+N 275 -370 410 -370 {
+lab=supply}
+N 495 -340 525 -340 {
+lab=supply}
+N 525 -370 525 -340 {
+lab=supply}
+N 410 -370 525 -370 {
+lab=supply}
+N 615 -340 655 -340 {
+lab=supply}
+N 655 -370 655 -340 {
+lab=supply}
+N 525 -370 655 -370 {
+lab=supply}
+N 755 -340 780 -340 {
+lab=supply}
+N 780 -370 780 -340 {
+lab=supply}
+N 655 -370 780 -370 {
+lab=supply}
+N 865 -340 895 -340 {
+lab=supply}
+N 895 -370 895 -340 {
+lab=supply}
+N 780 -370 895 -370 {
+lab=supply}
+N 1010 -340 1040 -340 {
+lab=supply}
+N 1040 -370 1040 -340 {
+lab=supply}
+N 895 -370 1040 -370 {
+lab=supply}
+N 1135 -340 1170 -340 {
+lab=supply}
+N 1170 -370 1170 -340 {
+lab=supply}
+N 1040 -370 1170 -370 {
+lab=supply}
+N 1260 -340 1295 -340 {
+lab=supply}
+N 1295 -370 1295 -340 {
+lab=supply}
+N 1170 -370 1295 -370 {
+lab=supply}
+N 1380 -340 1410 -340 {
+lab=supply}
+N 1410 -370 1410 -340 {
+lab=supply}
+N 1295 -370 1410 -370 {
+lab=supply}
+N 1520 -340 1550 -340 {
+lab=supply}
+N 1550 -370 1550 -340 {
+lab=supply}
+N 1410 -370 1550 -370 {
+lab=supply}
+N 1640 -340 1675 -340 {
+lab=supply}
+N 1675 -370 1675 -340 {
+lab=supply}
+N 1550 -370 1675 -370 {
+lab=supply}
+N 1765 -340 1795 -340 {
+lab=supply}
+N 1795 -370 1795 -340 {
+lab=supply}
+N 1675 -370 1795 -370 {
+lab=supply}
+N 1880 -340 1910 -340 {
+lab=supply}
+N 1910 -370 1910 -340 {
+lab=supply}
+N 1795 -370 1910 -370 {
+lab=supply}
+N 2025 -340 2050 -340 {
+lab=supply}
+N 2050 -370 2050 -340 {
+lab=supply}
+N 1910 -370 2050 -370 {
+lab=supply}
+N 2150 -340 2180 -340 {
+lab=supply}
+N 2180 -370 2180 -340 {
+lab=supply}
+N 2050 -370 2180 -370 {
+lab=supply}
+N 2270 -340 2300 -340 {
+lab=supply}
+N 2300 -370 2300 -340 {
+lab=supply}
+N 2180 -370 2300 -370 {
+lab=supply}
+N 2390 -340 2420 -340 {
+lab=supply}
+N 2420 -370 2420 -340 {
+lab=supply}
+N 2300 -370 2420 -370 {
+lab=supply}
+N 2510 -340 2535 -340 {
+lab=supply}
+N 2535 -370 2535 -340 {
+lab=supply}
+N 2420 -370 2535 -370 {
+lab=supply}
+N 2645 -340 2680 -340 {
+lab=supply}
+N 2680 -370 2680 -340 {
+lab=supply}
+N 2680 -470 2680 -370 {
+lab=supply}
+N 905 20 1925 20 {
+lab=out}
+N -400 -310 -400 -285 {
+lab=out}
+N 2650 -310 2650 -285 {
+lab=out}
+N 2575 -285 2650 -285 {
+lab=out}
+N 2510 -310 2510 -285 {
+lab=out}
+N 2390 -285 2510 -285 {
+lab=out}
+N 2390 -305 2390 -285 {
+lab=out}
+N 2270 -285 2390 -285 {
+lab=out}
+N 2270 -310 2270 -285 {
+lab=out}
+N 2150 -285 2270 -285 {
+lab=out}
+N 2150 -310 2150 -285 {
+lab=out}
+N 2025 -285 2150 -285 {
+lab=out}
+N 2025 -310 2025 -285 {
+lab=out}
+N 1885 -285 2025 -285 {
+lab=out}
+N 1885 -310 1885 -285 {
+lab=out}
+N 1765 -285 1885 -285 {
+lab=out}
+N 1765 -310 1765 -285 {
+lab=out}
+N 1645 -285 1765 -285 {
+lab=out}
+N 1645 -310 1645 -285 {
+lab=out}
+N 1525 -285 1645 -285 {
+lab=out}
+N 1525 -310 1525 -285 {
+lab=out}
+N 1385 -285 1525 -285 {
+lab=out}
+N 1385 -310 1385 -285 {
+lab=out}
+N 1265 -285 1385 -285 {
+lab=out}
+N 1265 -310 1265 -285 {
+lab=out}
+N 1135 -285 1265 -285 {
+lab=out}
+N 1135 -310 1135 -285 {
+lab=out}
+N 1010 -285 1135 -285 {
+lab=out}
+N 1010 -310 1010 -285 {
+lab=out}
+N 905 -285 1010 -285 {
+lab=out}
+N 870 -310 870 -285 {
+lab=out}
+N 755 -285 870 -285 {
+lab=out}
+N 755 -310 755 -285 {
+lab=out}
+N 615 -285 755 -285 {
+lab=out}
+N 615 -310 615 -285 {
+lab=out}
+N 495 -285 615 -285 {
+lab=out}
+N 495 -310 495 -285 {
+lab=out}
+N 375 -285 495 -285 {
+lab=out}
+N 375 -310 375 -285 {
+lab=out}
+N 255 -285 375 -285 {
+lab=out}
+N 255 -310 255 -285 {
+lab=out}
+N 115 -285 255 -285 {
+lab=out}
+N 115 -310 115 -285 {
+lab=out}
+N -5 -285 115 -285 {
+lab=out}
+N -5 -310 -5 -285 {
+lab=out}
+N -135 -285 -5 -285 {
+lab=out}
+N -135 -310 -135 -285 {
+lab=out}
+N -260 -285 -135 -285 {
+lab=out}
+N -260 -310 -260 -285 {
+lab=out}
+N -400 -285 -260 -285 {
+lab=out}
+N 2575 -440 2655 -440 {
+lab=out}
+N 2575 -440 2575 -285 {
+lab=out}
+N -395 -440 2575 -440 {
+lab=out}
+N 2510 -285 2575 -285 {
+lab=out}
+N 905 -130 905 20 {
+lab=out}
+N 870 -285 905 -285 {
+lab=out}
+N 465 20 905 20 {
+lab=out}
+N -515 -110 -450 -110 {
+lab=in}
+N -515 -215 -515 -110 {
+lab=in}
+N -515 -470 -435 -470 {
+lab=in}
+N -515 -340 -440 -340 {
+lab=in}
+N -515 -470 -515 -340 {
+lab=in}
+N -515 50 -440 50 {
+lab=in}
+N -515 -15 -515 50 {
+lab=in}
+N 2470 -215 2610 -215 {
+lab=in}
+N -515 -340 -515 -215 {
+lab=in}
+N 2610 -340 2610 -215 {
+lab=in}
+N -330 -215 -330 -120 {
+lab=in}
+N -515 -215 -330 -215 {
+lab=in}
+N -190 -215 -190 -120 {
+lab=in}
+N -300 -215 -190 -215 {
+lab=in}
+N -80 -215 -80 -120 {
+lab=in}
+N -175 -215 -80 -215 {
+lab=in}
+N 30 -215 30 -120 {
+lab=in}
+N -45 -215 30 -215 {
+lab=in}
+N 130 -215 130 -120 {
+lab=in}
+N 75 -215 130 -215 {
+lab=in}
+N 250 -215 250 -120 {
+lab=in}
+N 215 -215 250 -215 {
+lab=in}
+N -300 -340 -300 -215 {
+lab=in}
+N -330 -215 -300 -215 {
+lab=in}
+N -175 -340 -175 -215 {
+lab=in}
+N -190 -215 -175 -215 {
+lab=in}
+N -45 -340 -45 -215 {
+lab=in}
+N -80 -215 -45 -215 {
+lab=in}
+N 75 -340 75 -215 {
+lab=in}
+N 30 -215 75 -215 {
+lab=in}
+N 215 -340 215 -215 {
+lab=in}
+N 130 -215 215 -215 {
+lab=in}
+N 335 -340 335 -215 {
+lab=in}
+N 250 -215 335 -215 {
+lab=in}
+N 455 -340 455 -215 {
+lab=in}
+N 335 -215 455 -215 {
+lab=in}
+N 575 -340 575 -215 {
+lab=in}
+N 455 -215 575 -215 {
+lab=in}
+N -515 -110 -515 -15 {
+lab=in}
+N 425 -15 425 50 {
+lab=in}
+N 260 -15 425 -15 {
+lab=in}
+N 1740 -15 1885 -15 {
+lab=in}
+N 1885 -15 1885 50 {
+lab=in}
+N 1740 -15 1740 50 {
+lab=in}
+N 1600 -15 1740 -15 {
+lab=in}
+N 1600 -15 1600 50 {
+lab=in}
+N 1470 -15 1600 -15 {
+lab=in}
+N 1470 -15 1470 50 {
+lab=in}
+N 1345 -15 1470 -15 {
+lab=in}
+N 1345 -15 1345 50 {
+lab=in}
+N 1225 -15 1345 -15 {
+lab=in}
+N 1225 -15 1225 50 {
+lab=in}
+N 1090 -15 1225 -15 {
+lab=in}
+N 1090 -15 1090 50 {
+lab=in}
+N 940 -15 1090 -15 {
+lab=in}
+N 940 -15 940 50 {
+lab=in}
+N 795 -15 940 -15 {
+lab=in}
+N 795 -15 795 50 {
+lab=in}
+N 670 -15 795 -15 {
+lab=in}
+N 670 -15 670 50 {
+lab=in}
+N 550 -15 670 -15 {
+lab=in}
+N 550 -15 550 50 {
+lab=in}
+N 425 -15 550 -15 {
+lab=in}
+N 260 -15 260 40 {
+lab=in}
+N 140 -15 260 -15 {
+lab=in}
+N 140 -15 140 40 {
+lab=in}
+N 40 -15 140 -15 {
+lab=in}
+N 40 -15 40 40 {
+lab=in}
+N -70 -15 40 -15 {
+lab=in}
+N -70 -15 -70 40 {
+lab=in}
+N -180 -15 -70 -15 {
+lab=in}
+N -180 -15 -180 40 {
+lab=in}
+N -320 -15 -180 -15 {
+lab=in}
+N -320 -15 -320 40 {
+lab=in}
+N -515 -15 -320 -15 {
+lab=in}
+N 715 -340 715 -215 {
+lab=in}
+N 575 -215 715 -215 {
+lab=in}
+N 830 -340 830 -215 {
+lab=in}
+N 715 -215 830 -215 {
+lab=in}
+N 970 -340 970 -215 {
+lab=in}
+N 830 -215 970 -215 {
+lab=in}
+N 1095 -340 1095 -215 {
+lab=in}
+N 970 -215 1095 -215 {
+lab=in}
+N 1225 -340 1225 -215 {
+lab=in}
+N 1095 -215 1225 -215 {
+lab=in}
+N 1345 -340 1345 -215 {
+lab=in}
+N 1225 -215 1345 -215 {
+lab=in}
+N 1485 -340 1485 -215 {
+lab=in}
+N 1345 -215 1485 -215 {
+lab=in}
+N 1605 -340 1605 -215 {
+lab=in}
+N 1485 -215 1605 -215 {
+lab=in}
+N 1725 -340 1725 -215 {
+lab=in}
+N 1605 -215 1725 -215 {
+lab=in}
+N 1845 -340 1845 -215 {
+lab=in}
+N 1725 -215 1845 -215 {
+lab=in}
+N 1985 -340 1985 -215 {
+lab=in}
+N 1845 -215 1985 -215 {
+lab=in}
+N 2110 -340 2110 -215 {
+lab=in}
+N 1985 -215 2110 -215 {
+lab=in}
+N 2230 -340 2230 -215 {
+lab=in}
+N 2110 -215 2230 -215 {
+lab=in}
+N 2350 -340 2350 -215 {
+lab=in}
+N 2230 -215 2350 -215 {
+lab=in}
+N 2470 -340 2470 -215 {
+lab=in}
+N 2350 -215 2470 -215 {
+lab=in}
+N 2475 -400 2615 -400 {
+lab=#net1}
+N 2615 -470 2615 -400 {
+lab=#net1}
+N 2475 -470 2475 -400 {
+lab=#net1}
+N 2355 -400 2475 -400 {
+lab=#net1}
+N 2355 -470 2355 -400 {
+lab=#net1}
+N 2235 -400 2355 -400 {
+lab=#net1}
+N 2235 -470 2235 -400 {
+lab=#net1}
+N 2115 -400 2235 -400 {
+lab=#net1}
+N 2115 -470 2115 -400 {
+lab=#net1}
+N 1990 -400 2115 -400 {
+lab=#net1}
+N 1990 -470 1990 -400 {
+lab=#net1}
+N 1850 -400 1990 -400 {
+lab=#net1}
+N 1850 -470 1850 -400 {
+lab=#net1}
+N 1730 -400 1850 -400 {
+lab=#net1}
+N 1730 -470 1730 -400 {
+lab=#net1}
+N 1610 -400 1730 -400 {
+lab=#net1}
+N 1610 -470 1610 -400 {
+lab=#net1}
+N 1490 -400 1610 -400 {
+lab=#net1}
+N 1490 -470 1490 -400 {
+lab=#net1}
+N 1350 -400 1490 -400 {
+lab=#net1}
+N 1350 -470 1350 -400 {
+lab=#net1}
+N 1230 -400 1350 -400 {
+lab=#net1}
+N 1230 -470 1230 -400 {
+lab=#net1}
+N 1100 -400 1230 -400 {
+lab=#net1}
+N 1100 -470 1100 -400 {
+lab=#net1}
+N 975 -400 1100 -400 {
+lab=#net1}
+N 975 -470 975 -400 {
+lab=#net1}
+N 835 -400 975 -400 {
+lab=#net1}
+N 835 -470 835 -400 {
+lab=#net1}
+N 720 -400 835 -400 {
+lab=#net1}
+N 720 -470 720 -400 {
+lab=#net1}
+N 580 -400 720 -400 {
+lab=#net1}
+N 580 -470 580 -400 {
+lab=#net1}
+N 460 -400 580 -400 {
+lab=#net1}
+N 460 -470 460 -400 {
+lab=#net1}
+N 340 -400 460 -400 {
+lab=#net1}
+N 340 -470 340 -400 {
+lab=#net1}
+N 220 -400 340 -400 {
+lab=#net1}
+N 220 -470 220 -400 {
+lab=#net1}
+N 80 -400 220 -400 {
+lab=#net1}
+N 80 -470 80 -400 {
+lab=#net1}
+N -40 -400 80 -400 {
+lab=#net1}
+N -40 -470 -40 -400 {
+lab=#net1}
+N -170 -400 -40 -400 {
+lab=#net1}
+N -170 -470 -170 -400 {
+lab=#net1}
+N -295 -400 -170 -400 {
+lab=#net1}
+N -295 -470 -295 -400 {
+lab=#net1}
+N -510 -400 -295 -400 {
+lab=#net1}
+N 390 120 390 225 {
+lab=ground}
+N 300 120 390 120 {
+lab=ground}
+N 905 -130 1120 -130 {
+lab=out}
+N 905 -285 905 -130 {
+lab=out}
+N -590 -110 -515 -110 {
+lab=in}
+N 825 -605 825 -540 {
+lab=supply}
+N 760 -540 825 -540 {
+lab=supply}
+C {sg13g2_pr/sg13_hv_nmos.sym} -160 40 0 0 {name=M1
+l=9.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -50 40 0 0 {name=M2
+l=9.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 60 40 0 0 {name=M3
+l=9.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 160 40 0 0 {name=M4
+l=9.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -300 40 0 0 {name=M5
+l=9.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 280 40 0 0 {name=M6
+l=9.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -420 50 0 0 {name=M7
+l=9.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -170 -120 0 0 {name=M8
+l=9.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -60 -120 0 0 {name=M9
+l=9.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 50 -120 0 0 {name=M10
+l=9.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 150 -120 0 0 {name=M11
+l=9.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -310 -120 0 0 {name=M12
+l=9.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 270 -120 0 0 {name=M13
+l=9.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} -430 -110 0 0 {name=M14
+l=9.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 445 50 0 0 {name=M15
+l=0.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 570 50 0 0 {name=M16
+l=0.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 690 50 0 0 {name=M17
+l=0.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 815 50 0 0 {name=M18
+l=0.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 960 50 0 0 {name=M19
+l=0.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1110 50 0 0 {name=M20
+l=0.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1245 50 0 0 {name=M21
+l=0.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1365 50 0 0 {name=M22
+l=0.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1490 50 0 0 {name=M23
+l=0.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1620 50 0 0 {name=M24
+l=0.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1760 50 0 0 {name=M25
+l=0.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_nmos.sym} 1905 50 0 0 {name=M26
+l=0.5u
+w=9.0u
+ng=1
+m=1
+model=sg13_hv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} -20 -470 0 0 {name=M27
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 100 -470 0 0 {name=M28
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 240 -470 0 0 {name=M29
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 360 -470 0 0 {name=M30
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 480 -470 0 0 {name=M31
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 600 -470 0 0 {name=M32
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} -150 -470 0 0 {name=M33
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} -275 -470 0 0 {name=M34
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} -415 -470 0 0 {name=M35
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 740 -470 0 0 {name=M36
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1250 -470 0 0 {name=M37
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1370 -470 0 0 {name=M38
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1510 -470 0 0 {name=M39
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1630 -470 0 0 {name=M40
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1750 -470 0 0 {name=M41
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1870 -470 0 0 {name=M42
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1120 -470 0 0 {name=M43
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 995 -470 0 0 {name=M44
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 855 -470 0 0 {name=M45
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2010 -470 0 0 {name=M46
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2135 -470 0 0 {name=M47
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2255 -470 0 0 {name=M48
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2375 -470 0 0 {name=M49
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2495 -470 0 0 {name=M50
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2635 -470 0 0 {name=M51
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} -25 -340 0 0 {name=M52
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 95 -340 0 0 {name=M53
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 235 -340 0 0 {name=M54
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 355 -340 0 0 {name=M55
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 475 -340 0 0 {name=M56
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 595 -340 0 0 {name=M57
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} -155 -340 0 0 {name=M58
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} -280 -340 0 0 {name=M59
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} -420 -340 0 0 {name=M60
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 735 -340 0 0 {name=M61
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1245 -340 0 0 {name=M62
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1365 -340 0 0 {name=M63
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1505 -340 0 0 {name=M64
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1625 -340 0 0 {name=M65
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1745 -340 0 0 {name=M66
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1865 -340 0 0 {name=M67
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 1115 -340 0 0 {name=M68
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 990 -340 0 0 {name=M69
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 850 -340 0 0 {name=M70
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2005 -340 0 0 {name=M71
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2130 -340 0 0 {name=M72
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2250 -340 0 0 {name=M73
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2370 -340 0 0 {name=M74
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2490 -340 0 0 {name=M75
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_hv_pmos.sym} 2630 -340 0 0 {name=M76
+l=0.5u
+w=7.0u
+ng=1
+m=1
+model=sg13_hv_pmos
+spiceprefix=X
+}
+C {devices/iopin.sym} 825 -605 3 0 {name=supply lab=supply}
+C {devices/iopin.sym} 390 225 1 0 {name=ground lab=ground}
+C {devices/opin.sym} 1120 -130 0 0 {name=out lab=out}
+C {devices/ipin.sym} -585 -110 0 0 {name=in lab=in}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_RCClampInverter.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_RCClampInverter.sym
new file mode 100644
index 00000000..24cf1503
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_RCClampInverter.sym
@@ -0,0 +1,29 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -130 -30 130 -30 {}
+L 4 -130 30 130 30 {}
+L 4 -130 -30 -130 30 {}
+L 4 130 -30 130 30 {}
+L 4 130 0 150 0 {}
+L 4 -150 0 -130 0 {}
+L 7 10 -50 10 -30 {}
+L 7 10 30 10 50 {}
+B 5 7.5 -52.5 12.5 -47.5 {name=supply dir=inout}
+B 5 147.5 -2.5 152.5 2.5 {name=out dir=out}
+B 5 -152.5 -2.5 -147.5 2.5 {name=in dir=in}
+B 5 7.5 47.5 12.5 52.5 {name=ground dir=inout}
+T {sg13g2_RCClampInverter
+} -67 -6 0 0 0.2 0.2 {}
+T {@name} 135 -42 0 0 0.2 0.2 {}
+T {supply} 45 -44 0 1 0.2 0.2 {}
+T {out} 125 -4 0 1 0.2 0.2 {}
+T {in} -145 -14 0 0 0.2 0.2 {}
+T {ground} 55 36 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_RCClampResistor.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_RCClampResistor.sch
new file mode 100644
index 00000000..290347e1
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_RCClampResistor.sch
@@ -0,0 +1,273 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N -690 -270 -690 -220 {
+lab=pin1}
+N -690 -380 -690 -330 {
+lab=#net1}
+N -690 -490 -690 -440 {
+lab=#net2}
+N -690 -600 -690 -550 {
+lab=#net3}
+N -690 -660 -510 -660 {
+lab=#net4}
+N -510 -600 -510 -550 {
+lab=#net5}
+N -510 -490 -510 -440 {
+lab=#net6}
+N -510 -380 -510 -330 {
+lab=#net7}
+N -510 -270 -330 -270 {
+lab=#net8}
+N -330 -380 -330 -330 {
+lab=#net9}
+N -330 -490 -330 -440 {
+lab=#net10}
+N -330 -600 -330 -550 {
+lab=#net11}
+N -330 -660 -180 -660 {
+lab=#net12}
+N -180 -600 -180 -550 {
+lab=#net13}
+N -180 -490 -180 -440 {
+lab=#net14}
+N -180 -380 -180 -330 {
+lab=#net15}
+N -180 -270 -20 -270 {
+lab=#net16}
+N -20 -380 -20 -330 {
+lab=#net17}
+N -20 -490 -20 -440 {
+lab=#net18}
+N -20 -600 -20 -550 {
+lab=#net19}
+N -20 -660 150 -660 {
+lab=#net20}
+N 150 -660 150 -650 {
+lab=#net20}
+N 150 -590 150 -540 {
+lab=#net21}
+N 150 -480 150 -430 {
+lab=#net22}
+N 150 -370 150 -320 {
+lab=#net23}
+N 150 -260 310 -260 {
+lab=#net24}
+N 310 -360 310 -320 {
+lab=#net25}
+N 310 -460 310 -420 {
+lab=xxx}
+C {sg13g2_pr/rppd.sym} -690 -300 0 0 {name=R1
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/rppd.sym} -690 -410 0 0 {name=R2
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/rppd.sym} -690 -520 0 0 {name=R3
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/rppd.sym} -690 -630 0 0 {name=R4
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/rppd.sym} -510 -300 0 0 {name=R5
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/rppd.sym} -510 -410 0 0 {name=R6
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/rppd.sym} -510 -520 0 0 {name=R7
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/rppd.sym} -510 -630 0 0 {name=R8
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/rppd.sym} -330 -300 0 0 {name=R9
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/rppd.sym} -330 -410 0 0 {name=R10
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/rppd.sym} -330 -520 0 0 {name=R11
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/rppd.sym} -330 -630 0 0 {name=R12
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/rppd.sym} -180 -300 0 0 {name=R13
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/rppd.sym} -180 -410 0 0 {name=R14
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/rppd.sym} -180 -520 0 0 {name=R15
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/rppd.sym} -180 -630 0 0 {name=R16
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/rppd.sym} -20 -300 0 0 {name=R17
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/rppd.sym} -20 -410 0 0 {name=R18
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/rppd.sym} -20 -520 0 0 {name=R19
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/rppd.sym} -20 -630 0 0 {name=R20
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/rppd.sym} 150 -290 0 0 {name=R21
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/rppd.sym} 150 -400 0 0 {name=R22
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/rppd.sym} 150 -510 0 0 {name=R23
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/rppd.sym} 150 -620 0 0 {name=R24
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/rppd.sym} 310 -290 0 0 {name=R25
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/rppd.sym} 310 -390 0 0 {name=R26
+w=1.0e-6
+l=20.0e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {devices/iopin.sym} -690 -220 0 0 {name=pin1 lab=pin1}
+C {devices/iopin.sym} 310 -460 0 0 {name=pin2 lab=pin2}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_RCClampResistor.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_RCClampResistor.sym
new file mode 100644
index 00000000..601d7702
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_RCClampResistor.sym
@@ -0,0 +1,17 @@
+v {xschem version=3.4.4 file_version=1.2}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+T {@symname} -117 -6 0 0 0.3 0.3 {}
+T {@name} 135 -32 0 0 0.2 0.2 {}
+L 4 -130 -20 130 -20 {}
+L 4 -130 20 130 20 {}
+L 4 -130 -20 -130 20 {}
+L 4 130 -20 130 20 {}
+B 5 147.5 -12.5 152.5 -7.5 {name=pin2 dir=inout}
+L 7 130 -10 150 -10 {}
+T {pin2} 125 -14 0 1 0.2 0.2 {}
+B 5 147.5 7.5 152.5 12.5 {name=pin1 dir=inout}
+L 7 130 10 150 10 {}
+T {pin1} 125 6 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_SecondaryProtection.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_SecondaryProtection.sch
new file mode 100644
index 00000000..cb046982
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_SecondaryProtection.sch
@@ -0,0 +1,47 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 0 10 -0 30 {
+lab=core}
+N 0 90 -0 130 {
+lab=iovss}
+N 0 -140 0 -90 {
+lab=iovdd}
+N -60 0 0 -0 {
+lab=core}
+N -0 -30 0 -0 {
+lab=core}
+N -180 0 -120 -0 {
+lab=xxx}
+N 0 10 120 10 {
+lab=core}
+N 0 -0 0 10 {
+lab=core}
+C {sg13g2_pr/rppd.sym} -90 0 1 1 {name=R1
+w=1e-6
+l=2e-6
+model=rppd
+spiceprefix=X
+b=0
+m=1
+}
+C {sg13g2_pr/dantenna.sym} 0 60 0 0 {name=D1
+model=dantenna
+l=3.1u
+w=0.64u
+spiceprefix=X
+}
+C {sg13g2_pr/dpantenna.sym} 0 -60 0 0 {name=D2
+model=dpantenna
+l=0.64u
+w=4.98u
+spiceprefix=X
+}
+C {devices/iopin.sym} 0 -140 0 0 {name=iovdd lab=iovdd}
+C {devices/iopin.sym} 0 130 0 0 {name=iovss lab=iovss}
+C {devices/iopin.sym} 120 10 0 0 {name=core lab=core}
+C {devices/iopin.sym} -180 0 0 0 {name=pad lab=pad}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_SecondaryProtection.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_SecondaryProtection.sym
new file mode 100644
index 00000000..f89bf341
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_SecondaryProtection.sym
@@ -0,0 +1,25 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+L 4 -130 -40 130 -40 {}
+L 4 -130 40 130 40 {}
+L 4 -130 -40 -130 40 {}
+L 4 130 -40 130 40 {}
+L 7 10 -60 10 -40 {}
+L 7 -150 0 -130 0 {}
+L 7 130 10 150 10 {}
+L 7 10 40 10 60 {}
+B 5 7.5 -62.5 12.5 -57.5 {name=iovdd dir=inout}
+B 5 -152.5 -2.5 -147.5 2.5 {name=pad dir=inout}
+B 5 147.5 7.5 152.5 12.5 {name=core dir=inout}
+B 5 7.5 57.5 12.5 62.5 {name=iovss dir=inout}
+T {sg13g2_SecondaryProtection} -55 -6 0 0 0.2 0.2 {}
+T {@name} 135 -52 0 0 0.2 0.2 {}
+T {iovdd} 45 -54 0 1 0.2 0.2 {}
+T {pad} -135 -14 0 1 0.2 0.2 {}
+T {core} 125 6 0 1 0.2 0.2 {}
+T {iovss} 45 46 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_inv_x1.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_inv_x1.sch
new file mode 100644
index 00000000..6d9d1ce1
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_inv_x1.sch
@@ -0,0 +1,63 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 160 -190 160 -170 {
+lab=vdd}
+N 160 -140 220 -140 {
+lab=vdd}
+N 220 -190 220 -140 {
+lab=vdd}
+N 160 -190 220 -190 {
+lab=vdd}
+N 160 -220 160 -190 {
+lab=vdd}
+N 80 -140 120 -140 {
+lab=i}
+N 80 -90 80 -40 {
+lab=i}
+N 40 -90 80 -90 {
+lab=i}
+N 80 -140 80 -90 {
+lab=i}
+N 160 -90 160 -70 {
+lab=nq}
+N 160 20 160 50 {
+lab=vss}
+N 160 -40 210 -40 {
+lab=vss}
+N 210 -40 210 20 {
+lab=vss}
+N 160 20 210 20 {
+lab=vss}
+N 160 -10 160 20 {
+lab=vss}
+N 80 -40 120 -40 {
+lab=i}
+N 160 -90 260 -90 {
+lab=nq}
+N 160 -110 160 -90 {
+lab=nq}
+C {sg13g2_pr/sg13_lv_pmos.sym} 140 -140 0 0 {name=M2
+l=0.13u
+w=4.41u
+ng=1
+m=1
+model=sg13_lv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_lv_nmos.sym} 140 -40 2 1 {name=M1
+l=0.13u
+w=3.93u
+ng=1
+m=1
+model=sg13_lv_nmos
+spiceprefix=X
+}
+C {devices/ipin.sym} 40 -90 0 0 {name=i lab=i}
+C {devices/iopin.sym} 160 -220 0 0 {name=vdd lab=vdd}
+C {devices/iopin.sym} 160 50 0 0 {name=vss lab=vss}
+C {devices/opin.sym} 260 -90 0 0 {name=nq lab=nq}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_inv_x1.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_inv_x1.sym
new file mode 100644
index 00000000..7353113f
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_inv_x1.sym
@@ -0,0 +1,28 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -150 0 -130 0 {}
+L 4 70 0 90 0 {}
+L 4 -130 -60 -130 50 {}
+L 4 -130 50 50 0 {}
+L 4 -130 -60 50 0 {}
+L 7 -40 -50 -40 -30 {}
+L 7 -40 20 -40 40 {}
+B 5 -42.5 -52.5 -37.5 -47.5 {name=vdd dir=inout}
+B 5 -152.5 -2.5 -147.5 2.5 {name=i dir=in}
+B 5 87.5 -2.5 92.5 2.5 {name=nq dir=out}
+B 5 -42.5 37.5 -37.5 42.5 {name=vss dir=inout}
+A 4 62.5 0 12.5 306.869897645844 360 {}
+T {sg13g2_io_inv_x1} -100 -6 0 0 0.2 0.2 {}
+T {@name} 5 -32 0 0 0.2 0.2 {}
+T {vdd} -15 -44 0 1 0.2 0.2 {}
+T {i} -145 6 0 0 0.2 0.2 {}
+T {nq} 95 6 0 1 0.2 0.2 {}
+T {vss} -15 26 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_nand2_x1.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_nand2_x1.sch
new file mode 100644
index 00000000..a7027ec5
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_nand2_x1.sch
@@ -0,0 +1,130 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N -20 -160 -20 -110 {
+lab=xxx}
+N 60 -110 190 -110 {
+lab=xxx}
+N 190 -160 190 -110 {
+lab=xxx}
+N 60 -90 60 -70 {
+lab=xxx}
+N -20 -110 60 -110 {
+lab=xxx}
+N 60 -10 60 40 {
+lab=#net1}
+N -20 -250 -20 -220 {
+lab=vdd}
+N 70 -280 190 -280 {
+lab=vdd}
+N 190 -240 190 -220 {
+lab=vdd}
+N 70 -340 70 -280 {
+lab=vdd}
+N -20 -280 70 -280 {
+lab=vdd}
+N 60 120 60 160 {
+lab=vss}
+N -30 -40 20 -40 {
+lab=i1}
+N -130 -190 -60 -190 {
+lab=i0}
+N 90 -190 150 -190 {
+lab=i1}
+N -20 -190 30 -190 {
+lab=vdd}
+N 30 -250 30 -190 {
+lab=vdd}
+N -20 -250 30 -250 {
+lab=vdd}
+N -20 -280 -20 -250 {
+lab=vdd}
+N 190 -190 240 -190 {
+lab=vdd}
+N 240 -240 240 -190 {
+lab=vdd}
+N 190 -240 240 -240 {
+lab=vdd}
+N 190 -280 190 -240 {
+lab=vdd}
+N 60 70 120 70 {
+lab=vss}
+N 120 70 120 120 {
+lab=vss}
+N 60 120 120 120 {
+lab=vss}
+N 60 100 60 120 {
+lab=vss}
+N 60 -40 150 -40 {
+lab=vss}
+N 150 -40 150 120 {
+lab=vss}
+N 120 120 150 120 {
+lab=vss}
+N -130 70 20 70 {
+lab=i0}
+N -130 -190 -130 70 {
+lab=i0}
+N -180 70 -130 70 {
+lab=i0}
+N -30 -130 -30 -40 {
+lab=i1}
+N -60 -40 -30 -40 {
+lab=i1}
+N -30 -130 90 -130 {
+lab=i1}
+N 90 -190 90 -130 {
+lab=i1}
+N 60 -90 300 -90 {
+lab=xxx}
+N 60 -110 60 -90 {
+lab=xxx}
+C {sg13g2_pr/sg13_lv_nmos.sym} 40 -40 2 1 {name=M1
+l=0.13u
+w=3.93u
+ng=1
+m=1
+model=sg13_lv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_lv_pmos.sym} 170 -190 0 0 {name=M2
+l=0.13u
+w=4.41u
+ng=1
+m=1
+model=sg13_lv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_lv_nmos.sym} 40 -40 2 1 {name=M3
+l=0.13u
+w=3.93u
+ng=1
+m=1
+model=sg13_lv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_lv_nmos.sym} 40 70 2 1 {name=M4
+l=0.13u
+w=3.93u
+ng=1
+m=1
+model=sg13_lv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_lv_pmos.sym} -40 -190 0 0 {name=M5
+l=0.13u
+w=4.41u
+ng=1
+m=1
+model=sg13_lv_pmos
+spiceprefix=X
+}
+C {devices/iopin.sym} 70 -340 0 0 {name=vdd lab=vdd}
+C {devices/iopin.sym} 60 160 0 0 {name=vss lab=vss}
+C {devices/ipin.sym} -180 70 0 0 {name=i0 lab=i0}
+C {devices/ipin.sym} -60 -40 0 0 {name=i1 lab=i1}
+C {devices/opin.sym} 300 -90 0 0 {name=nq lab=nq}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_nand2_x1.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_nand2_x1.sym
new file mode 100644
index 00000000..0c73e032
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_nand2_x1.sym
@@ -0,0 +1,32 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 70 0 90 0 {}
+L 4 -150 -20 -130 -20 {}
+L 4 -150 20 -130 20 {}
+L 4 -130 -60 -130 60 {}
+L 4 -130 -60 -0 -60 {}
+L 4 -130 60 -0 60 {}
+L 7 -50 -80 -50 -60 {}
+L 7 -50 60 -50 80 {}
+B 5 -52.5 -82.5 -47.5 -77.5 {name=vdd dir=inout}
+B 5 87.5 -2.5 92.5 2.5 {name=nq dir=out}
+B 5 -152.5 -22.5 -147.5 -17.5 {name=i1 dir=in}
+B 5 -152.5 17.5 -147.5 22.5 {name=i0 dir=in}
+B 5 -52.5 77.5 -47.5 82.5 {name=vss dir=inout}
+A 4 -10 0 60.8276253029822 279.4623222080256 161.0753555839487 {}
+A 4 60 -0 10 180 360 {}
+T {sg13g2_io_nand2_x1} -119 -6 0 0 0.3 0.3 {}
+T {@name} 35 -62 0 0 0.2 0.2 {}
+T {vdd} -25 -74 0 1 0.2 0.2 {}
+T {nq} 85 6 0 1 0.2 0.2 {}
+T {i1} -145 -34 0 0 0.2 0.2 {}
+T {i0} -145 6 0 0 0.2 0.2 {}
+T {vss} -25 66 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_nor2_x1.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_nor2_x1.sch
new file mode 100644
index 00000000..4f165523
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_nor2_x1.sch
@@ -0,0 +1,118 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 40 -120 40 -90 {
+lab=#net1}
+N -30 0 -30 20 {
+lab=nq}
+N 40 0 120 0 {
+lab=nq}
+N -30 90 -30 110 {
+lab=vss}
+N 40 110 120 110 {
+lab=vss}
+N 120 100 120 110 {
+lab=vss}
+N 40 -20 40 0 {
+lab=nq}
+N -30 0 40 0 {
+lab=nq}
+N 40 -200 40 -180 {
+lab=vdd}
+N 40 -150 100 -150 {
+lab=vdd}
+N 100 -200 100 -150 {
+lab=vdd}
+N 40 -200 100 -200 {
+lab=vdd}
+N 40 -230 40 -200 {
+lab=vdd}
+N 40 -60 120 -60 {
+lab=vdd}
+N 120 -200 120 -60 {
+lab=vdd}
+N 100 -200 120 -200 {
+lab=vdd}
+N 40 110 40 160 {
+lab=vss}
+N -30 110 40 110 {
+lab=vss}
+N -30 -60 -0 -60 {
+lab=i0}
+N -110 50 -70 50 {
+lab=i1}
+N -30 50 0 50 {
+lab=vss}
+N 0 50 -0 90 {
+lab=vss}
+N -30 90 -0 90 {
+lab=vss}
+N -30 80 -30 90 {
+lab=vss}
+N 120 50 150 50 {
+lab=vss}
+N 120 100 150 100 {
+lab=vss}
+N 40 -20 210 -20 {
+lab=nq}
+N 40 -30 40 -20 {
+lab=nq}
+N 120 80 120 100 {
+lab=vss}
+N 120 0 120 20 {
+lab=nq}
+N 150 50 150 100 {
+lab=vss}
+N -110 -150 -0 -150 {
+lab=i1}
+N -110 -150 -110 50 {
+lab=i1}
+N -120 50 -110 50 {
+lab=i1}
+N -30 -60 -30 -10 {}
+N -50 -60 -30 -60 {
+lab=i0}
+N -30 -10 30 -10 {}
+N 30 -10 30 50 {}
+N 30 50 80 50 {}
+C {sg13g2_pr/sg13_lv_nmos.sym} -50 50 2 1 {name=M1
+l=0.13u
+w=3.93u
+ng=1
+m=1
+model=sg13_lv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_lv_pmos.sym} 20 -150 0 0 {name=M2
+l=0.13u
+w=4.41u
+ng=1
+m=1
+model=sg13_lv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_lv_nmos.sym} 100 50 2 1 {name=M3
+l=0.13u
+w=3.93u
+ng=1
+m=1
+model=sg13_lv_nmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_lv_pmos.sym} 20 -60 0 0 {name=M4
+l=0.13u
+w=4.41u
+ng=1
+m=1
+model=sg13_lv_pmos
+spiceprefix=X
+}
+C {devices/iopin.sym} 40 160 0 0 {name=vss lab=vss}
+C {devices/iopin.sym} 40 -230 0 0 {name=vdd lab=vdd}
+C {devices/ipin.sym} -50 -60 0 0 {name=i0 lab=i0}
+C {devices/ipin.sym} -120 50 0 0 {name=i2 lab=i1}
+C {devices/opin.sym} 210 -20 0 0 {name=nq lab=nq}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_nor2_x1.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_nor2_x1.sym
new file mode 100644
index 00000000..fdb8c24d
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_nor2_x1.sym
@@ -0,0 +1,33 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+V {}
+S {}
+E {}
+L 4 -140 10 -120 10 {}
+L 4 20 0 40 0 {}
+L 4 -140 -10 -120 -10 {}
+L 4 -130 -40 -70 -40 {}
+L 4 -130 40 -70 40 {}
+L 7 -90 -60 -90 -40 {}
+L 7 -90 40 -90 60 {}
+B 5 -92.5 -62.5 -87.5 -57.5 {name=vdd dir=inout}
+B 5 -142.5 7.5 -137.5 12.5 {name=i0 dir=in}
+B 5 37.5 -2.5 42.5 2.5 {name=nq dir=out}
+B 5 -142.5 -12.5 -137.5 -7.5 {name=i1 dir=in}
+B 5 -92.5 57.5 -87.5 62.5 {name=vss dir=inout}
+A 4 -185 0 68.00735254367721 323.9726266148964 72.0547467702072 {}
+A 4 -95 85 127.4754878398196 41.82016988013577 36.86989764584401 {}
+A 4 -195 -260 325 292.6198649480405 14.25003269780359 {}
+A 4 10 0 10 270 360 {}
+T {sg13g2_io_nor2_x1} -114.5 -6 0 0 0.2 0.2 {}
+T {@name} -25 -42 0 0 0.2 0.2 {}
+T {vdd} -55 -64 0 1 0.2 0.2 {}
+T {i0} -135 16 0 0 0.2 0.2 {}
+T {nq} 35 6 0 1 0.2 0.2 {}
+T {i1} -135 -24 0 0 0.2 0.2 {}
+T {vss} -65 46 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_tie.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_tie.sch
new file mode 100644
index 00000000..4ccb95d6
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_tie.sch
@@ -0,0 +1,13 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 40 -60 40 -40 {
+lab=vdd}
+N 40 -20 40 10 {
+lab=xxx}
+C {devices/iopin.sym} 40 -60 0 0 {name=vdd lab=vdd}
+C {devices/iopin.sym} 40 10 0 0 {name=vss lab=vss}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_tie.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_tie.sym
new file mode 100644
index 00000000..f5aeb8e5
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_io_tie.sym
@@ -0,0 +1,17 @@
+v {xschem version=3.4.4 file_version=1.2}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+T {@symname} -76.5 -6 0 0 0.3 0.3 {}
+T {@name} 135 -32 0 0 0.2 0.2 {}
+L 4 -130 -20 130 -20 {}
+L 4 -130 20 130 20 {}
+L 4 -130 -20 -130 20 {}
+L 4 130 -20 130 20 {}
+B 5 147.5 -12.5 152.5 -7.5 {name=vdd dir=inout}
+L 7 130 -10 150 -10 {}
+T {vdd} 125 -14 0 1 0.2 0.2 {}
+B 5 147.5 7.5 152.5 12.5 {name=vss dir=inout}
+L 7 130 10 150 10 {}
+T {vss} 125 6 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_ioinv_x1.kicad_prl b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_ioinv_x1.kicad_prl
new file mode 100644
index 00000000..cd3b99ae
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_ioinv_x1.kicad_prl
@@ -0,0 +1,75 @@
+{
+ "board": {
+ "active_layer": 0,
+ "active_layer_preset": "",
+ "auto_track_width": true,
+ "hidden_nets": [],
+ "high_contrast_mode": 0,
+ "net_color_mode": 1,
+ "opacity": {
+ "pads": 1.0,
+ "tracks": 1.0,
+ "vias": 1.0,
+ "zones": 0.6
+ },
+ "ratsnest_display_mode": 0,
+ "selection_filter": {
+ "dimensions": true,
+ "footprints": true,
+ "graphics": true,
+ "keepouts": true,
+ "lockedItems": true,
+ "otherItems": true,
+ "pads": true,
+ "text": true,
+ "tracks": true,
+ "vias": true,
+ "zones": true
+ },
+ "visible_items": [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 8,
+ 9,
+ 10,
+ 11,
+ 12,
+ 13,
+ 14,
+ 15,
+ 16,
+ 17,
+ 18,
+ 19,
+ 20,
+ 21,
+ 22,
+ 23,
+ 24,
+ 25,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 32,
+ 33,
+ 34,
+ 35,
+ 36
+ ],
+ "visible_layers": "fffffff_ffffffff",
+ "zone_display_mode": 0
+ },
+ "meta": {
+ "filename": "sg13g2_ioinv_x1.kicad_prl",
+ "version": 3
+ },
+ "project": {
+ "files": []
+ }
+}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_ioinv_x1.kicad_pro b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_ioinv_x1.kicad_pro
new file mode 100644
index 00000000..1c17326e
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_ioinv_x1.kicad_pro
@@ -0,0 +1,298 @@
+{
+ "board": {
+ "layer_presets": []
+ },
+ "boards": [],
+ "cvpcb": {
+ "equivalence_files": []
+ },
+ "erc": {
+ "erc_exclusions": [],
+ "meta": {
+ "version": 0
+ },
+ "pin_map": [
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2
+ ],
+ [
+ 0,
+ 2,
+ 0,
+ 1,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 2,
+ 2,
+ 2
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 2
+ ],
+ [
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 1,
+ 2,
+ 1,
+ 1,
+ 2
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2
+ ],
+ [
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 2
+ ],
+ [
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2
+ ],
+ [
+ 0,
+ 2,
+ 1,
+ 2,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 2,
+ 2,
+ 2
+ ],
+ [
+ 0,
+ 2,
+ 0,
+ 1,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 0,
+ 0,
+ 2
+ ],
+ [
+ 0,
+ 2,
+ 1,
+ 1,
+ 0,
+ 0,
+ 1,
+ 0,
+ 2,
+ 0,
+ 0,
+ 2
+ ],
+ [
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2
+ ]
+ ],
+ "rule_severities": {
+ "bus_definition_conflict": "error",
+ "bus_entry_needed": "error",
+ "bus_label_syntax": "error",
+ "bus_to_bus_conflict": "error",
+ "bus_to_net_conflict": "error",
+ "different_unit_footprint": "error",
+ "different_unit_net": "error",
+ "duplicate_reference": "error",
+ "duplicate_sheet_names": "error",
+ "extra_units": "error",
+ "global_label_dangling": "warning",
+ "hier_label_mismatch": "error",
+ "label_dangling": "error",
+ "lib_symbol_issues": "warning",
+ "multiple_net_names": "warning",
+ "net_not_bus_member": "warning",
+ "no_connect_connected": "warning",
+ "no_connect_dangling": "warning",
+ "pin_not_connected": "error",
+ "pin_not_driven": "error",
+ "pin_to_pin": "warning",
+ "power_pin_not_driven": "error",
+ "similar_labels": "warning",
+ "unannotated": "error",
+ "unit_value_mismatch": "error",
+ "unresolved_variable": "error",
+ "wire_dangling": "error"
+ }
+ },
+ "libraries": {
+ "pinned_footprint_libs": [],
+ "pinned_symbol_libs": []
+ },
+ "meta": {
+ "filename": "sg13g2_ioinv_x1.kicad_pro",
+ "version": 1
+ },
+ "net_settings": {
+ "classes": [
+ {
+ "bus_width": 12.0,
+ "clearance": 0.2,
+ "diff_pair_gap": 0.25,
+ "diff_pair_via_gap": 0.25,
+ "diff_pair_width": 0.2,
+ "line_style": 0,
+ "microvia_diameter": 0.3,
+ "microvia_drill": 0.1,
+ "name": "Default",
+ "pcb_color": "rgba(0, 0, 0, 0.000)",
+ "schematic_color": "rgba(0, 0, 0, 0.000)",
+ "track_width": 0.25,
+ "via_diameter": 0.8,
+ "via_drill": 0.4,
+ "wire_width": 6.0
+ }
+ ],
+ "meta": {
+ "version": 2
+ },
+ "net_colors": null
+ },
+ "pcbnew": {
+ "last_paths": {
+ "gencad": "",
+ "idf": "",
+ "netlist": "",
+ "specctra_dsn": "",
+ "step": "",
+ "vrml": ""
+ },
+ "page_layout_descr_file": ""
+ },
+ "schematic": {
+ "annotate_start_num": 0,
+ "drawing": {
+ "default_line_thickness": 6.0,
+ "default_text_size": 50.0,
+ "field_names": [],
+ "intersheets_ref_own_page": false,
+ "intersheets_ref_prefix": "",
+ "intersheets_ref_short": false,
+ "intersheets_ref_show": false,
+ "intersheets_ref_suffix": "",
+ "junction_size_choice": 3,
+ "label_size_ratio": 0.375,
+ "pin_symbol_size": 25.0,
+ "text_offset_ratio": 0.15
+ },
+ "legacy_lib_dir": "",
+ "legacy_lib_list": [],
+ "meta": {
+ "version": 1
+ },
+ "net_format_name": "",
+ "ngspice": {
+ "fix_include_paths": true,
+ "fix_passive_vals": false,
+ "meta": {
+ "version": 0
+ },
+ "model_mode": 0,
+ "workbook_filename": ""
+ },
+ "page_layout_descr_file": "",
+ "plot_directory": "",
+ "spice_adjust_passive_values": false,
+ "spice_external_command": "spice \"%I\"",
+ "subpart_first_id": 65,
+ "subpart_id_separator": 0
+ },
+ "sheets": [],
+ "text_variables": {}
+}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_ioinv_x1.sch b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_ioinv_x1.sch
new file mode 100644
index 00000000..6d9d1ce1
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_ioinv_x1.sch
@@ -0,0 +1,63 @@
+v {xschem version=3.4.4 file_version=1.2
+}
+G {}
+K {}
+V {}
+S {}
+E {}
+N 160 -190 160 -170 {
+lab=vdd}
+N 160 -140 220 -140 {
+lab=vdd}
+N 220 -190 220 -140 {
+lab=vdd}
+N 160 -190 220 -190 {
+lab=vdd}
+N 160 -220 160 -190 {
+lab=vdd}
+N 80 -140 120 -140 {
+lab=i}
+N 80 -90 80 -40 {
+lab=i}
+N 40 -90 80 -90 {
+lab=i}
+N 80 -140 80 -90 {
+lab=i}
+N 160 -90 160 -70 {
+lab=nq}
+N 160 20 160 50 {
+lab=vss}
+N 160 -40 210 -40 {
+lab=vss}
+N 210 -40 210 20 {
+lab=vss}
+N 160 20 210 20 {
+lab=vss}
+N 160 -10 160 20 {
+lab=vss}
+N 80 -40 120 -40 {
+lab=i}
+N 160 -90 260 -90 {
+lab=nq}
+N 160 -110 160 -90 {
+lab=nq}
+C {sg13g2_pr/sg13_lv_pmos.sym} 140 -140 0 0 {name=M2
+l=0.13u
+w=4.41u
+ng=1
+m=1
+model=sg13_lv_pmos
+spiceprefix=X
+}
+C {sg13g2_pr/sg13_lv_nmos.sym} 140 -40 2 1 {name=M1
+l=0.13u
+w=3.93u
+ng=1
+m=1
+model=sg13_lv_nmos
+spiceprefix=X
+}
+C {devices/ipin.sym} 40 -90 0 0 {name=i lab=i}
+C {devices/iopin.sym} 160 -220 0 0 {name=vdd lab=vdd}
+C {devices/iopin.sym} 160 50 0 0 {name=vss lab=vss}
+C {devices/opin.sym} 260 -90 0 0 {name=nq lab=nq}
diff --git a/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_ioinv_x1.sym b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_ioinv_x1.sym
new file mode 100644
index 00000000..f7e5b2f6
--- /dev/null
+++ b/ihp-sg13g2/libs.ref/sg13g2_io/xschem/sg13g2_ioinv_x1.sym
@@ -0,0 +1,23 @@
+v {xschem version=3.4.4 file_version=1.2}
+K {type=subcircuit
+format="@name @pinlist @symname"
+template="name=x1"
+}
+T {@symname} -85.5 -6 0 0 0.3 0.3 {}
+T {@name} 135 -42 0 0 0.2 0.2 {}
+L 4 -130 -30 130 -30 {}
+L 4 -130 30 130 30 {}
+L 4 -130 -30 -130 30 {}
+L 4 130 -30 130 30 {}
+B 5 147.5 -22.5 152.5 -17.5 {name=vdd dir=inout}
+L 7 130 -20 150 -20 {}
+T {vdd} 125 -24 0 1 0.2 0.2 {}
+B 5 -152.5 -22.5 -147.5 -17.5 {name=i dir=in}
+L 4 -150 -20 -130 -20 {}
+T {i} -125 -24 0 0 0.2 0.2 {}
+B 5 147.5 -2.5 152.5 2.5 {name=nq dir=out}
+L 4 130 0 150 0 {}
+T {nq} 125 -4 0 1 0.2 0.2 {}
+B 5 147.5 17.5 152.5 22.5 {name=vss dir=inout}
+L 7 130 20 150 20 {}
+T {vss} 125 16 0 1 0.2 0.2 {}
diff --git a/ihp-sg13g2/libs.tech/digital b/ihp-sg13g2/libs.tech/digital
new file mode 160000
index 00000000..9a6e7c9d
--- /dev/null
+++ b/ihp-sg13g2/libs.tech/digital
@@ -0,0 +1 @@
+Subproject commit 9a6e7c9d404f9f4334513a24788aa8454918d400
diff --git a/ihp-sg13g2/libs.tech/klayout/python/cni/box.py b/ihp-sg13g2/libs.tech/klayout/python/cni/box.py
index cc596e19..69df6a67 100644
--- a/ihp-sg13g2/libs.tech/klayout/python/cni/box.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/cni/box.py
@@ -29,40 +29,40 @@ class Box(object):
def __init__(self, l = INT_MAX, b = INT_MAX, r = INT_MIN, t = INT_MIN):
self.box = pya.DBox(l, b, r, t)
- def abut(dir, refBox, align = True):
+ def abut(self, dir, refBox, align = True):
raise Exception("Not implemented yet!")
- def alignEdge(dir, refBox, refDir=None, offset=None):
+ def alignEdge(self, dir, refBox, refDir=None, offset=None):
raise Exception("Not implemented yet!")
- def alignEdgeToCoord(dir, coord):
+ def alignEdgeToCoord(self, dir, coord):
raise Exception("Not implemented yet!")
- def alignEdgeToPoint(dir, point):
+ def alignEdgeToPoint(self, dir, point):
raise Exception("Not implemented yet!")
- def alignLocation(loc, refBox, refLoc=None, offset=None):
+ def alignLocation(self, loc, refBox, refLoc=None, offset=None):
raise Exception("Not implemented yet!")
- def alignLocationToPoint(loc, pt):
+ def alignLocationToPoint(self, loc, pt):
raise Exception("Not implemented yet!")
- def centerCenter():
+ def centerCenter(self):
raise Exception("Not implemented yet!")
- def centerLeft():
+ def centerLeft(self):
raise Exception("Not implemented yet!")
- def centerRight():
+ def centerRight(self):
raise Exception("Not implemented yet!")
def clone(self, nameMap : NameMapper = NameMapper(), netMap : NameMapper = NameMapper()):
return Box(self.box.left, self.box.bottom, self.box.right, self.box.top)
- def contains(box, incEdges = True):
+ def contains(self, box, incEdges = True):
raise Exception("Not implemented yet!")
- def containsPoint(p, incEdges = True):
+ def containsPoint(self, p, incEdges = True):
raise Exception("Not implemented yet!")
def destroy(self):
@@ -73,119 +73,126 @@ def destroy(self):
else:
pya.Logger.warn(f"Box.destroy: already destroyed!")
- def expand(coord):
+ def expand(self, coord):
raise Exception("Not implemented yet!")
- def expandDir(dir, coord):
+ def expandDir(self, dir, coord):
raise Exception("Not implemented yet!")
- def expandForMinArea(dir, minArea, grid = None):
+ def expandForMinArea(self, dir, minArea, grid = None):
raise Exception("Not implemented yet!")
- def expandForMinWidth(dir, minWidth, grid = None):
+ def expandForMinWidth(self, dir, minWidth, grid = None):
raise Exception("Not implemented yet!")
- def expandToGrid(grid, dir = None):
+ def expandToGrid(self, grid, dir = None):
raise Exception("Not implemented yet!")
def fix(self):
- # is that function supposed for normalize the order?
+ if self.box.left > self.box.right or self.box.bottom > self.box.top:
+ fixedBox = pya.DBox(
+ min(self.box.left, self.box.right),
+ min(self.box.bottom, self.box.top),
+ max(self.box.left, self.box.right),
+ max(self.box.bottom, self.box.top))
+ self.box.assign(fixedBox)
return self
- def getArea():
+ def getArea(self):
raise Exception("Not implemented yet!")
- def getCenter():
- raise Exception("Not implemented yet!")
+ def getCenter(self):
+ center = self.box.center()
+ return Point(center.x, center.y)
- def getCenterX():
+ def getCenterX(self):
raise Exception("Not implemented yet!")
- def getCenterY():
+ def getCenterY(self):
raise Exception("Not implemented yet!")
- def getCoord(dir):
+ def getCoord(self, dir):
raise Exception("Not implemented yet!")
- def getDimension(dir):
+ def getDimension(self, dir):
raise Exception("Not implemented yet!")
def getHeight(self):
return self.box.top - self.box.bottom
- def getLeft():
+ def getLeft(self):
raise Exception("Not implemented yet!")
- def getLocationPoint(loc):
+ def getLocationPoint(self, loc):
raise Exception("Not implemented yet!")
- def getLocationPoint(dir):
+ def getLocationPoint(self, dir):
raise Exception("Not implemented yet!")
- def getPoints():
+ def getPoints(self):
raise Exception("Not implemented yet!")
- def getRange(dir):
+ def getRange(self, dir):
raise Exception("Not implemented yet!")
- def getRangeX():
+ def getRangeX(self):
raise Exception("Not implemented yet!")
- def getRangeY():
+ def getRangeY(self):
raise Exception("Not implemented yet!")
- def getRight():
+ def getRight(self):
raise Exception("Not implemented yet!")
- def getSpacing(dir, refBox):
+ def getSpacing(self, dir, refBox):
raise Exception("Not implemented yet!")
- def getTop():
+ def getTop(self):
raise Exception("Not implemented yet!")
def getWidth(self):
return self.box.right - self.box.left
- def hasNoArea():
+ def hasNoArea(self):
raise Exception("Not implemented yet!")
- def init():
+ def init(self):
raise Exception("Not implemented yet!")
- def intersect(box):
+ def intersect(self, box):
raise Exception("Not implemented yet!")
- def intersect(box, dir):
+ def intersect(self, box, dir):
raise Exception("Not implemented yet!")
- def isInverted():
+ def isInverted(self):
raise Exception("Not implemented yet!")
- def isNormal():
+ def isNormal(self):
raise Exception("Not implemented yet!")
- def limit(point):
+ def limit(self, point):
raise Exception("Not implemented yet!")
- def lowerCenter():
+ def lowerCenter(self):
raise Exception("Not implemented yet!")
def lowerLeft(self):
return Point(self.box.left, self.box.bottom)
- def lowerRight():
+ def lowerRight(self):
raise Exception("Not implemented yet!")
- def merge(box, dir):
+ def merge(self, box, dir):
raise Exception("Not implemented yet!")
- def mergePoint(p):
+ def mergePoint(self, p):
raise Exception("Not implemented yet!")
- def mirrorX(yCoord = 0):
+ def mirrorX(self, yCoord = 0):
raise Exception("Not implemented yet!")
- def mirrorY(xCoord = 0):
+ def mirrorY(self, xCoord = 0):
raise Exception("Not implemented yet!")
def moveBy(self, dx: float, dy: float) -> None:
@@ -196,97 +203,97 @@ def moveBy(self, dx: float, dy: float) -> None:
self.__rect._shape = shape
self.box = movedBox
- def moveTo(destination, loc = Location.CENTER_CENTER):
+ def moveTo(self, destination, loc = Location.CENTER_CENTER):
raise Exception("Not implemented yet!")
- def moveTowards(dir, d):
+ def moveTowards(self, dir, d):
raise Exception("Not implemented yet!")
- def overlaps(box, incEdges = True):
+ def overlaps(self, box, incEdges = True):
raise Exception("Not implemented yet!")
- def place(dir, refBox, distance, align = True):
+ def place(self, dir, refBox, distance, align = True):
raise Exception("Not implemented yet!")
- def removeRegion(box):
+ def removeRegion(self, box):
raise Exception("Not implemented yet!")
- def rotate90(origin = None):
+ def rotate90(self, origin = None):
raise Exception("Not implemented yet!")
- def rotate180(origin = None):
+ def rotate180(self, origin = None):
raise Exception("Not implemented yet!")
- def rotate270(origin = None):
+ def rotate270(self, origin = None):
raise Exception("Not implemented yet!")
- def set(b):
+ def set(self, b):
raise Exception("Not implemented yet!")
- def set(b, dir = None):
+ def set(self, b, dir = None):
raise Exception("Not implemented yet!")
- def set(lowerLeft, upperRight):
+ def set(self, lowerLeft, upperRight):
raise Exception("Not implemented yet!")
- def set(left, bottom, right, top):
+ def set(self, left, bottom, right, top):
raise Exception("Not implemented yet!")
- def setBottom(v):
+ def setBottom(self, v):
raise Exception("Not implemented yet!")
- def setCenter(point):
+ def setCenter(self, point):
raise Exception("Not implemented yet!")
- def setCenterY(v):
+ def setCenterY(self, v):
raise Exception("Not implemented yet!")
- def setCoord(dir, coord):
+ def setCoord(self, dir, coord):
raise Exception("Not implemented yet!")
- def setDimension(coord, dir):
+ def setDimension(self, coord, dir):
raise Exception("Not implemented yet!")
- def setBottom(v):
+ def setBottom(self, v):
raise Exception("Not implemented yet!")
- def setHeight(height):
+ def setHeight(self, height):
raise Exception("Not implemented yet!")
- def setLocationPoint(loc, pt):
+ def setLocationPoint(self, loc, pt):
raise Exception("Not implemented yet!")
- def setRange(dir, range):
+ def setRange(self, dir, range):
raise Exception("Not implemented yet!")
- def setRangeX(range):
+ def setRangeX(self, range):
raise Exception("Not implemented yet!")
- def setRangeY(range):
+ def setRangeY(self, range):
raise Exception("Not implemented yet!")
def setRect(self, rect):
self.__rect = rect
- def setRight(v):
+ def setRight(self, v):
raise Exception("Not implemented yet!")
- def setTop(v):
+ def setTop(self, v):
raise Exception("Not implemented yet!")
- def setWidth(width):
+ def setWidth(self, width):
raise Exception("Not implemented yet!")
- def snap(grid, snapType = None):
+ def snap(self, grid, snapType = None):
raise Exception("Not implemented yet!")
- def snapX(grid, snapType = None):
+ def snapX(self, grid, snapType = None):
raise Exception("Not implemented yet!")
- def snapY(grid, snapType = None):
+ def snapY(self, grid, snapType = None):
raise Exception("Not implemented yet!")
- def snapTowards(grid, dir):
+ def snapTowards(self, grid, dir):
raise Exception("Not implemented yet!")
def transform(self, transform: Transform) -> None:
@@ -300,10 +307,10 @@ def transform(self, transform: Transform) -> None:
self.__rect._shape = shape
self.box = transformedBox
- def upperCenter():
+ def upperCenter(self):
raise Exception("Not implemented yet!")
- def upperLeft():
+ def upperLeft(self):
raise Exception("Not implemented yet!")
def upperRight(self):
diff --git a/ihp-sg13g2/libs.tech/klayout/python/cni/dlo.py b/ihp-sg13g2/libs.tech/klayout/python/cni/dlo.py
index feec0cf8..d97ee324 100644
--- a/ihp-sg13g2/libs.tech/klayout/python/cni/dlo.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/cni/dlo.py
@@ -37,6 +37,11 @@
from cni.transform import *
from cni.instance import *
from cni.paramarray import *
+from cni.pin import *
+from cni.term import *
+from cni.path import *
+from cni.shapefilter import *
+from cni.net import *
import pya
import sys
@@ -81,10 +86,11 @@ def getCurrentPyCellContext(cls) -> PyCellContext:
raise Exception("No current PyCellContext")
return cls._pyCellContexts[-1]
- def __init__(self, tech, cell):
+ def __init__(self, tech, cell, impl):
PyCellContext._pyCellContexts.append(self)
self._tech = tech
self._cell = cell
+ self._impl = impl
def __enter__(self):
Layer.layout = self._cell.layout()
@@ -94,6 +100,7 @@ def __exit__(self, *params):
Layer.layout = None
self._cell = None
self._tech = None
+ self._impl = None
@property
def cell(self):
@@ -113,14 +120,26 @@ def layout(self):
raise Exception("Layout not set!")
return self._cell.layout()
+ @property
+ def impl(self):
+ if self._impl is None:
+ raise Exception("Impl not set!")
+ return self._impl
+
+ @property
+ def cell(self):
+ if self._cell is None:
+ raise Exception("Cell not set!")
+ return self._cell
+
class PCellWrapper(pya.PCellDeclaration):
def __init__(self, impl, tech):
super(PCellWrapper, self).__init__()
- self.impl = impl
- self.impl.setTech(tech)
+ self._impl = impl
+ self._impl.setTech(tech)
self.tech = tech
Tech.techInUse = tech.getTechParams()['libName']
@@ -140,6 +159,8 @@ def __call__(self, name, value, description = None, constraint = None):
value_type = pya.PCellParameterDeclaration.TypeInt
elif type(value) is str:
value_type = pya.PCellParameterDeclaration.TypeString
+ elif type(value) is bool:
+ value_type = pya.PCellParameterDeclaration.TypeBoolean
else:
print(f"Invalid parameter type for parameter {name} (value is {repr(value)})")
assert(False)
@@ -175,8 +196,9 @@ def display_text(self, parameters):
def produce(self, layout, layers, parameters, cell):
params = self.params_as_hash(parameters)
- with (PyCellContext(self.tech, cell)):
- self.impl.setupParams(params)
- self.impl.genLayout()
+ with (PyCellContext(self.tech, cell, self._impl)):
+ self._impl.addCellContext(cell)
+ self._impl.setupParams(params)
+ self._impl.genLayout()
diff --git a/ihp-sg13g2/libs.tech/klayout/python/cni/dlogen.py b/ihp-sg13g2/libs.tech/klayout/python/cni/dlogen.py
index c1adabaf..a443f671 100644
--- a/ihp-sg13g2/libs.tech/klayout/python/cni/dlogen.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/cni/dlogen.py
@@ -17,15 +17,23 @@
########################################################################
from cni.rect import *
-from cni.dlo import *
from cni.grouping import *
+from cni.pin import *
+from cni.term import *
import pya
class Dlo(object):
+ class _CellContext:
+ def __init__(self):
+ self.pins = {}
+ self.terms = {}
+ self.nets = {}
+
+
def __init__(self, libName, cellName, viewName='layout', viewType=None):
- pass
+ self._cellContexts = {}
@classmethod
def exists(cls, dloName : str) -> bool:
@@ -80,12 +88,70 @@ def exists(cls, dloName : str) -> bool:
return True
+ def findPin(self, name: str) -> Pin:
+ cellContext = self._getCurrentCellContext()
+
+ if name == "":
+ if len(cellContext.pins) != 0:
+ return next(iter(cellContext.pins))
+ else:
+ raise Exception(f"No pins defined")
+ else:
+ if name in cellContext.pins:
+ return cellContext.pins[name]
+ else:
+ raise Exception(f"Pin '{name}' don't exists")
+
+
+ def hasPin(self, name: str) -> bool:
+ cellContext = self._getCurrentCellContext()
+ return name in cellContext.pins
+
+ def hasTerm(self, name: str) -> bool:
+ cellContext = self._getCurrentCellContext()
+ return name in cellContext.terms
+
+ def hasNet(self, name: str) -> bool:
+ cellContext = self._getCurrentCellContext()
+ return name in cellContext.nets
+
+ def findTerm(self, name: str) -> Term:
+ cellContext = self._getCurrentCellContext()
+
+ if name == "":
+ if len(cellContext.terms) != 0:
+ return next(iter(cellContext.terms))
+ else:
+ raise Exception(f"No terminals defined")
+ else:
+ if name in cellContext.terms:
+ return cellContext.terms[name]
+ else:
+ raise Exception(f"Terminal '{name}' don't exists")
+
+ def _getCurrentCellContext(self):
+ import cni.dlo
+ cell = cni.dlo.PyCellContext.getCurrentPyCellContext().cell
+ cellContext = self._cellContexts.get(cell)
+
+ if cellContext is None:
+ raise Exception("No current cell context")
+
+ return cellContext
+
+ def addCellContext(self, cell):
+ if cell in self._cellContexts:
+ self._cellContexts.pop(cell)
+
+ self._cellContexts[cell] = Dlo._CellContext()
+
class DloGen(Dlo):
_libName = ''
def __init__(self):
+ super(DloGen, self).__init__('', '')
self.tech = None
self.props = {}
@@ -102,8 +168,23 @@ def getLibName(cls) -> str:
def setTech(self, tech):
self.tech = tech
- def addPin(self, name, label, box, layer):
- # simply creates a shape - needs to support other shape types?
- Rect(layer, box)
+ def addPin(self, pinName : str, termName: str, box : Box, layer: Layer) -> Pin:
+ pin = Pin(pinName, termName)
+
+ cellContext = self._getCurrentCellContext()
+ cellContext.pins[pinName] = pin
+
+ term = pin.getTerm()
+ if not self.hasTerm(termName):
+ cellContext.terms[termName] = term
+
+ # Note: The net associated with a terminal has the same name.
+ net = term.getNet()
+ if not self.hasNet(termName):
+ cellContext.nets[termName] = net
+
+ pin.setBBox(box, layer)
+
+ return pin
diff --git a/ihp-sg13g2/libs.tech/klayout/python/cni/geo.py b/ihp-sg13g2/libs.tech/klayout/python/cni/geo.py
index 9b10bc2f..898bce4e 100644
--- a/ihp-sg13g2/libs.tech/klayout/python/cni/geo.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/cni/geo.py
@@ -22,16 +22,16 @@
from cni.point import Point
from cni.polygon import Polygon
from cni.dlo import Tech
+from cni.shapefilter import ShapeFilter
import pya
def fgOr(components1: ulist[PhysicalComponent], components2: ulist[PhysicalComponent], resultLayer: Layer) -> Grouping:
"""
- Performs a logical OR operation for lists of physical components comps1
- and comps2, by selecting those polygon areas which are in either list of physical
- components. The resulting merged polygon shapes are generated on the resultLayer layer.
- In addition, these polygon shapes are used to create a Grouping object, which is the return
- value for this method.
+ Performs a logical OR operation for lists of physical components components1 and components2, by
+ selecting those polygon areas which are in either list of physical components. The resulting
+ merged polygon shapes are generated on the resultLayer layer. In addition, these polygon shapes
+ are used to create a Grouping object, which is the return value for this method.
:param components1: first list of physical component derived objects
:type components1: list of PhysicalCompent
@@ -43,17 +43,104 @@ def fgOr(components1: ulist[PhysicalComponent], components2: ulist[PhysicalCompo
:rtype: Grouping
"""
+
+ return __fgOperation(components1, components2, resultLayer, 'fgOr')
+
+
+def fgAnd(components1: ulist[PhysicalComponent], components2: ulist[PhysicalComponent], resultLayer: Layer) -> Grouping:
+ """
+ Performs a logical AND operation for lists of physical components components1 and components2,
+ by selecting those polygon areas which are in both physical components. The resulting polygon
+ shapes are generated on the resultLayer layer. In addition,these polygon shapes are used to
+ create a Grouping object, which is the return value for this method. If there are no polygon
+ shapes, then this Grouping object is empty.
+
+ :param components1: first list of physical component derived objects
+ :type components1: list of PhysicalCompent
+ :param components2: second list of physical component derived objects
+ :type components2: list of PhysicalCompent
+ :param resultLayer: layer where resulting shapes will be generated on
+ :type resultLayer: Layer
+ :return: grouping object
+ :rtype: Grouping
+
+ """
+
+ return __fgOperation(components1, components2, resultLayer, 'fgAnd')
+
+
+def fgXor(components1: ulist[PhysicalComponent], components2: ulist[PhysicalComponent], resultLayer: Layer) -> Grouping:
+ """
+ Performs a logical XOR operation for lists of physical components components1 and components2,
+ by selecting those polygon areas which are in either list of physical components, but not in
+ both lists of physical components. The resulting merged polygon shapes are generated on the
+ resultLayer layer. In addition, these polygon shapes are used to create a Grouping object, which
+ is the return value for this method.
+
+ :param components1: first list of physical component derived objects
+ :type components1: list of PhysicalCompent
+ :param components2: second list of physical component derived objects
+ :type components2: list of PhysicalCompent
+ :param resultLayer: layer where resulting shapes will be generated on
+ :type resultLayer: Layer
+ :return: grouping object
+ :rtype: Grouping
+
+ """
+
+ return __fgOperation(components1, components2, resultLayer, 'fgXor')
+
+
+def fgNot(components1: ulist[PhysicalComponent], components2: ulist[PhysicalComponent], resultLayer: Layer) -> Grouping:
+ """
+ Performs a logical NOT operation for lists of physical components components1 and components2,
+ by selecting those polygon areas contained in the components1 physical component which are not
+ contained in the components2 physical component. The resulting polygon shapes are generated on
+ the resultLayer layer. In addition, these polygon shapes are used to create a Grouping object,
+ which is the return value for this method. If there are no polygon shapes generated, then this
+ Grouping object will be empty.
+
+ :param components1: first list of physical component derived objects
+ :type components1: list of PhysicalCompent
+ :param components2: second list of physical component derived objects
+ :type components2: list of PhysicalCompent
+ :param resultLayer: layer where resulting shapes will be generated on
+ :type resultLayer: Layer
+ :return: grouping object
+ :rtype: Grouping
+
+ """
+
+ return __fgOperation(components1, components2, resultLayer, 'fgNot')
+
+
+def __fgOperation(
+ components1: ulist[PhysicalComponent],
+ components2: ulist[PhysicalComponent],
+ resultLayer: Layer,
+ operation: str,
+ filter1: ShapeFilter = ShapeFilter(),
+ filter2: ShapeFilter = ShapeFilter()) -> Grouping:
region1 = pya.Region()
region2 = pya.Region()
- [component.addToRegion(region1) for component in components1]
- [component.addToRegion(region2) for component in components2]
+ [component.addToRegion(region1, filter1) for component in components1]
+ [component.addToRegion(region2, filter2) for component in components2]
- orRegion = region1.or_(region2).merge()
+ if operation == 'fgXor':
+ region = region1.xor(region2)
+ elif operation == 'fgAnd':
+ region = region1.and_(region2)
+ elif operation == 'fgOr':
+ region = region1.or_(region2)
+ elif operation == 'fgNot':
+ region = region1.not_(region2)
+ else:
+ raise Exception(f"Operation '{operation}' not supported")
grouping = Grouping()
- for poly in orRegion.each():
+ for poly in region.each():
pointList = PointList()
for point in poly.to_simple_polygon().to_dtype(Tech.get(Tech.techInUse).dataBaseUnits).each_point():
pointList.append(Point(point.x, point.y))
@@ -64,23 +151,52 @@ def fgOr(components1: ulist[PhysicalComponent], components2: ulist[PhysicalCompo
return grouping
-def fgAnd():
- # TODO: implement
- pass
+def fgSize(components: ulist[PhysicalComponent], filter: ShapeFilter, sizeValue: float, resultLayer: Layer, grid: float = None) -> Grouping:
+ """
+ Expands or shrinks all polygon areas contained in this list of physical components, according to
+ the sizeValue parameter value. If this sizeValue parameter is positive, then the polygon edges
+ are expanded outward by that amount. If this sizeValue parameter is negative, then the polygon
+ edges are shrunk inward by that amount. The resulting polygon shapes are generated on the
+ resultLayer layer. In addition, these polygon shapes are used to create a Grouping object, which
+ is the return value for this method. Note that filter shape filter is first used to merge all
+ shapes from the comps list, and then the SIZE geometrical operation is performed on these merged
+ geometries. If the grid parameter is specified, then the points of the physical components are
+ snapped with grid value to the nearest grid point.
+
+ :param components: list of physical component derived objects
+ :type components: list of PhysicalCompent
+ :param filter: layer filter to use
+ :type filter: ShapeFilter
+ :param sizeValue: value for sizing (bias)
+ :type sizeValue: float
+ :param resultLayer: layer where resulting shapes will be generated on
+ :type resultLayer: Layer
+ :param grid: optional value for snapping
+ :type grid: float
+ :return: grouping object
+ :rtype: Grouping
+ """
-def fgXor():
- # TODO: implement
- pass
+ region = pya.Region()
+ [component.addToRegion(region, filter) for component in components]
-def fgNot():
- # TODO: implement
- pass
+ grouping = Grouping()
+ sizedRegion = region.sized(sizeValue / Tech.get(Tech.techInUse).dataBaseUnits)
-def fgMerge():
- # TODO: implement
- pass
+ if grid is not None:
+ decimalGrid = int(grid / Tech.get(Tech.techInUse).dataBaseUnits)
+ sizedRegion.snap(decimalGrid, decimalGrid)
+ for poly in sizedRegion.each():
+ pointList = PointList()
+ for point in poly.to_simple_polygon().to_dtype(Tech.get(Tech.techInUse).dataBaseUnits).each_point():
+ pointList.append(Point(point.x, point.y))
+
+ polygon = Polygon(resultLayer, pointList)
+ grouping.add(polygon)
+
+ return grouping
diff --git a/ihp-sg13g2/libs.tech/klayout/python/cni/grouping.py b/ihp-sg13g2/libs.tech/klayout/python/cni/grouping.py
index a7ddc775..953c2f6f 100644
--- a/ihp-sg13g2/libs.tech/klayout/python/cni/grouping.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/cni/grouping.py
@@ -30,14 +30,20 @@ def __init__(self, name: str = "", components: PhysicalComponent = None):
if components is not None:
self._components.add(components)
+ def __iter__(self):
+ return self._components.__iter__()
+
+ def __next__(self):
+ return self._components.__next__()
+
def add(self, components: PhysicalComponent) -> None:
if type(components) is not list:
self._components.append(components)
else:
self._components.extend(components)
- def addToRegion(self, region: pya.Region):
- [component.addToRegion(region) for component in self._components]
+ def addToRegion(self, region: pya.Region, filter: ShapeFilter):
+ [component.addToRegion(region, filter) for component in self._components]
def clone(self, nameMap : NameMapper = NameMapper(), netMap : NameMapper = NameMapper()):
components = []
diff --git a/ihp-sg13g2/libs.tech/klayout/python/cni/net.py b/ihp-sg13g2/libs.tech/klayout/python/cni/net.py
new file mode 100644
index 00000000..c9f61673
--- /dev/null
+++ b/ihp-sg13g2/libs.tech/klayout/python/cni/net.py
@@ -0,0 +1,118 @@
+########################################################################
+#
+# Copyright 2024 IHP PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+########################################################################
+
+from __future__ import annotations
+from typing import List
+
+from cni.signaltype import SignalType
+
+class Net(object):
+ """
+ Creates a Net object in the current design, using the netName parameter to name this newly
+ created Net object. If this netName string parameter is empty, or is the name of anexisting net
+ in the design, then an exception is raised. In addition, the sigType parameter is used to
+ specify the signal type for this net, and the isGlobal Boolean flag parameter should be set to
+ True, when this net is a global net for the current design.
+
+ :param netName: name of the new net
+ :type netName: string
+ :param sigType: optional signal type of the new net
+ :type sigType: SignalType
+
+ """
+
+ def __init__(self, netName: str, sigType: SignalType = SignalType.SIGNAL, isGlobal: bool = False):
+ import cni.dlo
+ impl = cni.dlo.PyCellContext.getCurrentPyCellContext().impl
+
+ if netName == "":
+ raise Exception("Empty net name given")
+
+ if impl.hasNet(netName):
+ raise Exception(f"Net {netName} already defined")
+
+
+ self._name = netName
+ self._type = sigType
+ self._terminal = None
+ self._isGlobal = isGlobal
+
+ def addTerm(self, term: Term) -> None:
+ self._terminal = term
+
+ def getName(self) -> str:
+ """
+ Returns the name for this Net.
+
+ :return: The name of the Net
+ :rtype: string
+
+ """
+ return self._name
+
+ def getPins(self) -> list[Pin]:
+ """
+ Returns a list of pins which are connected to any terminal associated with this Net object.
+ All Pin objects associated with this terminal are returned in this list.
+
+ :return: List of Pin
+ :rtype: list[Pin]
+ """
+ if self._terminal is not None:
+ return self._terminal.getPins()
+ else:
+ pins = []
+ return pins
+
+ def setName(self, name: str) -> None:
+ """
+ Sets the name for this Net object. Note that the name of any associated terminal for this
+ Net will also be changed to use this new name. This is done in order to ensure that any
+ terminal connected to a net will always have the same name as the net. If this name string
+ parameter is empty, or is the name of an existing net or terminal in the current design,
+ then an exception is raised.
+
+ :param name: The name of the net
+ :type name: string
+
+ """
+
+ import cni.dlo
+ impl = cni.dlo.PyCellContext.getCurrentPyCellContext().impl
+
+ if name == "" or impl.hasNet(name):
+ raise Exception(f"Net {name} already defined")
+ self._name = name
+
+ @property
+ def name(self):
+ """
+ Returns the name of this terminal
+
+ """
+ return self.getName()
+
+ @name.setter
+ def name(self, value):
+ """
+ Sets the name of this terminal
+
+ """
+ self.setName(value)
+
+
diff --git a/ihp-sg13g2/libs.tech/klayout/python/cni/path.py b/ihp-sg13g2/libs.tech/klayout/python/cni/path.py
new file mode 100644
index 00000000..0f007cab
--- /dev/null
+++ b/ihp-sg13g2/libs.tech/klayout/python/cni/path.py
@@ -0,0 +1,101 @@
+########################################################################
+#
+# Copyright 2024 IHP PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+########################################################################
+
+from functools import singledispatchmethod
+from cni.shape import *
+from cni.layer import *
+from cni.pointlist import *
+from cni.pathstyle import *
+from cni.tech import Tech
+
+import pya
+
+class Path(Shape):
+ """
+ Creates a path object, using the points list of points to define the path. The width
+ parameter is used to specify the width of this path. The layer parameter is a Layer object,
+ the width parameter is an integer value, and the points parameter is a Python list of Point
+ objects.
+
+ :param layer: Layer to place the path
+ :type layer: Layer
+ :param width: width of the path
+ :type width: float
+ :param points: pointlist to define the path
+ :type points: PointList
+
+ """
+
+ @singledispatchmethod
+ def __init__(self, arg1, arg2, arg3, arg4 = None):
+ pass
+
+ @__init__.register
+ def _(self, arg1: Layer, arg2: float, arg3: PointList, arg4 = PathStyle.TRUNCATE) -> None:
+ pyaPoints = []
+ [pyaPoints.append(point.point) for point in arg3]
+
+ self._path = pya.DPath(pyaPoints, arg2)
+ super().__init__(arg1, self._path.bbox())
+ self.set_shape(Shape.getCell().shapes(arg1.number).insert(self._path))
+
+ @__init__.register
+ def _(self, arg1: pya.DPath, arg2: int, arg3: Layer) -> None:
+ self._path = arg1
+ super().__init__(arg3, self._path.bbox())
+ self.set_shape(Shape.getCell().shapes(arg2).insert(self._path))
+
+ def addToRegion(self, region: pya.Region, filter: ShapeFilter):
+ if filter.isIncluded(self._shape.layer):
+ region.insert(self._path.to_itype(Tech.get(Tech.techInUse).dataBaseUnits))
+
+ def clone(self, nameMap : NameMapper = NameMapper(), netMap : NameMapper = NameMapper()):
+ dup = self._path.dup();
+ path = Path(dup, self.getShape().layer, self.layer)
+ return path
+
+ def destroy(self):
+ if not self._path._destroyed():
+ Shape.getCell().shapes(self.getShape().layer).erase(self.getShape())
+ self._path._destroy()
+ else:
+ pya.Logger.warn(f"Path.destroy: already destroyed!")
+
+ def getPoints(self) -> PointList:
+ pointList = PointList()
+ [pointList.append(Point(point.x, point.y)) for point in self._path.each_point()]
+ return pointList
+
+ def moveBy(self, dx: float, dy: float) -> None:
+ movedPath = (pya.DTrans(float(dx), float(dy)) * self._path).to_itype(Tech.get(Tech.techInUse).
+ dataBaseUnits).to_simple_polygon().to_dtype(Tech.get(Tech.techInUse).dataBaseUnits)
+ shape = Shape.getCell().shapes(self._shape.layer).insert(movedPath)
+ self.destroy()
+ self._path = movedPath
+ self.set_shape(shape)
+
+ def toString(self) -> str:
+ return "Path: {}".format(self._path.to_s())
+
+ def transform(self, transform: Transform) -> None:
+ transformedPath = self._path.transformed(transform.transform)
+ shape = Shape.getCell().shapes(self.getShape().layer).insert(transformedPath)
+ self.destroy()
+ self._path = transformedPath
+ self.set_shape(shape)
+
diff --git a/ihp-sg13g2/libs.tech/klayout/python/cni/physicalComponent.py b/ihp-sg13g2/libs.tech/klayout/python/cni/physicalComponent.py
index db424919..5cc36afc 100644
--- a/ihp-sg13g2/libs.tech/klayout/python/cni/physicalComponent.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/cni/physicalComponent.py
@@ -58,6 +58,111 @@ def fgOr(self, component: PhysicalComponent, resultLayer: Layer) -> Grouping:
import cni.geo
return cni.geo.fgOr(components1, components2, resultLayer)
+ def fgXor(self, component: PhysicalComponent, resultLayer: Layer) -> Grouping:
+ """
+ Performs a logical xor operation for this physical component and another physical component,
+ by selecting those polygon areas which are in either physical component, but not in both
+ lists of physical components. The resulting merged polygon shapes are generated on the
+ resultLayer layer. In addition, these polygon shapes are used to create a Grouping object,
+ which is the return value for this method.
+
+ :param component: physical component derived object
+ :type component: PhysicalCompent
+ :param resultLayer: layer where resulting shapes will be generated on
+ :type resultLayer: Layer
+ :return: grouping object
+ :rtype: Grouping
+
+ """
+ components1 = ulist[PhysicalComponent]()
+ components1.append(self)
+
+ components2 = ulist[PhysicalComponent]()
+ components2.append(component)
+
+ import cni.geo
+ return cni.geo.fgXor(components1, components2, resultLayer)
+
+ def fgAnd(self, component: PhysicalComponent, resultLayer: Layer) -> Grouping:
+ """
+ Performs a logical and operation for this physical component and the component physical
+ component, by selecting those polygon areas which are in both physical components. The
+ resulting polygon shapes are generated on the resultLayer layer. In addition, these polygon
+ shapes are used to create a Grouping object, which is the return value for this method. If
+ there are no polygon shapes, then this Grouping object is empty.
+
+ :param component: physical component derived object
+ :type component: PhysicalCompent
+ :param resultLayer: layer where resulting shapes will be generated on
+ :type resultLayer: Layer
+ :return: grouping object
+ :rtype: Grouping
+
+ """
+ components1 = ulist[PhysicalComponent]()
+ components1.append(self)
+
+ components2 = ulist[PhysicalComponent]()
+ components2.append(component)
+
+ import cni.geo
+ return cni.geo.fgAnd(components1, components2, resultLayer)
+
+ def fgNot(self, component: PhysicalComponent, resultLayer: Layer) -> Grouping:
+ """
+ Performs a logical not operation for this physical component and another physical component,
+ by selecting those polygon areas contained in this physical component which are not
+ contained in the component physical component. The resulting polygon shapes are generated on
+ the resultLayer layer. In addition, these polygon shapes are used to create a Grouping
+ object, which is the return value for this method. If there are no polygon shapes generated,
+ then this Grouping object will be empty.
+
+ :param component: physical component derived object
+ :type component: PhysicalCompent
+ :param resultLayer: layer where resulting shapes will be generated on
+ :type resultLayer: Layer
+ :return: grouping object
+ :rtype: Grouping
+
+ """
+ components1 = ulist[PhysicalComponent]()
+ components1.append(self)
+
+ components2 = ulist[PhysicalComponent]()
+ components2.append(component)
+
+ import cni.geo
+ return cni.geo.fgNot(components1, components2, resultLayer)
+
+ def fgSize(self, filter: ShapeFilter, sizeValue: float, resultLayer: Layer, grid: float = None) -> Grouping:
+ """
+ Expands or shrinks all polygon areas contained in this physical component, according to the
+ sizeValue parameter value. If this sizeValue parameter is positive, then the polygon edges
+ are expanded outward by that amount. If this sizeValue parameter is negative, then the
+ polygon edges are shrunk inward by that amount. The resulting polygon shapes are generated
+ on the resultLayer layer. In addition, these polygon shapes are used to create a Grouping
+ object, which is the return value for this method. If the grid parameter is specified, then
+ the points of the physical components are snapped with grid value to the nearest grid point.
+
+ :param filter: layer filter to use
+ :type filter: ShapeFilter
+ :param sizeValue: value for sizing (bias)
+ :type sizeValue: float
+ :param resultLayer: layer where resulting shapes will be generated on
+ :type resultLayer: Layer
+ :param grid: optional value for snapping
+ :type grid: float
+ :return: grouping object
+ :rtype: Grouping
+
+ """
+
+ components = ulist[PhysicalComponent]()
+ components.append(self)
+
+ import cni.geo
+ return cni.geo.fgSize(components, filter, sizeValue, resultLayer, grid)
+
@abstractmethod
def destroy(self):
pass
diff --git a/ihp-sg13g2/libs.tech/klayout/python/cni/pin.py b/ihp-sg13g2/libs.tech/klayout/python/cni/pin.py
new file mode 100644
index 00000000..747bfe7b
--- /dev/null
+++ b/ihp-sg13g2/libs.tech/klayout/python/cni/pin.py
@@ -0,0 +1,153 @@
+########################################################################
+#
+# Copyright 2024 IHP PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+########################################################################
+
+from functools import singledispatchmethod
+
+from cni.shape import Shape
+from cni.term import Term
+from cni.box import Box
+from cni.layer import Layer
+from cni.ulist import ulist
+
+import pya
+
+class Pin(object):
+ """
+ Creates a Pin object for the specified terminal in the current design, using the pinName
+ parameter to name this newly created Pin object. If there is already a terminal in the
+ current design having the same name as the termName parameter, then this terminal will be
+ used to create this Pin object. Otherwise, a new terminal will be created, using this
+ termName string to name this newly created terminal. If there is already a pin in the
+ current design having the same name as the pinName string parameter, then an exception is
+ raised. In addition, the shape parameter can optionally be used to associate a shape object
+ with this pin.
+
+ :param pinName: Name of the pin.
+ :type pinName: string
+ :param termName: second point.
+ :type termName: string
+ :param shape: optional shape to associate
+ :type shape: Shape
+
+ """
+
+ def __init__(self, pinName: str, termName: str, shape: Shape = None):
+ self._name = pinName
+ self._term = None
+ self._bbox = None
+ self._shapes = []
+ self._layers = []
+
+ import cni.dlo
+ impl = cni.dlo.PyCellContext.getCurrentPyCellContext().impl
+
+ if impl.hasPin(pinName):
+ raise Exception(f"Pin {pinName} already defined")
+
+ if impl.hasTerm(termName):
+ self._term = impl.findTerm(termName)
+ else:
+ self._term = Term(termName)
+
+ self._term.addPin(self)
+
+ if shape is not None:
+ self._shapes.append(shape)
+
+ @singledispatchmethod
+ def addShape(self, arg):
+ pass
+
+ @addShape.register
+ def _(self, arg: Shape) -> None:
+ shapes = ulist[Shape]()
+ shapes.append(arg)
+ self.addShape(shapes)
+
+ @addShape.register
+ def _(self, arg: list) -> None:
+ for shape in arg:
+ shape.setPin(self)
+ self._shapes.append(shape)
+
+ def getName(self) -> str:
+ """
+ Returns the name for this Pin object.
+
+ :return: pin name
+ :rtype: string
+ """
+ return self._name
+
+ def setBBox(self, box: Box, layer: Layer) -> None:
+ self._bbox = box
+ self._layers.append(layer)
+
+ def getBBox(self) -> Box:
+ return self._bbox
+
+ def setName(self, name: str) -> None:
+ """
+ Sets the name for this Pin object. If there is already a pin in the current design with the
+ same name as the name parameter, an exception is raised.
+
+ :param name: Name to set
+ :type name: string
+ """
+
+ import cni.dlo
+ impl = cni.dlo.PyCellContext.getCurrentPyCellContext().impl
+
+ if impl.hasPin(name):
+ raise Exception(f"Pin {name} already defined")
+ self._name = name
+
+ def setTerm(self, term: Term) -> None:
+ """
+ Associates the term terminal with this Pin object. Note that multiple Pin objects may be
+ associated with a single terminal.
+
+ :param Term: Terminal to associate
+ :type name: Term
+ """
+
+ self._term = term
+
+ def getTerm(self) -> Term:
+ if self._term is None:
+ raise Exception("Pin '{self._name}' has no terminal")
+ else:
+ return self._term
+
+ @property
+ def name(self):
+ """
+ Returns the name of this pin
+
+ """
+ return self.getName()
+
+ @name.setter
+ def name(self, value):
+ """
+ Sets the name of this pin
+
+ """
+ self.setName(value)
+
+
diff --git a/ihp-sg13g2/libs.tech/klayout/python/cni/pointlist.py b/ihp-sg13g2/libs.tech/klayout/python/cni/pointlist.py
index 68e12be3..82a26100 100644
--- a/ihp-sg13g2/libs.tech/klayout/python/cni/pointlist.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/cni/pointlist.py
@@ -35,7 +35,7 @@ def compress(self, isClose = True) -> PointList:
last points are coincident, then only the first point is returned
:param isClose: Whether represented shape is closed
- :type p1: boolean
+ :type isClose: boolean
:return: see description above
:rtype: PointList
"""
diff --git a/ihp-sg13g2/libs.tech/klayout/python/cni/polygon.py b/ihp-sg13g2/libs.tech/klayout/python/cni/polygon.py
index 1819f5f4..e77b5816 100644
--- a/ihp-sg13g2/libs.tech/klayout/python/cni/polygon.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/cni/polygon.py
@@ -27,7 +27,7 @@
class Polygon(Shape):
@singledispatchmethod
- def __init__(self, arg1, arg2 = None):
+ def __init__(self, arg1, arg2, arg3 = None):
pass
@__init__.register
@@ -36,21 +36,22 @@ def _(self, arg1: Layer, arg2: PointList) -> None:
[pyaPoints.append(point.point) for point in arg2]
self._polygon = pya.DSimplePolygon(pyaPoints, True)
- super().__init__(self._polygon.bbox())
+ super().__init__(arg1, self._polygon.bbox())
self.set_shape(Shape.getCell().shapes(arg1.number).insert(self._polygon))
@__init__.register
- def _(self, arg1: pya.DSimplePolygon, arg2: int) -> None:
+ def _(self, arg1: pya.DSimplePolygon, arg2: int, arg3: Layer) -> None:
self._polygon = arg1
- super().__init__(self._polygon.bbox())
+ super().__init__(arg3, self._polygon.bbox())
self.set_shape(Shape.getCell().shapes(arg2).insert(self._polygon))
- def addToRegion(self, region: pya.Region):
- region.insert(self._polygon.to_itype(Tech.get(Tech.techInUse).dataBaseUnits))
+ def addToRegion(self, region: pya.Region, filter: ShapeFilter):
+ if filter.isIncluded(self._shape.layer):
+ region.insert(self._polygon.to_itype(Tech.get(Tech.techInUse).dataBaseUnits))
def clone(self, nameMap : NameMapper = NameMapper(), netMap : NameMapper = NameMapper()):
dup = self._polygon.dup();
- polygon = Polygon(dup, self.getShape().layer)
+ polygon = Polygon(dup, self.getShape().layer, self.layer)
return polygon
def destroy(self):
diff --git a/ihp-sg13g2/libs.tech/klayout/python/cni/rect.py b/ihp-sg13g2/libs.tech/klayout/python/cni/rect.py
index 8070e138..b1921f6f 100644
--- a/ihp-sg13g2/libs.tech/klayout/python/cni/rect.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/cni/rect.py
@@ -27,13 +27,14 @@ def __init__(self, layer: Layer, box: Box):
self._box = box
self._layer = layer
- super().__init__(box)
+ super().__init__(layer, box)
shape = Shape.getCell().shapes(layer.number).insert(box.box)
self.set_shape(shape)
self._box.setRect(self)
- def addToRegion(self, region: pya.Region):
- region.insert(self._box.box.to_itype(Tech.get(Tech.techInUse).dataBaseUnits))
+ def addToRegion(self, region: pya.Region, filter: ShapeFilter):
+ if filter.isIncluded(self._layer):
+ region.insert(self._box.box.to_itype(Tech.get(Tech.techInUse).dataBaseUnits))
def clone(self, nameMap : NameMapper = NameMapper(), netMap : NameMapper = NameMapper()):
return Rect(self._layer, self._box.clone(nameMap, netMap))
diff --git a/ihp-sg13g2/libs.tech/klayout/python/cni/shape.py b/ihp-sg13g2/libs.tech/klayout/python/cni/shape.py
index 487eba24..ce9fb2aa 100644
--- a/ihp-sg13g2/libs.tech/klayout/python/cni/shape.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/cni/shape.py
@@ -19,6 +19,10 @@
from __future__ import annotations
from cni.box import *
from cni.physicalComponent import *
+from cni.layer import *
+from cni.shapefilter import *
+from cni.constants import *
+
import pya
class Shape(PhysicalComponent):
@@ -28,9 +32,12 @@ def getCell(cls) -> pya.Cell:
import cni.dlo
return cni.dlo.PyCellContext.getCurrentPyCellContext().cell
- def __init__(self, bbox = None):
+ def __init__(self, layer: Layer, bbox: Box):
self._shape = None
+ self._layer = layer
self._bbox = bbox
+ self._net = None
+ self._pin = None
def set_shape(self, shape: Shape):
self._shape = shape
@@ -40,5 +47,42 @@ def getShape(self):
raise Exception(f"Shape.getShape no shape set {hex(id(self))}: {hex(id(self._shape))}")
return self._shape
- def getBBox(self):
- return Box(self._bbox.box.left, self._bbox.box.bottom, self._bbox.box.right, self._bbox.box.top)
+ def getBBox(self, filter: ShapeFilter = ShapeFilter()) -> Box:
+ if type(filter) is Layer and self._layer.getLayerName() == filter.getLayerName():
+ return Box(self._bbox.box.left, self._bbox.box.bottom, self._bbox.box.right, self._bbox.box.top)
+
+ if filter.isIncluded(self._layer):
+ return Box(self._bbox.box.left, self._bbox.box.bottom, self._bbox.box.right, self._bbox.box.top)
+ else:
+ return Box(INT_MAX, INT_MAX, INT_MIN, INT_MIN)
+
+ def getLayer(self) -> Layer:
+ return self._layer
+
+ def getNet(self) -> Net:
+ return self._net
+
+ def getPin(self) -> Pin:
+ return self._pin
+
+ def setPin(self, pin: Pin) -> None:
+ if self._pin is not None:
+ raise Exception("Shape already associated to a pin")
+
+ self._pin = pin
+
+ @property
+ def bbox(self):
+ """
+ The bounding box for this Shape
+
+ """
+ return self.getBBox()
+
+ @property
+ def layer(self):
+ """
+ The Layer associated with this Shape
+
+ """
+ return self.getLayer()
diff --git a/ihp-sg13g2/libs.tech/klayout/python/cni/shapefilter.py b/ihp-sg13g2/libs.tech/klayout/python/cni/shapefilter.py
new file mode 100644
index 00000000..9d282995
--- /dev/null
+++ b/ihp-sg13g2/libs.tech/klayout/python/cni/shapefilter.py
@@ -0,0 +1,83 @@
+########################################################################
+#
+# Copyright 2024 IHP PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+########################################################################
+
+from cni.layer import Layer
+
+class ShapeFilter(object):
+ """
+ Creates an empty ShapeFilter object, which would be used to indicate that all layers should be
+ considered in any bounding box or placement calculations
+
+
+ Creates a ShapeFilter object, consisting of only a single layer. This single layer is the only
+ layer which should be considered when the ShapeFilter object is passed to methods which perform
+ bounding box and placement calculations.
+
+ :param layer: Layer to filter
+ :type layer: Layer
+
+
+ Creates a ShapeFilter object, consisting of a list of Layer objects. These layers are the only
+ layers which should be considered when the ShapeFilter is passed to methods which perform
+ bounding box or placement calculations.
+
+ :param layerList: Layers to filter
+ :type layerList: LayerList
+
+
+ Creates a ShapeFilter object, consisting of the Layer objects which are specified by the
+ shapeFilter ShapeFilter object. These layers are the only layers which should be considered when
+ the ShapeFilter is passed to methods which perform bounding box or placement calculations.
+
+ :param shapeFilter: ShapeFilter to filter
+ :type shapeFilter: ShapeFilter
+
+ """
+
+ def __init__(self, arg = None):
+ self._layers = []
+
+ if arg is not None:
+ if type(arg) is Layer:
+ self._layers.append(arg)
+ elif type(arg) is list:
+ self._layers.extend(arg)
+ elif type(arg) is ShapeFilter:
+ self = arg.copy.deepcopy();
+ else:
+ raise Exception(f"Not supported type '{type(arg)}'")
+
+ def isIncluded(self, layer: Layer) -> bool:
+ """
+ Returns true if the layer parameter is a layer which is in the list of layers considered by
+ the ShapeFilter object, and returns False otherwise.
+
+ :param layer: Layer to check
+ :type layer: Layer
+ :rtype: bool
+
+ """
+
+ if len(self._layers) == 0:
+ return True
+
+ for item in self._layers:
+ if layer.getLayerName() == item.getLayerName():
+ return True
+
+ return False
diff --git a/ihp-sg13g2/libs.tech/klayout/python/cni/term.py b/ihp-sg13g2/libs.tech/klayout/python/cni/term.py
new file mode 100644
index 00000000..77a319d3
--- /dev/null
+++ b/ihp-sg13g2/libs.tech/klayout/python/cni/term.py
@@ -0,0 +1,134 @@
+########################################################################
+#
+# Copyright 2024 IHP PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+########################################################################
+
+from __future__ import annotations
+from typing import List
+
+from cni.termtype import TermType
+from cni.net import Net
+
+class Term(object):
+ """
+ Creates a Term terminal object in the current design, using the termName parameter to name this
+ newly created Term object. If there is already a net in the current design having the same name
+ as this terminal, then this net will be connected to this terminal. Otherwise, a new net will be
+ created, and connected to this terminal, using this termName string to name this newly created
+ net. If the termName string parameter is empty, or is the name of an existing terminal in the
+ design, then an exception is raised. In addition, the termType parameter is used to specify the
+ terminal type for this terminal.
+
+ :param termName: name of the new terminal
+ :type termName: string
+ :param termType: optional type of the new terminal
+ :type termType: Termtype
+
+ """
+
+ def __init__(self, termName: str, termType: TermType = TermType.INPUT_OUTPUT):
+ import cni.dlo
+ impl = cni.dlo.PyCellContext.getCurrentPyCellContext().impl
+
+ if termName == "":
+ raise Exception("Empty terminal name given")
+
+ if impl.hasTerm(termName):
+ raise Exception(f"Term {termName} already defined")
+
+ self._name = termName
+ self._type = termType
+ self._pins = []
+ self._net = None
+
+ if impl.hasNet(termName):
+ self._net = impl.findNet(termName)
+ else:
+ self._net = Net(termName)
+
+ def addPin(self, pin: Pin) -> None:
+ self._pins.append(pin)
+
+ def getName(self) -> str:
+ """
+ Returns the name for this terminal.
+
+ :return: The name of the terminal
+ :rtype: string
+
+ """
+ return self._name
+
+ def getNet(self) -> Net:
+ """
+ Returns the net associated with this Term terminal object. If there is no associated net,
+ then an exception is raised.
+
+ :return: The associated net
+ :rtype: Net
+
+ """
+ if self._net is None:
+ raise Exception(f"No net associated for terminal {termName}")
+
+ return self._net
+
+ def getPins(self) -> list[Pin]:
+ """
+ Returns a uniform list of all of the Pin objects associated with this Term terminal object.
+
+ :return: List of Pin
+ :rtype: list[Pin]
+ """
+ return self._pins
+
+ def setName(self, name: str) -> None:
+ """
+ Sets the name for this terminal. Note that the name of the associated net for this terminal
+ is also changed to have the same name as this terminal. This is done in order to ensure that
+ any net connected to this terminal will always have the same name as this terminal. If this
+ name string parameter is empty, or is the name of an existing terminal or net in the design,
+ then an exception is raised.
+
+ :param name: The name of the terminal
+ :type name: string
+
+ """
+
+ import cni.dlo
+ impl = cni.dlo.PyCellContext.getCurrentPyCellContext().impl
+
+ if name == "" or impl.hasTerm(name):
+ raise Exception(f"Term {name} already defined")
+ self._name = name
+
+ @property
+ def name(self):
+ """
+ Returns the name of this terminal
+
+ """
+ return self.getName()
+
+ @name.setter
+ def name(self, value):
+ """
+ Sets the name of this terminal
+
+ """
+ self.setName(value)
+
+
diff --git a/ihp-sg13g2/libs.tech/klayout/python/cni/text.py b/ihp-sg13g2/libs.tech/klayout/python/cni/text.py
index 46ee01d7..e025347c 100644
--- a/ihp-sg13g2/libs.tech/klayout/python/cni/text.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/cni/text.py
@@ -19,23 +19,26 @@
from cni.box import *
from cni.shape import *
from cni.rect import *
+from cni.location import Location
+from cni.transform import Transform
import pya
class Text(Shape):
- def __init__(self, layer, text, point, size):
- # TODO: size
- text = pya.DText(text, pya.DTrans(point.getX(), point.getY()), 1, 0)
+ def __init__(self, layer: Layer, text: str, origin: Point, height: float):
+ text = pya.DText(text, pya.DTrans(origin.getX(), origin.getY()), height, 2)
self._text = text
self._layer = layer
+ self._height = height
+ super().__init__(layer, Box(text.bbox().left, text.bbox().bottom, text.bbox().right, text.bbox().top))
self.set_shape(Shape.getCell().shapes(layer.number).insert(text))
- super().__init__(Box(text.bbox().left, text.bbox().bottom, text.bbox().right, text.bbox().top))
- def addToRegion(self, region: pya.Region):
- region.insert(self._text)
+ def addToRegion(self, region: pya.Region, filter: ShapeFilter):
+ if filter.isIncluded(self.getShape().layer):
+ region.insert(self._text)
def clone(self, nameMap : NameMapper = NameMapper(), netMap : NameMapper = NameMapper()):
return Text(self._layer, self._text.dup())
@@ -51,16 +54,52 @@ def moveBy(self, dx: float, dy: float) -> None:
movedText = (pya.DTrans(float(dx), float(dy)) * self._text)
shape = Shape.getCell().shapes(self._shape.layer).insert(movedText)
self.destroy()
- self._polygon = movedPolygon
+ self._text = movedText
self.set_shape(shape)
- def setAlignment(self, align):
- # TODO
- pass
+ def setAlignment(self, location: Location) -> None:
+ width = len(self._text.string) * self._height
+
+ match location:
+ case Location.LOWER_LEFT:
+ self._text.halign = pya.HAlign.HAlignLeft
+ self._text.valign = pya.VAlign.VAlignBottom
+ case Location.CENTER_LEFT:
+ self._text.halign = pya.HAlign.HAlignLeft
+ self._text.valign = pya.VAlign.VAlignCenter
+ case Location.UPPER_LEFT:
+ self._text.halign = pya.HAlign.HAlignLeft
+ self._text.valign = pya.VAlign.VAlignTop
+ case Location.LOWER_CENTER:
+ self._text.halign = pya.HAlign.HAlignCenter
+ self._text.valign = pya.VAlign.VAlignBottom
+ case Location.CENTER_CENTER:
+ self._text.halign = pya.HAlign.HAlignCenter
+ self._text.valign = pya.VAlign.VAlignCenter
+ case Location.UPPER_CENTER:
+ self._text.halign = pya.HAlign.HAlignCenter
+ self._text.valign = pya.VAlign.VAlignTop
+ case Location.LOWER_RIGHT:
+ self._text.halign = pya.HAlign.HAlignRight
+ self._text.valign = pya.VAlign.VAlignBottom
+ case Location.CENTER_RIGHT:
+ self._text.halign = pya.HAlign.HAlignRight
+ self._text.valign = pya.VAlign.VAlignCenter
+ case Location.UPPER_RIGHT:
+ self._text.halign = pya.HAlign.HAlignRight
+ self._text.valign = pya.VAlign.VAlignTop
+
+ layer = self.getShape().layer
+
+ Shape.getCell().shapes(layer).erase(self.getShape())
+ self.set_shape(Shape.getCell().shapes(layer).insert(self._text))
def setOrientation(self, orient):
- # TODO
- pass
+ x = self._text.x
+ y = self._text.y
+ self.moveBy(-x, -y)
+ self.transform(Transform(0.0, 0.0, orient))
+ self.moveBy(x, y)
def setDrafting(self, drafting):
# TODO
diff --git a/ihp-sg13g2/libs.tech/klayout/python/doc/pycell4klayout.pdf b/ihp-sg13g2/libs.tech/klayout/python/doc/pycell4klayout.pdf
index a7961b7a..653e11af 100644
Binary files a/ihp-sg13g2/libs.tech/klayout/python/doc/pycell4klayout.pdf and b/ihp-sg13g2/libs.tech/klayout/python/doc/pycell4klayout.pdf differ
diff --git a/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/__init__.py b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/__init__.py
index ffe7f1c5..40a420d3 100644
--- a/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/__init__.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/__init__.py
@@ -26,34 +26,51 @@
# Creates the SG13_dev technology
from .sg13_tech import *
-# Defines the IHP PCells
-from .ihp import nmos_code
-from .ihp import pmos_code
-from .ihp import cmim_code
-from .ihp import rsil_code
-from .ihp import rhigh_code
-from .ihp import rppd_code
-from .ihp import sealring_code
-from .ihp import npn13G2_base_code
-from .ihp import npn13G2_code
+import pya
+import os
+import sys
+import inspect
+import re
+import importlib
+
+moduleNames = [
+ 'nmos_code',
+ 'nmosHV_code',
+ 'pmos_code',
+ 'pmosHV_code',
+ 'cmim_code',
+ 'rsil_code',
+ 'rhigh_code',
+ 'rppd_code',
+ 'sealring_code',
+ 'npn13G2_base_code',
+ 'npn13G2_code',
+ 'npn13G2L_code',
+ 'npn13G2V_code',
+ 'inductor2_code',
+ 'inductor2_sc_code',
+ 'inductor2_sp_code',
+ 'inductor3_code',
+ 'inductor3_sc_code',
+ 'inductor3_sp_code',
+ 'dantenna_code',
+ 'dpantenna_code'
+
+]
class PyCellLib(pya.Library):
def __init__(self):
- self.description = "SG13_dev"
+ self.description = "IHP SG13G2 Pcells"
tech = Tech.get('SG13_dev')
- # TODO: instead of explicitly creating the PCells here we could
- # use introspection to collect the classes defined
- self.layout().register_pcell("nmos", PCellWrapper(nmos_code.nmos(), tech))
- self.layout().register_pcell("pmos", PCellWrapper(pmos_code.pmos(), tech))
- self.layout().register_pcell("cmim", PCellWrapper(cmim_code.cmim(), tech))
- self.layout().register_pcell("rsil", PCellWrapper(rsil_code.rsil(), tech))
- self.layout().register_pcell("rhigh", PCellWrapper(rhigh_code.rhigh(), tech))
- self.layout().register_pcell("rppd", PCellWrapper(rppd_code.rppd(), tech))
- self.layout().register_pcell("sealring", PCellWrapper(sealring_code.sealring(), tech))
- self.layout().register_pcell("npn13G2_base", PCellWrapper(npn13G2_base_code.npn13G2_base(), tech))
- self.layout().register_pcell("npn13G2", PCellWrapper(npn13G2_code.npn13G2(), tech))
+ for moduleName in moduleNames:
+ module = importlib.import_module(f"{__name__}.ihp." + moduleName)
+
+ match = re.fullmatch(r'^(\S+)_code$', moduleName)
+ if match:
+ func = getattr(module, f"{match.group(1)}")
+ self.layout().register_pcell(match.group(1), PCellWrapper(func(), tech))
self.register("SG13_dev")
diff --git a/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/dantenna_code.py b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/dantenna_code.py
new file mode 100644
index 00000000..372de78f
--- /dev/null
+++ b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/dantenna_code.py
@@ -0,0 +1,100 @@
+__version__ = "$Revision: #3 $"
+
+from cni.dlo import *
+from .geometry import *
+from .utility_functions import *
+
+import math
+
+
+class dantenna(DloGen):
+
+ @classmethod
+ def defineParamSpecs(self, specs):
+ techparams = specs.tech.getTechParams()
+
+ CDFVersion = techparams['CDFVersion']
+ model = techparams['dantenna_model']
+ defL = techparams['dantenna_defL']
+ defW = techparams['dantenna_defW']
+
+ specs('cdf_version', CDFVersion, 'CDF Version')
+ specs('Display', 'Selected', 'Display', ChoiceConstraint(['All', 'Selected']))
+ specs('model', model, 'Model name')
+ specs('Calculate', 'a', 'Calculate', ChoiceConstraint(['a', 'w', 'l', 'w&l']))
+
+ specs('w', defW, 'Width')
+ specs('l', defL, 'Length')
+ specs('a', eng_string(CbDiodeCalc('a', 0, Numeric(defL), Numeric(defW), 'dantenna'), 3), 'Device area')
+ specs('p', eng_string(CbDiodeCalc('p', 0, Numeric(defL), Numeric(defW), 'dantenna'), 3), 'Device perimeter')
+
+ specs('addRecLayer', 't', 'Add Recognition Layer', ChoiceConstraint(['t', 'f']))
+ specs('bn', 'sub!', 'Bulk node connection')
+ specs('off', False, 'Device initially off')
+ specs('Vd', '', 'Initial diode voltage')
+ specs('perim', '', 'Junction perimeter factor')
+ specs('m', '1', 'Multiplier')
+ specs('trise', '', 'Temp rise from ambient')
+ specs('region', ' ', 'Estimated operating region', ChoiceConstraint([' ', 'off', 'on']))
+ specs('dtemp', '', 'Temperature difference')
+ specs('mode', 'No', 'Linearized Region', ChoiceConstraint(['Yes', 'No']))
+
+ def setupParams(self, params):
+ # process parameter values entered by user
+ self.w = Numeric(params['w']) * 1e6
+ self.l = Numeric(params['l']) * 1e6
+ self.addRecLayer = params['addRecLayer']
+
+ def genLayout(self):
+ w = self.w
+ l = self.l
+ addRecLayer = self.addRecLayer
+
+ self.techparams = self.tech.getTechParams()
+ epsilon = self.techparams['epsilon1']
+
+ typ = 'N'
+ metall_layer = Layer('Metal1')
+ ndiff_layer = Layer('Activ')
+ pdiff_layer = Layer('Activ')
+ pdiffx_layer = Layer('pSD')
+ cont_layer = Layer('Cont')
+ diods_layer = Layer('Recog', 'diode')
+ textlayer = Layer('TEXT', 'drawing')
+
+ cont_size = self.techparams['Cnt_a']
+ cont_dist = self.techparams['Cnt_b']
+ cont_diff_over = self.techparams['Cnt_c']
+ pdiffx_over = self.techparams['pSD_c']
+ wmin = Numeric(self.techparams['dantenna_minW']) * 1e6
+ lmin = Numeric(self.techparams['dantenna_minL']) * 1e6
+ diods_over = Numeric(self.techparams['dantenna_dov']) * 1e6
+
+ dbReplaceProp(self, 'pin#', 2)
+
+ if w < wmin - epsilon:
+ w = wmin
+ hiGetAttention()
+ print('W < ' + str(wmin))
+
+ if l < lmin - epsilon:
+ l = lmin
+ hiGetAttention()
+ print('L < ' + str(lmin))
+
+ dbCreateLabel(self, textlayer, Point(w / 2, l / 2), 'dant', 'centerCenter', 'R0', Font.EURO_STYLE, 0.2)
+
+ bBox = DrawContArray(self, cont_layer, Box(0, 0, w, l), cont_size, cont_dist, cont_diff_over)
+
+ dbCreateRect(self, metall_layer, bBox)
+
+ MkPin(self, 'MINUS', 1, bBox, metall_layer)
+
+ if typ == 'N':
+ dbCreateRect(self, ndiff_layer, Box(0, 0, w, l))
+ else:
+ dbCreateRect(self, pdiff_layer, Box(0, 0, w, l))
+ dbCreateRect(self, pdiffx_layer, Box(-pdiffx_over, -pdiffx_over, w + pdiffx_over, l + pdiffx_over))
+
+ if addRecLayer == 't':
+ dbCreateRect(self, diods_layer, Box(-diods_over, -diods_over, w + diods_over, l + diods_over))
\ No newline at end of file
diff --git a/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/dpantenna_code.py b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/dpantenna_code.py
new file mode 100644
index 00000000..f4882d07
--- /dev/null
+++ b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/dpantenna_code.py
@@ -0,0 +1,98 @@
+__version__ = '$Revision: #3 $'
+
+from cni.dlo import *
+from .geometry import *
+from .utility_functions import *
+
+import math
+
+
+class dpantenna(DloGen):
+
+ @classmethod
+ def defineParamSpecs(self, specs):
+ techparams = specs.tech.getTechParams()
+
+ CDFVersion = techparams['CDFVersion']
+ model = techparams['dpantenna_model']
+ defL = techparams['dpantenna_defL']
+ defW = techparams['dpantenna_defW']
+
+ specs('cdf_version', CDFVersion, 'CDF Version')
+ specs('Display', 'Selected', 'Display', ChoiceConstraint(['All', 'Selected']))
+ specs('model', model, 'Model name')
+ specs('Calculate', 'a', 'Calculate', ChoiceConstraint(['a', 'w', 'l', 'w&l']))
+
+ specs('w', defW, 'Width')
+ specs('l', defL, 'Length')
+ specs('a', eng_string(CbDiodeCalc('a', 0, Numeric(defL), Numeric(defW), 'dantenna'), 3), 'Device area')
+ specs('p', eng_string(CbDiodeCalc('p', 0, Numeric(defL), Numeric(defW), 'dantenna'), 3), 'Device perimeter')
+
+ specs('addRecLayer', 't', 'Add Recognition Layer', ChoiceConstraint(['t', 'f']))
+ specs('off', False, 'Device initially off')
+ specs('Vd', '', 'Initial diode voltage')
+ specs('perim', '', 'Junction perimeter factor')
+ specs('m', '1', 'Multiplier')
+ specs('trise', '', 'Temp rise from ambient')
+ specs('region', ' ', 'Estimated operating region', ChoiceConstraint([' ', 'off', 'on']))
+ specs('dtemp', '', 'Temperature difference')
+ specs('mode', 'No', 'Linearized Region', ChoiceConstraint(['Yes', 'No']))
+
+ def setupParams(self, params):
+ # process parameter values entered by user
+ self.w = Numeric(params['w']) * 1e6
+ self.l = Numeric(params['l']) * 1e6
+ self.addRecLayer = params['addRecLayer']
+
+ def genLayout(self):
+ w = self.w
+ l = self.l
+ addRecLayer = self.addRecLayer
+
+ self.techparams = self.tech.getTechParams()
+ self.epsilon = self.techparams['epsilon1']
+
+ typ = 'P'
+ metall_layer = Layer('Metal1')
+ ndiff_layer = Layer('Activ')
+ pdiff_layer = Layer('Activ')
+ pdiffx_layer = Layer('pSD')
+ cont_layer = Layer('Cont')
+ diods_layer = Layer('Recog', 'diode')
+ textlayer = Layer('TEXT')
+ cont_size = self.techparams['Cnt_a']
+ cont_dist = self.techparams['Cnt_b']
+ cont_diff_over = self.techparams['Cnt_c']
+ pdiffx_over = self.techparams['pSD_c']
+ wmin = Numeric(self.techparams['dpantenna_minW']) * 1e6
+ lmin = Numeric(self.techparams['dpantenna_minL']) * 1e6
+ diods_over = Numeric(self.techparams['dpantenna_dov']) * 1e6
+
+ dbReplaceProp(self, 'pin#', 2)
+
+ if w < wmin - self.epsilon:
+ w = wmin
+ hiGetAttention()
+ print('W < ' + str(wmin))
+
+ if l < lmin - self.epsilon:
+ l = lmin
+ hiGetAttention()
+ print('L < ' + str(lmin))
+
+ dbCreateLabel(self, textlayer, Point(w / 2, l / 2), 'dpant', 'centerCenter', 'R0', Font.EURO_STYLE, 0.2)
+
+ bBox = DrawContArray(self, cont_layer, Box(0, 0, w, l), cont_size, cont_dist, cont_diff_over)
+
+ dbCreateRect(self, metall_layer, bBox)
+
+ MkPin(self, 'MINUS', 1, bBox, metall_layer)
+
+ if typ == 'N':
+ dbCreateRect(self, ndiff_layer, Box(0, 0, w, l))
+ else:
+ dbCreateRect(self, pdiff_layer, Box(0, 0, w, l))
+ dbCreateRect(self, pdiffx_layer, Box(-pdiffx_over, -pdiffx_over, w + pdiffx_over, l + pdiffx_over))
+
+ if addRecLayer == 't':
+ dbCreateRect(self, diods_layer, Box(-diods_over, -diods_over, w + diods_over, l + diods_over))
diff --git a/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/geometry.py b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/geometry.py
index 9599b053..1867bfb7 100644
--- a/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/geometry.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/geometry.py
@@ -23,7 +23,6 @@
from cni.geo import fgAnd
from cni.geo import fgXor
from cni.geo import fgNot
-from cni.geo import fgMerge
from .utility_functions import *
from math import *
@@ -118,7 +117,6 @@ def dbLayerAndList(layerId, shapes):
def dbLayerXor(layerId, id1, id2):
if type(layerId) == str :
layerId = Layer(layerId)
-
xorId = id1.fgXor(id2, layerId)
return xorId
@@ -126,13 +124,11 @@ def dbLayerXor(layerId, id1, id2):
#***********************************************************************************************************************
# dbLayerXorList
#***********************************************************************************************************************
-def dbLayerXorList(layerId, shapes):
+def dbLayerXorList(layerId, shapes1, shapes2):
if type(layerId) == str :
layerId = Layer(layerId)
- xorId = shapes[0]
- for id in shapes[1:] :
- xorId = fgXor(xorId, id, layerId)
+ xorId = fgXor(ulist(shapes1), ulist(shapes2), layerId)
return xorId
@@ -173,9 +169,12 @@ def dbLayerMerge(self, layerId):
return mergeId
#***********************************************************************************************************************
-# dbCopyShape
+# dbLayerSize
#***********************************************************************************************************************
-def dbLayerSize(self, layerId, shapes, size, numPoints, grid = 0) :
+def dbLayerSize(layerId, shapes, size, grid = 0) :
+ if type(layerId) == str :
+ layerId = Layer(layerId)
+
for id in shapes :
id.fgSize(ShapeFilter(), size, layerId, grid)
diff --git a/ihp-sg13g2/libs.tech/pycell/inductor2_code.py b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/inductor2_code.py
similarity index 90%
rename from ihp-sg13g2/libs.tech/pycell/inductor2_code.py
rename to ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/inductor2_code.py
index 071b6137..c66e95e0 100644
--- a/ihp-sg13g2/libs.tech/pycell/inductor2_code.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/inductor2_code.py
@@ -1,13 +1,13 @@
########################################################################
#
-# Copyright 2023 IHP PDK Authors
-#
+# Copyright 2024 IHP PDK Authors
+#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# https://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,10 +17,10 @@
########################################################################
__version__ = '$Revision: #3 $'
-from inductors_code import *
-
+from .inductors_code import *
+
class inductor2(inductors):
-
+
DMIN = '15.48u'
NR = 1
model = 'inductor2'
diff --git a/ihp-sg13g2/libs.tech/pycell/inductor2_sc_code.py b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/inductor2_sc_code.py
similarity index 90%
rename from ihp-sg13g2/libs.tech/pycell/inductor2_sc_code.py
rename to ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/inductor2_sc_code.py
index a2f19f0e..82e3b122 100644
--- a/ihp-sg13g2/libs.tech/pycell/inductor2_sc_code.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/inductor2_sc_code.py
@@ -1,13 +1,13 @@
########################################################################
#
-# Copyright 2023 IHP PDK Authors
-#
+# Copyright 2024 IHP PDK Authors
+#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# https://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,10 +17,10 @@
########################################################################
__version__ = '$Revision: #3 $'
-from inductors_code import *
-
+from .inductors_code import *
+
class inductor2_sc(inductors):
-
+
DMIN = '15.48u'
NR = 1
model = 'inductor2_sc'
diff --git a/ihp-sg13g2/libs.tech/pycell/inductor2_sp_code.py b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/inductor2_sp_code.py
similarity index 90%
rename from ihp-sg13g2/libs.tech/pycell/inductor2_sp_code.py
rename to ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/inductor2_sp_code.py
index f9f44c1c..0e5d584c 100644
--- a/ihp-sg13g2/libs.tech/pycell/inductor2_sp_code.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/inductor2_sp_code.py
@@ -1,13 +1,13 @@
########################################################################
#
-# Copyright 2023 IHP PDK Authors
-#
+# Copyright 2024 IHP PDK Authors
+#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# https://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,9 +17,9 @@
########################################################################
__version__ = '$Revision: #3 $'
-from inductors_code import *
-
+from .inductors_code import *
+
class inductor2_sp(inductors):
-
+
DMIN = '15.48u'
model = 'inductor2_sp'
diff --git a/ihp-sg13g2/libs.tech/pycell/inductor3_code.py b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/inductor3_code.py
similarity index 90%
rename from ihp-sg13g2/libs.tech/pycell/inductor3_code.py
rename to ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/inductor3_code.py
index 75d69e9d..a0685fb2 100644
--- a/ihp-sg13g2/libs.tech/pycell/inductor3_code.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/inductor3_code.py
@@ -1,13 +1,13 @@
########################################################################
#
-# Copyright 2023 IHP PDK Authors
-#
+# Copyright 2024 IHP PDK Authors
+#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# https://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,10 +17,10 @@
########################################################################
__version__ = '$Revision: #3 $'
-from inductors_code import *
-
+from .inductors_code import *
+
class inductor3(inductors):
-
+
DMIN = '25.84u'
NR = 2
model = 'inductor3'
diff --git a/ihp-sg13g2/libs.tech/pycell/inductor3_sc_code.py b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/inductor3_sc_code.py
similarity index 90%
rename from ihp-sg13g2/libs.tech/pycell/inductor3_sc_code.py
rename to ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/inductor3_sc_code.py
index b33fd717..0c7413b3 100644
--- a/ihp-sg13g2/libs.tech/pycell/inductor3_sc_code.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/inductor3_sc_code.py
@@ -1,13 +1,13 @@
########################################################################
#
-# Copyright 2023 IHP PDK Authors
-#
+# Copyright 2024 IHP PDK Authors
+#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# https://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,10 +17,10 @@
########################################################################
__version__ = '$Revision: #3 $'
-from inductors_code import *
-
+from .inductors_code import *
+
class inductor3_sc(inductors):
-
+
DMIN = '25.84u'
NR = 2
model = 'inductor3_sc'
diff --git a/ihp-sg13g2/libs.tech/pycell/inductor3_sp_code.py b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/inductor3_sp_code.py
similarity index 90%
rename from ihp-sg13g2/libs.tech/pycell/inductor3_sp_code.py
rename to ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/inductor3_sp_code.py
index 7de61657..93495b0f 100644
--- a/ihp-sg13g2/libs.tech/pycell/inductor3_sp_code.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/inductor3_sp_code.py
@@ -1,13 +1,13 @@
########################################################################
#
-# Copyright 2023 IHP PDK Authors
-#
+# Copyright 2024 IHP PDK Authors
+#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# https://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,9 +17,9 @@
########################################################################
__version__ = '$Revision: #3 $'
-from inductors_code import *
-
+from .inductors_code import *
+
class inductor3_sp(inductors):
-
+
DMIN = '25.84u'
model = 'inductor3_sp'
diff --git a/ihp-sg13g2/libs.tech/pycell/inductors_code.py b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/inductors_code.py
similarity index 92%
rename from ihp-sg13g2/libs.tech/pycell/inductors_code.py
rename to ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/inductors_code.py
index 99e6dec0..67ee2808 100644
--- a/ihp-sg13g2/libs.tech/pycell/inductors_code.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/inductors_code.py
@@ -1,13 +1,13 @@
########################################################################
#
-# Copyright 2023 IHP PDK Authors
-#
+# Copyright 2024 IHP PDK Authors
+#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# https://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,21 +18,21 @@
__version__ = '$Revision: #3 $'
from cni.dlo import *
-from geometry import *
-from utility_functions import *
+from .geometry import *
+from .utility_functions import *
import math
-
+
class inductors(DloGen):
- @classmethod
+ @classmethod
def defineParamSpecs(self, specs):
techparams = specs.tech.getTechParams()
-
+
CDFVersion = techparams['CDFVersion']
-
- defS = '2.1u'
- defW = '2u'
+
+ defS = '2.1u'
+ defW = '2u'
minS = defS
minW = defW
if 'inductor2' in self.model :
@@ -47,16 +47,16 @@ def defineParamSpecs(self, specs):
defL = '221.5pH'
defR = '1.386'
model = 'inductor3'
-
+
grid = techparams['grid']
minDf = inductor_minD(2, 2.1, defNr_t, grid)
minD = str(minDf)+'u'
defD = minD
-
+
specs('cdf_version', CDFVersion, 'CDF Version')
specs('Display', 'Selected', 'Display', ChoiceConstraint(['All', 'Selected']))
specs('model', self.model, 'Model name')
-
+
specs('w', defW, 'Width')
specs('s', defS, 'Space')
specs('d', self.DMIN, 'The distance in the center of the inductor')
@@ -65,10 +65,10 @@ def defineParamSpecs(self, specs):
specs('nr_r', defNr_t, 'The number of turns')
specs('blockqrc', True, 'Block QRC layer')
specs('subE', False, 'Substrate Etching')
-
+
specs('lEstim', defL, 'Inductance (estim.)')
specs('rEstim', defR, 'Resistance (estim.)')
-
+
specs('Wmin', minW, 'Wmin')
specs('Smin', minS, 'Smin')
specs('Dmin', self.DMIN, 'Dmin')
@@ -98,14 +98,14 @@ def genLayout(self):
nr_r = self.nr_r
blockqrc = self.blockqrc
subE = self.subE
-
+
cellName = self.__class__.__name__
-
+
w = GridFix(Numeric(w)*5e5)*2
s = GridFix(Numeric(s)*1e6)
d = GridFix(Numeric(d)*5e5)*2
d1 = d
-
+
# layers
TM2 = Layer('TopMetal2', 'drawing')
TM1 = Layer('TopMetal1', 'drawing')
@@ -123,83 +123,83 @@ def genLayout(self):
NoTMet2Filler = Layer('TopMetal2', 'nofill')
NoRCX = Layer('NoRCX', 'drawing')
substrateE = Layer('LBE', 'drawing')
-
+
self.techparams = self.tech.getTechParams()
self.epsilon = self.techparams['epsilon1']
#tech_libName = self.techparams['libName']
#grid = self.tech.getGridResolution()
-
+
nr_vias = round((w+0.06)/1.96-0.5)
-
+
var = 1+sqrt(2)
grid = 0.01
d_min = inductor_minD(w, s, nr_r, grid)
if d < d_min :
d = d_min
-
+
lat_sm = GridFix(d/(2*var))*2
lat_big = GridFix((d+2*w)/var)
cateta_sm = (d-lat_sm)/2
cateta_big = GridFix((d+2*w)/(var*sqrt(2)))
-
+
type2 = '2' in cellName
type3 = '3' in cellName
typesc = '_sc' in cellName
-
+
if type3 :
pathPoints = PointList([Point(0, -1), Point(0, 30)])
dbCreatePath(self, TM2, pathPoints, w);
dbCreateLabel(self, Layer('TEXT', 'drawing'), Point(0, 0), 'LC', 'centerCenter', 'R0', Font.EURO_STYLE, w/2)
pcInst = dbCreateRect(self, TM2p, Box(-w/2, -1, w/2, 1))
pcPin = dbCreatePin(self, 'LC', pcInst)
-
- x1 = GridFix(lat_sm/2)-w
+
+ x1 = GridFix(lat_sm/2)-w
y1 = 30-w/2
x2 = GridFix(lat_big/2)
x = x1+(x2-x1)/2
y2 = nr_r*w+(nr_r-1)*s+30-w
x_cross = GridFix(w/sqrt(2)+s/2)
- d_via_cross = GridFix(s*0.4143)+grid
+ d_via_cross = GridFix(s*0.4143)+grid
d1_via_cross = GridFix(w*0.4143)+grid
x_via = x_cross+d_via_cross+grid
-
+
if type3 or (not oddp(nr_r)) :
dbCreateRect(self, TM2, Box(-x_via, 30, x_via, w+30))
if type2 :
dbCreateRect(self, IND, Box(-w/2-grid, 30-grid, w/2+grid, 30+w+grid))
dbCreateLabel(self, Layer('TEXT', 'drawing'), Point(0, w/2+30), 'L2_TM2', 'centerCenter', 'R0', Font.EURO_STYLE, w/6)
-
-
+
+
lat_big2 = d1_via_cross+grid
if (nr_r == 2) or (nr_r == 1) :
if type3 :
x1_via = s+w/2+0.5+(w-nr_vias*0.9-(nr_vias-1)*1.06-1)/2
else :
x1_via = s/2+0.5+(w-nr_vias*0.9-(nr_vias-1)*1.06-1)/2
-
+
else :
x1_via = x_via+s+w+0.5+(w-nr_vias*0.9-(nr_vias-1)*1.06-1)/2
-
+
y1_via = y2+0.5+(w-nr_vias*0.9-(nr_vias-1)*1.06-1)/2
-
+
if nr_r != 1 :
for pcIndex1 in range(int(nr_vias)) :
for pcIndex2 in range(int(nr_vias)) :
dbCreateRect(self, TV2, Box(x1_via, y1_via, x1_via+0.9, y1_via+0.9))
dbCreateRect(self, TV2, Box(-x1_via, y1_via, -(x1_via+0.9), y1_via+0.9))
x1_via = x1_via+1.96
-
+
if nr_r == 2 :
if type3 :
x1_via = s+w/2+0.5+(w-nr_vias*0.9-(nr_vias-1)*1.06-1)/2
else :
x1_via = s/2+0.5+(w-nr_vias*0.9-(nr_vias-1)*1.06-1)/2
-
+
else :
x1_via = x_via+s+w+0.5+(w-nr_vias*0.9-(nr_vias-1)*1.06-1)/2
-
+
y1_via = y1_via+1.96
-
+
for pcIndexX in range(nr_r) :
if pcIndexX == 0 :
if (nr_r == 2) or (nr_r == 1) :
@@ -217,24 +217,24 @@ def genLayout(self):
polyPoints2 = PointList([Point(-s/2, y2), Point(-s/2, y2+w), Point(-lat_sm/2, y2+w), Point(-d/2, y2+w+cateta_sm), Point(-d/2, y2+w+cateta_sm+lat_sm), Point(-lat_sm/2, y2+w+d),
Point(-x_via, y2+w+d), Point(-x_via, y2+w*2+d), Point(-lat_sm/2-d1_via_cross, y2+d+2*w), Point(-(d+2*w)/2, y2+w+cateta_sm+lat_sm+d1_via_cross),
Point(-(d+2*w)/2, y2+w+cateta_sm-d1_via_cross), Point(-lat_sm/2-d1_via_cross, y2)])
-
+
else :
polyPoints1 = PointList([Point(x_via+s+w, y2), Point(x_via+s+w, y2+w), Point(lat_sm/2, y2+w), Point(d/2, y2+w+cateta_sm), Point(d/2, y2+w+cateta_sm+lat_sm), Point(lat_sm/2, y2+w+d),
- Point(x_via, y2+w+d), Point(x_via, y2+w*2+d), Point(lat_sm/2+d1_via_cross, y2+d+2*w), Point((d+2*w)/2, y2+w+cateta_sm+lat_sm+d1_via_cross),
+ Point(x_via, y2+w+d), Point(x_via, y2+w*2+d), Point(lat_sm/2+d1_via_cross, y2+d+2*w), Point((d+2*w)/2, y2+w+cateta_sm+lat_sm+d1_via_cross),
Point((d+2*w)/2, y2+w+cateta_sm-d1_via_cross), Point(lat_sm/2+d1_via_cross, y2)])
- polyPoints2 = PointList([Point(-x_via-s-w, y2), Point(-x_via-s-w, y2+w), Point(-lat_sm/2, y2+w), Point(-d/2, y2+w+cateta_sm), Point(-d/2, y2+w+cateta_sm+lat_sm), Point(-lat_sm/2, y2+w+d),
- Point(-x_via, y2+w+d), Point(-x_via, y2+w*2+d), Point(-lat_sm/2-d1_via_cross, y2+d+2*w), Point(-(d+2*w)/2, y2+w+cateta_sm+lat_sm+d1_via_cross),
+ polyPoints2 = PointList([Point(-x_via-s-w, y2), Point(-x_via-s-w, y2+w), Point(-lat_sm/2, y2+w), Point(-d/2, y2+w+cateta_sm), Point(-d/2, y2+w+cateta_sm+lat_sm), Point(-lat_sm/2, y2+w+d),
+ Point(-x_via, y2+w+d), Point(-x_via, y2+w*2+d), Point(-lat_sm/2-d1_via_cross, y2+d+2*w), Point(-(d+2*w)/2, y2+w+cateta_sm+lat_sm+d1_via_cross),
Point(-(d+2*w)/2, y2+w+cateta_sm-d1_via_cross), Point(-lat_sm/2-d1_via_cross, y2)])
-
+
else :
- polyPoints1 = PointList([Point(x1, y2), Point(x1, y2+w), Point(lat_sm/2, y2+w), Point(d/2, y2+w+cateta_sm), Point(d/2, y2+w+cateta_sm+lat_sm), Point(lat_sm/2, y2+w+d), Point(x_via, y2+w+d),
+ polyPoints1 = PointList([Point(x1, y2), Point(x1, y2+w), Point(lat_sm/2, y2+w), Point(d/2, y2+w+cateta_sm), Point(d/2, y2+w+cateta_sm+lat_sm), Point(lat_sm/2, y2+w+d), Point(x_via, y2+w+d),
Point(x_via, y2+w*2+d), Point(lat_sm/2+d1_via_cross, y2+d+2*w), Point((d+2*w)/2, y2+w+cateta_sm+lat_sm+d1_via_cross), Point((d+2*w)/2, y2+w+cateta_sm-d1_via_cross), Point(lat_sm/2+d1_via_cross, y2)])
polyPoints2 = PointList([Point(-x1, y2), Point(-x1, y2+w), Point(-lat_sm/2, y2+w), Point(-d/2, y2+w+cateta_sm), Point(-d/2, y2+w+cateta_sm+lat_sm), Point(-lat_sm/2, y2+w+d), Point(-x_via, y2+w+d),
Point(-x_via, y2+w*2+d), Point(-lat_sm/2-d1_via_cross, y2+d+2*w), Point(-(d+2*w)/2, y2+w+cateta_sm+lat_sm+d1_via_cross), Point(-(d+2*w)/2, y2+w+cateta_sm-d1_via_cross), Point(-lat_sm/2-d1_via_cross, y2)])
-
+
dbCreatePolygon(self, TM2, polyPoints1)
dbCreatePolygon(self, TM2, polyPoints2)
-
+
# potential stopper left and right
if type3 and pcIndexX == nr_r-1 :
x_mid = d/2+w/2
@@ -243,45 +243,45 @@ def genLayout(self):
dbCreateLabel(self, Layer('TEXT', 'drawing'), Point(x_mid, y_mid), 'L2_TM2', 'centerCenter', 'R0', Font.EURO_STYLE, w/6)
lh = eng_string(Numeric(l)*0.5, 3)
rh = eng_string(Numeric(r)*0.5, 3)
-
+
if cellName == 'inductor3' :
dbCreateLabel(self, Layer('TEXT', 'drawing'), Point(x_mid, y_mid+w/3), 'l='+lh, 'centerCenter', 'R0', Font.EURO_STYLE, w/6)
dbCreateLabel(self, Layer('TEXT', 'drawing'), Point(x_mid, y_mid-w/3), 'r='+rh, 'centerCenter', 'R0', Font.EURO_STYLE, w/6)
-
+
if cellName == 'inductor3_sc' :
dbCreateLabel(self, Layer('TEXT', 'drawing'), Point(x_mid, y_mid-w/3), 'model='+model, 'centerCenter', 'R0', Font.EURO_STYLE, w/6)
-
+
x_mid = -d/2-w/2
dbCreateRect(self, IND, Box(-d/2+grid, y_mid-w/2, -(d+2*w)/2-grid, y_mid+w/2))
dbCreateLabel(self, Layer('TEXT', 'drawing'), Point(x_mid, y_mid), 'L2_TM2', 'centerCenter', 'R0', Font.EURO_STYLE, w/6)
-
+
if cellName == 'inductor3' :
dbCreateLabel(self, Layer('TEXT', 'drawing'), Point(x_mid, y_mid+w/3), 'l='+lh, 'centerCenter', 'R0', Font.EURO_STYLE, w/6)
dbCreateLabel(self, Layer('TEXT', 'drawing'), Point(x_mid, y_mid-w/3), 'r='+rh, 'centerCenter', 'R0', Font.EURO_STYLE, w/6)
-
+
if cellName == 'inductor3_sc' :
dbCreateLabel(self, Layer('TEXT', 'drawing'), Point(x_mid, y_mid-w/3), 'model='+model, 'centerCenter', 'R0', Font.EURO_STYLE, w/6)
-
-
+
+
if evenp(pcIndexX) :
if type2 and (oddp(nr_r) and (pcIndexX == nr_r-1)) :
polyPoints4 = PointList([Point(x_via, y2+w+d), Point(x_via, y2+w*2+d), Point(-x_via, y2+w*2+d), Point(-x_via, y2+w+d)])
dbCreatePolygon(self, TM2, polyPoints4)
dbCreateRect(self, IND, Box(-w/2-grid, y2+w*2+d+grid, w/2+grid, y2+w+d-grid))
dbCreateLabel(self, Layer('TEXT', 'drawing'), Point(0, y2+w+w/2+d), 'L2_TM2', 'centerCenter', 'R0', Font.EURO_STYLE, w/6)
-
+
if cellName == 'inductor2' :
dbCreateLabel(self, Layer('TEXT', 'drawing'), Point(0, y2+w+w/2+d+w/3), 'l='+l, 'centerCenter', 'R0', Font.EURO_STYLE, w/6)
dbCreateLabel(self, Layer('TEXT', 'drawing'), Point(0, y2+w+w/2+d-w/3), 'r='+r, 'centerCenter', 'R0', Font.EURO_STYLE, w/6)
-
+
if cellName == 'inductor2_sc' :
dbCreateLabel(self, Layer('TEXT', 'drawing'), Point(0, y2+w+w/2+d-w/3), 'model='+model, 'centerCenter', 'R0', Font.EURO_STYLE, w/6)
-
+
else :
- polyPoints3 = PointList([Point(x_via+w, y2+w+d), Point(x_via+w, y2+w*2+d), Point(x_cross, y2+w*2+d), Point(x_cross-(w+s+2*grid), y2+w*3+s+d+2*grid), Point(-x_via-w, y2+w*3+s+d+2*grid),
+ polyPoints3 = PointList([Point(x_via+w, y2+w+d), Point(x_via+w, y2+w*2+d), Point(x_cross, y2+w*2+d), Point(x_cross-(w+s+2*grid), y2+w*3+s+d+2*grid), Point(-x_via-w, y2+w*3+s+d+2*grid),
Point(-x_via-w, y2+w*2+s+d+2*grid), Point(-x_cross, y2+w*2+s+d+2*grid), Point(w+s+2*grid-x_cross, y2+w+d)])
dbCreatePolygon(self, TM1, polyPoints3)
- polyPoints3 = PointList([Point(-x_via, y2+w+d), Point(-x_via, y2+w*2+d), Point(-x_cross, y2+w*2+d), Point(w+s+2*grid-x_cross, y2+w*3+s+d+2*grid), Point(x_via, y2+w*3+s+d+2*grid),
+ polyPoints3 = PointList([Point(-x_via, y2+w+d), Point(-x_via, y2+w*2+d), Point(-x_cross, y2+w*2+d), Point(w+s+2*grid-x_cross, y2+w*3+s+d+2*grid), Point(x_via, y2+w*3+s+d+2*grid),
Point(x_via, y2+w*2+s+d+2*grid), Point(x_cross+3*grid, y2+w*2+s+d+2*grid), Point(x_cross-(w+s-grid), y2+w+d)])
dbCreatePolygon(self, TM2, polyPoints3)
x1_via = x_via+0.5+(w-nr_vias*0.9-(nr_vias-1)*1.06-1)/2
@@ -291,15 +291,15 @@ def genLayout(self):
dbCreateRect(self, TV2, Box( x1_via, y1_via, x1_via+0.9, y1_via+0.9))
dbCreateRect(self, TV2, Box(-x1_via, y1_via+s+w, -(x1_via+0.9), y1_via+0.9+s+w))
x1_via = x1_via+1.96
-
+
x1_via = x_via+0.5+(w-nr_vias*0.9-(nr_vias-1)*1.06-1)/2
y1_via = y1_via+1.96
-
+
if pcIndexX != 0 :
- polyPoints3 = PointList([Point(x_via, y2), Point(x_via, y2+w), Point(x_cross+grid, y2+w), Point(x_cross-(w+s)+grid, y2+w*2+s), Point(-x_via, y2+w*2+s),
+ polyPoints3 = PointList([Point(x_via, y2), Point(x_via, y2+w), Point(x_cross+grid, y2+w), Point(x_cross-(w+s)+grid, y2+w*2+s), Point(-x_via, y2+w*2+s),
Point(-x_via, y2+w+s), Point(-x_cross, y2+w+s), Point(-x_cross+w+s, y2)])
dbCreatePolygon(self, TM2, polyPoints3)
- polyPoints3 = PointList([Point(-x_via-w, y2), Point(-x_via-w, y2+w), Point(-x_cross-grid, y2+w), Point(-x_cross+w+s-grid, y2+w*2+s), Point(x_via+w+grid, y2+w*2+s),
+ polyPoints3 = PointList([Point(-x_via-w, y2), Point(-x_via-w, y2+w), Point(-x_cross-grid, y2+w), Point(-x_cross+w+s-grid, y2+w*2+s), Point(x_via+w+grid, y2+w*2+s),
Point(x_via+w+grid, y2+w+s), Point(x_cross, y2+w+s), Point(x_cross-(w+s), y2)])
dbCreatePolygon(self, TM1, polyPoints3)
x1_via = x_via+grid+0.5+(w-nr_vias*0.9-(nr_vias-1)*1.06-1)/2
@@ -309,18 +309,18 @@ def genLayout(self):
dbCreateRect(self, TV2, Box(x1_via, y1_via, x1_via+0.9, y1_via+0.9))
dbCreateRect(self, TV2, Box(-x1_via+grid, y1_via-s-w, -(x1_via-grid+0.9), y1_via+0.9-s-w))
x1_via = x1_via+1.96
-
+
x1_via = x_via+grid+0.5+(w-nr_vias*0.9-(nr_vias-1)*1.06-1)/2
y1_via = y1_via+1.96
-
+
y2 = y2-w-s
x1 = x_via
d = d+2*(s+w+grid)
- lat_sm = GridFix(d/(2*var))*2
+ lat_sm = GridFix(d/(2*var))*2
lat_big = GridFix((d+2*w)/var)
cateta_sm = (d-lat_sm)/2
cateta_big = GridFix((d+2*w)/(var*sqrt(2)))
-
+
if type2 :
if (nr_r == 2) or (nr_r == 1) :
x1 = (w+s)/2
@@ -331,7 +331,7 @@ def genLayout(self):
x1 = w+s
else :
x1 = x1+w/2+s+w
-
+
pathPoints1 = PointList([Point(x1, -1), Point(x1, nr_r*w+(nr_r-1)*s+30)])
pathPoints2 = PointList([Point(-x1, -1),Point( -x1, nr_r*w+(nr_r-1)*s+30)])
if type2 and (nr_r == 1) :
@@ -344,22 +344,22 @@ def genLayout(self):
dbCreatePath(self, TM1, pathPoints2, w);
pcInst1 = dbCreateRect(self, TM1p, Box(x1-w/2, -1, x1+w/2, 1))
pcInst2 = dbCreateRect(self, TM1p, Box(-x1-w/2, -1, -x1+w/2, 1))
-
+
pcPin = dbCreatePin(self, 'LB', pcInst1)
dbCreateLabel(self, Layer('TEXT', 'drawing'), Point(x1, 0), 'LB', 'centerCenter', 'R0', Font.EURO_STYLE, w/2)
pcPin = dbCreatePin(self, 'LA', pcInst2)
dbCreateLabel(self, Layer('TEXT', 'drawing'), Point(-x1, 0), 'LA', 'centerCenter', 'R0', Font.EURO_STYLE, w/2)
-
+
dbCreateLabel(self, Layer('TEXT', 'drawing'), Point(0, y2+cateta_sm/2+lat_sm), cellName, 'centerCenter', 'R0', Font.EURO_STYLE, w)
-
+
y2 = 0
d = d-2*s+2*30
- lat_sm = GridFix(d/(2*var))*2
+ lat_sm = GridFix(d/(2*var))*2
lat_big = GridFix((d+2*w)/var)
cateta_sm = (d-lat_sm)/2
cateta_big = GridFix((d+2*w)/(var*sqrt(2)))
-
- polyPoints1 = PointList([Point(lat_sm/2, y2), Point(d/2, y2+cateta_sm), Point(d/2, y2+cateta_sm+lat_sm), Point(lat_sm/2, y2+d), Point(-lat_sm/2, y2+d),
+
+ polyPoints1 = PointList([Point(lat_sm/2, y2), Point(d/2, y2+cateta_sm), Point(d/2, y2+cateta_sm+lat_sm), Point(lat_sm/2, y2+d), Point(-lat_sm/2, y2+d),
Point(-d/2, y2+cateta_sm+lat_sm), Point(-d/2, y2+cateta_sm), Point(-lat_sm/2, y2)])
dbCreatePolygon(self, PWellBlock, polyPoints1)
dbCreatePolygon(self, NoActFiller, polyPoints1)
@@ -367,16 +367,16 @@ def genLayout(self):
dbCreatePolygon(self, NoMet1Filler, polyPoints1)
dbCreatePolygon(self, NoMet2Filler, polyPoints1)
dbCreatePolygon(self, NoMet3Filler, polyPoints1)
-
+
dbCreatePolygon(self, NoTMet1Filler, polyPoints1)
dbCreatePolygon(self, NoTMet2Filler, polyPoints1)
-
+
if blockqrc :
dbCreatePolygon(self, NoRCX, polyPoints1)
-
+
if subE :
dbCreatePolygon(self, substrateE, polyPoints1)
-
+
y2 = 2*nr_r*w+2*(nr_r-1)*s
d = d1
-
+
diff --git a/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/nmosHV_code.py b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/nmosHV_code.py
new file mode 100644
index 00000000..d8adedc1
--- /dev/null
+++ b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/nmosHV_code.py
@@ -0,0 +1,240 @@
+########################################################################
+#
+# Copyright 2023 IHP PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+########################################################################
+__version__ = "$Revision: #3 $"
+
+from cni.dlo import *
+from .thermal import *
+from .geometry import *
+from .utility_functions import *
+
+import math
+
+class nmosHV(DloGen):
+
+ @classmethod
+ def defineParamSpecs(cls, specs):
+ techparams = specs.tech.getTechParams()
+
+ CDFVersion = techparams['CDFVersion']
+ model = 'sg13_hv_nmos'
+ defL = techparams['nmosHV_defL']
+ defW = techparams['nmosHV_defW']
+ defNG = techparams['nmosHV_defNG']
+ minL = techparams['nmosHV_minL']
+ minW = techparams['nmosHV_minW']
+
+ specs('cdf_version', CDFVersion, 'CDF Version')
+ specs('Display', 'Selected', 'Display', ChoiceConstraint(['All', 'Selected']))
+ specs('model', model, 'Model name')
+
+ specs('w', defW, 'Width')
+ specs('ws', eng_string(Numeric(defW)/Numeric(defNG)), 'SingleWidth')
+ specs('l', defL, 'Length')
+ specs('Wmin', minW, 'Wmin')
+ specs('Lmin', minL, 'Lmin')
+ specs('ng', defNG, 'Number of Gates')
+
+ specs('m', '1', 'Multiplier')
+ specs('trise', '', 'Temp rise from ambient')
+
+ def setupParams(self, params):
+
+ self.w = Numeric(params['w'])*1e6
+ self.ng = int(params['ng'])
+ self.l = Numeric(params['l'])*1e6
+
+ def genLayout(self):
+ w = self.w
+ ng = self.ng
+ l = self.l
+
+ techparams = self.tech.getTechParams()
+ self.techparams = techparams
+ self.epsilon = techparams['epsilon1']
+
+ Cell = self.__class__.__name__
+ typ = 'N'
+ hv = True
+
+ # *************************************************************************
+ # *
+ # * Cell Properties
+ # *
+ # ************************************************************************
+ dbReplaceProp(self, 'ivCellType', 'graphic')
+ dbReplaceProp(self, 'viewSubType', 'maskLayoutParamCell')
+ dbReplaceProp(self, 'instNamePrefix', 'M')
+ dbReplaceProp(self, 'function', 'transistor')
+ dbReplaceProp(self, 'pcellVersion', '$Revision: 1.0 $')
+ dbReplaceProp(self, 'pin#', 5)
+
+ # *************************************************************************
+ # *
+ # * Layer Definitions
+ # *
+ # ************************************************************************
+
+ metall_layer = Layer('Metal1')
+ metall_layer_pin = Layer('Metal1', 'pin')
+ ndiff_layer = Layer('Activ')
+ poly_layer = Layer('GatPoly')
+ poly_layer_pin = Layer('GatPoly', 'pin')
+ locint_layer = Layer('Cont')
+ text_layer = Layer('TEXT', 'drawing')
+ tgo_layer = Layer('ThickGateOx')
+
+ # *************************************************************************
+ # *
+ # * Generic Design Rule Definitions
+ # *
+ # ************************************************************************
+ epsilon = techparams['epsilon1']
+ endcap = techparams['M1_c1']
+ cont_size = techparams['Cnt_a']
+ cont_dist = techparams['Cnt_b']
+ cont_Activ_overRec = techparams['Cnt_c']
+ cont_metall_over = techparams['M1_c']
+ gatpoly_Activ_over = techparams['Gat_c']
+ gatpoly_cont_dist = techparams['Cnt_f']
+ smallw_gatpoly_cont_dist = cont_Activ_overRec + techparams['Gat_d']
+ contActMin = 2 * cont_Activ_overRec + cont_size
+
+ thGateOxGat = techparams['TGO_c']
+ thGateOxAct = techparams['TGO_a']
+
+ dbReplaceProp(self, 'pin#', 5)
+
+ ng = fix(ng + epsilon)
+
+ w = w / ng
+ w = GridFix(w)
+ l = GridFix(l)
+
+ # *************************************************************************
+ # *
+ # * Main body of code
+ # *
+ # ************************************************************************
+
+ if endcap < cont_metall_over:
+ endcap = cont_metall_over
+ if w < contActMin - epsilon: # adjust size of Gate to S/D contact region due to corner
+ gatpoly_cont_dist = smallw_gatpoly_cont_dist
+
+ if hv:
+ labelhv = 'HV'
+ else:
+ labelhv = ''
+
+ xdiff_beg = 0
+ ydiff_beg = 0
+ ydiff_end = w
+
+ xanz = fix((w - 2 * cont_Activ_overRec + cont_dist) / (cont_size + cont_dist) + epsilon)
+ w1 = xanz * (cont_size + cont_dist) - cont_dist + cont_Activ_overRec + cont_Activ_overRec
+ xoffset = (w - w1) / 2
+ xoffset = GridFix(xoffset)
+ diffoffset = 0
+ if w < contActMin:
+ xoffset = 0
+ diffoffset = (contActMin - w) / 2
+ diffoffset = Snap(diffoffset)
+
+ # get the number of contacts
+ lcon = w - 2 * cont_Activ_overRec
+ distc = cont_size + cont_dist
+ ncont = fix((w - 2 * cont_Activ_overRec + cont_dist) / (cont_size + cont_dist) + epsilon)
+ if zerop(ncont):
+ ncont = 1
+
+ diff_cont_offset = GridFix((w - 2 * cont_Activ_overRec - ncont * cont_size - (ncont - 1) * cont_dist) / 2)
+
+ # draw the cont row
+ xcont_beg = xdiff_beg + cont_Activ_overRec
+ ycont_beg = ydiff_beg + cont_Activ_overRec
+ ycont_cnt = ycont_beg + diffoffset + diff_cont_offset
+ xcont_end = xcont_beg + cont_size
+
+ # draw Metal rect
+ # calculate bot and top cont position
+ yMet1 = ycont_cnt - endcap
+ yMet2 = ycont_cnt + cont_size + (ncont - 1) * distc + endcap
+ # is metal1 overlapping Activ?
+ yMet1 = min(yMet1, ydiff_beg + diffoffset)
+ yMet2 = max(yMet2, ydiff_end + diffoffset)
+ dbCreateRect(self, metall_layer, Box(xcont_beg - cont_metall_over, yMet1, xcont_end + cont_metall_over, yMet2))
+
+ # draw contacts and Metall
+ contactArray(self, 0, locint_layer, xcont_beg, ydiff_beg, xcont_end, ydiff_end + diffoffset * 2, 0,
+ cont_Activ_overRec, cont_size, cont_dist)
+
+ MkPin(self, 'S', 3, Box(xcont_beg - cont_metall_over, yMet1, xcont_end + cont_metall_over, yMet2),
+ metall_layer_pin)
+
+ # draw source diffusion
+ dbCreateRect(self, ndiff_layer, Box(xcont_beg - cont_Activ_overRec, ycont_beg - cont_Activ_overRec,
+ xcont_end + cont_Activ_overRec, ycont_beg + cont_size + cont_Activ_overRec))
+
+ for i in range(1, ng + 1):
+ # draw the poly line
+ xpoly_beg = xcont_end + gatpoly_cont_dist
+ ypoly_beg = ydiff_beg - gatpoly_Activ_over
+ xpoly_end = xpoly_beg + l
+ ypoly_end = ydiff_end + gatpoly_Activ_over
+ dbCreateRect(self, poly_layer, Box(xpoly_beg, ypoly_beg + diffoffset, xpoly_end, ypoly_end + diffoffset))
+
+ ihpAddThermalMosLayer(self, Box(xpoly_beg, ypoly_beg + diffoffset, xpoly_end, ypoly_end + diffoffset), True,
+ Cell)
+
+ if i == 1:
+ dbCreateLabel(self, text_layer,
+ Point((xpoly_beg + xpoly_end) / 2, (ypoly_beg + ypoly_end) / 2 + diffoffset), 'nmos'+labelhv,
+ 'centerCenter', 'R90', Font.EURO_STYLE, 0.1)
+
+ if onep(i):
+ MkPin(self, 'G', 2, Box(xpoly_beg, ypoly_beg + diffoffset, xpoly_end, ypoly_end + diffoffset),
+ poly_layer_pin)
+
+ # draw the second cont row
+ xcont_beg = xpoly_end + gatpoly_cont_dist
+ ycont_beg = ydiff_beg + cont_Activ_overRec
+ ycont_cnt = ycont_beg + diffoffset + diff_cont_offset
+ xcont_end = xcont_beg + cont_size
+ dbCreateRect(self, metall_layer,
+ Box(xcont_beg - cont_metall_over, yMet1, xcont_end + cont_metall_over, yMet2))
+
+ contactArray(self, 0, locint_layer, xcont_beg, ydiff_beg, xcont_end, ydiff_end + diffoffset * 2, 0,
+ cont_Activ_overRec, cont_size, cont_dist)
+
+ if onep(i):
+ MkPin(self, 'D', 1, Box(xcont_beg - cont_metall_over, yMet1, xcont_end + cont_metall_over, yMet2),
+ metall_layer_pin)
+
+ # draw drain diffusion
+ dbCreateRect(self, ndiff_layer, Box(xcont_beg - cont_Activ_overRec, ycont_beg - cont_Activ_overRec,
+ xcont_end + cont_Activ_overRec,
+ ycont_beg + cont_size + cont_Activ_overRec))
+
+ # now finish drawing the diffusion
+ xdiff_end = xcont_end + cont_Activ_overRec
+ dbCreateRect(self, ndiff_layer, Box(xdiff_beg, ydiff_beg + diffoffset, xdiff_end, ydiff_end + diffoffset))
+
+ if hv:
+ dbCreateRect(self, tgo_layer,
+ Box(xdiff_beg - thGateOxAct, ydiff_beg - gatpoly_Activ_over - thGateOxGat,
+ xdiff_end + thGateOxAct, ydiff_end + gatpoly_Activ_over + thGateOxGat))
\ No newline at end of file
diff --git a/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/nmos_code.py b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/nmos_code.py
index 04ed2e23..7dedb1e9 100644
--- a/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/nmos_code.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/nmos_code.py
@@ -1,13 +1,13 @@
########################################################################
#
-# Copyright 2023 IHP PDK Authors
-#
+# Copyright 2024 IHP PDK Authors
+#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# https://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -30,7 +30,7 @@ class nmos(DloGen):
@classmethod
def defineParamSpecs(cls, specs):
techparams = specs.tech.getTechParams()
-
+
CDFVersion = techparams['CDFVersion']
model = 'sg13_lv_nmos'
defL = techparams['nmos_defL']
@@ -38,18 +38,18 @@ def defineParamSpecs(cls, specs):
defNG = techparams['nmos_defNG']
minL = techparams['nmos_minL']
minW = techparams['nmos_minW']
-
+
specs('cdf_version', CDFVersion, 'CDF Version')
specs('Display', 'Selected', 'Display', ChoiceConstraint(['All', 'Selected']))
specs('model', model, 'Model name')
-
+
specs('w' , defW, 'Width')
specs('ws', eng_string(Numeric(defW)/Numeric(defNG)), 'SingleWidth')
specs('l' , defL, 'Length')
specs('Wmin', minW, 'Wmin')
specs('Lmin', minL, 'Lmin')
specs('ng', defNG, 'Number of Gates')
-
+
specs('m', '1', 'Multiplier')
specs('trise', '', 'Temp rise from ambient')
@@ -67,9 +67,9 @@ def genLayout(self):
techparams = self.tech.getTechParams()
self.techparams = techparams
self.epsilon = techparams['epsilon1']
-
+
Cell = self.__class__.__name__
-
+
#*************************************************************************
#*
#* Cell Properties
@@ -81,7 +81,7 @@ def genLayout(self):
dbReplaceProp(self, 'function', 'transistor')
dbReplaceProp(self, 'pcellVersion', '$Revision: 1.0 $')
dbReplaceProp(self, 'pin#', 5)
-
+
#*************************************************************************
#*
#* Layer Definitions
@@ -111,30 +111,30 @@ def genLayout(self):
gatpoly_cont_dist = techparams['Cnt_f']
smallw_gatpoly_cont_dist = cont_Activ_overRec+techparams['Gat_d']
contActMin = 2*cont_Activ_overRec+cont_size
-
+
dbReplaceProp(self, 'pin#', 5)
-
+
ng = fix(ng+epsilon)
-
+
w = w/ng
w = GridFix(w)
l = GridFix(l)
-
+
#*************************************************************************
#*
#* Main body of code
#*
#************************************************************************
-
+
if endcap < cont_metall_over :
endcap = cont_metall_over
if w < contActMin-epsilon : # adjust size of Gate to S/D contact region due to corner
gatpoly_cont_dist = smallw_gatpoly_cont_dist
-
+
xdiff_beg = 0
ydiff_beg = 0
ydiff_end = w
-
+
xanz = fix((w-2*cont_Activ_overRec+cont_dist)/(cont_size+cont_dist)+epsilon)
w1 = xanz*(cont_size+cont_dist)-cont_dist+cont_Activ_overRec+cont_Activ_overRec
xoffset = (w-w1)/2
@@ -144,22 +144,22 @@ def genLayout(self):
xoffset = 0
diffoffset = (contActMin-w)/2
diffoffset = Snap(diffoffset)
-
+
# get the number of contacts
lcon = w-2*cont_Activ_overRec
distc = cont_size+cont_dist
ncont = fix((w-2*cont_Activ_overRec+cont_dist)/(cont_size+cont_dist)+epsilon)
if zerop(ncont) :
ncont = 1
-
+
diff_cont_offset = GridFix((w-2*cont_Activ_overRec-ncont*cont_size-(ncont-1)*cont_dist)/2)
-
+
# draw the cont row
xcont_beg = xdiff_beg+cont_Activ_overRec
ycont_beg = ydiff_beg+cont_Activ_overRec
ycont_cnt = ycont_beg+diffoffset+diff_cont_offset
xcont_end = xcont_beg+cont_size
-
+
# draw Metal rect
# calculate bot and top cont position
yMet1 = ycont_cnt-endcap
@@ -168,16 +168,16 @@ def genLayout(self):
yMet1 = min(yMet1, ydiff_beg+diffoffset)
yMet2 = max(yMet2, ydiff_end+diffoffset)
dbCreateRect(self, metall_layer, Box(xcont_beg-cont_metall_over, yMet1, xcont_end+cont_metall_over, yMet2))
-
+
# draw contacts and Metall
contactArray(self, 0, locint_layer, xcont_beg, ydiff_beg, xcont_end, ydiff_end+diffoffset*2, 0, cont_Activ_overRec, cont_size, cont_dist)
-
+
MkPin(self, 'S', 3, Box(xcont_beg-cont_metall_over, yMet1, xcont_end+cont_metall_over, yMet2), metall_layer_pin)
-
+
# draw source diffusion
dbCreateRect(self, ndiff_layer, Box(xcont_beg-cont_Activ_overRec, ycont_beg-cont_Activ_overRec,
xcont_end+cont_Activ_overRec, ycont_beg+cont_size+cont_Activ_overRec))
-
+
for i in range(1, ng+1) :
# draw the poly line
xpoly_beg = xcont_end+gatpoly_cont_dist
@@ -185,32 +185,32 @@ def genLayout(self):
xpoly_end = xpoly_beg+l
ypoly_end = ydiff_end+gatpoly_Activ_over
dbCreateRect(self, poly_layer, Box(xpoly_beg, ypoly_beg+diffoffset, xpoly_end, ypoly_end+diffoffset))
-
+
ihpAddThermalMosLayer(self, Box(xpoly_beg, ypoly_beg+diffoffset, xpoly_end, ypoly_end+diffoffset), True, Cell)
-
+
if i == 1 :
dbCreateLabel(self, text_layer, Point((xpoly_beg+xpoly_end)/2, (ypoly_beg+ypoly_end)/2+diffoffset), 'nmos', 'centerCenter', 'R90', Font.EURO_STYLE, 0.1)
-
+
if onep(i) :
MkPin(self, 'G', 2, Box(xpoly_beg, ypoly_beg+diffoffset, xpoly_end, ypoly_end+diffoffset), poly_layer_pin)
-
+
# draw the second cont row
xcont_beg = xpoly_end+gatpoly_cont_dist
ycont_beg = ydiff_beg+cont_Activ_overRec
ycont_cnt = ycont_beg+diffoffset+diff_cont_offset
xcont_end = xcont_beg+cont_size
dbCreateRect(self, metall_layer, Box(xcont_beg-cont_metall_over, yMet1, xcont_end+cont_metall_over, yMet2))
-
+
contactArray(self, 0, locint_layer, xcont_beg, ydiff_beg, xcont_end, ydiff_end+diffoffset*2, 0, cont_Activ_overRec, cont_size, cont_dist)
-
+
if onep(i) :
MkPin(self, 'D', 1, Box(xcont_beg-cont_metall_over, yMet1, xcont_end+cont_metall_over, yMet2), metall_layer_pin)
-
+
# draw drain diffusion
dbCreateRect(self, ndiff_layer, Box(xcont_beg-cont_Activ_overRec, ycont_beg-cont_Activ_overRec,
xcont_end+cont_Activ_overRec, ycont_beg+cont_size+cont_Activ_overRec))
-
+
# now finish drawing the diffusion
xdiff_end = xcont_end+cont_Activ_overRec
dbCreateRect(self, ndiff_layer, Box(xdiff_beg, ydiff_beg+diffoffset, xdiff_end, ydiff_end+diffoffset))
-
+
diff --git a/ihp-sg13g2/libs.tech/pycell/npn13G2L_code.py b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/npn13G2L_code.py
similarity index 92%
rename from ihp-sg13g2/libs.tech/pycell/npn13G2L_code.py
rename to ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/npn13G2L_code.py
index 1b9af42c..9154a105 100644
--- a/ihp-sg13g2/libs.tech/pycell/npn13G2L_code.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/npn13G2L_code.py
@@ -1,13 +1,13 @@
########################################################################
#
-# Copyright 2023 IHP PDK Authors
-#
+# Copyright 2024 IHP PDK Authors
+#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# https://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,30 +18,30 @@
__version__ = '$Revision: #3 $'
from cni.dlo import *
-from geometry import *
-from thermal import *
-from utility_functions import *
+from .geometry import *
+from .thermal import *
+from .utility_functions import *
import math
class npn13G2L(DloGen):
@classmethod
- def defineParamSpecs(cls, specs):
+ def defineParamSpecs(cls, specs):
techparams = specs.tech.getTechParams()
-
+
CDFVersion = techparams['CDFVersion']
model = techparams['npn13G2L_model']
-
+
specs('cdf_version', CDFVersion, 'CDF Version')
specs('Display', 'Selected', 'Display', ChoiceConstraint(['All', 'Selected']))
specs('model', model, 'Model name')
-
+
specs('Nx', 1, 'x-Multiplier', RangeConstraint(1, 4))
specs('Ny', 1, 'y-Multiplier', ChoiceConstraint([1]))
specs('le', '1.0u', "Emitter Length")
specs('we', '0.07u', "Emitter Width")
-
+
specs('Icmax', '2.6m', 'Ic,max@Uce=2V (50%@0.5V)')
specs('Iarea', '2.6m', 'Ic,max/squm@Uce=2V')
specs('area', '1', 'Area Factor')
@@ -50,7 +50,7 @@ def defineParamSpecs(cls, specs):
specs('Vce', '', 'Collector-emitter voltage')
specs('m', '1', 'Multiplier')
specs('trise', '', 'Temp rise from ambient')
-
+
def setupParams(self, params):
# process parameter values entered by user
self.params = params
@@ -82,36 +82,37 @@ def genLayout(self):
Bas_Metal1_width = 0.16
Emi_Metal1_enc_vert = 0.2
Emi_Metal1_enc_hori = 0.095
-
+
Cell = self.__class__.__name__
-
+
le = Numeric(le)*1e6
Nx = Numeric(Nx)
we = Numeric(we)*1e6
-
+
pcPurpose = 'drawing'
-
+
id = dbCreateRect(self,Layer('EmWind', 'drawing'), Box(emWindOrigin_x, emWindOrigin_y, emWindOrigin_x + we, emWindOrigin_y + le))
-
+
ihpAddThermalBjtLayer(self, Box((emWindOrigin_x - 0.05), (emWindOrigin_y - 0.05), (emWindOrigin_x + we + 0.05), (emWindOrigin_y + le + 0.05)), True, Cell)
-
+
groupId = list()
groupId.append(id)
-
+
+ masks = Grouping()
+
outer = dbCreateRect(self, Layer('Activ', 'drawing'), Box(emWindOrigin_x - Activ_enc_hori, emWindOrigin_y - Activ_enc_vert, emWindOrigin_x + we + Activ_enc_hori, emWindOrigin_y + le + Activ_enc_vert))
inner = dbCreateRect(self, Layer('Activ', 'mask'), Box(emWindOrigin_x - 0.705, emWindOrigin_y - Activ_enc_vert, emWindOrigin_x - Emi_Metal1_enc_hori, emWindOrigin_y + le + Activ_enc_vert))
+ masks.add(inner)
inner1 = dbCreateRect(self, Layer('Activ', 'mask'), Box(emWindOrigin_x + we + 0.705, emWindOrigin_y - Activ_enc_vert, emWindOrigin_x +we + Emi_Metal1_enc_hori, emWindOrigin_y + le + Activ_enc_vert))
-
- id = dbLayerXor(Layer('Activ', 'drawing'), outer, inner)
- id = dbLayerXor(Layer('Activ', 'drawing'), id, inner1)
-
+ masks.add(inner1)
+
+ id = dbLayerXor(Layer('Activ', 'drawing'), outer, masks)
for item in id :
groupId.append(item)
-
dbDeleteObject(outer)
groupId.append(inner)
groupId.append(inner1)
-
+
# Draw contacts & Via
id = dbCreateRect(self, Layer('Via1', 'drawing'), Box(3.805, 3, 3.995, 3.2+le))
groupId.append(id)
@@ -121,21 +122,21 @@ def genLayout(self):
groupId.append(id)
id = dbCreateRect(self, Layer('Cont', 'drawing'), Box(4.96, 2.95, 5.12, 3.25+le))
groupId.append(id)
-
+
cont_cnt = fix((le+0.21)/(0.16+0.18))
-
+
id = dbCreateRect(self, Layer('Cont', 'drawing'), Box(3.385, 2.89, 3.545, 3.05))
groupId.append(id)
for cnt in range(cont_cnt) :
id = dbCopyShape(id, Point(0, 0.34), 'R0')
groupId.append(id)
-
+
id = dbCreateRect(self, Layer('Cont', 'drawing'), Box(4.255, 2.89, 4.415, 3.05))
groupId.append(id)
for cnt in range(cont_cnt) :
id = dbCopyShape(id, Point(0, 0.34), 'R0')
groupId.append(id)
-
+
# Metals
# Metal Path upwards
# Collector
@@ -145,7 +146,7 @@ def genLayout(self):
groupId.append(id)
id = dbCreateRect(self, Layer('Metal1', 'drawing'), Box(emWindOrigin_x - Col_Metal1_distance - Col_Metal1_width, 4.1 + le, emWindOrigin_x + we + Col_Metal1_distance + Col_Metal1_width, 4.1 + le + 0.65))
groupId.append(id)
-
+
# Basis
id = dbCreateRect(self, Layer('Metal1', 'drawing'), Box(emWindOrigin_x - Bas_Metal1_distance, 2.1, emWindOrigin_x - Bas_Metal1_distance - Bas_Metal1_width, 3.38+le))
groupId.append(id)
@@ -153,32 +154,33 @@ def genLayout(self):
groupId.append(id)
id = dbCreateRect(self, Layer('Metal2', 'drawing'), Box(emWindOrigin_x - Bas_Metal1_distance - Bas_Metal1_width, 1.45, emWindOrigin_x + we + Bas_Metal1_distance + Bas_Metal1_width, 2.1))
groupId.append(id)
-
+
# Emitter
id = dbCreateRect(self, Layer('Metal1', 'drawing'), Box(emWindOrigin_x - Emi_Metal1_enc_hori, emWindOrigin_y - Emi_Metal1_enc_vert, emWindOrigin_x + we + Emi_Metal1_enc_hori, emWindOrigin_y + le + Emi_Metal1_enc_vert))
groupId.append(id)
id = dbCreateRect(self, Layer('Metal2', 'drawing'), Box(emWindOrigin_x - Col_Metal1_distance - Col_Metal1_width, 2.9, emWindOrigin_x + Col_Metal1_distance + Col_Metal1_width + we, 3.3+le))
groupId.append(id)
-
+
# Draw Guardring
pcLayer = 'TRANS'
dbCreateRect(self, Layer('TRANS', 'drawing'), Box(0.9, 0.9, 6.9+((Nx-1)*2.8), 5.3+le))
-
+
pcLayer = 'pSD'
outer = dbCreateRect(self, Layer('pSD', 'drawing'), Box(0, 0, 7.8+((Nx-1)*2.8), 6.2+le))
+ inner = dbCreateRect(self, Layer('pSD', 'drawing'), Box(0.9, 0.9, 7.8-0.9+((Nx-1)*2.8), 6.2-0.9+le))
dbLayerXor(pcLayer, outer, inner)
dbDeleteObject(outer)
dbDeleteObject(inner)
-
+
pcLayer = 'Activ'
outer = dbCreateRect(self, Layer(pcLayer, pcPurpose), Box(0.2, 0.2, 7.6+((Nx-1)*2.8), 6.0+le))
inner = dbCreateRect(self, Layer(pcLayer, pcPurpose), Box(0.7, 0.7, (7.6-0.5)+((Nx-1)*2.8), 6.0-0.5+le))
dbLayerXor(pcLayer, outer, inner)
dbDeleteObject(outer)
dbDeleteObject(inner)
-
+
pcLayer = 'TEXT'
- pcLabelText = 'Ae={Ae}um2'.format(Ae=Nx*1*le*we);
+ pcLabelText = 'Ae={0:d}*{1:d}*{2:.2f}*{3:.2f}'.format(int(Nx), 1, le, we)
pcLabelHeight = 0.35
pcInst = dbCreateLabel(self, Layer('TEXT', 'drawing'), Point(1.5, 1.0), pcLabelText, 'lowerLeft', 'R90', Font.EURO_STYLE, pcLabelHeight)
pcInst.setDrafting(True)
@@ -186,15 +188,14 @@ def genLayout(self):
pcLabelHeight = 0.35
pcInst = dbCreateLabel(self, Layer('TEXT', 'drawing'), Point(1.75, 1.0), pcLabelText, 'lowerLeft', 'R0', Font.EURO_STYLE, pcLabelHeight)
pcInst.setDrafting(True)
-
- if Nx > 1 :
+
+ if self.Nx > 1 :
id = dbCreateRect(self, Layer('Metal1', 'drawing'), Box(4.415, 1.45, 6.185, 2.1))
- for cnt in range(1, Nx) :
+ for cnt in range(1, self.Nx) :
groupId = ihpCopyFig(groupId, Point(2.8, 0), 'R0')
- if cnt != Nx-1 :
+ if cnt != self.Nx-1 :
id = dbCopyShape(id, Point(2.8, 0), 'R0')
-
+
MkPin(self, 'C', 1, Box((emWindOrigin_x-Col_Metal1_distance-Col_Metal1_width), (4.1+le), (emWindOrigin_x+we+Col_Metal1_distance+Col_Metal1_width), (4.1+le+0.65)), 'Metal1')
MkPin(self, 'B', 2, Box((emWindOrigin_x-Bas_Metal1_distance-Bas_Metal1_width), 1.45, (emWindOrigin_x+we+Bas_Metal1_distance+Bas_Metal1_width), 2.1), 'Metal1')
MkPin(self, 'E', 3, Box((emWindOrigin_x-Col_Metal1_distance-Col_Metal1_width), 2.9, (emWindOrigin_x+Col_Metal1_distance+Col_Metal1_width+we), (3.3+le)), 'Metal2')
-
diff --git a/ihp-sg13g2/libs.tech/pycell/npn13G2V_code.py b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/npn13G2V_code.py
similarity index 92%
rename from ihp-sg13g2/libs.tech/pycell/npn13G2V_code.py
rename to ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/npn13G2V_code.py
index 21ec6fce..227a736e 100644
--- a/ihp-sg13g2/libs.tech/pycell/npn13G2V_code.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/npn13G2V_code.py
@@ -1,13 +1,13 @@
########################################################################
#
-# Copyright 2023 IHP PDK Authors
-#
+# Copyright 2024 IHP PDK Authors
+#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# https://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,9 +18,9 @@
__version__ = "$Revision: #3 $"
from cni.dlo import *
-from geometry import *
-from thermal import *
-from utility_functions import *
+from .geometry import *
+from .thermal import *
+from .utility_functions import *
import math
@@ -29,19 +29,19 @@ class npn13G2V(DloGen):
@classmethod
def defineParamSpecs(cls, specs):
techparams = specs.tech.getTechParams()
-
+
CDFVersion = techparams['CDFVersion']
model = techparams['npn13G2V_model']
-
+
specs('cdf_version', CDFVersion, 'CDF Version')
specs('Display', 'Selected', 'Display', ChoiceConstraint(['All', 'Selected']))
specs('model', model, 'Model name')
-
+
specs('Nx', 1, 'x-Multiplier', RangeConstraint(1, 8))
specs('Ny', 1, 'y-Multiplier', ChoiceConstraint([1]))
specs('le', '1.0u', "Emitter Length")
specs('we', '0.12u', "Emitter Width")
-
+
specs('Icmax', '0.41m', 'Ic,max@Uce=2V (50%@0.5V)')
specs('Iarea', '0.41m', 'Ic,max/squm@Uce=2V')
specs('area', '1', 'Area Factor')
@@ -73,7 +73,7 @@ def genLayout(self):
Bas_Metal1_width = 0.17
Emi_Metal1_enc_vert = 0.28
Emi_Metal1_enc_hori = 0.07
-
+
Cell = self.__class__.__name__
techparams = self.tech.getTechParams()
@@ -91,7 +91,7 @@ def genLayout(self):
dbReplaceProp(self, 'function', 'transistor')
dbReplaceProp(self, 'pcellVersion', '$Revision: 1.0 $')
dbReplaceProp(self, 'pin#', 4)
-
+
#*************************************************************************
#
# Pcell layers Definitions
@@ -107,7 +107,7 @@ def genLayout(self):
l_trans = Layer('TRANS', 'drawing')
l_pSD = Layer('pSD', 'drawing')
l_text = Layer('TEXT', 'drawing')
-
+
#*************************************************************************
#
# Generic Design Rule Definitions
@@ -116,7 +116,7 @@ def genLayout(self):
Via1Width = techparams['V1_a']
Via1Space = techparams['V1_b']
m1EncVia1 = techparams['V1_c']
-
+
#*************************************************************************
#
# Main body of code
@@ -125,27 +125,27 @@ def genLayout(self):
le = Numeric(le)*1e6
Nx = Numeric(Nx)
we = Numeric(we)*1e6
-
+
id = dbCreateRect(self, l_EmWiHV, Box(emWindOrigin_x, emWindOrigin_y, emWindOrigin_x + we, emWindOrigin_y + le))
-
+
ihpAddThermalBjtLayer(self, Box(emWindOrigin_x - 0.05, emWindOrigin_y - 0.05, emWindOrigin_x + we + 0.05, emWindOrigin_y + le + 0.05), True, Cell)
-
+
groupId = list()
groupId.append(id)
-
+
outer = dbCreateRect(self, l_act, Box(emWindOrigin_x - Activ_enc_hori, emWindOrigin_y - Activ_enc_vert, emWindOrigin_x + we + Activ_enc_hori, emWindOrigin_y + le + Activ_enc_vert))
inner = dbCreateRect(self, l_actMask, Box(emWindOrigin_x - 0.705, emWindOrigin_y - Activ_enc_vert, emWindOrigin_x - Emi_Metal1_enc_hori, emWindOrigin_y + le + Activ_enc_vert))
inner1 = dbCreateRect(self, l_actMask, Box(emWindOrigin_x + we + 0.705, emWindOrigin_y - Activ_enc_vert, emWindOrigin_x +we + Emi_Metal1_enc_hori, emWindOrigin_y + le + Activ_enc_vert))
-
- id = dbLayerXorList(l_act, [outer, inner, inner1])
-
+
+ id = dbLayerXorList(l_act, [outer], [inner, inner1])
+
for item in id :
groupId.append(item)
-
+
dbDeleteObject(outer)
groupId.append(inner)
groupId.append(inner1)
-
+
# Metals
# Metal Path upwards
# Collector
@@ -155,101 +155,101 @@ def genLayout(self):
groupId.append(id)
id = dbCreateRect(self, l_met1, Box(emWindOrigin_x - Col_Metal1_distance - Col_Metal1_width, 4.1 + le, emWindOrigin_x + we + Col_Metal1_distance + Col_Metal1_width, 4.1 + le + 0.65))
groupId.append(id)
-
- # Basis
+
+ # Basis
id = dbCreateRect(self, l_met1, Box(emWindOrigin_x-Bas_Metal1_distance, 2.1, emWindOrigin_x-Bas_Metal1_distance-Bas_Metal1_width, 3.38+le))
groupId.append(id)
id = dbCreateRect(self, l_met1, Box(emWindOrigin_x+we+Bas_Metal1_distance, 2.1, emWindOrigin_x+we+Bas_Metal1_distance+Bas_Metal1_width, 3.38+le))
groupId.append(id)
id = dbCreateRect(self, l_met1, Box(emWindOrigin_x-Bas_Metal1_distance-Bas_Metal1_width, 1.45, emWindOrigin_x+we+Bas_Metal1_distance+Bas_Metal1_width, 2.1))
groupId.append(id)
-
+
# Emitter
emMet1 = dbCreateRect(self, l_met1, Box(emWindOrigin_x - Emi_Metal1_enc_hori, emWindOrigin_y - Emi_Metal1_enc_vert, emWindOrigin_x + we + Emi_Metal1_enc_hori, emWindOrigin_y + le + Emi_Metal1_enc_vert))
groupId.append(emMet1)
id = dbCreateRect(self, l_met2, Box(emWindOrigin_x-Col_Metal1_distance-Col_Metal1_width, 2.82, emWindOrigin_x+Col_Metal1_distance+Col_Metal1_width+we, 3.38+le))
groupId.append(id)
-
+
#; Draw contacts & Via
via_cnt = int((le+0.46)/(0.19+0.22))
id = dbCreateRect(self, l_via1, Box(3.775, 2.87, 3.965, 3.06))
-
+
bbx= emMet1.bbox
# 0.5 is Y offset on bottom
viaColumn = via_cnt*Via1Width+(via_cnt-1)*Via1Space+(Via1Width+Via1Space)+0.05+m1EncVia1
if bbx.getHeight() < viaColumn :
via_cnt -= 1
-
+
groupId.append(id)
-
+
for cnt in range(via_cnt) :
id = dbCopyShape(id, Point(0, 0.41), 'R0')
groupId.append(id)
-
+
id = dbCreateRect(self, l_cont, Box(3.79, 3.04, 3.95, 3.16+le))
groupId.append(id)
-
+
cont_cnt = int((le+0.21)/(0.16+0.18))
-
+
id = dbCreateRect(self, l_cont, Box(2.8, 2.89, 2.96, 3.05))
groupId.append(id)
-
+
for cnt in range(cont_cnt) :
id = dbCopyShape(id, Point(0, 0.34), 'R0')
groupId.append(id)
-
+
id = dbCreateRect(self, l_cont, Box(3.35, 2.89, 3.51, 3.05))
groupId.append(id)
for cnt in range(cont_cnt) :
id = dbCopyShape(id, Point(0, 0.34), 'R0')
groupId.append(id)
-
+
id = dbCreateRect(self, l_cont, Box(4.23, 2.89, 4.39, 3.05))
groupId.append(id)
for cnt in range(1, cont_cnt) :
id = dbCopyShape(id, Point(0, 0.34), 'R0')
groupId.append(id)
-
+
id = dbCreateRect(self, l_cont, Box(4.78, 2.89, 4.94, 3.05))
groupId.append(id)
for cnt in range(cont_cnt) :
id = dbCopyShape(id, Point(0, 0.34), 'R0')
groupId.append(id)
-
+
# Draw Guardring
-
+
dbCreateRect(self, l_trans, Box(0.9, 0.9, 6.84+((Nx-1)*2.34), 5.3+le))
outer = dbCreateRect(self, l_pSD, Box(0, 0, 7.74+((Nx-1)*2.34), 6.2+le))
inner = dbCreateRect(self, l_pSD, Box(0.9, 0.9, (7.74-0.9)+((Nx-1)*2.34), 6.2-0.9+le))
dbLayerXor(l_pSD, outer, inner)
dbDeleteObject(outer)
dbDeleteObject(inner)
-
+
outer = dbCreateRect(self, l_act, Box(0.2, 0.2, 7.54+((Nx-1)*2.34), 6.0+le))
inner = dbCreateRect(self, l_act, Box(0.7, 0.7, (7.54-0.5)+((Nx-1)*2.34), 6.0-0.5+le))
dbLayerXor(l_act, outer, inner)
dbDeleteObject(outer)
dbDeleteObject(inner)
-
- pcLabelText = 'Ae={Ae:.4f}um2'.format(Ae=Nx*le*we);
+
+ pcLabelText = 'Ae={0:d}*{1:.2f}*{2:.2f}'.format(int(Nx), le, we)
pcLabelHeight = 0.35
pcInst = dbCreateLabel(self, l_text, Point(1.5, 1.0), pcLabelText, 'lowerLeft', 'R90', Font.EURO_STYLE, pcLabelHeight)
pcInst.setDrafting(True)
-
+
pcLabelText = Cell
pcLabelHeight = 0.35
pcInst = dbCreateLabel(self, l_text, Point(1.75, 1.0), pcLabelText, 'lowerLeft', 'R0', Font.EURO_STYLE, pcLabelHeight)
pcInst.setDrafting(True)
-
- if Nx > 1 :
+
+ if self.Nx > 1 :
id = dbCreateRect(self, l_met1, Box(4.395, 1.45, 5.685, 2.1))
- for cnt in range(Nx) :
- groupId = ihpCopyFig(groupId, self, Box(2.34, 0), 'R0')
- if cnt != Nx-1 :
- id = dbCopyShape(id, self, Layer(2.34, 0), 'R0')
-
-
+ for cnt in range(1, self.Nx) :
+ groupId = ihpCopyFig(groupId, Point(2.34, 0), 'R0')
+ if cnt != self.Nx-1 :
+ id = dbCopyShape(id, Point(2.34, 0), 'R0')
+
+
MkPin(self, 'C', 1, Box((emWindOrigin_x-Col_Metal1_distance-Col_Metal1_width), (4.1+le), (emWindOrigin_x+we+Col_Metal1_distance+Col_Metal1_width), (4.1+le+0.65)), 'Metal1')
MkPin(self, 'B', 2, Box((emWindOrigin_x-Bas_Metal1_distance-Bas_Metal1_width), 1.45, (emWindOrigin_x+we+Bas_Metal1_distance+Bas_Metal1_width), 2.1), 'Metal1')
MkPin(self, 'E', 3, Box((emWindOrigin_x-Col_Metal1_distance-Col_Metal1_width), 2.82, (emWindOrigin_x+Col_Metal1_distance+Col_Metal1_width+we), (3.38+le)), 'Metal2')
-
+
diff --git a/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/npn13G2_base_code.py b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/npn13G2_base_code.py
index a47e215b..1840318f 100644
--- a/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/npn13G2_base_code.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/npn13G2_base_code.py
@@ -83,27 +83,24 @@ def genLayout(self):
stepX = 1.85
stretchX = stepX*(Nx-1)
+
bipwinxoffset = ((2 * (bipwinx - 0.04)) / 2)
empolyxoffset = ((2 * (empolyx - 0.15)) / 2)
baspolyxoffset = ((2 * (baspolyx - 0.3)) / 2)
STIoffset = ((2 * (STI - 0.44)) / 2)
bipwinyoffset = ((2 * (bipwiny - 0.1)) / 2)
empolyyoffset = ((2 * (empolyy - 0.18)) / 2)
- nSDBlockShift = 0.43 - le
- leoffset = 0
- if le < 0.5 :
- pcStepY = 0.41
- yOffset = 0.20
- else :
- pcStepY = 0.41
- yOffset = 0.20
-
- if we <= 0.9 :
- pcRepeatY = 3
- else :
- pcRepeatY = 4
+
+ nSDBlockShift = 0.43 - le # 23.07.09: needed to draw nSDBlock shorter in small pCell
+
+ # 28.02.07: In the moment only le=48 and le=84 is possible. So use an if to get the right values
+ leoffset = 0 # ((le - 0.07) / 2) # 03.04.08: moved here
+
+ pcStepY = 0.41
+ yOffset = 0.20
pcRepeatY = 4
+
if Nx > 1 :
CMetY1 = -1.01 - we/2 - leoffset - bipwinyoffset - empolyyoffset
CMetY2 = -0.57 - we/2 - leoffset - bipwinyoffset - empolyyoffset
@@ -113,39 +110,61 @@ def genLayout(self):
pcPurpose = 'drawing'
for pcIndexX in range(int(math.floor(Nx))) :
- pcLayer = Layer('Via1')
+ # loop for generate the given number of vias in variable pcRepeatY
+ # two vias are generated per loop
for pcIndexY in range(int((math.floor(pcRepeatY)))) :
- pcInst = dbCreateRect(self, Layer('Via1', 'drawing'), Box((stepX*pcIndexX)-0.3, ((-0.30-yOffset-leoffset-bipwinyoffset-empolyyoffset)+(pcIndexY*pcStepY))-0.2, (stepX*pcIndexX)-0.11, ((-0.11-yOffset-leoffset-bipwinyoffset-empolyyoffset)+(pcIndexY*pcStepY))-0.2))
- pcInst = dbCreateRect(self, Layer('Via1', 'drawing'), Box((stepX*pcIndexX)+0.11, ((-0.3-yOffset-leoffset-bipwinyoffset-empolyyoffset)+(pcIndexY*pcStepY))-0.2, (stepX*pcIndexX)+0.3, ((-0.11-yOffset-leoffset-bipwinyoffset-empolyyoffset)+(pcIndexY*pcStepY))-0.2))
+ # via on left side
+ pcInst = dbCreateRect(self, Layer('Via1', pcPurpose),
+ Box((stepX*pcIndexX)-0.3, (( -0.3-yOffset-leoffset-bipwinyoffset-empolyyoffset)+(pcIndexY*pcStepY))-0.2,
+ (stepX*pcIndexX)-0.11, ((-0.11-yOffset-leoffset-bipwinyoffset-empolyyoffset)+(pcIndexY*pcStepY))-0.2))
+ # via on right side
+ pcInst = dbCreateRect(self, Layer('Via1', pcPurpose),
+ Box((stepX*pcIndexX)+0.11, ((-0.3-yOffset-leoffset-bipwinyoffset-empolyyoffset)+(pcIndexY*pcStepY))-0.2,
+ (stepX*pcIndexX)+0.3, ((-0.11-yOffset-leoffset-bipwinyoffset-empolyyoffset)+(pcIndexY*pcStepY))-0.2))
- pcLayer = Layer('Metal1')
- pcInst = dbCreateRect(self, Layer('Metal1', 'drawing'), Box(stepX*pcIndexX-0.35, (-0.32-we/2-leoffset-bipwinyoffset-empolyyoffset), stepX*pcIndexX+0.35, (0.335+we/2+leoffset+bipwinyoffset+empolyyoffset)))
- pcLayer = Layer('Cont')
- pcInst = dbCreateRect(self, Layer('Cont', 'drawing'), Box(stepX*pcIndexX-0.79-le/2, (-0.76-we/2-leoffset-bipwinyoffset-empolyyoffset), stepX*pcIndexX+0.79+le/2, (-0.6-we/2-leoffset-bipwinyoffset-empolyyoffset)))
- pcInst = dbCreateRect(self, Layer('Cont', 'drawing'), Box(stepX*pcIndexX-0.76, (0.77+we/2-leoffset-bipwinyoffset-empolyyoffset), stepX*pcIndexX+0.76, (0.61+we/2-leoffset-bipwinyoffset-empolyyoffset)))
- pcLayer = Layer('EmWind')
- pcInst = dbCreateRect(self, Layer('EmWind', 'drawing'), Box(stepX*pcIndexX-le/2, (-we/2-leoffset), stepX*pcIndexX+le/2, (we/2+leoffset)))
+ pcLayer = 'Metal1'
+ pcInst = dbCreateRect(self, Layer(pcLayer, pcPurpose), Box(stepX*pcIndexX-0.35, (-0.32-we/2-leoffset-bipwinyoffset-empolyyoffset), stepX*pcIndexX+0.35, (0.335+we/2+leoffset+bipwinyoffset+empolyyoffset)))
+
+ pcLayer = 'Cont'
+ pcInst = dbCreateRect(self, Layer(pcLayer, pcPurpose), Box(stepX*pcIndexX-0.79-le/2, (-0.76-we/2-leoffset-bipwinyoffset-empolyyoffset), stepX*pcIndexX+0.79+le/2, (-0.6-we/2-leoffset-bipwinyoffset-empolyyoffset)))
+ pcInst = dbCreateRect(self, Layer(pcLayer, pcPurpose), Box(stepX*pcIndexX-0.76, (0.77+we/2-leoffset-bipwinyoffset-empolyyoffset), stepX*pcIndexX+0.76, (0.61+we/2-leoffset-bipwinyoffset-empolyyoffset)))
+
+ pcLayer = 'EmWind'
+ pcInst = dbCreateRect(self, Layer(pcLayer, pcPurpose), Box(stepX*pcIndexX-le/2, (-we/2-leoffset), stepX*pcIndexX+le/2, (we/2+leoffset)))
#ihpAddThermalBjtLayer(pcCellView, Box((stepX*pcIndexX-le/2)-0.05, , -we/2 - leoffset, -0.05, (stepX*pcIndexX+le/2)+0.05, , we/2 + leoffset, +0.05), t, Cell)
- pcInst = dbCreateRect(self, Layer('EmWind', 'drawing'), Box(stepX*pcIndexX-le/2, (-we/2-leoffset), stepX*pcIndexX+le/2, (we/2+leoffset)))
- pcLayer = Layer('Activ')
+
+ pcLayer = 'Activ'
xl = stepX*pcIndexX-0.06
xh = xl+0.12
yl = -0.24-leoffset
yh = -yl
- pcInst = dbCreatePolygon(self, Layer('Activ', 'mask'), PointList([Point(xh+0.865, yl-0.74), Point(xl-0.865, yl-0.74), Point(xl-0.865, yh+0.38), Point(xl-0.385, yh+0.38), Point(xl-0.175, yh+0.59), Point(xh+0.175, yh+0.59), Point(xh+0.385, yh+0.38), Point(xh+0.865, yh+0.38)]))
- pcLayer = Layer('Activ')
- pcInst = dbCreateRect(self, Layer('Activ', 'drawing'), Box((stepX*pcIndexX-0.89-le/2-empolyxoffset-baspolyxoffset-STIoffset), (-0.83-we/2-leoffset-bipwinyoffset-empolyyoffset), (stepX*pcIndexX+0.89+le/2+empolyxoffset+baspolyxoffset+STIoffset), (-0.89-we/2+0.36-leoffset-bipwinyoffset-empolyyoffset)))
- pcLayer = Layer('nSD')
- pcInst = dbCreatePolygon(self, Layer('nSD', 'block'), PointList([Point((stepX * pcIndexX + 0.94 + le/2 + empolyxoffset + baspolyxoffset + STIoffset), (1.98 + we/2 + leoffset + bipwinyoffset + empolyyoffset)), Point((stepX * pcIndexX + 0.94 + le/2 + empolyxoffset + baspolyxoffset + STIoffset), (0.45 + we/2 + leoffset + bipwinyoffset + empolyyoffset)), Point((stepX * pcIndexX + 0.52 + le/2 + empolyxoffset + baspolyxoffset + STIoffset), (0.03 + we/2 + leoffset + bipwinyoffset + empolyyoffset)), Point((stepX * pcIndexX + 0.52 + le/2 + empolyxoffset + baspolyxoffset + STIoffset), ( - 0.6 - we/2 + leoffset + bipwinyoffset + empolyyoffset + nSDBlockShift)), Point((stepX * pcIndexX + 0.27 + le/2 + empolyxoffset + baspolyxoffset + STIoffset), (- 0.85 - we/2 + leoffset + bipwinyoffset + empolyyoffset + nSDBlockShift)), Point((stepX * pcIndexX - 0.27 - le/2 - empolyxoffset - baspolyxoffset - STIoffset), (- 0.85 - we/2 + leoffset + bipwinyoffset + empolyyoffset + nSDBlockShift)), Point((stepX * pcIndexX - 0.52 - le/2 - empolyxoffset - baspolyxoffset - STIoffset), (- 0.6 - we/2 + leoffset + bipwinyoffset + empolyyoffset + nSDBlockShift)), Point((stepX * pcIndexX - 0.52 - le/2 - empolyxoffset - baspolyxoffset - STIoffset), (0.03 + we/2 + leoffset + bipwinyoffset + empolyyoffset) ), Point((stepX * pcIndexX - 0.94 - le/2 - empolyxoffset - baspolyxoffset - STIoffset), (0.45 + we/2 + leoffset + bipwinyoffset + empolyyoffset)), Point((stepX * pcIndexX - 0.94 - le/2 - empolyxoffset - baspolyxoffset - STIoffset), (1.98 + we/2 + leoffset + bipwinyoffset + empolyyoffset))]))
+ pcInst = dbCreatePolygon(self, Layer(pcLayer, 'mask'), PointList([Point(xh+0.865, yl-0.74), Point(xl-0.865, yl-0.74), Point(xl-0.865, yh+0.38), Point(xl-0.385, yh+0.38), Point(xl-0.175, yh+0.59), Point(xh+0.175, yh+0.59), Point(xh+0.385, yh+0.38), Point(xh+0.865, yh+0.38)]))
+
+ pcInst = dbCreateRect(self, Layer(pcLayer, pcPurpose), Box((stepX*pcIndexX-0.89-le/2-empolyxoffset-baspolyxoffset-STIoffset), (-0.83-we/2-leoffset-bipwinyoffset-empolyyoffset), (stepX*pcIndexX+0.89+le/2+empolyxoffset+baspolyxoffset+STIoffset), (-0.89-we/2+0.36-leoffset-bipwinyoffset-empolyyoffset)))
+
+ pcLayer ='nSD'
+ pcInst = dbCreatePolygon(self, Layer(pcLayer, 'block'),
+ PointList([Point((stepX * pcIndexX + 0.94 + le/2 + empolyxoffset + baspolyxoffset + STIoffset), (1.98 + we/2 + leoffset + bipwinyoffset + empolyyoffset)),
+ Point((stepX * pcIndexX + 0.94 + le/2 + empolyxoffset + baspolyxoffset + STIoffset), (0.45 + we/2 + leoffset + bipwinyoffset + empolyyoffset)),
+ Point((stepX * pcIndexX + 0.52 + le/2 + empolyxoffset + baspolyxoffset + STIoffset), (0.03 + we/2 + leoffset + bipwinyoffset + empolyyoffset)),
+ Point((stepX * pcIndexX + 0.52 + le/2 + empolyxoffset + baspolyxoffset + STIoffset), (-0.6 - we/2 + leoffset + bipwinyoffset + empolyyoffset + nSDBlockShift)),
+ Point((stepX * pcIndexX + 0.27 + le/2 + empolyxoffset + baspolyxoffset + STIoffset), (-0.85 - we/2 + leoffset + bipwinyoffset + empolyyoffset + nSDBlockShift)),
+ Point((stepX * pcIndexX - 0.27 - le/2 - empolyxoffset - baspolyxoffset - STIoffset), (-0.85 - we/2 + leoffset + bipwinyoffset + empolyyoffset + nSDBlockShift)),
+ Point((stepX * pcIndexX - 0.52 - le/2 - empolyxoffset - baspolyxoffset - STIoffset), (-0.6 - we/2 + leoffset + bipwinyoffset + empolyyoffset + nSDBlockShift)),
+ Point((stepX * pcIndexX - 0.52 - le/2 - empolyxoffset - baspolyxoffset - STIoffset), (0.03 + we/2 + leoffset + bipwinyoffset + empolyyoffset) ),
+ Point((stepX * pcIndexX - 0.94 - le/2 - empolyxoffset - baspolyxoffset - STIoffset), (0.45 + we/2 + leoffset + bipwinyoffset + empolyyoffset)),
+ Point((stepX * pcIndexX - 0.94 - le/2 - empolyxoffset - baspolyxoffset - STIoffset), (1.98 + we/2 + leoffset + bipwinyoffset + empolyyoffset))]))
- pcLayer = Layer('Metal1')
- pcInst = dbCreateRect(self, Layer('Metal1', 'drawing'), Box(-0.89-le/2, CMetY1, stretchX+0.89+le/2, CMetY2))
- pcInst = dbCreateRect(self, Layer('Metal1', 'drawing'), Box(-0.94-le/2, (0.57+we/2+leoffset+bipwinyoffset+empolyyoffset), stretchX+0.94+le/2, (0.81+we/2+leoffset+bipwinyoffset+empolyyoffset)))
- pcLayer = Layer('Metal2')
- pcInst = dbCreateRect(self, Layer('Metal2', 'drawing'), Box(-0.89-le/2, (-0.32-we/2-leoffset-bipwinyoffset-empolyyoffset), stretchX+0.89+le/2, (0.335+we/2+leoffset+bipwinyoffset+empolyyoffset)))
- pcLayer = Layer('TEXT')
+ pcLayer = 'Metal1'
+ pcInst = dbCreateRect(self, Layer(pcLayer, pcPurpose), Box(-0.89-le/2, CMetY1, stretchX+0.89+le/2, CMetY2))
+ pcInst = dbCreateRect(self, Layer(pcLayer, pcPurpose), Box(-0.94-le/2, (0.57+we/2+leoffset+bipwinyoffset+empolyyoffset), stretchX+0.94+le/2, (0.81+we/2+leoffset+bipwinyoffset+empolyyoffset)))
+
+ pcLayer = 'Metal2'
+ pcInst = dbCreateRect(self, Layer(pcLayer, pcPurpose), Box(-0.89-le/2, (-0.32-we/2-leoffset-bipwinyoffset-empolyyoffset), stretchX+0.89+le/2, (0.335+we/2+leoffset+bipwinyoffset+empolyyoffset)))
+
+ pcLayer = 'TEXT'
pcLabelText = self.Text
pcLabelHeight = 0.35
- pcInst = dbCreateLabel(self, Layer('TEXT', 'drawing'), Point(0.015, (-1.86 - we/2 - leoffset - bipwinyoffset - empolyyoffset)), pcLabelText, 'centerCenter', 'R0', Font.EURO_STYLE, pcLabelHeight)
+ pcInst = dbCreateLabel(self, Layer(pcLayer, pcPurpose), Point(0.015, (-1.86 - we/2 - leoffset - bipwinyoffset - empolyyoffset)), pcLabelText, 'centerCenter', 'R0', Font.EURO_STYLE, pcLabelHeight)
pcInst.setDrafting(True)
diff --git a/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/npn13G2_code.py b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/npn13G2_code.py
index 3e4c12cd..6543ef7e 100644
--- a/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/npn13G2_code.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/npn13G2_code.py
@@ -42,7 +42,7 @@ def defineParamSpecs(cls, specs):
specs('le', '0.9u', "Emitter Length")
specs('we', '0.07u', "Emitter Width")
specs('STI', '0.44u', 'STI')
- specs('baspolyx', '0.30u', 'baspolyx')
+ specs('baspolyx', '0.3u', 'baspolyx')
specs('bipwinx', '0.07u', 'bipwinx')
specs('bipwiny', '0.1u', 'bipwiny')
specs('empolyx', '0.15u', 'empolyx')
@@ -96,37 +96,38 @@ def genLayout(self):
le = Numeric(le)*1e6
we = Numeric(we)*1e6
- a = le
+ tmp = le
le = we
- we = a
+ we = tmp
+
ActivShift = 0.01
ActivShift = 0.0
- PWellBlockShift = -0.01
+
+ # for multiplied npn: le has to be bigger
stepX = 1.85
stretchX = stepX*(Nx-1)
bipwinyoffset = (2 * (bipwiny - 0.1) - 0) / 2
empolyyoffset = (2 * (empolyy - 0.18)) / 2
- if le < 0.5 :
- leoffset = 0
- else :
- leoffset = 0
-
+ leoffset = 0 # ((le - 0.07) / 2)
+
name = self.masterLib + '/' + self.masterCell +'/' + self.masterView
+ # Draw inner part as a subCell
if Dlo.exists(name) :
pcMaster = Instance(name)
params = pcMaster.getParams()
- params['le'] = self.le
+ params['le'] = self.we
params['Nx'] = self.Nx
- params['we'] = self.we
+ params['we'] = self.le
pcMaster.setParams(params)
pcMaster.setOrientation(strToOrient(self.masterOrient))
pcMaster.setOrigin(Point(0, 0))
else :
print('(OA) Design "' + name + '" was not found')
- pcLayer = 'TRANS'
pcPurpose = 'drawing'
+
+ pcLayer = 'TRANS'
dbCreatePolygon(self, Layer(pcLayer, pcPurpose), PointList([Point(stretchX+2.45, (2.43 + we/2 + leoffset + bipwinyoffset + empolyyoffset)),
Point(-2.45, (2.43 + we/2 + leoffset + bipwinyoffset + empolyyoffset)),
Point(-2.45, (-1.98 - we/2 - leoffset - bipwinyoffset - empolyyoffset)),
@@ -162,7 +163,7 @@ def genLayout(self):
MkPin(self, 'E', 3, Box(-0.71-le/2, (0.32+we/2+leoffset+bipwinyoffset+empolyyoffset), stretchX+0.71+le/2, (-0.335-we/2-leoffset-bipwinyoffset-empolyyoffset)), Layer('Metal2', 'pin'))
pcLayer = 'TEXT'
- pcLabelText = 'Ae={Ae}um2'.format(Ae=Nx*Ny*le*we)
+ pcLabelText = 'Ae={0:d}*{1:d}*{2:.2f}*{3:.2f}'.format(int(Nx), int(Ny), le, we)
pcLabelHeight = 0.35
pcInst = dbCreateLabel(self, Layer(pcLayer, pcPurpose), Point(-1.977, -2.546), pcLabelText, 'lowerLeft', 'R90', Font.EURO_STYLE, pcLabelHeight)
#setSGq(pcInst, "normalLabel", labelType)
diff --git a/ihp-sg13g2/libs.tech/pycell/pmos_code.py b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/pmosHV_code.py
similarity index 88%
rename from ihp-sg13g2/libs.tech/pycell/pmos_code.py
rename to ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/pmosHV_code.py
index 03c25cdc..2ad07b6c 100644
--- a/ihp-sg13g2/libs.tech/pycell/pmos_code.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/pmosHV_code.py
@@ -1,13 +1,13 @@
########################################################################
#
# Copyright 2023 IHP PDK Authors
-#
+#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# https://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,37 +18,39 @@
__version__ = '$Revision: #3 $'
from cni.dlo import *
-from geometry import *
-from thermal import *
-from utility_functions import *
+from .geometry import *
+from .thermal import *
+from .utility_functions import *
import math
-class pmos(DloGen):
+class pmosHV(DloGen):
@classmethod
def defineParamSpecs(self, specs):
techparams = specs.tech.getTechParams()
-
+
CDFVersion = techparams['CDFVersion']
- model = 'sg13_lv_pmos'
- defL = techparams['pmos_defL']
- defW = techparams['pmos_defW']
- defNG = techparams['pmos_defNG']
- minL = techparams['pmos_minL']
- minW = techparams['pmos_minW']
-
+ model = 'sg13_hv_pmos'
+ defL = techparams['pmosHV_defL']
+ defW = techparams['pmosHV_defW']
+ defNG = techparams['pmosHV_defNG']
+ minL = techparams['pmosHV_minL']
+ minW = techparams['pmosHV_minW']
+
specs('cdf_version', CDFVersion, 'CDF Version')
specs('Display', 'Selected', 'Display', ChoiceConstraint(['All', 'Selected']))
specs('model', model, 'Model name')
-
+
specs('w' , defW, 'Width')
+
+ test = Numeric(defW)
specs('ws', eng_string(Numeric(defW)/Numeric(defNG)), 'SingleWidth')
specs('l' , defL, 'Length')
specs('Wmin', minW, 'Wmin')
specs('Lmin', minL, 'Lmin')
specs('ng', defNG, 'Number of Gates')
-
+
specs('m', '1', 'Multiplier')
specs('trise', '', 'Temp rise from ambient')
@@ -63,24 +65,24 @@ def genLayout(self):
self.grid = self.tech.getGridResolution()
self.techparams = self.tech.getTechParams()
self.epsilon = self.techparams['epsilon1']
-
+
w = self.w
ng = self.ng
l = self.l
typ = 'P'
- hv = False
-
+ hv = True
+
ndiff_layer = Layer('Activ', 'drawing') # 1
pdiff_layer = Layer('Activ', 'drawing') # 1
poly_layer = Layer('GatPoly', 'drawing') # 5
locint_layer = Layer('Cont', 'drawing') # 6
- metall_layer = Layer('Metal1', 'drawing') # 8
- pdiffx_layer = Layer('pSD', 'drawing') # 14
+ metall_layer = Layer('Metal1', 'drawing') # 8
+ pdiffx_layer = Layer('pSD', 'drawing') # 14
well_layer = Layer('NWell', 'drawing') # 31
tgo_layer = Layer('ThickGateOx', 'drawing') # 44
textlayer = Layer('TEXT', 'drawing') # 63
-
+
endcap = self.techparams['M1_c1']
cont_size = self.techparams['Cnt_a']
cont_dist = self.techparams['Cnt_b']
@@ -93,49 +95,49 @@ def genLayout(self):
smallw_gatpoly_cont_dist = cont_Activ_overRec+self.techparams['Gat_d']
psd_PFET_over = self.techparams['pSD_i']
pdiffx_poly_over_orth = 0.48
- wmin = Numeric(self.techparams['pmos_minW'])
- lmin = Numeric(self.techparams['pmos_minL'])
- contActMin = 2*cont_Activ_overRec+cont_size
+ wmin = Numeric(self.techparams['pmosHV_minW'])
+ lmin = Numeric(self.techparams['pmosHV_minL'])
+ contActMin = 2*cont_Activ_overRec+cont_size
thGateOxGat = self.techparams['TGO_c']
thGateOxAct = self.techparams['TGO_a']
dbReplaceProp(self, 'pin#', 5)
-
+
w = w*1e6;
l = l*1e6;
ng = math.floor(Numeric(ng)+self.epsilon)
w = w/ng
w = GridFix(w)
l = GridFix(l)
-
+
# additional Text for label
if hv :
labelhv = 'HV'
else :
labelhv = ''
-
+
if w < contActMin-self.epsilon :
gatpoly_cont_dist = smallw_gatpoly_cont_dist
-
+
xdiff_beg = 0
ydiff_beg = 0
ydiff_end = w
-
+
if w < wmin-self.epsilon :
hiGetAttention()
print('Width < '+str(wmin))
w = wmin
-
+
if l < lmin-self.epsilon :
hiGetAttention()
print('Length < '+str(lmin))
l = lmin
-
+
if ng < 1 :
hiGetAttention()
print('Minimum one finger')
ng = 1
-
+
xanz = math.floor((w-2*cont_Activ_overRec+cont_dist)/(cont_size+cont_dist)+self.epsilon)
w1 = xanz*(cont_size+cont_dist)-cont_dist+cont_Activ_overRec+cont_Activ_overRec
xoffset = (w-w1)/2
@@ -145,26 +147,26 @@ def genLayout(self):
xoffset = 0
diffoffset = (contActMin-w)/2
diffoffset = Snap(diffoffset)
-
- # get the number of contacts
+
+ # get the number of contacts
lcon = w-2*cont_Activ_overRec
distc = cont_size+cont_dist
ncont = math.floor((lcon+cont_dist-2*endcap)/distc + self.epsilon)
if zerop(ncont) :
ncont = 1
-
+
diff_cont_offset = GridFix((w-2*cont_Activ_overRec-ncont*cont_size-(ncont-1)*cont_dist)/2)
-
+
# draw the cont row
xcont_beg = xdiff_beg+cont_Activ_overRec
ycont_beg = ydiff_beg+cont_Activ_overRec
ycont_cnt = ycont_beg+diffoffset+diff_cont_offset
xcont_end = xcont_beg+cont_size
-
+
# draw contacts
# LI and Metall
contactArray(self, 0, locint_layer, xcont_beg, ydiff_beg, xcont_end, ydiff_end+diffoffset*2, 0, cont_Activ_overRec, cont_size, cont_dist)
-
+
# 30.01.08 GGa added block
# draw Metal rect
# calculate bot and top cont position
@@ -175,59 +177,59 @@ def genLayout(self):
yMet2 = max(yMet2, ydiff_end+diffoffset)
dbCreateRect(self, metall_layer, Box(xcont_beg-cont_metall_over, yMet1, xcont_end+cont_metall_over, yMet2))
-
+
if w > contActMin :
MkPin(self, 'S', 3, Box(xcont_beg-cont_metall_over, yMet1, xcont_end+cont_metall_over, yMet2), metall_layer)
else :
MkPin(self, 'S', 3, Box(xcont_beg-cont_metall_over, yMet1, xcont_end+cont_metall_over, yMet2), metall_layer)
-
+
if typ == 'N' :
dbCreateRect(self, ndiff_layer, Box(xcont_beg-cont_Activ_overRec, ycont_beg-cont_Activ_overRec, xcont_end+cont_Activ_overRec, ycont_beg+cont_size+cont_Activ_overRec))
else : # typ == 'P'
dbCreateRect(self, pdiff_layer, Box(xcont_beg-cont_Activ_overRec, ycont_beg-cont_Activ_overRec, xcont_end+cont_Activ_overRec, ycont_beg+cont_size+cont_Activ_overRec))
-
+
for i in range(1, int(ng)+1) :
# draw the poly line
xpoly_beg = xcont_end+gatpoly_cont_dist
ypoly_beg = ydiff_beg-gatpoly_Activ_over
xpoly_end = xpoly_beg+l
ypoly_end = ydiff_end+gatpoly_Activ_over
-
+
dbCreateRect(self, poly_layer, Box(xpoly_beg, ypoly_beg+diffoffset, xpoly_end, ypoly_end+diffoffset))
-
+
ihpAddThermalMosLayer(self, Box(xpoly_beg, ypoly_beg+diffoffset, xpoly_end, ypoly_end+diffoffset), True, 'pmos')
-
+
if i == 1 :
dbCreateLabel(self, textlayer, Point((xpoly_beg+xpoly_end)/2, (ypoly_beg+ypoly_end)/2+diffoffset), 'pmos'+labelhv, 'centerCenter', 'R90', Font.EURO_STYLE, 0.1)
-
+
if onep(i) :
MkPin(self, 'G', 2, Box(xpoly_beg, ypoly_beg+diffoffset, xpoly_end, ypoly_end+diffoffset), poly_layer)
-
- # draw the second cont row
+
+ # draw the second cont row
xcont_beg = xpoly_end+gatpoly_cont_dist
ycont_beg = ydiff_beg+cont_Activ_overRec
ycont_cnt = ycont_beg+diffoffset+diff_cont_offset
xcont_end = xcont_beg+cont_size
-
+
dbCreateRect(self, metall_layer, Box(xcont_beg-cont_metall_over, yMet1, xcont_end+cont_metall_over, yMet2))
# draw contacts
# LI and Metall
contactArray(self, 0, locint_layer, xcont_beg, ydiff_beg, xcont_end, ydiff_end+diffoffset*2, 0, cont_Activ_overRec, cont_size, cont_dist)
-
+
if onep(i) :
if w > contActMin :
MkPin(self, 'D', 1, Box(xcont_beg-cont_metall_over, yMet1, xcont_end+cont_metall_over, yMet2), metall_layer)
else :
MkPin(self, 'D', 1, Box(xcont_beg-cont_metall_over, yMet1, xcont_end+cont_metall_over, yMet2), metall_layer)
-
-
+
+
if typ == 'N' :
dbCreateRect(self, ndiff_layer, Box(xcont_beg-cont_Activ_overRec, ycont_beg-cont_Activ_overRec, xcont_end+cont_Activ_overRec, ycont_beg+cont_size+cont_Activ_overRec))
else :
dbCreateRect(self, pdiff_layer, Box(xcont_beg-cont_Activ_overRec, ycont_beg-cont_Activ_overRec, xcont_end+cont_Activ_overRec, ycont_beg+cont_size+cont_Activ_overRec))
# for i 1 ng
-
- # now finish drawing the diffusion
+
+ # now finish drawing the diffusion
xdiff_end = xcont_end+cont_Activ_overRec
if typ == 'N' :
dbCreateRect(self, ndiff_layer, Box(xdiff_beg, ydiff_beg+diffoffset, xdiff_end, ydiff_end+diffoffset))
@@ -237,10 +239,10 @@ def genLayout(self):
# draw minimum nWell
nwell_offset = max(0, GridFix((contActMin-w)/2+0.5*self.grid))
dbCreateRect(self, well_layer, Box(xdiff_beg-nwell_pActiv_over, ydiff_beg-nwell_pActiv_over+diffoffset-nwell_offset, xdiff_end+nwell_pActiv_over, ydiff_end+nwell_pActiv_over+diffoffset+nwell_offset))
-
- # B-Pin
+
+ # B-Pin
MkPin(self, 'B', 4, Box(xcont_beg-cont_Activ_overRec, ycont_beg-cont_Activ_overRec, xcont_end+cont_Activ_overRec, ycont_beg+cont_size+cont_Activ_overRec), Layer('Substrate', 'drawing'))
-
+
# draw Thick Gate Oxide
if hv :
dbCreateRect(self, Layer('ThickGateOx', 'drawing'), Box(xdiff_beg-thGateOxAct, ydiff_beg-gatpoly_Activ_over-thGateOxGat, xdiff_end+thGateOxAct, ydiff_end+gatpoly_Activ_over+thGateOxGat))
diff --git a/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/utility_functions.py b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/utility_functions.py
index a716fdc1..f4c83cbb 100644
--- a/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/utility_functions.py
+++ b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/ihp/utility_functions.py
@@ -351,8 +351,8 @@ def strToAlignt(value):
if value == 'upperCenter' :
return Location.UPPER_CENTER
- if value == 'lowerCenter' :
- return Location.LOWER_CENTER
+ if value == 'lowerRight' :
+ return Location.LOWER_RIGHT
if value == 'centerRight' :
return Location.CENTER_RIGHT
diff --git a/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/sg13g2_tech.json b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/sg13g2_tech.json
index bbc72377..de7d4262 100644
--- a/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/sg13g2_tech.json
+++ b/ihp-sg13g2/libs.tech/klayout/python/sg13g2_pycell_lib/sg13g2_tech.json
@@ -905,304 +905,5 @@
"sealring_complete_edgeBox": "25u"
},
"Layers": {
- "Activ": "1, 0",
- "Activ.drawing": "1, 0",
- "Activ.label": "1, 1",
- "Activ.pin": "1, 2",
- "Activ.net": "1, 3",
- "Activ.boundary": "1, 4",
- "Activ.lvs": "1, 19",
- "Activ.mask": "1, 20",
- "Activ.filler": "1, 22",
- "Activ.nofill": "1, 23",
- "Activ.OPC": "1, 26",
- "Activ.iOPC": "1, 27",
- "Activ.noqrc": "1, 28",
-
- "GatPoly": "5, 0",
- "GatPoly.drawing": "5, 0",
- "GatPoly.label": "5, 1",
- "GatPoly.pin": "5, 2",
- "GatPoly.net": "5, 3",
- "GatPoly.boundary": "5, 4",
- "GatPoly.track": "5, 5",
- "GatPoly.filler": "5, 22",
- "GatPoly.nofill": "5, 23",
- "GatPoly.OPC": "5, 26",
- "GatPoly.iOPC": "5, 27",
- "GatPoly.noqrc": "5, 28",
-
- "Cont": "6, 0",
- "Cont.drawing": "6, 0",
- "Cont.grid": "6, 1",
- "Cont.blockage": "6, 2",
- "Cont.net": "6, 3",
- "Cont.boundary": "6, 4",
- "Cont.OPC": "6, 26",
-
- "nSD": "7, 0",
- "nSD.drawing": "7, 0",
- "nSD.block": "7, 21",
-
- "Metal1": "8, 0",
- "Metal1.drawing": "8, 0",
- "Metal1.label": "8, 1",
- "Metal1.pin": "8, 2",
- "Metal1.net": "8, 3",
- "Metal1.boundary": "8, 4",
- "Metal1.track": "8, 5",
- "Metal1.grid": "8, 6",
- "Metal1.blockage": "8, 7",
- "Metal1.mask": "8, 20",
- "Metal1.filler": "8, 22",
- "Metal1.nofill": "8, 23",
- "Metal1.slit": "8, 24",
- "Metal1.text": "8, 25",
- "Metal1.OPC": "8, 26",
- "Metal1.noqrc": "8, 28",
- "Metal1.res": "8, 29",
- "Metal1.iprobe": "8, 33",
- "Metal1.diffprb": "8, 34",
-
- "Passiv": "9, 0",
- "Passiv.drawing": "9, 0",
- "Passiv.label": "9, 1",
- "Passiv.pin": "9, 2",
- "Passiv.net": "9, 3",
- "Passiv.boundary": "9, 4",
- "Passiv.pdl": "9, 40",
- "Passiv.sbump": "9, 36",
- "Passiv.pillar": "9, 35",
-
- "Metal2": "10, 0",
- "Metal2.drawing": "10, 0",
- "Metal2.label": "10, 1",
- "Metal2.pin": "10, 2",
- "Metal2.net": "10, 3",
- "Metal2.boundary": "10, 4",
- "Metal2.track": "10, 5",
- "Metal2.grid": "10, 6",
- "Metal2.blockage": "10, 7",
- "Metal2.mask": "10, 20",
- "Metal2.filler": "10, 22",
- "Metal2.nofill": "10, 23",
- "Metal2.slit": "10, 24",
- "Metal2.text": "10, 25",
- "Metal2.OPC": "10, 26",
- "Metal2.noqrc": "10, 28",
- "Metal2.res": "10, 29",
- "Metal2.iprobe": "10, 33",
- "Metal2.diffprb": "10, 34",
-
- "pSD": "14, 0",
- "pSD.drawing": "14, 0",
-
- "Via1": "19, 0",
- "Via1.drawing": "19, 0",
- "Via1.grid": "19, 1",
- "Via1.blockage": "19, 2",
- "Via1.net": "19, 3",
- "Via1.boundary": "19, 4",
-
- "RES": "24, 0",
- "RES.drawing": "24, 0",
- "RES.label": "24, 1",
-
- "TRANS": "26, 0",
- "TRANS.drawing": "26, 0",
-
- "SalBlock": "28, 0",
-
- "Via2": "29, 0",
- "Via2.drawing": "29, 0",
- "Via2.grid": "29, 1",
- "Via2.blockage": "29, 2",
- "Via2.net": "29, 3",
- "Via2.boundary": "29, 4",
-
- "Metal3": "30, 0",
- "Metal3.drawing": "30, 0",
- "Metal3.label": "30, 1",
- "Metal3.pin": "30, 2",
- "Metal3.net": "30, 3",
- "Metal3.boundary": "30, 4",
- "Metal3.track": "30, 5",
- "Metal3.grid": "30, 6",
- "Metal3.blockage": "30, 7",
- "Metal3.mask": "30, 20",
- "Metal3.filler": "30, 22",
- "Metal3.nofill": "30, 23",
- "Metal3.slit": "30, 24",
- "Metal3.text": "30, 25",
- "Metal3.OPC": "30, 26",
- "Metal3.noqrc": "30, 28",
- "Metal3.res": "30, 29",
- "Metal3.iprobe": "30, 33",
- "Metal3.diffprb": "30, 34",
-
- "NWell": "31, 0",
- "NWell.drawing": "31, 0",
- "NWell.label": "31, 1",
- "NWell.pin": "31, 2",
- "NWell.net": "31, 3",
- "NWell.boundary": "31, 4",
-
- "nBuLay": "32, 0",
- "nBuLay.drawing": "32, 0",
- "nBuLay.label": "32, 1",
- "nBuLay.pin": "32, 2",
- "nBuLay.net": "32, 3",
- "nBuLay.boundary": "32, 4",
- "nBuLay.blockage": "32, 21",
-
- "EmWind": "33, 0",
- "EmWind.drawing": "33, 0",
- "EmWind.OPC": "33, 26",
-
- "MIM": "36, 0",
- "MIM.drawing": "36, 0",
- "MIM.net": "36, 3",
- "MIM.boundary": "36, 4",
-
- "EdgeSeal": "39, 0",
- "EdgeSeal.drawing": "39, 0",
- "EdgeSeal.boundary": "39, 4",
-
- "Substrate": "40, 0",
- "Substrate.drawing": "40, 0",
- "Substrate.text": "40, 25",
-
- "ThickGateOx": "44, 0",
- "ThickGateOx.drawing": "44, 0",
-
- "Via3": "49, 0",
- "Via3.drawing": "49, 0",
- "Via3.grid": "49, 1",
- "Via3.blockage": "49, 2",
- "Via3.net": "49, 3",
- "Via3.boundary": "49, 4",
-
- "Metal4": "50, 0",
- "Metal4.drawing": "50, 0",
- "Metal4.label": "50, 1",
- "Metal4.pin": "50, 2",
- "Metal4.net": "50, 3",
- "Metal4.boundary": "50, 4",
- "Metal4.track": "50, 5",
- "Metal4.grid": "50, 6",
- "Metal4.blockage": "50, 7",
- "Metal4.mask": "50, 20",
- "Metal4.filler": "50, 22",
- "Metal4.nofill": "50, 23",
- "Metal4.slit": "50, 24",
- "Metal4.text": "50, 25",
- "Metal4.OPC": "50, 26",
- "Metal4.noqrc": "50, 28",
- "Metal4.res": "50, 29",
- "Metal4.iprobe": "50, 33",
- "Metal4.diffprb": "50, 34",
-
- "HeatTrans": "51, 0",
- "HeatTrans.drawing": "51, 0",
-
- "HeatRes": "52, 0",
- "HeatRes.drawing": "52, 0",
-
- "TEXT": "63, 0",
- "TEXT.drawing": "63, 0",
-
- "Via4": "66, 0",
- "Via4.drawing": "66, 0",
- "Via4.grid": "66, 1",
- "Via4.blockage": "66, 2",
- "Via4.net": "66, 3",
- "Via4.boundary": "66, 4",
-
- "Metal5": "67, 0",
- "Metal5.drawing": "67, 0",
- "Metal5.label": "67, 1",
- "Metal5.pin": "67, 2",
- "Metal5.net": "67, 3",
- "Metal5.boundary": "67, 4",
- "Metal5.track": "67, 5",
- "Metal5.grid": "67, 6",
- "Metal5.blockage": "67, 7",
- "Metal5.mask": "67, 20",
- "Metal5.filler": "67, 22",
- "Metal5.nofill": "67, 23",
- "Metal5.slit": "67, 24",
- "Metal5.text": "67, 25",
- "Metal5.OPC": "67, 26",
- "Metal5.noqrc": "67, 28",
- "Metal5.res": "67, 29",
- "Metal5.iprobe": "67, 33",
- "Metal5.diffprb": "67, 34",
-
- "EXTBlock": "111, 0",
- "EXTBlock.drawing": "111, 0",
-
- "TopVia1": "125, 0",
- "TopVia1.drawing": "125, 0",
- "TopVia1.grid": "125, 1",
- "TopVia1.blockage": "125, 2",
- "TopVia1.net": "125, 3",
- "TopVia1.boundary": "125, 4",
-
- "TopMetal1": "126, 0",
- "TopMetal1.drawing": "126, 0",
- "TopMetal1.label": "126, 1",
- "TopMetal1.pin": "126, 2",
- "TopMetal1.net": "126, 3",
- "TopMetal1.boundary": "126, 4",
- "TopMetal1.track": "126, 5",
- "TopMetal1.grid": "126, 6",
- "TopMetal1.blockage": "126, 7",
- "TopMetal1.mask": "126, 20",
- "TopMetal1.filler": "126, 22",
- "TopMetal1.nofill": "126, 23",
- "TopMetal1.slit": "126, 24",
- "TopMetal1.text": "126, 25",
- "TopMetal1.OPC": "126, 26",
- "TopMetal1.noqrc": "126, 28",
- "TopMetal1.res": "126, 29",
- "TopMetal1.iprobe": "126, 33",
- "TopMetal1.diffprb": "126, 34",
-
- "PolyRes": "128, 0",
- "PolyRes.drawing": "128, 0",
- "PolyRes.label": "128, 1",
- "PolyRes.pin": "128, 2",
- "PolyRes.net": "128, 3",
- "PolyRes.boundary": "128, 4",
-
- "Vmim": "129, 0",
- "Vmim.drawing": "129, 0",
-
- "TopVia2": "133, 0",
- "TopVia2.drawing": "133, 0",
- "TopVia2.grid": "133, 1",
- "TopVia2.blockage": "133, 2",
- "TopVia2.net": "133, 3",
- "TopVia2.boundary": "133, 4",
-
- "TopMetal2": "134, 0",
- "TopMetal2.drawing": "134, 0",
- "TopMetal2.label": "134, 1",
- "TopMetal2.pin": "134, 2",
- "TopMetal2.net": "134, 3",
- "TopMetal2.boundary": "134, 4",
- "TopMetal2.track": "134, 5",
- "TopMetal2.grid": "134, 6",
- "TopMetal2.blockage": "134, 7",
- "TopMetal2.mask": "134, 20",
- "TopMetal2.filler": "134, 22",
- "TopMetal2.nofill": "134, 23",
- "TopMetal2.slit": "134, 24",
- "TopMetal2.text": "134, 25",
- "TopMetal2.OPC": "134, 26",
- "TopMetal2.noqrc": "134, 28",
- "TopMetal2.res": "134, 29",
- "TopMetal2.iprobe": "134, 33",
- "TopMetal2.diffprb": "134, 34"
}
}
diff --git a/ihp-sg13g2/libs.tech/klayout/sg13g2_tests/pycell_test.py b/ihp-sg13g2/libs.tech/klayout/sg13g2_tests/pycell_test.py
index 85dd85b5..c342e945 100644
--- a/ihp-sg13g2/libs.tech/klayout/sg13g2_tests/pycell_test.py
+++ b/ihp-sg13g2/libs.tech/klayout/sg13g2_tests/pycell_test.py
@@ -25,26 +25,46 @@
#
# KLAYOUT_PATH=$(pwd)/.. klayout ihp-pycells.gds -e
-ly = pya.Layout()
+layout = pya.Layout()
-pcellNmos = ly.create_cell("nmos", "SG13_dev", { "l": 0.350e-6, "w": 6e-6, "ng": 3 })
-pcellPmos = ly.create_cell("pmos", "SG13_dev", { "l": 0.350e-6, "w": 6e-6, "ng": 3 })
-pcellCmim = ly.create_cell("cmim", "SG13_dev", {})
-pcellSealring = ly.create_cell("sealring", "SG13_dev", {})
-pcellNpn13G2Base = ly.create_cell("npn13G2_base", "SG13_dev", {})
-pcellNpn13G2 = ly.create_cell("npn13G2", "SG13_dev", {})
+pcellNmos = layout.create_cell("nmos", "SG13_dev", { "l": 0.350e-6, "w": 6e-6, "ng": 3 })
+pcellPmos = layout.create_cell("pmos", "SG13_dev", { "l": 0.350e-6, "w": 6e-6, "ng": 3 })
+pcellCmim = layout.create_cell("cmim", "SG13_dev", {})
+pcellSealring = layout.create_cell("sealring", "SG13_dev", {})
+pcellNpn13G2Base = layout.create_cell("npn13G2_base", "SG13_dev", {})
+pcellNpn13G2 = layout.create_cell("npn13G2", "SG13_dev", {})
+pcellNpn13G2L = layout.create_cell("npn13G2L", "SG13_dev", {})
+pcellNpn13G2V = layout.create_cell("npn13G2V", "SG13_dev", {})
+pcellRsil = layout.create_cell("rsil", "SG13_dev", {})
+pcellRhigh = layout.create_cell("rhigh", "SG13_dev", {})
+pcellRppd = layout.create_cell("rppd", "SG13_dev", {})
+pcellInductor2 = layout.create_cell("inductor2", "SG13_dev", {})
+pcellInductor2_sc = layout.create_cell("inductor2_sc", "SG13_dev", {})
+pcellInductor2_sp = layout.create_cell("inductor2_sp", "SG13_dev", {})
+pcellInductor3 = layout.create_cell("inductor3", "SG13_dev", {})
+pcellInductor3_sc = layout.create_cell("inductor3_sc", "SG13_dev", {})
+pcellInductor3_sp = layout.create_cell("inductor3_sp", "SG13_dev", {})
-#pcell = ly.create_cell("rsil", "SG13_dev", { "l": "3e-6", "w": "6e-6", "b": 1, "ps": "1e-6", "R": "1e-6"})
-
-top = ly.create_cell("TOP")
+top = layout.create_cell("TOP")
top.insert(pya.DCellInstArray(pcellNmos, pya.DTrans()))
-top.insert(pya.DCellInstArray(pcellPmos, pya.DTrans(pya.DVector(3, 0))))
-top.insert(pya.DCellInstArray(pcellCmim, pya.DTrans(pya.DVector(0, -9))))
-top.insert(pya.DCellInstArray(pcellSealring, pya.DTrans(pya.DVector(50, -9))))
-top.insert(pya.DCellInstArray(pcellNpn13G2, pya.DTrans(pya.DVector(3, 8))))
+top.insert(pya.DCellInstArray(pcellPmos, pya.DTrans(pya.DVector(4, 0))))
+top.insert(pya.DCellInstArray(pcellNpn13G2, pya.DTrans(pya.DVector(11, 3.1))))
+top.insert(pya.DCellInstArray(pcellNpn13G2L, pya.DTrans(pya.DVector(16, -0.3))))
+top.insert(pya.DCellInstArray(pcellNpn13G2V, pya.DTrans(pya.DVector(25, -0.3))))
+top.insert(pya.DCellInstArray(pcellRhigh, pya.DTrans(pya.DVector(34, 0.2))))
+top.insert(pya.DCellInstArray(pcellRppd, pya.DTrans(pya.DVector(36, 0.2))))
+top.insert(pya.DCellInstArray(pcellRsil, pya.DTrans(pya.DVector(38, 0.2))))
+top.insert(pya.DCellInstArray(pcellCmim, pya.DTrans(pya.DVector(41, 0.2))))
+top.insert(pya.DCellInstArray(pcellInductor2, pya.DTrans(pya.DVector(40, -85))))
+top.insert(pya.DCellInstArray(pcellInductor2_sc, pya.DTrans(pya.DVector(125, -85))))
+top.insert(pya.DCellInstArray(pcellInductor2_sp, pya.DTrans(pya.DVector(210, -85))))
+top.insert(pya.DCellInstArray(pcellInductor3, pya.DTrans(pya.DVector(49, -190))))
+top.insert(pya.DCellInstArray(pcellInductor3_sc, pya.DTrans(pya.DVector(152, -190))))
+top.insert(pya.DCellInstArray(pcellInductor3_sp, pya.DTrans(pya.DVector(255, -190))))
+top.insert(pya.DCellInstArray(pcellSealring, pya.DTrans(pya.DVector(310, -190))))
output = "SG13_dev.gds"
-ly.write(output)
+layout.write(output)
print("IHP PyCells layout written to: " + output)
diff --git a/ihp-sg13g2/libs.tech/klayout/tech/drc/MissingRules_maximal.md b/ihp-sg13g2/libs.tech/klayout/tech/drc/MissingRules_maximal.md
index cd239ee6..8e516cd0 100644
--- a/ihp-sg13g2/libs.tech/klayout/tech/drc/MissingRules_maximal.md
+++ b/ihp-sg13g2/libs.tech/klayout/tech/drc/MissingRules_maximal.md
@@ -1,246 +1,153 @@
# Missing Rules
-- NW.b
-- NW.b1
-- NW.c
-- NW.c1
-- NW.d
-- NW.e
-- NW.e1
-- NW.f
-- NW.f1
-- PWB.d
-- PWB.e
-- PWB.e1
-- PWB.f
-- PWB.f1
-- NBL.b
-- NBL.c
-- NBL.d
-- NBL.e
-- NBL.f
-- NBLB.c
-- Act.c
-- Act.e
-- AFil.c
-- AFil.c1
-- AFil.d
-- AFil.e
-- AFil.i
-- AFil.j
-- TGO.a
-- TGO.b
-- TGO.c
-- TGO.d
-- Gat.a1
-- Gat.a2
-- Gat.a3
-- Gat.a4
-- Gat.c
-- Gat.g
-- GFil.e
-- GFil.i
-- pSD.c
-- pSD.c1
-- pSD.f
-- pSD.g
-- pSD.i
-- pSD.i1
-- pSD.l
-- pSD.m
-- pSD.n
-- nSDB.c
-- nSDB.d
-- nSDB.e
-- Sal.c
-- Cnt.c
-- Cnt.d
-- Cnt.e
-- Cnt.g1
-- Cnt.g2
-- CntB.a
-- CntB.b1
-- CntB.c
-- CntB.d
-- CntB.g2
-- CntB.h1
-- M1.c1
-- M1.e
-- M1.f
-- M1.g
-- M1.i
-- M2.c
-- M2.c1
-- M2.e
-- M2.f
-- M2.g
-- M2.i
-- M3.c
-- M3.c1
-- M3.e
-- M3.f
-- M3.g
-- M3.i
-- M4.c
-- M4.c1
-- M4.e
-- M4.f
-- M4.g
-- M4.i
-- M5.c
-- M5.c1
-- M5.e
-- M5.f
-- M5.g
-- M5.i
-- M1Fil.a2
-- M2Fil.a2
-- M3Fil.a2
-- M4Fil.a2
-- M5Fil.a2
-- V1.c
-- V1.c1
-- V2.c
-- V2.c1
-- V3.c
-- V3.c1
-- V4.c
-- V4.c1
-- TV1.c
-- TV1.d
-- TM1Fil.a1
-- TV2.c
-- TV2.d
-- TM2.bR
-- TM2Fil.a1
-- Pas.c
-- npnG2.a
-- npnG2.b
-- npnG2.c
-- npnG2.d
-- npnG2.d1
-- npnG2.d2
-- npnG2.e
-- npnG2.f
-- npn13G2.bR
-- npn13G2L.cR
-- npn13G2V.cR
-- Rsil.a
-- Rsil.c
-- Rsil.d
-- Rsil.e
-- Rppd.a
-- Rppd.b
-- Rppd.c
-- Rppd.d
-- Rppd.e
-- Rhi.b
-- Rhi.c
-- Rhi.d
-- Rhi.e
-- nmosi.b
-- nmosi.e1
-- nmosi.e2
-- Sdiod.a
-- Sdiod.b
-- Sdiod.c
-- Sdiod.d
-- Sdiod.e
-- Pad.eR
-- Pad.fR
-- Pad.gR
-- Pad.i
-- Padb.a
-- Padb.b
-- Padb.c
-- Padb.d
-- Padb.e
-- Padb.f
-- Padc.a
-- Padc.c
-- Padc.e
-- Padc.f
-- Seal.b
-- Seal.d
-- Seal.f
-- Seal.k
-- Seal.l
-- Seal.m
-- MIM.c
-- MIM.d
-- MIM.gR
-- Ant.a
-- Ant.b
-- Ant.c
-- Ant.d
-- Ant.e
-- Ant.f
-- Ant.g
-- LU.a
-- LU.b
-- LU.c
-- LU.c1
-- LU.d
-- LU.d1
-- Slt.b.M1
-- Slt.c.M1
-- Slt.e1
-- Slt.f.M1
-- Slt.b.M2
-- Slt.c.M2
-- Slt.f.M2
-- Slt.b.M3
-- Slt.c.M3
-- Slt.f.M3
-- Slt.b.M4
-- Slt.c.M4
-- Slt.f.M4
-- Slt.b.M5
-- Slt.c.M5
-- Slt.f.M5
-- Slt.g.M5
-- Slt.b.TM1
-- Slt.c.TM1
-- Slt.f.TM1
-- Slt.g.TM1
-- Slt.b.TM2
-- Slt.c.TM2
-- Slt.f.TM2
-- Slt.i.M1
-- Slt.i.M2
-- Slt.i.M3
-- Slt.i.M4
-- Slt.i.M5
-- Slt.i.TM1
-- Slt.i.TM2
-- NW.c1.dig
-- NW.e1.dig
-- Cnt.c.Digi
-- NW.c.SRAM
-- NW.d.SRAM
-- Act.c.SRAM
-- Gat.c.SRAM
-- pSD.g.SRAM
-- pSD.i.SRAM
-- Cnt.c.SRAM
-- Cnt.d.SRAM
-- Cnt.g2.SRAM
-- M1.c1.SRAM
-- M1.i.SRAM
-- M2.c1.SRAM
-- M3.c1.SRAM
-- M4.c1.SRAM
-- M5.c1.SRAM
-- V1.c1.SRAM
-- V2.c1.SRAM
-- V3.c1.SRAM
-- V4.c1.SRAM
-- TSV_G.a
-- TSV_G.b
-- TSV_G.c
-- TSV_G.d
-- TSV_G.e
-- TSV_G.f
-- TSV_G.g
-- TSV_G.i
-- TSV_G.j
+| Name | Description |
+| ----------- | ------------------------------------------------------------------------------------------------------------------------------ |
+| NW.b | Min. NWell space or notch (same net). NWell regions separated by less than this value will be merged. |
+| NW.b1 | Min. PWell width between NWell regions (different net) (Note 3) |
+| NW.c | Min. NWell enclosure of P+Activ not inside ThickGateOx |
+| NW.c1 | Min. NWell enclosure of P+Activ inside ThickGateOx |
+| NW.d | Min. NWell space to external N+Activ not inside ThickGateOx |
+| NW.e | Min. NWell enclosure of NWell tie surrounded entirely by NWell in N+Activ not inside ThickGateOx |
+| NW.e1 | Min. NWell enclosure of NWell tie surrounded entirely by NWell in N+Activ inside ThickGateOx |
+| PWB.d | Min. PWell:block overlap of NWell |
+| PWB.e | Min. PWell:block space to (N+Activ not inside ThickGateOx) in PWell |
+| PWB.e1 | Min. PWell:block space to (N+Activ inside ThickGateOx) in PWell |
+| PWB.f | Min. PWell:block space to (P+Activ not inside ThickGateOx) in PWell |
+| PWB.f1 | Min. PWell:block space to (P+Activ inside ThickGateOx) in PWell |
+| NBL.b | Min. nBuLay space or notch (same net) |
+| NBL.c | Min. PWell width between nBuLay regions (different net) (Note 1) |
+| NBL.d | Min. PWell width between nBuLay and NWell (different net) (Note 1) |
+| NBL.e | Min. nBuLay space to unrelated N+Activ |
+| NBL.f | Min. nBuLay space to unrelated P+Activ |
+| Act.c | Min. Activ drain/source extension |
+| AFil.c | Min. Activ:filler space to Cont, GatPoly |
+| AFil.c1 | Min. Activ:filler space to Activ |
+| AFil.d | Min. Activ:filler space to NWell, nBuLay |
+| AFil.e | Min. Activ:filler space to TRANS |
+| AFil.i | Min. Activ:filler space to edges of PWell:block |
+| AFil.j | Min. nSD:block and SalBlock enclosure of Activ:filler inside PWell:block |
+| Gat.a1 | Min. GatPoly width for channel length of 1.2 V NFET |
+| Gat.a2 | Min. GatPoly width for channel length of 1.2 V PFET |
+| Gat.g | Min. GatPoly width for 45-degree bent shapes if the bend GatPoly length is > 0.39 µm |
+| GFil.e | Min. GatPoly:filler space to NWell, nBuLay |
+| GFil.i | Max. GatPoly:nofill area (µm²) |
+| pSD.c1 | Min. pSD enclosure of P+Activ in PWell |
+| nSDB.d | Min. nSD:block overlap of pSD (Note 1) |
+| Cnt.c | Min. Activ enclosure of Cont |
+| Cnt.d | Min. GatPoly enclosure of Cont |
+| Cnt.e | Min. Cont on GatPoly space to Activ |
+| Cnt.g1 | Min. pSD space to Cont on nSD-Activ |
+| Cnt.g2 | Min. pSD overlap of Cont on pSD-Activ |
+| CntB.b1 | Min. ContBar space with common run > 5 µm |
+| CntB.c | Min. Activ enclosure of ContBar |
+| CntB.d | Min. GatPoly enclosure of ContBar |
+| CntB.h1 | Min. Metal1 enclosure of ContBar |
+| M1.e | Min. space of Metal1 lines if, at least one line is wider than 0.3 µm and the parallel run is more than 1.0 µm |
+| M1.f | Min. space of Metal1 lines if, at least one line is wider than 10.0 µm and the parallel run is more than 10.0 µm |
+| M1.g | Min. 45-degree bent Metal1 width if the bent metal length is > 0.5 µm |
+| M1.i | Min. space of Metal1 lines of which at least one is bent by 45-degree |
+| M2.e | Min. space of Metal2 lines if, at least one line is wider than 0.39 µm and the parallel run is more than 1.0 µm |
+| M2.f | Min. space of Metal2 lines if, at least one line is wider than 10.0 µm and the parallel run is more than 10.0 µm |
+| M2.g | Min. 45-degree bent Metal2 width if the bent metal length is > 0.5 µm |
+| M2.i | Min. space of Metal2 lines of which at least one is bent by 45-degree |
+| M3.e | Min. space of Metal3 lines if, at least one line is wider than 0.39 µm and the parallel run is more than 1.0 µm |
+| M3.f | Min. space of Metal3 lines if, at least one line is wider than 10.0 µm and the parallel run is more than 10.0 µm |
+| M3.g | Min. 45-degree bent Metal3 width if the bent metal length is > 0.5 µm |
+| M3.i | Min. space of Metal3 lines of which at least one is bent by 45-degree |
+| M4.e | Min. space of Metal4 lines if, at least one line is wider than 0.39 µm and the parallel run is more than 1.0 µm |
+| M4.f | Min. space of Metal4 lines if, at least one line is wider than 10.0 µm and the parallel run is more than 10.0 µm |
+| M4.g | Min. 45-degree bent Metal4 width if the bent metal length is > 0.5 µm |
+| M4.i | Min. space of Metal4 lines of which at least one is bent by 45-degree |
+| M5.e | Min. space of Metal5 lines if, at least one line is wider than 0.39 µm and the parallel run is more than 1.0 µm |
+| M5.f | Min. space of Metal5 lines if, at least one line is wider than 10.0 µm and the parallel run is more than 10.0 µm |
+| M5.g | Min. 45-degree bent Metal5 width if the bent metal length is > 0.5 µm |
+| M5.i | Min. space of Metal5 lines of which at least one is bent by 45-degree |
+| M1Fil.a2 | Max. Metal1:filler width |
+| M2Fil.a2 | Max. Metal2:filler width |
+| M3Fil.a2 | Max. Metal3:filler width |
+| M4Fil.a2 | Max. Metal4:filler width |
+| M5Fil.a2 | Max. Metal5:filler width |
+| V1.c | Min. Metal1 enclosure of Via1 |
+| V2.c | Min. Metal2 enclosure of Via2 |
+| V3.c | Min. Metal3 enclosure of Via3 |
+| V4.c | Min. Metal4 enclosure of Via4 |
+| TV1.c | Min. Metal5 enclosure of TopVia1 |
+| TV1.d | Min. TopMetal1 enclosure of TopVia1 |
+| TM1Fil.a1 | Max. TopMetal1:filler width |
+| TV2.c | Min. TopMetal1 enclosure of TopVia2 |
+| TV2.d | Min. TopMetal2 enclosure of TopVia2 |
+| TM2.bR | Min. space of TopMetal2 lines if, at least one line is wider than 5.0 µm and the parallel run is more than 50.0 µm (Note 1, 2) |
+| TM2Fil.a1 | Max. TopMetal2:filler width |
+| Pas.c | Min. TopMetal2 enclosure of Passiv (Note 1) |
+| npnG2.a | NPN Substrate-Tie = Activ AND pSD |
+| npnG2.b | NPN Substrate-Tie must enclose TRANS |
+| npnG2.c | pSD enclosure of Activ inside NPN Substrate-Tie |
+| npnG2.d | Min. unrelated N+Activ, NWell, PWell:block, nBuLay, nSD:block space to TRANS |
+| npnG2.d1 | Min. unrelated GatPoly space to TRANS |
+| npnG2.d2 | Min. unrelated SalBlock space to TRANS |
+| npnG2.e | Min. unrelated Cont space to TRANS |
+| npnG2.f | NPN Substrate-Ties are allowed to overlap each other |
+| npn13G2.bR | Max. recommended total number of npn13G2 emitters per chip |
+| npn13G2L.cR | Max. recommended total number of npn13G2L emitters per chip |
+| npn13G2V.cR | Max. recommended total number of npn13G2V emitters per chip |
+| Rppd.d | Min. EXTBlock enclosure of GatPoly |
+| Rhi.e | Min. EXTBlock enclosure of GatPoly |
+| nmosi.e1 | A separate Iso-PWell contact unabutted to a nmosi device is not allowed |
+| nmosi.e2 | nmosi unabutted to an Iso-PWell-Activ tie is not allowed |
+| Sdiod.d | Min. and max. ContBar width inside nBuLay |
+| Sdiod.e | Min. and max. ContBar length inside nBuLay |
+| Pad.eR | Min. recommended Metal(n), TopMetal1, TopMetal2 exit width |
+| Pad.fR | Min. recommended Metal(n), TopMetal1, TopMetal2 exit length |
+| Pad.i | dfpad without TopMetal2 not allowed |
+| Padb.a | SBumpPad size |
+| Padb.b | Min. SBumpPad space |
+| Padb.c | Min. TopMetal2 (within dfpad) enclosure of SBumpPad |
+| Padb.d | Min. SBumpPad space to EdgeSeal |
+| Padb.e | Min. SBumpPad pitch (Note 1) |
+| Padb.f | Allowed passivation opening shape (Note 1) |
+| Padc.a | CuPillarPad size |
+| Padc.c | Min. TopMetal2 (within dfpad) enclosure of CuPillarPad |
+| Padc.e | Min. CuPillarPad pitch (Note 1) |
+| Padc.f | Allowed passivation opening shape (Note 1) |
+| Seal.b | Min. Activ space to EdgeSeal-Activ, EdgeSeal-pSD, EdgeSeal-Metal(n=1-5), EdgeSeal-TopMetal1, EdgeSeal-TopMetal2 |
+| Seal.d | Min. EdgeSeal-Activ enclosure of EdgeSeal-Cont, EdgeSeal-Metal(n=1-5), EdgeSeal-TopMetal1, EdgeSeal-TopMetal2 ring |
+| Seal.f | Min. Passiv ring outside of sealring space to EdgeSeal-Activ, EdgeSeal-Metal(n=1-5), EdgeSeal-TopMetal1, EdgeSeal-TopMetal2 |
+| Seal.k | Min. EdgeSeal 45-degree corner length (Note 1) |
+| Seal.l | No structures outside sealring boundary allowed |
+| Seal.m | Only one sealring per chip allowed (Note 1) |
+| MIM.c | Min. Metal5 enclosure of MIM |
+| MIM.d | Min. MIM enclosure of TopVia1 |
+| MIM.gR | Max. recommended total MIM area per chip (µm²) |
+| Ant.a | Max. ratio of GatPoly over field oxide area to connected Gate area |
+| Ant.b | Max. ratio of cumulative metal area (from Metal1 to TopMetal2) to connected Gate area (without protection diode) |
+| Ant.c | Max. ratio of Cont area to connected Gate area |
+| Ant.d | Max. ratio of cumulative via area (from Via1 to TopVia2) to connected Gate area (without protection diode) |
+| Ant.e | Max. ratio of cumulative metal area (from Metal1 to TopMetal2) to connected Gate area (with protection diode) |
+| Ant.f | Max. ratio of cumulative via area (from Via1 to TopVia2) to connected Gate area (with protection diode) |
+| Ant.g | Size of protection diode (µm²) (Note 4) |
+| LU.b | Max. space from any portion of N+Activ inside PWell to an pSD-PWell tie |
+| Slt.e1 | No slits required on MIM |
+| Slt.i.M1 | Min. Metal1:slit density for any Metal1 plate bigger than 35 µm x 35 µm [%] |
+| Slt.i.M2 | Min. Metal2:slit density for any Metal2 plate bigger than 35 µm x 35 µm [%] |
+| Slt.i.M3 | Min. Metal3:slit density for any Metal3 plate bigger than 35 µm x 35 µm [%] |
+| Slt.i.M4 | Min. Metal4:slit density for any Metal4 plate bigger than 35 µm x 35 µm [%] |
+| Slt.i.M5 | Min. Metal5:slit density for any Metal5 plate bigger than 35 µm x 35 µm [%] |
+| Slt.i.TM1 | Min. TopMetal1:slit density for any TopMetal1 plate bigger than 35 µm x 35 µm [%] |
+| Slt.i.TM2 | Min. TopMetal2:slit density for any TopMetal2 plate bigger than 35 µm x 35 µm [%] |
+| NW.c1.dig | Min. NWell enclosure of P+Activ inside ThickGateOx |
+| NW.e1.dig | Min. NWell enclosure of NWell tie surrounded entirely by NWell in N+Activ inside ThickGateOx |
+| Cnt.c.Digi | Min. Activ enclosure of Cont |
+| NW.c.SRAM | Min. NWell enclosure of P+Activ not inside ThickGateOx |
+| NW.d.SRAM | Min. NWell space to external N+Activ not inside ThickGateOx |
+| Act.c.SRAM | Min. Activ drain/source extension |
+| Cnt.c.SRAM | Min. Activ enclosure of Cont |
+| Cnt.d.SRAM | Min. GatPoly enclosure of Cont |
+| Cnt.g2.SRAM | Min. pSD overlap of Cont on pSD-Activ |
+| M1.i.SRAM | Min. space of Metal1 lines of which at least one is bent by 45-degree |
+| V1.c1.SRAM | Min. Metal1 endcap enclosure of Via1 |
+| V2.c1.SRAM | Min. Metal2 endcap enclosure of Via2 |
+| V3.c1.SRAM | Min. Metal3 endcap enclosure of Via3 |
+| V4.c1.SRAM | Min. Metal4 endcap enclosure of Via4 |
+| TSV_G.b | Min. and max. DeepVia width |
+| TSV_G.c | DeepVia ring diameter |
+| TSV_G.e | Min. DeepVia space to Activ, Activ:filler, GatPoly, GatPoly:filler and Cont |
diff --git a/ihp-sg13g2/libs.tech/klayout/tech/drc/README.md b/ihp-sg13g2/libs.tech/klayout/tech/drc/README.md
index 18ae0ca6..9d80cad4 100644
--- a/ihp-sg13g2/libs.tech/klayout/tech/drc/README.md
+++ b/ihp-sg13g2/libs.tech/klayout/tech/drc/README.md
@@ -1,4 +1,2 @@
**Minimum Rule Set** - [README](README_minimal.md)
**Maximum Rule Set** - [README](README_maximal.md), [MissingRules](MissingRules_maximal.md)
-> **NOTE**: Starting with this version the rule names are extracted from the OpenPDK DRM PDF.
-> The extraction algorithm will be updated to include the 'values' in the next version of rule deck.
diff --git a/ihp-sg13g2/libs.tech/klayout/tech/drc/README_maximal.md b/ihp-sg13g2/libs.tech/klayout/tech/drc/README_maximal.md
index 87999f0b..6730b15b 100644
--- a/ihp-sg13g2/libs.tech/klayout/tech/drc/README_maximal.md
+++ b/ihp-sg13g2/libs.tech/klayout/tech/drc/README_maximal.md
@@ -6,30 +6,41 @@ List of available DRC rules:
| ------------------------ | --------------------------------------------------------------------------------------- |
| NW.a | Min. NWell width |
| NW.d1 | Min. NWell space to external N+Activ inside ThickGateOx |
+| NW.f | Min. NWell space to substrate tie in P+Activ not inside ThickGateOx |
+| NW.f1 | Min. NWell space to substrate tie in P+Activ inside ThickGateOx |
| PWB.a | Min. PWell:block width |
| PWB.b | Min. PWell:block space or notch |
| PWB.c | Min. PWell:block space to unrelated NWell |
| NBL.a | Min. nBuLay width |
| NBLB.a | Min. nBuLay:block width |
| NBLB.b | Min. nBuLay:block space or notch |
+| NBLB.c | Min. nBuLay enclosure of nBuLay:block |
| NBLB.d | Min. nBuLay:block space to unrelated nBuLay |
| Act.a | Min. Activ width |
| Act.b | Min. Activ space or notch |
-| Act.d | Min. Activ area (µm²) |
+| Act.d | Min. Activ area (µm²) |
+| Act.e | Min. Activ enclosed area (µm²) |
| AFil.a | Max. Activ:filler width |
| AFil.a1 | Min. Activ:filler width |
| AFil.b | Min. Activ:filler space |
| AFil.g | Min. global Activ density [%] |
| AFil.g1 | Max. global Activ density [%] |
-| AFil.g2 | Min. Activ coverage ratio for any 800 x 800 µm² chip area [%] |
-| AFil.g3 | Max. Activ coverage ratio for any 800 x 800 µm² chip area [%] |
+| AFil.g2 | Min. Activ coverage ratio for any 800 x 800 µm² chip area [%] |
+| AFil.g3 | Max. Activ coverage ratio for any 800 x 800 µm² chip area [%] |
+| TGO.a | Min. ThickGateOx extension over Activ |
+| TGO.b | Min. space between ThickGateOx and Activ outside thick gate oxide region |
+| TGO.c | Min. ThickGateOx extension over GatPoly over Activ |
+| TGO.d | Min. space between ThickGateOx and GatPoly over Activ outside thick gate oxide region |
| TGO.e | Min. ThickGateOx space (merge if less than this value) |
| TGO.f | Min. ThickGateOx width |
| Gat.a | Min. GatPoly width |
+| Gat.a3 | Min. GatPoly width for channel length of 3.3 V NFET |
+| Gat.a4 | Min. GatPoly width for channel length of 3.3 V PFET |
| Gat.b | Min. GatPoly space or notch |
| Gat.b1 | Min. space between unrelated 3.3 V GatPoly over Activ regions |
+| Gat.c | Min. GatPoly extension over Activ (end cap) |
| Gat.d | Min. GatPoly space to Activ |
-| Gat.e | Min. GatPoly area (µm²) |
+| Gat.e | Min. GatPoly area (µm²) |
| Gat.f | 45-degree and 90-degree angles for GatPoly on Activ area are not allowed |
| GFil.a | Max. GatPoly:filler width |
| GFil.b | Min. GatPoly:filler width |
@@ -45,19 +56,30 @@ List of available DRC rules:
| GFil.j | Min. GatPoly:filler extension over Activ:filler (end cap) |
| pSD.a | Min. pSD width |
| pSD.b | Min. pSD space or notch (Note 1) |
+| pSD.c | Min. pSD enclosure of P+Activ in NWell |
| pSD.d | Min. pSD space to unrelated N+Activ in PWell |
| pSD.d1 | Min. pSD space to N+Activ in NWell |
| pSD.e | Min. pSD overlap of Activ at one position when forming abutted substrate tie (Note 2) |
+| pSD.f | Min. Activ extension over pSD at one position when forming abutted NWell tie (Note 2) |
+| pSD.g | Min. N+Activ or P+Activ area (µm²) when forming abutted tie (Note 2) |
+| pSD.i | Min. pSD enclosure of PFET gate not inside ThickGateOx |
+| pSD.i1 | Min. pSD enclosure of PFET gate inside ThickGateOx |
| pSD.j | Min. pSD space to NFET gate not inside ThickGateOx |
| pSD.j1 | Min. pSD space to NFET gate inside ThickGateOx |
-| pSD.k | Min. pSD area (µm²) |
+| pSD.k | Min. pSD area (µm²) |
+| pSD.l | Min. pSD enclosed area (µm²) |
+| pSD.m | Min. pSD space to n-type poly resistors |
+| pSD.n | Min. pSD enclosure of p-type poly resistors |
| nSDB.a | Min. nSD:block width |
| nSDB.b | Min. nSD:block space or notch |
+| nSDB.c | Min. nSD:block space to unrelated pSD |
+| nSDB.e | Min. nSD:block space to Cont (Note 2) |
| EXT.a | Min. EXTBlock width |
| EXT.b | Min. EXTBlock space or notch |
| EXT.c | Min. EXTBlock space to pSD |
| Sal.a | Min. SalBlock width |
| Sal.b | Min. SalBlock space or notch |
+| Sal.c | Min. SalBlock extension over Activ or GatPoly |
| Sal.d | Min. SalBlock space to unrelated Activ or GatPoly |
| Sal.e | Min. SalBlock space to Cont |
| Cnt.a | Min. and max. Cont width |
@@ -67,6 +89,7 @@ List of available DRC rules:
| Cnt.g | Cont must be within Activ or GatPoly |
| Cnt.h | Cont must be covered with Metal1 |
| Cnt.j | Cont on GatPoly over Activ is not allowed |
+| CntB.a | Min. and max. ContBar width |
| CntB.a1 | Min. ContBar length |
| CntB.b | Min. ContBar space |
| CntB.b2 | Min. ContBar space to Cont |
@@ -74,76 +97,90 @@ List of available DRC rules:
| CntB.f | Min. ContBar on Activ space to GatPoly |
| CntB.g | ContBar must be within Activ or GatPoly |
| CntB.g1 | Min. pSD space to ContBar on nSD-Activ |
+| CntB.g2 | Min. pSD overlap of ContBar on pSD-Activ |
| CntB.h | ContBar must be covered with Metal1 |
| CntB.j | ContBar on GatPoly over Activ is not allowed |
| M1.a | Min. Metal1 width |
| M1.b | Min. Metal1 space or notch |
| M1.c | Min. Metal1 enclosure of Cont |
-| M1.d | Min. Metal1 area (µm²) |
+| M1.c1 | Min. Metal1 endcap enclosure of Cont (Note 1) |
+| M1.d | Min. Metal1 area (µm²) |
| M1.j | Min. global Metal1 density [%] |
| M1.k | Max. global Metal1 density [%] |
| M2.a | Min. Metal2 width |
| M2.b | Min. Metal2 space or notch |
-| M2.d | Min. Metal2 area (µm²) |
+| M2.c | Min. Metal2 enclosure of Via1 |
+| M2.c1 | Min. Metal2 endcap enclosure of Via1 (Note 1) |
+| M2.d | Min. Metal2 area (µm²) |
| M2.j | Min. global Metal2 density [%] |
| M2.k | Max. global Metal2 density [%] |
| M3.a | Min. Metal3 width |
| M3.b | Min. Metal3 space or notch |
-| M3.d | Min. Metal3 area (µm²) |
+| M3.c | Min. Metal3 enclosure of Via2 |
+| M3.c1 | Min. Metal3 endcap enclosure of Via2 (Note 1) |
+| M3.d | Min. Metal3 area (µm²) |
| M3.j | Min. global Metal3 density [%] |
| M3.k | Max. global Metal3 density [%] |
| M4.a | Min. Metal4 width |
| M4.b | Min. Metal4 space or notch |
-| M4.d | Min. Metal4 area (µm²) |
+| M4.c | Min. Metal4 enclosure of Via3 |
+| M4.c1 | Min. Metal4 endcap enclosure of Via3 (Note 1) |
+| M4.d | Min. Metal4 area (µm²) |
| M4.j | Min. global Metal4 density [%] |
| M4.k | Max. global Metal4 density [%] |
| M5.a | Min. Metal5 width |
| M5.b | Min. Metal5 space or notch |
-| M5.d | Min. Metal5 area (µm²) |
+| M5.c | Min. Metal5 enclosure of Via4 |
+| M5.c1 | Min. Metal5 endcap enclosure of Via4 (Note 1) |
+| M5.d | Min. Metal5 area (µm²) |
| M5.j | Min. global Metal5 density [%] |
| M5.k | Max. global Metal5 density [%] |
| M1Fil.a1 | Min. Metal1:filler width |
| M1Fil.b | Min. Metal1:filler space |
| M1Fil.c | Min. Metal1:filler space to Metal1 |
| M1Fil.d | Min. Metal1:filler space to TRANS |
-| M1Fil.h | Min. Metal1 and Metal1:filler coverage ratio for any 800 x 800 µm² chip area [%] |
-| M1Fil.k | Max. Metal1 and Metal1:filler coverage ratio for any 800 x 800 µm² chip area [%] |
+| M1Fil.h | Min. Metal1 and Metal1:filler coverage ratio for any 800 x 800 µm² chip area [%] |
+| M1Fil.k | Max. Metal1 and Metal1:filler coverage ratio for any 800 x 800 µm² chip area [%] |
| M2Fil.a1 | Min. Metal2:filler width |
| M2Fil.b | Min. Metal2:filler space |
| M2Fil.c | Min. Metal2:filler space to Metal2 |
| M2Fil.d | Min. Metal2:filler space to TRANS |
-| M2Fil.h | Min. Metal2 and Metal2:filler coverage ratio for any 800 x 800 µm² chip area [%] |
-| M2Fil.k | Max. Metal2 and Metal2:filler coverage ratio for any 800 x 800 µm² chip area [%] |
+| M2Fil.h | Min. Metal2 and Metal2:filler coverage ratio for any 800 x 800 µm² chip area [%] |
+| M2Fil.k | Max. Metal2 and Metal2:filler coverage ratio for any 800 x 800 µm² chip area [%] |
| M3Fil.a1 | Min. Metal3:filler width |
| M3Fil.b | Min. Metal3:filler space |
| M3Fil.c | Min. Metal3:filler space to Metal3 |
| M3Fil.d | Min. Metal3:filler space to TRANS |
-| M3Fil.h | Min. Metal3 and Metal3:filler coverage ratio for any 800 x 800 µm² chip area [%] |
-| M3Fil.k | Max. Metal3 and Metal3:filler coverage ratio for any 800 x 800 µm² chip area [%] |
+| M3Fil.h | Min. Metal3 and Metal3:filler coverage ratio for any 800 x 800 µm² chip area [%] |
+| M3Fil.k | Max. Metal3 and Metal3:filler coverage ratio for any 800 x 800 µm² chip area [%] |
| M4Fil.a1 | Min. Metal4:filler width |
| M4Fil.b | Min. Metal4:filler space |
| M4Fil.c | Min. Metal4:filler space to Metal4 |
| M4Fil.d | Min. Metal4:filler space to TRANS |
-| M4Fil.h | Min. Metal4 and Metal4:filler coverage ratio for any 800 x 800 µm² chip area [%] |
-| M4Fil.k | Max. Metal4 and Metal4:filler coverage ratio for any 800 x 800 µm² chip area [%] |
+| M4Fil.h | Min. Metal4 and Metal4:filler coverage ratio for any 800 x 800 µm² chip area [%] |
+| M4Fil.k | Max. Metal4 and Metal4:filler coverage ratio for any 800 x 800 µm² chip area [%] |
| M5Fil.a1 | Min. Metal5:filler width |
| M5Fil.b | Min. Metal5:filler space |
| M5Fil.c | Min. Metal5:filler space to Metal5 |
| M5Fil.d | Min. Metal5:filler space to TRANS |
-| M5Fil.h | Min. Metal5 and Metal5:filler coverage ratio for any 800 x 800 µm² chip area [%] |
-| M5Fil.k | Max. Metal5 and Metal5:filler coverage ratio for any 800 x 800 µm² chip area [%] |
+| M5Fil.h | Min. Metal5 and Metal5:filler coverage ratio for any 800 x 800 µm² chip area [%] |
+| M5Fil.k | Max. Metal5 and Metal5:filler coverage ratio for any 800 x 800 µm² chip area [%] |
| V1.a | Min. and max. Via1 width |
| V1.b | Min. Via1 space |
| V1.b1 | Min. Via1 space in an array of more than 3 rows and more then 3 columns (Note 1) |
+| V1.c1 | Min. Metal1 endcap enclosure of Via1 (Note 2) |
| V2.a | Min. and max. Via2 width |
| V2.b | Min. Via2 space |
| V2.b1 | Min. Via2 space in an array of more than 3 rows and more then 3 columns (Note 1) |
+| V2.c1 | Min. Metal2 endcap enclosure of Via2 (Note 2) |
| V3.a | Min. and max. Via3 width |
| V3.b | Min. Via3 space |
| V3.b1 | Min. Via3 space in an array of more than 3 rows and more then 3 columns (Note 1) |
+| V3.c1 | Min. Metal3 endcap enclosure of Via3 (Note 2) |
| V4.a | Min. and max. Via4 width |
| V4.b | Min. Via4 space |
| V4.b1 | Min. Via4 space in an array of more than 3 rows and more then 3 columns (Note 1) |
+| V4.c1 | Min. Metal4 endcap enclosure of Via4 (Note 2) |
| TV1.a | Min. and max. TopVia1 width |
| TV1.b | Min. TopVia1 space |
| TM1.a | Min. TopMetal1 width |
@@ -171,20 +208,36 @@ List of available DRC rules:
| npn13G2L.b | Max. npn13G2L emitter length |
| npn13G2V.a | Min. npn13G2V emitter length |
| npn13G2V.b | Max. npn13G2V emitter length |
+| Rsil.a | Min. GatPoly width |
| Rsil.b | Min. RES space to Cont |
+| Rsil.c | Min. RES extension over GatPoly |
+| Rsil.d | Min. pSD space to GatPoly |
+| Rsil.e | Min. EXTBlock enclosure of GatPoly |
| Rsil.f | Min. RES length |
+| Rppd.a | Min. GatPoly width |
+| Rppd.b | Min. pSD enclosure of GatPoly |
+| Rppd.c | Min. and max. SalBlock space to Cont |
+| Rppd.e | Min. SalBlock length |
| Rhi.a | Min. GatPoly width |
+| Rhi.b | pSD and nSD are identical (Note 1) |
+| Rhi.c | Min. pSD and nSD enclosure of GatPoly |
+| Rhi.d | Min. and max. SalBlock space to Cont |
| Rhi.f | Min. SalBlock length |
+| nmosi.b | Min. nBuLay enclosure of Iso-PWell-Activ (Note 1) |
| nmosi.c | Min. NWell space to Iso-PWell-Activ |
| nmosi.d | Min. NWell-nBuLay width forming an unbroken ring around any Iso-PWell-Activ (Note 2) |
| nmosi.f | Min. nSD:block width to separate ptap in nmosi |
| nmosi.g | Min. SalBlock overlap of nSD:block over Activ |
+| Sdiod.a | Min. and max. PWell:block enclosure of ContBar |
+| Sdiod.b | Min. and max. nSD:block enclosure of ContBar |
+| Sdiod.c | Min. and max. SalBlock enclosure of ContBar |
| Pad.aR | Min. recommended Pad width |
| Pad.a1 | Max. Pad width |
| Pad.bR | Min. recommended Pad space |
| Pad.d | Min. Pad space to EdgeSeal |
| Pad.dR | Min. recommended Pad to EdgeSeal space (Note 1) |
| Pad.d1R | Min. recommended Pad to Activ (inside chip area) space |
+| Pad.gR | TopMetal1 (within dfpad) enclosure of TopVia2 |
| Pad.jR | No devices under Pad allowed (Note 2) |
| Pad.kR | TopVia2 under Pad not allowed (Note 3) |
| Padc.b | Min. CuPillarPad space |
@@ -209,29 +262,57 @@ List of available DRC rules:
| MIM.a | Min. MIM width |
| MIM.b | Min. MIM space |
| MIM.e | Min. TopMetal1 space to MIM |
-| MIM.f | Min. MIM area per MIM device (µm²) |
-| MIM.g | Max. MIM area per MIM device (µm²) |
+| MIM.f | Min. MIM area per MIM device (µm²) |
+| MIM.g | Max. MIM area per MIM device (µm²) |
| MIM.h | TopVia1 must be over MIM |
+| LU.a | Max. space from any portion of P+Activ inside NWell to an nSD-NWell tie |
+| LU.c | Max. extension of an abutted NWell tie beyond Cont |
+| LU.c1 | Max. extension of an abutted substrate tie beyond Cont |
+| LU.d | Max. extension of NWell tie Activ tie beyond Cont |
+| LU.d1 | Max. extension of an substrate tie Activ beyond Cont |
| Slt.a.M1 | Min. Metal1:slit width |
+| Slt.b.M1 | Max. Metal1:slit width |
+| Slt.c.M1 | Max. Metal1 width without requiring a slit |
| Slt.e.M1 | No slits required on bond pads |
+| Slt.f.M1 | Min. Metal1 enclosure of Metal1:slit |
| Slt.h1 | Min. Metal1:slit space to Cont and Via1 |
| Slt.a.M2 | Min. Metal2:slit width |
+| Slt.b.M2 | Max. Metal2:slit width |
+| Slt.c.M2 | Max. Metal2 width without requiring a slit |
| Slt.e.M2 | No slits required on bond pads |
+| Slt.f.M2 | Min. Metal2 enclosure of Metal2:slit |
| Slt.h2.M2 | Min. Metal2:slit space to Via1 and Via2 |
| Slt.a.M3 | Min. Metal3:slit width |
+| Slt.b.M3 | Max. Metal3:slit width |
+| Slt.c.M3 | Max. Metal3 width without requiring a slit |
| Slt.e.M3 | No slits required on bond pads |
+| Slt.f.M3 | Min. Metal3 enclosure of Metal2:slit |
| Slt.h2.M3 | Min. Metal3:slit space to Via2 and Via3 |
| Slt.a.M4 | Min. Metal4:slit width |
+| Slt.b.M4 | Max. Metal4:slit width |
+| Slt.c.M4 | Max. Metal4 width without requiring a slit |
| Slt.e.M4 | No slits required on bond pads |
+| Slt.f.M4 | Min. Metal4 enclosure of Metal4:slit |
| Slt.h2.M4 | Min. Metal4:slit space to Via3 and Via4 |
| Slt.a.M5 | Min. Metal5:slit width |
+| Slt.b.M5 | Max. Metal5:slit width |
+| Slt.c.M5 | Max. Metal5 width without requiring a slit |
| Slt.e.M5 | No slits required on bond pads |
+| Slt.f.M5 | Min. Metal5 enclosure of Metal5:slit |
+| Slt.g.M5 | Min. Metal5:slit and TopMetal1:slit space to MIM |
| Slt.h2.M5 | Min. Metal5:slit space to Via4 and Via5 |
| Slt.a.TM1 | Min. TopMetal1:slit width |
+| Slt.b.TM1 | Max. TopMetal1:slit width |
+| Slt.c.TM1 | Max. TopMetal1 width without requiring a slit |
| Slt.e.TM1 | No slits required on bond pads |
+| Slt.f.TM1 | Min. TopMetal1 enclosure of TopMetal1:slit |
+| Slt.g.TM1 | Min. Metal5:slit and TopMetal1:slit space to MIM |
| Slt.h3 | Min. TopMetal1:slit space to TopVia1 and TopVia2 |
| Slt.a.TM2 | Min. TopMetal2:slit width |
+| Slt.b.TM2 | Max. TopMetal2:slit width |
+| Slt.c.TM2 | Max. TopMetal2 width without requiring a slit |
| Slt.e.TM2 | No slits required on bond pads |
+| Slt.f.TM2 | Min. TopMetal2 enclosure of TopMetal2:slit |
| Slt.h4 | Min. TopMetal2:slit space to TopVia2 |
| Pin.a | Min. Activ enclosure of Activ:pin |
| Pin.b | Min. GatPoly enclosure of GatPoly:pin |
@@ -246,19 +327,27 @@ List of available DRC rules:
| NW.f1.dig | Min. NWell space to substrate tie in P+Activ inside ThickGateOx |
| Gat.a.SRAM | Min. GatPoly width |
| Gat.b.SRAM | Min. GatPoly space or notch |
+| Gat.c.SRAM | Min. GatPoly extension over Activ (end cap) |
| Gat.d.SRAM | Min. GatPoly space to Activ |
| pSD.e.SRAM | Min. pSD overlap of Activ when forming abutted substrate tie |
+| pSD.g.SRAM | Min. N+Activ or P+Activ width when forming abutted tie |
+| pSD.i.SRAM | Min. pSD enclosure of PFET gate not inside ThickGateOx |
| pSD.j.SRAM | Min. pSD space to NFET gate not inside ThickGateOx |
| Cnt.f.SRAM | Min. Cont on Activ space to GatPoly |
| M1.b.SRAM | Min. Metal1 space or notch |
+| M1.c1.SRAM | Min. Metal1 endcap enclosure of Cont |
| M2.b.SRAM | Min. Metal2 space or notch |
+| M2.c1.SRAM | Min. Metal2 endcap enclosure of Via1 |
| M3.b.SRAM | Min. Metal3 space or notch |
+| M3.c1.SRAM | Min. Metal3 endcap enclosure of Via2 |
| M4.b.SRAM | Min. Metal4 space or notch |
+| M4.c1.SRAM | Min. Metal4 endcap enclosure of Via3 |
| M5.b.SRAM | Min. Metal5 space or notch |
+| M5.c1.SRAM | Min. Metal5 endcap enclosure of Via4 |
| LBE.a | Min. LBE width |
| LBE.b | Max. LBE width |
-| LBE.b1 | Max. LBE area (µm²) |
-| LBE.b2 | Min. LBE area (µm²) |
+| LBE.b1 | Max. LBE area (µm²) |
+| LBE.b2 | Min. LBE area (µm²) |
| LBE.c | Min. LBE space or notch |
| LBE.d | Min. LBE space to inner edge of EdgeSeal |
| LBE.e.dfPad | Min. LBE space to dfpad and Passiv |
@@ -266,6 +355,12 @@ List of available DRC rules:
| LBE.f | Min. LBE space to Activ |
| LBE.h | No LBE ring allowed |
| LBE.i | Max. global LBE density [%] |
+| TSV_G.a | DeepVia has to be a ring structure |
+| TSV_G.d | Min. DeepVia space |
+| TSV_G.f | Min. PWell:block enclosure of DeepVia |
+| TSV_G.g | Min. Metal1 enclosure of DeepVia ring structure |
+| TSV_G.i | Max. global DeepVia density [%] |
+| TSV_G.j | Max. DeepVia coverage ratio for any 500.0 x 500.0 µm² chip area [%] |
| forbidden.BiWind | Forbidden drawn layer BiWind on GDS layer 3/0 |
| forbidden.PEmWind | Forbidden drawn layer PEmWind on GDS layer 11/0 |
| forbidden.BasPoly | Forbidden drawn layer BasPoly on GDS layer 13/0 |
@@ -349,4 +444,4 @@ List of available DRC rules:
| OffGrid.dfpad_sbump | dfpad_sbump is off-grid |
| OffGrid.DeepVia | DeepVia is off-grid |
| OffGrid.LBE | LBE is off-grid |
-| OffGrid.PolyRes | PolyRes is off-grid |
\ No newline at end of file
+| OffGrid.PolyRes | PolyRes is off-grid |
diff --git a/ihp-sg13g2/libs.tech/klayout/tech/drc/sg13g2.lydrc b/ihp-sg13g2/libs.tech/klayout/tech/drc/sg13g2.lydrc
deleted file mode 100644
index 4238b0c0..00000000
--- a/ihp-sg13g2/libs.tech/klayout/tech/drc/sg13g2.lydrc
+++ /dev/null
@@ -1,766 +0,0 @@
-
-
-
-
-
- drc
-
-
-
- false
- false
-
- true
- drc_scripts
- tools_menu.drc.end
- dsl
- drc-dsl-xml
-
-application = RBA::Application.instance
-main_window = application.main_window
-if main_window
- curr_layout_view = main_window.current_view()
- unless curr_layout_view
- layout_path = RBA::FileDialog::ask_open_file_name("Chose your layout file.", ".", "GDSII files (*.GDS *.gds *.GDS.gz *.gds.gz *.GDS2 *.gds2 *.GDS2.gz *.gds2.gz);; All files (*)")
- main_window.load_layout(layout_path, 1)
- curr_layout_view = main_window.current_view()
- end
- active_cellname = RBA::CellView::active.cell_name
-else
- puts "DRC: batch mode"
- if $cell
- active_cellname = $cell
- puts "Active cell: " + active_cellname
- else
- raise("ERROR: 'cell' script variable must be defined on cmd line")
- end
-end
-active_layout = RBA::CellView::active.layout
-
-source(active_layout, active_cellname)
-if active_layout.dbu != 0.001
- puts "WARNING: Layout dbu value (" + active_layout.dbu.to_s + " ) deviates from rule file dbu value (0.001). This will scale the layout and may not be intended."
-end
-report("design rules: sg13g2 | layout cell: " + active_cellname, "sg13g2_#{active_cellname}.lyrdb", active_cellname)
-
-deep
-
-# Initial definitions of control flow variables
-conditional_enabled = {}
-conditional_enabled[:density] = true
-conditional_enabled[:sanityRules] = true
-
-class DRC::DRCLayer
- def ext_and(other)
- self_min_coherence_state = self.data.min_coherence?
- other_min_coherence_state = other.data.min_coherence?
- self.data.min_coherence = true
- other.data.min_coherence = true
- output_layer = self & other
- self.data.min_coherence = self_min_coherence_state
- other.data.min_coherence = other_min_coherence_state
- return output_layer
- end
-
- def ext_area(constraint)
- output_layer = self.dup
- constraint.each do |expression|
- output_layer.data.min_coherence = true
- relation = expression[0]
- value = expression[1].to_i
- if relation == ">"
- output_layer = output_layer.with_area((value + 1), nil)
- elsif relation == "<"
- output_layer = output_layer.with_area(nil, value)
- elsif relation == "=="
- output_layer = output_layer.with_area(value)
- elsif relation == "!="
- output_layer = output_layer.without_area(value)
- elsif relation == ">="
- output_layer = output_layer.with_area(value, nil)
- elsif relation == "<="
- output_layer = output_layer.with_area(nil, (value + 1))
- else
- raise "invalid expression"
- end
- end
- return output_layer
- end
-
- def ext_constraint_satisfied(value, constraint)
- output_bool = true
- constraint.each do |expression|
- if expression[0] == ">"
- output_bool = output_bool && (value > expression[1])
- elsif expression[0] == "<"
- output_bool = output_bool && (value < expression[1])
- elsif expression[0] == "=="
- output_bool = output_bool && (value == expression[1])
- elsif expression[0] == "!="
- output_bool = output_bool && (value != expression[1])
- elsif expression[0] == ">="
- output_bool = output_bool && (value >= expression[1])
- elsif expression[0] == "<="
- output_bool = output_bool && (value <= expression[1])
- else
- raise "invalid expression"
- end
- end
- return output_bool
- end
-
- def ext_covering(other)
- self_min_coherence_state = self.data.min_coherence?
- other_min_coherence_state = other.data.min_coherence?
- self.data.min_coherence = true
- other.data.min_coherence = true
- output_layer = self.covering(other.inside(self))
- self.data.min_coherence = self_min_coherence_state
- other.data.min_coherence = other_min_coherence_state
- return output_layer
- end
-
- def ext_not(other)
- self_min_coherence_state = self.data.min_coherence?
- other_min_coherence_state = other.data.min_coherence?
- self.data.min_coherence = true
- other.data.min_coherence = true
- output_layer = self - other
- self.data.min_coherence = self_min_coherence_state
- other.data.min_coherence = other_min_coherence_state
- return output_layer
- end
-
- def ext_or(other)
- self_min_coherence_state = self.data.min_coherence?
- other_min_coherence_state = other.data.min_coherence?
- self.data.min_coherence = true
- other.data.min_coherence = true
- output_layer = self | other
- self.data.min_coherence = self_min_coherence_state
- other.data.min_coherence = other_min_coherence_state
- return output_layer
- end
-
- def ext_rectangles(axis_aligned = false, use_bbox = false, constraint1 = nil, constraint2 = nil, aspect_ratio_constraint = nil, inverted: false)
- self_min_coherence_state = self.data.min_coherence?
- self.data.min_coherence = true
- if ( ( constraint1 && ( !constraint2 || constraint1.length() > 1 || constraint1[0][0] != "==") ) ||
- ( constraint2 && ( constraint2.length() > 1 || constraint2[0][0] != "==" ) ) ||
- ( constraint1 && constraint2 && constraint1[0][1] != constraint2[0][1] ) )
- raise "ext_rectangle: unsupported options"
- end
- square = constraint1 ? true : false
- shape_filter =
- if use_bbox
- @engine.extents
- elsif axis_aligned
- @engine.rectangles
- else
- @engine.if_all((@engine.corners == 270).count == 4, @engine.corners.count == 4)
- end
- if square
- if use_bbox
- shape_filter = @engine.if_all((@engine.extents.length == constraint1[0][1]).count == 4)
- else
- square_filter = (@engine.length == constraint1[0][1]).count == 4
- shape_filter = @engine.if_all(shape_filter, square_filter)
- end
- end
- if inverted
- output_layer = self.drc(! shape_filter)
- else
- output_layer = self.drc(shape_filter)
- end
- self.data.min_coherence = self_min_coherence_state
- return output_layer
- end
-
- def ext_ring
- holes = self.holes
- hulls = self.hulls
- covering = hulls.covering(holes)
- result = covering.and(self)
- return result
- end
-
- def ext_interacting_with_text(text_layer_number, text)
- text_layer = @engine.labels(text_layer_number)
- initial_merged_semantics = self.data.merged_semantics?
- self.data.merged_semantics = false
- result = self.interacting(text_layer.texts(text))
- self.data.merged_semantics = initial_merged_semantics
- return result
- end
-
- def ext_with_density(range, *args)
- if self.is_empty?
- return DRC::DRCLayer::new(@engine, RBA::Region::new())
- end
- origin = 'cc'
- tile_size = nil
- tile_step = nil
- arguments = [range]
- args.each do |a|
- if a.is_a?(DRC::DRCTileSize)
- tile_size = a
- arguments.push(tile_size)
- elsif a.is_a?(DRC::DRCTileStep)
- tile_step = a
- arguments.push(tile_step)
- elsif a.is_a?(String)
- origin = a
- else
- raise "argument error"
- end
- end
- bbox = @engine.extent.bbox
- if origin == 'll'
- origin_x = bbox.left
- origin_y = bbox.bottom
- tile_origin = DRC::DRCTileOrigin::new(origin_x, origin_y)
- arguments.push(tile_origin)
- elsif origin != 'cc'
- raise "Unkown origin: 'cc' or 'll' expected"
- end
- if tile_size
- return self.with_density(*arguments)
- else
- tile_size = DRC::DRCTileSize::new(bbox.width, bbox.height)
- tile_count = DRC::DRCTileCount::new(1,2)
- enlarged_bbox = bbox.enlarged(1.1).to_itype(@engine.dbu)
- boundary_layer = DRC::DRCLayer::new(@engine, RBA::Region::new(enlarged_bbox))
- tile_boundary = DRC::DRCTileBoundary::new(boundary_layer)
- result = self.with_density(*arguments, tile_size, tile_count, tile_boundary)
- return result.raw.overlapping(DRC::DRCLayer::new(@engine, RBA::Region::new(bbox.to_itype(@engine.dbu))))
- end
- end
-end
-NWell_org = source.polygons("31/0")
-NWell_pin_org = source.polygons("31/2")
-Activ_org = source.polygons("1/0")
-Activ_pin_org = source.polygons("1/2")
-Activ_filler_org = source.polygons("1/22")
-ThickGateOx_org = source.polygons("44/0")
-GatPoly_org = source.polygons("5/0")
-GatPoly_pin_org = source.polygons("5/2")
-GatPoly_filler_org = source.polygons("5/22")
-Cont_org = source.polygons("6/0")
-Metal1_org = source.polygons("8/0")
-Metal1_pin_org = source.polygons("8/2")
-Metal1_filler_org = source.polygons("8/22")
-Metal1_slit_org = source.polygons("8/24")
-Via1_org = source.polygons("19/0")
-Metal2_org = source.polygons("10/0")
-Metal2_pin_org = source.polygons("10/2")
-Metal2_filler_org = source.polygons("10/22")
-Metal2_slit_org = source.polygons("10/24")
-Via2_org = source.polygons("29/0")
-Metal3_org = source.polygons("30/0")
-Metal3_pin_org = source.polygons("30/2")
-Metal3_filler_org = source.polygons("30/22")
-Metal3_slit_org = source.polygons("30/24")
-Via3_org = source.polygons("49/0")
-Metal4_org = source.polygons("50/0")
-Metal4_pin_org = source.polygons("50/2")
-Metal4_filler_org = source.polygons("50/22")
-Metal4_slit_org = source.polygons("50/24")
-Via4_org = source.polygons("66/0")
-Metal5_org = source.polygons("67/0")
-Metal5_pin_org = source.polygons("67/2")
-Metal5_filler_org = source.polygons("67/22")
-Metal5_slit_org = source.polygons("67/24")
-TopVia1_org = source.polygons("125/0")
-TopMetal1_org = source.polygons("126/0")
-TopMetal1_pin_org = source.polygons("126/2")
-TopMetal1_filler_org = source.polygons("126/22")
-TopMetal1_slit_org = source.polygons("126/24")
-Vmim_org = source.polygons("129/0")
-TopVia2_org = source.polygons("133/0")
-TopMetal2_org = source.polygons("134/0")
-TopMetal2_pin_org = source.polygons("134/2")
-TopMetal2_filler_org = source.polygons("134/22")
-TopMetal2_slit_org = source.polygons("134/24")
-Passiv_org = source.polygons("9/0")
-EdgeSeal_org = source.polygons("39/0")
-BiWind_org = source.polygons("3/0")
-PEmWind_org = source.polygons("11/0")
-BasPoly_org = source.polygons("13/0")
-DeepCo_org = source.polygons("35/0")
-PEmPoly_org = source.polygons("53/0", "70/0")
-EmPoly_org = source.polygons("55/0")
-LDMOS_org = source.polygons("57/0")
-PBiWind_org = source.polygons("58/0")
-Flash_org = source.polygons("71/0")
-ColWind_org = source.polygons("139/0")
-SRAM_org = source.polygons("25/0")
-TRANS_org = source.polygons("26/0")
-NoDRC = source.polygons("62/0")
-LBE_org = source.polygons("157/0")
-NWell = NWell_org.ext_not(NoDRC)
-Activ = Activ_org.ext_not(NoDRC)
-ThickGateOx = ThickGateOx_org.ext_not(NoDRC)
-GatPoly = GatPoly_org.ext_not(NoDRC)
-Cont = Cont_org.ext_not(NoDRC)
-ActFiller = Activ_filler_org.ext_not(NoDRC)
-GatFiller = GatPoly_filler_org.ext_not(NoDRC)
-Activ_pin = Activ_pin_org.ext_not(NoDRC)
-GatPoly_pin = GatPoly_pin_org.ext_not(NoDRC)
-NWell_pin = NWell_pin_org.ext_not(NoDRC)
-Metal1 = Metal1_org.ext_not(NoDRC)
-Via1 = Via1_org.ext_not(NoDRC)
-Metal2 = Metal2_org.ext_not(NoDRC)
-Via2 = Via2_org.ext_not(NoDRC)
-Metal3 = Metal3_org.ext_not(NoDRC)
-Via3 = Via3_org.ext_not(NoDRC)
-Metal4 = Metal4_org.ext_not(NoDRC)
-Via4 = Via4_org.ext_not(NoDRC)
-Metal5 = Metal5_org.ext_not(NoDRC)
-Vmim = Vmim_org.ext_not(NoDRC)
-TopMetal1 = TopMetal1_org.ext_not(NoDRC)
-TopVia2 = TopVia2_org.ext_not(NoDRC)
-TopMetal2 = TopMetal2_org.ext_not(NoDRC)
-Passiv = Passiv_org.ext_not(NoDRC)
-EdgeSeal = EdgeSeal_org.ext_not(NoDRC)
-M1Filler = Metal1_filler_org.ext_not(NoDRC)
-M2Filler = Metal2_filler_org.ext_not(NoDRC)
-M3Filler = Metal3_filler_org.ext_not(NoDRC)
-M4Filler = Metal4_filler_org.ext_not(NoDRC)
-M5Filler = Metal5_filler_org.ext_not(NoDRC)
-TopMet1Filler = TopMetal1_filler_org.ext_not(NoDRC)
-TopMet2Filler = TopMetal2_filler_org.ext_not(NoDRC)
-M1Slit = Metal1_slit_org.ext_not(NoDRC)
-M2Slit = Metal2_slit_org.ext_not(NoDRC)
-M3Slit = Metal3_slit_org.ext_not(NoDRC)
-M4Slit = Metal4_slit_org.ext_not(NoDRC)
-M5Slit = Metal5_slit_org.ext_not(NoDRC)
-TopMet1Slit = TopMetal1_slit_org.ext_not(NoDRC)
-TopMet2Slit = TopMetal2_slit_org.ext_not(NoDRC)
-Metal1_pin = Metal1_pin_org.ext_not(NoDRC)
-Metal2_pin = Metal2_pin_org.ext_not(NoDRC)
-Metal3_pin = Metal3_pin_org.ext_not(NoDRC)
-Metal4_pin = Metal4_pin_org.ext_not(NoDRC)
-Metal5_pin = Metal5_pin_org.ext_not(NoDRC)
-TopMetal1_pin = TopMetal1_pin_org.ext_not(NoDRC)
-TopMetal2_pin = TopMetal2_pin_org.ext_not(NoDRC)
-TRANS = TRANS_org.ext_not(NoDRC)
-SRAM = SRAM_org.ext_not(NoDRC)
-LBE = LBE_org.ext_not(NoDRC)
-TopVia1 = NoDRC.ext_or(Vmim_org).ext_or(TopVia1_org.ext_not(NoDRC))
-Activ_Act_a = Activ.width(150)
-ThickGateOx_TGO_f = ThickGateOx.width(860)
-Cont_SQ = Cont.ext_rectangles(true, false, [["==", 160]], [["==", 160]], nil)
-ContBar = Cont.ext_area([[">", (0.16*0.16)*1000.0*1000.0]])
-Act_density = ActFiller.ext_or(Activ)
-Gat_density = GatFiller.ext_or(GatPoly)
-Act_Nsram = Activ.ext_not(SRAM)
-GP_Nsram = GatPoly.ext_not(SRAM)
-M1_Nsram = Metal1.ext_not(SRAM)
-M2_Nsram = Metal2.ext_not(SRAM)
-M3_Nsram = Metal3.ext_not(SRAM)
-M4_Nsram = Metal4.ext_not(SRAM)
-M5_Nsram = Metal5.ext_not(SRAM)
-M1_density = M1Filler.ext_or(Metal1).ext_not(M1Slit)
-M2_density = M2Filler.ext_or(Metal2).ext_not(M2Slit)
-M3_density = M3Filler.ext_or(Metal3).ext_not(M3Slit)
-M4_density = M4Filler.ext_or(Metal4).ext_not(M4Slit)
-M5_density = M5Filler.ext_or(Metal5).ext_not(M5Slit)
-TM1_density = TopMet1Filler.ext_or(TopMetal1).ext_not(TopMet1Slit)
-TM2_density = TopMet2Filler.ext_or(TopMetal2).ext_not(TopMet2Slit)
-emi2Pin = Metal2_pin.ext_and(TRANS).ext_interacting_with_text(63, "E")
-GP_Nsram_Gat_a = GP_Nsram.width(130)
-GP_Nsram_Gat_b = GP_Nsram.space(180)
-transG2L = TRANS.ext_interacting_with_text(63, "npn13G2L").ext_covering(emi2Pin)
-
--> do
- Activ_Act_a.dup
-end.().output("Act.a", "Min. Activ width = 0.15")
-
--> do
- Act_Nsram.space(210)
-end.().output("Act.b", "Act.b: Min. Activ space or notch = 0.21")
-
--> do
- ThickGateOx_TGO_f.dup
-end.().output("TGO.f", "Min. ThickGateOx width = 0.86")
-
--> do
- GP_Nsram_Gat_a.dup
-end.().output("Gat.a", "Min GatPoly width = 0.13")
-
--> do
- GP_Nsram_Gat_b.dup
-end.().output("Gat.b", "Min. GatPoly space or notch = 0.18")
-
--> do
- GP_Nsram.separation(Act_Nsram, 70)
-end.().output("Gat.d", "Min. GatPoly to Activ space = 0.07")
-
--> do
- Cont.merged(true, 0).outside(EdgeSeal).ext_not(ContBar.ext_or(Cont_SQ))
-end.().output("Cnt.a", "Min.and max. size of Cont = 0.16")
-
--> do
- Cont.merged(true, 0).outside(EdgeSeal).space(180)
-end.().output("Cnt.b", "Min. Cont space = 0.18")
-
--> do
- Passiv.width(2100)
-end.().output("Pas.a", "Min. Passiv width = 2.10")
-
--> do
- Passiv.space(3500)
-end.().output("Pas.b", "Min. Passiv space or notch = 3.50")
-
--> do
- Metal1.width(160)
-end.().output("M1.a", "Min. width of Metal1 = 0.16")
-
--> do
- M1_Nsram.space(180)
-end.().output("M1.b", "Min. Metal1 space or notch = 0.18")
-
--> do
- Metal2.width(200)
-end.().output("M2.a", "Min. width of Metal2 = 0.2")
-
--> do
- M2_Nsram.space(210)
-end.().output("M2.b", "Min. Metal2 space or notch = 0.21")
-
--> do
- Metal3.width(200)
-end.().output("M3.a", "Min. width of Metal3 = 0.2")
-
--> do
- M3_Nsram.space(210)
-end.().output("M3.b", "Min. Metal3 space or notch = 0.21")
-
--> do
- Metal4.width(200)
-end.().output("M4.a", "Min. width of Metal4 = 0.2")
-
--> do
- M4_Nsram.space(210)
-end.().output("M4.b", "Min. Metal4 space or notch = 0.21")
-
--> do
- Metal5.width(200)
-end.().output("M5.a", "Min. width of Metal5 = 0.2")
-
--> do
- M5_Nsram.space(210)
-end.().output("M5.b", "Min. Metal5 space or notch = 0.21")
-
--> do
- Via1.ext_not(EdgeSeal).merged(true, 0).outside(transG2L).ext_rectangles(false, false, [["==", 190]], [["==", 190]], nil, inverted: true)
-end.().output("Via1.a", "Via1.a: Min. and Maxi. size of Via1 = 0.19")
-
--> do
- Via1.ext_not(EdgeSeal).space(220)
-end.().output("Via1.b", "Via1.b: Min. Via1 space = 0.22")
-
--> do
- Via2.ext_not(EdgeSeal).merged(true, 0).outside(transG2L).ext_rectangles(false, false, [["==", 190]], [["==", 190]], nil, inverted: true)
-end.().output("Via2.a", "Via2.a: Min. and Maxi. size of Via2 = 0.19")
-
--> do
- Via2.ext_not(EdgeSeal).space(220)
-end.().output("Via2.b", "Via2.b: Min. Via2 space = 0.22")
-
--> do
- Via3.ext_not(EdgeSeal).merged(true, 0).outside(transG2L).ext_rectangles(false, false, [["==", 190]], [["==", 190]], nil, inverted: true)
-end.().output("Via3.a", "Via3.a: Min. and Maxi. size of Via3 = 0.19")
-
--> do
- Via3.ext_not(EdgeSeal).space(220)
-end.().output("Via3.b", "Via3.b: Min. Via3 space = 0.22")
-
--> do
- Via4.ext_not(EdgeSeal).merged(true, 0).outside(transG2L).ext_rectangles(false, false, [["==", 190]], [["==", 190]], nil, inverted: true)
-end.().output("Via4.a", "Via4.a: Min. and Maxi. size of Via4 = 0.19")
-
--> do
- Via4.ext_not(EdgeSeal).space(220)
-end.().output("Via4.b", "Via4.b: Min. Via4 space = 0.22")
-
--> do
- Vmim.ext_or(TopVia1.ext_not(EdgeSeal)).ext_rectangles(false, false, [["==", 420]], [["==", 420]], nil, inverted: true)
-end.().output("TV1.a", "Min.and Max. TopVia1 (µm²) = 0.42")
-
--> do
- TopVia1.ext_or(Vmim).space(420)
-end.().output("TV1.b", "Min. TopVia1 space = 0.42")
-
--> do
- TopMetal1.width(1640)
-end.().output("TM1.a", "Min. width of TopMetal1 = 1.64")
-
--> do
- TopMetal1.space(1640)
-end.().output("TM1.b", "Min. TopMetal1 space or notch = 1.64")
-
--> do
- TopMetal2.width(2000)
-end.().output("TM2.a", "Min. width of TopMetal2 = 2.0")
-
--> do
- TopMetal2.space(2000)
-end.().output("TM2.b", "Min. TopMetal2 space or notch = 2.0")
-
--> do
- TopVia2.ext_not(EdgeSeal).ext_rectangles(false, false, [["==", 900]], [["==", 900]], nil, inverted: true)
-end.().output("TV2.a", "Min.and Max. TopVia2 = 0.90")
-
--> do
- TopVia2.space(1060)
-end.().output("TV2.b", "Min. TopVia2 space = 1.06")
-
-if conditional_enabled[:density]
-
- -> do
- Act_density.ext_with_density(0.0 .. 0.35, 'll')
- end.().output("aFil.g", "Min. global Activ coverage = 35.0 %")
-
- -> do
- Act_density.ext_with_density(0.55 .. 1.0, 'll')
- end.().output("aFil.g1", "Max. global Activ coverage = 55.0 %")
-
- -> do
- Act_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("aFil.g2", "Min. Active coverage ratio for any 800 x 800 µm² chip area = 25.0 %")
-
- -> do
- Act_density.ext_with_density(0.65 .. 1.0, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("aFil.g3", "Max. Active coverage ratio for any 800 x 800 µm² chip area = 65.0 %")
-
- -> do
- Gat_density.ext_with_density(0.0 .. 0.15, 'll')
- end.().output("GFil.g", "Min. global GatPoly density [%] = 15.0")
-
- -> do
- M1_density.ext_with_density(0.0 .. 0.35, 'll')
- end.().output("M1.j", "Min. global Metal1 density [%] = 35.0")
-
- -> do
- M1_density.ext_with_density(0.6 .. 1.0, 'll')
- end.().output("M1.k", "Max. global Metal1 density [%] = 60.0")
-
- -> do
- M2_density.ext_with_density(0.0 .. 0.35, 'll')
- end.().output("M2.j", "Min. global Metal2 density [%] = 35.0")
-
- -> do
- M2_density.ext_with_density(0.6 .. 1.0, 'll')
- end.().output("M2.k", "Max. global Metal2 density [%] = 60.0")
-
- -> do
- M3_density.ext_with_density(0.0 .. 0.35, 'll')
- end.().output("M3.j", "Min. global Metal3 density [%] = 35.0")
-
- -> do
- M3_density.ext_with_density(0.6 .. 1.0, 'll')
- end.().output("M3.k", "Max. global Metal3 density [%] = 60.0")
-
- -> do
- M4_density.ext_with_density(0.0 .. 0.35, 'll')
- end.().output("M4.j", "Min. global Metal4 density [%] = 35.0")
-
- -> do
- M4_density.ext_with_density(0.6 .. 1.0, 'll')
- end.().output("M4.k", "Max. global Metal4 density [%] = 60.0")
-
- -> do
- M5_density.ext_with_density(0.0 .. 0.35, 'll')
- end.().output("M5.j", "Min. global Metal5 density [%] = 35.0")
-
- -> do
- M5_density.ext_with_density(0.6 .. 1.0, 'll')
- end.().output("M5.k", "Max. global Metal5 density [%] = 60.0")
-
- -> do
- M1_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M1Fil.h", "Min. Metal coverage MM1Filler ratio for any 800 x 800 µm² chip area [%] = 25.0")
-
- -> do
- M1_density.ext_with_density(0.75 .. 1.0, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M1Fil.k", "Max. Metal coverage MM1Filler ratio for any 800 x 800 µm² chip area [%] = 75.0")
-
- -> do
- M2_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M2Fil.h", "Min. Metal coverage MM2Filler ratio for any 800 x 800 µm² chip area [%] = 25.0")
-
- -> do
- M2_density.ext_with_density(0.75 .. 1.0, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M2Fil.k", "Max. Metal coverage MM2Filler ratio for any 800 x 800 µm² chip area [%] = 75.0")
-
- -> do
- M3_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M3Fil.h", "Min. Metal coverage MM3Filler ratio for any 800 x 800 µm² chip area [%] = 25.0")
-
- -> do
- M3_density.ext_with_density(0.75 .. 1.0, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M3Fil.k", "Max. Metal coverage MM3Filler ratio for any 800 x 800 µm² chip area [%] = 75.0")
-
- -> do
- M4_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M4Fil.h", "Min. Metal coverage MM4Filler ratio for any 800 x 800 µm² chip area [%] = 25.0")
-
- -> do
- M4_density.ext_with_density(0.75 .. 1.0, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M4Fil.k", "Max. Metal coverage MM4Filler ratio for any 800 x 800 µm² chip area [%] = 75.0")
-
- -> do
- M5_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M5Fil.h", "Min. Metal coverage MM5Filler ratio for any 800 x 800 µm² chip area [%] = 25.0")
-
- -> do
- M5_density.ext_with_density(0.75 .. 1.0, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M5Fil.k", "Max. Metal coverage MM5Filler ratio for any 800 x 800 µm² chip area [%] = 75.0")
-
- -> do
- TM1_density.ext_with_density(0.0 .. 0.25, 'll')
- end.().output("TM1.c", "Min. global TopMetal1 density [%] = 25.00")
-
- -> do
- TM1_density.ext_with_density(0.7 .. 1.0, 'll')
- end.().output("TM1.d", "Max. global TopMetal1 density [%] = 70.00")
-
- -> do
- TM2_density.ext_with_density(0.0 .. 0.25, 'll')
- end.().output("TM2.c", "Min. global TopMetal1 density [%] = 25.0")
-
- -> do
- TM2_density.ext_with_density(0.7 .. 1.0, 'll')
- end.().output("TM2.c1", "Max. global TopMetal1 density [%] = 70.0")
-
- -> do
- LBE.ext_with_density(0.2 .. 1.0, 'll')
- end.().output("LBE.i", "Max. global LBE density [%] = 20.0 %")
-
-end
-
-if conditional_enabled[:sanityRules]
-
- -> do
- Activ_pin.ext_not(Activ)
- end.().output("forbidden.a", "Activ enclosure of Activ_pin = 0.0")
-
- -> do
- GatPoly_pin.ext_not(GatPoly)
- end.().output("forbidden.b", "GatPoly enclosure of GatPoly_pin = 0.0")
-
- -> do
- NWell_pin.ext_not(NWell)
- end.().output("forbidden.c", "NWell enclosure of NWell_pin = 0.0")
-
- -> do
- Metal1_pin.ext_not(Metal1)
- end.().output("forbidden.d", "Metal1 enclosure of Metal1_pin = 0.0")
-
- -> do
- Metal2_pin.ext_not(Metal2)
- end.().output("forbidden.f.M1", "Metal2 enclosure of Metal2_pin = 0.0")
-
- -> do
- Metal3_pin.ext_not(Metal3)
- end.().output("forbidden.f.M2", "Metal3 enclosure of Metal3_pin = 0.0")
-
- -> do
- Metal4_pin.ext_not(Metal4)
- end.().output("forbidden.f.M3", "Metal4 enclosure of Metal4_pin = 0.0")
-
- -> do
- Metal5_pin.ext_not(Metal5)
- end.().output("forbidden.f.M4", "Metal5 enclosure of Metal5_pin = 0.0")
-
- -> do
- TopMetal1_pin.ext_not(TopMetal1)
- end.().output("forbidden.f.M5", "TopMetal1 enclosure of TopMetal1_pin = 0.0")
-
- -> do
- TopMetal2_pin.ext_not(TopMetal2)
- end.().output("forbidden.f.MT1", "TopMetal2 enclosure of TopMetal2_pin = 0.0")
-
- -> do
- BiWind_org.dup
- end.().output("forbidden.Biwind", "Biwind forbidden layer in 0.13um designs")
-
- -> do
- PEmWind_org.dup
- end.().output("forbidden.PEmWind", "PEmWind forbidden layer in 0.13um designs")
-
- -> do
- BasPoly_org.dup
- end.().output("forbidden.BasPoly", "BasPoly forbidden layer in 0.13um designs")
-
- -> do
- DeepCo_org.dup
- end.().output("forbidden.DeepCo", "DeepCo forbidden layer in 0.13um designs")
-
- -> do
- PEmPoly_org.dup
- end.().output("forbidden.PEmPoly", "PEmPoly forbidden layer in 0.13um designs")
-
- -> do
- EmPoly_org.dup
- end.().output("forbidden.EmPoly", "EmPoly forbidden layer in 0.13um designs")
-
- -> do
- LDMOS_org.dup
- end.().output("forbidden.LDMOS", "LDMOS forbidden layer in 0.13um designs")
-
- -> do
- PBiWind_org.dup
- end.().output("forbidden.PBiWind", "PBiWind forbidden layer in 0.13um designs")
-
- -> do
- Flash_org.dup
- end.().output("forbidden.Flash", "Flash forbidden layer in 0.13um designs")
-
- -> do
- ColWind_org.dup
- end.().output("forbidden.ColWind", "ColWind forbidden layer in 0.13um designs")
-
-end
-
--> do
- LBE.width(100000)
-end.().output("LBE.a", "LBE.a: Min. width of LBE = 100.0")
-
--> do
- LBE.drc(width > 1500000)
-end.().output("LBE.b", "LBE.b: Max. width of LBE = 1500.0")
-
--> do
- LBE.ext_area([[">", 250000.0*1000.0*1000.0]])
-end.().output("LBE.b1", "LBE.b1: Max allowed LBE area = 250000.0")
-
--> do
- LBE.space(100000)
-end.().output("LBE.c", "LBE.c: Min. LBE space or notch = 100.0")
-
--> (;lbe_in_seal) do
- lbe_in_seal = LBE.merged(true, 0).inside(EdgeSeal.holes.merge)
- lbe_in_seal.separation(EdgeSeal, 150000)
-end.().output("LBE.d", "LBE.d: Min. space of LBE to inner edge of Edge Seal = 150.0")
-
--> do
- LBE.ext_ring.dup
-end.().output("LBE.h", "LBE.h: No LBE ring allowed")
-
-
diff --git a/ihp-sg13g2/libs.tech/klayout/tech/drc/sg13g2_maximal.lydrc b/ihp-sg13g2/libs.tech/klayout/tech/drc/sg13g2_maximal.lydrc
index 40a9590e..7bcd4dc8 100644
--- a/ihp-sg13g2/libs.tech/klayout/tech/drc/sg13g2_maximal.lydrc
+++ b/ihp-sg13g2/libs.tech/klayout/tech/drc/sg13g2_maximal.lydrc
@@ -30,14 +30,14 @@
dsl
drc-dsl-xml
# Supported variables that can be set using "-rd <name>=<value>" on the command line:
-# logfile - path to the log file [default: no log file]
-# gdsfile - path to the GDS layout to check (required in batch mode)
-# cell - name of the cell to check (required in batch mode)
-# outfile - path to the report database [default: sg13g2_maximal.lyrdb in the script directory]
+# log_file - path to the log file [default: no log file]
+# in_gds - path to the GDS layout to check (required in batch mode)
+# cell - name of the cell to check
+# report_file - path to the report database [default: sg13g2_maximal.lyrdb in the script directory]
# to set logfile: -rd logfile="sg13g2_maximal.log"
-if $logfile
- log_file($logfile)
+if $log_file
+ log_file($log_file)
end
application = RBA::Application.instance
@@ -49,30 +49,27 @@ if main_window
main_window.load_layout(layout_path, 1)
curr_layout_view = main_window.current_view()
end
+ active_layout = RBA::CellView::active.layout
active_cellname = RBA::CellView::active.cell_name
+ source(active_layout, active_cellname)
else
log("DRC: batch mode")
+ # to set input layout: -rd in_gds="path to GDS file"
# to set cell: -rd cell="topcell"
if $cell
active_cellname = $cell
log("Active cell: " + active_cellname)
+ source($in_gds, active_cellname)
+ active_layout = source.layout
else
- raise("'cell' script variable must be defined on command line")
+ source($in_gds)
+ active_layout = source.layout
+ active_cellname = source.cell_name
end
end
-active_layout = RBA::CellView::active.layout
-
-unless active_layout or $gdsfile
- raise("layout file must be defined on command line or via 'gdsfile' script variable")
-end
-
-# to set input layout: -rd gdsfile="path to GDS file"
-if $gdsfile
- source($gdsfile, active_cellname)
- active_layout = source.layout
-else
- source(active_layout, active_cellname)
+unless active_layout or $in_gds
+ raise("layout file must be defined on command line or via 'in_gds' script variable")
end
if active_layout.dbu != 0.001
@@ -80,14 +77,28 @@ if active_layout.dbu != 0.001
end
report_file = __dir__ + "/sg13g2_maximal.lyrdb"
-# to set report file: -rd outfile="sg13g2_maximal.lyrdb"
-if $outfile
- report_file = File.expand_path($outfile)
+# to set report file: -rd report_file="sg13g2_maximal.lyrdb"
+if $report_file
+ report_file = File.expand_path($report_file)
end
+
report("design rules: sg13g2_maximal | layout cell: " + active_cellname, report_file)
deep
+$drc_error_count = 0
+
+class DRC::DRCLayer
+ unless method_defined?(:original_output)
+ alias_method :original_output, :output
+ end
+
+ def output(*args)
+ $drc_error_count += self.count()
+ original_output(*args)
+ end
+end
+
# Initial definitions of control flow variables
# Strings from the command line have to be converted
if defined? $offGrid
@@ -128,31 +139,149 @@ class DRC::DRCLayer
return output_layer
end
- def ext_area(constraint)
- output_layer = self.dup
+ def ext_with_angle(constraint)
+ if self.polygons?
+ self_min_coherence_state = self.data.min_coherence?
+ self.data.min_coherence = true
+ self_edges = self.edges
+ self.data.min_coherence = self_min_coherence_state
+ else
+ self_edges = self
+ end
+ lower_bound = nil
+ upper_bound = nil
+ output_layer = nil
+ constraint.each do |expression|
+ relation = expression[0]
+ value = expression[1]
+ if relation == ">"
+ lower_bound = value + 1e-6
+ elsif relation == "<"
+ upper_bound = value
+ elsif relation == "=="
+ output_layer = self_edges.with_angle(value)
+ if value > 0 and value < 90
+ output_layer += self_edges.with_angle(-value)
+ end
+ elsif relation == "!="
+ output_layer = self_edges.without_angle(value)
+ if value > 0 and value < 90
+ output_layer += self_edges.without_angle(-value)
+ end
+ elsif relation == ">="
+ lower_bound = value
+ elsif relation == "<="
+ upper_bound = value + 1e-6
+ else
+ raise "invalid expression"
+ end
+ end
+ if lower_bound or upper_bound
+ output_layer = self_edges.with_angle(lower_bound, upper_bound)
+ output_layer += self_edges.with_angle(-upper_bound, -lower_bound)
+ end
+ return output_layer
+ end
+
+ def ext_with_area(constraint)
+ lower_bound = nil
+ upper_bound = nil
+ output_layer = nil
+ self_min_coherence_state = self.data.min_coherence?
+ self.data.min_coherence = true
constraint.each do |expression|
- output_layer.data.min_coherence = true
relation = expression[0]
value = expression[1]
if relation == ">"
- output_layer = output_layer.with_area((value + @engine.dbu), nil)
+ lower_bound = value + 1e-6
elsif relation == "<"
- output_layer = output_layer.with_area(nil, value)
+ upper_bound = value
elsif relation == "=="
- output_layer = output_layer.with_area(value)
+ output_layer = self.with_area(value)
elsif relation == "!="
- output_layer = output_layer.without_area(value)
+ output_layer = self.without_area(value)
elsif relation == ">="
- output_layer = output_layer.with_area(value, nil)
+ lower_bound = value
elsif relation == "<="
- output_layer = output_layer.with_area(nil, (value + @engine.dbu))
+ upper_bound = value + 1e-6
else
raise "invalid expression"
end
end
+ if lower_bound or upper_bound
+ output_layer = self.with_area(lower_bound, upper_bound)
+ end
+ self.data.min_coherence = self_min_coherence_state
return output_layer
end
+ def ext_coincident_part(other, outside: false, inverted: false)
+ if outside and !inverted and self.polygons? and other.polygons?
+ return self.separation(other, 1).first_edges
+ end
+ if self.polygons?
+ self_min_coherence_state = self.data.min_coherence?
+ self.data.min_coherence = true
+ self_edges = self.edges
+ self.data.min_coherence = self_min_coherence_state
+ else
+ self_edges = self
+ end
+ if other.polygons?
+ other_min_coherence_state = other.data.min_coherence?
+ other.data.min_coherence = true
+ other_edges = other.edges
+ other.data.min_coherence = other_min_coherence_state
+ else
+ other_edges = other
+ end
+ if outside
+ if inverted
+ return self_edges.not(self_edges.separation(other_edges, 1).first_edges)
+ else
+ return self_edges.separation(other_edges, 1).first_edges
+ end
+ else
+ if inverted
+ return self_edges.not(other_edges)
+ else
+ return self_edges.and(other_edges)
+ end
+ end
+ end
+
+ def ext_coincident_edges(other, outside: false, consider_touch_points: false)
+ if self.polygons?
+ self_min_coherence_state = self.data.min_coherence?
+ self.data.min_coherence = true
+ self_edges = self.edges
+ self.data.min_coherence = self_min_coherence_state
+ else
+ self_edges = self
+ end
+ if other.polygons?
+ other_min_coherence_state = other.data.min_coherence?
+ other.data.min_coherence = true
+ other_edges = other.edges
+ other.data.min_coherence = other_min_coherence_state
+ else
+ other_edges = other
+ end
+ if outside
+ if consider_touch_points
+ return self_edges.not_outside(self_edges.separation(other_edges, 1, @engine.whole_edges).first_edges)
+ else
+ return self_edges.not_outside(self_edges.separation(other_edges, 1, @engine.whole_edges, @engine.without_touching_corners).first_edges)
+ end
+ else
+ if consider_touch_points
+ raise "not implemented"
+ else
+ return met1_edges.not_outside(self_edges & other_edges)
+ end
+ end
+ end
+
def ext_constraint_satisfied(value, constraint)
output_bool = true
constraint.each do |expression|
@@ -175,6 +304,21 @@ class DRC::DRCLayer
return output_bool
end
+ def ext_overlapping(other, constraint = [])
+ self_min_coherence_state = self.data.min_coherence?
+ other_min_coherence_state = other.data.min_coherence?
+ self.data.min_coherence = true
+ other.data.min_coherence = true
+ overlap_filter = @engine.overlapping(other.not_inside(self))
+ constraint.each do |expression|
+ overlap_filter = overlap_filter.public_send(expression[0], expression[1])
+ end
+ output_layer = self.drc(@engine.if_all(overlap_filter, ! @engine.inside(other)))
+ self.data.min_coherence = self_min_coherence_state
+ other.data.min_coherence = other_min_coherence_state
+ return output_layer
+ end
+
def ext_covering(other)
self_min_coherence_state = self.data.min_coherence?
other_min_coherence_state = other.data.min_coherence?
@@ -191,7 +335,7 @@ class DRC::DRCLayer
other_min_coherence_state = other.data.min_coherence?
self.data.min_coherence = true
other.data.min_coherence = true
- output_layer = self.enclosed(other, value)
+ output_layer = self.enclosed(other, value, @engine.projection)
self.data.min_coherence = self_min_coherence_state
other.data.min_coherence = other_min_coherence_state
if polygon_output
@@ -201,6 +345,26 @@ class DRC::DRCLayer
end
end
+ def ext_extended(outside = 0, inside = 0)
+ if self.polygons?
+ self_min_coherence_state = self.data.min_coherence?
+ self.data.min_coherence = true
+ edge_layer = self.edges
+ self.data.min_coherence = self_min_coherence_state
+ else
+ edge_layer = self
+ end
+ return edge_layer.extended(:out => outside, :in => inside).merge(true, 0)
+ end
+
+ def ext_extents
+ self_min_coherence_state = self.data.min_coherence?
+ self.data.min_coherence = true
+ output_layer = self.extents.merge(true, 0)
+ self.data.min_coherence = self_min_coherence_state
+ return output_layer
+ end
+
def ext_fast_separation(other, value, polygon_output: false)
self_min_coherence_state = self.data.min_coherence?
other_min_coherence_state = other.data.min_coherence?
@@ -216,7 +380,23 @@ class DRC::DRCLayer
end
end
- def ext_interacting(other, constraint=nil)
+ def ext_inside_part(other, inverted: false)
+ if self.polygons?
+ self_min_coherence_state = self.data.min_coherence?
+ self.data.min_coherence = true
+ edge_layer = self.edges
+ self.data.min_coherence = self_min_coherence_state
+ else
+ edge_layer = self
+ end
+ if inverted
+ return edge_layer.outside_part(other.merged(true, 0))
+ else
+ return edge_layer.inside_part(other.merged(true, 0))
+ end
+ end
+
+ def ext_interacting(other, constraint=nil, inverted: false)
self_min_coherence_state = self.data.min_coherence?
other_min_coherence_state = other.data.min_coherence?
self.data.min_coherence = true
@@ -224,20 +404,70 @@ class DRC::DRCLayer
overlap_filter = @engine.secondary(other).overlapping(@engine.primary)
if not constraint
touch_filter = @engine.secondary(other).outside(@engine.primary).edges & @engine.primary
- output_layer = self.drc(@engine.if_any(overlap_filter, touch_filter))
+ if inverted
+ output_layer = self.drc(@engine.if_none(overlap_filter, touch_filter))
+ else
+ output_layer = self.drc(@engine.if_any(overlap_filter, touch_filter))
+ end
else
touch_filter = (@engine.secondary(other).outside(@engine.primary).edges & @engine.primary).polygons(0.1.um).merged
filter = (overlap_filter + touch_filter).count
constraint.each do |expression|
filter = filter.public_send(expression[0], expression[1])
end
- output_layer = self.drc(@engine.if_any(filter))
+ if inverted
+ output_layer = self.drc(@engine.if_none(filter))
+ else
+ output_layer = self.drc(@engine.if_any(filter))
+ end
end
self.data.min_coherence = self_min_coherence_state
other.data.min_coherence = other_min_coherence_state
return output_layer
end
+ def ext_fast_overlap(other, value, polygon_output: false)
+ if self.polygons?
+ self_min_coherence_state = self.data.min_coherence?
+ self.data.min_coherence = true
+ end
+ if other.polygons?
+ other_min_coherence_state = other.data.min_coherence?
+ other.data.min_coherence = true
+ end
+ if self.polygons? and other.polygons?
+ output_layer = self.overlap(other, value)
+ else
+ if self.polygons?
+ self_edges = self.edges
+ else
+ self_edges = self
+ end
+ if other.polygons?
+ other_edges = other.edges
+ else
+ other_edges = other
+ end
+ output_layer = self_edges.overlap(other_edges, value)
+ end
+ if self.polygons?
+ self.data.min_coherence = self_min_coherence_state
+ end
+ if other.polygons?
+ other.data.min_coherence = other_min_coherence_state
+ end
+ if polygon_output
+ return output_layer.polygons.merge(true, 0)
+ else
+ return output_layer
+ end
+ end
+
+ def ext_with_coincident_edges(other)
+ coincident_edges = self.edges & other
+ return self.interacting(coincident_edges)
+ end
+
def ext_with_length(constraint)
if self.polygons?
self_min_coherence_state = self.data.min_coherence?
@@ -278,12 +508,18 @@ class DRC::DRCLayer
return output_layer
end
- def ext_or(other)
+ def ext_or(other, *further_layers)
self_min_coherence_state = self.data.min_coherence?
other_min_coherence_state = other.data.min_coherence?
self.data.min_coherence = true
other.data.min_coherence = true
output_layer = self.join(other)
+ further_layers.each do |further_layer|
+ further_layer_min_coherence_state = further_layer.data.min_coherence?
+ further_layer.data.min_coherence = true
+ output_layer = output_layer.join(further_layer)
+ further_layer.data.min_coherence = further_layer_min_coherence_state
+ end
self.data.min_coherence = self_min_coherence_state
other.data.min_coherence = other_min_coherence_state
return output_layer
@@ -347,6 +583,19 @@ class DRC::DRCLayer
end
end
+ def ext_enlarge_inside(other, distance, step)
+ enlarged_layer = self.dup
+ num_steps = (distance / step + 0.5).to_i
+ for i in 1..num_steps
+ enlarged_layer = enlarged_layer.sized(step, @engine.acute_limit) & other
+ end
+ rest = distance - num_steps * step
+ if rest > 1.dbu
+ enlarged_layer = enlarged_layer.sized(rest, @engine.acute_limit) & other
+ end
+ return enlarged_layer
+ end
+
def ext_touching(other, constraint = [[">", 0]])
self_min_coherence_state = self.data.min_coherence?
other_min_coherence_state = other.data.min_coherence?
@@ -366,14 +615,6 @@ class DRC::DRCLayer
return output_layer
end
- def ext_ring
- holes = self.holes
- hulls = self.hulls
- covering = hulls.covering(holes)
- result = covering.and(self)
- return result
- end
-
def ext_interacting_with_text(text_layer, text)
if text_layer.is_a? Integer
text_layer = @engine.labels(text_layer)
@@ -415,20 +656,26 @@ class DRC::DRCLayer
if origin == 'll'
origin_x = bbox.left
origin_y = bbox.bottom
+ if tile_size and tile_step and (tile_size.get[0] != tile_step.get[0] or tile_size.get[1] != tile_step.get[1])
+ origin_x = bbox.left + tile_step.get[0]/2
+ origin_y = bbox.bottom + tile_step.get[1]/2
+ end
tile_origin = DRC::DRCTileOrigin::new(origin_x, origin_y)
arguments.push(tile_origin)
elsif origin != 'cc'
raise "Unknown origin: 'cc' or 'll' expected"
end
if tile_size
- return merged_layer.with_density(*arguments)
+ boundary_layer = DRC::DRCLayer::new(@engine, RBA::Region::new(bbox.to_itype(@engine.dbu)))
+ tile_boundary = DRC::DRCTileBoundary::new(boundary_layer)
+ return merged_layer.with_density(*arguments, tile_boundary, @engine.padding_ignore)
else
tile_size = DRC::DRCTileSize::new(bbox.width, bbox.height)
tile_count = DRC::DRCTileCount::new(1,2)
enlarged_bbox = bbox.enlarged(1.1).to_itype(@engine.dbu)
boundary_layer = DRC::DRCLayer::new(@engine, RBA::Region::new(enlarged_bbox))
tile_boundary = DRC::DRCTileBoundary::new(boundary_layer)
- result = merged_layer.with_density(*arguments, tile_size, tile_count, tile_boundary)
+ result = merged_layer.with_density(*arguments, tile_size, tile_count, tile_boundary, @engine.padding_ignore)
return result.raw.overlapping(DRC::DRCLayer::new(@engine, RBA::Region::new(bbox.to_itype(@engine.dbu))))
end
end
@@ -536,37 +783,47 @@ if $sanityRules
Flash = source.polygons("71/0")
end
-Activ_Act_a = Activ.ext_fast_width(150)
-Activ_Act_d = Activ.ext_area([["<", 0.122]])
+Activ_Act_a = Activ.ext_fast_width(0.15.um)
+Activ_Act_d = Activ.ext_with_area([["<", 0.122.um2]])
+nmosi_relevant_activ = Activ.ext_or(Activ_mask)
Act_density = Activ.ext_or(Activ_filler)
GP_or_Act = Activ.ext_or(GatPoly)
Gate = Activ.ext_and(GatPoly)
-GatPoly_Gat_e = GatPoly.ext_area([["<", 0.09]])
+Act_connect = Activ.ext_not(GatPoly)
+GatPoly_Gat_e = GatPoly.ext_with_area([["<", 0.09.um2]])
Gat_density = GatPoly.ext_or(GatPoly_filler)
-Cont_SQ = Cont.ext_rectangles(true, false, [["==", 160]], [["==", 160]], nil)
-ContBar = Cont.ext_area([[">", 0.16*0.16]])
-selring_pass = Passiv.ext_ring
-Passiv_Pad_a1 = Passiv.drc((width(projection) > 150000).polygons)
-pSD_pSD_a = pSD.ext_fast_width(310)
-pSD_pSD_k = pSD.ext_area([["<", 0.25]])
+Cont_SQ = Cont.ext_rectangles(true, false, [["==", 0.16.um]], [["==", 0.16.um]], nil)
+ContBar = Cont.ext_with_area([[">", (0.16*0.16).um2]])
+Activ_and_nSD_block = Activ.ext_and(nSD_block)
+selring_pass = Passiv.with_holes
+Passiv_Pad_a1 = Passiv.drc((width(projection) > 150.0.um).polygons)
+X2 = nSD_block.ext_or(pSD)
+pSD_not_nSD = nSD.ext_not(pSD)
+subst_tie_hole = (pSD.holes - pSD.with_holes).without_holes
+pSD_pSD_a = pSD.ext_fast_width(0.31.um)
+pSD_pSD_k = pSD.ext_with_area([["<", 0.25.um2]])
Act_Nsram = Activ.ext_not(SRAM)
pSD_Nsram = pSD.ext_not(SRAM)
GP_Nsram = GatPoly.ext_not(SRAM)
Cont_Nsram = Cont.ext_not(SRAM)
+V1_Nsram = Via1.ext_not(SRAM)
M1_Nsram = Metal1.ext_not(SRAM)
M2_Nsram = Metal2.ext_not(SRAM)
M2_SRAM = Metal2.ext_and(SRAM)
+V2_Nsram = Via2.ext_not(SRAM)
M3_Nsram = Metal3.ext_not(SRAM)
M3_SRAM = Metal3.ext_and(SRAM)
-lNw_a1 = NWell.ext_and(RES)
-NWell_NW_a = NWell.ext_fast_width(620)
+Act_NWell = Activ.ext_and(NWell)
+NWell_NW_a = NWell.ext_fast_width(0.62.um)
NWell_nBuLay = NWell.ext_and(nBuLay)
-nBuLay_block_NBLB_a = nBuLay_block.ext_fast_width(1500)
-MIM_Mim_a = MIM.ext_fast_width(1140, polygon_output: true)
-MIM_Mim_f = MIM.ext_area([["<", 1.3]])
-sealring = EdgeSeal.ext_ring
+isoPWell = nBuLay.ext_not(NWell)
+nBuLay_block_NBLB_a = nBuLay_block.ext_fast_width(1.5.um)
+nBuLay_nBuLay_block_enc_tmp = nBuLay_block.ext_fast_enclosed(nBuLay, 1.0.um, polygon_output: true)
+nBuLay_nBuLay_block_enc_tmp2 = nBuLay_block.ext_overlapping(nBuLay)
+MIM_Mim_a = MIM.ext_fast_width(1.14.um, polygon_output: true)
+MIM_Mim_f = MIM.ext_with_area([["<", 1.3.um2]])
+sealring = EdgeSeal.with_holes
Act_EdgeSeal = Activ.ext_and(EdgeSeal)
-Activ_edgA1_in = Activ.ext_and(EdgeSeal)
Act_Not_EdgeSeal = Activ.ext_not(EdgeSeal)
pSD_edgA1_in = pSD.ext_and(EdgeSeal)
Metal1_edgA1_in = Metal1.ext_and(EdgeSeal)
@@ -574,315 +831,627 @@ Metal2_edgA1_in = Metal2.ext_and(EdgeSeal)
Metal3_edgA1_in = Metal3.ext_and(EdgeSeal)
Cont_edgC1_in = Cont.ext_and(EdgeSeal)
Via1_edgC1_in = Via1.ext_and(EdgeSeal)
+Via1_edgC1_out = Via1.ext_not(EdgeSeal)
Via2_edgC1_in = Via2.ext_and(EdgeSeal)
+Via2_edgC1_out = Via2.ext_not(EdgeSeal)
+Cont_outside_EdgeSeal = Cont.outside(EdgeSeal)
+Metal1_outside_EdgeSeal = Metal1.outside(EdgeSeal)
+Metal2_outside_EdgeSeal = Metal2.outside(EdgeSeal)
+Metal3_outside_EdgeSeal = Metal3.outside(EdgeSeal)
Passiv_dfpad = Passiv.ext_and(dfpad)
-pad = dfpad.merged(true, 0).not_outside(Passiv)
+pad = dfpad.not_outside(Passiv)
cupPad_candidat = Passiv.ext_and(dfpad_pillar)
-ThickGateOx_TGO_e = ThickGateOx.ext_fast_space(860, polygon_output: true)
-ThickGateOx_TGO_f = ThickGateOx.ext_fast_width(860, polygon_output: true)
-PWell_block_PWB_a = PWell_block.ext_fast_width(620)
-PWell_block_PWB_b = PWell_block.ext_fast_space(620, polygon_output: true)
+dfpad_all = dfpad.ext_or(dfpad_pillar, dfpad_sbump)
+ThickGateOx_TGO_e = ThickGateOx.ext_fast_space(0.86.um, polygon_output: true)
+ThickGateOx_TGO_f = ThickGateOx.ext_fast_width(0.86.um, polygon_output: true)
+X1 = NWell.ext_or(PWell_block)
+PWell_block_PWB_a = PWell_block.ext_fast_width(0.62.um)
+PWell_block_PWB_b = PWell_block.ext_fast_space(0.62.um, polygon_output: true)
+V3_Nsram = Via3.ext_not(SRAM)
Via3_edgC1_in = Via3.ext_and(EdgeSeal)
+Via3_edgC1_out = Via3.ext_not(EdgeSeal)
M4_Nsram = Metal4.ext_not(SRAM)
M4_SRAM = Metal4.ext_and(SRAM)
Metal4_edgA1_in = Metal4.ext_and(EdgeSeal)
+Metal4_outside_EdgeSeal = Metal4.outside(EdgeSeal)
+V4_Nsram = Via4.ext_not(SRAM)
Via4_edgC1_in = Via4.ext_and(EdgeSeal)
+Via4_edgC1_out = Via4.ext_not(EdgeSeal)
M5_Nsram = Metal5.ext_not(SRAM)
M5_SRAM = Metal5.ext_and(SRAM)
+belowTopMetaln_dfpad = Metal5.ext_and(dfpad)
Metal5_edgA1_in = Metal5.ext_and(EdgeSeal)
+Metal5_outside_EdgeSeal = Metal5.outside(EdgeSeal)
+Metal5_slit_MIM_Slt_g_M5_sep_tmp1 = Metal5_slit.ext_fast_separation(MIM, 0.6.um, polygon_output: true)
+Metal5_slit_MIM_Slt_g_M5_sep_tmp2 = MIM.ext_coincident_edges(Metal5_slit, outside: true, consider_touch_points: true)
+Metal5_slit_MIM_Slt_g_M5_sep_tmp5 = Metal5_slit.ext_and(MIM)
scr1 = Recog_esd.ext_interacting_with_text(TEXT_0, "scr1")
+nmoscl_2 = Recog_esd.ext_interacting_with_text(TEXT_0, "nmoscl_2")
+nmoscl_4 = Recog_esd.ext_interacting_with_text(TEXT_0, "nmoscl_4")
+Rhigh_recognition_0 = EXTBlock.ext_and(pSD)
TopVia1_edgC1_in = TopVia1.ext_and(EdgeSeal)
+TopVia1_edgC1_out = TopVia1.ext_not(EdgeSeal)
TopMetal1_edgA1_in = TopMetal1.ext_and(EdgeSeal)
+TopMetal1_slit_MIM_Slt_g_TM1_sep_tmp1 = TopMetal1_slit.ext_fast_separation(MIM, 0.6.um, polygon_output: true)
+TopMetal1_slit_MIM_Slt_g_TM1_sep_tmp2 = MIM.ext_coincident_edges(TopMetal1_slit, outside: true, consider_touch_points: true)
+TopMetal1_slit_MIM_Slt_g_TM1_sep_tmp5 = TopMetal1_slit.ext_and(MIM)
GatPoly_res = GatPoly.ext_or(PolyRes)
+TopVia1_or_Vmim = TopVia1.ext_or(Vmim)
TopVia2_edgC1_in = TopVia2.ext_and(EdgeSeal)
+TopVia2_edgC1_out = TopVia2.ext_not(EdgeSeal)
TopMetal2_edgA1_in = TopMetal2.ext_and(EdgeSeal)
+holes_TopMetal2 = TopMetal2.holes.merge
+tsv_tmp2 = (DeepVia.holes - DeepVia.with_holes).without_holes.outside(DeepVia)
+bad_tsv = DeepVia.without_holes
M1_density = Metal1.ext_or(Metal1_filler).ext_not(Metal1_slit)
M2_density = Metal2.ext_or(Metal2_filler).ext_not(Metal2_slit)
-DigiBnd_ring = DigiBnd.merged(true, 0).size(0.01, acute_limit).merge(true, 0).ext_not(DigiBnd)
+DigiBnd_ring = DigiBnd.sized(0.01.um, acute_limit).ext_not(DigiBnd)
emi2Pin = Metal2_pin.ext_and(TRANS).ext_interacting_with_text(TEXT_0, "E")
M3_density = Metal3.ext_or(Metal3_filler).ext_not(Metal3_slit)
-nBuLayGen_sized = NWell.merged(true, 0).size(-1+1.to_f/2, acute_limit).merge(true, 0).merged(true, 0).size(1.to_f/2, acute_limit).merge(true, 0)
-Iso_PWell_Act = Activ.ext_and(nBuLay).ext_not(NWell.ext_or(PWell_block))
-PWellBlock_relatedNWell_0 = NWell.merged(true, 0).not_inside(PWell_block).ext_interacting(PWell_block)
+nBuLayGen_sized = NWell.sized((-1+1.to_f/2).um, acute_limit).sized((1.to_f/2).um, acute_limit)
+Act_out_ThickGateOx = Activ.ext_not(Activ.ext_interacting(ThickGateOx))
+PWellBlock_relatedNWell_0 = NWell.not_inside(PWell_block).ext_interacting(PWell_block)
M4_density = Metal4.ext_or(Metal4_filler).ext_not(Metal4_slit)
M5_density = Metal5.ext_or(Metal5_filler).ext_not(Metal5_slit)
SalBlock_not_nSDBlock_not_esd = SalBlock.ext_not(Recog_esd.ext_or(nSD_block))
TM1_density = TopMetal1.ext_or(TopMetal1_filler).ext_not(TopMetal1_slit)
TM2_density = TopMetal2.ext_or(TopMetal2_filler).ext_not(TopMetal2_slit)
-GP_mosHV = Gate.merged(true, 0).not_outside(ThickGateOx)
+GP_mosHV = Gate.not_outside(ThickGateOx)
+GP_out_ThickGateOx = Gate.outside(ThickGateOx)
+size_Cont = Cont.ext_enlarge_inside(Act_connect, 6.0.um, 0.21.um)
Cont_Act = Cont_SQ.ext_and(Activ)
Cont_not_M1 = Cont_SQ.ext_not(Metal1)
Cont_Act_GP = Cont_SQ.ext_and(Gate)
-CntB_a1_error = ContBar.ext_area([["<", 0.16*0.34]])
+CntB_a1_error = ContBar.ext_with_area([["<", (0.16*0.34).um2]])
ContBar_GP = ContBar.ext_and(GatPoly)
ContBar_Act = ContBar.ext_and(Activ)
ContBar_not_M1 = ContBar.ext_not(Metal1)
ContBar_Act_GP = ContBar.ext_and(Gate)
-nSD_drv = nSD.ext_or(Activ.ext_not(nSD_block.ext_or(pSD)))
+ContBar_outside_TRANS = ContBar.outside(TRANS)
+dschottky_1 = Activ_and_nSD_block.ext_and(nBuLay)
+dpin_0 = BasPoly.ext_and(Activ).ext_and(BiWind).ext_and(nSD_block)
+nSD_not_pSD = pSD_not_nSD.dup
+subst_tie_hole_w_npn = subst_tie_hole.ext_interacting_with_text(TEXT_0, "npn*")
+pSDL_enc_area = subst_tie_hole.ext_not(pSD)
Act_SRAM = Activ.ext_not(Act_Nsram)
pSD_SRAM = pSD.ext_not(pSD_Nsram)
+pSDHV_Nsram = pSD_Nsram.inside(ThickGateOx)
GP_SRAM = GatPoly.ext_not(GP_Nsram)
-GP_Nsram_Gat_a = GP_Nsram.ext_fast_width(130, polygon_output: true)
-GP_Nsram_Gat_b = GP_Nsram.ext_fast_space(180, polygon_output: true)
+GP_Nsram_Gat_a = GP_Nsram.ext_fast_width(0.13.um, polygon_output: true)
+GP_Nsram_Gat_b = GP_Nsram.ext_fast_space(0.18.um, polygon_output: true)
+Cont_SRAM = Cont.ext_not(Cont_Nsram)
+V1_SRAM = Via1.ext_not(V1_Nsram)
+V1_Nsram_outside_EdgeSeal = V1_Nsram.outside(EdgeSeal)
M1_SRAM = Metal1.ext_not(M1_Nsram)
npnMPA_0 = nBuLay.ext_and(Activ.ext_and(SalBlock.ext_and(nSD_block)))
-lNw_a1_NW_a1 = lNw_a1.ext_fast_width(1800)
+V2_SRAM = Via2.ext_not(V2_Nsram)
+V2_Nsram_outside_EdgeSeal = V2_Nsram.outside(EdgeSeal)
+nBuLay_nBuLay_block_enc_tmp3 = nBuLay_nBuLay_block_enc_tmp + nBuLay_nBuLay_block_enc_tmp2
Act_EdgeSeal_not_HRACT = Act_EdgeSeal.ext_not(Recog)
-Cont_not_Act_GP = Cont_SQ.ext_not(GP_or_Act).merged(true, 0).outside(TRANS)
-ContBar_not_Act_GP = ContBar.ext_not(GP_or_Act).merged(true, 0).outside(TRANS)
+Activ_edgA1_in = Act_EdgeSeal.dup
+Metal1_slit_not_pad = Metal1_slit.ext_not(pad)
+Metal2_slit_not_pad = Metal2_slit.ext_not(pad)
+Metal3_slit_not_pad = Metal3_slit.ext_not(pad)
+Metal4_slit_not_pad = Metal4_slit.ext_not(pad)
+Metal5_slit_not_pad = Metal5_slit.ext_not(pad)
+TopMetal1_slit_not_pad = TopMetal1_slit.ext_not(pad)
+TopMetal2_slit_not_pad = TopMetal2_slit.ext_not(pad)
+Recog_or_dfpad_all = Recog.ext_or(dfpad_all)
+Recog_or_MIM_or_dfpad_all = MIM.ext_or(Recog, dfpad_all)
+Iso_PWell_Act = Activ.ext_and(nBuLay).ext_not(X1)
+V3_SRAM = Via3.ext_not(V3_Nsram)
+V3_Nsram_outside_EdgeSeal = V3_Nsram.outside(EdgeSeal)
+V4_SRAM = Via4.ext_not(V4_Nsram)
+V4_Nsram_outside_EdgeSeal = V4_Nsram.outside(EdgeSeal)
+cmim_a = MIM.not_outside(Metal5).not_outside(TopMetal1).not_outside(Vmim)
+Metal5_slit_MIM_Slt_g_M5_sep_tmp3 = Metal5_slit.ext_with_coincident_edges(Metal5_slit_MIM_Slt_g_M5_sep_tmp2)
+nmoscl = nmoscl_2.ext_or(nmoscl_4)
+Rhigh_recognition_1 = Rhigh_recognition_0.ext_and(nSD)
+TopMetal1_slit_MIM_Slt_g_TM1_sep_tmp3 = TopMetal1_slit.ext_with_coincident_edges(TopMetal1_slit_MIM_Slt_g_TM1_sep_tmp2)
+temp_layer_1 = MIM.ext_covering(TopVia1_or_Vmim)
+temp_layer_6 = TopMetal2.ext_or(holes_TopMetal2)
+tsv = DeepVia.with_holes.ext_not(bad_tsv)
+Cont_not_Act_GP = Cont_SQ.ext_not(GP_or_Act).outside(TRANS)
+ContBar_not_Act_GP = ContBar.ext_not(GP_or_Act).outside(TRANS)
+nSD_drv = nSD.ext_or(Activ.ext_not(X2))
+X2_Extent = X2.ext_extents.sized(0.001.um, acute_limit)
transG2 = TRANS.ext_interacting_with_text(TEXT_0, "npn13G2").ext_covering(emi2Pin)
+transG2C = TRANS.ext_interacting_with_text(TEXT_0, "npn13G2C").ext_covering(emi2Pin)
transG2L = TRANS.ext_interacting_with_text(TEXT_0, "npn13G2L").ext_covering(emi2Pin)
transG2V = TRANS.ext_interacting_with_text(TEXT_0, "npn13G2V").ext_covering(emi2Pin)
nBuLayGen = nBuLayGen_sized.ext_not(nBuLay_block)
-nSDBlock_Iso_PWell_Act = nSD_block.merged(true, 0).not_outside(Iso_PWell_Act)
-SalBlock_Iso_PWell_Act = SalBlock.merged(true, 0).not_outside(Iso_PWell_Act)
-PWellBlock_relatedNWell = PWellBlock_relatedNWell_0.ext_or(NWell.merged(true, 0).inside(PWell_block))
-GP_mosHV_Gat_b1 = GP_mosHV.ext_fast_space(250, polygon_output: true)
-seal_passiv = selring_pass.ext_interacting(selring_pass.holes.merge.merged(true, 0).not_outside(sealring))
-NAct = Activ.ext_and(nSD_drv)
-pSD_nSD = pSD.ext_and(nSD_drv)
+ThickGateOx_Act_out_ThickGateOx_TGO_b_sep_tmp1 = ThickGateOx.ext_fast_separation(Act_out_ThickGateOx, 0.27.um, polygon_output: true)
+ThickGateOx_Act_out_ThickGateOx_TGO_b_sep_tmp2 = Act_out_ThickGateOx.ext_coincident_edges(ThickGateOx, outside: true, consider_touch_points: true)
+ThickGateOx_Act_out_ThickGateOx_TGO_b_sep_tmp5 = ThickGateOx.ext_and(Act_out_ThickGateOx)
+PWellBlock_relatedNWell = PWellBlock_relatedNWell_0.ext_or(NWell.inside(PWell_block))
+Rppd_0 = GatPoly_res.ext_and(pSD).ext_and(SalBlock_not_nSDBlock_not_esd)
+tsv_fill = DeepVia.ext_or(tsv_tmp2).ext_not(bad_tsv)
+GP_mosHV_Gat_b1 = GP_mosHV.ext_fast_space(0.25.um, polygon_output: true)
+ThickGateOx_GP_out_ThickGateOx_TGO_d_sep_tmp1 = ThickGateOx.ext_fast_separation(GP_out_ThickGateOx, 0.34.um, polygon_output: true)
+ThickGateOx_GP_out_ThickGateOx_TGO_d_sep_tmp2 = GP_out_ThickGateOx.ext_coincident_edges(ThickGateOx, outside: true, consider_touch_points: true)
+ThickGateOx_GP_out_ThickGateOx_TGO_d_sep_tmp5 = ThickGateOx.ext_and(GP_out_ThickGateOx)
+dschottky_2 = dschottky_1.sized(1.12.um, acute_limit)
+seal_passiv = selring_pass.ext_interacting(selring_pass.holes.merge.not_outside(sealring))
+dpin_1 = dpin_0.sized(1.12.um, acute_limit)
+pSD_not_nSD_or_nSD_not_pSD = nSD_not_pSD.ext_or(pSD_not_nSD)
+pSDL_enc_area_pSD_l = pSDL_enc_area.ext_with_area([["<", 0.25.um2]])
DigiBnd_hole = DigiBnd.ext_or(DigiBnd_ring.holes.merge)
-GP_SRAM_Gat_a_SRAM = GP_SRAM.ext_fast_width(130, polygon_output: true)
-GP_SRAM_Gat_b_SRAM = GP_SRAM.ext_fast_space(149, polygon_output: true)
+GP_SRAM_Gat_a_SRAM = GP_SRAM.ext_fast_width(0.13.um, polygon_output: true)
+GP_SRAM_Gat_b_SRAM = GP_SRAM.ext_fast_space(0.149.um, polygon_output: true)
+V1_SRAM_outside_EdgeSeal = V1_SRAM.outside(EdgeSeal)
+M1_SRAM_outside_EdgeSeal = M1_SRAM.outside(EdgeSeal)
npnMPA = npnMPA_0.ext_interacting_with_text(TEXT_0, "npnMPA")
-schottky_nbl_rec = nBuLay.ext_not(NWell).merged(true, 0).not_outside(SalBlock).merged(true, 0).not_outside(nSD_block).merged(true, 0).not_outside(Recog_diode).merged(true, 0).not_outside(ThickGateOx)
-emit_npn13G2 = EmWind.merged(true, 0).inside(transG2)
-emit_npn13G2L = EmWind.merged(true, 0).inside(transG2L)
-emit_npn13G2V = EmWind.merged(true, 0).inside(transG2V)
+V2_SRAM_outside_EdgeSeal = V2_SRAM.outside(EdgeSeal)
+nBuLay_nBuLay_block_enc_tmp6 = nBuLay_nBuLay_block_enc_tmp3.dup
+sltc_M1 = Metal1.ext_not(Recog_or_dfpad_all)
+sltc_M2 = Metal2.ext_not(Recog_or_dfpad_all)
+sltc_M3 = Metal3.ext_not(Recog_or_dfpad_all)
+sltc_M4 = Metal4.ext_not(Recog_or_dfpad_all)
+sltc_TM2 = TopMetal2.ext_not(Recog_or_dfpad_all)
+sltc_M5 = Metal5.ext_not(Recog_or_MIM_or_dfpad_all)
+sltc_TM1 = TopMetal1.ext_not(Recog_or_MIM_or_dfpad_all)
+nSDBlock_Iso_PWell_Act = nSD_block.not_outside(Iso_PWell_Act)
+SalBlock_Iso_PWell_Act = SalBlock.not_outside(Iso_PWell_Act)
+V3_SRAM_outside_EdgeSeal = V3_SRAM.outside(EdgeSeal)
+V4_SRAM_outside_EdgeSeal = V4_SRAM.outside(EdgeSeal)
+rfcmim_a = cmim_a.not_outside(PWell_block.ext_interacting_with_text(TEXT_0, "rfcmim"))
+Metal5_slit_MIM_Slt_g_M5_sep_tmp4 = Metal5_slit_MIM_Slt_g_M5_sep_tmp1 + Metal5_slit_MIM_Slt_g_M5_sep_tmp3
+Rhigh_recognition = Rhigh_recognition_1.ext_covering(GatPoly)
+TopMetal1_slit_MIM_Slt_g_TM1_sep_tmp4 = TopMetal1_slit_MIM_Slt_g_TM1_sep_tmp1 + TopMetal1_slit_MIM_Slt_g_TM1_sep_tmp3
+Rsil_all = GatPoly_res.ext_and(RES).ext_and(EXTBlock).ext_interacting(SalBlock, inverted: true)
+NAct = Activ.ext_and(nSD_drv)
+pSD_nSD = pSD.ext_and(nSD_drv)
+Y2 = X2_Extent.ext_not(X2)
+emit_npn13G2 = EmWind.inside(transG2)
+emit_npn13G2L = EmWind.inside(transG2L)
+trans_bip = transG2.ext_or(transG2C, transG2L, transG2V)
+emit_npn13G2V = EmWind.inside(transG2V)
nBuLayGen_nBuLay = nBuLay.ext_or(nBuLayGen)
+schottky_nbl_rec = isoPWell.not_outside(SalBlock).not_outside(nSD_block).not_outside(Recog_diode).not_outside(ThickGateOx)
+ThickGateOx_Act_out_ThickGateOx_TGO_b_sep_tmp3 = ThickGateOx.ext_with_coincident_edges(ThickGateOx_Act_out_ThickGateOx_TGO_b_sep_tmp2)
PWellBlock_unrelatedNWell = NWell.ext_not(PWellBlock_relatedNWell)
-NGate = Gate.merged(true, 0).not_outside(NAct)
+tsvOutRing = tsv_fill.ext_extents
+tsv_fill_TSV_G_d = tsv_fill.ext_fast_space(25.0.um, polygon_output: true)
+ThickGateOx_GP_out_ThickGateOx_TGO_d_sep_tmp3 = ThickGateOx.ext_with_coincident_edges(ThickGateOx_GP_out_ThickGateOx_TGO_d_sep_tmp2)
+dschottky_3 = dschottky_2.ext_and(PWell_block)
+dpin = dpin_1.ext_and(PWell_block)
+Rppd_all = Rppd_0.ext_interacting(Activ.ext_or(nSD_drv), inverted: true)
+nBuLay_nBuLay_block_enc = nBuLay_nBuLay_block_enc_tmp6.dup
+Metal5_slit_MIM_Slt_g_M5_sep_tmp6 = Metal5_slit_MIM_Slt_g_M5_sep_tmp4 + Metal5_slit_MIM_Slt_g_M5_sep_tmp5
+Rhigh_identical_nsd_psd_edge = pSD_not_nSD_or_nSD_not_pSD.ext_coincident_part(Rhigh_recognition, outside: true)
+TopMetal1_slit_MIM_Slt_g_TM1_sep_tmp6 = TopMetal1_slit_MIM_Slt_g_TM1_sep_tmp4 + TopMetal1_slit_MIM_Slt_g_TM1_sep_tmp5
+rsil_gatpoly = GatPoly_res.not_outside(Rsil_all)
+Rsil_all_not_interact_NWell = Rsil_all.ext_interacting(NWell, inverted: true)
+NGate = Gate.not_outside(NAct)
PAct = Activ.ext_not(NAct)
+PAct_connect = Act_connect.ext_not(NAct)
NActLV = NAct.ext_not(ThickGateOx)
-NAct_NWell = NAct.ext_and(NWell.ext_or(PWell_block))
+NAct_NWell = NAct.ext_and(X1)
+sal_nActiv = NAct.ext_not(SalBlock)
ContBar_NAct = ContBar.ext_and(NAct)
+Cont_not_outside_NAct = Cont.not_outside(NAct)
+nBuLayGen_nBuLay_NBL_a = nBuLayGen_nBuLay.ext_fast_width(1.0.um)
+ThickGateOx_Act_out_ThickGateOx_TGO_b_sep_tmp4 = ThickGateOx_Act_out_ThickGateOx_TGO_b_sep_tmp1 + ThickGateOx_Act_out_ThickGateOx_TGO_b_sep_tmp3
+rfcmim = PWell_block.not_outside(rfcmim_a).sized(0.65.um, acute_limit)
+PWell_block_tsvOutRing_enc_tmp = tsvOutRing.ext_fast_enclosed(PWell_block, 2.5.um, polygon_output: true)
+PWell_block_tsvOutRing_enc_tmp2 = tsvOutRing.ext_overlapping(PWell_block)
+Metal1_tsvOutRing_enc_tmp = tsvOutRing.ext_fast_enclosed(Metal1, 1.5.um, polygon_output: true)
+Metal1_tsvOutRing_enc_tmp2 = tsvOutRing.ext_overlapping(Metal1)
+ThickGateOx_GP_out_ThickGateOx_TGO_d_sep_tmp4 = ThickGateOx_GP_out_ThickGateOx_TGO_d_sep_tmp1 + ThickGateOx_GP_out_ThickGateOx_TGO_d_sep_tmp3
+dschottky = dschottky_3.ext_not(dpin)
+SalBlock_Rppd = SalBlock.ext_and(Rppd_all)
+Rppd_all_enclosure_pSD = Rppd_all.ext_fast_enclosed(pSD, 0.18.um, polygon_output: true)
Rhigh_a = GatPoly_res.ext_and(pSD_nSD).ext_and(SalBlock_not_nSDBlock_not_esd)
-nBuLayGen_nBuLay_NBL_a = nBuLayGen_nBuLay.ext_fast_width(1000)
schottky_nbl1_nw = NWell.ext_interacting(NWell.holes.merge.ext_covering(schottky_nbl_rec))
-PAct_NWell = PAct.ext_and(NWell.ext_or(PWell_block))
+schottky_nw1_rect = NWell.not_outside(nSD_block).ext_interacting(schottky_nbl_rec, inverted: true).ext_and(Recog_diode)
+Metal5_slit_MIM_Slt_g_M5_sep_tmp9 = Metal5_slit_MIM_Slt_g_M5_sep_tmp6.dup
+Rhigh_identical_nsd_psd = pSD_not_nSD_or_nSD_not_pSD.ext_with_coincident_edges(Rhigh_identical_nsd_psd_edge)
+TopMetal1_slit_MIM_Slt_g_TM1_sep_tmp9 = TopMetal1_slit_MIM_Slt_g_TM1_sep_tmp6.dup
+Rsil = Rsil_all_not_interact_NWell.ext_interacting(nBuLay, inverted: true)
+PGate = Gate.outside(NGate)
+PAct_NWell = PAct.ext_and(X1)
+ContBar_PAct = ContBar.ext_and(PAct)
+Cont_not_outside_PAct = Cont.not_outside(PAct)
NActHV = NAct.ext_not(NActLV)
NAct_PWell = NAct.ext_not(NAct_NWell)
-SVaricap_gate_0 = NGate.merged(true, 0).not_outside(NWell).merged(true, 0).not_outside(nBuLay)
+WellContDev = NAct_NWell.ext_interacting_with_text(TEXT_0, "well")
+NAct_NWell_not_Gate = NAct_NWell.ext_not(Gate)
+sal_nactive = sal_nActiv.dup
+Rppd_Cont = EXTBlock.ext_covering(Rppd_all).ext_and(Cont)
+n_tie = NWell.ext_and(Activ.ext_and(Y2)).ext_not(SalBlock)
+ThickGateOx_Act_out_ThickGateOx_TGO_b_sep_tmp6 = ThickGateOx_Act_out_ThickGateOx_TGO_b_sep_tmp4 + ThickGateOx_Act_out_ThickGateOx_TGO_b_sep_tmp5
+PWell_block_tsvOutRing_enc_tmp3 = PWell_block_tsvOutRing_enc_tmp + PWell_block_tsvOutRing_enc_tmp2
+Metal1_tsvOutRing_enc_tmp3 = Metal1_tsvOutRing_enc_tmp + Metal1_tsvOutRing_enc_tmp2
+ThickGateOx_GP_out_ThickGateOx_TGO_d_sep_tmp6 = ThickGateOx_GP_out_ThickGateOx_TGO_d_sep_tmp4 + ThickGateOx_GP_out_ThickGateOx_TGO_d_sep_tmp5
+SVaricap_gate_0 = NGate.not_outside(NWell).not_outside(nBuLay)
+GP_Rhigh_extended = GatPoly_res.ext_covering(Rhigh_a)
SalBlock_Rhigh = SalBlock.ext_and(Rhigh_a)
-schottky_nbl1 = schottky_nbl1_nw.merged(true, 0).size(1.36, acute_limit).merge(true, 0)
+schottky_nbl1 = schottky_nbl1_nw.sized(1.36.um, acute_limit)
+Metal5_slit_MIM_Slt_g_M5_sep_tmp11 = Metal5_slit_MIM_Slt_g_M5_sep_tmp9.dup
+TopMetal1_slit_MIM_Slt_g_TM1_sep_tmp11 = TopMetal1_slit_MIM_Slt_g_TM1_sep_tmp9.dup
+GP_Rsil_extended = GatPoly_res.ext_covering(Rsil)
PAct_PWell = PAct.ext_not(PAct_NWell)
-NActHV_digi = NActHV.merged(true, 0).not_outside(DigiBnd_hole)
-SVaricap_text = Activ.merged(true, 0).not_outside(SVaricap_gate_0).ext_interacting_with_text(TEXT_0, "SVaricap")
+Abut_NWell_Tie_Edge = NAct_NWell.ext_coincident_part(PAct_NWell, outside: true)
+MVaricap = PWell_block.ext_and(NWell.sized(1.0.um, acute_limit)).not_outside(GatPoly).not_outside(nBuLay).not_outside(PAct).not_outside(NAct).ext_interacting_with_text(TEXT_0, "MVaricap")
+NActHV_digi = NActHV.not_outside(DigiBnd_hole)
+abut_tie_edge_NWell = NAct_NWell_not_Gate.ext_coincident_part(PAct_NWell, outside: true)
+ntaparea = sal_nactive.ext_and(NWell)
+Rhigh_Cont = EXTBlock.ext_covering(Rhigh_a).ext_and(Cont)
+hard_n_tie = n_tie.ext_covering(Cont)
+schottky_nw1_sized = schottky_nw1_rect.sized(1.36.um, acute_limit).ext_and(ThickGateOx)
+ThickGateOx_Act_out_ThickGateOx_TGO_b_sep_tmp9 = ThickGateOx_Act_out_ThickGateOx_TGO_b_sep_tmp6.dup
+PWell_block_tsvOutRing_enc_tmp6 = PWell_block_tsvOutRing_enc_tmp3.dup
+Metal1_tsvOutRing_enc_tmp6 = Metal1_tsvOutRing_enc_tmp3.dup
+ThickGateOx_GP_out_ThickGateOx_TGO_d_sep_tmp9 = ThickGateOx_GP_out_ThickGateOx_TGO_d_sep_tmp6.dup
+SVaricap_poly = GatPoly.not_outside(SVaricap_gate_0)
+NWell_Tie = NAct_NWell.ext_not(WellContDev.ext_or(SalBlock.ext_or(TRANS)))
+schottky_pwb = schottky_nbl1.ext_and(PWell_block)
+schottky_nSDBlock = schottky_nbl1.ext_and(nSD_block)
+schottky_salblock = schottky_nbl1.ext_and(SalBlock)
+schottky_contbar = schottky_nbl1.ext_and(ContBar)
+scr1_or_schottky_nbl1 = schottky_nbl1.ext_or(scr1)
+Metal5_slit_MIM_Slt_g_M5_sep = Metal5_slit_MIM_Slt_g_M5_sep_tmp11.dup
+TopMetal1_slit_MIM_Slt_g_TM1_sep = TopMetal1_slit_MIM_Slt_g_TM1_sep_tmp11.dup
+GP_Rsil_extended_external_pSD = GP_Rsil_extended.ext_fast_separation(pSD, 0.18.um)
+SVaricap_text = Activ.not_outside(SVaricap_gate_0).ext_interacting_with_text(TEXT_0, "SVaricap")
PAct_PWellLV = PAct_PWell.ext_not(ThickGateOx)
+cmim_tie = PAct_PWell.not_outside(rfcmim)
+Abut_PWell_Tie_Edge = PAct_PWell.ext_coincident_part(NAct_PWell, outside: true)
+BJT_ring_a = PAct_PWell.with_holes
+PAct_PWell_not_Gate = PAct_PWell.ext_not(Gate)
+Abut_NWell_Tie = NAct_NWell.ext_with_coincident_edges(Abut_NWell_Tie_Edge)
NActHV_ana = NActHV.ext_not(NActHV_digi)
-SVaricap = NWell.merged(true, 0).not_outside(SVaricap_text)
+soft_n_tie = n_tie.ext_not(hard_n_tie)
+schottky_nbl1_b = PAct_connect.not_outside(schottky_nbl1).ext_not(schottky_nbl1)
+schottky_nw1 = schottky_nw1_sized.ext_interacting_with_text(TEXT_0, "schottky_nw1")
+ThickGateOx_Act_out_ThickGateOx_TGO_b_sep_tmp11 = ThickGateOx_Act_out_ThickGateOx_TGO_b_sep_tmp9.dup
+PWell_block_tsvOutRing_enc = PWell_block_tsvOutRing_enc_tmp6.dup
+Metal1_tsvOutRing_enc = Metal1_tsvOutRing_enc_tmp6.dup
+ThickGateOx_GP_out_ThickGateOx_TGO_d_sep_tmp11 = ThickGateOx_GP_out_ThickGateOx_TGO_d_sep_tmp9.dup
+MOSvaricap = MVaricap.ext_or(SVaricap_poly)
+SubContDev_basic = PAct_PWell.ext_interacting_with_text(TEXT_0, "sub!").ext_not(Recog_esd)
+NwellRing_innermost = NWell_Tie.holes.merge.outside(NWell_Tie)
+ntap = ntaparea.ext_covering(Cont.ext_and(ntaparea))
+SVaricap = NWell.not_outside(SVaricap_text)
PAct_PWellHV = PAct_PWell.ext_not(PAct_PWellLV)
-PAct_PWellHV_digi = PAct_PWellHV.merged(true, 0).not_outside(DigiBnd_hole)
+Abut_PWell_Tie = PAct_PWell.ext_with_coincident_edges(Abut_PWell_Tie_Edge)
+abut_tie_edge_PWell = PAct_PWell_not_Gate.ext_coincident_part(NAct_PWell, outside: true)
+Abut_NWell_Tie_PAct = PAct.ext_interacting(Abut_NWell_Tie)
+nsdb_exlcDev = dschottky.ext_or(schottky_nbl1, schottky_nw1, trans_bip)
+schottky_nbl1_or_schottky_nw1 = schottky_nbl1.ext_or(schottky_nw1)
+ThickGateOx_Act_out_ThickGateOx_TGO_b_sep = ThickGateOx_Act_out_ThickGateOx_TGO_b_sep_tmp11.dup
+ThickGateOx_GP_out_ThickGateOx_TGO_d_sep = ThickGateOx_GP_out_ThickGateOx_TGO_d_sep_tmp11.dup
+SubContDev = SubContDev_basic.ext_interacting(nBuLay, inverted: true)
+SubContDev_iso = SubContDev_basic.not_outside(nBuLay)
+PGate_inside_NwellRing = PGate.not_outside(NwellRing_innermost)
+NwellRing_edge = NWell_Tie.ext_coincident_part(NwellRing_innermost, outside: true)
+all_ntie = ntap.ext_or(soft_n_tie)
+schottky_nw1_b = PAct_connect.not_outside(schottky_nw1).ext_not(schottky_nw1)
+pSD_c_tmp1 = pSD.outside(SVaricap)
+devExclud = Recog_diode.ext_or(SVaricap, nmoscl_2, nmoscl_4, npnMPA, schottky_nbl1, scr1, subst_tie_hole_w_npn, trans_bip)
+SVaricap_or_schottky_nbl1 = SVaricap.ext_or(schottky_nbl1)
+NGate_outside_SVaricap = NGate.outside(SVaricap)
+PAct_PWellHV_digi = PAct_PWellHV.not_outside(DigiBnd_hole)
+Abut_PWell_Tie_NAct = NAct.ext_interacting(Abut_PWell_Tie)
+Abut_NWell_Tie_Cont = Cont.inside(Abut_NWell_Tie_PAct)
+SVaricap_Tie = PAct_PWell.not_outside(Activ.not_outside(SVaricap))
+NwellRing = NWell_Tie.ext_with_coincident_edges(NwellRing_edge)
+PAct_PWellHV_ana = PAct_PWellHV.ext_not(PAct_PWellHV_digi)
+Abut_PWell_Tie_Cont = Cont.inside(Abut_PWell_Tie_NAct)
+PWell_Tie_w_rf = PAct_PWell.ext_not(Recog_esd.ext_or(SalBlock, SubContDev, SubContDev_iso, cmim_tie, schottky_nbl1, schottky_nbl1_b, schottky_nw1, schottky_nw1_b))
+Holes_NwellRing = NwellRing.holes.merge
+PwellRing_innermost = PWell_Tie_w_rf.holes.merge.outside(PWell_Tie_w_rf)
+NoHoles_NwellRing = Holes_NwellRing.ext_or(NwellRing)
+NGate_inside_PwellRing = NGate.not_outside(PwellRing_innermost)
+PwellRing_edge = PWell_Tie_w_rf.ext_coincident_part(PwellRing_innermost, outside: true)
+rfNwellRing = NoHoles_NwellRing.ext_interacting_with_text(TEXT_0, "rfpmos*")
+PwellRing = PWell_Tie_w_rf.ext_with_coincident_edges(PwellRing_edge)
+rfpmos_all = PGate_inside_NwellRing.not_outside(rfNwellRing)
+Holes_PwellRing = PwellRing.holes.merge
+NoHoles_PwellRing = Holes_PwellRing.ext_or(PwellRing)
+pmosHV = PGate.ext_or(rfpmos_all).ext_not(MOSvaricap).not_outside(ThickGateOx)
+rfPwellRing = NoHoles_PwellRing.ext_interacting_with_text(TEXT_0, "rfnmos*")
+pnpMPARing = NoHoles_PwellRing.ext_interacting_with_text(TEXT_0, "pnpMPA")
+rfnmos_all = NGate_inside_PwellRing.not_outside(rfPwellRing)
+pnpMPA = PAct_NWell.not_outside(nBuLay).not_outside(pnpMPARing)
+BJT_hole = (BJT_ring_a.holes - BJT_ring_a.with_holes).without_holes.ext_covering(TRANS.ext_or(pnpMPA))
+nmosHV = NGate.ext_or(rfnmos_all).ext_not(MOSvaricap).not_outside(ThickGateOx)
+BJT_ring = BJT_ring_a.ext_interacting(BJT_hole)
+PWell_Tie_wo_varicap_abut = PAct_PWell.ext_interacting(Abut_PWell_Tie.ext_or(BJT_ring, SVaricap_Tie), inverted: true)
-> do
NWell_NW_a.dup
-end.().output("NW.a", "Min. NWell width")
+end.().output("NW.a", "Min. NWell width = 0.62")
-> do
- NWell.ext_fast_separation(NActHV_ana, 620)
-end.().output("NW.d1", "Min. NWell space to external N+Activ inside ThickGateOx")
+ NWell.ext_fast_separation(NActHV_ana, 0.62.um)
+end.().output("NW.d1", "Min. NWell space to external N+Activ inside ThickGateOx = 0.62")
+-> (;x, y) do
+ x = PAct_PWellLV.ext_coincident_edges(SVaricap, outside: true)
+ y = PAct_PWellLV.ext_with_coincident_edges(x)
+ NWell.ext_fast_separation(PAct_PWellLV.ext_not(y), 0.24.um)
+end.().output("NW.f", "Min. NWell space to substrate tie in P+Activ not inside ThickGateOx = 0.24")
+-> do
+ NWell.ext_fast_separation(PAct_PWellHV_ana.ext_interacting(SVaricap, inverted: true), 0.62.um)
+end.().output("NW.f1", "Min. NWell space to substrate tie in P+Activ inside ThickGateOx = 0.62")
-> do
PWell_block_PWB_a.dup
-end.().output("PWB.a", "Min. PWell:block width")
+end.().output("PWB.a", "Min. PWell:block width = 0.62")
-> do
PWell_block_PWB_b.dup
-end.().output("PWB.b", "Min. PWell:block space or notch")
+end.().output("PWB.b", "Min. PWell:block space or notch = 0.62")
-> do
- PWellBlock_unrelatedNWell.ext_fast_separation(PWell_block, 620)
-end.().output("PWB.c", "Min. PWell:block space to unrelated NWell")
+ PWellBlock_unrelatedNWell.ext_fast_separation(PWell_block, 0.62.um)
+end.().output("PWB.c", "Min. PWell:block space to unrelated NWell = 0.62")
-> do
nBuLayGen_nBuLay_NBL_a.dup
-end.().output("NBL.a", "Min. nBuLay width")
+end.().output("NBL.a", "Min. nBuLay width = 1.00")
-> do
nBuLay_block_NBLB_a.dup
-end.().output("NBLB.a", "Min. nBuLay:block width")
+end.().output("NBLB.a", "Min. nBuLay:block width = 1.50")
+-> do
+ nBuLay_block.ext_fast_space(1.0.um)
+end.().output("NBLB.b", "Min. nBuLay:block space or notch = 1.00")
-> do
- nBuLay_block.ext_fast_space(1000)
-end.().output("NBLB.b", "Min. nBuLay:block space or notch")
+ nBuLay_nBuLay_block_enc.dup
+end.().output("NBLB.c", "Min. nBuLay enclosure of nBuLay:block = 1.00")
-> do
- nBuLay_block.ext_fast_separation(nBuLay, 1500)
-end.().output("NBLB.d", "Min. nBuLay:block space to unrelated nBuLay")
+ nBuLay_block.ext_fast_separation(nBuLay, 1.5.um)
+end.().output("NBLB.d", "Min. nBuLay:block space to unrelated nBuLay = 1.50")
-> do
Activ_Act_a.dup
-end.().output("Act.a", "Min. Activ width")
+end.().output("Act.a", "Min. Activ width = 0.15")
-> do
- Act_Nsram.ext_fast_space(210)
-end.().output("Act.b", "Min. Activ space or notch")
+ Act_Nsram.ext_fast_space(0.21.um)
+end.().output("Act.b", "Min. Activ space or notch = 0.21")
-> do
Activ_Act_d.dup
-end.().output("Act.d", "Min. Activ area (µm²)")
+end.().output("Act.d", "Min. Activ area (µm²) = 0.122")
+-> do
+ (Activ.holes - Activ.with_holes).without_holes.ext_not(Activ).ext_with_area([["<", 0.15.um2]])
+end.().output("Act.e", "Min. Activ enclosed area (µm²) = 0.15")
if $filler
-> do
- Activ_filler.drc((width(projection) > 5000).polygons)
- end.().output("AFil.a", "Max. Activ:filler width")
+ Activ_filler.drc((width(projection) > 5.0.um).polygons)
+ end.().output("AFil.a", "Max. Activ:filler width = 5.00")
-> do
- Activ_filler.ext_fast_width(1000)
- end.().output("AFil.a1", "Min. Activ:filler width")
+ Activ_filler.ext_fast_width(1.0.um)
+ end.().output("AFil.a1", "Min. Activ:filler width = 1.00")
-> do
- Activ_filler.ext_fast_space(1000)
- end.().output("AFil.b", "Min. Activ:filler space")
+ Activ_filler.ext_fast_space(1.0.um)
+ end.().output("AFil.b", "Min. Activ:filler space = 0.42")
end
if $density
-> do
Act_density.ext_with_density(0.0 .. 0.35, 'll')
- end.().output("AFil.g", "Min. global Activ density [%]")
+ end.().output("AFil.g", "Min. global Activ density [%] = 35.00")
-> do
Act_density.ext_with_density(0.55 .. 1.0, 'll')
- end.().output("AFil.g1", "Max. global Activ density [%]")
+ end.().output("AFil.g1", "Max. global Activ density [%] = 55.00")
-> do
- Act_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("AFil.g2", "Min. Activ coverage ratio for any 800 x 800 µm² chip area [%]")
+ Act_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0.um), tile_step(400.0.um))
+ end.().output("AFil.g2", "Min. Activ coverage ratio for any 800 x 800 µm² chip area [%] = 25.00")
-> do
- Act_density.ext_with_density(0.65 .. 1.0, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("AFil.g3", "Max. Activ coverage ratio for any 800 x 800 µm² chip area [%]")
+ Act_density.ext_with_density(0.65 .. 1.0, 'll', tile_size(800.0.um), tile_step(400.0.um))
+ end.().output("AFil.g3", "Max. Activ coverage ratio for any 800 x 800 µm² chip area [%] = 65.00")
end
+-> do
+ Activ.ext_fast_enclosed(ThickGateOx, 0.27.um, polygon_output: true)
+end.().output("TGO.a", "Min. ThickGateOx extension over Activ = 0.27")
+-> do
+ ThickGateOx_Act_out_ThickGateOx_TGO_b_sep.dup
+end.().output("TGO.b", "Min. space between ThickGateOx and Activ outside thick gate oxide region = 0.27")
+-> (;a) do
+ a = Gate.ext_fast_enclosed(ThickGateOx, 0.34.um, polygon_output: true)
+ a.ext_and(Activ)
+end.().output("TGO.c", "Min. ThickGateOx extension over GatPoly over Activ = 0.34")
+-> do
+ ThickGateOx_GP_out_ThickGateOx_TGO_d_sep.dup
+end.().output("TGO.d", "Min. space between ThickGateOx and GatPoly over Activ outside thick gate oxide region = 0.34")
-> do
ThickGateOx_TGO_e.dup
-end.().output("TGO.e", "Min. ThickGateOx space (merge if less than this value)")
+end.().output("TGO.e", "Min. ThickGateOx space (merge if less than this value) = 0.86")
-> do
ThickGateOx_TGO_f.dup
-end.().output("TGO.f", "Min. ThickGateOx width")
+end.().output("TGO.f", "Min. ThickGateOx width = 0.86")
-> do
GP_Nsram_Gat_a.dup
-end.().output("Gat.a", "Min. GatPoly width")
+end.().output("Gat.a", "Min. GatPoly width = 0.13")
+-> (;a) do
+ a = Activ.ext_not(nmosHV).ext_interacting(nmosHV).ext_fast_space(0.45.um, polygon_output: true)
+ a.ext_and(Activ).outside(nmoscl.ext_or(scr1))
+end.().output("Gat.a3", "Min. GatPoly width for channel length of 3.3 V NFET = 0.45")
+-> (;b) do
+ b = Activ.ext_not(pmosHV).ext_interacting(pmosHV).ext_fast_space(0.4.um, polygon_output: true)
+ b.ext_and(Activ)
+end.().output("Gat.a4", "Min. GatPoly width for channel length of 3.3 V PFET = 0.4")
-> do
GP_Nsram_Gat_b.dup
-end.().output("Gat.b", "Min. GatPoly space or notch")
+end.().output("Gat.b", "Min. GatPoly space or notch = 0.18")
-> do
GP_mosHV_Gat_b1.dup
-end.().output("Gat.b1", "Min. space between unrelated 3.3 V GatPoly over Activ regions")
+end.().output("Gat.b1", "Min. space between unrelated 3.3 V GatPoly over Activ regions = 0.25")
+-> do
+ [ Activ.ext_fast_enclosed(GP_Nsram, 0.18.um, polygon_output: true),
+ Activ.ext_fast_enclosed(GatPoly_filler, 0.18.um, polygon_output: true),
+ GatPoly.inside(Activ)
+ ].each { |result| result.output("Gat.c", "Min. GatPoly extension over Activ (end cap) = 0.18") }
+end.()
-> do
- GP_Nsram.ext_fast_separation(Act_Nsram, 70)
-end.().output("Gat.d", "Min. GatPoly space to Activ")
+ GP_Nsram.ext_fast_separation(Act_Nsram, 0.07.um)
+end.().output("Gat.d", "Min. GatPoly space to Activ = 0.07")
-> do
GatPoly_Gat_e.dup
-end.().output("Gat.e", "Min. GatPoly area (µm²)")
+end.().output("Gat.e", "Min. GatPoly area (µm²) = 0.09")
-> do
- GatPoly.ext_and(Activ).ext_not(SVaricap).ext_rectangles(true, false, nil, nil, nil, inverted: true)
+ Gate.ext_not(SVaricap).ext_rectangles(true, false, nil, nil, nil, inverted: true)
end.().output("Gat.f", "45-degree and 90-degree angles for GatPoly on Activ area are not allowed")
if $filler
-> do
- GatPoly_filler.drc((width(projection) > 5000).polygons)
- end.().output("GFil.a", "Max. GatPoly:filler width")
+ GatPoly_filler.drc((width(projection) > 5.0.um).polygons)
+ end.().output("GFil.a", "Max. GatPoly:filler width = 5.00")
-> do
- GatPoly_filler.ext_fast_width(700)
- end.().output("GFil.b", "Min. GatPoly:filler width")
+ GatPoly_filler.ext_fast_width(0.7.um)
+ end.().output("GFil.b", "Min. GatPoly:filler width = 0.70")
-> do
- GatPoly_filler.ext_fast_space(800)
- end.().output("GFil.c", "Min. GatPoly:filler space")
+ GatPoly_filler.ext_fast_space(0.8.um)
+ end.().output("GFil.c", "Min. GatPoly:filler space = 0.80")
-> do
- Activ.ext_fast_separation(GatPoly_filler, 1100)
- end.().output("GFil.d.Activ", "Min. GatPoly:filler space to Activ")
+ Activ.ext_fast_separation(GatPoly_filler, 1.1.um)
+ end.().output("GFil.d.Activ", "Min. GatPoly:filler space to Activ = 1.10")
-> do
- GatPoly.ext_fast_separation(GatPoly_filler, 1100)
- end.().output("GFil.d.GatPoly", "Min. GatPoly:filler space to GatPoly")
+ GatPoly.ext_fast_separation(GatPoly_filler, 1.1.um)
+ end.().output("GFil.d.GatPoly", "Min. GatPoly:filler space to GatPoly = 1.10")
-> do
- Cont.ext_fast_separation(GatPoly_filler, 1100)
- end.().output("GFil.d.Cont", "Min. GatPoly:filler space to Cont")
+ Cont.ext_fast_separation(GatPoly_filler, 1.1.um)
+ end.().output("GFil.d.Cont", "Min. GatPoly:filler space to Cont = 1.10")
-> do
- pSD.ext_fast_separation(GatPoly_filler, 1100)
- end.().output("GFil.d.pSD", "Min. GatPoly:filler space to pSD")
+ pSD.ext_fast_separation(GatPoly_filler, 1.1.um)
+ end.().output("GFil.d.pSD", "Min. GatPoly:filler space to pSD = 1.10")
-> do
- nSD_block.ext_fast_separation(GatPoly_filler, 1100)
- end.().output("GFil.d.nSD_block", "Min. GatPoly:filler space to nSD:block")
+ nSD_block.ext_fast_separation(GatPoly_filler, 1.1.um)
+ end.().output("GFil.d.nSD_block", "Min. GatPoly:filler space to nSD:block = 1.10")
-> do
- SalBlock.ext_fast_separation(GatPoly_filler, 1100)
- end.().output("GFil.d.SalBlock", "Min. GatPoly:filler space to SalBlock")
+ SalBlock.ext_fast_separation(GatPoly_filler, 1.1.um)
+ end.().output("GFil.d.SalBlock", "Min. GatPoly:filler space to SalBlock = 1.10")
-> do
- GatPoly_filler.ext_fast_separation(TRANS, 1100)
- end.().output("GFil.f", "Min. GatPoly:filler space to TRANS")
+ GatPoly_filler.ext_fast_separation(TRANS, 1.1.um)
+ end.().output("GFil.f", "Min. GatPoly:filler space to TRANS = 1.10")
end
if $density
-> do
Gat_density.ext_with_density(0.0 .. 0.15, 'll')
- end.().output("GFil.g", "Min. global GatPoly density [%]")
+ end.().output("GFil.g", "Min. global GatPoly density [%] = 15.00")
end
if $filler
-> do
- GatPoly_nofill.ext_fast_space(20000)
- end.().output("GFil.j", "Min. GatPoly:filler extension over Activ:filler (end cap)")
+ GatPoly_nofill.ext_fast_space(20.um)
+ end.().output("GFil.j", "Min. GatPoly:filler extension over Activ:filler (end cap) = 0.18")
end
-> do
pSD_pSD_a.dup
-end.().output("pSD.a", "Min. pSD width")
+end.().output("pSD.a", "Min. pSD width = 0.31")
-> do
- pSD.ext_fast_space(310)
-end.().output("pSD.b", "Min. pSD space or notch (Note 1)")
+ pSD.ext_fast_space(0.31.um)
+end.().output("pSD.b", "Min. pSD space or notch (Note 1) = 0.31")
-> do
- pSD.ext_fast_separation(NAct_PWell, 180)
-end.().output("pSD.d", "Min. pSD space to unrelated N+Activ in PWell")
+ Act_NWell.ext_fast_enclosed(pSD_c_tmp1, 0.18.um, polygon_output: true)
+end.().output("pSD.c", "Min. pSD enclosure of P+Activ in NWell = 0.18")
-> do
- pSD.ext_fast_separation(NAct_NWell, 30)
-end.().output("pSD.d1", "Min. pSD space to N+Activ in NWell")
+ pSD.ext_fast_separation(NAct_PWell, 0.18.um)
+end.().output("pSD.d", "Min. pSD space to unrelated N+Activ in PWell = 0.18")
+-> do
+ pSD.ext_fast_separation(NAct_NWell, 0.03.um)
+end.().output("pSD.d1", "Min. pSD space to N+Activ in NWell = 0.03")
-> (;layA, layB, layC, layD) do
- layA = Activ.ext_not(SRAM).merged(true, 0).not_inside(pSD).ext_interacting(pSD)
- layB = layA.ext_and(pSD).merged(true, 0).outside(SVaricap)
- layC = layB.ext_fast_width(300, polygon_output: true)
+ layA = Act_Nsram.not_inside(pSD).ext_interacting(pSD)
+ layB = layA.ext_and(pSD).outside(SVaricap)
+ layC = layB.ext_fast_width(0.3.um, polygon_output: true)
layD = layC.ext_covering(layB)
layD.dup
-end.().output("pSD.e", "Min. pSD overlap of Activ at one position when forming abutted substrate tie (Note 2)")
+end.().output("pSD.e", "Min. pSD overlap of Activ at one position when forming abutted substrate tie (Note 2) = 0.30")
+-> (;abuttedNTAP, bad_region, good_region) do
+ abuttedNTAP = NAct_NWell.ext_interacting(PAct_NWell)
+ bad_region = abuttedNTAP.ext_coincident_part(PAct_NWell, outside: true).ext_fast_overlap(NAct_NWell, 0.3.um, polygon_output: true)
+ good_region = abuttedNTAP.ext_not(bad_region)
+ abuttedNTAP.outside(good_region)
+end.().output("pSD.f", "Min. Activ extension over pSD at one position when forming abutted NWell tie (Note 2) = 0.30")
+-> (;x, y) do
+ x = NAct_NWell_not_Gate.ext_interacting(SVaricap_or_schottky_nbl1, inverted: true).outside(SRAM)
+ y = PAct_PWell_not_Gate.ext_interacting(SVaricap_or_schottky_nbl1, inverted: true).outside(SRAM)
+ [ x.ext_interacting(Gate, inverted: true).ext_with_area([["<", 0.09.um2]]),
+ y.ext_interacting(Gate, inverted: true).ext_with_area([["<", 0.09.um2]])
+ ].each { |result| result.output("pSD.g", "Min. N+Activ or P+Activ area (µm²) when forming abutted tie (Note 2) = 0.09") }
+end.()
+-> do
+ PGate.ext_fast_enclosed(pSD_Nsram, 0.3.um, polygon_output: true)
+end.().output("pSD.i", "Min. pSD enclosure of PFET gate not inside ThickGateOx = 0.30")
+-> do
+ PGate.ext_fast_enclosed(pSDHV_Nsram, 0.4.um, polygon_output: true)
+end.().output("pSD.i1", "Min. pSD enclosure of PFET gate inside ThickGateOx = 0.40")
+-> do
+ pSD_Nsram.ext_fast_separation(NGate_outside_SVaricap, 0.3.um)
+end.().output("pSD.j", "Min. pSD space to NFET gate not inside ThickGateOx = 0.30")
+-> do
+ pSD_Nsram.ext_fast_separation(NGate_outside_SVaricap.inside(ThickGateOx), 0.4.um)
+end.().output("pSD.j1", "Min. pSD space to NFET gate inside ThickGateOx = 0.40")
-> do
- pSD_Nsram.ext_fast_separation(NGate.merged(true, 0).outside(SVaricap), 300)
-end.().output("pSD.j", "Min. pSD space to NFET gate not inside ThickGateOx")
+ pSD_pSD_k.dup
+end.().output("pSD.k", "Min. pSD area (µm²) = 0.25")
-> do
- pSD_Nsram.ext_fast_separation(NGate.merged(true, 0).outside(SVaricap).merged(true, 0).inside(ThickGateOx), 400)
-end.().output("pSD.j1", "Min. pSD space to NFET gate inside ThickGateOx")
+ pSDL_enc_area_pSD_l.dup
+end.().output("pSD.l", "Min. pSD enclosed area (µm²) = 0.25")
-> do
- pSD_pSD_k.dup
-end.().output("pSD.k", "Min. pSD area (µm²)")
+ GP_Rsil_extended_external_pSD.dup
+end.().output("pSD.m", "Min. pSD space to n-type poly resistors = 0.18")
+-> do
+ Rppd_all_enclosure_pSD.dup
+end.().output("pSD.n", "Min. pSD enclosure of p-type poly resistors = 0.18")
+-> do
+ nSD_block.ext_fast_width(0.31.um)
+end.().output("nSDB.a", "Min. nSD:block width = 0.31")
-> do
- nSD_block.ext_fast_width(310)
-end.().output("nSDB.a", "Min. nSD:block width")
+ nSD_block.ext_fast_space(0.31.um)
+end.().output("nSDB.b", "Min. nSD:block space or notch = 0.31")
-> do
- nSD_block.ext_fast_space(310)
-end.().output("nSDB.b", "Min. nSD:block space or notch")
+ nSD_block.ext_fast_separation(pSD.ext_interacting(nSD_block, inverted: true), 0.31.um)
+end.().output("nSDB.c", "Min. nSD:block space to unrelated pSD = 0.31")
-> do
- EXTBlock.ext_fast_width(310)
-end.().output("EXT.a", "Min. EXTBlock width")
+ Cont.outside(nsdb_exlcDev).ext_and(nSD_block)
+end.().output("nSDB.e", "Min. nSD:block space to Cont (Note 2) = 0.00")
-> do
- EXTBlock.ext_fast_space(310)
-end.().output("EXT.b", "Min. EXTBlock space or notch")
+ EXTBlock.ext_fast_width(0.31.um)
+end.().output("EXT.a", "Min. EXTBlock width = 0.31")
-> do
- EXTBlock.ext_fast_separation(pSD, 310)
-end.().output("EXT.c", "Min. EXTBlock space to pSD")
+ EXTBlock.ext_fast_space(0.31.um)
+end.().output("EXT.b", "Min. EXTBlock space or notch = 0.31")
-> do
- SalBlock.ext_fast_width(420)
-end.().output("Sal.a", "Min. SalBlock width")
+ EXTBlock.ext_fast_separation(pSD, 0.31.um)
+end.().output("EXT.c", "Min. EXTBlock space to pSD = 0.31")
-> do
- SalBlock.ext_fast_space(420)
-end.().output("Sal.b", "Min. SalBlock space or notch")
+ SalBlock.ext_fast_width(0.42.um)
+end.().output("Sal.a", "Min. SalBlock width = 0.42")
-> do
- SalBlock.ext_fast_separation(GatPoly.ext_or(PolyRes), 200)
- SalBlock.ext_fast_separation(Activ.ext_or(Activ_mask), 200)
-end.().output("Sal.d", "Min. SalBlock space to unrelated Activ or GatPoly")
+ SalBlock.ext_fast_space(0.42.um)
+end.().output("Sal.b", "Min. SalBlock space or notch = 0.42")
-> do
- SalBlock.ext_fast_separation(Cont, 200)
-end.().output("Sal.e", "Min. SalBlock space to Cont")
+ [ GatPoly_res.ext_fast_enclosed(SalBlock, 0.2.um, polygon_output: true),
+ Activ.ext_fast_enclosed(SalBlock, 0.2.um, polygon_output: true)
+ ].each { |result| result.output("Sal.c", "Min. SalBlock extension over Activ or GatPoly = 0.20") }
+end.()
-> do
- Cont.merged(true, 0).outside(EdgeSeal).ext_not(ContBar.ext_or(Cont_SQ))
-end.().output("Cnt.a", "Min. and max. Cont width")
+ [ SalBlock.ext_fast_separation(GatPoly_res, 0.2.um),
+ SalBlock.ext_fast_separation(nmosi_relevant_activ, 0.2.um)
+ ].each { |result| result.output("Sal.d", "Min. SalBlock space to unrelated Activ or GatPoly = 0.20") }
+end.()
-> do
- Cont.merged(true, 0).outside(EdgeSeal).ext_fast_space(180)
-end.().output("Cnt.b", "Min. Cont space")
+ SalBlock.ext_fast_separation(Cont, 0.2.um)
+end.().output("Sal.e", "Min. SalBlock space to Cont = 0.20")
+-> do
+ Cont_outside_EdgeSeal.ext_not(ContBar.ext_or(Cont_SQ))
+end.().output("Cnt.a", "Min. and max. Cont width = 0.16")
+-> do
+ Cont_outside_EdgeSeal.ext_fast_space(0.18.um)
+end.().output("Cnt.b", "Min. Cont space = 0.18")
-> (;x1, viaLargeArray, viaInLargeArray, viaInLargeArray_error, badViaLine) do
- x1 = Cont.merged(true, 0).size(0.20*0.5, acute_limit).merge(true, 0).size(-0.20*0.5, acute_limit).merge(true, 0)
- viaLargeArray = x1.merged(true, 0).size(-(5*0.16)+(3*0.18)/2-0.001, acute_limit).merge(true, 0).size((5*0.16)+(3*0.18)/2-0.001, acute_limit).merge(true, 0)
- viaInLargeArray = Cont.merged(true, 0).inside(viaLargeArray)
- viaInLargeArray_error = viaInLargeArray.merged(true, 0).size(0.20/2-0.001, acute_limit).merge(true, 0).size(-0.20/2-0.001, acute_limit).merge(true, 0)
+ x1 = Cont.sized((0.20*0.5).um, acute_limit).sized(-(0.20*0.5).um, acute_limit)
+ viaLargeArray = x1.sized(-((5*0.16)+(3*0.18)/2-0.001).um, acute_limit).sized(((5*0.16)+(3*0.18)/2-0.001).um, acute_limit)
+ viaInLargeArray = Cont.inside(viaLargeArray)
+ viaInLargeArray_error = viaInLargeArray.sized((0.20/2-0.001).um, acute_limit).sized(-(0.20/2-0.001).um, acute_limit)
badViaLine = viaInLargeArray_error.ext_not(viaInLargeArray)
badViaLine.ext_rectangles(inverted: true)
-end.().output("Cnt.b1", "Min. Cont space in a contact array of more than 4 rows and more then 4 columns (Note 1)")
+end.().output("Cnt.b1", "Min. Cont space in a contact array of more than 4 rows and more then 4 columns (Note 1) = 0.20")
-> do
- Cont_Act.ext_not(SVaricap).ext_fast_separation(GP_Nsram, 110)
-end.().output("Cnt.f", "Min. Cont on Activ space to GatPoly")
+ Cont_Act.ext_not(SVaricap).ext_fast_separation(GP_Nsram, 0.11.um)
+end.().output("Cnt.f", "Min. Cont on Activ space to GatPoly = 0.11")
-> do
Cont_not_Act_GP.dup
end.().output("Cnt.g", "Cont must be within Activ or GatPoly")
@@ -892,27 +1461,35 @@ end.().output("Cnt.h", "Cont must be covered with Metal1")
-> do
Cont_Act_GP.ext_not(SVaricap)
end.().output("Cnt.j", "Cont on GatPoly over Activ is not allowed")
+-> do
+ [ ContBar.outside(EdgeSeal).ext_not(schottky_nbl1_or_schottky_nw1).ext_fast_width(0.16.um),
+ Cont_outside_EdgeSeal.ext_not(schottky_nbl1_or_schottky_nw1).drc((width(projection) > 0.16.um).polygons)
+ ].each { |result| result.output("CntB.a", "Min. and max. ContBar width = 0.16") }
+end.()
-> do
CntB_a1_error.dup
-end.().output("CntB.a1", "Min. ContBar length")
+end.().output("CntB.a1", "Min. ContBar length = 0.34")
-> do
- ContBar.merged(true, 0).outside(TRANS).ext_fast_space(280)
-end.().output("CntB.b", "Min. ContBar space")
+ ContBar_outside_TRANS.ext_fast_space(0.28.um)
+end.().output("CntB.b", "Min. ContBar space = 0.28")
-> do
- ContBar.ext_fast_separation(Cont_SQ, 220)
-end.().output("CntB.b2", "Min. ContBar space to Cont")
+ ContBar.ext_fast_separation(Cont_SQ, 0.22.um)
+end.().output("CntB.b2", "Min. ContBar space to Cont = 0.22")
-> do
- ContBar_GP.ext_fast_separation(Activ, 140)
-end.().output("CntB.e", "Min. ContBar on GatPoly space to Activ")
+ ContBar_GP.ext_fast_separation(Activ, 0.14.um)
+end.().output("CntB.e", "Min. ContBar on GatPoly space to Activ = 0.14")
-> do
- ContBar_Act.ext_fast_separation(GatPoly, 110)
-end.().output("CntB.f", "Min. ContBar on Activ space to GatPoly")
+ ContBar_Act.ext_fast_separation(GatPoly, 0.11.um)
+end.().output("CntB.f", "Min. ContBar on Activ space to GatPoly = 0.11")
-> do
ContBar_not_Act_GP.dup
end.().output("CntB.g", "ContBar must be within Activ or GatPoly")
-> do
- pSD.ext_fast_separation(ContBar_NAct, 90, polygon_output: true)
-end.().output("CntB.g1", "Min. pSD space to ContBar on nSD-Activ")
+ pSD.ext_fast_separation(ContBar_NAct, 0.09.um, polygon_output: true)
+end.().output("CntB.g1", "Min. pSD space to ContBar on nSD-Activ = 0.09")
+-> do
+ ContBar_PAct.ext_fast_enclosed(pSD, 0.09.um, polygon_output: true)
+end.().output("CntB.g2", "Min. pSD overlap of ContBar on pSD-Activ = 0.09")
-> do
ContBar_not_M1.dup
end.().output("CntB.h", "ContBar must be covered with Metal1")
@@ -920,751 +1497,1082 @@ end.().output("CntB.h", "ContBar must be covered with Metal1")
ContBar_Act_GP.dup
end.().output("CntB.j", "ContBar on GatPoly over Activ is not allowed")
-> do
- Metal1.ext_fast_width(160)
-end.().output("M1.a", "Min. Metal1 width")
+ Metal1.ext_fast_width(0.16.um)
+end.().output("M1.a", "Min. Metal1 width = 0.16")
-> do
- M1_Nsram.ext_fast_space(180)
-end.().output("M1.b", "Min. Metal1 space or notch")
+ M1_Nsram.ext_fast_space(0.18.um)
+end.().output("M1.b", "Min. Metal1 space or notch = 0.18")
-> do
Cont_Nsram.ext_not(M1_Nsram)
-end.().output("M1.c", "Min. Metal1 enclosure of Cont")
+end.().output("M1.c", "Min. Metal1 enclosure of Cont = 0.00")
-> do
- Metal1.merged(true, 0).outside(EdgeSeal).ext_area([["<", 0.09]])
-end.().output("M1.d", "Min. Metal1 area (µm²)")
+ Cont_Nsram.outside(EdgeSeal).drc(if_any(
+ !rectangles,
+ primary-secondary(Metal1_outside_EdgeSeal),
+ ((enclosed(Metal1_outside_EdgeSeal, projection, whole_edges, one_side_allowed, two_opposite_sides_allowed) < 0.05.um))))
+end.().output("M1.c1", "Min. Metal1 endcap enclosure of Cont (Note 1) = 0.05")
+-> do
+ Metal1_outside_EdgeSeal.ext_with_area([["<", 0.09.um2]])
+end.().output("M1.d", "Min. Metal1 area (µm²) = 0.09")
if $density
-> do
M1_density.ext_with_density(0.0 .. 0.35, 'll')
- end.().output("M1.j", "Min. global Metal1 density [%]")
+ end.().output("M1.j", "Min. global Metal1 density [%] = 35.0")
-> do
M1_density.ext_with_density(0.6 .. 1.0, 'll')
- end.().output("M1.k", "Max. global Metal1 density [%]")
+ end.().output("M1.k", "Max. global Metal1 density [%] = 60.0")
end
-> do
- Metal2.ext_fast_width(200)
-end.().output("M2.a", "Min. Metal2 width")
+ Metal2.ext_fast_width(0.2.um)
+end.().output("M2.a", "Min. Metal2 width = 0.20")
+-> do
+ M2_Nsram.ext_fast_space(0.21.um)
+end.().output("M2.b", "Min. Metal2 space or notch = 0.21")
+-> do
+ Via1.outside(EdgeSeal).ext_fast_enclosed(Metal2_outside_EdgeSeal, 0.005.um, polygon_output: true)
+end.().output("M2.c", "Min. Metal2 enclosure of Via1 = 0.005")
-> do
- M2_Nsram.ext_fast_space(210)
-end.().output("M2.b", "Min. Metal2 space or notch")
+ V1_Nsram_outside_EdgeSeal.drc(if_any(
+ !rectangles,
+ primary-secondary(Metal2_outside_EdgeSeal),
+ ((enclosed(Metal2_outside_EdgeSeal, projection, whole_edges, one_side_allowed, two_opposite_sides_allowed) < 0.05.um))))
+end.().output("M2.c1", "Min. Metal2 endcap enclosure of Via1 (Note 1) = 0.05")
-> do
- Metal2.merged(true, 0).outside(EdgeSeal).ext_area([["<", 0.144]])
-end.().output("M2.d", "Min. Metal2 area (µm²)")
+ Metal2_outside_EdgeSeal.ext_with_area([["<", 0.144.um2]])
+end.().output("M2.d", "Min. Metal2 area (µm²) = 0.144")
if $density
-> do
M2_density.ext_with_density(0.0 .. 0.35, 'll')
- end.().output("M2.j", "Min. global Metal2 density [%]")
+ end.().output("M2.j", "Min. global Metal2 density [%] = 35.00")
-> do
M2_density.ext_with_density(0.6 .. 1.0, 'll')
- end.().output("M2.k", "Max. global Metal2 density [%]")
+ end.().output("M2.k", "Max. global Metal2 density [%] = 60.00")
end
-> do
- Metal3.ext_fast_width(200)
-end.().output("M3.a", "Min. Metal3 width")
+ Metal3.ext_fast_width(0.2.um)
+end.().output("M3.a", "Min. Metal3 width = 0.20")
-> do
- M3_Nsram.ext_fast_space(210)
-end.().output("M3.b", "Min. Metal3 space or notch")
+ M3_Nsram.ext_fast_space(0.21.um)
+end.().output("M3.b", "Min. Metal3 space or notch = 0.21")
-> do
- Metal3.merged(true, 0).outside(EdgeSeal).ext_area([["<", 0.144]])
-end.().output("M3.d", "Min. Metal3 area (µm²)")
+ Via2.outside(EdgeSeal).ext_fast_enclosed(Metal3_outside_EdgeSeal, 0.005.um, polygon_output: true)
+end.().output("M3.c", "Min. Metal3 enclosure of Via2 = 0.005")
+-> do
+ V2_Nsram_outside_EdgeSeal.drc(if_any(
+ !rectangles,
+ primary-secondary(Metal3_outside_EdgeSeal),
+ ((enclosed(Metal3_outside_EdgeSeal, projection, whole_edges, one_side_allowed, two_opposite_sides_allowed) < 0.05.um))))
+end.().output("M3.c1", "Min. Metal3 endcap enclosure of Via2 (Note 1) = 0.05")
+-> do
+ Metal3_outside_EdgeSeal.ext_with_area([["<", 0.144.um2]])
+end.().output("M3.d", "Min. Metal3 area (µm²) = 0.144")
if $density
-> do
M3_density.ext_with_density(0.0 .. 0.35, 'll')
- end.().output("M3.j", "Min. global Metal3 density [%]")
+ end.().output("M3.j", "Min. global Metal3 density [%] = 35.00")
-> do
M3_density.ext_with_density(0.6 .. 1.0, 'll')
- end.().output("M3.k", "Max. global Metal3 density [%]")
+ end.().output("M3.k", "Max. global Metal3 density [%] = 60.00")
end
-> do
- Metal4.ext_fast_width(200)
-end.().output("M4.a", "Min. Metal4 width")
+ Metal4.ext_fast_width(0.2.um)
+end.().output("M4.a", "Min. Metal4 width = 0.20")
+-> do
+ M4_Nsram.ext_fast_space(0.21.um)
+end.().output("M4.b", "Min. Metal4 space or notch = 0.21")
+-> do
+ Via3.outside(EdgeSeal).ext_fast_enclosed(Metal4_outside_EdgeSeal, 0.005.um, polygon_output: true)
+end.().output("M4.c", "Min. Metal4 enclosure of Via3 = 0.005")
-> do
- M4_Nsram.ext_fast_space(210)
-end.().output("M4.b", "Min. Metal4 space or notch")
+ V3_Nsram_outside_EdgeSeal.drc(if_any(
+ !rectangles,
+ primary-secondary(Metal4_outside_EdgeSeal),
+ ((enclosed(Metal4_outside_EdgeSeal, projection, whole_edges, one_side_allowed, two_opposite_sides_allowed) < 0.05.um))))
+end.().output("M4.c1", "Min. Metal4 endcap enclosure of Via3 (Note 1) = 0.05")
-> do
- Metal4.merged(true, 0).outside(EdgeSeal).ext_area([["<", 0.144]])
-end.().output("M4.d", "Min. Metal4 area (µm²)")
+ Metal4_outside_EdgeSeal.ext_with_area([["<", 0.144.um2]])
+end.().output("M4.d", "Min. Metal4 area (µm²) = 0.144")
if $density
-> do
M4_density.ext_with_density(0.0 .. 0.35, 'll')
- end.().output("M4.j", "Min. global Metal4 density [%]")
+ end.().output("M4.j", "Min. global Metal4 density [%] = 35.00")
-> do
M4_density.ext_with_density(0.6 .. 1.0, 'll')
- end.().output("M4.k", "Max. global Metal4 density [%]")
+ end.().output("M4.k", "Max. global Metal4 density [%] = 60.00")
end
-> do
- Metal5.ext_fast_width(200)
-end.().output("M5.a", "Min. Metal5 width")
+ Metal5.ext_fast_width(0.2.um)
+end.().output("M5.a", "Min. Metal5 width = 0.20")
-> do
- M5_Nsram.ext_fast_space(210)
-end.().output("M5.b", "Min. Metal5 space or notch")
+ M5_Nsram.ext_fast_space(0.21.um)
+end.().output("M5.b", "Min. Metal5 space or notch = 0.21")
-> do
- Metal5.merged(true, 0).outside(EdgeSeal).ext_area([["<", 0.144]])
-end.().output("M5.d", "Min. Metal5 area (µm²)")
+ Via4.outside(EdgeSeal).ext_fast_enclosed(Metal5_outside_EdgeSeal, 0.005.um, polygon_output: true)
+end.().output("M5.c", "Min. Metal5 enclosure of Via4 = 0.005")
+-> do
+ V4_Nsram_outside_EdgeSeal.drc(if_any(
+ !rectangles,
+ primary-secondary(Metal5_outside_EdgeSeal),
+ ((enclosed(Metal5_outside_EdgeSeal, projection, whole_edges, one_side_allowed, two_opposite_sides_allowed) < 0.05.um))))
+end.().output("M5.c1", "Min. Metal5 endcap enclosure of Via4 (Note 1) = 0.05")
+-> do
+ Metal5_outside_EdgeSeal.ext_with_area([["<", 0.144.um2]])
+end.().output("M5.d", "Min. Metal5 area (µm²) = 0.144")
if $density
-> do
M5_density.ext_with_density(0.0 .. 0.35, 'll')
- end.().output("M5.j", "Min. global Metal5 density [%]")
+ end.().output("M5.j", "Min. global Metal5 density [%] = 35.00")
-> do
M5_density.ext_with_density(0.6 .. 1.0, 'll')
- end.().output("M5.k", "Max. global Metal5 density [%]")
+ end.().output("M5.k", "Max. global Metal5 density [%] = 60.00")
end
if $filler
-> do
- Metal1_filler.ext_fast_width(1000)
- end.().output("M1Fil.a1", "Min. Metal1:filler width")
+ Metal1_filler.ext_fast_width(1.0.um)
+ end.().output("M1Fil.a1", "Min. Metal1:filler width = 1.00")
-> do
- Metal1_filler.ext_fast_space(600)
- end.().output("M1Fil.b", "Min. Metal1:filler space")
+ Metal1_filler.ext_fast_space(0.6.um)
+ end.().output("M1Fil.b", "Min. Metal1:filler space = 0.42")
-> do
- Metal1_filler.ext_fast_separation(Metal1, 420)
- end.().output("M1Fil.c", "Min. Metal1:filler space to Metal1")
+ Metal1_filler.ext_fast_separation(Metal1, 0.42.um)
+ end.().output("M1Fil.c", "Min. Metal1:filler space to Metal1 = 0.42")
-> do
- Metal1_filler.ext_fast_separation(TRANS, 1000)
- end.().output("M1Fil.d", "Min. Metal1:filler space to TRANS")
+ Metal1_filler.ext_fast_separation(TRANS, 1.0.um)
+ end.().output("M1Fil.d", "Min. Metal1:filler space to TRANS = 1.00")
end
if $density
-> do
- M1_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M1Fil.h", "Min. Metal1 and Metal1:filler coverage ratio for any 800 x 800 µm² chip area [%]")
+ M1_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0.um), tile_step(400.0.um))
+ end.().output("M1Fil.h", "Min. Metal1 and Metal1:filler coverage ratio for any 800 x 800 µm² chip area [%] = 25.00")
-> do
- M1_density.ext_with_density(0.75 .. 1.0, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M1Fil.k", "Max. Metal1 and Metal1:filler coverage ratio for any 800 x 800 µm² chip area [%]")
+ M1_density.ext_with_density(0.75 .. 1.0, 'll', tile_size(800.0.um), tile_step(400.0.um))
+ end.().output("M1Fil.k", "Max. Metal1 and Metal1:filler coverage ratio for any 800 x 800 µm² chip area [%] = 75.00")
end
if $filler
-> do
- Metal2_filler.ext_fast_width(1000)
- end.().output("M2Fil.a1", "Min. Metal2:filler width")
+ Metal2_filler.ext_fast_width(1.0.um)
+ end.().output("M2Fil.a1", "Min. Metal2:filler width = 1.00")
-> do
- Metal2_filler.ext_fast_space(600)
- end.().output("M2Fil.b", "Min. Metal2:filler space")
+ Metal2_filler.ext_fast_space(0.6.um)
+ end.().output("M2Fil.b", "Min. Metal2:filler space = 0.42")
-> do
- Metal2_filler.ext_fast_separation(Metal2, 420)
- end.().output("M2Fil.c", "Min. Metal2:filler space to Metal2")
+ Metal2_filler.ext_fast_separation(Metal2, 0.42.um)
+ end.().output("M2Fil.c", "Min. Metal2:filler space to Metal2 = 0.42")
-> do
- Metal2_filler.ext_fast_separation(TRANS, 1000)
- end.().output("M2Fil.d", "Min. Metal2:filler space to TRANS")
+ Metal2_filler.ext_fast_separation(TRANS, 1.0.um)
+ end.().output("M2Fil.d", "Min. Metal2:filler space to TRANS = 1.00")
end
if $density
-> do
- M2_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M2Fil.h", "Min. Metal2 and Metal2:filler coverage ratio for any 800 x 800 µm² chip area [%]")
+ M2_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0.um), tile_step(400.0.um))
+ end.().output("M2Fil.h", "Min. Metal2 and Metal2:filler coverage ratio for any 800 x 800 µm² chip area [%] = 25.00")
-> do
- M2_density.ext_with_density(0.75 .. 1.0, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M2Fil.k", "Max. Metal2 and Metal2:filler coverage ratio for any 800 x 800 µm² chip area [%]")
+ M2_density.ext_with_density(0.75 .. 1.0, 'll', tile_size(800.0.um), tile_step(400.0.um))
+ end.().output("M2Fil.k", "Max. Metal2 and Metal2:filler coverage ratio for any 800 x 800 µm² chip area [%] = 75.00")
end
if $filler
-> do
- Metal3_filler.ext_fast_width(1000)
- end.().output("M3Fil.a1", "Min. Metal3:filler width")
+ Metal3_filler.ext_fast_width(1.0.um)
+ end.().output("M3Fil.a1", "Min. Metal3:filler width = 1.00")
-> do
- Metal3_filler.ext_fast_space(600)
- end.().output("M3Fil.b", "Min. Metal3:filler space")
+ Metal3_filler.ext_fast_space(0.6.um)
+ end.().output("M3Fil.b", "Min. Metal3:filler space = 0.42")
-> do
- Metal3_filler.ext_fast_separation(Metal3, 420)
- end.().output("M3Fil.c", "Min. Metal3:filler space to Metal3")
+ Metal3_filler.ext_fast_separation(Metal3, 0.42.um)
+ end.().output("M3Fil.c", "Min. Metal3:filler space to Metal3 = 0.42")
-> do
- Metal3_filler.ext_fast_separation(TRANS, 1000)
- end.().output("M3Fil.d", "Min. Metal3:filler space to TRANS")
+ Metal3_filler.ext_fast_separation(TRANS, 1.0.um)
+ end.().output("M3Fil.d", "Min. Metal3:filler space to TRANS = 1.00")
end
if $density
-> do
- M3_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M3Fil.h", "Min. Metal3 and Metal3:filler coverage ratio for any 800 x 800 µm² chip area [%]")
+ M3_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0.um), tile_step(400.0.um))
+ end.().output("M3Fil.h", "Min. Metal3 and Metal3:filler coverage ratio for any 800 x 800 µm² chip area [%] = 25.00")
-> do
- M3_density.ext_with_density(0.75 .. 1.0, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M3Fil.k", "Max. Metal3 and Metal3:filler coverage ratio for any 800 x 800 µm² chip area [%]")
+ M3_density.ext_with_density(0.75 .. 1.0, 'll', tile_size(800.0.um), tile_step(400.0.um))
+ end.().output("M3Fil.k", "Max. Metal3 and Metal3:filler coverage ratio for any 800 x 800 µm² chip area [%] = 75.00")
end
if $filler
-> do
- Metal4_filler.ext_fast_width(1000)
- end.().output("M4Fil.a1", "Min. Metal4:filler width")
+ Metal4_filler.ext_fast_width(1.0.um)
+ end.().output("M4Fil.a1", "Min. Metal4:filler width = 1.00")
-> do
- Metal4_filler.ext_fast_space(600)
- end.().output("M4Fil.b", "Min. Metal4:filler space")
+ Metal4_filler.ext_fast_space(0.6.um)
+ end.().output("M4Fil.b", "Min. Metal4:filler space = 0.42")
-> do
- Metal4_filler.ext_fast_separation(Metal4, 420)
- end.().output("M4Fil.c", "Min. Metal4:filler space to Metal4")
+ Metal4_filler.ext_fast_separation(Metal4, 0.42.um)
+ end.().output("M4Fil.c", "Min. Metal4:filler space to Metal4 = 0.42")
-> do
- Metal4_filler.ext_fast_separation(TRANS, 1000)
- end.().output("M4Fil.d", "Min. Metal4:filler space to TRANS")
+ Metal4_filler.ext_fast_separation(TRANS, 1.0.um)
+ end.().output("M4Fil.d", "Min. Metal4:filler space to TRANS = 1.00")
end
if $density
-> do
- M4_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M4Fil.h", "Min. Metal4 and Metal4:filler coverage ratio for any 800 x 800 µm² chip area [%]")
+ M4_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0.um), tile_step(400.0.um))
+ end.().output("M4Fil.h", "Min. Metal4 and Metal4:filler coverage ratio for any 800 x 800 µm² chip area [%] = 25.00")
-> do
- M4_density.ext_with_density(0.75 .. 1.0, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M4Fil.k", "Max. Metal4 and Metal4:filler coverage ratio for any 800 x 800 µm² chip area [%]")
+ M4_density.ext_with_density(0.75 .. 1.0, 'll', tile_size(800.0.um), tile_step(400.0.um))
+ end.().output("M4Fil.k", "Max. Metal4 and Metal4:filler coverage ratio for any 800 x 800 µm² chip area [%] = 75.00")
end
if $filler
-> do
- Metal5_filler.ext_fast_width(1000)
- end.().output("M5Fil.a1", "Min. Metal5:filler width")
+ Metal5_filler.ext_fast_width(1.0.um)
+ end.().output("M5Fil.a1", "Min. Metal5:filler width = 1.00")
-> do
- Metal5_filler.ext_fast_space(600)
- end.().output("M5Fil.b", "Min. Metal5:filler space")
+ Metal5_filler.ext_fast_space(0.6.um)
+ end.().output("M5Fil.b", "Min. Metal5:filler space = 0.42")
-> do
- Metal5_filler.ext_fast_separation(Metal5, 420)
- end.().output("M5Fil.c", "Min. Metal5:filler space to Metal5")
+ Metal5_filler.ext_fast_separation(Metal5, 0.42.um)
+ end.().output("M5Fil.c", "Min. Metal5:filler space to Metal5 = 0.42")
-> do
- Metal5_filler.ext_fast_separation(TRANS, 1000)
- end.().output("M5Fil.d", "Min. Metal5:filler space to TRANS")
+ Metal5_filler.ext_fast_separation(TRANS, 1.0.um)
+ end.().output("M5Fil.d", "Min. Metal5:filler space to TRANS = 1.00")
end
if $density
-> do
- M5_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M5Fil.h", "Min. Metal5 and Metal5:filler coverage ratio for any 800 x 800 µm² chip area [%]")
+ M5_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0.um), tile_step(400.0.um))
+ end.().output("M5Fil.h", "Min. Metal5 and Metal5:filler coverage ratio for any 800 x 800 µm² chip area [%] = 25.00")
-> do
- M5_density.ext_with_density(0.75 .. 1.0, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M5Fil.k", "Max. Metal5 and Metal5:filler coverage ratio for any 800 x 800 µm² chip area [%]")
+ M5_density.ext_with_density(0.75 .. 1.0, 'll', tile_size(800.0.um), tile_step(400.0.um))
+ end.().output("M5Fil.k", "Max. Metal5 and Metal5:filler coverage ratio for any 800 x 800 µm² chip area [%] = 75.00")
end
-> do
- Via1.ext_not(EdgeSeal).merged(true, 0).outside(transG2L).ext_rectangles(false, false, [["==", 190]], [["==", 190]], nil, inverted: true)
-end.().output("V1.a", "Min. and max. Via1 width")
+ Via1_edgC1_out.outside(transG2L).ext_rectangles(false, false, [["==", 0.19.um]], [["==", 0.19.um]], nil, inverted: true)
+end.().output("V1.a", "Min. and max. Via1 width = 0.19")
-> do
- Via1.ext_not(EdgeSeal).ext_fast_space(220)
-end.().output("V1.b", "Min. Via1 space")
+ Via1_edgC1_out.ext_fast_space(0.22.um)
+end.().output("V1.b", "Min. Via1 space = 0.22")
-> (;via1NoES, x1, via1Array, via1In, via1BigArray, via1SepErr_1, via1SepErr_2) do
- via1NoES = Via1.ext_not(EdgeSeal)
- x1 = via1NoES.merged(true, 0).size(0.29*0.5, acute_limit).merge(true, 0).size(-0.29*0.5, acute_limit).merge(true, 0)
- via1Array = x1.merged(true, 0).size(-((4*0.19+3*0.22)-0.05)*0.5, acute_limit).merge(true, 0).size(((4*0.19+3*0.22)-0.05)*0.5, acute_limit).merge(true, 0)
- via1In = via1NoES.merged(true, 0).inside(via1Array)
- via1BigArray = via1In.merged(true, 0).size(0.143, acute_limit).merge(true, 0).size(-0.143, acute_limit).merge(true, 0)
+ via1NoES = Via1_edgC1_out.dup
+ x1 = via1NoES.sized((0.29*0.5).um, acute_limit).sized(-(0.29*0.5).um, acute_limit)
+ via1Array = x1.sized(-(((4*0.19+3*0.22)-0.05)*0.5).um, acute_limit).sized((((4*0.19+3*0.22)-0.05)*0.5).um, acute_limit)
+ via1In = via1NoES.inside(via1Array)
+ via1BigArray = via1In.sized(0.143.um, acute_limit).sized(-0.143.um, acute_limit)
via1SepErr_1 = via1BigArray.ext_not(via1In)
via1SepErr_2 = via1SepErr_1.ext_not(via1SepErr_1.ext_rectangles)
via1SepErr_2.ext_or(via1In.ext_touching(via1SepErr_2))
-end.().output("V1.b1", "Min. Via1 space in an array of more than 3 rows and more then 3 columns (Note 1)")
--> do
- Via2.ext_not(EdgeSeal).merged(true, 0).outside(transG2L).ext_rectangles(false, false, [["==", 190]], [["==", 190]], nil, inverted: true)
-end.().output("V2.a", "Min. and max. Via2 width")
--> do
- Via2.ext_not(EdgeSeal).ext_fast_space(220)
-end.().output("V2.b", "Min. Via2 space")
+end.().output("V1.b1", "Min. Via1 space in an array of more than 3 rows and more then 3 columns (Note 1) = 0.29")
+-> (;x) do
+ x = V1_Nsram_outside_EdgeSeal.ext_rectangles(false, false, [["==", 0.19.um]], [["==", 0.19.um]], nil)
+ x.drc(if_any(
+ !rectangles,
+ primary-secondary(Metal1_outside_EdgeSeal),
+ (if_any(enclosed(Metal1_outside_EdgeSeal) < 0.01.um, enclosed(Metal1_outside_EdgeSeal, projection, whole_edges, one_side_allowed, two_opposite_sides_allowed) < 0.05.um))))
+end.().output("V1.c1", "Min. Metal1 endcap enclosure of Via1 (Note 2) = 0.05")
+-> do
+ Via2_edgC1_out.outside(transG2L).ext_rectangles(false, false, [["==", 0.19.um]], [["==", 0.19.um]], nil, inverted: true)
+end.().output("V2.a", "Min. and max. Via2 width = 0.19")
+-> do
+ Via2_edgC1_out.ext_fast_space(0.22.um)
+end.().output("V2.b", "Min. Via2 space = 0.22")
-> (;via2NoES, x1, via2Array, via2In, via2BigArray, via2SepErr_1, via2SepErr_2) do
- via2NoES = Via2.ext_not(EdgeSeal)
- x1 = via2NoES.merged(true, 0).size(0.29*0.5, acute_limit).merge(true, 0).size(-0.29*0.5, acute_limit).merge(true, 0)
- via2Array = x1.merged(true, 0).size(-((4*0.19+3*0.22)-0.05)*0.5, acute_limit).merge(true, 0).size(((4*0.19+3*0.22)-0.05)*0.5, acute_limit).merge(true, 0)
- via2In = via2NoES.merged(true, 0).inside(via2Array)
- via2BigArray = via2In.merged(true, 0).size(0.143, acute_limit).merge(true, 0).size(-0.143, acute_limit).merge(true, 0)
+ via2NoES = Via2_edgC1_out.dup
+ x1 = via2NoES.sized((0.29*0.5).um, acute_limit).sized(-(0.29*0.5).um, acute_limit)
+ via2Array = x1.sized(-(((4*0.19+3*0.22)-0.05)*0.5).um, acute_limit).sized((((4*0.19+3*0.22)-0.05)*0.5).um, acute_limit)
+ via2In = via2NoES.inside(via2Array)
+ via2BigArray = via2In.sized(0.143.um, acute_limit).sized(-0.143.um, acute_limit)
via2SepErr_1 = via2BigArray.ext_not(via2In)
via2SepErr_2 = via2SepErr_1.ext_not(via2SepErr_1.ext_rectangles)
via2SepErr_2.ext_or(via2In.ext_touching(via2SepErr_2))
-end.().output("V2.b1", "Min. Via2 space in an array of more than 3 rows and more then 3 columns (Note 1)")
--> do
- Via3.ext_not(EdgeSeal).merged(true, 0).outside(transG2L).ext_rectangles(false, false, [["==", 190]], [["==", 190]], nil, inverted: true)
-end.().output("V3.a", "Min. and max. Via3 width")
--> do
- Via3.ext_not(EdgeSeal).ext_fast_space(220)
-end.().output("V3.b", "Min. Via3 space")
+end.().output("V2.b1", "Min. Via2 space in an array of more than 3 rows and more then 3 columns (Note 1) = 0.29")
+-> (;x) do
+ x = V2_Nsram_outside_EdgeSeal.ext_rectangles(false, false, [["==", 0.19.um]], [["==", 0.19.um]], nil)
+ x.drc(if_any(
+ !rectangles,
+ primary-secondary(Metal2_outside_EdgeSeal),
+ (if_any(enclosed(Metal2_outside_EdgeSeal) < 0.005.um, enclosed(Metal2_outside_EdgeSeal, projection, whole_edges, one_side_allowed, two_opposite_sides_allowed) < 0.05.um))))
+end.().output("V2.c1", "Min. Metal2 endcap enclosure of Via2 (Note 2) = 0.05")
+-> do
+ Via3_edgC1_out.outside(transG2L).ext_rectangles(false, false, [["==", 0.19.um]], [["==", 0.19.um]], nil, inverted: true)
+end.().output("V3.a", "Min. and max. Via3 width = 0.19")
+-> do
+ Via3_edgC1_out.ext_fast_space(0.22.um)
+end.().output("V3.b", "Min. Via3 space = 0.22")
-> (;via3NoES, x1, via3Array, via3In, via3BigArray, via3SepErr_1, via3SepErr_2) do
- via3NoES = Via3.ext_not(EdgeSeal)
- x1 = via3NoES.merged(true, 0).size(0.29*0.5, acute_limit).merge(true, 0).size(-0.29*0.5, acute_limit).merge(true, 0)
- via3Array = x1.merged(true, 0).size(-((4*0.19+3*0.22)-0.05)*0.5, acute_limit).merge(true, 0).size(((4*0.19+3*0.22)-0.05)*0.5, acute_limit).merge(true, 0)
- via3In = via3NoES.merged(true, 0).inside(via3Array)
- via3BigArray = via3In.merged(true, 0).size(0.143, acute_limit).merge(true, 0).size(-0.143, acute_limit).merge(true, 0)
+ via3NoES = Via3_edgC1_out.dup
+ x1 = via3NoES.sized((0.29*0.5).um, acute_limit).sized(-(0.29*0.5).um, acute_limit)
+ via3Array = x1.sized(-(((4*0.19+3*0.22)-0.05)*0.5).um, acute_limit).sized((((4*0.19+3*0.22)-0.05)*0.5).um, acute_limit)
+ via3In = via3NoES.inside(via3Array)
+ via3BigArray = via3In.sized(0.143.um, acute_limit).sized(-0.143.um, acute_limit)
via3SepErr_1 = via3BigArray.ext_not(via3In)
via3SepErr_2 = via3SepErr_1.ext_not(via3SepErr_1.ext_rectangles)
via3SepErr_2.ext_or(via3In.ext_touching(via3SepErr_2))
-end.().output("V3.b1", "Min. Via3 space in an array of more than 3 rows and more then 3 columns (Note 1)")
--> do
- Via4.ext_not(EdgeSeal).merged(true, 0).outside(transG2L).ext_rectangles(false, false, [["==", 190]], [["==", 190]], nil, inverted: true)
-end.().output("V4.a", "Min. and max. Via4 width")
--> do
- Via4.ext_not(EdgeSeal).ext_fast_space(220)
-end.().output("V4.b", "Min. Via4 space")
+end.().output("V3.b1", "Min. Via3 space in an array of more than 3 rows and more then 3 columns (Note 1) = 0.29")
+-> (;x) do
+ x = V3_Nsram_outside_EdgeSeal.ext_rectangles(false, false, [["==", 0.19.um]], [["==", 0.19.um]], nil)
+ x.drc(if_any(
+ !rectangles,
+ primary-secondary(Metal3_outside_EdgeSeal),
+ (if_any(enclosed(Metal3_outside_EdgeSeal) < 0.005.um, enclosed(Metal3_outside_EdgeSeal, projection, whole_edges, one_side_allowed, two_opposite_sides_allowed) < 0.05.um))))
+end.().output("V3.c1", "Min. Metal3 endcap enclosure of Via3 (Note 2) = 0.05")
+-> do
+ Via4_edgC1_out.outside(transG2L).ext_rectangles(false, false, [["==", 0.19.um]], [["==", 0.19.um]], nil, inverted: true)
+end.().output("V4.a", "Min. and max. Via4 width = 0.19")
+-> do
+ Via4_edgC1_out.ext_fast_space(0.22.um)
+end.().output("V4.b", "Min. Via4 space = 0.22")
-> (;via4NoES, x1, via4Array, via4In, via4BigArray, via4SepErr_1, via4SepErr_2) do
- via4NoES = Via4.ext_not(EdgeSeal)
- x1 = via4NoES.merged(true, 0).size(0.29*0.5, acute_limit).merge(true, 0).size(-0.29*0.5, acute_limit).merge(true, 0)
- via4Array = x1.merged(true, 0).size(-((4*0.19+3*0.22)-0.05)*0.5, acute_limit).merge(true, 0).size(((4*0.19+3*0.22)-0.05)*0.5, acute_limit).merge(true, 0)
- via4In = via4NoES.merged(true, 0).inside(via4Array)
- via4BigArray = via4In.merged(true, 0).size(0.143, acute_limit).merge(true, 0).size(-0.143, acute_limit).merge(true, 0)
+ via4NoES = Via4_edgC1_out.dup
+ x1 = via4NoES.sized((0.29*0.5).um, acute_limit).sized(-(0.29*0.5).um, acute_limit)
+ via4Array = x1.sized(-(((4*0.19+3*0.22)-0.05)*0.5).um, acute_limit).sized((((4*0.19+3*0.22)-0.05)*0.5).um, acute_limit)
+ via4In = via4NoES.inside(via4Array)
+ via4BigArray = via4In.sized(0.143.um, acute_limit).sized(-0.143.um, acute_limit)
via4SepErr_1 = via4BigArray.ext_not(via4In)
via4SepErr_2 = via4SepErr_1.ext_not(via4SepErr_1.ext_rectangles)
via4SepErr_2.ext_or(via4In.ext_touching(via4SepErr_2))
-end.().output("V4.b1", "Min. Via4 space in an array of more than 3 rows and more then 3 columns (Note 1)")
+end.().output("V4.b1", "Min. Via4 space in an array of more than 3 rows and more then 3 columns (Note 1) = 0.29")
+-> (;x) do
+ x = V4_Nsram_outside_EdgeSeal.ext_rectangles(false, false, [["==", 0.19.um]], [["==", 0.19.um]], nil)
+ x.drc(if_any(
+ !rectangles,
+ primary-secondary(Metal4_outside_EdgeSeal),
+ (if_any(enclosed(Metal4_outside_EdgeSeal) < 0.005.um, enclosed(Metal4_outside_EdgeSeal, projection, whole_edges, one_side_allowed, two_opposite_sides_allowed) < 0.05.um))))
+end.().output("V4.c1", "Min. Metal4 endcap enclosure of Via4 (Note 2) = 0.05")
-> do
- Vmim.ext_or(TopVia1.ext_not(EdgeSeal)).ext_rectangles(false, false, [["==", 420]], [["==", 420]], nil, inverted: true)
-end.().output("TV1.a", "Min. and max. TopVia1 width")
+ TopVia1_edgC1_out.ext_or(Vmim).ext_rectangles(false, false, [["==", 0.42.um]], [["==", 0.42.um]], nil, inverted: true)
+end.().output("TV1.a", "Min. and max. TopVia1 width = 0.42")
-> do
- TopVia1.ext_or(Vmim).ext_fast_space(420)
-end.().output("TV1.b", "Min. TopVia1 space")
+ TopVia1_or_Vmim.ext_fast_space(0.42.um)
+end.().output("TV1.b", "Min. TopVia1 space = 0.42")
-> do
- TopMetal1.ext_fast_width(1640)
-end.().output("TM1.a", "Min. TopMetal1 width")
+ TopMetal1.ext_fast_width(1.64.um)
+end.().output("TM1.a", "Min. TopMetal1 width = 1.64")
-> do
- TopMetal1.ext_fast_space(1640)
-end.().output("TM1.b", "Min. TopMetal1 space or notch")
+ TopMetal1.ext_fast_space(1.64.um)
+end.().output("TM1.b", "Min. TopMetal1 space or notch = 1.64")
if $density
-> do
TM1_density.ext_with_density(0.0 .. 0.25, 'll')
- end.().output("TM1.c", "Min. global TopMetal1 density [%]")
+ end.().output("TM1.c", "Min. global TopMetal1 density [%] = 25.00")
-> do
TM1_density.ext_with_density(0.7 .. 1.0, 'll')
- end.().output("TM1.d", "Max. global TopMetal1 density [%]")
+ end.().output("TM1.d", "Max. global TopMetal1 density [%] = 70.00")
end
if $filler
-> do
- TopMetal1_filler.ext_fast_width(5000)
- end.().output("TM1Fil.a", "Min. TopMetal1:filler width")
+ TopMetal1_filler.ext_fast_width(5.0.um)
+ end.().output("TM1Fil.a", "Min. TopMetal1:filler width = 5.00")
-> do
- TopMetal1_filler.ext_fast_space(3000)
- end.().output("TM1Fil.b", "Min. TopMetal1:filler space")
+ TopMetal1_filler.ext_fast_space(3.0.um)
+ end.().output("TM1Fil.b", "Min. TopMetal1:filler space = 3.00")
-> do
- TopMetal1_filler.ext_fast_separation(TopMetal1, 3000)
- end.().output("TM1Fil.c", "Min. TopMetal1:filler space to TopMetal1")
+ TopMetal1_filler.ext_fast_separation(TopMetal1, 3.0.um)
+ end.().output("TM1Fil.c", "Min. TopMetal1:filler space to TopMetal1 = 3.00")
-> do
- TopMetal1_filler.ext_fast_separation(TRANS, 4900)
- end.().output("TM1Fil.d", "Min. TopMetal1:filler space to TRANS")
+ TopMetal1_filler.ext_fast_separation(TRANS, 4.9.um)
+ end.().output("TM1Fil.d", "Min. TopMetal1:filler space to TRANS = 4.90")
end
-> do
- TopVia2.ext_not(EdgeSeal).ext_rectangles(false, false, [["==", 900]], [["==", 900]], nil, inverted: true)
-end.().output("TV2.a", "Min. and max. TopVia2 width")
+ TopVia2_edgC1_out.ext_rectangles(false, false, [["==", 0.9.um]], [["==", 0.9.um]], nil, inverted: true)
+end.().output("TV2.a", "Min. and max. TopVia2 width = 0.90")
-> do
- TopVia2.ext_fast_space(1060)
-end.().output("TV2.b", "Min. TopVia2 space")
+ TopVia2.ext_fast_space(1.06.um)
+end.().output("TV2.b", "Min. TopVia2 space = 1.06")
-> do
- TopMetal2.ext_fast_width(2000)
-end.().output("TM2.a", "Min. TopMetal2 width")
+ TopMetal2.ext_fast_width(2.0.um)
+end.().output("TM2.a", "Min. TopMetal2 width = 2.00")
-> do
- TopMetal2.ext_fast_space(2000)
-end.().output("TM2.b", "Min. TopMetal2 space or notch")
+ TopMetal2.ext_fast_space(2.0.um)
+end.().output("TM2.b", "Min. TopMetal2 space or notch = 2.00")
if $density
-> do
TM2_density.ext_with_density(0.0 .. 0.25, 'll')
- end.().output("TM2.c", "Min. global TopMetal2 density [%]")
+ end.().output("TM2.c", "Min. global TopMetal2 density [%] = 25.00")
-> do
TM2_density.ext_with_density(0.7 .. 1.0, 'll')
- end.().output("TM2.d", "Max. global TopMetal2 density [%]")
+ end.().output("TM2.d", "Max. global TopMetal2 density [%] = 70.00")
end
if $filler
-> do
- TopMetal2_filler.ext_fast_width(5000)
- end.().output("TM2Fil.a", "Min. TopMetal2:filler width")
+ TopMetal2_filler.ext_fast_width(5.0.um)
+ end.().output("TM2Fil.a", "Min. TopMetal2:filler width = 5.00")
-> do
- TopMetal2_filler.ext_fast_space(3000)
- end.().output("TM2Fil.b", "Min. TopMetal2:filler space")
+ TopMetal2_filler.ext_fast_space(3.0.um)
+ end.().output("TM2Fil.b", "Min. TopMetal2:filler space = 3.00")
-> do
- TopMetal2_filler.ext_fast_separation(TopMetal2, 3000)
- end.().output("TM2Fil.c", "Min. TopMetal2:filler space to TopMetal2")
+ TopMetal2_filler.ext_fast_separation(TopMetal2, 3.0.um)
+ end.().output("TM2Fil.c", "Min. TopMetal2:filler space to TopMetal2 = 3.00")
-> do
- TopMetal2_filler.ext_fast_separation(TRANS, 4900)
- end.().output("TM2Fil.d", "Min. TopMetal2:filler space to TRANS")
+ TopMetal2_filler.ext_fast_separation(TRANS, 4.9.um)
+ end.().output("TM2Fil.d", "Min. TopMetal2:filler space to TRANS = 4.90")
end
-> do
- Passiv.ext_fast_width(2100)
-end.().output("Pas.a", "Min. Passiv width")
+ Passiv.ext_fast_width(2.1.um)
+end.().output("Pas.a", "Min. Passiv width = 2.10")
+-> do
+ Passiv.ext_fast_space(3.5.um)
+end.().output("Pas.b", "Min. Passiv space or notch = 3.50")
+-> do
+ emit_npn13G2.ext_with_length([[">", 0.07.um], ["<", 0.9.um]])
+end.().output("npn13G2.a", "Min. and max. npn13G2 emitter length = 0.90")
+-> do
+ emit_npn13G2L.ext_with_length([[">", 0.07.um], ["<", 1.0.um]])
+end.().output("npn13G2L.a", "Min. npn13G2L emitter length = 1.00")
-> do
- Passiv.ext_fast_space(3500)
-end.().output("Pas.b", "Min. Passiv space or notch")
+ emit_npn13G2L.ext_with_length([[">", 2.5.um]])
+end.().output("npn13G2L.b", "Max. npn13G2L emitter length = 2.50")
-> do
- emit_npn13G2.ext_with_length([[">", 70], ["<", 900]])
-end.().output("npn13G2.a", "Min. and max. npn13G2 emitter length")
+ emit_npn13G2V.ext_with_length([[">", 0.12.um], ["<", 1.0.um]])
+end.().output("npn13G2V.a", "Min. npn13G2V emitter length = 1.00")
-> do
- emit_npn13G2L.ext_with_length([[">", 70], ["<", 1000]])
-end.().output("npn13G2L.a", "Min. npn13G2L emitter length")
+ emit_npn13G2V.ext_with_length([[">", 5.0.um]])
+end.().output("npn13G2V.b", "Max. npn13G2V emitter length = 5.00")
-> do
- emit_npn13G2L.ext_with_length([[">", 2500]])
-end.().output("npn13G2L.b", "Max. npn13G2L emitter length")
+ Rsil_all.ext_fast_width(0.5.um)
+end.().output("Rsil.a", "Min. GatPoly width = 0.50")
-> do
- emit_npn13G2V.ext_with_length([[">", 120], ["<", 1000]])
-end.().output("npn13G2V.a", "Min. npn13G2V emitter length")
+ RES.ext_fast_separation(Cont, 0.12.um)
+end.().output("Rsil.b", "Min. RES space to Cont = 0.12")
+-> (;x) do
+ x = rsil_gatpoly.ext_fast_enclosed(RES, 1.0.um, polygon_output: true)
+ x.outside(Cont)
+end.().output("Rsil.c", "Min. RES extension over GatPoly = 0.00")
-> do
- emit_npn13G2V.ext_with_length([[">", 5000]])
-end.().output("npn13G2V.b", "Max. npn13G2V emitter length")
+ GP_Rsil_extended_external_pSD.dup
+end.().output("Rsil.d", "Min. pSD space to GatPoly = 0.18")
-> do
- RES.ext_fast_separation(Cont, 120)
-end.().output("Rsil.b", "Min. RES space to Cont")
+ GP_Rsil_extended.ext_fast_enclosed(EXTBlock, 0.18.um, polygon_output: true)
+end.().output("Rsil.e", "Min. EXTBlock enclosure of GatPoly = 0.18")
-> do
- RES.ext_fast_width(500)
-end.().output("Rsil.f", "Min. RES length")
+ RES.ext_fast_width(0.5.um)
+end.().output("Rsil.f", "Min. RES length = 0.50")
-> do
- Rhigh_a.ext_fast_width(500)
-end.().output("Rhi.a", "Min. GatPoly width")
+ Rppd_all.ext_fast_width(0.5.um)
+end.().output("Rppd.a", "Min. GatPoly width = 0.50")
-> do
- SalBlock_Rhigh.ext_fast_width(500)
-end.().output("Rhi.f", "Min. SalBlock length")
+ Rppd_all_enclosure_pSD.dup
+end.().output("Rppd.b", "Min. pSD enclosure of GatPoly = 0.18")
+-> (;x) do
+ x = SalBlock_Rppd.ext_extended(0.2.um, 0.2.um)
+ [ Rppd_Cont.ext_fast_separation(SalBlock_Rppd, 0.2.um),
+ Rppd_Cont.ext_interacting(x, inverted: true)
+ ].each { |result| result.output("Rppd.c", "Min. and max. SalBlock space to Cont = 0.20") }
+end.()
-> do
- Iso_PWell_Act.ext_not(schottky_nbl1.ext_or(scr1)).ext_fast_separation(NWell.ext_ring, 390)
-end.().output("nmosi.c", "Min. NWell space to Iso-PWell-Activ")
+ SalBlock_Rppd.ext_fast_width(0.5.um)
+end.().output("Rppd.e", "Min. SalBlock length = 0.50")
-> do
- NWell_nBuLay.ext_fast_width(620)
-end.().output("nmosi.d", "Min. NWell-nBuLay width forming an unbroken ring around any Iso-PWell-Activ (Note 2)")
+ Rhigh_a.ext_fast_width(0.5.um)
+end.().output("Rhi.a", "Min. GatPoly width = 0.50")
-> do
- nSDBlock_Iso_PWell_Act.ext_fast_width(620)
-end.().output("nmosi.f", "Min. nSD:block width to separate ptap in nmosi")
+ Rhigh_identical_nsd_psd.dup
+end.().output("Rhi.b", "pSD and nSD are identical (Note 1)")
+-> do
+ GP_Rhigh_extended.ext_fast_enclosed(pSD_nSD, 0.18.um, polygon_output: true)
+end.().output("Rhi.c", "Min. pSD and nSD enclosure of GatPoly = 0.18")
+-> (;x) do
+ x = SalBlock_Rhigh.ext_extended(0.2.um, 0.2.um)
+ [ Rhigh_Cont.ext_fast_separation(SalBlock_Rhigh, 0.2.um),
+ Rhigh_Cont.ext_interacting(x, inverted: true)
+ ].each { |result| result.output("Rhi.d", "Min. and max. SalBlock space to Cont = 0.20") }
+end.()
+-> do
+ SalBlock_Rhigh.ext_fast_width(0.5.um)
+end.().output("Rhi.f", "Min. SalBlock length = 0.50")
+-> do
+ Iso_PWell_Act.outside(schottky_nbl1).ext_fast_enclosed(nBuLay, 1.24.um, polygon_output: true)
+end.().output("nmosi.b", "Min. nBuLay enclosure of Iso-PWell-Activ (Note 1) = 1.24")
+-> do
+ Iso_PWell_Act.ext_not(scr1_or_schottky_nbl1).ext_fast_separation(NWell.with_holes, 0.39.um)
+end.().output("nmosi.c", "Min. NWell space to Iso-PWell-Activ = 0.39")
+-> do
+ NWell_nBuLay.ext_fast_width(0.62.um)
+end.().output("nmosi.d", "Min. NWell-nBuLay width forming an unbroken ring around any Iso-PWell-Activ (Note 2) = 0.62")
+-> do
+ nSDBlock_Iso_PWell_Act.ext_fast_width(0.62.um)
+end.().output("nmosi.f", "Min. nSD:block width to separate ptap in nmosi = 0.62")
-> (;tmp, x1) do
- tmp = SalBlock_Iso_PWell_Act.ext_not(schottky_nbl1.ext_or(scr1))
- x1 = nSDBlock_Iso_PWell_Act.ext_fast_enclosed(tmp.ext_not(tmp.ext_covering(npnMPA)), 150, polygon_output: true)
+ tmp = SalBlock_Iso_PWell_Act.ext_not(scr1_or_schottky_nbl1)
+ x1 = nSDBlock_Iso_PWell_Act.ext_fast_enclosed(tmp.ext_not(tmp.ext_covering(npnMPA)), 0.15.um, polygon_output: true)
x1.ext_and(Activ)
-end.().output("nmosi.g", "Min. SalBlock overlap of nSD:block over Activ")
+end.().output("nmosi.g", "Min. SalBlock overlap of nSD:block over Activ = 0.15")
+-> do
+ schottky_contbar.ext_fast_enclosed(schottky_pwb, 0.25.um, polygon_output: true)
+end.().output("Sdiod.a", "Min. and max. PWell:block enclosure of ContBar = 0.25")
+-> do
+ schottky_contbar.ext_fast_enclosed(schottky_nSDBlock, 0.4.um, polygon_output: true)
+end.().output("Sdiod.b", "Min. and max. nSD:block enclosure of ContBar = 0.40")
+-> do
+ schottky_contbar.ext_fast_enclosed(schottky_salblock, 0.45.um, polygon_output: true)
+end.().output("Sdiod.c", "Min. and max. SalBlock enclosure of ContBar = 0.45")
if not $noRecommendedRules
-> do
- Passiv_dfpad.ext_fast_width(30000)
- end.().output("Pad.aR", "Min. recommended Pad width")
+ Passiv_dfpad.ext_fast_width(30.0.um)
+ end.().output("Pad.aR", "Min. recommended Pad width = 30.00")
end
-> do
Passiv_Pad_a1.dup
-end.().output("Pad.a1", "Max. Pad width")
+end.().output("Pad.a1", "Max. Pad width = 150.00")
if not $noRecommendedRules
-> do
- Passiv_dfpad.ext_fast_space(8400)
- end.().output("Pad.bR", "Min. recommended Pad space")
+ Passiv_dfpad.ext_fast_space(8.4.um)
+ end.().output("Pad.bR", "Min. recommended Pad space = 8.40")
end
-> do
- Passiv_dfpad.ext_fast_separation(Act_EdgeSeal_not_HRACT, 7500)
-end.().output("Pad.d", "Min. Pad space to EdgeSeal")
+ Passiv_dfpad.ext_fast_separation(Act_EdgeSeal_not_HRACT, 7.5.um)
+end.().output("Pad.d", "Min. Pad space to EdgeSeal = 7.50")
if not $noRecommendedRules
-> do
- Passiv_dfpad.ext_fast_separation(Act_EdgeSeal_not_HRACT, 25000)
- end.().output("Pad.dR", "Min. recommended Pad to EdgeSeal space (Note 1)")
+ Passiv_dfpad.ext_fast_separation(Act_EdgeSeal_not_HRACT, 25.0.um)
+ end.().output("Pad.dR", "Min. recommended Pad to EdgeSeal space (Note 1) = 25.00")
-> do
- Passiv_dfpad.ext_fast_separation(Act_Not_EdgeSeal, 11200)
- end.().output("Pad.d1R", "Min. recommended Pad to Activ (inside chip area) space")
+ Passiv_dfpad.ext_fast_separation(Act_Not_EdgeSeal, 11.2.um)
+ end.().output("Pad.d1R", "Min. recommended Pad to Activ (inside chip area) space = 11.20")
-> do
- MIM.ext_and(Passiv_dfpad)
- GatPoly.ext_and(Activ).ext_and(Passiv_dfpad)
- end.().output("Pad.jR", "No devices under Pad allowed (Note 2)")
+ TopVia2.ext_fast_enclosed(belowTopMetaln_dfpad, 1.4.um, polygon_output: true)
+ end.().output("Pad.gR", "TopMetal1 (within dfpad) enclosure of TopVia2 = 1.40")
-> do
- TopVia2.merged(true, 0).inside(Passiv_dfpad)
+ [ MIM.ext_and(Passiv_dfpad),
+ Gate.ext_and(Passiv_dfpad)
+ ].each { |result| result.output("Pad.jR", "No devices under Pad allowed (Note 2)") }
+ end.()
+ -> do
+ TopVia2.inside(Passiv_dfpad)
end.().output("Pad.kR", "TopVia2 under Pad not allowed (Note 3)")
end
-> do
- cupPad_candidat.ext_fast_space(45000, polygon_output: true)
-end.().output("Padc.b", "Min. CuPillarPad space")
+ cupPad_candidat.ext_fast_space(45.0.um, polygon_output: true)
+end.().output("Padc.b", "Min. CuPillarPad space = Table 6.1")
-> do
- cupPad_candidat.ext_fast_separation(Act_EdgeSeal_not_HRACT, 30000, polygon_output: true)
-end.().output("Padc.d", "Min. CuPillarPad space to EdgeSeal")
+ cupPad_candidat.ext_fast_separation(Act_EdgeSeal_not_HRACT, 30.0.um, polygon_output: true)
+end.().output("Padc.d", "Min. CuPillarPad space to EdgeSeal = 30.00")
-> do
- Activ_edgA1_in.ext_fast_width(3500)
-end.().output("Seal.a_Activ", "Min. EdgeSeal-Activ width")
+ Activ_edgA1_in.ext_fast_width(3.5.um)
+end.().output("Seal.a_Activ", "Min. EdgeSeal-Activ width = 3.50")
-> do
- pSD_edgA1_in.ext_fast_width(3500)
-end.().output("Seal.a_pSD", "Min. EdgeSeal-pSD width")
+ pSD_edgA1_in.ext_fast_width(3.5.um)
+end.().output("Seal.a_pSD", "Min. EdgeSeal-pSD width = 3.50")
-> do
- Metal1_edgA1_in.ext_fast_width(3500)
-end.().output("Seal.a_Metal1", "Min. EdgeSeal-Metal1 width")
+ Metal1_edgA1_in.ext_fast_width(3.5.um)
+end.().output("Seal.a_Metal1", "Min. EdgeSeal-Metal1 width = 3.50")
-> do
- Metal2_edgA1_in.ext_fast_width(3500)
-end.().output("Seal.a_Metal2", "Min. EdgeSeal-Metal2 width")
+ Metal2_edgA1_in.ext_fast_width(3.5.um)
+end.().output("Seal.a_Metal2", "Min. EdgeSeal-Metal2 width = 3.50")
-> do
- Metal3_edgA1_in.ext_fast_width(3500)
-end.().output("Seal.a_Metal3", "Min. EdgeSeal-Metal3 width")
+ Metal3_edgA1_in.ext_fast_width(3.5.um)
+end.().output("Seal.a_Metal3", "Min. EdgeSeal-Metal3 width = 3.50")
-> do
- Metal4_edgA1_in.ext_fast_width(3500)
-end.().output("Seal.a_Metal4", "Min. EdgeSeal-Metal4 width")
+ Metal4_edgA1_in.ext_fast_width(3.5.um)
+end.().output("Seal.a_Metal4", "Min. EdgeSeal-Metal4 width = 3.50")
-> do
- Metal5_edgA1_in.ext_fast_width(3500)
-end.().output("Seal.a_Metal5", "Min. EdgeSeal-Metal5 width")
+ Metal5_edgA1_in.ext_fast_width(3.5.um)
+end.().output("Seal.a_Metal5", "Min. EdgeSeal-Metal5 width = 3.50")
-> do
- TopMetal1_edgA1_in.ext_fast_width(3500)
-end.().output("Seal.a_TopMetal1", "Min. EdgeSeal-TopMetal1 width")
+ TopMetal1_edgA1_in.ext_fast_width(3.5.um)
+end.().output("Seal.a_TopMetal1", "Min. EdgeSeal-TopMetal1 width = 3.50")
-> do
- TopMetal2_edgA1_in.ext_fast_width(3500)
-end.().output("Seal.a_TopMetal2", "Min. EdgeSeal-TopMetal2 width")
+ TopMetal2_edgA1_in.ext_fast_width(3.5.um)
+end.().output("Seal.a_TopMetal2", "Min. EdgeSeal-TopMetal2 width = 3.50")
-> do
- Cont_edgC1_in.ext_fast_width(160)
- Cont_edgC1_in.drc((width(projection) > 160).polygons)
-end.().output("Seal.c", "EdgeSeal-Cont ring width")
+ [ Cont_edgC1_in.ext_fast_width(0.16.um),
+ Cont_edgC1_in.drc((width(projection) > 0.16.um).polygons)
+ ].each { |result| result.output("Seal.c", "EdgeSeal-Cont ring width = 0.16") }
+end.()
-> do
- Via1_edgC1_in.ext_fast_width(190)
- Via1_edgC1_in.drc((width(projection) > 190).polygons)
-end.().output("Seal.c1.Via1", "EdgeSeal-Via1 ring width")
+ [ Via1_edgC1_in.ext_fast_width(0.19.um),
+ Via1_edgC1_in.drc((width(projection) > 0.19.um).polygons)
+ ].each { |result| result.output("Seal.c1.Via1", "EdgeSeal-Via1 ring width = 0.19") }
+end.()
-> do
- Via2_edgC1_in.ext_fast_width(190)
- Via2_edgC1_in.drc((width(projection) > 190).polygons)
-end.().output("Seal.c1.Via2", "EdgeSeal-Via2 ring width")
+ [ Via2_edgC1_in.ext_fast_width(0.19.um),
+ Via2_edgC1_in.drc((width(projection) > 0.19.um).polygons)
+ ].each { |result| result.output("Seal.c1.Via2", "EdgeSeal-Via2 ring width = 0.19") }
+end.()
-> do
- Via3_edgC1_in.ext_fast_width(190)
- Via3_edgC1_in.drc((width(projection) > 190).polygons)
-end.().output("Seal.c1.Via3", "EdgeSeal-Via3 ring width")
+ [ Via3_edgC1_in.ext_fast_width(0.19.um),
+ Via3_edgC1_in.drc((width(projection) > 0.19.um).polygons)
+ ].each { |result| result.output("Seal.c1.Via3", "EdgeSeal-Via3 ring width = 0.19") }
+end.()
-> do
- Via4_edgC1_in.ext_fast_width(190)
- Via4_edgC1_in.drc((width(projection) > 190).polygons)
-end.().output("Seal.c1.Via4", "EdgeSeal-Via4 ring width")
+ [ Via4_edgC1_in.ext_fast_width(0.19.um),
+ Via4_edgC1_in.drc((width(projection) > 0.19.um).polygons)
+ ].each { |result| result.output("Seal.c1.Via4", "EdgeSeal-Via4 ring width = 0.19") }
+end.()
-> do
- TopVia1_edgC1_in.ext_fast_width(420)
- TopVia1_edgC1_in.drc((width(projection) > 420).polygons)
-end.().output("Seal.c2", "EdgeSeal-TopVia1 ring width")
+ [ TopVia1_edgC1_in.ext_fast_width(0.42.um),
+ TopVia1_edgC1_in.drc((width(projection) > 0.42.um).polygons)
+ ].each { |result| result.output("Seal.c2", "EdgeSeal-TopVia1 ring width = 0.42") }
+end.()
-> do
- TopVia2_edgC1_in.ext_fast_width(900)
- TopVia2_edgC1_in.drc((width(projection) > 900).polygons)
-end.().output("Seal.c3", "EdgeSeal-TopVia2 ring width")
+ [ TopVia2_edgC1_in.ext_fast_width(0.9.um),
+ TopVia2_edgC1_in.drc((width(projection) > 0.9.um).polygons)
+ ].each { |result| result.output("Seal.c3", "EdgeSeal-TopVia2 ring width = 0.90") }
+end.()
-> do
- seal_passiv.ext_fast_width(4200)
-end.().output("Seal.e", "Min. Passiv ring width outside of sealring")
+ seal_passiv.ext_fast_width(4.2.um)
+end.().output("Seal.e", "Min. Passiv ring width outside of sealring = 4.20")
-> do
MIM_Mim_a.dup
-end.().output("MIM.a", "Min. MIM width")
+end.().output("MIM.a", "Min. MIM width = 1.14")
-> do
- MIM.ext_fast_space(600)
-end.().output("MIM.b", "Min. MIM space")
+ MIM.ext_fast_space(0.6.um)
+end.().output("MIM.b", "Min. MIM space = 0.60")
-> do
- TopMetal1.ext_fast_separation(MIM, 600)
-end.().output("MIM.e", "Min. TopMetal1 space to MIM")
+ TopMetal1.ext_fast_separation(MIM, 0.6.um)
+end.().output("MIM.e", "Min. TopMetal1 space to MIM = 0.60")
-> do
MIM_Mim_f.dup
-end.().output("MIM.f", "Min. MIM area per MIM device (µm²)")
+end.().output("MIM.f", "Min. MIM area per MIM device (µm²) = 1.30")
-> do
- MIM.ext_area([[">", 5625.0]])
-end.().output("MIM.g", "Max. MIM area per MIM device (µm²)")
+ MIM.ext_with_area([[">", 5625.0.um2]])
+end.().output("MIM.g", "Max. MIM area per MIM device (µm²) = 5625.00")
-> do
- MIM.ext_not(MIM.ext_covering(TopVia1.ext_or(Vmim)))
+ MIM.ext_not(temp_layer_1)
end.().output("MIM.h", "TopVia1 must be over MIM")
--> do
- Metal1_slit.ext_not(pad).ext_fast_width(2800)
-end.().output("Slt.a.M1", "Min. Metal1:slit width")
+-> (;x) do
+ x = all_ntie.ext_enlarge_inside(NWell, 20.0.um, 0.1.um)
+ PAct_NWell.ext_not(x).outside(devExclud)
+end.().output("LU.a", "Max. space from any portion of P+Activ inside NWell to an nSD-NWell tie = 20.00")
+-> (;sizedA, drcErrA, drcErrA_Edge, drcErrA_Poly) do
+ sizedA = Abut_NWell_Tie_Cont.ext_enlarge_inside(Act_connect.ext_interacting(Gate), 6.0.um, 0.21.um).ext_interacting(Cont_not_outside_NAct, inverted: true)
+ drcErrA = Abut_NWell_Tie.ext_not(sizedA)
+ drcErrA_Edge = drcErrA.ext_coincident_part(sizedA, outside: true)
+ drcErrA_Poly = drcErrA.ext_with_coincident_edges(drcErrA_Edge)
+ drcErrA_Poly.ext_interacting(Cont_not_outside_NAct, inverted: true)
+end.().output("LU.c", "Max. extension of an abutted NWell tie beyond Cont = 6.00")
+-> (;sizedA, drcErrA, drcErrA_Edge, drcErrA_Poly) do
+ sizedA = Abut_PWell_Tie_Cont.ext_enlarge_inside(Act_connect, 6.0.um, 0.21.um).ext_interacting(Cont_not_outside_PAct, inverted: true)
+ drcErrA = Abut_PWell_Tie.ext_not(sizedA)
+ drcErrA_Edge = drcErrA.ext_coincident_part(sizedA, outside: true)
+ drcErrA_Poly = drcErrA.ext_with_coincident_edges(drcErrA_Edge)
+ drcErrA_Poly.ext_interacting(Cont_not_outside_PAct, inverted: true)
+end.().output("LU.c1", "Max. extension of an abutted substrate tie beyond Cont = 6.00")
+-> (;sizedA, tmp, drcErrA, drcErrA_Edge) do
+ sizedA = size_Cont.dup
+ tmp = NAct_NWell.outside(scr1).ext_interacting(Activ.ext_interacting(GatPoly), inverted: true)
+ drcErrA = tmp.ext_not(sizedA)
+ drcErrA_Edge = drcErrA.ext_coincident_part(sizedA, outside: true)
+ drcErrA.ext_with_coincident_edges(drcErrA_Edge)
+end.().output("LU.d", "Max. extension of NWell tie Activ tie beyond Cont = 6.00")
+-> (;sizedA, drcErrA, drcErrA_Edge) do
+ sizedA = Cont.ext_enlarge_inside(Act_connect, 6.0.um, 0.21.um)
+ drcErrA = PWell_Tie_wo_varicap_abut.ext_not(sizedA).ext_not(GatPoly)
+ drcErrA_Edge = drcErrA.ext_coincident_part(sizedA, outside: true)
+ drcErrA.ext_with_coincident_edges(drcErrA_Edge)
+end.().output("LU.d1", "Max. extension of an substrate tie Activ beyond Cont = 6.00")
+-> do
+ Metal1_slit_not_pad.ext_fast_width(2.8.um)
+end.().output("Slt.a.M1", "Min. Metal1:slit width = 2.80")
+-> (;tmp) do
+ tmp = Metal1_slit_not_pad.ext_with_length([[">", 20.0.um]])
+ Metal1_slit.ext_with_coincident_edges(tmp)
+end.().output("Slt.b.M1", "Max. Metal1:slit width = 20.00")
+-> (;m1mitSlots, m1_L1, m1_L2) do
+ m1mitSlots = sltc_M1.ext_not(Metal1_slit)
+ m1_L1 = m1mitSlots.sized(-3.0.um, acute_limit)
+ m1_L2 = m1_L1.sized(-12.0.um, acute_limit)
+ m1_L2.sized(15.0.um, acute_limit)
+end.().output("Slt.c.M1", "Max. Metal1 width without requiring a slit = 30.00")
-> do
Metal1_slit.ext_and(pad)
end.().output("Slt.e.M1", "No slits required on bond pads")
-> do
- Metal1_slit.ext_not(pad).ext_fast_separation(Cont, 300)
- Metal1_slit.ext_not(pad).ext_fast_separation(Via1, 300)
-end.().output("Slt.h1", "Min. Metal1:slit space to Cont and Via1")
--> do
- Metal2_slit.ext_not(pad).ext_fast_width(2800)
-end.().output("Slt.a.M2", "Min. Metal2:slit width")
+ Metal1_slit_not_pad.ext_fast_enclosed(Metal1, 1.0.um, polygon_output: true)
+end.().output("Slt.f.M1", "Min. Metal1 enclosure of Metal1:slit = 1.00")
+-> do
+ [ Metal1_slit_not_pad.ext_fast_separation(Cont, 0.3.um),
+ Metal1_slit_not_pad.ext_fast_separation(Via1, 0.3.um)
+ ].each { |result| result.output("Slt.h1", "Min. Metal1:slit space to Cont and Via1 = 0.30") }
+end.()
+-> do
+ Metal2_slit_not_pad.ext_fast_width(2.8.um)
+end.().output("Slt.a.M2", "Min. Metal2:slit width = 2.80")
+-> (;tmp) do
+ tmp = Metal2_slit_not_pad.ext_with_length([[">", 20.0.um]])
+ Metal2_slit.ext_with_coincident_edges(tmp)
+end.().output("Slt.b.M2", "Max. Metal2:slit width = 20.00")
+-> (;m2mitSlots, m2_L1, m2_L2) do
+ m2mitSlots = sltc_M2.ext_not(Metal2_slit)
+ m2_L1 = m2mitSlots.sized(-3.0.um, acute_limit)
+ m2_L2 = m2_L1.sized(-12.0.um, acute_limit)
+ m2_L2.sized(15.0.um, acute_limit)
+end.().output("Slt.c.M2", "Max. Metal2 width without requiring a slit = 30.00")
-> do
Metal2_slit.ext_and(pad)
end.().output("Slt.e.M2", "No slits required on bond pads")
-> do
- Metal2_slit.ext_not(pad).ext_fast_separation(Via1, 300)
- Metal2_slit.ext_not(pad).ext_fast_separation(Via2, 300)
-end.().output("Slt.h2.M2", "Min. Metal2:slit space to Via1 and Via2")
--> do
- Metal3_slit.ext_not(pad).ext_fast_width(2800)
-end.().output("Slt.a.M3", "Min. Metal3:slit width")
+ Metal2_slit_not_pad.ext_fast_enclosed(Metal2, 1.0.um, polygon_output: true)
+end.().output("Slt.f.M2", "Min. Metal2 enclosure of Metal2:slit = 1.00")
+-> do
+ [ Metal2_slit_not_pad.ext_fast_separation(Via1, 0.3.um),
+ Metal2_slit_not_pad.ext_fast_separation(Via2, 0.3.um)
+ ].each { |result| result.output("Slt.h2.M2", "Min. Metal2:slit space to Via1 and Via2 = 0.30") }
+end.()
+-> do
+ Metal3_slit_not_pad.ext_fast_width(2.8.um)
+end.().output("Slt.a.M3", "Min. Metal3:slit width = 2.80")
+-> (;tmp) do
+ tmp = Metal3_slit_not_pad.ext_with_length([[">", 20.0.um]])
+ Metal3_slit.ext_with_coincident_edges(tmp)
+end.().output("Slt.b.M3", "Max. Metal3:slit width = 20.00")
+-> (;m3mitSlots, m3_L1, m3_L2) do
+ m3mitSlots = sltc_M3.ext_not(Metal3_slit)
+ m3_L1 = m3mitSlots.sized(-3.0.um, acute_limit)
+ m3_L2 = m3_L1.sized(-12.0.um, acute_limit)
+ m3_L2.sized(15.0.um, acute_limit)
+end.().output("Slt.c.M3", "Max. Metal3 width without requiring a slit = 30.00")
-> do
Metal3_slit.ext_and(pad)
end.().output("Slt.e.M3", "No slits required on bond pads")
-> do
- Metal3_slit.ext_not(pad).ext_fast_separation(Via2, 300)
- Metal3_slit.ext_not(pad).ext_fast_separation(Via3, 300)
-end.().output("Slt.h2.M3", "Min. Metal3:slit space to Via2 and Via3")
--> do
- Metal4_slit.ext_not(pad).ext_fast_width(2800)
-end.().output("Slt.a.M4", "Min. Metal4:slit width")
+ Metal3_slit_not_pad.ext_fast_enclosed(Metal3, 1.0.um, polygon_output: true)
+end.().output("Slt.f.M3", "Min. Metal3 enclosure of Metal2:slit = 1.00")
+-> do
+ [ Metal3_slit_not_pad.ext_fast_separation(Via2, 0.3.um),
+ Metal3_slit_not_pad.ext_fast_separation(Via3, 0.3.um)
+ ].each { |result| result.output("Slt.h2.M3", "Min. Metal3:slit space to Via2 and Via3 = 0.30") }
+end.()
+-> do
+ Metal4_slit_not_pad.ext_fast_width(2.8.um)
+end.().output("Slt.a.M4", "Min. Metal4:slit width = 2.80")
+-> (;tmp) do
+ tmp = Metal4_slit_not_pad.ext_with_length([[">", 20.0.um]])
+ Metal4_slit.ext_with_coincident_edges(tmp)
+end.().output("Slt.b.M4", "Max. Metal4:slit width = 20.00")
+-> (;m4mitSlots, m4_L1, m4_L2) do
+ m4mitSlots = sltc_M4.ext_not(Metal4_slit)
+ m4_L1 = m4mitSlots.sized(-3.0.um, acute_limit)
+ m4_L2 = m4_L1.sized(-12.0.um, acute_limit)
+ m4_L2.sized(15.0.um, acute_limit)
+end.().output("Slt.c.M4", "Max. Metal4 width without requiring a slit = 30.00")
-> do
Metal4_slit.ext_and(pad)
end.().output("Slt.e.M4", "No slits required on bond pads")
-> do
- Metal4_slit.ext_not(pad).ext_fast_separation(Via3, 300)
- Metal4_slit.ext_not(pad).ext_fast_separation(Via4, 300)
-end.().output("Slt.h2.M4", "Min. Metal4:slit space to Via3 and Via4")
--> do
- Metal5_slit.ext_not(pad).ext_fast_width(2800)
-end.().output("Slt.a.M5", "Min. Metal5:slit width")
+ Metal4_slit_not_pad.ext_fast_enclosed(Metal4, 1.0.um, polygon_output: true)
+end.().output("Slt.f.M4", "Min. Metal4 enclosure of Metal4:slit = 1.00")
+-> do
+ [ Metal4_slit_not_pad.ext_fast_separation(Via3, 0.3.um),
+ Metal4_slit_not_pad.ext_fast_separation(Via4, 0.3.um)
+ ].each { |result| result.output("Slt.h2.M4", "Min. Metal4:slit space to Via3 and Via4 = 0.30") }
+end.()
+-> do
+ Metal5_slit_not_pad.ext_fast_width(2.8.um)
+end.().output("Slt.a.M5", "Min. Metal5:slit width = 2.80")
+-> (;tmp) do
+ tmp = Metal5_slit_not_pad.ext_with_length([[">", 20.0.um]])
+ Metal5_slit.ext_with_coincident_edges(tmp)
+end.().output("Slt.b.M5", "Max. Metal5:slit width = 20.00")
+-> (;m5mitSlots, m5_L1, m5_L2) do
+ m5mitSlots = sltc_M5.ext_not(Metal5_slit)
+ m5_L1 = m5mitSlots.sized(-3.0.um, acute_limit)
+ m5_L2 = m5_L1.sized(-12.0.um, acute_limit)
+ m5_L2.sized(15.0.um, acute_limit)
+end.().output("Slt.c.M5", "Max. Metal5 width without requiring a slit = 30.00")
-> do
Metal5_slit.ext_and(pad)
end.().output("Slt.e.M5", "No slits required on bond pads")
-> do
- Metal5_slit.ext_not(pad).ext_fast_separation(Via4, 300)
- Metal5_slit.ext_not(pad).ext_fast_separation(TopVia1, 300)
-end.().output("Slt.h2.M5", "Min. Metal5:slit space to Via4 and Via5")
--> do
- TopMetal1_slit.ext_not(pad).ext_fast_width(2800)
-end.().output("Slt.a.TM1", "Min. TopMetal1:slit width")
+ Metal5_slit_not_pad.ext_fast_enclosed(Metal5, 1.0.um, polygon_output: true)
+end.().output("Slt.f.M5", "Min. Metal5 enclosure of Metal5:slit = 1.00")
+-> do
+ Metal5_slit_MIM_Slt_g_M5_sep.dup
+end.().output("Slt.g.M5", "Min. Metal5:slit and TopMetal1:slit space to MIM = 0.60")
+-> do
+ [ Metal5_slit_not_pad.ext_fast_separation(Via4, 0.3.um),
+ Metal5_slit_not_pad.ext_fast_separation(TopVia1, 0.3.um)
+ ].each { |result| result.output("Slt.h2.M5", "Min. Metal5:slit space to Via4 and Via5 = 0.30") }
+end.()
+-> do
+ TopMetal1_slit_not_pad.ext_fast_width(2.8.um)
+end.().output("Slt.a.TM1", "Min. TopMetal1:slit width = 2.80")
+-> (;tmp) do
+ tmp = TopMetal1_slit_not_pad.ext_with_length([[">", 20.0.um]])
+ TopMetal1_slit.ext_with_coincident_edges(tmp)
+end.().output("Slt.b.TM1", "Max. TopMetal1:slit width = 20.00")
+-> (;tM1mitSlots, tM1_L1, tM1_L2) do
+ tM1mitSlots = sltc_TM1.ext_not(TopMetal1_slit)
+ tM1_L1 = tM1mitSlots.sized(-3.0.um, acute_limit)
+ tM1_L2 = tM1_L1.sized(-12.0.um, acute_limit)
+ tM1_L2.sized(15.0.um, acute_limit)
+end.().output("Slt.c.TM1", "Max. TopMetal1 width without requiring a slit = 30.00")
-> do
TopMetal1_slit.ext_and(pad)
end.().output("Slt.e.TM1", "No slits required on bond pads")
-> do
- TopMetal1_slit.ext_not(pad).ext_fast_separation(TopVia1, 1000)
-end.().output("Slt.h3", "Min. TopMetal1:slit space to TopVia1 and TopVia2")
+ TopMetal1_slit_not_pad.ext_fast_enclosed(TopMetal1, 1.0.um, polygon_output: true)
+end.().output("Slt.f.TM1", "Min. TopMetal1 enclosure of TopMetal1:slit = 1.00")
+-> do
+ TopMetal1_slit_MIM_Slt_g_TM1_sep.dup
+end.().output("Slt.g.TM1", "Min. Metal5:slit and TopMetal1:slit space to MIM = 0.60")
+-> do
+ TopMetal1_slit_not_pad.ext_fast_separation(TopVia1, 1.0.um)
+end.().output("Slt.h3", "Min. TopMetal1:slit space to TopVia1 and TopVia2 = 1.00")
-> do
- TopMetal2_slit.ext_not(pad).ext_fast_width(2800)
-end.().output("Slt.a.TM2", "Min. TopMetal2:slit width")
+ TopMetal2_slit_not_pad.ext_fast_width(2.8.um)
+end.().output("Slt.a.TM2", "Min. TopMetal2:slit width = 2.80")
+-> (;tmp) do
+ tmp = TopMetal2_slit_not_pad.ext_with_length([[">", 20.0.um]])
+ TopMetal2_slit.ext_with_coincident_edges(tmp)
+end.().output("Slt.b.TM2", "Max. TopMetal2:slit width = 20.00")
+-> (;tM2mitSlots, tM2_L1, tM2_L2) do
+ tM2mitSlots = sltc_TM2.ext_not(TopMetal2_slit)
+ tM2_L1 = tM2mitSlots.sized(-3.0.um, acute_limit)
+ tM2_L2 = tM2_L1.sized(-12.0.um, acute_limit)
+ tM2_L2.sized(15.0.um, acute_limit)
+end.().output("Slt.c.TM2", "Max. TopMetal2 width without requiring a slit = 30.00")
-> do
TopMetal2_slit.ext_and(pad)
end.().output("Slt.e.TM2", "No slits required on bond pads")
-> do
- TopMetal2_slit.ext_not(pad).ext_fast_separation(TopVia2, 1000)
-end.().output("Slt.h4", "Min. TopMetal2:slit space to TopVia2")
+ TopMetal2_slit_not_pad.ext_fast_enclosed(TopMetal2, 1.0.um, polygon_output: true)
+end.().output("Slt.f.TM2", "Min. TopMetal2 enclosure of TopMetal2:slit = 1.00")
+-> do
+ TopMetal2_slit_not_pad.ext_fast_separation(TopVia2, 1.0.um)
+end.().output("Slt.h4", "Min. TopMetal2:slit space to TopVia2 = 1.00")
if $sanityRules
-> do
Activ_pin.ext_not(Activ)
- end.().output("Pin.a", "Min. Activ enclosure of Activ:pin")
+ end.().output("Pin.a", "Min. Activ enclosure of Activ:pin = 0.00")
-> do
GatPoly_pin.ext_not(GatPoly)
- end.().output("Pin.b", "Min. GatPoly enclosure of GatPoly:pin")
+ end.().output("Pin.b", "Min. GatPoly enclosure of GatPoly:pin = 0.00")
-> do
Metal1_pin.ext_not(Metal1)
- end.().output("Pin.e", "Min. Metal1 enclosure of Metal1:pin")
+ end.().output("Pin.e", "Min. Metal1 enclosure of Metal1:pin = 0.00")
-> do
Metal2_pin.ext_not(Metal2)
- end.().output("Pin.f.M2", "Min. Metal2 enclosure of Metal2:pin")
+ end.().output("Pin.f.M2", "Min. Metal2 enclosure of Metal2:pin = 0.00")
-> do
Metal3_pin.ext_not(Metal3)
- end.().output("Pin.f.M3", "Min. Metal3 enclosure of Metal3:pin")
+ end.().output("Pin.f.M3", "Min. Metal3 enclosure of Metal3:pin = 0.00")
-> do
Metal4_pin.ext_not(Metal4)
- end.().output("Pin.f.M4", "Min. Metal4 enclosure of Metal4:pin")
+ end.().output("Pin.f.M4", "Min. Metal4 enclosure of Metal4:pin = 0.00")
-> do
Metal5_pin.ext_not(Metal5)
- end.().output("Pin.f.M5", "Min. Metal5 enclosure of Metal5:pin")
+ end.().output("Pin.f.M5", "Min. Metal5 enclosure of Metal5:pin = 0.00")
-> do
TopMetal1_pin.ext_not(TopMetal1)
- end.().output("Pin.g", "Min. TopMetal1 enclosure of TopMetal1:pin")
+ end.().output("Pin.g", "Min. TopMetal1 enclosure of TopMetal1:pin = 0.00")
-> do
TopMetal2_pin.ext_not(TopMetal2)
- end.().output("Pin.h", "Min. TopMetal2 enclosure of TopMetal2:pin")
+ end.().output("Pin.h", "Min. TopMetal2 enclosure of TopMetal2:pin = 0.00")
end
-> do
- NWell.ext_fast_separation(NActHV_digi, 310)
-end.().output("NW.d1.dig", "Min. NWell space to external N+Activ inside ThickGateOx")
+ NWell.ext_fast_separation(NActHV_digi, 0.31.um)
+end.().output("NW.d1.dig", "Min. NWell space to external N+Activ inside ThickGateOx = 0.31")
-> do
- NWell.ext_fast_separation(PAct_PWellHV_digi, 240)
-end.().output("NW.f1.dig", "Min. NWell space to substrate tie in P+Activ inside ThickGateOx")
+ NWell.ext_fast_separation(PAct_PWellHV_digi, 0.24.um)
+end.().output("NW.f1.dig", "Min. NWell space to substrate tie in P+Activ inside ThickGateOx = 0.24")
-> do
GP_SRAM_Gat_a_SRAM.dup
-end.().output("Gat.a.SRAM", "Min. GatPoly width")
+end.().output("Gat.a.SRAM", "Min. GatPoly width = 0.069")
-> do
GP_SRAM_Gat_b_SRAM.dup
-end.().output("Gat.b.SRAM", "Min. GatPoly space or notch")
+end.().output("Gat.b.SRAM", "Min. GatPoly space or notch = 0.149")
+-> do
+ Activ.ext_fast_enclosed(GP_SRAM, 0.079.um, polygon_output: true)
+end.().output("Gat.c.SRAM", "Min. GatPoly extension over Activ (end cap) = 0.079")
-> do
- GP_SRAM.ext_fast_separation(Act_SRAM, 29)
-end.().output("Gat.d.SRAM", "Min. GatPoly space to Activ")
+ GP_SRAM.ext_fast_separation(Act_SRAM, 0.029.um)
+end.().output("Gat.d.SRAM", "Min. GatPoly space to Activ = 0.029")
-> (;layA, layB, layC, layD) do
- layA = Activ.ext_and(SRAM).merged(true, 0).not_inside(pSD).ext_interacting(pSD)
+ layA = Activ.ext_and(SRAM).not_inside(pSD).ext_interacting(pSD)
layB = layA.ext_and(pSD)
- layC = layB.ext_fast_width(280, polygon_output: true)
+ layC = layB.ext_fast_width(0.28.um, polygon_output: true)
layD = layC.ext_covering(layB)
layD.dup
-end.().output("pSD.e.SRAM", "Min. pSD overlap of Activ when forming abutted substrate tie")
--> do
- pSD_SRAM.ext_fast_separation(NGate.merged(true, 0).outside(SVaricap), 239)
-end.().output("pSD.j.SRAM", "Min. pSD space to NFET gate not inside ThickGateOx")
--> do
- Cont_Act.ext_fast_separation(GP_SRAM, 59)
-end.().output("Cnt.f.SRAM", "Min. Cont on Activ space to GatPoly")
--> do
- M1_SRAM.ext_fast_space(159)
-end.().output("M1.b.SRAM", "Min. Metal1 space or notch")
--> do
- M2_SRAM.ext_fast_space(169)
-end.().output("M2.b.SRAM", "Min. Metal2 space or notch")
--> do
- M3_SRAM.ext_fast_space(169)
-end.().output("M3.b.SRAM", "Min. Metal3 space or notch")
--> do
- M4_SRAM.ext_fast_space(169)
-end.().output("M4.b.SRAM", "Min. Metal4 space or notch")
--> do
- M5_SRAM.ext_fast_space(169)
-end.().output("M5.b.SRAM", "Min. Metal5 space or notch")
--> do
- LBE.ext_fast_width(100000)
-end.().output("LBE.a", "Min. LBE width")
--> do
- LBE.drc((width(projection) > 1500000).polygons)
-end.().output("LBE.b", "Max. LBE width")
--> do
- LBE.ext_area([[">", 250000.0]])
-end.().output("LBE.b1", "Max. LBE area (µm²)")
--> do
- LBE.ext_area([["<", 250000.0]])
-end.().output("LBE.b2", "Min. LBE area (µm²)")
--> do
- LBE.ext_fast_space(100000)
-end.().output("LBE.c", "Min. LBE space or notch")
+end.().output("pSD.e.SRAM", "Min. pSD overlap of Activ when forming abutted substrate tie = 0.28")
+-> (;x, y) do
+ x = abut_tie_edge_NWell.ext_inside_part(SRAM)
+ y = abut_tie_edge_PWell.ext_inside_part(SRAM)
+ [ x.ext_with_length([["<", 0.15.um]]),
+ y.ext_with_length([["<", 0.15.um]])
+ ].each { |result| result.output("pSD.g.SRAM", "Min. N+Activ or P+Activ width when forming abutted tie = 0.15") }
+end.()
+-> do
+ PGate.ext_fast_enclosed(pSD_SRAM, 0.068.um, polygon_output: true)
+end.().output("pSD.i.SRAM", "Min. pSD enclosure of PFET gate not inside ThickGateOx = 0.068")
+-> do
+ pSD_SRAM.ext_fast_separation(NGate_outside_SVaricap, 0.239.um)
+end.().output("pSD.j.SRAM", "Min. pSD space to NFET gate not inside ThickGateOx = 0.239")
+-> do
+ Cont_Act.ext_fast_separation(GP_SRAM, 0.059.um)
+end.().output("Cnt.f.SRAM", "Min. Cont on Activ space to GatPoly = 0.059")
+-> do
+ M1_SRAM.ext_fast_space(0.159.um)
+end.().output("M1.b.SRAM", "Min. Metal1 space or notch = 0.159")
+-> do
+ Cont_SRAM.outside(EdgeSeal).drc(if_any(
+ !rectangles,
+ primary-secondary(M1_SRAM_outside_EdgeSeal),
+ ((enclosed(M1_SRAM_outside_EdgeSeal, projection, whole_edges, one_side_allowed, two_opposite_sides_allowed) < 0.005.um))))
+end.().output("M1.c1.SRAM", "Min. Metal1 endcap enclosure of Cont = 0.005")
+-> do
+ M2_SRAM.ext_fast_space(0.169.um)
+end.().output("M2.b.SRAM", "Min. Metal2 space or notch = 0.169")
+-> do
+ V1_SRAM_outside_EdgeSeal.drc(if_any(
+ !rectangles,
+ primary-secondary(M2_SRAM.outside(EdgeSeal)),
+ ((enclosed(M2_SRAM.outside(EdgeSeal), projection, whole_edges, one_side_allowed, two_opposite_sides_allowed) < 0.02.um))))
+end.().output("M2.c1.SRAM", "Min. Metal2 endcap enclosure of Via1 = 0.02")
+-> do
+ M3_SRAM.ext_fast_space(0.169.um)
+end.().output("M3.b.SRAM", "Min. Metal3 space or notch = 0.169")
+-> do
+ V2_SRAM_outside_EdgeSeal.drc(if_any(
+ !rectangles,
+ primary-secondary(M3_SRAM.outside(EdgeSeal)),
+ ((enclosed(M3_SRAM.outside(EdgeSeal), projection, whole_edges, one_side_allowed, two_opposite_sides_allowed) < 0.02.um))))
+end.().output("M3.c1.SRAM", "Min. Metal3 endcap enclosure of Via2 = 0.02")
+-> do
+ M4_SRAM.ext_fast_space(0.169.um)
+end.().output("M4.b.SRAM", "Min. Metal4 space or notch = 0.169")
+-> do
+ V3_SRAM_outside_EdgeSeal.drc(if_any(
+ !rectangles,
+ primary-secondary(M4_SRAM.outside(EdgeSeal)),
+ ((enclosed(M4_SRAM.outside(EdgeSeal), projection, whole_edges, one_side_allowed, two_opposite_sides_allowed) < 0.02.um))))
+end.().output("M4.c1.SRAM", "Min. Metal4 endcap enclosure of Via3 = 0.02")
+-> do
+ M5_SRAM.ext_fast_space(0.169.um)
+end.().output("M5.b.SRAM", "Min. Metal5 space or notch = 0.169")
+-> do
+ V4_SRAM_outside_EdgeSeal.drc(if_any(
+ !rectangles,
+ primary-secondary(M5_SRAM.outside(EdgeSeal)),
+ ((enclosed(M5_SRAM.outside(EdgeSeal), projection, whole_edges, one_side_allowed, two_opposite_sides_allowed) < 0.02.um))))
+end.().output("M5.c1.SRAM", "Min. Metal5 endcap enclosure of Via4 = 0.02")
+-> do
+ LBE.ext_fast_width(100.0.um)
+end.().output("LBE.a", "Min. LBE width = 100.00")
+-> do
+ LBE.drc((width(projection) > 1500.0.um).polygons)
+end.().output("LBE.b", "Max. LBE width = 1500.00")
+-> do
+ LBE.ext_with_area([[">", 250000.0.um2]])
+end.().output("LBE.b1", "Max. LBE area (µm²) = 250000.00")
+-> do
+ LBE.ext_with_area([["<", 250000.0.um2]])
+end.().output("LBE.b2", "Min. LBE area (µm²) = 30000.00")
+-> do
+ LBE.ext_fast_space(100.0.um)
+end.().output("LBE.c", "Min. LBE space or notch = 100.00")
-> (;lbe_in_seal) do
- lbe_in_seal = LBE.merged(true, 0).inside(EdgeSeal.holes.merge)
- lbe_in_seal.ext_fast_separation(EdgeSeal, 150000)
-end.().output("LBE.d", "Min. LBE space to inner edge of EdgeSeal")
+ lbe_in_seal = LBE.inside(EdgeSeal.holes.merge)
+ lbe_in_seal.ext_fast_separation(EdgeSeal, 150.0.um)
+end.().output("LBE.d", "Min. LBE space to inner edge of EdgeSeal = 150.00")
-> do
- LBE.ext_fast_separation(dfpad, 50000)
-end.().output("LBE.e.dfPad", "Min. LBE space to dfpad and Passiv")
+ LBE.ext_fast_separation(dfpad, 50.0.um)
+end.().output("LBE.e.dfPad", "Min. LBE space to dfpad and Passiv = 50.00")
-> do
- LBE.ext_fast_separation(Passiv, 50000)
-end.().output("LBE.e.Passiv", "Min. LBE space to dfpad and Passiv")
+ LBE.ext_fast_separation(Passiv, 50.0.um)
+end.().output("LBE.e.Passiv", "Min. LBE space to dfpad and Passiv = 50.00")
-> do
- LBE.ext_fast_separation(Activ, 30000)
-end.().output("LBE.f", "Min. LBE space to Activ")
+ LBE.ext_fast_separation(Activ, 30.0.um)
+end.().output("LBE.f", "Min. LBE space to Activ = 30.00")
-> do
- LBE.ext_ring.dup
+ LBE.with_holes.dup
end.().output("LBE.h", "No LBE ring allowed")
if $density
-> do
LBE.ext_with_density(0.2 .. 1.0, 'll')
- end.().output("LBE.i", "Max. global LBE density [%]")
+ end.().output("LBE.i", "Max. global LBE density [%] = 20.00")
+end
+
+-> do
+ bad_tsv.dup
+end.().output("TSV_G.a", "DeepVia has to be a ring structure")
+-> do
+ tsv_fill_TSV_G_d.dup
+end.().output("TSV_G.d", "Min. DeepVia space = 25.00")
+-> do
+ PWell_block_tsvOutRing_enc.dup
+end.().output("TSV_G.f", "Min. PWell:block enclosure of DeepVia = 2.50")
+-> do
+ Metal1_tsvOutRing_enc.dup
+end.().output("TSV_G.g", "Min. Metal1 enclosure of DeepVia ring structure = 1.50")
+
+if $checkDensityRules
+ -> do
+ tsv.ext_with_density(0.0 .. 0.0001, 'll')
+ end.().output("TSV_G.i", "Max. global DeepVia density [%] = 1.00")
+ -> do
+ tsv.ext_with_density(0.001 .. 1.0, 'll')
+ end.().output("TSV_G.j", "Max. DeepVia coverage ratio for any 500.0 x 500.0 µm² chip area [%] = 10.00")
end
if $sanityRules
-> do
BiWind.dup
- end.().output("forbidden.BiWind", "Forbidden drawn layer BiWind on GDS layer 3/0")
+ end.().output("forbidden.BiWind", "Forbidden drawn layer BiWind on GDS layer 3/0 = 3/0")
-> do
PEmWind.dup
- end.().output("forbidden.PEmWind", "Forbidden drawn layer PEmWind on GDS layer 11/0")
+ end.().output("forbidden.PEmWind", "Forbidden drawn layer PEmWind on GDS layer 11/0 = 11/0")
-> do
BasPoly.dup
- end.().output("forbidden.BasPoly", "Forbidden drawn layer BasPoly on GDS layer 13/0")
+ end.().output("forbidden.BasPoly", "Forbidden drawn layer BasPoly on GDS layer 13/0 = 13/0")
-> do
DeepCo.dup
- end.().output("forbidden.DeepCo", "Forbidden drawn layer DeepCo on GDS layer 35/0")
+ end.().output("forbidden.DeepCo", "Forbidden drawn layer DeepCo on GDS layer 35/0 = 35/0")
-> do
PEmPoly.dup
- end.().output("forbidden.PEmPoly", "Forbidden drawn layer PEmPoly on GDS layer 53/0")
+ end.().output("forbidden.PEmPoly", "Forbidden drawn layer PEmPoly on GDS layer 53/0 = 53/0")
-> do
EmPoly.dup
- end.().output("forbidden.EmPoly", "Forbidden gen./drawn layer EmPoly on GDS layer 53/0")
+ end.().output("forbidden.EmPoly", "Forbidden gen./drawn layer EmPoly on GDS layer 53/0 = 53/0")
-> do
LDMOS.dup
- end.().output("forbidden.LDMOS", "Forbidden drawn layer LDMOS on GDS layer 57/0")
+ end.().output("forbidden.LDMOS", "Forbidden drawn layer LDMOS on GDS layer 57/0 = 57/0")
-> do
PBiWind.dup
- end.().output("forbidden.PBiWind", "Forbidden drawn layer PBiWind on GDS layer 58/0")
+ end.().output("forbidden.PBiWind", "Forbidden drawn layer PBiWind on GDS layer 58/0 = 58/0")
-> do
Flash.dup
- end.().output("forbidden.Flash", "Forbidden drawn layer Flash on GDS layer 71/0")
+ end.().output("forbidden.Flash", "Forbidden drawn layer Flash on GDS layer 71/0 = 71/0")
-> do
ColWind.dup
- end.().output("forbidden.ColWind", "Forbidden drawn layer ColWind on GDS layer 139/0")
+ end.().output("forbidden.ColWind", "Forbidden drawn layer ColWind on GDS layer 139/0 = 139/0")
end
@@ -1892,5 +2800,7 @@ if $offGrid
PolyRes.ongrid(5)
end.().output("OffGrid.PolyRes", "PolyRes is off-grid")
end
+
+puts("Number of DRC errors: #{$drc_error_count}")
diff --git a/ihp-sg13g2/libs.tech/klayout/tech/drc/sg13g2_minimal.lydrc b/ihp-sg13g2/libs.tech/klayout/tech/drc/sg13g2_minimal.lydrc
index 287b8ee3..277b4815 100644
--- a/ihp-sg13g2/libs.tech/klayout/tech/drc/sg13g2_minimal.lydrc
+++ b/ihp-sg13g2/libs.tech/klayout/tech/drc/sg13g2_minimal.lydrc
@@ -30,14 +30,14 @@
dsl
drc-dsl-xml
# Supported variables that can be set using "-rd <name>=<value>" on the command line:
-# logfile - path to the log file [default: no log file]
-# gdsfile - path to the GDS layout to check (required in batch mode)
-# cell - name of the cell to check (required in batch mode)
-# outfile - path to the report database [default: sg13g2_minimal.lyrdb in the script directory]
+# log_file - path to the log file [default: no log file]
+# in_gds - path to the GDS layout to check (required in batch mode)
+# cell - name of the cell to check
+# report_file - path to the report database [default: sg13g2_minimal.lyrdb in the script directory]
# to set logfile: -rd logfile="sg13g2_minimal.log"
-if $logfile
- log_file($logfile)
+if $log_file
+ log_file($log_file)
end
application = RBA::Application.instance
@@ -49,30 +49,27 @@ if main_window
main_window.load_layout(layout_path, 1)
curr_layout_view = main_window.current_view()
end
+ active_layout = RBA::CellView::active.layout
active_cellname = RBA::CellView::active.cell_name
+ source(active_layout, active_cellname)
else
log("DRC: batch mode")
+ # to set input layout: -rd in_gds="path to GDS file"
# to set cell: -rd cell="topcell"
if $cell
active_cellname = $cell
log("Active cell: " + active_cellname)
+ source($in_gds, active_cellname)
+ active_layout = source.layout
else
- raise("'cell' script variable must be defined on command line")
+ source($in_gds)
+ active_layout = source.layout
+ active_cellname = source.cell_name
end
end
-active_layout = RBA::CellView::active.layout
-
-unless active_layout or $gdsfile
- raise("layout file must be defined on command line or via 'gdsfile' script variable")
-end
-
-# to set input layout: -rd gdsfile="path to GDS file"
-if $gdsfile
- source($gdsfile, active_cellname)
- active_layout = source.layout
-else
- source(active_layout, active_cellname)
+unless active_layout or $in_gds
+ raise("layout file must be defined on command line or via 'in_gds' script variable")
end
if active_layout.dbu != 0.001
@@ -80,14 +77,28 @@ if active_layout.dbu != 0.001
end
report_file = __dir__ + "/sg13g2_minimal.lyrdb"
-# to set report file: -rd outfile="sg13g2_minimal.lyrdb"
-if $outfile
- report_file = File.expand_path($outfile)
+# to set report file: -rd report_file="sg13g2_minimal.lyrdb"
+if $report_file
+ report_file = File.expand_path($report_file)
end
+
report("design rules: sg13g2_minimal | layout cell: " + active_cellname, report_file)
deep
+$drc_error_count = 0
+
+class DRC::DRCLayer
+ unless method_defined?(:original_output)
+ alias_method :original_output, :output
+ end
+
+ def output(*args)
+ $drc_error_count += self.count()
+ original_output(*args)
+ end
+end
+
# Initial definitions of control flow variables
# Strings from the command line have to be converted
if defined? $density
@@ -113,28 +124,35 @@ class DRC::DRCLayer
return output_layer
end
- def ext_area(constraint)
- output_layer = self.dup
+ def ext_with_area(constraint)
+ lower_bound = nil
+ upper_bound = nil
+ output_layer = nil
+ self_min_coherence_state = self.data.min_coherence?
+ self.data.min_coherence = true
constraint.each do |expression|
- output_layer.data.min_coherence = true
relation = expression[0]
value = expression[1]
if relation == ">"
- output_layer = output_layer.with_area((value + @engine.dbu), nil)
+ lower_bound = value + 1e-6
elsif relation == "<"
- output_layer = output_layer.with_area(nil, value)
+ upper_bound = value
elsif relation == "=="
- output_layer = output_layer.with_area(value)
+ output_layer = self.with_area(value)
elsif relation == "!="
- output_layer = output_layer.without_area(value)
+ output_layer = self.without_area(value)
elsif relation == ">="
- output_layer = output_layer.with_area(value, nil)
+ lower_bound = value
elsif relation == "<="
- output_layer = output_layer.with_area(nil, (value + @engine.dbu))
+ upper_bound = value + 1e-6
else
raise "invalid expression"
end
end
+ if lower_bound or upper_bound
+ output_layer = self.with_area(lower_bound, upper_bound)
+ end
+ self.data.min_coherence = self_min_coherence_state
return output_layer
end
@@ -197,12 +215,18 @@ class DRC::DRCLayer
return output_layer
end
- def ext_or(other)
+ def ext_or(other, *further_layers)
self_min_coherence_state = self.data.min_coherence?
other_min_coherence_state = other.data.min_coherence?
self.data.min_coherence = true
other.data.min_coherence = true
output_layer = self.join(other)
+ further_layers.each do |further_layer|
+ further_layer_min_coherence_state = further_layer.data.min_coherence?
+ further_layer.data.min_coherence = true
+ output_layer = output_layer.join(further_layer)
+ further_layer.data.min_coherence = further_layer_min_coherence_state
+ end
self.data.min_coherence = self_min_coherence_state
other.data.min_coherence = other_min_coherence_state
return output_layer
@@ -266,14 +290,6 @@ class DRC::DRCLayer
end
end
- def ext_ring
- holes = self.holes
- hulls = self.hulls
- covering = hulls.covering(holes)
- result = covering.and(self)
- return result
- end
-
def ext_interacting_with_text(text_layer, text)
if text_layer.is_a? Integer
text_layer = @engine.labels(text_layer)
@@ -315,20 +331,26 @@ class DRC::DRCLayer
if origin == 'll'
origin_x = bbox.left
origin_y = bbox.bottom
+ if tile_size and tile_step and (tile_size.get[0] != tile_step.get[0] or tile_size.get[1] != tile_step.get[1])
+ origin_x = bbox.left + tile_step.get[0]/2
+ origin_y = bbox.bottom + tile_step.get[1]/2
+ end
tile_origin = DRC::DRCTileOrigin::new(origin_x, origin_y)
arguments.push(tile_origin)
elsif origin != 'cc'
raise "Unknown origin: 'cc' or 'll' expected"
end
if tile_size
- return merged_layer.with_density(*arguments)
+ boundary_layer = DRC::DRCLayer::new(@engine, RBA::Region::new(bbox.to_itype(@engine.dbu)))
+ tile_boundary = DRC::DRCTileBoundary::new(boundary_layer)
+ return merged_layer.with_density(*arguments, tile_boundary, @engine.padding_ignore)
else
tile_size = DRC::DRCTileSize::new(bbox.width, bbox.height)
tile_count = DRC::DRCTileCount::new(1,2)
enlarged_bbox = bbox.enlarged(1.1).to_itype(@engine.dbu)
boundary_layer = DRC::DRCLayer::new(@engine, RBA::Region::new(enlarged_bbox))
tile_boundary = DRC::DRCTileBoundary::new(boundary_layer)
- result = merged_layer.with_density(*arguments, tile_size, tile_count, tile_boundary)
+ result = merged_layer.with_density(*arguments, tile_size, tile_count, tile_boundary, @engine.padding_ignore)
return result.raw.overlapping(DRC::DRCLayer::new(@engine, RBA::Region::new(bbox.to_itype(@engine.dbu))))
end
end
@@ -360,8 +382,6 @@ Metal3 = source.polygons("30/0")
Metal3_pin = source.polygons("30/2")
Metal3_filler = source.polygons("30/22")
Metal3_slit = source.polygons("30/24")
-NWell = source.polygons("31/0")
-NWell_pin = source.polygons("31/2")
DeepCo = source.polygons("35/0")
EdgeSeal = source.polygons("39/0")
ThickGateOx = source.polygons("44/0")
@@ -399,19 +419,27 @@ if $sanityRules
Flash = source.polygons("71/0")
end
-Activ_Act_a = Activ.ext_fast_width(150)
+Activ_Act_a = Activ.ext_fast_width(0.15.um)
Act_density = Activ.ext_or(Activ_filler)
Gat_density = GatPoly.ext_or(GatPoly_filler)
-Cont_SQ = Cont.ext_rectangles(true, false, [["==", 160]], [["==", 160]], nil)
-ContBar = Cont.ext_area([[">", 0.16*0.16]])
+Cont_SQ = Cont.ext_rectangles(true, false, [["==", 0.16.um]], [["==", 0.16.um]], nil)
+ContBar = Cont.ext_with_area([[">", (0.16*0.16).um2]])
Act_Nsram = Activ.ext_not(SRAM)
GP_Nsram = GatPoly.ext_not(SRAM)
M1_Nsram = Metal1.ext_not(SRAM)
M2_Nsram = Metal2.ext_not(SRAM)
M3_Nsram = Metal3.ext_not(SRAM)
-ThickGateOx_TGO_f = ThickGateOx.ext_fast_width(860, polygon_output: true)
+Via1_edgC1_out = Via1.ext_not(EdgeSeal)
+Via2_edgC1_out = Via2.ext_not(EdgeSeal)
+Cont_outside_EdgeSeal = Cont.outside(EdgeSeal)
+ThickGateOx_TGO_f = ThickGateOx.ext_fast_width(0.86.um, polygon_output: true)
+Via3_edgC1_out = Via3.ext_not(EdgeSeal)
M4_Nsram = Metal4.ext_not(SRAM)
+Via4_edgC1_out = Via4.ext_not(EdgeSeal)
M5_Nsram = Metal5.ext_not(SRAM)
+TopVia1_edgC1_out = TopVia1.ext_not(EdgeSeal)
+TopVia1_or_Vmim = TopVia1.ext_or(Vmim)
+TopVia2_edgC1_out = TopVia2.ext_not(EdgeSeal)
M1_density = Metal1.ext_or(Metal1_filler).ext_not(Metal1_slit)
M2_density = Metal2.ext_or(Metal2_filler).ext_not(Metal2_slit)
emi2Pin = Metal2_pin.ext_and(TRANS).ext_interacting_with_text(TEXT_0, "E")
@@ -420,329 +448,331 @@ M4_density = Metal4.ext_or(Metal4_filler).ext_not(Metal4_slit)
M5_density = Metal5.ext_or(Metal5_filler).ext_not(Metal5_slit)
TM1_density = TopMetal1.ext_or(TopMetal1_filler).ext_not(TopMetal1_slit)
TM2_density = TopMetal2.ext_or(TopMetal2_filler).ext_not(TopMetal2_slit)
-GP_Nsram_Gat_a = GP_Nsram.ext_fast_width(130, polygon_output: true)
-GP_Nsram_Gat_b = GP_Nsram.ext_fast_space(180, polygon_output: true)
+GP_Nsram_Gat_a = GP_Nsram.ext_fast_width(0.13.um, polygon_output: true)
+GP_Nsram_Gat_b = GP_Nsram.ext_fast_space(0.18.um, polygon_output: true)
transG2L = TRANS.ext_interacting_with_text(TEXT_0, "npn13G2L").ext_covering(emi2Pin)
-> do
Activ_Act_a.dup
-end.().output("Act.a", "Min. Activ width")
+end.().output("Act.a", "Min. Activ width = 0.15")
-> do
- Act_Nsram.ext_fast_space(210)
-end.().output("Act.b", "Min. Activ space or notch")
+ Act_Nsram.ext_fast_space(0.21.um)
+end.().output("Act.b", "Min. Activ space or notch = 0.21")
if $density
-> do
Act_density.ext_with_density(0.0 .. 0.35, 'll')
- end.().output("AFil.g", "Min. global Activ density [%]")
+ end.().output("AFil.g", "Min. global Activ density [%] = 35.00")
-> do
Act_density.ext_with_density(0.55 .. 1.0, 'll')
- end.().output("AFil.g1", "Max. global Activ density [%]")
+ end.().output("AFil.g1", "Max. global Activ density [%] = 55.00")
-> do
- Act_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("AFil.g2", "Min. Activ coverage ratio for any 800 x 800 µm² chip area [%]")
+ Act_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0.um), tile_step(400.0.um))
+ end.().output("AFil.g2", "Min. Activ coverage ratio for any 800 x 800 µm² chip area [%] = 25.00")
-> do
- Act_density.ext_with_density(0.65 .. 1.0, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("AFil.g3", "Max. Activ coverage ratio for any 800 x 800 µm² chip area [%]")
+ Act_density.ext_with_density(0.65 .. 1.0, 'll', tile_size(800.0.um), tile_step(400.0.um))
+ end.().output("AFil.g3", "Max. Activ coverage ratio for any 800 x 800 µm² chip area [%] = 65.00")
end
-> do
ThickGateOx_TGO_f.dup
-end.().output("TGO.f", "Min. ThickGateOx width")
+end.().output("TGO.f", "Min. ThickGateOx width = 0.86")
-> do
GP_Nsram_Gat_a.dup
-end.().output("Gat.a", "Min. GatPoly width")
+end.().output("Gat.a", "Min. GatPoly width = 0.13")
-> do
GP_Nsram_Gat_b.dup
-end.().output("Gat.b", "Min. GatPoly space or notch")
+end.().output("Gat.b", "Min. GatPoly space or notch = 0.18")
-> do
- GP_Nsram.ext_fast_separation(Act_Nsram, 70)
-end.().output("Gat.d", "Min. GatPoly space to Activ")
+ GP_Nsram.ext_fast_separation(Act_Nsram, 0.07.um)
+end.().output("Gat.d", "Min. GatPoly space to Activ = 0.07")
if $density
-> do
Gat_density.ext_with_density(0.0 .. 0.15, 'll')
- end.().output("GFil.g", "Min. global GatPoly density [%]")
+ end.().output("GFil.g", "Min. global GatPoly density [%] = 15.00")
end
-> do
- Cont.merged(true, 0).outside(EdgeSeal).ext_not(ContBar.ext_or(Cont_SQ))
-end.().output("Cnt.a", "Min. and max. Cont width")
+ Cont_outside_EdgeSeal.ext_not(ContBar.ext_or(Cont_SQ))
+end.().output("Cnt.a", "Min. and max. Cont width = 0.16")
-> do
- Cont.merged(true, 0).outside(EdgeSeal).ext_fast_space(180)
-end.().output("Cnt.b", "Min. Cont space")
+ Cont_outside_EdgeSeal.ext_fast_space(0.18.um)
+end.().output("Cnt.b", "Min. Cont space = 0.18")
-> do
- Metal1.ext_fast_width(160)
-end.().output("M1.a", "Min. Metal1 width")
+ Metal1.ext_fast_width(0.16.um)
+end.().output("M1.a", "Min. Metal1 width = 0.16")
-> do
- M1_Nsram.ext_fast_space(180)
-end.().output("M1.b", "Min. Metal1 space or notch")
+ M1_Nsram.ext_fast_space(0.18.um)
+end.().output("M1.b", "Min. Metal1 space or notch = 0.18")
if $density
-> do
M1_density.ext_with_density(0.0 .. 0.35, 'll')
- end.().output("M1.j", "Min. global Metal1 density [%]")
+ end.().output("M1.j", "Min. global Metal1 density [%] = 35.0")
-> do
M1_density.ext_with_density(0.6 .. 1.0, 'll')
- end.().output("M1.k", "Max. global Metal1 density [%]")
+ end.().output("M1.k", "Max. global Metal1 density [%] = 60.0")
end
-> do
- Metal2.ext_fast_width(200)
-end.().output("M2.a", "Min. Metal2 width")
+ Metal2.ext_fast_width(0.2.um)
+end.().output("M2.a", "Min. Metal2 width = 0.20")
-> do
- M2_Nsram.ext_fast_space(210)
-end.().output("M2.b", "Min. Metal2 space or notch")
+ M2_Nsram.ext_fast_space(0.21.um)
+end.().output("M2.b", "Min. Metal2 space or notch = 0.21")
if $density
-> do
M2_density.ext_with_density(0.0 .. 0.35, 'll')
- end.().output("M2.j", "Min. global Metal2 density [%]")
+ end.().output("M2.j", "Min. global Metal2 density [%] = 35.00")
-> do
M2_density.ext_with_density(0.6 .. 1.0, 'll')
- end.().output("M2.k", "Max. global Metal2 density [%]")
+ end.().output("M2.k", "Max. global Metal2 density [%] = 60.00")
end
-> do
- Metal3.ext_fast_width(200)
-end.().output("M3.a", "Min. Metal3 width")
+ Metal3.ext_fast_width(0.2.um)
+end.().output("M3.a", "Min. Metal3 width = 0.20")
-> do
- M3_Nsram.ext_fast_space(210)
-end.().output("M3.b", "Min. Metal3 space or notch")
+ M3_Nsram.ext_fast_space(0.21.um)
+end.().output("M3.b", "Min. Metal3 space or notch = 0.21")
if $density
-> do
M3_density.ext_with_density(0.0 .. 0.35, 'll')
- end.().output("M3.j", "Min. global Metal3 density [%]")
+ end.().output("M3.j", "Min. global Metal3 density [%] = 35.00")
-> do
M3_density.ext_with_density(0.6 .. 1.0, 'll')
- end.().output("M3.k", "Max. global Metal3 density [%]")
+ end.().output("M3.k", "Max. global Metal3 density [%] = 60.00")
end
-> do
- Metal4.ext_fast_width(200)
-end.().output("M4.a", "Min. Metal4 width")
+ Metal4.ext_fast_width(0.2.um)
+end.().output("M4.a", "Min. Metal4 width = 0.20")
-> do
- M4_Nsram.ext_fast_space(210)
-end.().output("M4.b", "Min. Metal4 space or notch")
+ M4_Nsram.ext_fast_space(0.21.um)
+end.().output("M4.b", "Min. Metal4 space or notch = 0.21")
if $density
-> do
M4_density.ext_with_density(0.0 .. 0.35, 'll')
- end.().output("M4.j", "Min. global Metal4 density [%]")
+ end.().output("M4.j", "Min. global Metal4 density [%] = 35.00")
-> do
M4_density.ext_with_density(0.6 .. 1.0, 'll')
- end.().output("M4.k", "Max. global Metal4 density [%]")
+ end.().output("M4.k", "Max. global Metal4 density [%] = 60.00")
end
-> do
- Metal5.ext_fast_width(200)
-end.().output("M5.a", "Min. Metal5 width")
+ Metal5.ext_fast_width(0.2.um)
+end.().output("M5.a", "Min. Metal5 width = 0.20")
-> do
- M5_Nsram.ext_fast_space(210)
-end.().output("M5.b", "Min. Metal5 space or notch")
+ M5_Nsram.ext_fast_space(0.21.um)
+end.().output("M5.b", "Min. Metal5 space or notch = 0.21")
if $density
-> do
M5_density.ext_with_density(0.0 .. 0.35, 'll')
- end.().output("M5.j", "Min. global Metal5 density [%]")
+ end.().output("M5.j", "Min. global Metal5 density [%] = 35.00")
-> do
M5_density.ext_with_density(0.6 .. 1.0, 'll')
- end.().output("M5.k", "Max. global Metal5 density [%]")
+ end.().output("M5.k", "Max. global Metal5 density [%] = 60.00")
-> do
- M1_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M1Fil.h", "Min. Metal1 and Metal1:filler coverage ratio for any 800 x 800 µm² chip area [%]")
+ M1_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0.um), tile_step(400.0.um))
+ end.().output("M1Fil.h", "Min. Metal1 and Metal1:filler coverage ratio for any 800 x 800 µm² chip area [%] = 25.00")
-> do
- M1_density.ext_with_density(0.75 .. 1.0, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M1Fil.k", "Max. Metal1 and Metal1:filler coverage ratio for any 800 x 800 µm² chip area [%]")
+ M1_density.ext_with_density(0.75 .. 1.0, 'll', tile_size(800.0.um), tile_step(400.0.um))
+ end.().output("M1Fil.k", "Max. Metal1 and Metal1:filler coverage ratio for any 800 x 800 µm² chip area [%] = 75.00")
-> do
- M2_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M2Fil.h", "Min. Metal2 and Metal2:filler coverage ratio for any 800 x 800 µm² chip area [%]")
+ M2_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0.um), tile_step(400.0.um))
+ end.().output("M2Fil.h", "Min. Metal2 and Metal2:filler coverage ratio for any 800 x 800 µm² chip area [%] = 25.00")
-> do
- M2_density.ext_with_density(0.75 .. 1.0, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M2Fil.k", "Max. Metal2 and Metal2:filler coverage ratio for any 800 x 800 µm² chip area [%]")
+ M2_density.ext_with_density(0.75 .. 1.0, 'll', tile_size(800.0.um), tile_step(400.0.um))
+ end.().output("M2Fil.k", "Max. Metal2 and Metal2:filler coverage ratio for any 800 x 800 µm² chip area [%] = 75.00")
-> do
- M3_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M3Fil.h", "Min. Metal3 and Metal3:filler coverage ratio for any 800 x 800 µm² chip area [%]")
+ M3_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0.um), tile_step(400.0.um))
+ end.().output("M3Fil.h", "Min. Metal3 and Metal3:filler coverage ratio for any 800 x 800 µm² chip area [%] = 25.00")
-> do
- M3_density.ext_with_density(0.75 .. 1.0, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M3Fil.k", "Max. Metal3 and Metal3:filler coverage ratio for any 800 x 800 µm² chip area [%]")
+ M3_density.ext_with_density(0.75 .. 1.0, 'll', tile_size(800.0.um), tile_step(400.0.um))
+ end.().output("M3Fil.k", "Max. Metal3 and Metal3:filler coverage ratio for any 800 x 800 µm² chip area [%] = 75.00")
-> do
- M4_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M4Fil.h", "Min. Metal4 and Metal4:filler coverage ratio for any 800 x 800 µm² chip area [%]")
+ M4_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0.um), tile_step(400.0.um))
+ end.().output("M4Fil.h", "Min. Metal4 and Metal4:filler coverage ratio for any 800 x 800 µm² chip area [%] = 25.00")
-> do
- M4_density.ext_with_density(0.75 .. 1.0, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M4Fil.k", "Max. Metal4 and Metal4:filler coverage ratio for any 800 x 800 µm² chip area [%]")
+ M4_density.ext_with_density(0.75 .. 1.0, 'll', tile_size(800.0.um), tile_step(400.0.um))
+ end.().output("M4Fil.k", "Max. Metal4 and Metal4:filler coverage ratio for any 800 x 800 µm² chip area [%] = 75.00")
-> do
- M5_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M5Fil.h", "Min. Metal5 and Metal5:filler coverage ratio for any 800 x 800 µm² chip area [%]")
+ M5_density.ext_with_density(0.0 .. 0.25, 'll', tile_size(800.0.um), tile_step(400.0.um))
+ end.().output("M5Fil.h", "Min. Metal5 and Metal5:filler coverage ratio for any 800 x 800 µm² chip area [%] = 25.00")
-> do
- M5_density.ext_with_density(0.75 .. 1.0, 'll', tile_size(800.0), tile_step(400.0))
- end.().output("M5Fil.k", "Max. Metal5 and Metal5:filler coverage ratio for any 800 x 800 µm² chip area [%]")
+ M5_density.ext_with_density(0.75 .. 1.0, 'll', tile_size(800.0.um), tile_step(400.0.um))
+ end.().output("M5Fil.k", "Max. Metal5 and Metal5:filler coverage ratio for any 800 x 800 µm² chip area [%] = 75.00")
end
-> do
- Via1.ext_not(EdgeSeal).merged(true, 0).outside(transG2L).ext_rectangles(false, false, [["==", 190]], [["==", 190]], nil, inverted: true)
-end.().output("V1.a", "Min. and max. Via1 width")
+ Via1_edgC1_out.outside(transG2L).ext_rectangles(false, false, [["==", 0.19.um]], [["==", 0.19.um]], nil, inverted: true)
+end.().output("V1.a", "Min. and max. Via1 width = 0.19")
-> do
- Via1.ext_not(EdgeSeal).ext_fast_space(220)
-end.().output("V1.b", "Min. Via1 space")
+ Via1_edgC1_out.ext_fast_space(0.22.um)
+end.().output("V1.b", "Min. Via1 space = 0.22")
-> do
- Via2.ext_not(EdgeSeal).merged(true, 0).outside(transG2L).ext_rectangles(false, false, [["==", 190]], [["==", 190]], nil, inverted: true)
-end.().output("V2.a", "Min. and max. Via2 width")
+ Via2_edgC1_out.outside(transG2L).ext_rectangles(false, false, [["==", 0.19.um]], [["==", 0.19.um]], nil, inverted: true)
+end.().output("V2.a", "Min. and max. Via2 width = 0.19")
-> do
- Via2.ext_not(EdgeSeal).ext_fast_space(220)
-end.().output("V2.b", "Min. Via2 space")
+ Via2_edgC1_out.ext_fast_space(0.22.um)
+end.().output("V2.b", "Min. Via2 space = 0.22")
-> do
- Via3.ext_not(EdgeSeal).merged(true, 0).outside(transG2L).ext_rectangles(false, false, [["==", 190]], [["==", 190]], nil, inverted: true)
-end.().output("V3.a", "Min. and max. Via3 width")
+ Via3_edgC1_out.outside(transG2L).ext_rectangles(false, false, [["==", 0.19.um]], [["==", 0.19.um]], nil, inverted: true)
+end.().output("V3.a", "Min. and max. Via3 width = 0.19")
-> do
- Via3.ext_not(EdgeSeal).ext_fast_space(220)
-end.().output("V3.b", "Min. Via3 space")
+ Via3_edgC1_out.ext_fast_space(0.22.um)
+end.().output("V3.b", "Min. Via3 space = 0.22")
-> do
- Via4.ext_not(EdgeSeal).merged(true, 0).outside(transG2L).ext_rectangles(false, false, [["==", 190]], [["==", 190]], nil, inverted: true)
-end.().output("V4.a", "Min. and max. Via4 width")
+ Via4_edgC1_out.outside(transG2L).ext_rectangles(false, false, [["==", 0.19.um]], [["==", 0.19.um]], nil, inverted: true)
+end.().output("V4.a", "Min. and max. Via4 width = 0.19")
-> do
- Via4.ext_not(EdgeSeal).ext_fast_space(220)
-end.().output("V4.b", "Min. Via4 space")
+ Via4_edgC1_out.ext_fast_space(0.22.um)
+end.().output("V4.b", "Min. Via4 space = 0.22")
-> do
- Vmim.ext_or(TopVia1.ext_not(EdgeSeal)).ext_rectangles(false, false, [["==", 420]], [["==", 420]], nil, inverted: true)
-end.().output("TV1.a", "Min. and max. TopVia1 width")
+ TopVia1_edgC1_out.ext_or(Vmim).ext_rectangles(false, false, [["==", 0.42.um]], [["==", 0.42.um]], nil, inverted: true)
+end.().output("TV1.a", "Min. and max. TopVia1 width = 0.42")
-> do
- TopVia1.ext_or(Vmim).ext_fast_space(420)
-end.().output("TV1.b", "Min. TopVia1 space")
+ TopVia1_or_Vmim.ext_fast_space(0.42.um)
+end.().output("TV1.b", "Min. TopVia1 space = 0.42")
-> do
- TopMetal1.ext_fast_width(1640)
-end.().output("TM1.a", "Min. TopMetal1 width")
+ TopMetal1.ext_fast_width(1.64.um)
+end.().output("TM1.a", "Min. TopMetal1 width = 1.64")
-> do
- TopMetal1.ext_fast_space(1640)
-end.().output("TM1.b", "Min. TopMetal1 space or notch")
+ TopMetal1.ext_fast_space(1.64.um)
+end.().output("TM1.b", "Min. TopMetal1 space or notch = 1.64")
if $density
-> do
TM1_density.ext_with_density(0.0 .. 0.25, 'll')
- end.().output("TM1.c", "Min. global TopMetal1 density [%]")
+ end.().output("TM1.c", "Min. global TopMetal1 density [%] = 25.00")
-> do
TM1_density.ext_with_density(0.7 .. 1.0, 'll')
- end.().output("TM1.d", "Max. global TopMetal1 density [%]")
+ end.().output("TM1.d", "Max. global TopMetal1 density [%] = 70.00")
end
-> do
- TopVia2.ext_not(EdgeSeal).ext_rectangles(false, false, [["==", 900]], [["==", 900]], nil, inverted: true)
-end.().output("TV2.a", "Min. and max. TopVia2 width")
+ TopVia2_edgC1_out.ext_rectangles(false, false, [["==", 0.9.um]], [["==", 0.9.um]], nil, inverted: true)
+end.().output("TV2.a", "Min. and max. TopVia2 width = 0.90")
-> do
- TopVia2.ext_fast_space(1060)
-end.().output("TV2.b", "Min. TopVia2 space")
+ TopVia2.ext_fast_space(1.06.um)
+end.().output("TV2.b", "Min. TopVia2 space = 1.06")
-> do
- TopMetal2.ext_fast_width(2000)
-end.().output("TM2.a", "Min. TopMetal2 width")
+ TopMetal2.ext_fast_width(2.0.um)
+end.().output("TM2.a", "Min. TopMetal2 width = 2.00")
-> do
- TopMetal2.ext_fast_space(2000)
-end.().output("TM2.b", "Min. TopMetal2 space or notch")
+ TopMetal2.ext_fast_space(2.0.um)
+end.().output("TM2.b", "Min. TopMetal2 space or notch = 2.00")
if $density
-> do
TM2_density.ext_with_density(0.0 .. 0.25, 'll')
- end.().output("TM2.c", "Min. global TopMetal2 density [%]")
+ end.().output("TM2.c", "Min. global TopMetal2 density [%] = 25.00")
-> do
TM2_density.ext_with_density(0.7 .. 1.0, 'll')
- end.().output("TM2.d", "Max. global TopMetal2 density [%]")
+ end.().output("TM2.d", "Max. global TopMetal2 density [%] = 70.00")
end
-> do
- Passiv.ext_fast_width(2100)
-end.().output("Pas.a", "Min. Passiv width")
+ Passiv.ext_fast_width(2.1.um)
+end.().output("Pas.a", "Min. Passiv width = 2.10")
-> do
- Passiv.ext_fast_space(3500)
-end.().output("Pas.b", "Min. Passiv space or notch")
+ Passiv.ext_fast_space(3.5.um)
+end.().output("Pas.b", "Min. Passiv space or notch = 3.50")
if $sanityRules
-> do
Activ_pin.ext_not(Activ)
- end.().output("Pin.a", "Min. Activ enclosure of Activ:pin")
+ end.().output("Pin.a", "Min. Activ enclosure of Activ:pin = 0.00")
-> do
GatPoly_pin.ext_not(GatPoly)
- end.().output("Pin.b", "Min. GatPoly enclosure of GatPoly:pin")
+ end.().output("Pin.b", "Min. GatPoly enclosure of GatPoly:pin = 0.00")
-> do
Metal1_pin.ext_not(Metal1)
- end.().output("Pin.e", "Min. Metal1 enclosure of Metal1:pin")
+ end.().output("Pin.e", "Min. Metal1 enclosure of Metal1:pin = 0.00")
-> do
Metal2_pin.ext_not(Metal2)
- end.().output("Pin.f.M2", "Min. Metal2 enclosure of Metal2:pin")
+ end.().output("Pin.f.M2", "Min. Metal2 enclosure of Metal2:pin = 0.00")
-> do
Metal3_pin.ext_not(Metal3)
- end.().output("Pin.f.M3", "Min. Metal3 enclosure of Metal3:pin")
+ end.().output("Pin.f.M3", "Min. Metal3 enclosure of Metal3:pin = 0.00")
-> do
Metal4_pin.ext_not(Metal4)
- end.().output("Pin.f.M4", "Min. Metal4 enclosure of Metal4:pin")
+ end.().output("Pin.f.M4", "Min. Metal4 enclosure of Metal4:pin = 0.00")
-> do
Metal5_pin.ext_not(Metal5)
- end.().output("Pin.f.M5", "Min. Metal5 enclosure of Metal5:pin")
+ end.().output("Pin.f.M5", "Min. Metal5 enclosure of Metal5:pin = 0.00")
-> do
TopMetal1_pin.ext_not(TopMetal1)
- end.().output("Pin.g", "Min. TopMetal1 enclosure of TopMetal1:pin")
+ end.().output("Pin.g", "Min. TopMetal1 enclosure of TopMetal1:pin = 0.00")
-> do
TopMetal2_pin.ext_not(TopMetal2)
- end.().output("Pin.h", "Min. TopMetal2 enclosure of TopMetal2:pin")
+ end.().output("Pin.h", "Min. TopMetal2 enclosure of TopMetal2:pin = 0.00")
end
-> do
- LBE.ext_fast_width(100000)
-end.().output("LBE.a", "Min. LBE width")
+ LBE.ext_fast_width(100.0.um)
+end.().output("LBE.a", "Min. LBE width = 100.00")
-> do
- LBE.drc((width(projection) > 1500000).polygons)
-end.().output("LBE.b", "Max. LBE width")
+ LBE.drc((width(projection) > 1500.0.um).polygons)
+end.().output("LBE.b", "Max. LBE width = 1500.00")
-> do
- LBE.ext_area([[">", 250000.0]])
-end.().output("LBE.b1", "Max. LBE area (µm²)")
+ LBE.ext_with_area([[">", 250000.0.um2]])
+end.().output("LBE.b1", "Max. LBE area (µm²) = 250000.00")
-> do
- LBE.ext_fast_space(100000)
-end.().output("LBE.c", "Min. LBE space or notch")
+ LBE.ext_fast_space(100.0.um)
+end.().output("LBE.c", "Min. LBE space or notch = 100.00")
-> (;lbe_in_seal) do
- lbe_in_seal = LBE.merged(true, 0).inside(EdgeSeal.holes.merge)
- lbe_in_seal.ext_fast_separation(EdgeSeal, 150000)
-end.().output("LBE.d", "Min. LBE space to inner edge of EdgeSeal")
+ lbe_in_seal = LBE.inside(EdgeSeal.holes.merge)
+ lbe_in_seal.ext_fast_separation(EdgeSeal, 150.0.um)
+end.().output("LBE.d", "Min. LBE space to inner edge of EdgeSeal = 150.00")
-> do
- LBE.ext_ring.dup
+ LBE.with_holes.dup
end.().output("LBE.h", "No LBE ring allowed")
if $density
-> do
LBE.ext_with_density(0.2 .. 1.0, 'll')
- end.().output("LBE.i", "Max. global LBE density [%]")
+ end.().output("LBE.i", "Max. global LBE density [%] = 20.00")
end
if $sanityRules
-> do
BiWind.dup
- end.().output("forbidden.BiWind", "Forbidden drawn layer BiWind on GDS layer 3/0")
+ end.().output("forbidden.BiWind", "Forbidden drawn layer BiWind on GDS layer 3/0 = 3/0")
-> do
PEmWind.dup
- end.().output("forbidden.PEmWind", "Forbidden drawn layer PEmWind on GDS layer 11/0")
+ end.().output("forbidden.PEmWind", "Forbidden drawn layer PEmWind on GDS layer 11/0 = 11/0")
-> do
BasPoly.dup
- end.().output("forbidden.BasPoly", "Forbidden drawn layer BasPoly on GDS layer 13/0")
+ end.().output("forbidden.BasPoly", "Forbidden drawn layer BasPoly on GDS layer 13/0 = 13/0")
-> do
DeepCo.dup
- end.().output("forbidden.DeepCo", "Forbidden drawn layer DeepCo on GDS layer 35/0")
+ end.().output("forbidden.DeepCo", "Forbidden drawn layer DeepCo on GDS layer 35/0 = 35/0")
-> do
PEmPoly.dup
- end.().output("forbidden.PEmPoly", "Forbidden drawn layer PEmPoly on GDS layer 53/0")
+ end.().output("forbidden.PEmPoly", "Forbidden drawn layer PEmPoly on GDS layer 53/0 = 53/0")
-> do
EmPoly.dup
- end.().output("forbidden.EmPoly", "Forbidden gen./drawn layer EmPoly on GDS layer 53/0")
+ end.().output("forbidden.EmPoly", "Forbidden gen./drawn layer EmPoly on GDS layer 53/0 = 53/0")
-> do
LDMOS.dup
- end.().output("forbidden.LDMOS", "Forbidden drawn layer LDMOS on GDS layer 57/0")
+ end.().output("forbidden.LDMOS", "Forbidden drawn layer LDMOS on GDS layer 57/0 = 57/0")
-> do
PBiWind.dup
- end.().output("forbidden.PBiWind", "Forbidden drawn layer PBiWind on GDS layer 58/0")
+ end.().output("forbidden.PBiWind", "Forbidden drawn layer PBiWind on GDS layer 58/0 = 58/0")
-> do
Flash.dup
- end.().output("forbidden.Flash", "Forbidden drawn layer Flash on GDS layer 71/0")
+ end.().output("forbidden.Flash", "Forbidden drawn layer Flash on GDS layer 71/0 = 71/0")
-> do
ColWind.dup
- end.().output("forbidden.ColWind", "Forbidden drawn layer ColWind on GDS layer 139/0")
+ end.().output("forbidden.ColWind", "Forbidden drawn layer ColWind on GDS layer 139/0 = 139/0")
end
+
+puts("Number of DRC errors: #{$drc_error_count}")
diff --git a/ihp-sg13g2/libs.tech/klayout/tech/lvs/rule_decks/esd_connections.lvs b/ihp-sg13g2/libs.tech/klayout/tech/lvs/rule_decks/esd_connections.lvs
index 7c37e0a5..6a0c5cb9 100644
--- a/ihp-sg13g2/libs.tech/klayout/tech/lvs/rule_decks/esd_connections.lvs
+++ b/ihp-sg13g2/libs.tech/klayout/tech/lvs/rule_decks/esd_connections.lvs
@@ -17,9 +17,9 @@
# SPDX-License-Identifier: Apache-2.0
#==========================================================================
-#================================
-# ---- RESISTOR CONNECTIONS -----
-#================================
+#===============================
+# ------ ESD CONNECTIONS -------
+#===============================
logger.info('Starting ESD CONNECTIONS')
diff --git a/ihp-sg13g2/libs.tech/klayout/tech/lvs/rule_decks/esd_derivations.lvs b/ihp-sg13g2/libs.tech/klayout/tech/lvs/rule_decks/esd_derivations.lvs
index bd78b0ff..94e81af9 100644
--- a/ihp-sg13g2/libs.tech/klayout/tech/lvs/rule_decks/esd_derivations.lvs
+++ b/ihp-sg13g2/libs.tech/klayout/tech/lvs/rule_decks/esd_derivations.lvs
@@ -18,7 +18,7 @@
#==========================================================================
#================================
-# ---- MOS-SAB DERIVATIONS ------
+# ------- ESD DERIVATIONS -------
#================================
logger.info('Starting ESD DERIVATIONS')
diff --git a/ihp-sg13g2/libs.tech/klayout/tech/lvs/rule_decks/esd_extraction.lvs b/ihp-sg13g2/libs.tech/klayout/tech/lvs/rule_decks/esd_extraction.lvs
index 585281ee..3e502961 100644
--- a/ihp-sg13g2/libs.tech/klayout/tech/lvs/rule_decks/esd_extraction.lvs
+++ b/ihp-sg13g2/libs.tech/klayout/tech/lvs/rule_decks/esd_extraction.lvs
@@ -18,7 +18,7 @@
#==========================================================================
#================================
-# ----- MOS-SAB EXTRACTION ------
+# ------- ESD DERIVATIONS -------
#================================
logger.info('Starting ESD EXTRACTION')
diff --git a/ihp-sg13g2/libs.tech/klayout/tech/lvs/rule_decks/layers_definitions.lvs b/ihp-sg13g2/libs.tech/klayout/tech/lvs/rule_decks/layers_definitions.lvs
index e6cf6ba5..0d7cb466 100644
--- a/ihp-sg13g2/libs.tech/klayout/tech/lvs/rule_decks/layers_definitions.lvs
+++ b/ihp-sg13g2/libs.tech/klayout/tech/lvs/rule_decks/layers_definitions.lvs
@@ -32,19 +32,12 @@ def get_polygons(lay_no, lay_dt)
end
end
-nodrc_drw = get_polygons(62, 0)
-count = nodrc_drw.count()
-logger.info("nodrc_drw has #{count} polygons")
-polygons_count += count
-
activ_drw = get_polygons(1, 0)
-activ_drw = activ_drw.not(nodrc_drw)
count = activ_drw.count()
logger.info("activ_drw has #{count} polygons")
polygons_count += count
activ_filler = get_polygons(1, 22)
-activ_filler = activ_filler.not(nodrc_drw)
count = activ_filler.count()
logger.info("activ_filler has #{count} polygons")
polygons_count += count
@@ -55,61 +48,51 @@ count = activ.count()
logger.info("activ has #{count} polygons")
activ_pin = get_polygons(1, 2)
-activ_pin = activ_pin.not(nodrc_drw)
count = activ_pin.count()
logger.info("activ_pin has #{count} polygons")
polygons_count += count
activ_mask = get_polygons(1, 20)
-activ_mask = activ_mask.not(nodrc_drw)
count = activ_mask.count()
logger.info("activ_mask has #{count} polygons")
polygons_count += count
activ_nofill = get_polygons(1, 23)
-activ_nofill = activ_nofill.not(nodrc_drw)
count = activ_nofill.count()
logger.info("activ_nofill has #{count} polygons")
polygons_count += count
activ_OPC = get_polygons(1, 26)
-activ_OPC = activ_OPC.not(nodrc_drw)
count = activ_OPC.count()
logger.info("activ_OPC has #{count} polygons")
polygons_count += count
activ_iOPC = get_polygons(1, 27)
-activ_iOPC = activ_iOPC.not(nodrc_drw)
count = activ_iOPC.count()
logger.info("activ_iOPC has #{count} polygons")
polygons_count += count
activ_noqrc = get_polygons(1, 28)
-activ_noqrc = activ_noqrc.not(nodrc_drw)
count = activ_noqrc.count()
logger.info("activ_noqrc has #{count} polygons")
polygons_count += count
biwind_drw = get_polygons(3, 0)
-biwind_drw = biwind_drw.not(nodrc_drw)
count = biwind_drw.count()
logger.info("biwind_drw has #{count} polygons")
polygons_count += count
biwind_OPC = get_polygons(3, 26)
-biwind_OPC = biwind_OPC.not(nodrc_drw)
count = biwind_OPC.count()
logger.info("biwind_OPC has #{count} polygons")
polygons_count += count
gatpoly_drw = get_polygons(5, 0)
-gatpoly_drw = gatpoly_drw.not(nodrc_drw)
count = gatpoly_drw.count()
logger.info("gatpoly_drw has #{count} polygons")
polygons_count += count
gatpoly_filler = get_polygons(5, 22)
-gatpoly_filler = gatpoly_filler.not(nodrc_drw)
count = gatpoly_filler.count()
logger.info("gatpoly_filler has #{count} polygons")
polygons_count += count
@@ -120,73 +103,61 @@ count = gatpoly.count()
logger.info("gatpoly has #{count} polygons")
gatpoly_pin = get_polygons(5, 2)
-gatpoly_pin = gatpoly_pin.not(nodrc_drw)
count = gatpoly_pin.count()
logger.info("gatpoly_pin has #{count} polygons")
polygons_count += count
gatpoly_nofill = get_polygons(5, 23)
-gatpoly_nofill = gatpoly_nofill.not(nodrc_drw)
count = gatpoly_nofill.count()
logger.info("gatpoly_nofill has #{count} polygons")
polygons_count += count
gatpoly_OPC = get_polygons(5, 26)
-gatpoly_OPC = gatpoly_OPC.not(nodrc_drw)
count = gatpoly_OPC.count()
logger.info("gatpoly_OPC has #{count} polygons")
polygons_count += count
gatpoly_iOPC = get_polygons(5, 27)
-gatpoly_iOPC = gatpoly_iOPC.not(nodrc_drw)
count = gatpoly_iOPC.count()
logger.info("gatpoly_iOPC has #{count} polygons")
polygons_count += count
gatpoly_noqrc = get_polygons(5, 28)
-gatpoly_noqrc = gatpoly_noqrc.not(nodrc_drw)
count = gatpoly_noqrc.count()
logger.info("gatpoly_noqrc has #{count} polygons")
polygons_count += count
cont_drw = get_polygons(6, 0)
-cont_drw = cont_drw.not(nodrc_drw)
count = cont_drw.count()
logger.info("cont_drw has #{count} polygons")
polygons_count += count
cont_OPC = get_polygons(6, 26)
-cont_OPC = cont_OPC.not(nodrc_drw)
count = cont_OPC.count()
logger.info("cont_OPC has #{count} polygons")
polygons_count += count
nsd_drw = get_polygons(7, 0)
-nsd_drw = nsd_drw.not(nodrc_drw)
count = nsd_drw.count()
logger.info("nsd_drw has #{count} polygons")
polygons_count += count
nsd_block = get_polygons(7, 21)
-nsd_block = nsd_block.not(nodrc_drw)
count = nsd_block.count()
logger.info("nsd_block has #{count} polygons")
polygons_count += count
metal1_drw = get_polygons(8, 0)
-metal1_drw = metal1_drw.not(nodrc_drw)
count = metal1_drw.count()
logger.info("metal1_drw has #{count} polygons")
polygons_count += count
metal1_filler = get_polygons(8, 22)
-metal1_filler = metal1_filler.not(nodrc_drw)
count = metal1_filler.count()
logger.info("metal1_filler has #{count} polygons")
polygons_count += count
metal1_slit = get_polygons(8, 24)
-metal1_slit = metal1_slit.not(nodrc_drw)
count = metal1_slit.count()
logger.info("metal1_slit has #{count} polygons")
polygons_count += count
@@ -197,103 +168,86 @@ count = metal1.count()
logger.info("metal1 has #{count} polygons")
metal1_pin = get_polygons(8, 2)
-metal1_pin = metal1_pin.not(nodrc_drw)
count = metal1_pin.count()
logger.info("metal1_pin has #{count} polygons")
polygons_count += count
metal1_mask = get_polygons(8, 20)
-metal1_mask = metal1_mask.not(nodrc_drw)
count = metal1_mask.count()
logger.info("metal1_mask has #{count} polygons")
polygons_count += count
metal1_nofill = get_polygons(8, 23)
-metal1_nofill = metal1_nofill.not(nodrc_drw)
count = metal1_nofill.count()
logger.info("metal1_nofill has #{count} polygons")
polygons_count += count
metal1_text = labels(8, 25)
-metal1_text = metal1_text.not(nodrc_drw)
count = metal1_text.count()
logger.info("metal1_text has #{count} polygons")
polygons_count += count
metal1_OPC = get_polygons(8, 26)
-metal1_OPC = metal1_OPC.not(nodrc_drw)
count = metal1_OPC.count()
logger.info("metal1_OPC has #{count} polygons")
polygons_count += count
metal1_noqrc = get_polygons(8, 28)
-metal1_noqrc = metal1_noqrc.not(nodrc_drw)
count = metal1_noqrc.count()
logger.info("metal1_noqrc has #{count} polygons")
polygons_count += count
metal1_res = get_polygons(8, 29)
-metal1_res = metal1_res.not(nodrc_drw)
count = metal1_res.count()
logger.info("metal1_res has #{count} polygons")
polygons_count += count
metal1_iprobe = get_polygons(8, 33)
-metal1_iprobe = metal1_iprobe.not(nodrc_drw)
count = metal1_iprobe.count()
logger.info("metal1_iprobe has #{count} polygons")
polygons_count += count
metal1_diffprb = get_polygons(8, 34)
-metal1_diffprb = metal1_diffprb.not(nodrc_drw)
count = metal1_diffprb.count()
logger.info("metal1_diffprb has #{count} polygons")
polygons_count += count
passiv_drw = get_polygons(9, 0)
-passiv_drw = passiv_drw.not(nodrc_drw)
count = passiv_drw.count()
logger.info("passiv_drw has #{count} polygons")
polygons_count += count
passiv_pin = get_polygons(9, 2)
-passiv_pin = passiv_pin.not(nodrc_drw)
count = passiv_pin.count()
logger.info("passiv_pin has #{count} polygons")
polygons_count += count
passiv_sbump = get_polygons(9, 36)
-passiv_sbump = passiv_sbump.not(nodrc_drw)
count = passiv_sbump.count()
logger.info("passiv_sbump has #{count} polygons")
polygons_count += count
passiv_pillar = get_polygons(9, 35)
-passiv_pillar = passiv_pillar.not(nodrc_drw)
count = passiv_pillar.count()
logger.info("passiv_pillar has #{count} polygons")
polygons_count += count
passiv_pdl = get_polygons(9, 40)
-passiv_pdl = passiv_pdl.not(nodrc_drw)
count = passiv_pdl.count()
logger.info("passiv_pdl has #{count} polygons")
polygons_count += count
metal2_drw = get_polygons(10, 0)
-metal2_drw = metal2_drw.not(nodrc_drw)
count = metal2_drw.count()
logger.info("metal2_drw has #{count} polygons")
polygons_count += count
metal2_filler = get_polygons(10, 22)
-metal2_filler = metal2_filler.not(nodrc_drw)
count = metal2_filler.count()
logger.info("metal2_filler has #{count} polygons")
polygons_count += count
metal2_slit = get_polygons(10, 24)
-metal2_slit = metal2_slit.not(nodrc_drw)
count = metal2_slit.count()
logger.info("metal2_slit has #{count} polygons")
polygons_count += count
@@ -304,235 +258,196 @@ count = metal2.count()
logger.info("metal2 has #{count} polygons")
metal2_pin = get_polygons(10, 2)
-metal2_pin = metal2_pin.not(nodrc_drw)
count = metal2_pin.count()
logger.info("metal2_pin has #{count} polygons")
polygons_count += count
metal2_mask = get_polygons(10, 20)
-metal2_mask = metal2_mask.not(nodrc_drw)
count = metal2_mask.count()
logger.info("metal2_mask has #{count} polygons")
polygons_count += count
metal2_nofill = get_polygons(10, 23)
-metal2_nofill = metal2_nofill.not(nodrc_drw)
count = metal2_nofill.count()
logger.info("metal2_nofill has #{count} polygons")
polygons_count += count
metal2_text = labels(10, 25)
-metal2_text = metal2_text.not(nodrc_drw)
count = metal2_text.count()
logger.info("metal2_text has #{count} polygons")
polygons_count += count
metal2_OPC = get_polygons(10, 26)
-metal2_OPC = metal2_OPC.not(nodrc_drw)
count = metal2_OPC.count()
logger.info("metal2_OPC has #{count} polygons")
polygons_count += count
metal2_noqrc = get_polygons(10, 28)
-metal2_noqrc = metal2_noqrc.not(nodrc_drw)
count = metal2_noqrc.count()
logger.info("metal2_noqrc has #{count} polygons")
polygons_count += count
metal2_res = get_polygons(10, 29)
-metal2_res = metal2_res.not(nodrc_drw)
count = metal2_res.count()
logger.info("metal2_res has #{count} polygons")
polygons_count += count
metal2_iprobe = get_polygons(10, 33)
-metal2_iprobe = metal2_iprobe.not(nodrc_drw)
count = metal2_iprobe.count()
logger.info("metal2_iprobe has #{count} polygons")
polygons_count += count
metal2_diffprb = get_polygons(10, 34)
-metal2_diffprb = metal2_diffprb.not(nodrc_drw)
count = metal2_diffprb.count()
logger.info("metal2_diffprb has #{count} polygons")
polygons_count += count
baspoly_drw = get_polygons(13, 0)
-baspoly_drw = baspoly_drw.not(nodrc_drw)
count = baspoly_drw.count()
logger.info("baspoly_drw has #{count} polygons")
polygons_count += count
baspoly_pin = get_polygons(13, 2)
-baspoly_pin = baspoly_pin.not(nodrc_drw)
count = baspoly_pin.count()
logger.info("baspoly_pin has #{count} polygons")
polygons_count += count
psd_drw = get_polygons(14, 0)
-psd_drw = psd_drw.not(nodrc_drw)
count = psd_drw.count()
logger.info("psd_drw has #{count} polygons")
polygons_count += count
nldb_drw = get_polygons(15, 0)
-nldb_drw = nldb_drw.not(nodrc_drw)
count = nldb_drw.count()
logger.info("nldb_drw has #{count} polygons")
polygons_count += count
digibnd_drw = get_polygons(16, 0)
-digibnd_drw = digibnd_drw.not(nodrc_drw)
count = digibnd_drw.count()
logger.info("digibnd_drw has #{count} polygons")
polygons_count += count
via1_drw = get_polygons(19, 0)
-via1_drw = via1_drw.not(nodrc_drw)
count = via1_drw.count()
logger.info("via1_drw has #{count} polygons")
polygons_count += count
backmetal1_drw = get_polygons(20, 0)
-backmetal1_drw = backmetal1_drw.not(nodrc_drw)
count = backmetal1_drw.count()
logger.info("backmetal1_drw has #{count} polygons")
polygons_count += count
backmetal1_pin = get_polygons(20, 2)
-backmetal1_pin = backmetal1_pin.not(nodrc_drw)
count = backmetal1_pin.count()
logger.info("backmetal1_pin has #{count} polygons")
polygons_count += count
backmetal1_mask = get_polygons(20, 20)
-backmetal1_mask = backmetal1_mask.not(nodrc_drw)
count = backmetal1_mask.count()
logger.info("backmetal1_mask has #{count} polygons")
polygons_count += count
backmetal1_filler = get_polygons(20, 22)
-backmetal1_filler = backmetal1_filler.not(nodrc_drw)
count = backmetal1_filler.count()
logger.info("backmetal1_filler has #{count} polygons")
polygons_count += count
backmetal1_nofill = get_polygons(20, 23)
-backmetal1_nofill = backmetal1_nofill.not(nodrc_drw)
count = backmetal1_nofill.count()
logger.info("backmetal1_nofill has #{count} polygons")
polygons_count += count
backmetal1_slit = get_polygons(20, 24)
-backmetal1_slit = backmetal1_slit.not(nodrc_drw)
count = backmetal1_slit.count()
logger.info("backmetal1_slit has #{count} polygons")
polygons_count += count
backmetal1_text = labels(20, 25)
-backmetal1_text = backmetal1_text.not(nodrc_drw)
count = backmetal1_text.count()
logger.info("backmetal1_text has #{count} polygons")
polygons_count += count
backmetal1_OPC = get_polygons(20, 26)
-backmetal1_OPC = backmetal1_OPC.not(nodrc_drw)
count = backmetal1_OPC.count()
logger.info("backmetal1_OPC has #{count} polygons")
polygons_count += count
backmetal1_noqrc = get_polygons(20, 28)
-backmetal1_noqrc = backmetal1_noqrc.not(nodrc_drw)
count = backmetal1_noqrc.count()
logger.info("backmetal1_noqrc has #{count} polygons")
polygons_count += count
backmetal1_res = get_polygons(20, 29)
-backmetal1_res = backmetal1_res.not(nodrc_drw)
count = backmetal1_res.count()
logger.info("backmetal1_res has #{count} polygons")
polygons_count += count
backmetal1_iprobe = get_polygons(20, 33)
-backmetal1_iprobe = backmetal1_iprobe.not(nodrc_drw)
count = backmetal1_iprobe.count()
logger.info("backmetal1_iprobe has #{count} polygons")
polygons_count += count
backmetal1_diffprb = get_polygons(20, 34)
-backmetal1_diffprb = backmetal1_diffprb.not(nodrc_drw)
count = backmetal1_diffprb.count()
logger.info("backmetal1_diffprb has #{count} polygons")
polygons_count += count
backpassiv_drw = get_polygons(23, 0)
-backpassiv_drw = backpassiv_drw.not(nodrc_drw)
count = backpassiv_drw.count()
logger.info("backpassiv_drw has #{count} polygons")
polygons_count += count
res_drw = get_polygons(24, 0)
-res_drw = res_drw.not(nodrc_drw)
count = res_drw.count()
logger.info("res_drw has #{count} polygons")
polygons_count += count
sram_drw = get_polygons(25, 0)
-sram_drw = sram_drw.not(nodrc_drw)
count = sram_drw.count()
logger.info("sram_drw has #{count} polygons")
polygons_count += count
trans_drw = get_polygons(26, 0)
-trans_drw = trans_drw.not(nodrc_drw)
count = trans_drw.count()
logger.info("trans_drw has #{count} polygons")
polygons_count += count
ind_drw = get_polygons(27, 0)
-ind_drw = ind_drw.not(nodrc_drw)
count = ind_drw.count()
logger.info("ind_drw has #{count} polygons")
polygons_count += count
ind_pin = get_polygons(27, 2)
-ind_pin = ind_pin.not(nodrc_drw)
count = ind_pin.count()
logger.info("ind_pin has #{count} polygons")
polygons_count += count
ind_text = labels(27, 25)
-ind_text = ind_text.not(nodrc_drw)
count = ind_text.count()
logger.info("ind_text has #{count} polygons")
polygons_count += count
salblock_drw = get_polygons(28, 0)
-salblock_drw = salblock_drw.not(nodrc_drw)
count = salblock_drw.count()
logger.info("salblock_drw has #{count} polygons")
polygons_count += count
via2_drw = get_polygons(29, 0)
-via2_drw = via2_drw.not(nodrc_drw)
count = via2_drw.count()
logger.info("via2_drw has #{count} polygons")
polygons_count += count
metal3_drw = get_polygons(30, 0)
-metal3_drw = metal3_drw.not(nodrc_drw)
count = metal3_drw.count()
logger.info("metal3_drw has #{count} polygons")
polygons_count += count
metal3_filler = get_polygons(30, 22)
-metal3_filler = metal3_filler.not(nodrc_drw)
count = metal3_filler.count()
logger.info("metal3_filler has #{count} polygons")
polygons_count += count
metal3_slit = get_polygons(30, 24)
-metal3_slit = metal3_slit.not(nodrc_drw)
count = metal3_slit.count()
logger.info("metal3_slit has #{count} polygons")
polygons_count += count
@@ -543,205 +458,171 @@ count = metal3.count()
logger.info("metal3 has #{count} polygons")
metal3_pin = get_polygons(30, 2)
-metal3_pin = metal3_pin.not(nodrc_drw)
count = metal3_pin.count()
logger.info("metal3_pin has #{count} polygons")
polygons_count += count
metal3_mask = get_polygons(30, 20)
-metal3_mask = metal3_mask.not(nodrc_drw)
count = metal3_mask.count()
logger.info("metal3_mask has #{count} polygons")
polygons_count += count
metal3_nofill = get_polygons(30, 23)
-metal3_nofill = metal3_nofill.not(nodrc_drw)
count = metal3_nofill.count()
logger.info("metal3_nofill has #{count} polygons")
polygons_count += count
metal3_text = labels(30, 25)
-metal3_text = metal3_text.not(nodrc_drw)
count = metal3_text.count()
logger.info("metal3_text has #{count} polygons")
polygons_count += count
metal3_OPC = get_polygons(30, 26)
-metal3_OPC = metal3_OPC.not(nodrc_drw)
count = metal3_OPC.count()
logger.info("metal3_OPC has #{count} polygons")
polygons_count += count
metal3_noqrc = get_polygons(30, 28)
-metal3_noqrc = metal3_noqrc.not(nodrc_drw)
count = metal3_noqrc.count()
logger.info("metal3_noqrc has #{count} polygons")
polygons_count += count
metal3_res = get_polygons(30, 29)
-metal3_res = metal3_res.not(nodrc_drw)
count = metal3_res.count()
logger.info("metal3_res has #{count} polygons")
polygons_count += count
metal3_iprobe = get_polygons(30, 33)
-metal3_iprobe = metal3_iprobe.not(nodrc_drw)
count = metal3_iprobe.count()
logger.info("metal3_iprobe has #{count} polygons")
polygons_count += count
metal3_diffprb = get_polygons(30, 34)
-metal3_diffprb = metal3_diffprb.not(nodrc_drw)
count = metal3_diffprb.count()
logger.info("metal3_diffprb has #{count} polygons")
polygons_count += count
nwell_drw = get_polygons(31, 0)
-nwell_drw = nwell_drw.not(nodrc_drw)
count = nwell_drw.count()
logger.info("nwell_drw has #{count} polygons")
polygons_count += count
nwell_pin = get_polygons(31, 2)
-nwell_pin = nwell_pin.not(nodrc_drw)
count = nwell_pin.count()
logger.info("nwell_pin has #{count} polygons")
polygons_count += count
nbulay_drw = get_polygons(32, 0)
-nbulay_drw = nbulay_drw.not(nodrc_drw)
count = nbulay_drw.count()
logger.info("nbulay_drw has #{count} polygons")
polygons_count += count
nbulay_pin = get_polygons(32, 2)
-nbulay_pin = nbulay_pin.not(nodrc_drw)
count = nbulay_pin.count()
logger.info("nbulay_pin has #{count} polygons")
polygons_count += count
nbulay_block = get_polygons(32, 21)
-nbulay_block = nbulay_block.not(nodrc_drw)
count = nbulay_block.count()
logger.info("nbulay_block has #{count} polygons")
polygons_count += count
emwind_drw = get_polygons(33, 0)
-emwind_drw = emwind_drw.not(nodrc_drw)
count = emwind_drw.count()
logger.info("emwind_drw has #{count} polygons")
polygons_count += count
emwind_OPC = get_polygons(33, 26)
-emwind_OPC = emwind_OPC.not(nodrc_drw)
count = emwind_OPC.count()
logger.info("emwind_OPC has #{count} polygons")
polygons_count += count
deepco_drw = get_polygons(35, 0)
-deepco_drw = deepco_drw.not(nodrc_drw)
count = deepco_drw.count()
logger.info("deepco_drw has #{count} polygons")
polygons_count += count
mim_drw = get_polygons(36, 0)
-mim_drw = mim_drw.not(nodrc_drw)
count = mim_drw.count()
logger.info("mim_drw has #{count} polygons")
polygons_count += count
edgeseal_drw = get_polygons(39, 0)
-edgeseal_drw = edgeseal_drw.not(nodrc_drw)
count = edgeseal_drw.count()
logger.info("edgeseal_drw has #{count} polygons")
polygons_count += count
substrate_drw = get_polygons(40, 0)
-substrate_drw = substrate_drw.not(nodrc_drw)
count = substrate_drw.count()
logger.info("substrate_drw has #{count} polygons")
polygons_count += count
substrate_text = labels(40, 25)
-substrate_text = substrate_text.not(nodrc_drw)
count = substrate_text.count()
logger.info("substrate_text has #{count} polygons")
polygons_count += count
dfpad_drw = get_polygons(41, 0)
-dfpad_drw = dfpad_drw.not(nodrc_drw)
count = dfpad_drw.count()
logger.info("dfpad_drw has #{count} polygons")
polygons_count += count
dfpad_pillar = get_polygons(41, 35)
-dfpad_pillar = dfpad_pillar.not(nodrc_drw)
count = dfpad_pillar.count()
logger.info("dfpad_pillar has #{count} polygons")
polygons_count += count
dfpad_sbump = get_polygons(41, 36)
-dfpad_sbump = dfpad_sbump.not(nodrc_drw)
count = dfpad_sbump.count()
logger.info("dfpad_sbump has #{count} polygons")
polygons_count += count
thickgateox_drw = get_polygons(44, 0)
-thickgateox_drw = thickgateox_drw.not(nodrc_drw)
count = thickgateox_drw.count()
logger.info("thickgateox_drw has #{count} polygons")
polygons_count += count
pldb_drw = get_polygons(45, 0)
-pldb_drw = pldb_drw.not(nodrc_drw)
count = pldb_drw.count()
logger.info("pldb_drw has #{count} polygons")
polygons_count += count
pwell_drw = get_polygons(46, 0)
-pwell_drw = pwell_drw.not(nodrc_drw)
count = pwell_drw.count()
logger.info("pwell_drw has #{count} polygons")
polygons_count += count
pwell_pin = get_polygons(46, 2)
-pwell_pin = pwell_pin.not(nodrc_drw)
count = pwell_pin.count()
logger.info("pwell_pin has #{count} polygons")
polygons_count += count
pwell_block = get_polygons(46, 21)
-pwell_block = pwell_block.not(nodrc_drw)
count = pwell_block.count()
logger.info("pwell_block has #{count} polygons")
polygons_count += count
ic_drw = get_polygons(48, 0)
-ic_drw = ic_drw.not(nodrc_drw)
count = ic_drw.count()
logger.info("ic_drw has #{count} polygons")
polygons_count += count
via3_drw = get_polygons(49, 0)
-via3_drw = via3_drw.not(nodrc_drw)
count = via3_drw.count()
logger.info("via3_drw has #{count} polygons")
polygons_count += count
metal4_drw = get_polygons(50, 0)
-metal4_drw = metal4_drw.not(nodrc_drw)
count = metal4_drw.count()
logger.info("metal4_drw has #{count} polygons")
polygons_count += count
metal4_filler = get_polygons(50, 22)
-metal4_filler = metal4_filler.not(nodrc_drw)
count = metal4_filler.count()
logger.info("metal4_filler has #{count} polygons")
polygons_count += count
metal4_slit = get_polygons(50, 24)
-metal4_slit = metal4_slit.not(nodrc_drw)
count = metal4_slit.count()
logger.info("metal4_slit has #{count} polygons")
polygons_count += count
@@ -752,115 +633,96 @@ count = metal4.count()
logger.info("metal4 has #{count} polygons")
metal4_pin = get_polygons(50, 2)
-metal4_pin = metal4_pin.not(nodrc_drw)
count = metal4_pin.count()
logger.info("metal4_pin has #{count} polygons")
polygons_count += count
metal4_mask = get_polygons(50, 20)
-metal4_mask = metal4_mask.not(nodrc_drw)
count = metal4_mask.count()
logger.info("metal4_mask has #{count} polygons")
polygons_count += count
metal4_nofill = get_polygons(50, 23)
-metal4_nofill = metal4_nofill.not(nodrc_drw)
count = metal4_nofill.count()
logger.info("metal4_nofill has #{count} polygons")
polygons_count += count
metal4_text = labels(50, 25)
-metal4_text = metal4_text.not(nodrc_drw)
count = metal4_text.count()
logger.info("metal4_text has #{count} polygons")
polygons_count += count
metal4_OPC = get_polygons(50, 26)
-metal4_OPC = metal4_OPC.not(nodrc_drw)
count = metal4_OPC.count()
logger.info("metal4_OPC has #{count} polygons")
polygons_count += count
metal4_noqrc = get_polygons(50, 28)
-metal4_noqrc = metal4_noqrc.not(nodrc_drw)
count = metal4_noqrc.count()
logger.info("metal4_noqrc has #{count} polygons")
polygons_count += count
metal4_res = get_polygons(50, 29)
-metal4_res = metal4_res.not(nodrc_drw)
count = metal4_res.count()
logger.info("metal4_res has #{count} polygons")
polygons_count += count
metal4_iprobe = get_polygons(50, 33)
-metal4_iprobe = metal4_iprobe.not(nodrc_drw)
count = metal4_iprobe.count()
logger.info("metal4_iprobe has #{count} polygons")
polygons_count += count
metal4_diffprb = get_polygons(50, 34)
-metal4_diffprb = metal4_diffprb.not(nodrc_drw)
count = metal4_diffprb.count()
logger.info("metal4_diffprb has #{count} polygons")
polygons_count += count
heattrans_drw = get_polygons(51, 0)
-heattrans_drw = heattrans_drw.not(nodrc_drw)
count = heattrans_drw.count()
logger.info("heattrans_drw has #{count} polygons")
polygons_count += count
heatres_drw = get_polygons(52, 0)
-heatres_drw = heatres_drw.not(nodrc_drw)
count = heatres_drw.count()
logger.info("heatres_drw has #{count} polygons")
polygons_count += count
fbe_drw = get_polygons(54, 0)
-fbe_drw = fbe_drw.not(nodrc_drw)
count = fbe_drw.count()
logger.info("fbe_drw has #{count} polygons")
polygons_count += count
empoly_drw = get_polygons(55, 0)
-empoly_drw = empoly_drw.not(nodrc_drw)
count = empoly_drw.count()
logger.info("empoly_drw has #{count} polygons")
polygons_count += count
digisub_drw = get_polygons(60, 0)
-digisub_drw = digisub_drw.not(nodrc_drw)
count = digisub_drw.count()
logger.info("digisub_drw has #{count} polygons")
polygons_count += count
text_drw = labels(63, 0)
-text_drw = text_drw.not(nodrc_drw)
count = text_drw.count()
logger.info("text_drw has #{count} polygons")
polygons_count += count
via4_drw = get_polygons(66, 0)
-via4_drw = via4_drw.not(nodrc_drw)
count = via4_drw.count()
logger.info("via4_drw has #{count} polygons")
polygons_count += count
metal5_drw = get_polygons(67, 0)
-metal5_drw = metal5_drw.not(nodrc_drw)
count = metal5_drw.count()
logger.info("metal5_drw has #{count} polygons")
polygons_count += count
metal5_filler = get_polygons(67, 22)
-metal5_filler = metal5_filler.not(nodrc_drw)
count = metal5_filler.count()
logger.info("metal5_filler has #{count} polygons")
polygons_count += count
metal5_slit = get_polygons(67, 24)
-metal5_slit = metal5_slit.not(nodrc_drw)
count = metal5_slit.count()
logger.info("metal5_slit has #{count} polygons")
polygons_count += count
@@ -871,457 +733,381 @@ count = metal5.count()
logger.info("metal5 has #{count} polygons")
metal5_pin = get_polygons(67, 2)
-metal5_pin = metal5_pin.not(nodrc_drw)
count = metal5_pin.count()
logger.info("metal5_pin has #{count} polygons")
polygons_count += count
metal5_mask = get_polygons(67, 20)
-metal5_mask = metal5_mask.not(nodrc_drw)
count = metal5_mask.count()
logger.info("metal5_mask has #{count} polygons")
polygons_count += count
metal5_nofill = get_polygons(67, 23)
-metal5_nofill = metal5_nofill.not(nodrc_drw)
count = metal5_nofill.count()
logger.info("metal5_nofill has #{count} polygons")
polygons_count += count
metal5_text = labels(67, 25)
-metal5_text = metal5_text.not(nodrc_drw)
count = metal5_text.count()
logger.info("metal5_text has #{count} polygons")
polygons_count += count
metal5_OPC = get_polygons(67, 26)
-metal5_OPC = metal5_OPC.not(nodrc_drw)
count = metal5_OPC.count()
logger.info("metal5_OPC has #{count} polygons")
polygons_count += count
metal5_noqrc = get_polygons(67, 28)
-metal5_noqrc = metal5_noqrc.not(nodrc_drw)
count = metal5_noqrc.count()
logger.info("metal5_noqrc has #{count} polygons")
polygons_count += count
metal5_res = get_polygons(67, 29)
-metal5_res = metal5_res.not(nodrc_drw)
count = metal5_res.count()
logger.info("metal5_res has #{count} polygons")
polygons_count += count
metal5_iprobe = get_polygons(67, 33)
-metal5_iprobe = metal5_iprobe.not(nodrc_drw)
count = metal5_iprobe.count()
logger.info("metal5_iprobe has #{count} polygons")
polygons_count += count
metal5_diffprb = get_polygons(67, 34)
-metal5_diffprb = metal5_diffprb.not(nodrc_drw)
count = metal5_diffprb.count()
logger.info("metal5_diffprb has #{count} polygons")
polygons_count += count
radhard_drw = get_polygons(68, 0)
-radhard_drw = radhard_drw.not(nodrc_drw)
count = radhard_drw.count()
logger.info("radhard_drw has #{count} polygons")
polygons_count += count
memcap_drw = get_polygons(69, 0)
-memcap_drw = memcap_drw.not(nodrc_drw)
count = memcap_drw.count()
logger.info("memcap_drw has #{count} polygons")
polygons_count += count
varicap_drw = get_polygons(70, 0)
-varicap_drw = varicap_drw.not(nodrc_drw)
count = varicap_drw.count()
logger.info("varicap_drw has #{count} polygons")
polygons_count += count
intbondvia_drw = get_polygons(72, 0)
-intbondvia_drw = intbondvia_drw.not(nodrc_drw)
count = intbondvia_drw.count()
logger.info("intbondvia_drw has #{count} polygons")
polygons_count += count
intbondmet_drw = get_polygons(73, 0)
-intbondmet_drw = intbondmet_drw.not(nodrc_drw)
count = intbondmet_drw.count()
logger.info("intbondmet_drw has #{count} polygons")
polygons_count += count
devbondvia_drw = get_polygons(74, 0)
-devbondvia_drw = devbondvia_drw.not(nodrc_drw)
count = devbondvia_drw.count()
logger.info("devbondvia_drw has #{count} polygons")
polygons_count += count
devbondmet_drw = get_polygons(75, 0)
-devbondmet_drw = devbondmet_drw.not(nodrc_drw)
count = devbondmet_drw.count()
logger.info("devbondmet_drw has #{count} polygons")
polygons_count += count
devtrench_drw = get_polygons(76, 0)
-devtrench_drw = devtrench_drw.not(nodrc_drw)
count = devtrench_drw.count()
logger.info("devtrench_drw has #{count} polygons")
polygons_count += count
redist_drw = get_polygons(77, 0)
-redist_drw = redist_drw.not(nodrc_drw)
count = redist_drw.count()
logger.info("redist_drw has #{count} polygons")
polygons_count += count
graphbot_drw = get_polygons(78, 0)
-graphbot_drw = graphbot_drw.not(nodrc_drw)
count = graphbot_drw.count()
logger.info("graphbot_drw has #{count} polygons")
polygons_count += count
graphtop_drw = get_polygons(79, 0)
-graphtop_drw = graphtop_drw.not(nodrc_drw)
count = graphtop_drw.count()
logger.info("graphtop_drw has #{count} polygons")
polygons_count += count
antvia1_drw = get_polygons(83, 0)
-antvia1_drw = antvia1_drw.not(nodrc_drw)
count = antvia1_drw.count()
logger.info("antvia1_drw has #{count} polygons")
polygons_count += count
antmetal2_drw = get_polygons(84, 0)
-antmetal2_drw = antmetal2_drw.not(nodrc_drw)
count = antmetal2_drw.count()
logger.info("antmetal2_drw has #{count} polygons")
polygons_count += count
graphcont_drw = get_polygons(85, 0)
-graphcont_drw = graphcont_drw.not(nodrc_drw)
count = graphcont_drw.count()
logger.info("graphcont_drw has #{count} polygons")
polygons_count += count
siwg_drw = get_polygons(86, 0)
-siwg_drw = siwg_drw.not(nodrc_drw)
count = siwg_drw.count()
logger.info("siwg_drw has #{count} polygons")
polygons_count += count
siwg_filler = get_polygons(86, 22)
-siwg_filler = siwg_filler.not(nodrc_drw)
count = siwg_filler.count()
logger.info("siwg_filler has #{count} polygons")
polygons_count += count
siwg_nofill = get_polygons(86, 23)
-siwg_nofill = siwg_nofill.not(nodrc_drw)
count = siwg_nofill.count()
logger.info("siwg_nofill has #{count} polygons")
polygons_count += count
sigrating_drw = get_polygons(87, 0)
-sigrating_drw = sigrating_drw.not(nodrc_drw)
count = sigrating_drw.count()
logger.info("sigrating_drw has #{count} polygons")
polygons_count += count
singrating_drw = get_polygons(88, 0)
-singrating_drw = singrating_drw.not(nodrc_drw)
count = singrating_drw.count()
logger.info("singrating_drw has #{count} polygons")
polygons_count += count
graphpas_drw = get_polygons(89, 0)
-graphpas_drw = graphpas_drw.not(nodrc_drw)
count = graphpas_drw.count()
logger.info("graphpas_drw has #{count} polygons")
polygons_count += count
emwind3_drw = get_polygons(90, 0)
-emwind3_drw = emwind3_drw.not(nodrc_drw)
count = emwind3_drw.count()
logger.info("emwind3_drw has #{count} polygons")
polygons_count += count
emwihv3_drw = get_polygons(91, 0)
-emwihv3_drw = emwihv3_drw.not(nodrc_drw)
count = emwihv3_drw.count()
logger.info("emwihv3_drw has #{count} polygons")
polygons_count += count
redbulay_drw = get_polygons(92, 0)
-redbulay_drw = redbulay_drw.not(nodrc_drw)
count = redbulay_drw.count()
logger.info("redbulay_drw has #{count} polygons")
polygons_count += count
smos_drw = get_polygons(93, 0)
-smos_drw = smos_drw.not(nodrc_drw)
count = smos_drw.count()
logger.info("smos_drw has #{count} polygons")
polygons_count += count
graphpad_drw = get_polygons(97, 0)
-graphpad_drw = graphpad_drw.not(nodrc_drw)
count = graphpad_drw.count()
logger.info("graphpad_drw has #{count} polygons")
polygons_count += count
polimide_drw = get_polygons(98, 0)
-polimide_drw = polimide_drw.not(nodrc_drw)
count = polimide_drw.count()
logger.info("polimide_drw has #{count} polygons")
polygons_count += count
polimide_pin = get_polygons(98, 2)
-polimide_pin = polimide_pin.not(nodrc_drw)
count = polimide_pin.count()
logger.info("polimide_pin has #{count} polygons")
polygons_count += count
recog_drw = get_polygons(99, 0)
-recog_drw = recog_drw.not(nodrc_drw)
count = recog_drw.count()
logger.info("recog_drw has #{count} polygons")
polygons_count += count
recog_pin = get_polygons(99, 2)
-recog_pin = recog_pin.not(nodrc_drw)
count = recog_pin.count()
logger.info("recog_pin has #{count} polygons")
polygons_count += count
recog_esd = get_polygons(99, 30)
-recog_esd = recog_esd.not(nodrc_drw)
count = recog_esd.count()
logger.info("recog_esd has #{count} polygons")
polygons_count += count
recog_diode = get_polygons(99, 31)
-recog_diode = recog_diode.not(nodrc_drw)
count = recog_diode.count()
logger.info("recog_diode has #{count} polygons")
polygons_count += count
recog_tsv = get_polygons(99, 32)
-recog_tsv = recog_tsv.not(nodrc_drw)
count = recog_tsv.count()
logger.info("recog_tsv has #{count} polygons")
polygons_count += count
recog_iprobe = get_polygons(99, 33)
-recog_iprobe = recog_iprobe.not(nodrc_drw)
count = recog_iprobe.count()
logger.info("recog_iprobe has #{count} polygons")
polygons_count += count
recog_diffprb = get_polygons(99, 34)
-recog_diffprb = recog_diffprb.not(nodrc_drw)
count = recog_diffprb.count()
logger.info("recog_diffprb has #{count} polygons")
polygons_count += count
recog_pillar = get_polygons(99, 35)
-recog_pillar = recog_pillar.not(nodrc_drw)
count = recog_pillar.count()
logger.info("recog_pillar has #{count} polygons")
polygons_count += count
recog_sbump = get_polygons(99, 36)
-recog_sbump = recog_sbump.not(nodrc_drw)
count = recog_sbump.count()
logger.info("recog_sbump has #{count} polygons")
polygons_count += count
recog_otp = get_polygons(99, 37)
-recog_otp = recog_otp.not(nodrc_drw)
count = recog_otp.count()
logger.info("recog_otp has #{count} polygons")
polygons_count += count
recog_pdiode = get_polygons(99, 38)
-recog_pdiode = recog_pdiode.not(nodrc_drw)
count = recog_pdiode.count()
logger.info("recog_pdiode has #{count} polygons")
polygons_count += count
recog_mom = get_polygons(99, 39)
-recog_mom = recog_mom.not(nodrc_drw)
count = recog_mom.count()
logger.info("recog_mom has #{count} polygons")
polygons_count += count
recog_pcm = get_polygons(99, 100)
-recog_pcm = recog_pcm.not(nodrc_drw)
count = recog_pcm.count()
logger.info("recog_pcm has #{count} polygons")
polygons_count += count
colopen_drw = get_polygons(101, 0)
-colopen_drw = colopen_drw.not(nodrc_drw)
count = colopen_drw.count()
logger.info("colopen_drw has #{count} polygons")
polygons_count += count
graphmetal1_drw = get_polygons(109, 0)
-graphmetal1_drw = graphmetal1_drw.not(nodrc_drw)
count = graphmetal1_drw.count()
logger.info("graphmetal1_drw has #{count} polygons")
polygons_count += count
graphmetal1_filler = get_polygons(109, 22)
-graphmetal1_filler = graphmetal1_filler.not(nodrc_drw)
count = graphmetal1_filler.count()
logger.info("graphmetal1_filler has #{count} polygons")
polygons_count += count
graphmetal1_nofill = get_polygons(109, 23)
-graphmetal1_nofill = graphmetal1_nofill.not(nodrc_drw)
count = graphmetal1_nofill.count()
logger.info("graphmetal1_nofill has #{count} polygons")
polygons_count += count
graphmetal1_slit = get_polygons(109, 24)
-graphmetal1_slit = graphmetal1_slit.not(nodrc_drw)
count = graphmetal1_slit.count()
logger.info("graphmetal1_slit has #{count} polygons")
polygons_count += count
graphmetal1_OPC = get_polygons(109, 26)
-graphmetal1_OPC = graphmetal1_OPC.not(nodrc_drw)
count = graphmetal1_OPC.count()
logger.info("graphmetal1_OPC has #{count} polygons")
polygons_count += count
graphmet1l_drw = get_polygons(110, 0)
-graphmet1l_drw = graphmet1l_drw.not(nodrc_drw)
count = graphmet1l_drw.count()
logger.info("graphmet1l_drw has #{count} polygons")
polygons_count += count
graphmet1l_filler = get_polygons(110, 22)
-graphmet1l_filler = graphmet1l_filler.not(nodrc_drw)
count = graphmet1l_filler.count()
logger.info("graphmet1l_filler has #{count} polygons")
polygons_count += count
graphmet1l_nofill = get_polygons(110, 23)
-graphmet1l_nofill = graphmet1l_nofill.not(nodrc_drw)
count = graphmet1l_nofill.count()
logger.info("graphmet1l_nofill has #{count} polygons")
polygons_count += count
graphmet1l_slit = get_polygons(110, 24)
-graphmet1l_slit = graphmet1l_slit.not(nodrc_drw)
count = graphmet1l_slit.count()
logger.info("graphmet1l_slit has #{count} polygons")
polygons_count += count
graphmet1l_OPC = get_polygons(110, 26)
-graphmet1l_OPC = graphmet1l_OPC.not(nodrc_drw)
count = graphmet1l_OPC.count()
logger.info("graphmet1l_OPC has #{count} polygons")
polygons_count += count
extblock_drw = get_polygons(111, 0)
-extblock_drw = extblock_drw.not(nodrc_drw)
count = extblock_drw.count()
logger.info("extblock_drw has #{count} polygons")
polygons_count += count
nldd_drw = get_polygons(112, 0)
-nldd_drw = nldd_drw.not(nodrc_drw)
count = nldd_drw.count()
logger.info("nldd_drw has #{count} polygons")
polygons_count += count
pldd_drw = get_polygons(113, 0)
-pldd_drw = pldd_drw.not(nodrc_drw)
count = pldd_drw.count()
logger.info("pldd_drw has #{count} polygons")
polygons_count += count
next_drw = get_polygons(114, 0)
-next_drw = next_drw.not(nodrc_drw)
count = next_drw.count()
logger.info("next_drw has #{count} polygons")
polygons_count += count
pext_drw = get_polygons(115, 0)
-pext_drw = pext_drw.not(nodrc_drw)
count = pext_drw.count()
logger.info("pext_drw has #{count} polygons")
polygons_count += count
nexthv_drw = get_polygons(116, 0)
-nexthv_drw = nexthv_drw.not(nodrc_drw)
count = nexthv_drw.count()
logger.info("nexthv_drw has #{count} polygons")
polygons_count += count
pexthv_drw = get_polygons(117, 0)
-pexthv_drw = pexthv_drw.not(nodrc_drw)
count = pexthv_drw.count()
logger.info("pexthv_drw has #{count} polygons")
polygons_count += count
graphgate_drw = get_polygons(118, 0)
-graphgate_drw = graphgate_drw.not(nodrc_drw)
count = graphgate_drw.count()
logger.info("graphgate_drw has #{count} polygons")
polygons_count += count
sinwg_drw = get_polygons(119, 0)
-sinwg_drw = sinwg_drw.not(nodrc_drw)
count = sinwg_drw.count()
logger.info("sinwg_drw has #{count} polygons")
polygons_count += count
sinwg_filler = get_polygons(119, 22)
-sinwg_filler = sinwg_filler.not(nodrc_drw)
count = sinwg_filler.count()
logger.info("sinwg_filler has #{count} polygons")
polygons_count += count
sinwg_nofill = get_polygons(119, 23)
-sinwg_nofill = sinwg_nofill.not(nodrc_drw)
count = sinwg_nofill.count()
logger.info("sinwg_nofill has #{count} polygons")
polygons_count += count
mempad_drw = get_polygons(124, 0)
-mempad_drw = mempad_drw.not(nodrc_drw)
count = mempad_drw.count()
logger.info("mempad_drw has #{count} polygons")
polygons_count += count
topvia1_drw = get_polygons(125, 0)
-topvia1_drw = topvia1_drw.not(nodrc_drw)
count = topvia1_drw.count()
logger.info("topvia1_drw has #{count} polygons")
polygons_count += count
topmetal1_drw = get_polygons(126, 0)
-topmetal1_drw = topmetal1_drw.not(nodrc_drw)
count = topmetal1_drw.count()
logger.info("topmetal1_drw has #{count} polygons")
polygons_count += count
topmetal1_filler = get_polygons(126, 22)
-topmetal1_filler = topmetal1_filler.not(nodrc_drw)
count = topmetal1_filler.count()
logger.info("topmetal1_filler has #{count} polygons")
polygons_count += count
topmetal1_slit = get_polygons(126, 24)
-topmetal1_slit = topmetal1_slit.not(nodrc_drw)
count = topmetal1_slit.count()
logger.info("topmetal1_slit has #{count} polygons")
polygons_count += count
@@ -1332,109 +1118,91 @@ count = topmetal1.count()
logger.info("topmetal1 has #{count} polygons")
topmetal1_pin = get_polygons(126, 2)
-topmetal1_pin = topmetal1_pin.not(nodrc_drw)
count = topmetal1_pin.count()
logger.info("topmetal1_pin has #{count} polygons")
polygons_count += count
topmetal1_mask = get_polygons(126, 20)
-topmetal1_mask = topmetal1_mask.not(nodrc_drw)
count = topmetal1_mask.count()
logger.info("topmetal1_mask has #{count} polygons")
polygons_count += count
topmetal1_nofill = get_polygons(126, 23)
-topmetal1_nofill = topmetal1_nofill.not(nodrc_drw)
count = topmetal1_nofill.count()
logger.info("topmetal1_nofill has #{count} polygons")
polygons_count += count
topmetal1_text = labels(126, 25)
-topmetal1_text = topmetal1_text.not(nodrc_drw)
count = topmetal1_text.count()
logger.info("topmetal1_text has #{count} polygons")
polygons_count += count
topmetal1_noqrc = get_polygons(126, 28)
-topmetal1_noqrc = topmetal1_noqrc.not(nodrc_drw)
count = topmetal1_noqrc.count()
logger.info("topmetal1_noqrc has #{count} polygons")
polygons_count += count
topmetal1_res = get_polygons(126, 29)
-topmetal1_res = topmetal1_res.not(nodrc_drw)
count = topmetal1_res.count()
logger.info("topmetal1_res has #{count} polygons")
polygons_count += count
topmetal1_iprobe = get_polygons(126, 33)
-topmetal1_iprobe = topmetal1_iprobe.not(nodrc_drw)
count = topmetal1_iprobe.count()
logger.info("topmetal1_iprobe has #{count} polygons")
polygons_count += count
topmetal1_diffprb = get_polygons(126, 34)
-topmetal1_diffprb = topmetal1_diffprb.not(nodrc_drw)
count = topmetal1_diffprb.count()
logger.info("topmetal1_diffprb has #{count} polygons")
polygons_count += count
inldpwl_drw = get_polygons(127, 0)
-inldpwl_drw = inldpwl_drw.not(nodrc_drw)
count = inldpwl_drw.count()
logger.info("inldpwl_drw has #{count} polygons")
polygons_count += count
polyres_drw = get_polygons(128, 0)
-polyres_drw = polyres_drw.not(nodrc_drw)
count = polyres_drw.count()
logger.info("polyres_drw has #{count} polygons")
polygons_count += count
polyres_pin = get_polygons(128, 2)
-polyres_pin = polyres_pin.not(nodrc_drw)
count = polyres_pin.count()
logger.info("polyres_pin has #{count} polygons")
polygons_count += count
vmim_drw = get_polygons(129, 0)
-vmim_drw = vmim_drw.not(nodrc_drw)
count = vmim_drw.count()
logger.info("vmim_drw has #{count} polygons")
polygons_count += count
nbulaycut_drw = get_polygons(131, 0)
-nbulaycut_drw = nbulaycut_drw.not(nodrc_drw)
count = nbulaycut_drw.count()
logger.info("nbulaycut_drw has #{count} polygons")
polygons_count += count
antmetal1_drw = get_polygons(132, 0)
-antmetal1_drw = antmetal1_drw.not(nodrc_drw)
count = antmetal1_drw.count()
logger.info("antmetal1_drw has #{count} polygons")
polygons_count += count
topvia2_drw = get_polygons(133, 0)
-topvia2_drw = topvia2_drw.not(nodrc_drw)
count = topvia2_drw.count()
logger.info("topvia2_drw has #{count} polygons")
polygons_count += count
topmetal2_drw = get_polygons(134, 0)
-topmetal2_drw = topmetal2_drw.not(nodrc_drw)
count = topmetal2_drw.count()
logger.info("topmetal2_drw has #{count} polygons")
polygons_count += count
topmetal2_filler = get_polygons(134, 22)
-topmetal2_filler = topmetal2_filler.not(nodrc_drw)
count = topmetal2_filler.count()
logger.info("topmetal2_filler has #{count} polygons")
polygons_count += count
topmetal2_slit = get_polygons(134, 24)
-topmetal2_slit = topmetal2_slit.not(nodrc_drw)
count = topmetal2_slit.count()
logger.info("topmetal2_slit has #{count} polygons")
polygons_count += count
@@ -1445,409 +1213,341 @@ count = topmetal2.count()
logger.info("topmetal2 has #{count} polygons")
topmetal2_pin = get_polygons(134, 2)
-topmetal2_pin = topmetal2_pin.not(nodrc_drw)
count = topmetal2_pin.count()
logger.info("topmetal2_pin has #{count} polygons")
polygons_count += count
topmetal2_mask = get_polygons(134, 20)
-topmetal2_mask = topmetal2_mask.not(nodrc_drw)
count = topmetal2_mask.count()
logger.info("topmetal2_mask has #{count} polygons")
polygons_count += count
topmetal2_nofill = get_polygons(134, 23)
-topmetal2_nofill = topmetal2_nofill.not(nodrc_drw)
count = topmetal2_nofill.count()
logger.info("topmetal2_nofill has #{count} polygons")
polygons_count += count
topmetal2_text = labels(134, 25)
-topmetal2_text = topmetal2_text.not(nodrc_drw)
count = topmetal2_text.count()
logger.info("topmetal2_text has #{count} polygons")
polygons_count += count
topmetal2_noqrc = get_polygons(134, 28)
-topmetal2_noqrc = topmetal2_noqrc.not(nodrc_drw)
count = topmetal2_noqrc.count()
logger.info("topmetal2_noqrc has #{count} polygons")
polygons_count += count
topmetal2_res = get_polygons(134, 29)
-topmetal2_res = topmetal2_res.not(nodrc_drw)
count = topmetal2_res.count()
logger.info("topmetal2_res has #{count} polygons")
polygons_count += count
topmetal2_iprobe = get_polygons(134, 33)
-topmetal2_iprobe = topmetal2_iprobe.not(nodrc_drw)
count = topmetal2_iprobe.count()
logger.info("topmetal2_iprobe has #{count} polygons")
polygons_count += count
topmetal2_diffprb = get_polygons(134, 34)
-topmetal2_diffprb = topmetal2_diffprb.not(nodrc_drw)
count = topmetal2_diffprb.count()
logger.info("topmetal2_diffprb has #{count} polygons")
polygons_count += count
snsring_drw = get_polygons(135, 0)
-snsring_drw = snsring_drw.not(nodrc_drw)
count = snsring_drw.count()
logger.info("snsring_drw has #{count} polygons")
polygons_count += count
sensor_drw = get_polygons(136, 0)
-sensor_drw = sensor_drw.not(nodrc_drw)
count = sensor_drw.count()
logger.info("sensor_drw has #{count} polygons")
polygons_count += count
snsarms_drw = get_polygons(137, 0)
-snsarms_drw = snsarms_drw.not(nodrc_drw)
count = snsarms_drw.count()
logger.info("snsarms_drw has #{count} polygons")
polygons_count += count
snscmosvia_drw = get_polygons(138, 0)
-snscmosvia_drw = snscmosvia_drw.not(nodrc_drw)
count = snscmosvia_drw.count()
logger.info("snscmosvia_drw has #{count} polygons")
polygons_count += count
colwind_drw = get_polygons(139, 0)
-colwind_drw = colwind_drw.not(nodrc_drw)
count = colwind_drw.count()
logger.info("colwind_drw has #{count} polygons")
polygons_count += count
flm_drw = get_polygons(142, 0)
-flm_drw = flm_drw.not(nodrc_drw)
count = flm_drw.count()
logger.info("flm_drw has #{count} polygons")
polygons_count += count
hafniumox_drw = get_polygons(143, 0)
-hafniumox_drw = hafniumox_drw.not(nodrc_drw)
count = hafniumox_drw.count()
logger.info("hafniumox_drw has #{count} polygons")
polygons_count += count
memvia_drw = get_polygons(145, 0)
-memvia_drw = memvia_drw.not(nodrc_drw)
count = memvia_drw.count()
logger.info("memvia_drw has #{count} polygons")
polygons_count += count
thinfilmres_drw = get_polygons(146, 0)
-thinfilmres_drw = thinfilmres_drw.not(nodrc_drw)
count = thinfilmres_drw.count()
logger.info("thinfilmres_drw has #{count} polygons")
polygons_count += count
rfmem_drw = get_polygons(147, 0)
-rfmem_drw = rfmem_drw.not(nodrc_drw)
count = rfmem_drw.count()
logger.info("rfmem_drw has #{count} polygons")
polygons_count += count
norcx_drw = get_polygons(148, 0)
-norcx_drw = norcx_drw.not(nodrc_drw)
count = norcx_drw.count()
logger.info("norcx_drw has #{count} polygons")
polygons_count += count
norcx_m2m3 = get_polygons(148, 41)
-norcx_m2m3 = norcx_m2m3.not(nodrc_drw)
count = norcx_m2m3.count()
logger.info("norcx_m2m3 has #{count} polygons")
polygons_count += count
norcx_m2m4 = get_polygons(148, 42)
-norcx_m2m4 = norcx_m2m4.not(nodrc_drw)
count = norcx_m2m4.count()
logger.info("norcx_m2m4 has #{count} polygons")
polygons_count += count
norcx_m2m5 = get_polygons(148, 43)
-norcx_m2m5 = norcx_m2m5.not(nodrc_drw)
count = norcx_m2m5.count()
logger.info("norcx_m2m5 has #{count} polygons")
polygons_count += count
norcx_m2tm1 = get_polygons(148, 44)
-norcx_m2tm1 = norcx_m2tm1.not(nodrc_drw)
count = norcx_m2tm1.count()
logger.info("norcx_m2tm1 has #{count} polygons")
polygons_count += count
norcx_m2tm2 = get_polygons(148, 45)
-norcx_m2tm2 = norcx_m2tm2.not(nodrc_drw)
count = norcx_m2tm2.count()
logger.info("norcx_m2tm2 has #{count} polygons")
polygons_count += count
norcx_m3m4 = get_polygons(148, 46)
-norcx_m3m4 = norcx_m3m4.not(nodrc_drw)
count = norcx_m3m4.count()
logger.info("norcx_m3m4 has #{count} polygons")
polygons_count += count
norcx_m3m5 = get_polygons(148, 47)
-norcx_m3m5 = norcx_m3m5.not(nodrc_drw)
count = norcx_m3m5.count()
logger.info("norcx_m3m5 has #{count} polygons")
polygons_count += count
norcx_m3tm1 = get_polygons(148, 48)
-norcx_m3tm1 = norcx_m3tm1.not(nodrc_drw)
count = norcx_m3tm1.count()
logger.info("norcx_m3tm1 has #{count} polygons")
polygons_count += count
norcx_m3tm2 = get_polygons(148, 49)
-norcx_m3tm2 = norcx_m3tm2.not(nodrc_drw)
count = norcx_m3tm2.count()
logger.info("norcx_m3tm2 has #{count} polygons")
polygons_count += count
norcx_m4m5 = get_polygons(148, 50)
-norcx_m4m5 = norcx_m4m5.not(nodrc_drw)
count = norcx_m4m5.count()
logger.info("norcx_m4m5 has #{count} polygons")
polygons_count += count
norcx_m4tm1 = get_polygons(148, 51)
-norcx_m4tm1 = norcx_m4tm1.not(nodrc_drw)
count = norcx_m4tm1.count()
logger.info("norcx_m4tm1 has #{count} polygons")
polygons_count += count
norcx_m4tm2 = get_polygons(148, 52)
-norcx_m4tm2 = norcx_m4tm2.not(nodrc_drw)
count = norcx_m4tm2.count()
logger.info("norcx_m4tm2 has #{count} polygons")
polygons_count += count
norcx_m5tm1 = get_polygons(148, 53)
-norcx_m5tm1 = norcx_m5tm1.not(nodrc_drw)
count = norcx_m5tm1.count()
logger.info("norcx_m5tm1 has #{count} polygons")
polygons_count += count
norcx_m5tm2 = get_polygons(148, 54)
-norcx_m5tm2 = norcx_m5tm2.not(nodrc_drw)
count = norcx_m5tm2.count()
logger.info("norcx_m5tm2 has #{count} polygons")
polygons_count += count
norcx_tm1tm2 = get_polygons(148, 55)
-norcx_tm1tm2 = norcx_tm1tm2.not(nodrc_drw)
count = norcx_tm1tm2.count()
logger.info("norcx_tm1tm2 has #{count} polygons")
polygons_count += count
norcx_m1sub = get_polygons(148, 123)
-norcx_m1sub = norcx_m1sub.not(nodrc_drw)
count = norcx_m1sub.count()
logger.info("norcx_m1sub has #{count} polygons")
polygons_count += count
norcx_m2sub = get_polygons(148, 124)
-norcx_m2sub = norcx_m2sub.not(nodrc_drw)
count = norcx_m2sub.count()
logger.info("norcx_m2sub has #{count} polygons")
polygons_count += count
norcx_m3sub = get_polygons(148, 125)
-norcx_m3sub = norcx_m3sub.not(nodrc_drw)
count = norcx_m3sub.count()
logger.info("norcx_m3sub has #{count} polygons")
polygons_count += count
norcx_m4sub = get_polygons(148, 126)
-norcx_m4sub = norcx_m4sub.not(nodrc_drw)
count = norcx_m4sub.count()
logger.info("norcx_m4sub has #{count} polygons")
polygons_count += count
norcx_m5sub = get_polygons(148, 127)
-norcx_m5sub = norcx_m5sub.not(nodrc_drw)
count = norcx_m5sub.count()
logger.info("norcx_m5sub has #{count} polygons")
polygons_count += count
norcx_tm1sub = get_polygons(148, 300)
-norcx_tm1sub = norcx_tm1sub.not(nodrc_drw)
count = norcx_tm1sub.count()
logger.info("norcx_tm1sub has #{count} polygons")
polygons_count += count
norcx_tm2sub = get_polygons(148, 301)
-norcx_tm2sub = norcx_tm2sub.not(nodrc_drw)
count = norcx_tm2sub.count()
logger.info("norcx_tm2sub has #{count} polygons")
polygons_count += count
snsbotvia_drw = get_polygons(149, 0)
-snsbotvia_drw = snsbotvia_drw.not(nodrc_drw)
count = snsbotvia_drw.count()
logger.info("snsbotvia_drw has #{count} polygons")
polygons_count += count
snstopvia_drw = get_polygons(151, 0)
-snstopvia_drw = snstopvia_drw.not(nodrc_drw)
count = snstopvia_drw.count()
logger.info("snstopvia_drw has #{count} polygons")
polygons_count += count
deepvia_drw = get_polygons(152, 0)
-deepvia_drw = deepvia_drw.not(nodrc_drw)
count = deepvia_drw.count()
logger.info("deepvia_drw has #{count} polygons")
polygons_count += count
fgetch_drw = get_polygons(153, 0)
-fgetch_drw = fgetch_drw.not(nodrc_drw)
count = fgetch_drw.count()
logger.info("fgetch_drw has #{count} polygons")
polygons_count += count
ctrgat_drw = get_polygons(154, 0)
-ctrgat_drw = ctrgat_drw.not(nodrc_drw)
count = ctrgat_drw.count()
logger.info("ctrgat_drw has #{count} polygons")
polygons_count += count
fgimp_drw = get_polygons(155, 0)
-fgimp_drw = fgimp_drw.not(nodrc_drw)
count = fgimp_drw.count()
logger.info("fgimp_drw has #{count} polygons")
polygons_count += count
emwihv_drw = get_polygons(156, 0)
-emwihv_drw = emwihv_drw.not(nodrc_drw)
count = emwihv_drw.count()
logger.info("emwihv_drw has #{count} polygons")
polygons_count += count
lbe_drw = get_polygons(157, 0)
-lbe_drw = lbe_drw.not(nodrc_drw)
count = lbe_drw.count()
logger.info("lbe_drw has #{count} polygons")
polygons_count += count
alcustop_drw = get_polygons(159, 0)
-alcustop_drw = alcustop_drw.not(nodrc_drw)
count = alcustop_drw.count()
logger.info("alcustop_drw has #{count} polygons")
polygons_count += count
nometfiller_drw = get_polygons(160, 0)
-nometfiller_drw = nometfiller_drw.not(nodrc_drw)
count = nometfiller_drw.count()
logger.info("nometfiller_drw has #{count} polygons")
polygons_count += count
prboundary_drw = get_polygons(189, 0)
-prboundary_drw = prboundary_drw.not(nodrc_drw)
count = prboundary_drw.count()
logger.info("prboundary_drw has #{count} polygons")
polygons_count += count
exchange0_drw = get_polygons(190, 0)
-exchange0_drw = exchange0_drw.not(nodrc_drw)
count = exchange0_drw.count()
logger.info("exchange0_drw has #{count} polygons")
polygons_count += count
exchange0_pin = get_polygons(190, 2)
-exchange0_pin = exchange0_pin.not(nodrc_drw)
count = exchange0_pin.count()
logger.info("exchange0_pin has #{count} polygons")
polygons_count += count
exchange0_text = labels(190, 25)
-exchange0_text = exchange0_text.not(nodrc_drw)
count = exchange0_text.count()
logger.info("exchange0_text has #{count} polygons")
polygons_count += count
exchange1_drw = get_polygons(191, 0)
-exchange1_drw = exchange1_drw.not(nodrc_drw)
count = exchange1_drw.count()
logger.info("exchange1_drw has #{count} polygons")
polygons_count += count
exchange1_pin = get_polygons(191, 2)
-exchange1_pin = exchange1_pin.not(nodrc_drw)
count = exchange1_pin.count()
logger.info("exchange1_pin has #{count} polygons")
polygons_count += count
exchange1_text = labels(191, 25)
-exchange1_text = exchange1_text.not(nodrc_drw)
count = exchange1_text.count()
logger.info("exchange1_text has #{count} polygons")
polygons_count += count
exchange2_drw = get_polygons(192, 0)
-exchange2_drw = exchange2_drw.not(nodrc_drw)
count = exchange2_drw.count()
logger.info("exchange2_drw has #{count} polygons")
polygons_count += count
exchange2_pin = get_polygons(192, 2)
-exchange2_pin = exchange2_pin.not(nodrc_drw)
count = exchange2_pin.count()
logger.info("exchange2_pin has #{count} polygons")
polygons_count += count
exchange2_text = labels(192, 25)
-exchange2_text = exchange2_text.not(nodrc_drw)
count = exchange2_text.count()
logger.info("exchange2_text has #{count} polygons")
polygons_count += count
exchange3_drw = get_polygons(193, 0)
-exchange3_drw = exchange3_drw.not(nodrc_drw)
count = exchange3_drw.count()
logger.info("exchange3_drw has #{count} polygons")
polygons_count += count
exchange3_pin = get_polygons(193, 2)
-exchange3_pin = exchange3_pin.not(nodrc_drw)
count = exchange3_pin.count()
logger.info("exchange3_pin has #{count} polygons")
polygons_count += count
exchange3_text = labels(193, 25)
-exchange3_text = exchange3_text.not(nodrc_drw)
count = exchange3_text.count()
logger.info("exchange3_text has #{count} polygons")
polygons_count += count
exchange4_drw = get_polygons(194, 0)
-exchange4_drw = exchange4_drw.not(nodrc_drw)
count = exchange4_drw.count()
logger.info("exchange4_drw has #{count} polygons")
polygons_count += count
exchange4_pin = get_polygons(194, 2)
-exchange4_pin = exchange4_pin.not(nodrc_drw)
count = exchange4_pin.count()
logger.info("exchange4_pin has #{count} polygons")
polygons_count += count
exchange4_text = labels(194, 25)
-exchange4_text = exchange4_text.not(nodrc_drw)
count = exchange4_text.count()
logger.info("exchange4_text has #{count} polygons")
polygons_count += count
isonwell_drw = get_polygons(257, 0)
-isonwell_drw = isonwell_drw.not(nodrc_drw)
count = isonwell_drw.count()
logger.info("isonwell_drw has #{count} polygons")
polygons_count += count
diff --git a/ihp-sg13g2/libs.tech/klayout/tech/lvs/rule_decks/tap_extraction.lvs b/ihp-sg13g2/libs.tech/klayout/tech/lvs/rule_decks/tap_extraction.lvs
index d6cc82db..aab8d7d4 100644
--- a/ihp-sg13g2/libs.tech/klayout/tech/lvs/rule_decks/tap_extraction.lvs
+++ b/ihp-sg13g2/libs.tech/klayout/tech/lvs/rule_decks/tap_extraction.lvs
@@ -18,7 +18,7 @@
#==========================================================================
#================================
-# ------ EFUSE EXTRACTIONS ------
+# ------- TAPS EXTRACTIONS ------
#================================
logger.info('Starting Taps EXTRACTION')
diff --git a/ihp-sg13g2/libs.tech/klayout/tech/lvs/sg13g2_full.lylvs b/ihp-sg13g2/libs.tech/klayout/tech/lvs/sg13g2_full.lylvs
new file mode 100644
index 00000000..af0b57b6
--- /dev/null
+++ b/ihp-sg13g2/libs.tech/klayout/tech/lvs/sg13g2_full.lylvs
@@ -0,0 +1,4660 @@
+
+
+
+
+ Run Klayout LVS
+ 0.1
+ lvs
+
+
+
+ false
+ false
+ 0
+
+ true
+ Run Klayout LVS
+ tools_menu.lvs.end
+ dsl
+ lvs-dsl-xml
+
+ ]
+ num_terms = 3
+ when 'C'
+ # Determine number of terms based on component type
+ num_terms =
+ if line.downcase.include?('varicap')
+ 5
+ elsif line.downcase.include?('rfcmim')
+ 4
+ else
+ 3
+ end
+ end
+ line_no_param = line.split(' ').take(num_terms).join(' ')
+ "#{line_no_param.strip} #{valid_params.join(' ')}"
+ end
+
+ # Override parse_element method to handle exceptions gracefully
+ def parse_element(line, element)
+ # clean line
+ line = line.delete('[]$\\/')
+
+ # Prep sch for R, C
+ line = clean_sch(line, element) if %w[R C].include?(element)
+
+ super
+ rescue StandardError
+ case element
+ when 'C'
+ if line.downcase.include?('varicap')
+ super(line.to_s, 'M')
+ elsif line.downcase.include?('rfcmim')
+ super(line.to_s, 'Q')
+ else
+ super("#{line} C=1e-18", element)
+ end
+ when 'R'
+ super("#{line} R=0", element)
+ when 'D'
+ if line.downcase.include?('diodev') || line.downcase.include?('schottky')
+ super(line.to_s, 'Q')
+ else
+ super(line.to_s, element)
+ end
+ when 'L'
+ if line.downcase.include?('inductor3')
+ super("#{line} L=0", 'M')
+ else
+ super("#{line} L=0", element)
+ end
+ else
+ super
+ end
+ end
+
+ # Override the element method to handle different types of elements
+ def element(circuit, ele, name, model, value, nets, params)
+ if CUSTOM_READER.include?(ele)
+ process_device(ele, circuit, name, model, nets, params)
+ else
+ super
+ end
+ true
+ end
+
+ private
+
+ # Process device element
+ def process_device(ele, circuit, name, model, nets, params)
+ cls = circuit.netlist.device_class_by_name(model)
+ cls ||= create_device_class(ele, circuit, model, nets.size)
+
+ device = circuit.create_device(cls, name)
+ connect_terminals(ele, device, model, nets)
+ map_params(ele, device, model, params)
+ end
+
+ # Create or retrieve the device class based on the element type, model name, and number of nets.
+ #
+ # @param ele [String] The type of element (C, R, Q, L).
+ # @param circuit [Circuit] The circuit object to which the device class will be added.
+ # @param model [String] The model name of the device class.
+ # @param num_nets [Integer] The number of nets the device class should have.
+ # @return [RBA::DeviceClass] The created or retrieved device class.
+ def create_device_class(ele, circuit, model, num_nets)
+ cls = case ele
+ when 'M' then RBA::DeviceClassMOS4Transistor.new
+ when 'C' then create_capacitor(model, num_nets)
+ when 'R' then create_resistor(model, num_nets)
+ when 'Q' then create_bjt(model, num_nets)
+ when 'L' then DeviceCustomInd.new(model, num_nets - 1)
+ when 'D' then create_diode(model)
+ else
+ return super
+ end
+
+ cls.name = model
+ circuit.netlist.add(cls)
+ cls
+ end
+
+ # Create a capacitor device class.
+ def create_capacitor(model, num_nets)
+ if model.downcase.include?('varicap')
+ raise ArgumentError, 'Varicap should have 4 nodes, please recheck' unless num_nets == 4
+
+ DeviceCustomVaractor.new(model, num_nets - 1)
+ else
+ raise ArgumentError, 'Capacitor should have 2 or 3 nodes, please recheck' unless [2, 3].include?(num_nets)
+
+ DeviceCustomMIM.new(model)
+
+ end
+ end
+
+ # Create a diode device class.
+ def create_diode(model)
+ if model.downcase.include?('diodev') || model.downcase.include?('schottky')
+ Esd3Term.new
+ elsif model.downcase.include?('nmoscl')
+ Esd2Term.new
+ else
+ EnDiode.new
+ end
+ end
+
+ # Create a resistor device class.
+ def create_resistor(model, num_nets)
+ if RES_DEV.any? { |res| model.downcase.start_with?(res) }
+ DeviceCustomRes.new(model, num_nets)
+ elsif num_nets == 2 && model.downcase.include?('tap')
+ RBA::DeviceClassDiode.new
+ elsif num_nets == 2
+ RBA::DeviceClassResistor.new
+ elsif num_nets == 3
+ RBA::DeviceClassResistorWithBulk.new
+ else
+ raise ArgumentError, 'Resistor should have two or three nodes, please recheck'
+ end
+ end
+
+ # Create a bjt device class.
+ def create_bjt(model, _num_nets)
+ if model.downcase.include?('pnp')
+ CustomBJT3.new
+ else
+ CustomBJT4.new
+ end
+ end
+
+ # Connect device terminals based on element type, device, model, and nets.
+ #
+ # @param ele [String] The type of element (C, R, Q).
+ # @param device [RBA::Device] The device object to which terminals will be connected.
+ # @param model [String] The model name of the device.
+ # @param nets [Array] Array of net names to which terminals will be connected.
+ def connect_terminals(ele, device, model, nets)
+ term_list = terminal_list_for_element(ele, model, nets)
+
+ term_list.each_with_index do |t, index|
+ device.connect_terminal(t, nets[index])
+ end
+ end
+
+ # Determine terminal list based on element type, model, and nets.
+ def terminal_list_for_element(ele, model, nets)
+ case ele
+ when 'M'
+ %w[D G S B]
+ when 'Q'
+ model.downcase.include?('pnp') ? %w[C B E] : %w[C B E S]
+ when 'C'
+ model.downcase.include?('varicap') ? gen_term_with_sub(model, nets.size) : gen_mim_terms(model)
+ when 'R'
+ if RES_DEV.any? { |res| model.downcase.start_with?(res) }
+ gen_term_names(model, nets.size)
+ elsif model.downcase.include?('tap')
+ %w[C A]
+ else
+ nets.size == 3 ? %w[A B W] : %w[A B]
+ end
+ when 'D'
+ if model.downcase.include?('diodevdd')
+ %w[B E C]
+ elsif model.downcase.include?('diodevss')
+ %w[C E B]
+ elsif model.downcase.include?('schottky')
+ %w[E B C]
+ elsif model.downcase.include?('nmoscl')
+ %w[C A]
+ else
+ %w[A C]
+ end
+ when 'L'
+ gen_term_with_sub(model, nets.size)
+ else
+ gen_term_names(model, nets.size)
+ end
+ end
+
+ # Generate terminal names based on model and the number of nets.
+ def gen_term_names(model, size)
+ (0...size).map { |i| "#{model}_#{i + 1}" }
+ end
+
+ # Generate terminal names based on model and the number of nets.
+ def gen_mim_terms(model)
+ terms = %w[mim_top mim_btm]
+
+ return terms unless model.downcase.include?('rfcmim')
+
+ terms << 'mim_sub' # Add sub terminal
+ terms
+ end
+
+ # Generate terminal names based on model and the number of nets.
+ def gen_term_with_sub(model, size)
+ terms = (0...size - 1).map { |i| "#{model}_#{i + 1}" }
+ terms << "#{model}_sub" # Add sub terminal
+ end
+
+ # Map parameters based on the model type.
+ #
+ # @param ele [String] The type of element (M, C, R, Q, L, D).
+ # @param device [RBA::Device] The device object to which parameters will be mapped.
+ # @param model [String] The model name of the device.
+ # @param params [Hash] Hash containing parameter values.
+ def map_params(ele, device, model, params)
+ case ele
+ when 'M'
+ map_mos_params(device, params)
+ when 'Q'
+ map_bjt_params(device, model, params)
+ when 'C'
+ map_capacitor_params(device, model, params)
+ when 'R'
+ map_resistor_params(device, model, params)
+ when 'D'
+ map_diode_params(device, model, params)
+ when 'L'
+ map_inductor_params(device, params)
+ else
+ raise ArgumentError, "#{ele} device with model #{model} is not supported, please recheck"
+ end
+ end
+
+ # Map parameters for mos devices.
+ def map_mos_params(device, params)
+ device.set_parameter('W', (params['W'] || 0.0) * (params['M'] || 1.0) * 1e6)
+ device.set_parameter('L', (params['L'] || 0.0) * 1e6)
+ end
+
+ # Map parameters for a BJT device.
+ def map_bjt_params(device, model, params)
+ if model.downcase.include?('pnp')
+ device.set_parameter('AE', (params['A'] || ((params['W'] || 0.0) * (params['L'] || 0.0))) * 1e12)
+ device.set_parameter('PE', (params['P'] || (((params['W'] || 0.0) + (params['L'] || 0.0)) * 2)) * 1e6)
+ else
+ device.set_parameter('AE', (params['AE'] || ((params['WE'] || 0.0) * (params['LE'] || 0.0))) * 1e12)
+ device.set_parameter('PE', (params['PE'] || (((params['WE'] || 0.0) + (params['LE'] || 0.0)) * 2)) * 1e6)
+ end
+ device.set_parameter('NE', params['M'] || params['NE'] || 1.0)
+ device.set_parameter('m', params['M'] || params['NE'] || 1.0)
+ end
+
+ # Map parameters for a diode device.
+ def map_diode_params(device, model, params)
+ unless model.downcase.include?('diodev') || model.downcase.include?('schottky') || model.downcase.include?('nmoscl')
+ device.set_parameter('A', (params['A'] || ((params['W'] || 0.0) * (params['L'] || 0.0))) * 1e12)
+ device.set_parameter('P', (params['P'] || (((params['W'] || 0.0) + (params['L'] || 0.0)) * 2)) * 1e6)
+ end
+ device.set_parameter('m', params['M'] || 1.0)
+ end
+
+ # Map parameters for a capacitor device.
+ def map_capacitor_params(device, model, params)
+ device.set_parameter('w', (params['W'] || 0.0) * 1e6)
+ device.set_parameter('l', (params['L'] || 0.0) * 1e6)
+ device.set_parameter('m', params['M'] || params['MF'] || 1.0) if model.downcase.include?('cap_cmim')
+
+ if model.downcase.include?('mim')
+ device.set_parameter('A', (params['A'] || ((params['W'] || 0.0) * (params['L'] || 0.0))) * 1e12)
+ device.set_parameter('P', (params['P'] || (((params['W'] || 0.0) + (params['L'] || 0.0)) * 2)) * 1e6)
+ end
+ return unless model.downcase.include?('rfcmim')
+
+ device.set_parameter('wfeed', (params['WFEED'] || 0.0) * 1e6)
+ end
+
+ # Map parameters for a resistor device.
+ def map_resistor_params(device, model, params)
+ if model.downcase.include?('tap')
+ device.set_parameter('A', (params['A'] || ((params['W'] || 0.0) * (params['L'] || 0.0))) * 1e12)
+ device.set_parameter('P',
+ (params['P'] || params['PERIM'] || (((params['W'] || 0.0) + (params['L'] || 0.0)) * 2)) * 1e6)
+ elsif RES_DEV.any? { |res| model.downcase.start_with?(res) }
+ device.set_parameter('w', (params['W'] || 0.0) * 1e6)
+ device.set_parameter('l', (params['L'] || 0.0) * 1e6)
+ device.set_parameter('ps', (params['PS'] || 0.0) * 1e6)
+ device.set_parameter('b', params['B'] || 0.0)
+ device.set_parameter('m', params['M'] || 1.0)
+ else
+ device.set_parameter('W', (params['W'] || params['WIDTH'] || 0.0) * (params['M'] || 1.0) * 1e6)
+ device.set_parameter('L', (params['L'] || params['LENGTH'] || 0.0) * (params['S'] || 1.0) * 1e6)
+ device.set_parameter('R', (params['R'] || 0.0) * (params['S'] || 1.0) / (params['M'] || 1.0))
+ end
+ end
+
+ # Map parameters for an inductor device.
+ def map_inductor_params(device, params)
+ device.set_parameter('w', (params['W'] || 0.0) * 1e6)
+ device.set_parameter('s', (params['S'] || 0.0) * 1e6)
+ device.set_parameter('d', (params['D'] || 0.0) * 1e6)
+ device.set_parameter('nr_r', params['NR_R'] || 0.0)
+ end
+end
+
+#================================================
+# ---------------- CUSTOM WRITER ----------------
+#================================================
+
+#==============================
+# --------- Varaibles ---------
+#==============================
+
+# Prefix for each device
+PREFIX_MAP = {
+ 'sg13_lv_nmos' => 'M',
+ 'sg13_hv_nmos' => 'M',
+ 'sg13_lv_pmos' => 'M',
+ 'sg13_hv_pmos' => 'M',
+ 'rfnmos' => 'M',
+ 'rfnmosHV' => 'M',
+ 'rfpmos' => 'M',
+ 'rfpmosHV' => 'M',
+ 'npn13G2' => 'Q',
+ 'npn13G2L' => 'Q',
+ 'npn13G2V' => 'Q',
+ 'pnpMPA' => 'Q',
+ 'dantenna' => 'D',
+ 'dpantenna' => 'D',
+ 'schottky_nbl1' => 'D',
+ 'rsil' => 'R',
+ 'rppd' => 'R',
+ 'rhigh' => 'R',
+ 'lvsres' => 'R',
+ 'SVaricap' => 'C',
+ 'cap_cmim' => 'C',
+ 'rfcmim' => 'C',
+ 'diodevss_4kv' => 'D',
+ 'diodevss_2kv' => 'D',
+ 'diodevdd_4kv' => 'D',
+ 'diodevdd_2kv' => 'D',
+ 'idiodevss_4kv' => 'D',
+ 'idiodevss_2kv' => 'D',
+ 'idiodevdd_4kv' => 'D',
+ 'idiodevdd_2kv' => 'D',
+ 'nmoscl_2' => 'D',
+ 'nmoscl_4' => 'D',
+ 'ptap1' => 'R',
+ 'ntap1' => 'R',
+ 'inductor2' => 'L',
+ 'inductor3' => 'L'
+}.freeze
+
+# Prefix for devices will be customized
+CUSTOM_READER = %w[M C R Q L D].freeze
+
+# List of poly-resistors
+RES_DEV = ['rsil', 'rppd', 'rhigh']
+
+# Custom writer for SPICE netlists
+class CustomWriter < RBA::NetlistSpiceWriterDelegate
+ # Write device to SPICE format
+ # @param device [RBA::Device] The device to be written
+ def write_device(device)
+ device_class = device.device_class
+ str = generate_device_prefix(device, device_class)
+ str += generate_device_terminals(device, device_class)
+ str += "#{device_class.name} "
+ str += generate_default_parameters(device, device_class)
+ emit_line(str)
+ end
+
+ private
+
+ # Generate device prefix using the global prefix map
+ def generate_device_prefix(device, device_class)
+ prefix = PREFIX_MAP[device_class.name] || device.id.to_s
+ "#{prefix}#{device.expanded_name} "
+ end
+
+ # Generate device terminals
+ def generate_device_terminals(device, device_class)
+ terminals = device_class.terminal_definitions.map do |td|
+ net_to_string(device.net_for_terminal(td.id))
+ end
+ "#{terminals.join(' ')} "
+ end
+
+ # Generate parameters with given keys
+ def generate_parameters(device, *keys)
+ parameters = keys.map { |key| "#{key}=#{device.parameter(key)}" }
+ parameters.join(' ')
+ end
+
+ # Generate default parameters for the device
+ def generate_default_parameters(device, device_class)
+ parameters = device_class.parameter_definitions.map do |pd|
+ format('%s=%.12g', name: pd.name, value: device.parameter(pd.id))
+ end
+ parameters.join(' ')
+ end
+end
+
+#================================================
+# --------------- CUSTOM DEVICES ----------------
+#================================================
+
+# common methods
+module DeviceClassMethods
+ private
+
+ def add_parameters(*names)
+ names.each { |name| add_parameter(RBA::DeviceParameterDefinition.new(name)) }
+ end
+
+ def add_terminals(name, num, sub_en)
+ (1..num).each do |i|
+ terminal_name = "#{name}_#{i}"
+ ter = add_terminal(RBA::DeviceTerminalDefinition.new(terminal_name))
+ ter.name = terminal_name
+ end
+ return unless sub_en == 1
+
+ terminal_name = "#{name}_sub"
+ ter = add_terminal(RBA::DeviceTerminalDefinition.new(terminal_name))
+ ter.name = terminal_name
+ end
+end
+
+# res-custom device calss
+class DeviceCustomRes < RBA::DeviceClassResistor
+ include DeviceClassMethods
+
+ def initialize(name, num)
+ # clear terminals and parameters of resistor class
+ clear_parameters
+ clear_terminals
+
+ add_parameters('w', 'l', 'ps', 'b')
+ add_parameter(RBA::DeviceParameterDefinition.new('m', 'multiplier', 1, true))
+
+ if SERIES_RES || PARALLEL_RES
+ self.combiner = RESDeviceCombiner.new
+ else
+ self.combiner =nil
+ end
+
+ add_terminals(name, num, 0)
+ end
+end
+
+# BJT-3term device calss
+class CustomBJT3 < RBA::DeviceClassBJT3Transistor
+
+ def initialize
+ super
+ add_parameter(RBA::DeviceParameterDefinition.new('m', 'multiplier', 1, true))
+ self.combiner = BJTDeviceCombiner.new
+
+ enable_parameter('AE', true)
+ enable_parameter('PE', true)
+ enable_parameter('NE', true)
+ end
+end
+
+# BJT-4term device calss
+class CustomBJT4 < RBA::DeviceClassBJT4Transistor
+ include DeviceClassMethods
+
+ def initialize
+ super
+ add_parameter(RBA::DeviceParameterDefinition.new('m', 'multiplier', 1, true))
+ self.combiner = BJTDeviceCombiner.new
+
+ enable_parameter('AE', true)
+ enable_parameter('PE', true)
+ enable_parameter('NE', true)
+ end
+end
+
+# inductor device calss
+class DeviceCustomInd < RBA::DeviceClassInductor
+ include DeviceClassMethods
+
+ def initialize(name, num)
+ # clear terminals and parameters of class
+ clear_parameters
+ clear_terminals
+ clear_equivalent_terminal_ids
+
+ add_parameters('w', 's', 'd', 'nr_r')
+ add_terminals(name, num, 1)
+
+ # 5% tolerance for w,s,d:
+ equal_ind_parameters = RBA::EqualDeviceParameters::new(parameter_id('w'), 0.0, 0.05)
+ equal_ind_parameters += RBA::EqualDeviceParameters::new(parameter_id('s'), 0.0, 0.05)
+ equal_ind_parameters += RBA::EqualDeviceParameters::new(parameter_id('d'), 0.0, 0.05)
+ # applies the compare delegate:
+ self.equal_parameters = equal_ind_parameters
+
+ self.combiner = nil
+ self.supports_serial_combination=false
+ self.supports_parallel_combination=false
+ end
+end
+
+# Varactor-custom device calss
+class DeviceCustomVaractor < RBA::DeviceClassCapacitorWithBulk
+ include DeviceClassMethods
+
+ def initialize(name, num)
+ # clear terminals and parameters of resistor class
+ clear_parameters
+ clear_terminals
+
+ add_parameters('w', 'l')
+ add_terminals(name, num, 1)
+ end
+end
+
+# res-2term device calss
+class RES2 < RBA::DeviceClassResistor
+ def initialize
+ super
+ enable_parameter('W', true)
+ enable_parameter('L', true)
+ enable_parameter('R', false)
+ end
+end
+
+# Diode device class
+class EnDiode < RBA::DeviceClassDiode
+ def initialize
+
+ # 1% tolerance for A,P:
+ equal_diode_parameters = RBA::EqualDeviceParameters::new(parameter_id('A'), 0.0, 0.01)
+ equal_diode_parameters += RBA::EqualDeviceParameters::new(parameter_id('P'), 0.0, 0.01)
+ # applies the compare delegate:
+ self.equal_parameters = equal_diode_parameters
+
+ # combiner
+ self.combiner = DiodeDeviceCombiner.new
+ self.supports_serial_combination=true
+ self.supports_parallel_combination=true
+
+ add_parameter(RBA::DeviceParameterDefinition.new('m', 'multiplier', 1, true))
+ enable_parameter('A', true)
+ enable_parameter('P', true)
+ enable_parameter('m', true)
+ end
+end
+
+# schottky device class
+class CustomSchottky < RBA::DeviceClassBJT3Transistor
+ def initialize
+ super
+ clear_parameters
+ add_parameter(RBA::DeviceParameterDefinition.new('m', 'multiplier', 1, true))
+
+ self.combiner = SchottckyDeviceCombiner.new
+ end
+end
+
+# Taps device class
+class CustomTap < RBA::DeviceClassDiode
+ def initialize
+ super
+ clear_parameters
+ add_parameter(RBA::DeviceParameterDefinition.new('A', 'Area', 0, true))
+ add_parameter(RBA::DeviceParameterDefinition.new('P', 'Perimeter', 0, true))
+ enable_parameter('A', true)
+ enable_parameter('P', true)
+ end
+end
+
+# ESD-3term device class
+class Esd3Term < RBA::DeviceClassBJT3Transistor
+ def initialize
+ super
+ clear_parameters
+ add_parameter(RBA::DeviceParameterDefinition.new('m', 'area', 1, true))
+ enable_parameter('m', true)
+ end
+end
+
+# ESD-2term device class
+class Esd2Term < RBA::DeviceClassDiode
+ def initialize
+ super
+ clear_parameters
+ add_parameter(RBA::DeviceParameterDefinition.new('m', 'area', 1, true))
+ enable_parameter('m', true)
+ end
+end
+
+#================================================
+# -------------- CUSTOM COMBINER ----------------
+#================================================
+
+# common methods
+module DeviceCombinerMethods
+ private
+
+ # A helper function to check whether two nets are the same
+ def same_net(a, b, name)
+ a_net = a.net_for_terminal(name)
+ b_net = b.net_for_terminal(name)
+
+ # same polarity
+ same_po = a_net.expanded_name == b_net.expanded_name if a_net && b_net
+ a_net && b_net && same_po
+ end
+
+ # A helper function to check whether two device connected in parallel
+ def supp_parallel(a, b, net1, net2)
+ a_net1 = a.net_for_terminal(net1)
+ a_net2 = a.net_for_terminal(net2)
+ b_net1 = b.net_for_terminal(net1)
+ b_net2 = b.net_for_terminal(net2)
+
+ return false unless a_net1 && b_net1 && a_net2 && b_net2
+
+ same_po = a_net1.expanded_name == b_net1.expanded_name && a_net2.expanded_name == b_net2.expanded_name
+ diff_po = a_net1.expanded_name == b_net2.expanded_name && a_net2.expanded_name == b_net1.expanded_name
+
+ same_po || diff_po
+ end
+
+ # A helper function to check whether two device connected in series
+ def supp_series(a, b, net1, net2)
+ a_net1 = a.net_for_terminal(net1)
+ a_net2 = a.net_for_terminal(net2)
+ b_net1 = b.net_for_terminal(net1)
+ b_net2 = b.net_for_terminal(net2)
+
+ return false unless a_net1 && b_net1 && a_net2 && b_net2
+
+ series_con_a1 = a_net1.expanded_name == b_net1.expanded_name || a_net1.expanded_name == b_net2.expanded_name
+ series_con_a2 = a_net2.expanded_name == b_net1.expanded_name || a_net2.expanded_name == b_net2.expanded_name
+ series_con = series_con_a1 || series_con_a2
+
+ # Reroute terminal connections based on cluster IDs
+ if series_con_a1
+ if a_net1.expanded_name == b_net1.expanded_name
+ a.connect_terminal(0, b_net2)
+ else
+ a.connect_terminal(0, b_net1)
+ end
+ end
+
+ if series_con_a2
+ if a_net2.expanded_name == b_net1.expanded_name
+ a.connect_terminal(1, b_net2)
+ else
+ a.connect_terminal(1, b_net1)
+ end
+ end
+
+ series_con
+ end
+
+ # A helper function to check whether two parameters have approximately the same value
+ def same_parameter(a, b, name)
+ (a.parameter(name) - b.parameter(name)).abs < 1e-9
+ end
+end
+
+class MIMCAPNDeviceCombiner < RBA::GenericDeviceCombiner
+ include DeviceCombinerMethods
+
+ # Method to check and perform device combination
+ def combine_devices(a, b)
+ # Check if both devices have the same net
+ return false unless same_net(a, b, 'mim_top') && same_net(a, b, 'mim_btm')
+
+ # Check if parameters are the same
+ return false unless same_parameter(a, b, 'w') && same_parameter(a, b, 'l')
+
+ # Combine by summing up 'm' parameter
+ a.set_parameter('m', a.parameter('m') + b.parameter('m'))
+
+ # Disconnect the second device and let the system clean it up
+ b.disconnect_terminal('mim_top')
+ b.disconnect_terminal('mim_btm')
+
+ # Disconnect mim_sub terminal if present and model name includes 'rfcmim'
+ b.disconnect_terminal('mim_sub') if b.name.downcase.include?('rfcmim')
+
+ true
+ end
+end
+
+class DiodeDeviceCombiner < RBA::GenericDeviceCombiner
+ include DeviceCombinerMethods
+
+ # Method to check and perform device combination
+ def combine_devices(a, b)
+ # Check if both devices have the same net
+ return false unless same_net(a, b, 'A') && same_net(a, b, 'C')
+
+ # Check if parameters are the same
+ return false unless same_parameter(a, b, 'A') && same_parameter(a, b, 'P')
+
+ # Combine by summing up 'm' parameter
+ a.set_parameter('m', a.parameter('m') + b.parameter('m'))
+
+ # Disconnect the second device and let the system clean it up
+ b.disconnect_terminal('A')
+ b.disconnect_terminal('C')
+
+ true
+ end
+end
+
+class BJTDeviceCombiner < RBA::GenericDeviceCombiner
+ include DeviceCombinerMethods
+
+ # Method to check and perform device combination
+ def combine_devices(a, b)
+ bjt3_nets = %w[C B E]
+ bjt4_nets = %w[C B E S]
+
+ # Determine the correct nets based on device type (assuming PNP or NPN)
+ bjt_nets = a.device_class.name.downcase.include?('pnp') ? bjt3_nets : bjt4_nets
+
+ # Check if terminals have the same net
+ return false unless bjt_nets.all? { |net| same_net(a, b, net) }
+
+ # Check if parameters are the same
+ return false unless %w[AE PE].all? { |param| same_parameter(a, b, param) }
+
+ # Combine parameters
+ a.set_parameter('m', a.parameter('m') + b.parameter('m'))
+ a.set_parameter('NE', a.parameter('NE') + b.parameter('NE'))
+
+ # Disconnect the second device and let the system clean it up
+ bjt_nets.each { |term| b.disconnect_terminal(term) }
+
+ true
+ end
+end
+
+class RESDeviceCombiner < RBA::GenericDeviceCombiner
+ include DeviceCombinerMethods
+
+ # Method to check and perform device combination
+ def combine_devices(a, b)
+ res_nets = [0, 1] # Using id instead of names
+
+ # Check if same parameters
+
+ # Check if terminals series or parallel (With same params)
+ if supp_parallel(a, b, 0, 1)
+ return false unless PARALLEL_RES
+ return false unless %w[w l ps b].all? { |param| same_parameter(a, b, param) }
+
+ a.set_parameter('m', a.parameter('m') + b.parameter('m'))
+ elsif supp_series(a, b, 0, 1)
+ return false unless SERIES_RES
+ return false unless %w[w ps b m].all? { |param| same_parameter(a, b, param) }
+
+ a.set_parameter('l', a.parameter('l') + b.parameter('l'))
+ else
+ return false
+ end
+
+ # Disconnect the second device and let the system clean it up
+ res_nets.each { |term| b.disconnect_terminal(term) }
+
+ true
+ end
+end
+
+#================================================
+# -------------- CUSTOM EXTRACTOR ---------------
+#================================================
+
+# === GeneralNTerminalExtractor ===
+class GeneralNTerminalExtractor < RBA::GenericDeviceExtractor
+ # Extraction of N terminal devices - General Class
+
+ def initialize(name, num)
+ # Initialize the extractor with a device name and number of terminals.
+ #
+ # Args:
+ # name (String): The name of the device.
+ # num (Integer): Number of terminals.
+ create
+ self.name = name
+ @num = num
+ @name = name
+ end
+
+ def setup
+ # Set up layers and register device class for extraction.
+ define_layers
+ # Register device class for extraction.
+ if RES_DEV.any? { |res| name.downcase.start_with?(res) }
+ @reg_dev = DeviceCustomRes.new(name, @num)
+ elsif name.downcase.include?('varicap')
+ @reg_dev = DeviceCustomVaractor.new(name, @num)
+ elsif name.downcase.start_with?('ind')
+ @reg_dev = DeviceCustomInd.new(name, @num)
+ else
+ raise ArgumentError, "Custom-Class for #{name} device is not supported yet, please recheck"
+ end
+ register_device_class(@reg_dev)
+ end
+
+ def get_connectivity(_layout, layers)
+ # Establish connectivity between layers.
+ #
+ # Args:
+ # _layout: Layout object (unused).
+ # layers (Array): Array of layer objects.
+ #
+ # Returns:
+ # Connectivity object representing the connections between layers.
+ dev = layers[0]
+ ports = layers[1]
+ meas_mk = layers[2]
+ dev_mk = layers[3]
+
+ conn = RBA::Connectivity.new
+ conn.connect(dev, dev)
+ conn.connect(dev, dev_mk)
+ conn.connect(dev, meas_mk)
+ conn.connect(ports, dev_mk)
+ conn.connect(meas_mk, dev_mk)
+
+ # Sub connection for some devices
+ if name.downcase.start_with?('ind') || name.downcase.include?('varicap')
+ sub_mk = layers[4]
+ conn.connect(sub_mk, dev_mk)
+ end
+
+ conn
+ end
+
+ def extract_devices(layer_geometry)
+ # Extract devices based on layer geometry.
+ #
+ # Args:
+ # layer_geometry (Array): Array of layer geometries.
+ dev, ports, meas_mk, dev_mk, sub_mk = layer_geometry
+
+ dev_mk.merged.each do |region|
+ if ports.size != @num
+ $logger.info("#{@name} device terminals (#{@num}) don't touch device marker correctly")
+ $logger.info("No. of ports exist for #{@name} is #{ports.size}, should be #{@num}")
+ else
+ device = create_device
+ set_device_parameters(device, region, dev, ports, meas_mk, dev_mk)
+ define_and_sort_terminals(device, ports, sub_mk)
+ end
+ end
+ end
+
+ private
+
+ def define_layers
+ # Define layers for extraction.
+ define_layer('core', 'core Layer')
+ define_layer('ports', 'Connect Terminal')
+ define_layer('meas_mk', 'Measuring parameters marker')
+ define_layer('dev_mk', 'Device Marker')
+ # Define sub layer for some devices
+ if name.downcase.start_with?('ind') || name.downcase.include?('varicap')
+ define_layer('sub_mk', 'Substrate Marker')
+ end
+ end
+
+ def set_device_parameters(device, region, dev, ports, meas_mk, dev_mk)
+ # Set device parameters based on device type.
+ #
+ # Args:
+ # device: Device object to set parameters for.
+ # region: Region representing the measured region.
+ # dev: Device layer object.
+ # ports: ports layer object.
+ # meas_mk: Measuring marker layer object.
+ # dev_mk: main marker layer object.
+ #
+ # Returns:
+ # None
+
+ if RES_DEV.any? { |res| name.downcase.start_with?(res) }
+ width, length, poly_sp, bends = calc_res_params(dev, ports, meas_mk)
+ device.set_parameter('w', width * $unit)
+ device.set_parameter('l', length * $unit)
+ device.set_parameter('ps', poly_sp * $unit)
+ device.set_parameter('b', bends)
+
+ elsif name.downcase.include?('varicap')
+ width, length = calc_varicap_params(dev, ports, meas_mk, dev_mk)
+ device.set_parameter('w', width * $unit)
+ device.set_parameter('l', length * $unit)
+
+ elsif name.downcase.start_with?('ind')
+ width, space, diameter, no_turns = calc_ind_params(dev, ports, meas_mk, dev_mk, region)
+ device.set_parameter('w', width * $unit)
+ device.set_parameter('s', space * $unit)
+ device.set_parameter('d', diameter * $unit)
+ device.set_parameter('nr_r', no_turns)
+ end
+ end
+
+ def calc_res_params(dev, ports, meas_mk)
+ # Width
+ width_edges = dev.edges.and(ports.edges)
+ width = get_uniq_length(width_edges)
+
+ # Length
+ length_edges = dev.edges.interacting(width_edges).not(width_edges)
+ length, _ = get_min_max_length(length_edges)
+
+ # Bends
+ corners = meas_mk.interacting(dev).corners.not_interacting(ports).count
+ bends = corners / 4
+
+ # poly_space between bends
+ if bends.positive?
+ poly_sp_polygon = meas_mk.interacting(dev)
+ poly_sp = get_notch_min(poly_sp_polygon, 10 * length)
+ length = length + width
+ end
+
+ # Default values
+ width ||= 0
+ length ||= 0
+ poly_sp ||= 0
+ bends ||= 0
+
+ [width, length, poly_sp, bends]
+ end
+
+ def calc_varicap_params(dev, _ports, meas_mk, _dev_mk)
+ # Width & Length
+ width_edges = dev.edges.not_interacting(meas_mk.edges)
+ length, width = get_min_max_length(width_edges)
+
+ # Default values
+ width ||= 0
+ length ||= 0
+
+ [width, length]
+ end
+
+ def calc_ind_params(dev, ports, meas_mk, dev_mk, region)
+ # Get upper limit for width, space
+ _, max_mk_len = get_min_max_length(dev_mk.edges)
+
+ # Width
+ meas_sel = meas_mk.merged & region
+ width = get_width_val(meas_sel, max_mk_len)
+
+ # space
+ space = get_space_val(meas_sel, max_mk_len)
+
+ # Turns
+ # Calc steps used for no. of turns:
+ # step1: Get count of inductor metal (catch if we have more 1)
+ # Step2: For more than 1 turns, get number of holes
+ # Step3: Turns = 1 + (holes - 1)/2
+ no_turns_init = meas_mk.merged.count
+ no_turns = no_turns_init
+
+ ## Old implementation
+ # if no_turns_init == 1
+ # no_turns = no_turns_init
+ # else
+ # no_turns_pre1 = dev.merged.holes.count
+ # no_turns_pre2 = (no_turns_pre1 - 1) / 2
+ # no_turns = 1 + no_turns_pre2.ceil
+ # end
+
+ # Diameter
+ # Calc steps used for diameter:
+ # step1: Get extent of the inductor core
+ # step2: Exclude edges that touch inductor pins
+ # step3: Get length of the remaining edge (Outer diameter)
+ # step4: Get internal diameter --> din = dout - ((turns -1) * 2s) - (turns * w)
+ diam_extents = dev.extents.edges
+ diam_edge_exc = diam_extents.interacting(ports)
+ diam_edge = diam_extents.not_interacting(diam_edge_exc)
+ diameter = diam_edge.length
+ diameter = diameter - (2 * (no_turns - 1) * space) - (2 * no_turns * width)
+ diameter = diameter.negative? ? 0 : diameter
+
+ # Default values
+ width ||= 0
+ space ||= 0
+ diameter ||= 0
+ no_turns ||= 1
+
+ [width, space, diameter, no_turns]
+ end
+
+ def define_and_sort_terminals(device, ports, sub_mk)
+ # Define and sort terminals based on location.
+ #
+ # Args:
+ # device: Device object to define terminals for.
+ # ports: Contact layer object containing terminals.
+ # sub_mk: substrate marker layer object.
+ #
+ # Returns:
+ # None
+
+ # If none of the substrings match, sorted_ports remains the result of sort_polygons(ports)
+ substrings = %w[varicap]
+
+ # Initialize sorted_ports with a default value
+ sorted_ports = nil
+
+ # Iterate over each substring
+ substrings.each do |substring|
+ if name.include?(substring)
+ sorted_ports = ports
+ break # Exit loop if a match is found
+ end
+ end
+
+ # If none of the substrings match, sorted_ports remains the result of sort_polygons(ports)
+ sorted_ports ||= sort_polygons(ports)
+
+ # Define sub if exist (should be defined before other terminals)
+ if name.downcase.start_with?('ind') || name.downcase.include?('varicap')
+ if sub_mk.is_empty?
+ $logger.info("Sub terminal for #{@name} device doesn't exist, please recheck")
+ return nil
+ else
+ define_terminal(device, @reg_dev.terminal_id("#{name}_sub"), 4, sub_mk[0])
+ end
+ end
+
+ # Defination main terminals
+ (1..@num).each do |i|
+ define_terminal(device, @reg_dev.terminal_id("#{name}_#{i}"), 1, sorted_ports[i - 1])
+ end
+ end
+
+ def sort_polygons(polygons)
+ # Sort polygons points.
+ #
+ # Args:
+ # polygons: Polygons to sort.
+ #
+ # Returns:
+ # Sorted polygons.
+ #
+ # Note:
+ # This function sorts the points of the input polygons to be ordered as expected.
+ # It takes an array of polygons and returns the sorted array.
+ # The sorting is based on the x-coordinate of the first point of each polygon.
+ con_polygons = []
+
+ polygons.merged.each do |ports_pl|
+ con_edges = []
+ ports_pl.each_edge do |con_ed|
+ con_edges.append([con_ed.x1, con_ed.y1])
+ con_edges.append([con_ed.x2, con_ed.y2])
+ end
+ con_polygons.append(con_edges.uniq)
+ end
+ sorted_ports_polygons = con_polygons.sort_by(&:first)
+ sorted_ports = []
+ sorted_ports_polygons.each do |sorted_pl|
+ ports_pl = RBA::DPolygon.new([RBA::DPoint.new(sorted_pl[0][0], sorted_pl[0][1]),
+ RBA::DPoint.new(sorted_pl[1][0], sorted_pl[1][1]),
+ RBA::DPoint.new(sorted_pl[2][0], sorted_pl[2][1]),
+ RBA::DPoint.new(sorted_pl[3][0], sorted_pl[3][1])])
+ sorted_ports.append(ports_pl)
+ end
+
+ sorted_ports
+ end
+
+ def get_uniq_length(sel_edges)
+ # Extract uniqe length value for some selected edges
+ lengths = []
+ sel_edges.each do |edge|
+ lengths << edge.length
+ end
+ lengths.uniq!
+ lengths.size == 1 ? lengths[0] : 0.0
+ end
+
+ def get_sep_val(sel_edges, sep_edges, sep_val)
+ # Extract distance between edges for separation check
+ proj = RBA::Metrics::Projection
+ sep_paris = sel_edges.separation_check(sep_edges, sep_val, proj)
+ sep_values = []
+ sep_paris.each do |edge|
+ sep_values << edge.distance
+ end
+ sep_values.min
+ end
+
+ def get_space_val(sel_polygon, sep_val)
+ # Extract distance between edges for space check
+ proj = RBA::Metrics::Projection
+ space_paris = sel_polygon.space_check(sep_val, proj)
+ space_values = []
+ space_paris.each do |edge|
+ space_values << edge.distance
+ end
+ space_values.min
+ end
+
+ def get_width_val(sel_polygon, width_val)
+ # intra-polygon spacing check
+ proj = RBA::Metrics::Projection
+ width_paris = sel_polygon.width_check(width_val, metrics: proj, min_projection: 10)
+ width_values = []
+ width_paris.each do |edge|
+ width_values << edge.distance
+ end
+ # Group the array elements by their occurrences
+ width_values = width_values.reject(&:zero?)
+
+ width_values.min
+ end
+
+ def get_notch_min(sel_polygon, sep_val)
+ # intra-polygon spacing check
+ proj = RBA::Metrics::Projection
+ space_paris = sel_polygon.notch_check(sep_val, proj)
+ space_values = []
+ space_paris.each do |edge|
+ space_values << edge.distance
+ end
+ space_values.min
+ end
+
+ def get_notch_max(sel_polygon, sep_val)
+ # intra-polygon spacing check
+ proj = RBA::Metrics::Projection
+ space_paris = sel_polygon.notch_check(sep_val, proj)
+ space_values = []
+ space_paris.each do |edge|
+ space_values << edge.distance
+ end
+ space_values.max
+ end
+
+ def get_min_max_length(sel_edges)
+ # Extract max length value for some selected edges
+ lengths = []
+ sel_edges.each do |edge|
+ lengths << edge.length
+ end
+ lengths.minmax
+ end
+end
+
+#========= CUSTOM MIM-EXTRACTOR =========
+
+#================================================
+# --------------- CUSTOM DEVICES ----------------
+#================================================
+
+# MIM-custom device calss
+class DeviceCustomMIM < RBA::DeviceClassCapacitor
+ def initialize(name)
+ # clear terminals and parameters of resistor class
+ clear_parameters
+ clear_terminals
+ clear_equivalent_terminal_ids
+
+ # Adding params
+ add_parameter(RBA::DeviceParameterDefinition.new('w', 'width', 0, false))
+ add_parameter(RBA::DeviceParameterDefinition.new('l', 'length', 0, false))
+ add_parameter(RBA::DeviceParameterDefinition.new('A', 'area', 0, true))
+ add_parameter(RBA::DeviceParameterDefinition.new('P', 'perimeter', 0, true))
+ add_parameter(RBA::DeviceParameterDefinition.new('m', 'multiplier', 1, true))
+
+ # Adding terminals
+ ter1 = add_terminal(RBA::DeviceTerminalDefinition.new("mim_top"))
+ ter2 = add_terminal(RBA::DeviceTerminalDefinition.new("mim_btm"))
+ ter1.name = "mim_top"
+ ter2.name = "mim_btm"
+
+ # Adding extra param & terminal for rfcmim
+ return unless name.downcase.include?('rfcmim')
+
+ add_parameter(RBA::DeviceParameterDefinition.new('wfeed', 'feed width', 0, true))
+ sub_ter = add_terminal(RBA::DeviceTerminalDefinition.new("mim_sub"))
+ sub_ter.name = "mim_sub"
+ end
+end
+
+# === MIMCAPExtractor ===
+class MIMCAPExtractor < RBA::GenericDeviceExtractor
+ # Extraction of N terminal devices - General Class
+
+ def initialize(name)
+ # Initialize the extractor with a device name and number of terminals.
+ #
+ # Args:
+ # name (String): The name of the device.
+
+ self.name = name
+ @name = name
+ end
+
+ def setup
+ # Set up layers and register device class for extraction.
+ define_layers
+ # Register device class for extraction.
+ @reg_dev = DeviceCustomMIM.new(name)
+
+ # Disable combination for rfcmim
+ if name.downcase.include?('rfcmim')
+ @reg_dev.combiner = nil
+ else
+ @reg_dev.combiner = MIMCAPNDeviceCombiner.new
+ end
+ register_device_class(@reg_dev)
+ end
+
+ def get_connectivity(_layout, layers)
+ # Establish connectivity between layers.
+ #
+ # Args:
+ # _layout: Layout object (unused).
+ # layers (Array): Array of layer objects.
+ #
+ # Returns:
+ # Connectivity object representing the connections between layers.
+ dev = layers[0]
+ top_mim = layers[1]
+ btm_mim = layers[2]
+ dev_mk = layers[3]
+ meas_mk = layers[4]
+
+ conn = RBA::Connectivity.new
+ conn.connect(dev, dev)
+ conn.connect(dev, dev_mk)
+ conn.connect(dev, meas_mk)
+ conn.connect(top_mim, dev_mk)
+ conn.connect(btm_mim, dev_mk)
+
+ # Sub connection for rfcmim
+ if name.downcase.include?('rfcmim')
+ sub_mk = layers[5]
+ conn.connect(sub_mk, dev_mk)
+ end
+
+ conn
+ end
+
+ def extract_devices(layer_geometry)
+ # Extract devices based on layer geometry.
+ #
+ # Args:
+ # layer_geometry (Array): Array of layer geometries.
+ dev, top_mim, btm_mim, dev_mk, meas_mk, sub_mk = layer_geometry
+
+ dev_mk.merged.each do |_region|
+ if top_mim.size != 1
+ $logger.info("No. of ports exist for #{@name} topmetal is #{top_mim.size}, should be 1")
+ elsif btm_mim.size != 1
+ $logger.info("No. of ports exist for #{@name} btmmetal is #{btm_mim.size}, should be 1")
+ else
+ device = create_device
+ set_device_parameters(device, dev, dev_mk, meas_mk)
+ define_terminals(device, top_mim, btm_mim, sub_mk)
+ end
+ end
+ end
+
+ private
+
+ def define_layers
+ # Define layers for extraction.
+ define_layer('core', 'core Layer')
+ define_layer('top_mim', 'Connect Terminal for top mim')
+ define_layer('btm_mim', 'Connect Terminal for btm mim')
+ define_layer('dev_mk', 'Device Marker')
+ define_layer('meas_mk', 'Measuring parameters marker')
+
+ # Define sub layer for some devices
+ return unless name.downcase.include?('rfcmim')
+
+ define_layer('sub_mk', 'Substrate layer')
+ end
+
+ def set_device_parameters(device, dev, dev_mk, meas_mk)
+ # Set device parameters based on device type.
+ #
+ # Args:
+ # device: Device object to set parameters for.
+ # dev: Device layer object.
+ # dev_mk: device marker layer object.
+ # meas_mk: meas marker layer object.
+ #
+ # Returns:
+ # None
+
+ width, length, wfeed = calc_cmim_params(dev, dev_mk, meas_mk)
+
+ if name.downcase.include?('rfcmim')
+ device.set_parameter('l', width * $unit)
+ device.set_parameter('w', length * $unit)
+ device.set_parameter('wfeed', wfeed * $unit)
+ else
+ device.set_parameter('w', width * $unit)
+ device.set_parameter('l', length * $unit)
+ end
+ device.set_parameter('A', width * length * $unit * $unit)
+ device.set_parameter('P', (width + length) * 2 * $unit)
+
+ end
+
+ def calc_cmim_params(dev, dev_mk, meas_mk)
+ # Width & Length
+ dev_edges = dev.edges
+ width_edges = dev_edges.with_angle(0, false)
+ len_edges = dev_edges.not(width_edges)
+ width = get_uniq_length(width_edges)
+ length = get_uniq_length(len_edges)
+
+ # Wfeed
+ wfeed_edges = meas_mk.edges.and(dev_mk.edges)
+ wfeed = get_uniq_length(wfeed_edges)
+
+ # Default values
+ width ||= 0
+ length ||= 0
+ wfeed ||= 0
+
+ [width, length, wfeed]
+ end
+
+ def define_terminals(device, top_mim, btm_mim, sub_mk)
+ # Define terminals based on location.
+ #
+ # Args:
+ # device: Device object to define terminals for.
+ # top_mim: Contact layer object containing mim top metal.
+ # top_mim: Contact layer object containing mim btm metal.
+ # sub_mk: substrate marker layer object.
+ #
+ # Returns:
+ # None
+
+ # Define sub if exist (should be defined before other terminals)
+ if name.downcase.include?('rfcmim')
+ if sub_mk.is_empty?
+ $logger.info("Sub terminal for #{@name} device doesn't exist, please recheck")
+ return nil
+ else
+ define_terminal(device, @reg_dev.terminal_id("mim_sub"), 5, sub_mk[0])
+ end
+ end
+
+ # Defination main terminals
+ define_terminal(device, @reg_dev.terminal_id("mim_top"), 1, top_mim[0])
+ define_terminal(device, @reg_dev.terminal_id("mim_btm"), 2, btm_mim[0])
+ end
+
+ def get_min_max_length(sel_edges)
+ # Extract max length value for some selected edges
+ lengths = []
+ sel_edges.each do |edge|
+ lengths << edge.length
+ end
+ lengths.minmax
+ end
+
+ def get_uniq_length(sel_edges)
+ # Extract uniqe length value for some selected edges
+ lengths = []
+ sel_edges.each do |edge|
+ lengths << edge.length
+ end
+ lengths.uniq!
+ lengths.size == 1 ? lengths[0] : 0.0
+ end
+end
+
+#================================================
+# --------------- END OF CLASSES ----------------
+#================================================
+
+# Instantiate a reader using the new delegate
+reader = RBA::NetlistSpiceReader.new(CustomReader.new)
+
+#=== GET NETLIST ===
+unless NET_ONLY
+ if $cdl_file
+ schematic($cdl_file, reader)
+ logger.info("Netlist file: #{$cdl_file}")
+ else
+ exts = %w[spice cdl cir]
+ candidates = exts.map { |ext| "#{source.cell_name}.#{ext}" }
+ netlists = candidates.select { |f| File.exist?(f) }
+ if netlists.empty?
+ error("Netlist not found, tried: #{candidates}")
+ else
+ schematic(netlists[0], reader)
+ logger.info("Netlist file: #{netlists[0]}")
+ end
+ end
+end
+
+# Instantiate a writer using the new delegate
+custom_spice_writer = RBA::NetlistSpiceWriter.new(CustomWriter.new)
+custom_spice_writer.use_net_names = SPICE_WITH_NET_NAMES
+custom_spice_writer.with_comments = SPICE_WITH_COMMENTS
+
+if $target_netlist
+ logger.info("LVS extracted netlist at: #{$target_netlist}")
+ target_netlist($target_netlist, custom_spice_writer,
+ "Extracted by KLayout with SG13G2 LVS runset on : #{Time.now.strftime('%d/%m/%Y %H:%M')}")
+else
+ layout_dir = Pathname.new(RBA::CellView.active.filename).parent.realpath
+ netlist_path = layout_dir.join("#{source.cell_name}_extracted.cir")
+ target_netlist(netlist_path.to_s, custom_spice_writer,
+ "Extracted by KLayout with SG13G2 LVS runset on : #{Time.now.strftime('%d/%m/%Y %H:%M')}")
+ logger.info("SG13G2 Klayout LVS extracted netlist file at: #{source.cell_name}_extracted.cir")
+end
+
+#================================================
+#------------- LAYERS DEFINITIONS ---------------
+#================================================
+
+polygons_count = 0
+logger.info('Read in polygons from layers.')
+
+def get_polygons(lay_no, lay_dt)
+ if $run_mode == 'deep'
+ polygons(lay_no, lay_dt)
+ else
+ polygons(lay_no, lay_dt).merged
+ end
+end
+
+activ_drw = get_polygons(1, 0)
+count = activ_drw.count()
+logger.info("activ_drw has #{count} polygons")
+polygons_count += count
+
+activ_filler = get_polygons(1, 22)
+count = activ_filler.count()
+logger.info("activ_filler has #{count} polygons")
+polygons_count += count
+
+# activ org
+activ = activ_drw.join(activ_filler)
+count = activ.count()
+logger.info("activ has #{count} polygons")
+
+activ_pin = get_polygons(1, 2)
+count = activ_pin.count()
+logger.info("activ_pin has #{count} polygons")
+polygons_count += count
+
+activ_mask = get_polygons(1, 20)
+count = activ_mask.count()
+logger.info("activ_mask has #{count} polygons")
+polygons_count += count
+
+activ_nofill = get_polygons(1, 23)
+count = activ_nofill.count()
+logger.info("activ_nofill has #{count} polygons")
+polygons_count += count
+
+activ_OPC = get_polygons(1, 26)
+count = activ_OPC.count()
+logger.info("activ_OPC has #{count} polygons")
+polygons_count += count
+
+activ_iOPC = get_polygons(1, 27)
+count = activ_iOPC.count()
+logger.info("activ_iOPC has #{count} polygons")
+polygons_count += count
+
+activ_noqrc = get_polygons(1, 28)
+count = activ_noqrc.count()
+logger.info("activ_noqrc has #{count} polygons")
+polygons_count += count
+
+biwind_drw = get_polygons(3, 0)
+count = biwind_drw.count()
+logger.info("biwind_drw has #{count} polygons")
+polygons_count += count
+
+biwind_OPC = get_polygons(3, 26)
+count = biwind_OPC.count()
+logger.info("biwind_OPC has #{count} polygons")
+polygons_count += count
+
+gatpoly_drw = get_polygons(5, 0)
+count = gatpoly_drw.count()
+logger.info("gatpoly_drw has #{count} polygons")
+polygons_count += count
+
+gatpoly_filler = get_polygons(5, 22)
+count = gatpoly_filler.count()
+logger.info("gatpoly_filler has #{count} polygons")
+polygons_count += count
+
+# gatpoly org
+gatpoly = gatpoly_drw.join(gatpoly_filler)
+count = gatpoly.count()
+logger.info("gatpoly has #{count} polygons")
+
+gatpoly_pin = get_polygons(5, 2)
+count = gatpoly_pin.count()
+logger.info("gatpoly_pin has #{count} polygons")
+polygons_count += count
+
+gatpoly_nofill = get_polygons(5, 23)
+count = gatpoly_nofill.count()
+logger.info("gatpoly_nofill has #{count} polygons")
+polygons_count += count
+
+gatpoly_OPC = get_polygons(5, 26)
+count = gatpoly_OPC.count()
+logger.info("gatpoly_OPC has #{count} polygons")
+polygons_count += count
+
+gatpoly_iOPC = get_polygons(5, 27)
+count = gatpoly_iOPC.count()
+logger.info("gatpoly_iOPC has #{count} polygons")
+polygons_count += count
+
+gatpoly_noqrc = get_polygons(5, 28)
+count = gatpoly_noqrc.count()
+logger.info("gatpoly_noqrc has #{count} polygons")
+polygons_count += count
+
+cont_drw = get_polygons(6, 0)
+count = cont_drw.count()
+logger.info("cont_drw has #{count} polygons")
+polygons_count += count
+
+cont_OPC = get_polygons(6, 26)
+count = cont_OPC.count()
+logger.info("cont_OPC has #{count} polygons")
+polygons_count += count
+
+nsd_drw = get_polygons(7, 0)
+count = nsd_drw.count()
+logger.info("nsd_drw has #{count} polygons")
+polygons_count += count
+
+nsd_block = get_polygons(7, 21)
+count = nsd_block.count()
+logger.info("nsd_block has #{count} polygons")
+polygons_count += count
+
+metal1_drw = get_polygons(8, 0)
+count = metal1_drw.count()
+logger.info("metal1_drw has #{count} polygons")
+polygons_count += count
+
+metal1_filler = get_polygons(8, 22)
+count = metal1_filler.count()
+logger.info("metal1_filler has #{count} polygons")
+polygons_count += count
+
+metal1_slit = get_polygons(8, 24)
+count = metal1_slit.count()
+logger.info("metal1_slit has #{count} polygons")
+polygons_count += count
+
+# metal1 org
+metal1 = metal1_drw.join(metal1_filler).not(metal1_slit)
+count = metal1.count()
+logger.info("metal1 has #{count} polygons")
+
+metal1_pin = get_polygons(8, 2)
+count = metal1_pin.count()
+logger.info("metal1_pin has #{count} polygons")
+polygons_count += count
+
+metal1_mask = get_polygons(8, 20)
+count = metal1_mask.count()
+logger.info("metal1_mask has #{count} polygons")
+polygons_count += count
+
+metal1_nofill = get_polygons(8, 23)
+count = metal1_nofill.count()
+logger.info("metal1_nofill has #{count} polygons")
+polygons_count += count
+
+metal1_text = labels(8, 25)
+count = metal1_text.count()
+logger.info("metal1_text has #{count} polygons")
+polygons_count += count
+
+metal1_OPC = get_polygons(8, 26)
+count = metal1_OPC.count()
+logger.info("metal1_OPC has #{count} polygons")
+polygons_count += count
+
+metal1_noqrc = get_polygons(8, 28)
+count = metal1_noqrc.count()
+logger.info("metal1_noqrc has #{count} polygons")
+polygons_count += count
+
+metal1_res = get_polygons(8, 29)
+count = metal1_res.count()
+logger.info("metal1_res has #{count} polygons")
+polygons_count += count
+
+metal1_iprobe = get_polygons(8, 33)
+count = metal1_iprobe.count()
+logger.info("metal1_iprobe has #{count} polygons")
+polygons_count += count
+
+metal1_diffprb = get_polygons(8, 34)
+count = metal1_diffprb.count()
+logger.info("metal1_diffprb has #{count} polygons")
+polygons_count += count
+
+passiv_drw = get_polygons(9, 0)
+count = passiv_drw.count()
+logger.info("passiv_drw has #{count} polygons")
+polygons_count += count
+
+passiv_pin = get_polygons(9, 2)
+count = passiv_pin.count()
+logger.info("passiv_pin has #{count} polygons")
+polygons_count += count
+
+passiv_sbump = get_polygons(9, 36)
+count = passiv_sbump.count()
+logger.info("passiv_sbump has #{count} polygons")
+polygons_count += count
+
+passiv_pillar = get_polygons(9, 35)
+count = passiv_pillar.count()
+logger.info("passiv_pillar has #{count} polygons")
+polygons_count += count
+
+passiv_pdl = get_polygons(9, 40)
+count = passiv_pdl.count()
+logger.info("passiv_pdl has #{count} polygons")
+polygons_count += count
+
+metal2_drw = get_polygons(10, 0)
+count = metal2_drw.count()
+logger.info("metal2_drw has #{count} polygons")
+polygons_count += count
+
+metal2_filler = get_polygons(10, 22)
+count = metal2_filler.count()
+logger.info("metal2_filler has #{count} polygons")
+polygons_count += count
+
+metal2_slit = get_polygons(10, 24)
+count = metal2_slit.count()
+logger.info("metal2_slit has #{count} polygons")
+polygons_count += count
+
+# metal2 org
+metal2 = metal2_drw.join(metal2_filler).not(metal2_slit)
+count = metal2.count()
+logger.info("metal2 has #{count} polygons")
+
+metal2_pin = get_polygons(10, 2)
+count = metal2_pin.count()
+logger.info("metal2_pin has #{count} polygons")
+polygons_count += count
+
+metal2_mask = get_polygons(10, 20)
+count = metal2_mask.count()
+logger.info("metal2_mask has #{count} polygons")
+polygons_count += count
+
+metal2_nofill = get_polygons(10, 23)
+count = metal2_nofill.count()
+logger.info("metal2_nofill has #{count} polygons")
+polygons_count += count
+
+metal2_text = labels(10, 25)
+count = metal2_text.count()
+logger.info("metal2_text has #{count} polygons")
+polygons_count += count
+
+metal2_OPC = get_polygons(10, 26)
+count = metal2_OPC.count()
+logger.info("metal2_OPC has #{count} polygons")
+polygons_count += count
+
+metal2_noqrc = get_polygons(10, 28)
+count = metal2_noqrc.count()
+logger.info("metal2_noqrc has #{count} polygons")
+polygons_count += count
+
+metal2_res = get_polygons(10, 29)
+count = metal2_res.count()
+logger.info("metal2_res has #{count} polygons")
+polygons_count += count
+
+metal2_iprobe = get_polygons(10, 33)
+count = metal2_iprobe.count()
+logger.info("metal2_iprobe has #{count} polygons")
+polygons_count += count
+
+metal2_diffprb = get_polygons(10, 34)
+count = metal2_diffprb.count()
+logger.info("metal2_diffprb has #{count} polygons")
+polygons_count += count
+
+baspoly_drw = get_polygons(13, 0)
+count = baspoly_drw.count()
+logger.info("baspoly_drw has #{count} polygons")
+polygons_count += count
+
+baspoly_pin = get_polygons(13, 2)
+count = baspoly_pin.count()
+logger.info("baspoly_pin has #{count} polygons")
+polygons_count += count
+
+psd_drw = get_polygons(14, 0)
+count = psd_drw.count()
+logger.info("psd_drw has #{count} polygons")
+polygons_count += count
+
+nldb_drw = get_polygons(15, 0)
+count = nldb_drw.count()
+logger.info("nldb_drw has #{count} polygons")
+polygons_count += count
+
+digibnd_drw = get_polygons(16, 0)
+count = digibnd_drw.count()
+logger.info("digibnd_drw has #{count} polygons")
+polygons_count += count
+
+via1_drw = get_polygons(19, 0)
+count = via1_drw.count()
+logger.info("via1_drw has #{count} polygons")
+polygons_count += count
+
+backmetal1_drw = get_polygons(20, 0)
+count = backmetal1_drw.count()
+logger.info("backmetal1_drw has #{count} polygons")
+polygons_count += count
+
+backmetal1_pin = get_polygons(20, 2)
+count = backmetal1_pin.count()
+logger.info("backmetal1_pin has #{count} polygons")
+polygons_count += count
+
+backmetal1_mask = get_polygons(20, 20)
+count = backmetal1_mask.count()
+logger.info("backmetal1_mask has #{count} polygons")
+polygons_count += count
+
+backmetal1_filler = get_polygons(20, 22)
+count = backmetal1_filler.count()
+logger.info("backmetal1_filler has #{count} polygons")
+polygons_count += count
+
+backmetal1_nofill = get_polygons(20, 23)
+count = backmetal1_nofill.count()
+logger.info("backmetal1_nofill has #{count} polygons")
+polygons_count += count
+
+backmetal1_slit = get_polygons(20, 24)
+count = backmetal1_slit.count()
+logger.info("backmetal1_slit has #{count} polygons")
+polygons_count += count
+
+backmetal1_text = labels(20, 25)
+count = backmetal1_text.count()
+logger.info("backmetal1_text has #{count} polygons")
+polygons_count += count
+
+backmetal1_OPC = get_polygons(20, 26)
+count = backmetal1_OPC.count()
+logger.info("backmetal1_OPC has #{count} polygons")
+polygons_count += count
+
+backmetal1_noqrc = get_polygons(20, 28)
+count = backmetal1_noqrc.count()
+logger.info("backmetal1_noqrc has #{count} polygons")
+polygons_count += count
+
+backmetal1_res = get_polygons(20, 29)
+count = backmetal1_res.count()
+logger.info("backmetal1_res has #{count} polygons")
+polygons_count += count
+
+backmetal1_iprobe = get_polygons(20, 33)
+count = backmetal1_iprobe.count()
+logger.info("backmetal1_iprobe has #{count} polygons")
+polygons_count += count
+
+backmetal1_diffprb = get_polygons(20, 34)
+count = backmetal1_diffprb.count()
+logger.info("backmetal1_diffprb has #{count} polygons")
+polygons_count += count
+
+backpassiv_drw = get_polygons(23, 0)
+count = backpassiv_drw.count()
+logger.info("backpassiv_drw has #{count} polygons")
+polygons_count += count
+
+res_drw = get_polygons(24, 0)
+count = res_drw.count()
+logger.info("res_drw has #{count} polygons")
+polygons_count += count
+
+sram_drw = get_polygons(25, 0)
+count = sram_drw.count()
+logger.info("sram_drw has #{count} polygons")
+polygons_count += count
+
+trans_drw = get_polygons(26, 0)
+count = trans_drw.count()
+logger.info("trans_drw has #{count} polygons")
+polygons_count += count
+
+ind_drw = get_polygons(27, 0)
+count = ind_drw.count()
+logger.info("ind_drw has #{count} polygons")
+polygons_count += count
+
+ind_pin = get_polygons(27, 2)
+count = ind_pin.count()
+logger.info("ind_pin has #{count} polygons")
+polygons_count += count
+
+ind_text = labels(27, 25)
+count = ind_text.count()
+logger.info("ind_text has #{count} polygons")
+polygons_count += count
+
+salblock_drw = get_polygons(28, 0)
+count = salblock_drw.count()
+logger.info("salblock_drw has #{count} polygons")
+polygons_count += count
+
+via2_drw = get_polygons(29, 0)
+count = via2_drw.count()
+logger.info("via2_drw has #{count} polygons")
+polygons_count += count
+
+metal3_drw = get_polygons(30, 0)
+count = metal3_drw.count()
+logger.info("metal3_drw has #{count} polygons")
+polygons_count += count
+
+metal3_filler = get_polygons(30, 22)
+count = metal3_filler.count()
+logger.info("metal3_filler has #{count} polygons")
+polygons_count += count
+
+metal3_slit = get_polygons(30, 24)
+count = metal3_slit.count()
+logger.info("metal3_slit has #{count} polygons")
+polygons_count += count
+
+# metal3 org
+metal3 = metal3_drw.join(metal3_filler).not(metal3_slit)
+count = metal3.count()
+logger.info("metal3 has #{count} polygons")
+
+metal3_pin = get_polygons(30, 2)
+count = metal3_pin.count()
+logger.info("metal3_pin has #{count} polygons")
+polygons_count += count
+
+metal3_mask = get_polygons(30, 20)
+count = metal3_mask.count()
+logger.info("metal3_mask has #{count} polygons")
+polygons_count += count
+
+metal3_nofill = get_polygons(30, 23)
+count = metal3_nofill.count()
+logger.info("metal3_nofill has #{count} polygons")
+polygons_count += count
+
+metal3_text = labels(30, 25)
+count = metal3_text.count()
+logger.info("metal3_text has #{count} polygons")
+polygons_count += count
+
+metal3_OPC = get_polygons(30, 26)
+count = metal3_OPC.count()
+logger.info("metal3_OPC has #{count} polygons")
+polygons_count += count
+
+metal3_noqrc = get_polygons(30, 28)
+count = metal3_noqrc.count()
+logger.info("metal3_noqrc has #{count} polygons")
+polygons_count += count
+
+metal3_res = get_polygons(30, 29)
+count = metal3_res.count()
+logger.info("metal3_res has #{count} polygons")
+polygons_count += count
+
+metal3_iprobe = get_polygons(30, 33)
+count = metal3_iprobe.count()
+logger.info("metal3_iprobe has #{count} polygons")
+polygons_count += count
+
+metal3_diffprb = get_polygons(30, 34)
+count = metal3_diffprb.count()
+logger.info("metal3_diffprb has #{count} polygons")
+polygons_count += count
+
+nwell_drw = get_polygons(31, 0)
+count = nwell_drw.count()
+logger.info("nwell_drw has #{count} polygons")
+polygons_count += count
+
+nwell_pin = get_polygons(31, 2)
+count = nwell_pin.count()
+logger.info("nwell_pin has #{count} polygons")
+polygons_count += count
+
+nbulay_drw = get_polygons(32, 0)
+count = nbulay_drw.count()
+logger.info("nbulay_drw has #{count} polygons")
+polygons_count += count
+
+nbulay_pin = get_polygons(32, 2)
+count = nbulay_pin.count()
+logger.info("nbulay_pin has #{count} polygons")
+polygons_count += count
+
+nbulay_block = get_polygons(32, 21)
+count = nbulay_block.count()
+logger.info("nbulay_block has #{count} polygons")
+polygons_count += count
+
+emwind_drw = get_polygons(33, 0)
+count = emwind_drw.count()
+logger.info("emwind_drw has #{count} polygons")
+polygons_count += count
+
+emwind_OPC = get_polygons(33, 26)
+count = emwind_OPC.count()
+logger.info("emwind_OPC has #{count} polygons")
+polygons_count += count
+
+deepco_drw = get_polygons(35, 0)
+count = deepco_drw.count()
+logger.info("deepco_drw has #{count} polygons")
+polygons_count += count
+
+mim_drw = get_polygons(36, 0)
+count = mim_drw.count()
+logger.info("mim_drw has #{count} polygons")
+polygons_count += count
+
+edgeseal_drw = get_polygons(39, 0)
+count = edgeseal_drw.count()
+logger.info("edgeseal_drw has #{count} polygons")
+polygons_count += count
+
+substrate_drw = get_polygons(40, 0)
+count = substrate_drw.count()
+logger.info("substrate_drw has #{count} polygons")
+polygons_count += count
+
+substrate_text = labels(40, 25)
+count = substrate_text.count()
+logger.info("substrate_text has #{count} polygons")
+polygons_count += count
+
+dfpad_drw = get_polygons(41, 0)
+count = dfpad_drw.count()
+logger.info("dfpad_drw has #{count} polygons")
+polygons_count += count
+
+dfpad_pillar = get_polygons(41, 35)
+count = dfpad_pillar.count()
+logger.info("dfpad_pillar has #{count} polygons")
+polygons_count += count
+
+dfpad_sbump = get_polygons(41, 36)
+count = dfpad_sbump.count()
+logger.info("dfpad_sbump has #{count} polygons")
+polygons_count += count
+
+thickgateox_drw = get_polygons(44, 0)
+count = thickgateox_drw.count()
+logger.info("thickgateox_drw has #{count} polygons")
+polygons_count += count
+
+pldb_drw = get_polygons(45, 0)
+count = pldb_drw.count()
+logger.info("pldb_drw has #{count} polygons")
+polygons_count += count
+
+pwell_drw = get_polygons(46, 0)
+count = pwell_drw.count()
+logger.info("pwell_drw has #{count} polygons")
+polygons_count += count
+
+pwell_pin = get_polygons(46, 2)
+count = pwell_pin.count()
+logger.info("pwell_pin has #{count} polygons")
+polygons_count += count
+
+pwell_block = get_polygons(46, 21)
+count = pwell_block.count()
+logger.info("pwell_block has #{count} polygons")
+polygons_count += count
+
+ic_drw = get_polygons(48, 0)
+count = ic_drw.count()
+logger.info("ic_drw has #{count} polygons")
+polygons_count += count
+
+via3_drw = get_polygons(49, 0)
+count = via3_drw.count()
+logger.info("via3_drw has #{count} polygons")
+polygons_count += count
+
+metal4_drw = get_polygons(50, 0)
+count = metal4_drw.count()
+logger.info("metal4_drw has #{count} polygons")
+polygons_count += count
+
+metal4_filler = get_polygons(50, 22)
+count = metal4_filler.count()
+logger.info("metal4_filler has #{count} polygons")
+polygons_count += count
+
+metal4_slit = get_polygons(50, 24)
+count = metal4_slit.count()
+logger.info("metal4_slit has #{count} polygons")
+polygons_count += count
+
+# metal4 org
+metal4 = metal4_drw.join(metal4_filler).not(metal4_slit)
+count = metal4.count()
+logger.info("metal4 has #{count} polygons")
+
+metal4_pin = get_polygons(50, 2)
+count = metal4_pin.count()
+logger.info("metal4_pin has #{count} polygons")
+polygons_count += count
+
+metal4_mask = get_polygons(50, 20)
+count = metal4_mask.count()
+logger.info("metal4_mask has #{count} polygons")
+polygons_count += count
+
+metal4_nofill = get_polygons(50, 23)
+count = metal4_nofill.count()
+logger.info("metal4_nofill has #{count} polygons")
+polygons_count += count
+
+metal4_text = labels(50, 25)
+count = metal4_text.count()
+logger.info("metal4_text has #{count} polygons")
+polygons_count += count
+
+metal4_OPC = get_polygons(50, 26)
+count = metal4_OPC.count()
+logger.info("metal4_OPC has #{count} polygons")
+polygons_count += count
+
+metal4_noqrc = get_polygons(50, 28)
+count = metal4_noqrc.count()
+logger.info("metal4_noqrc has #{count} polygons")
+polygons_count += count
+
+metal4_res = get_polygons(50, 29)
+count = metal4_res.count()
+logger.info("metal4_res has #{count} polygons")
+polygons_count += count
+
+metal4_iprobe = get_polygons(50, 33)
+count = metal4_iprobe.count()
+logger.info("metal4_iprobe has #{count} polygons")
+polygons_count += count
+
+metal4_diffprb = get_polygons(50, 34)
+count = metal4_diffprb.count()
+logger.info("metal4_diffprb has #{count} polygons")
+polygons_count += count
+
+heattrans_drw = get_polygons(51, 0)
+count = heattrans_drw.count()
+logger.info("heattrans_drw has #{count} polygons")
+polygons_count += count
+
+heatres_drw = get_polygons(52, 0)
+count = heatres_drw.count()
+logger.info("heatres_drw has #{count} polygons")
+polygons_count += count
+
+fbe_drw = get_polygons(54, 0)
+count = fbe_drw.count()
+logger.info("fbe_drw has #{count} polygons")
+polygons_count += count
+
+empoly_drw = get_polygons(55, 0)
+count = empoly_drw.count()
+logger.info("empoly_drw has #{count} polygons")
+polygons_count += count
+
+digisub_drw = get_polygons(60, 0)
+count = digisub_drw.count()
+logger.info("digisub_drw has #{count} polygons")
+polygons_count += count
+
+text_drw = labels(63, 0)
+count = text_drw.count()
+logger.info("text_drw has #{count} polygons")
+polygons_count += count
+
+via4_drw = get_polygons(66, 0)
+count = via4_drw.count()
+logger.info("via4_drw has #{count} polygons")
+polygons_count += count
+
+metal5_drw = get_polygons(67, 0)
+count = metal5_drw.count()
+logger.info("metal5_drw has #{count} polygons")
+polygons_count += count
+
+metal5_filler = get_polygons(67, 22)
+count = metal5_filler.count()
+logger.info("metal5_filler has #{count} polygons")
+polygons_count += count
+
+metal5_slit = get_polygons(67, 24)
+count = metal5_slit.count()
+logger.info("metal5_slit has #{count} polygons")
+polygons_count += count
+
+# metal5 org
+metal5 = metal5_drw.join(metal5_filler).not(metal5_slit)
+count = metal5.count()
+logger.info("metal5 has #{count} polygons")
+
+metal5_pin = get_polygons(67, 2)
+count = metal5_pin.count()
+logger.info("metal5_pin has #{count} polygons")
+polygons_count += count
+
+metal5_mask = get_polygons(67, 20)
+count = metal5_mask.count()
+logger.info("metal5_mask has #{count} polygons")
+polygons_count += count
+
+metal5_nofill = get_polygons(67, 23)
+count = metal5_nofill.count()
+logger.info("metal5_nofill has #{count} polygons")
+polygons_count += count
+
+metal5_text = labels(67, 25)
+count = metal5_text.count()
+logger.info("metal5_text has #{count} polygons")
+polygons_count += count
+
+metal5_OPC = get_polygons(67, 26)
+count = metal5_OPC.count()
+logger.info("metal5_OPC has #{count} polygons")
+polygons_count += count
+
+metal5_noqrc = get_polygons(67, 28)
+count = metal5_noqrc.count()
+logger.info("metal5_noqrc has #{count} polygons")
+polygons_count += count
+
+metal5_res = get_polygons(67, 29)
+count = metal5_res.count()
+logger.info("metal5_res has #{count} polygons")
+polygons_count += count
+
+metal5_iprobe = get_polygons(67, 33)
+count = metal5_iprobe.count()
+logger.info("metal5_iprobe has #{count} polygons")
+polygons_count += count
+
+metal5_diffprb = get_polygons(67, 34)
+count = metal5_diffprb.count()
+logger.info("metal5_diffprb has #{count} polygons")
+polygons_count += count
+
+radhard_drw = get_polygons(68, 0)
+count = radhard_drw.count()
+logger.info("radhard_drw has #{count} polygons")
+polygons_count += count
+
+memcap_drw = get_polygons(69, 0)
+count = memcap_drw.count()
+logger.info("memcap_drw has #{count} polygons")
+polygons_count += count
+
+varicap_drw = get_polygons(70, 0)
+count = varicap_drw.count()
+logger.info("varicap_drw has #{count} polygons")
+polygons_count += count
+
+intbondvia_drw = get_polygons(72, 0)
+count = intbondvia_drw.count()
+logger.info("intbondvia_drw has #{count} polygons")
+polygons_count += count
+
+intbondmet_drw = get_polygons(73, 0)
+count = intbondmet_drw.count()
+logger.info("intbondmet_drw has #{count} polygons")
+polygons_count += count
+
+devbondvia_drw = get_polygons(74, 0)
+count = devbondvia_drw.count()
+logger.info("devbondvia_drw has #{count} polygons")
+polygons_count += count
+
+devbondmet_drw = get_polygons(75, 0)
+count = devbondmet_drw.count()
+logger.info("devbondmet_drw has #{count} polygons")
+polygons_count += count
+
+devtrench_drw = get_polygons(76, 0)
+count = devtrench_drw.count()
+logger.info("devtrench_drw has #{count} polygons")
+polygons_count += count
+
+redist_drw = get_polygons(77, 0)
+count = redist_drw.count()
+logger.info("redist_drw has #{count} polygons")
+polygons_count += count
+
+graphbot_drw = get_polygons(78, 0)
+count = graphbot_drw.count()
+logger.info("graphbot_drw has #{count} polygons")
+polygons_count += count
+
+graphtop_drw = get_polygons(79, 0)
+count = graphtop_drw.count()
+logger.info("graphtop_drw has #{count} polygons")
+polygons_count += count
+
+antvia1_drw = get_polygons(83, 0)
+count = antvia1_drw.count()
+logger.info("antvia1_drw has #{count} polygons")
+polygons_count += count
+
+antmetal2_drw = get_polygons(84, 0)
+count = antmetal2_drw.count()
+logger.info("antmetal2_drw has #{count} polygons")
+polygons_count += count
+
+graphcont_drw = get_polygons(85, 0)
+count = graphcont_drw.count()
+logger.info("graphcont_drw has #{count} polygons")
+polygons_count += count
+
+siwg_drw = get_polygons(86, 0)
+count = siwg_drw.count()
+logger.info("siwg_drw has #{count} polygons")
+polygons_count += count
+
+siwg_filler = get_polygons(86, 22)
+count = siwg_filler.count()
+logger.info("siwg_filler has #{count} polygons")
+polygons_count += count
+
+siwg_nofill = get_polygons(86, 23)
+count = siwg_nofill.count()
+logger.info("siwg_nofill has #{count} polygons")
+polygons_count += count
+
+sigrating_drw = get_polygons(87, 0)
+count = sigrating_drw.count()
+logger.info("sigrating_drw has #{count} polygons")
+polygons_count += count
+
+singrating_drw = get_polygons(88, 0)
+count = singrating_drw.count()
+logger.info("singrating_drw has #{count} polygons")
+polygons_count += count
+
+graphpas_drw = get_polygons(89, 0)
+count = graphpas_drw.count()
+logger.info("graphpas_drw has #{count} polygons")
+polygons_count += count
+
+emwind3_drw = get_polygons(90, 0)
+count = emwind3_drw.count()
+logger.info("emwind3_drw has #{count} polygons")
+polygons_count += count
+
+emwihv3_drw = get_polygons(91, 0)
+count = emwihv3_drw.count()
+logger.info("emwihv3_drw has #{count} polygons")
+polygons_count += count
+
+redbulay_drw = get_polygons(92, 0)
+count = redbulay_drw.count()
+logger.info("redbulay_drw has #{count} polygons")
+polygons_count += count
+
+smos_drw = get_polygons(93, 0)
+count = smos_drw.count()
+logger.info("smos_drw has #{count} polygons")
+polygons_count += count
+
+graphpad_drw = get_polygons(97, 0)
+count = graphpad_drw.count()
+logger.info("graphpad_drw has #{count} polygons")
+polygons_count += count
+
+polimide_drw = get_polygons(98, 0)
+count = polimide_drw.count()
+logger.info("polimide_drw has #{count} polygons")
+polygons_count += count
+
+polimide_pin = get_polygons(98, 2)
+count = polimide_pin.count()
+logger.info("polimide_pin has #{count} polygons")
+polygons_count += count
+
+recog_drw = get_polygons(99, 0)
+count = recog_drw.count()
+logger.info("recog_drw has #{count} polygons")
+polygons_count += count
+
+recog_pin = get_polygons(99, 2)
+count = recog_pin.count()
+logger.info("recog_pin has #{count} polygons")
+polygons_count += count
+
+recog_esd = get_polygons(99, 30)
+count = recog_esd.count()
+logger.info("recog_esd has #{count} polygons")
+polygons_count += count
+
+recog_diode = get_polygons(99, 31)
+count = recog_diode.count()
+logger.info("recog_diode has #{count} polygons")
+polygons_count += count
+
+recog_tsv = get_polygons(99, 32)
+count = recog_tsv.count()
+logger.info("recog_tsv has #{count} polygons")
+polygons_count += count
+
+recog_iprobe = get_polygons(99, 33)
+count = recog_iprobe.count()
+logger.info("recog_iprobe has #{count} polygons")
+polygons_count += count
+
+recog_diffprb = get_polygons(99, 34)
+count = recog_diffprb.count()
+logger.info("recog_diffprb has #{count} polygons")
+polygons_count += count
+
+recog_pillar = get_polygons(99, 35)
+count = recog_pillar.count()
+logger.info("recog_pillar has #{count} polygons")
+polygons_count += count
+
+recog_sbump = get_polygons(99, 36)
+count = recog_sbump.count()
+logger.info("recog_sbump has #{count} polygons")
+polygons_count += count
+
+recog_otp = get_polygons(99, 37)
+count = recog_otp.count()
+logger.info("recog_otp has #{count} polygons")
+polygons_count += count
+
+recog_pdiode = get_polygons(99, 38)
+count = recog_pdiode.count()
+logger.info("recog_pdiode has #{count} polygons")
+polygons_count += count
+
+recog_mom = get_polygons(99, 39)
+count = recog_mom.count()
+logger.info("recog_mom has #{count} polygons")
+polygons_count += count
+
+recog_pcm = get_polygons(99, 100)
+count = recog_pcm.count()
+logger.info("recog_pcm has #{count} polygons")
+polygons_count += count
+
+colopen_drw = get_polygons(101, 0)
+count = colopen_drw.count()
+logger.info("colopen_drw has #{count} polygons")
+polygons_count += count
+
+graphmetal1_drw = get_polygons(109, 0)
+count = graphmetal1_drw.count()
+logger.info("graphmetal1_drw has #{count} polygons")
+polygons_count += count
+
+graphmetal1_filler = get_polygons(109, 22)
+count = graphmetal1_filler.count()
+logger.info("graphmetal1_filler has #{count} polygons")
+polygons_count += count
+
+graphmetal1_nofill = get_polygons(109, 23)
+count = graphmetal1_nofill.count()
+logger.info("graphmetal1_nofill has #{count} polygons")
+polygons_count += count
+
+graphmetal1_slit = get_polygons(109, 24)
+count = graphmetal1_slit.count()
+logger.info("graphmetal1_slit has #{count} polygons")
+polygons_count += count
+
+graphmetal1_OPC = get_polygons(109, 26)
+count = graphmetal1_OPC.count()
+logger.info("graphmetal1_OPC has #{count} polygons")
+polygons_count += count
+
+graphmet1l_drw = get_polygons(110, 0)
+count = graphmet1l_drw.count()
+logger.info("graphmet1l_drw has #{count} polygons")
+polygons_count += count
+
+graphmet1l_filler = get_polygons(110, 22)
+count = graphmet1l_filler.count()
+logger.info("graphmet1l_filler has #{count} polygons")
+polygons_count += count
+
+graphmet1l_nofill = get_polygons(110, 23)
+count = graphmet1l_nofill.count()
+logger.info("graphmet1l_nofill has #{count} polygons")
+polygons_count += count
+
+graphmet1l_slit = get_polygons(110, 24)
+count = graphmet1l_slit.count()
+logger.info("graphmet1l_slit has #{count} polygons")
+polygons_count += count
+
+graphmet1l_OPC = get_polygons(110, 26)
+count = graphmet1l_OPC.count()
+logger.info("graphmet1l_OPC has #{count} polygons")
+polygons_count += count
+
+extblock_drw = get_polygons(111, 0)
+count = extblock_drw.count()
+logger.info("extblock_drw has #{count} polygons")
+polygons_count += count
+
+nldd_drw = get_polygons(112, 0)
+count = nldd_drw.count()
+logger.info("nldd_drw has #{count} polygons")
+polygons_count += count
+
+pldd_drw = get_polygons(113, 0)
+count = pldd_drw.count()
+logger.info("pldd_drw has #{count} polygons")
+polygons_count += count
+
+next_drw = get_polygons(114, 0)
+count = next_drw.count()
+logger.info("next_drw has #{count} polygons")
+polygons_count += count
+
+pext_drw = get_polygons(115, 0)
+count = pext_drw.count()
+logger.info("pext_drw has #{count} polygons")
+polygons_count += count
+
+nexthv_drw = get_polygons(116, 0)
+count = nexthv_drw.count()
+logger.info("nexthv_drw has #{count} polygons")
+polygons_count += count
+
+pexthv_drw = get_polygons(117, 0)
+count = pexthv_drw.count()
+logger.info("pexthv_drw has #{count} polygons")
+polygons_count += count
+
+graphgate_drw = get_polygons(118, 0)
+count = graphgate_drw.count()
+logger.info("graphgate_drw has #{count} polygons")
+polygons_count += count
+
+sinwg_drw = get_polygons(119, 0)
+count = sinwg_drw.count()
+logger.info("sinwg_drw has #{count} polygons")
+polygons_count += count
+
+sinwg_filler = get_polygons(119, 22)
+count = sinwg_filler.count()
+logger.info("sinwg_filler has #{count} polygons")
+polygons_count += count
+
+sinwg_nofill = get_polygons(119, 23)
+count = sinwg_nofill.count()
+logger.info("sinwg_nofill has #{count} polygons")
+polygons_count += count
+
+mempad_drw = get_polygons(124, 0)
+count = mempad_drw.count()
+logger.info("mempad_drw has #{count} polygons")
+polygons_count += count
+
+topvia1_drw = get_polygons(125, 0)
+count = topvia1_drw.count()
+logger.info("topvia1_drw has #{count} polygons")
+polygons_count += count
+
+topmetal1_drw = get_polygons(126, 0)
+count = topmetal1_drw.count()
+logger.info("topmetal1_drw has #{count} polygons")
+polygons_count += count
+
+topmetal1_filler = get_polygons(126, 22)
+count = topmetal1_filler.count()
+logger.info("topmetal1_filler has #{count} polygons")
+polygons_count += count
+
+topmetal1_slit = get_polygons(126, 24)
+count = topmetal1_slit.count()
+logger.info("topmetal1_slit has #{count} polygons")
+polygons_count += count
+
+# topmetal1 org
+topmetal1 = topmetal1_drw.join(topmetal1_filler).not(topmetal1_slit)
+count = topmetal1.count()
+logger.info("topmetal1 has #{count} polygons")
+
+topmetal1_pin = get_polygons(126, 2)
+count = topmetal1_pin.count()
+logger.info("topmetal1_pin has #{count} polygons")
+polygons_count += count
+
+topmetal1_mask = get_polygons(126, 20)
+count = topmetal1_mask.count()
+logger.info("topmetal1_mask has #{count} polygons")
+polygons_count += count
+
+topmetal1_nofill = get_polygons(126, 23)
+count = topmetal1_nofill.count()
+logger.info("topmetal1_nofill has #{count} polygons")
+polygons_count += count
+
+topmetal1_text = labels(126, 25)
+count = topmetal1_text.count()
+logger.info("topmetal1_text has #{count} polygons")
+polygons_count += count
+
+topmetal1_noqrc = get_polygons(126, 28)
+count = topmetal1_noqrc.count()
+logger.info("topmetal1_noqrc has #{count} polygons")
+polygons_count += count
+
+topmetal1_res = get_polygons(126, 29)
+count = topmetal1_res.count()
+logger.info("topmetal1_res has #{count} polygons")
+polygons_count += count
+
+topmetal1_iprobe = get_polygons(126, 33)
+count = topmetal1_iprobe.count()
+logger.info("topmetal1_iprobe has #{count} polygons")
+polygons_count += count
+
+topmetal1_diffprb = get_polygons(126, 34)
+count = topmetal1_diffprb.count()
+logger.info("topmetal1_diffprb has #{count} polygons")
+polygons_count += count
+
+inldpwl_drw = get_polygons(127, 0)
+count = inldpwl_drw.count()
+logger.info("inldpwl_drw has #{count} polygons")
+polygons_count += count
+
+polyres_drw = get_polygons(128, 0)
+count = polyres_drw.count()
+logger.info("polyres_drw has #{count} polygons")
+polygons_count += count
+
+polyres_pin = get_polygons(128, 2)
+count = polyres_pin.count()
+logger.info("polyres_pin has #{count} polygons")
+polygons_count += count
+
+vmim_drw = get_polygons(129, 0)
+count = vmim_drw.count()
+logger.info("vmim_drw has #{count} polygons")
+polygons_count += count
+
+nbulaycut_drw = get_polygons(131, 0)
+count = nbulaycut_drw.count()
+logger.info("nbulaycut_drw has #{count} polygons")
+polygons_count += count
+
+antmetal1_drw = get_polygons(132, 0)
+count = antmetal1_drw.count()
+logger.info("antmetal1_drw has #{count} polygons")
+polygons_count += count
+
+topvia2_drw = get_polygons(133, 0)
+count = topvia2_drw.count()
+logger.info("topvia2_drw has #{count} polygons")
+polygons_count += count
+
+topmetal2_drw = get_polygons(134, 0)
+count = topmetal2_drw.count()
+logger.info("topmetal2_drw has #{count} polygons")
+polygons_count += count
+
+topmetal2_filler = get_polygons(134, 22)
+count = topmetal2_filler.count()
+logger.info("topmetal2_filler has #{count} polygons")
+polygons_count += count
+
+topmetal2_slit = get_polygons(134, 24)
+count = topmetal2_slit.count()
+logger.info("topmetal2_slit has #{count} polygons")
+polygons_count += count
+
+# topmetal2 org
+topmetal2 = topmetal2_drw.join(topmetal2_filler).not(topmetal2_slit)
+count = topmetal2.count()
+logger.info("topmetal2 has #{count} polygons")
+
+topmetal2_pin = get_polygons(134, 2)
+count = topmetal2_pin.count()
+logger.info("topmetal2_pin has #{count} polygons")
+polygons_count += count
+
+topmetal2_mask = get_polygons(134, 20)
+count = topmetal2_mask.count()
+logger.info("topmetal2_mask has #{count} polygons")
+polygons_count += count
+
+topmetal2_nofill = get_polygons(134, 23)
+count = topmetal2_nofill.count()
+logger.info("topmetal2_nofill has #{count} polygons")
+polygons_count += count
+
+topmetal2_text = labels(134, 25)
+count = topmetal2_text.count()
+logger.info("topmetal2_text has #{count} polygons")
+polygons_count += count
+
+topmetal2_noqrc = get_polygons(134, 28)
+count = topmetal2_noqrc.count()
+logger.info("topmetal2_noqrc has #{count} polygons")
+polygons_count += count
+
+topmetal2_res = get_polygons(134, 29)
+count = topmetal2_res.count()
+logger.info("topmetal2_res has #{count} polygons")
+polygons_count += count
+
+topmetal2_iprobe = get_polygons(134, 33)
+count = topmetal2_iprobe.count()
+logger.info("topmetal2_iprobe has #{count} polygons")
+polygons_count += count
+
+topmetal2_diffprb = get_polygons(134, 34)
+count = topmetal2_diffprb.count()
+logger.info("topmetal2_diffprb has #{count} polygons")
+polygons_count += count
+
+snsring_drw = get_polygons(135, 0)
+count = snsring_drw.count()
+logger.info("snsring_drw has #{count} polygons")
+polygons_count += count
+
+sensor_drw = get_polygons(136, 0)
+count = sensor_drw.count()
+logger.info("sensor_drw has #{count} polygons")
+polygons_count += count
+
+snsarms_drw = get_polygons(137, 0)
+count = snsarms_drw.count()
+logger.info("snsarms_drw has #{count} polygons")
+polygons_count += count
+
+snscmosvia_drw = get_polygons(138, 0)
+count = snscmosvia_drw.count()
+logger.info("snscmosvia_drw has #{count} polygons")
+polygons_count += count
+
+colwind_drw = get_polygons(139, 0)
+count = colwind_drw.count()
+logger.info("colwind_drw has #{count} polygons")
+polygons_count += count
+
+flm_drw = get_polygons(142, 0)
+count = flm_drw.count()
+logger.info("flm_drw has #{count} polygons")
+polygons_count += count
+
+hafniumox_drw = get_polygons(143, 0)
+count = hafniumox_drw.count()
+logger.info("hafniumox_drw has #{count} polygons")
+polygons_count += count
+
+memvia_drw = get_polygons(145, 0)
+count = memvia_drw.count()
+logger.info("memvia_drw has #{count} polygons")
+polygons_count += count
+
+thinfilmres_drw = get_polygons(146, 0)
+count = thinfilmres_drw.count()
+logger.info("thinfilmres_drw has #{count} polygons")
+polygons_count += count
+
+rfmem_drw = get_polygons(147, 0)
+count = rfmem_drw.count()
+logger.info("rfmem_drw has #{count} polygons")
+polygons_count += count
+
+norcx_drw = get_polygons(148, 0)
+count = norcx_drw.count()
+logger.info("norcx_drw has #{count} polygons")
+polygons_count += count
+
+norcx_m2m3 = get_polygons(148, 41)
+count = norcx_m2m3.count()
+logger.info("norcx_m2m3 has #{count} polygons")
+polygons_count += count
+
+norcx_m2m4 = get_polygons(148, 42)
+count = norcx_m2m4.count()
+logger.info("norcx_m2m4 has #{count} polygons")
+polygons_count += count
+
+norcx_m2m5 = get_polygons(148, 43)
+count = norcx_m2m5.count()
+logger.info("norcx_m2m5 has #{count} polygons")
+polygons_count += count
+
+norcx_m2tm1 = get_polygons(148, 44)
+count = norcx_m2tm1.count()
+logger.info("norcx_m2tm1 has #{count} polygons")
+polygons_count += count
+
+norcx_m2tm2 = get_polygons(148, 45)
+count = norcx_m2tm2.count()
+logger.info("norcx_m2tm2 has #{count} polygons")
+polygons_count += count
+
+norcx_m3m4 = get_polygons(148, 46)
+count = norcx_m3m4.count()
+logger.info("norcx_m3m4 has #{count} polygons")
+polygons_count += count
+
+norcx_m3m5 = get_polygons(148, 47)
+count = norcx_m3m5.count()
+logger.info("norcx_m3m5 has #{count} polygons")
+polygons_count += count
+
+norcx_m3tm1 = get_polygons(148, 48)
+count = norcx_m3tm1.count()
+logger.info("norcx_m3tm1 has #{count} polygons")
+polygons_count += count
+
+norcx_m3tm2 = get_polygons(148, 49)
+count = norcx_m3tm2.count()
+logger.info("norcx_m3tm2 has #{count} polygons")
+polygons_count += count
+
+norcx_m4m5 = get_polygons(148, 50)
+count = norcx_m4m5.count()
+logger.info("norcx_m4m5 has #{count} polygons")
+polygons_count += count
+
+norcx_m4tm1 = get_polygons(148, 51)
+count = norcx_m4tm1.count()
+logger.info("norcx_m4tm1 has #{count} polygons")
+polygons_count += count
+
+norcx_m4tm2 = get_polygons(148, 52)
+count = norcx_m4tm2.count()
+logger.info("norcx_m4tm2 has #{count} polygons")
+polygons_count += count
+
+norcx_m5tm1 = get_polygons(148, 53)
+count = norcx_m5tm1.count()
+logger.info("norcx_m5tm1 has #{count} polygons")
+polygons_count += count
+
+norcx_m5tm2 = get_polygons(148, 54)
+count = norcx_m5tm2.count()
+logger.info("norcx_m5tm2 has #{count} polygons")
+polygons_count += count
+
+norcx_tm1tm2 = get_polygons(148, 55)
+count = norcx_tm1tm2.count()
+logger.info("norcx_tm1tm2 has #{count} polygons")
+polygons_count += count
+
+norcx_m1sub = get_polygons(148, 123)
+count = norcx_m1sub.count()
+logger.info("norcx_m1sub has #{count} polygons")
+polygons_count += count
+
+norcx_m2sub = get_polygons(148, 124)
+count = norcx_m2sub.count()
+logger.info("norcx_m2sub has #{count} polygons")
+polygons_count += count
+
+norcx_m3sub = get_polygons(148, 125)
+count = norcx_m3sub.count()
+logger.info("norcx_m3sub has #{count} polygons")
+polygons_count += count
+
+norcx_m4sub = get_polygons(148, 126)
+count = norcx_m4sub.count()
+logger.info("norcx_m4sub has #{count} polygons")
+polygons_count += count
+
+norcx_m5sub = get_polygons(148, 127)
+count = norcx_m5sub.count()
+logger.info("norcx_m5sub has #{count} polygons")
+polygons_count += count
+
+norcx_tm1sub = get_polygons(148, 300)
+count = norcx_tm1sub.count()
+logger.info("norcx_tm1sub has #{count} polygons")
+polygons_count += count
+
+norcx_tm2sub = get_polygons(148, 301)
+count = norcx_tm2sub.count()
+logger.info("norcx_tm2sub has #{count} polygons")
+polygons_count += count
+
+snsbotvia_drw = get_polygons(149, 0)
+count = snsbotvia_drw.count()
+logger.info("snsbotvia_drw has #{count} polygons")
+polygons_count += count
+
+snstopvia_drw = get_polygons(151, 0)
+count = snstopvia_drw.count()
+logger.info("snstopvia_drw has #{count} polygons")
+polygons_count += count
+
+deepvia_drw = get_polygons(152, 0)
+count = deepvia_drw.count()
+logger.info("deepvia_drw has #{count} polygons")
+polygons_count += count
+
+fgetch_drw = get_polygons(153, 0)
+count = fgetch_drw.count()
+logger.info("fgetch_drw has #{count} polygons")
+polygons_count += count
+
+ctrgat_drw = get_polygons(154, 0)
+count = ctrgat_drw.count()
+logger.info("ctrgat_drw has #{count} polygons")
+polygons_count += count
+
+fgimp_drw = get_polygons(155, 0)
+count = fgimp_drw.count()
+logger.info("fgimp_drw has #{count} polygons")
+polygons_count += count
+
+emwihv_drw = get_polygons(156, 0)
+count = emwihv_drw.count()
+logger.info("emwihv_drw has #{count} polygons")
+polygons_count += count
+
+lbe_drw = get_polygons(157, 0)
+count = lbe_drw.count()
+logger.info("lbe_drw has #{count} polygons")
+polygons_count += count
+
+alcustop_drw = get_polygons(159, 0)
+count = alcustop_drw.count()
+logger.info("alcustop_drw has #{count} polygons")
+polygons_count += count
+
+nometfiller_drw = get_polygons(160, 0)
+count = nometfiller_drw.count()
+logger.info("nometfiller_drw has #{count} polygons")
+polygons_count += count
+
+prboundary_drw = get_polygons(189, 0)
+count = prboundary_drw.count()
+logger.info("prboundary_drw has #{count} polygons")
+polygons_count += count
+
+exchange0_drw = get_polygons(190, 0)
+count = exchange0_drw.count()
+logger.info("exchange0_drw has #{count} polygons")
+polygons_count += count
+
+exchange0_pin = get_polygons(190, 2)
+count = exchange0_pin.count()
+logger.info("exchange0_pin has #{count} polygons")
+polygons_count += count
+
+exchange0_text = labels(190, 25)
+count = exchange0_text.count()
+logger.info("exchange0_text has #{count} polygons")
+polygons_count += count
+
+exchange1_drw = get_polygons(191, 0)
+count = exchange1_drw.count()
+logger.info("exchange1_drw has #{count} polygons")
+polygons_count += count
+
+exchange1_pin = get_polygons(191, 2)
+count = exchange1_pin.count()
+logger.info("exchange1_pin has #{count} polygons")
+polygons_count += count
+
+exchange1_text = labels(191, 25)
+count = exchange1_text.count()
+logger.info("exchange1_text has #{count} polygons")
+polygons_count += count
+
+exchange2_drw = get_polygons(192, 0)
+count = exchange2_drw.count()
+logger.info("exchange2_drw has #{count} polygons")
+polygons_count += count
+
+exchange2_pin = get_polygons(192, 2)
+count = exchange2_pin.count()
+logger.info("exchange2_pin has #{count} polygons")
+polygons_count += count
+
+exchange2_text = labels(192, 25)
+count = exchange2_text.count()
+logger.info("exchange2_text has #{count} polygons")
+polygons_count += count
+
+exchange3_drw = get_polygons(193, 0)
+count = exchange3_drw.count()
+logger.info("exchange3_drw has #{count} polygons")
+polygons_count += count
+
+exchange3_pin = get_polygons(193, 2)
+count = exchange3_pin.count()
+logger.info("exchange3_pin has #{count} polygons")
+polygons_count += count
+
+exchange3_text = labels(193, 25)
+count = exchange3_text.count()
+logger.info("exchange3_text has #{count} polygons")
+polygons_count += count
+
+exchange4_drw = get_polygons(194, 0)
+count = exchange4_drw.count()
+logger.info("exchange4_drw has #{count} polygons")
+polygons_count += count
+
+exchange4_pin = get_polygons(194, 2)
+count = exchange4_pin.count()
+logger.info("exchange4_pin has #{count} polygons")
+polygons_count += count
+
+exchange4_text = labels(194, 25)
+count = exchange4_text.count()
+logger.info("exchange4_text has #{count} polygons")
+polygons_count += count
+
+isonwell_drw = get_polygons(257, 0)
+count = isonwell_drw.count()
+logger.info("isonwell_drw has #{count} polygons")
+polygons_count += count
+
+logger.info("Total no. of polygons in the design is #{polygons_count}")
+
+#================================================================
+#------------------------- MAIN RUNSET --------------------------
+#================================================================
+
+logger.info('Starting SG13G2 LVS runset')
+
+#================================================
+#------------- LAYERS DERIVATIONS ---------------
+#================================================
+
+logger.info('Starting base layers derivations')
+
+#==================================
+# ------ GENERAL DERIVATIONS ------
+#==================================
+
+logger.info('Starting general LVS derivations')
+
+#=== Global Layers ===
+# === CHIP ===
+CHIP = case $run_mode
+when 'deep'
+ extent('*')
+else
+ #=== FLAT MODE ===
+ extent.sized(0.0)
+end
+
+# === General Derivations ===
+# nwell
+nwell_iso = nwell_drw.and(nbulay_drw)
+nwell_holes = nwell_drw.holes.not(nwell_drw)
+
+# pwell
+pwell_allowed = CHIP.not(pwell_block)
+digisub_gap = digisub_drw.not(digisub_drw.sized(-1.nm))
+pwell = pwell_allowed.not(nwell_drw).not(digisub_gap)
+
+# General pwell
+pwell_sub = pwell_allowed.not(digisub_drw).not(nbulay_drw.interacting(nwell_holes))
+
+# n & p activ
+nactiv = activ.not(psd_drw.join(nsd_block))
+pactiv = activ.and(psd_drw)
+
+# res/cap exclusion
+res_mk = polyres_drw.join(res_drw)
+poly_con = gatpoly.not(res_mk)
+metal1_con = metal1.not(metal1_res)
+metal2_con = metal2.not(metal2_res)
+metal3_con = metal3.not(metal3_res)
+metal4_con = metal4.not(metal4_res)
+metal5_con = metal5.not(metal5_res)
+topmetal1_con = topmetal1.not(topmetal1_res).not(ind_drw)
+topmetal2_con = topmetal2.not(topmetal2_res).not(ind_drw)
+
+# Gate FETs
+tgate = gatpoly.and(activ).not(res_mk)
+ngate = nactiv.and(tgate)
+pgate = pactiv.and(tgate)
+ngate_lv_base = ngate.not(thickgateox_drw)
+pgate_lv_base = pgate.not(thickgateox_drw)
+ngate_hv_base = ngate.and(thickgateox_drw)
+pgate_hv_base = pgate.and(thickgateox_drw)
+
+# S/D FETs
+nsd_fet = nactiv.not(nwell_drw).interacting(ngate).not(ngate).not_interacting(res_mk)
+psd_fet = pactiv.and(nwell_drw).interacting(pgate).not(pgate).not_interacting(res_mk)
+
+
+# n1/p1 taps labels
+well_patt = glob_to_case_insensitive_glob("well")
+sub_patt = glob_to_case_insensitive_glob("sub!")
+
+ntap1_lbl = text_drw.texts(well_patt)
+ntap1_mk = nwell_drw.interacting(ntap1_lbl)
+
+ptap1_lbl = text_drw.texts(sub_patt)
+ptap1_mk = substrate_drw.and(pwell).interacting(ptap1_lbl)
+
+# n & p taps (short connections)
+ntap = nactiv.and(nwell_drw).not(recog_diode).not(gatpoly).not(ntap1_mk)
+ptap = pactiv.and(pwell).not(ptap1_mk).not(recog_diode).not(gatpoly)
+ptap_holes = ptap.holes
+ntap_holes = ntap.holes
+
+# S/D (salicide)
+nsd_sal = nsd_fet.not(salblock_drw)
+psd_sal = psd_fet.not(salblock_drw)
+
+# n & p taps (salicide)
+ntap_sal = ntap.not(salblock_drw)
+ptap_sal = ptap.not(salblock_drw)
+
+# n/p SD abutted with n/p taps (salicide)
+nsd_ptap_abutt = nsd_sal.edges.and(ptap_sal.edges).extended(:in => 1.nm, :out => 1.nm)
+psd_ntap_abutt = psd_sal.edges.and(ntap_sal.edges).extended(:in => 1.nm, :out => 1.nm)
+
+#==================================
+# ------ MOSFET DERIVATIONS -------
+#==================================
+
+logger.info('Starting MOSFET DERIVATIONS')
+
+mos_exclude = pwell_block.join(nsd_drw).join(trans_drw)
+ .join(emwind_drw).join(emwihv_drw).join(salblock_drw)
+ .join(polyres_drw).join(extblock_drw).join(res_drw)
+ .join(activ_mask).join(recog_diode).join(recog_esd)
+ .join(ind_drw).join(ind_pin).join(ind_drw)
+ .join(substrate_drw).join(nsd_block)
+
+# ==== General FETs & RF-FETs =====
+
+rfnmos_exc = nwell_drw.join(psd_drw).join(mos_exclude)
+rfpmos_exc = pwell.join(nwell_holes).join(mos_exclude)
+
+# Get case insensitive patterns for FETs
+rfnmos_patt = glob_to_case_insensitive_glob("rfnmos")
+rfnmoshv_patt = glob_to_case_insensitive_glob("rfnmosHV")
+
+rfpmos_patt = glob_to_case_insensitive_glob("rfpmos")
+rfpmoshv_patt = glob_to_case_insensitive_glob("rfpmosHV")
+
+rfnmos_mk_gen = ptap.join(ptap_holes)
+rfnmos_mk = rfnmos_mk_gen.interacting(text_drw.texts(rfnmos_patt))
+rfnmoshv_mk = rfnmos_mk_gen.interacting(text_drw.texts(rfnmoshv_patt))
+
+rfpmos_mk_gen = ntap.join(ntap_holes)
+rfpmos_mk = rfpmos_mk_gen.interacting(text_drw.texts(rfpmos_patt))
+rfpmoshv_mk = rfpmos_mk_gen.interacting(text_drw.texts(rfpmoshv_patt))
+
+# ==============
+# ---- NMOS ----
+# ==============
+
+logger.info('Starting NMOS DERIVATIONS')
+
+# for regular FETs
+nmos_exc = rfnmos_exc.join(rfnmos_mk)
+nmoshv_exc = rfnmos_exc.join(rfnmoshv_mk)
+
+# nmos - LV
+ngate_lv = ngate_lv_base.not(nmos_exc)
+
+# nmos - HV
+ngate_hv = ngate_hv_base.not(nmoshv_exc)
+
+# ==============
+# ---- PMOS ----
+# ==============
+
+logger.info('Starting PMOS DERIVATIONS')
+
+# for regular FETs
+pmos_exc = rfpmos_exc.join(rfpmos_mk)
+pmoshv_exc = rfpmos_exc.join(rfpmoshv_mk)
+
+# pmos - LV
+pgate_lv = pgate_lv_base.not(pmos_exc)
+
+# pmos - HV
+pgate_hv = pgate_hv_base.not(pmoshv_exc)
+
+#==================================
+# ----- RF-MOSFET DERIVATIONS -----
+#==================================
+
+logger.info('Starting RF-MOSFET DERIVATIONS')
+
+# ===============
+# --- RF-NMOS ---
+# ===============
+
+logger.info('Starting RF-NMOS DERIVATIONS')
+
+
+# rfnmos - LV
+rfngate_lv = ngate_lv_base.and(rfnmos_mk).not(rfnmos_exc)
+
+# rfnmos - HV
+rfngate_hv = ngate_hv_base.and(rfnmoshv_mk).not(rfnmos_exc)
+
+# ===============
+# --- RF-PMOS ---
+# ===============
+
+logger.info('Starting RF-PMOS DERIVATIONS')
+
+# rfpmos - LV
+rfpgate_lv = pgate_lv_base.and(rfpmos_mk).not(rfpmos_exc)
+
+# rfpmos - HV
+rfpgate_hv = pgate_hv_base.and(rfpmoshv_mk).not(rfpmos_exc)
+
+#================================
+# ------ BJT DERIVATIONS --------
+#================================
+
+logger.info('Starting BJT DERIVATIONS')
+
+# =============
+# ---- NPN ----
+# =============
+
+logger.info('Starting NPN-BJT DERIVATIONS')
+
+bjt_exclude = gatpoly.join(pwell_block).join(nsd_drw)
+ .join(salblock_drw).join(polyres_drw).join(extblock_drw)
+ .join(res_drw).join(recog_diode).join(recog_esd)
+ .join(ind_drw).join(ind_pin).join(substrate_drw)
+
+npn_exclude = nwell_drw.join(psd_drw).join(nbulay_drw).join(bjt_exclude)
+
+# ---------- General NPN ----------
+npn_mk = trans_drw.and(pwell).and(ptap_holes)
+npn_c_exc = emwind_drw.join(emwihv_drw).join(activ_mask)
+ .join(nsd_block).join(npn_exclude)
+npn_b_exc = emwind_drw.join(emwihv_drw).join(npn_exclude)
+npn_sub = npn_mk.not(npn_exclude)
+npn_dev = activ.join(activ_mask).and(npn_mk)
+
+# ---------- npn13G2 ----------
+# npn13G2 exclusion layers
+npn13G2_e_exc = activ.join(emwihv_drw).join(npn_exclude)
+npn13G2_b_exc = npn_b_exc.join(activ_mask)
+
+# npn13G2 nodes
+npn13G2_e_ = emwind_drw.and(activ_mask).and(nsd_block).and(npn_mk).not(npn13G2_e_exc)
+# npn13G2 is a fixed device (0.07um X 0.9um)
+npn13G2_e_pin = npn13G2_e_.with_bbox_min(0.07.um).with_bbox_max(0.9.um).with_area(0.063.um)
+npn13G2_b_pin = nsd_block.and(npn_mk).not(npn13G2_b_exc)
+npn13G2_c_pin = activ.and(npn_mk).not_overlapping(npn_c_exc)
+
+npn13G2_dev = npn_dev.join(nsd_block).extents.covering(npn13G2_e_pin).covering(npn13G2_b_pin).covering(npn13G2_c_pin)
+npn13G2_c = npn13G2_dev.sized(-1.nm)
+npn13G2_tc = npn13G2_dev.not(npn13G2_c).interacting(npn13G2_c_pin)
+npn13G2_b = npn13G2_dev.not(npn13G2_c_pin)
+npn13G2_tb = npn13G2_b.not(npn13G2_e_pin).merged
+npn13G2_e = npn13G2_e_pin
+npn13G2_te = npn13G2_e
+
+# ---------- npn13G2L ----------
+# npn13G2L exclusion layers
+npn13G2l_e_exc = activ_mask.join(nsd_block).join(emwihv_drw).join(npn_exclude)
+npn13G2l_b_exc = npn_b_exc.join(activ).join(nsd_block)
+
+# npn13G2L nodes
+npn13G2l_e_ = emwind_drw.and(activ).and(npn_mk).not(npn13G2l_e_exc)
+# npn13G2L has fixed width (0.07um), Length could vary from 1:2.5 um
+npn13G2l_e_pin = npn13G2l_e_.with_bbox_min(0.07.um).with_bbox_max(1.um, 2.5.um).with_area(0.07.um, 0.175.um)
+npn13G2l_b_pin = activ_mask.and(npn_mk).not(npn13G2l_b_exc)
+npn13G2l_c_pin = npn13G2_c_pin
+
+npn13G2l_dev = npn_dev.covering(npn13G2l_e_pin).covering(npn13G2l_b_pin).covering(npn13G2l_c_pin)
+npn13G2l_c = npn13G2l_dev.sized(1.nm)
+npn13G2l_tc = npn13G2l_c.not(npn13G2l_dev).interacting(npn13G2l_c_pin)
+npn13G2l_b = npn13G2l_dev.not(npn13G2l_c_pin)
+npn13G2l_tb = npn13G2l_b.not(npn13G2l_e_pin).merged
+npn13G2l_e = npn13G2l_e_pin
+npn13G2l_te = npn13G2l_e
+
+# # ---------- npn13G2V ----------
+# npn13G2V exclusion layers
+npn13G2v_e_exc = activ_mask.join(nsd_block).join(emwind_drw).join(npn_exclude)
+
+# npn13G2V nodes
+npn13G2v_e_ = emwihv_drw.and(activ).and(npn_mk).not(npn13G2v_e_exc)
+# npn13G2L has fixed width (0.12um), Length could vary from 1:5 um
+npn13G2v_e_pin = npn13G2v_e_.with_bbox_min(0.12.um).with_bbox_max(1.um, 5.um).with_area(0.12.um, 0.6.um)
+npn13G2v_b_pin = npn13G2l_b_pin
+npn13G2v_c_pin = npn13G2l_c_pin
+
+npn13G2v_dev = npn_dev.covering(npn13G2v_e_pin).covering(npn13G2v_b_pin).covering(npn13G2v_c_pin)
+npn13G2v_c = npn13G2v_dev.sized(1.nm)
+npn13G2v_tc = npn13G2v_c.not(npn13G2v_dev).interacting(npn13G2v_c_pin)
+npn13G2v_b = npn13G2v_dev.not(npn13G2v_c_pin)
+npn13G2v_tb = npn13G2v_b.not(npn13G2v_e_pin).merged
+npn13G2v_e = npn13G2v_e_pin
+npn13G2v_te = npn13G2v_e
+
+# =============
+# ---- PNP ----
+# =============
+
+logger.info('Starting PNP-BJT DERIVATIONS')
+
+pnp_exclude = trans_drw.join(emwind_drw)
+ .join(emwihv_drw).join(nsd_block).join(bjt_exclude)
+
+pnp_mk = ptap_holes.not(pnp_exclude)
+
+# pnp general nodes DERIVATIONS
+pnp_e = pactiv.and(pnp_mk).and(nwell_iso)
+pnp_b = nactiv.and(pnp_mk).and(nwell_iso)
+pnp_c = ptap.interacting(pnp_mk).not(pnp_exclude)
+
+# pnp_mpa nodes DERIVATIONS
+pnp_mpa_e = pnp_e.and(pnp_b.extents).and(pnp_c.extents)
+pnp_mpa_b = pnp_b.interacting(pnp_b.extents.interacting(pnp_mpa_e))
+pnp_mpa_c = pnp_c.interacting(pnp_c.extents.interacting(pnp_mpa_e))
+
+#================================
+# ----- DIODE DERIVATIONS -------
+#================================
+
+logger.info('Starting DIODE DERIVATIONS')
+
+diode_exclude = gatpoly.join(nsd_drw).join(trans_drw)
+ .join(emwind_drw).join(emwihv_drw).join(polyres_drw)
+ .join(extblock_drw).join(res_drw).join(activ_mask)
+ .join(recog_esd).join(ind_drw).join(ind_pin)
+ .join(substrate_drw)
+
+antenna_d_exc = pwell_block.join(salblock_drw)
+ .join(nsd_block).join(diode_exclude)
+
+antenna_d_mk = recog_diode.not(antenna_d_exc)
+
+# ==== dantenna diode ====
+dantenna_n = activ.and(antenna_d_mk).not(psd_drw).not(nwell_drw)
+dantenna_p = pwell.and(antenna_d_mk).covering(dantenna_n)
+
+# ==== dpantenna diode ====
+dpantenna_p = pactiv.and(antenna_d_mk)
+dpantenna_n = nwell_drw.covering(dpantenna_p)
+
+# ==== schottky_nbl1 diode ====
+schottky_mk = recog_diode.and(thickgateox_drw).not(diode_exclude)
+ .and(pwell_block).and(ptap_holes).and(nbulay_drw)
+ .and(salblock_drw).and(nsd_block).and(nwell_holes)
+ .not(psd_drw).not(pwell).not(diode_exclude)
+
+schottcky_p_ = cont_drw.and(activ).and(metal1_con)
+ .and(schottky_mk)
+
+# schottky_nbl1 is a fixed device (0.3um X 1.0 um)
+schottcky_p = schottcky_p_.with_bbox_min(0.3.um).with_bbox_max(1.0.um)
+# Using box with area 1x1 to be used as a reference to (m)
+schottcky_p_1x1 = schottcky_p.middle(as_boxes).sized(0.499.um)
+
+schottcky_n = nsd_block.and(activ).covering(schottcky_p)
+
+# define port for schottcky
+schottcky_n_port = activ.interacting(nwell_iso).interacting(schottcky_n).not(schottcky_n.sized(-1.nm))
+schottcky_n_con = cont_drw.and(schottcky_n_port).not_interacting(schottcky_p)
+schottcky_sub = ptap.extents.covering(schottcky_p).covering(schottcky_n)
+
+#================================
+# ---- RESISTOR DERIVATIONS -----
+#================================
+
+logger.info('Starting RESISTOR DERIVATIONS')
+
+polyres_exclude = activ.join(pwell_block).join(nsd_block)
+ .join(nbulay_drw).join(thickgateox_drw).join(trans_drw)
+ .join(emwind_drw).join(emwihv_drw).join(activ_mask)
+ .join(recog_diode).join(recog_esd).join(ind_drw)
+ .join(ind_pin).join(substrate_drw)
+
+# ==============
+# ---- POLY ----
+# ==============
+
+## polyres
+polyres_mk = polyres_drw.and(extblock_drw).interacting(gatpoly).not(polyres_exclude)
+
+## rhigh
+rhigh_res = polyres_mk.and(psd_drw).and(nsd_drw).and(salblock_drw)
+rhigh_ports = gatpoly.interacting(rhigh_res).not(rhigh_res)
+
+## rppd
+rppd_res = polyres_mk.and(psd_drw).and(salblock_drw).not(nsd_block).not(nsd_drw)
+rppd_ports = gatpoly.interacting(rppd_res).not(rppd_res)
+
+## rsil
+rsil_exc = psd_drw.join(salblock_drw).join(nsd_drw).join(nsd_block)
+rsil_res = polyres_mk.and(res_drw).not(rsil_exc)
+rsil_ports = gatpoly.interacting(rsil_res).not(rsil_res)
+
+# ===============
+# ---- METAL ----
+# ===============
+
+# res_metal1
+res_metal1 = metal1.and(metal1_res)
+
+# res_metal2
+res_metal2 = metal2.and(metal2_res)
+
+# res_metal3
+res_metal3 = metal3.and(metal3_res)
+
+# res_metal4
+res_metal4 = metal4.and(metal4_res)
+
+# res_metal5
+res_metal5 = metal5.and(metal5_res)
+
+# res_topmetal1
+res_topmetal1 = topmetal1.and(topmetal1_res)
+
+# res_topmetal2
+res_topmetal2 = topmetal2.and(topmetal2_res)
+
+#==================================
+# -------- CAP DERIVATIONS --------
+#==================================
+
+logger.info('Starting CAP DERIVATIONS')
+
+rfmimcap_exc = ind_drw.join(ind_pin)
+
+# === MIMCAP ===
+mimcap_exclude = pwell_block.join(rfmimcap_exc)
+
+mim_top = mim_drw.overlapping(topmetal1_con).and(metal5_con)
+mim_btm = metal5_con.and(mim_drw).sized(0.6.um)
+mim_via = vmim_drw.join(topvia1_drw).and(mim_drw)
+topvia1_n_cap = topvia1_drw.not(mim_via)
+
+# === cap_cmim ===
+cmim_top = mim_top.not(mimcap_exclude)
+cmim_btm = mim_btm.covering(cmim_top)
+cmim_dev = mim_drw.covering(cmim_top).and(cmim_btm)
+
+# === rfcmim ===
+rfmim_area = pwell_block.interacting(mim_drw)
+rfmim_top = mim_top.and(rfmim_area).not(rfmimcap_exc)
+rfmim_btm = mim_btm.and(rfmim_area).covering(rfmim_top)
+rfmim_dev = mim_drw.covering(rfmim_top).and(rfmim_btm)
+rfmim_sub = ptap.extents.interacting(rfmim_area)
+rfmeas_mk = metal5_con.overlapping(rfmim_btm).and(rfmim_area)
+
+# === svaricap ===
+cap_exc = nsd_drw.join(trans_drw).join(emwind_drw)
+ .join(emwihv_drw).join(salblock_drw).join(polyres_drw)
+ .join(extblock_drw).join(res_drw).join(activ_mask)
+ .join(recog_diode).join(recog_esd).join(ind_drw)
+ .join(ind_pin).join(substrate_drw)
+
+varicap_exc = pwell.join(pwell_block).join(nwell_holes).join(cap_exc)
+
+varicap_core = ngate_hv_base.and(nwell_iso).not(varicap_exc)
+varicap_diff_port = nactiv.interacting(varicap_core).not(varicap_core)
+ .and(nwell_iso).not(varicap_exc).sized(-1.nm)
+varicap_poly_port = gatpoly.interacting(varicap_core)
+varicap_ports = varicap_poly_port.join(varicap_diff_port)
+varicap_sub = ptap.and(thickgateox_drw)
+varicap_dev_mk = thickgateox_drw.covering(varicap_core).interacting(varicap_ports)
+
+#================================
+# ------ ESD DERIVATIONS --------
+#================================
+
+logger.info('Starting ESD DERIVATIONS')
+
+# General
+esd_exclude = nsd_block.join(nsd_drw).join(trans_drw)
+ .join(emwind_drw).join(emwihv_drw).join(polyres_drw)
+ .join(extblock_drw).join(res_drw).join(substrate_drw)
+ .join(ind_drw).join(ind_pin)
+
+esd_exc_d = gatpoly.join(thickgateox_drw).join(salblock_drw)
+ .join(esd_exclude)
+
+idiodevdd_exc = esd_exc_d.join(nwell_holes)
+diodevdd_exc = idiodevdd_exc.join(nbulay_drw).join(pwell_block)
+
+idiodevss_exc = esd_exc_d.join(nwell_drw.not_interacting(nwell_holes))
+ .join(pwell_block)
+diodevss_exc = idiodevss_exc.join(nbulay_drw)
+
+nw_diode = nwell_drw.not_interacting(pwell_block)
+nw_idiode = nwell_iso.interacting(pwell_block)
+
+#======================
+# ----- diode-ESD -----
+#======================
+
+# diodevdd_2kv
+diodevdd_2kv_e = pactiv.and(nw_diode).and(recog_esd).not(diodevdd_exc)
+diodevdd_2kv_e_1x1 = diodevdd_2kv_e.middle.sized(0.499.um)
+diodevdd_2kv_b_ = nactiv.and(nw_diode).and(recog_esd).not(diodevdd_exc)
+diodevdd_2kv_b = diodevdd_2kv_b_.interacting(diodevdd_2kv_b_.extents.interacting(diodevdd_2kv_e, 1, 1))
+diodevdd_2kv_tb = cont_drw.and(diodevdd_2kv_b).not_interacting(diodevdd_2kv_e)
+diodevdd_2kv_c_ = pactiv.and(pwell).and(recog_esd).not(diodevdd_exc)
+diodevdd_2kv_c = diodevdd_2kv_c_.interacting(diodevdd_2kv_c_.extents.interacting(diodevdd_2kv_b, 1, 1))
+
+# diodevdd_4kv
+diodevdd_4kv_b = diodevdd_2kv_b_.interacting(diodevdd_2kv_b_.extents.interacting(diodevdd_2kv_e, 2, 2))
+diodevdd_4kv_c = diodevdd_2kv_c_.interacting(diodevdd_2kv_c_.extents.interacting(diodevdd_4kv_b, 1, 1))
+diodevdd_4kv_e = diodevdd_4kv_b.extents.sized(-0.15.um)
+diodevdd_4kv_e_1x1 = diodevdd_4kv_e.middle.sized(0.499.um)
+diodevdd_4kv_te = cont_drw.and(diodevdd_2kv_e).not_interacting(diodevdd_4kv_b)
+diodevdd_4kv_tb = cont_drw.and(diodevdd_4kv_b).not_interacting(diodevdd_2kv_e)
+
+# diodevss_2kv
+diodevss_2kv_e = nactiv.and(pwell).and(recog_esd).not(diodevss_exc)
+diodevss_2kv_e_1x1 = diodevss_2kv_e.middle.sized(0.499.um)
+diodevss_2kv_b_ = pactiv.and(pwell).and(recog_esd).not(diodevss_exc)
+diodevss_2kv_b = diodevss_2kv_b_.interacting(diodevss_2kv_b_.extents.interacting(diodevss_2kv_e, 1, 1))
+diodevss_2kv_tb = cont_drw.and(diodevss_2kv_b).not_interacting(diodevss_2kv_e)
+diodevss_2kv_c_ = nactiv.and(nw_diode).and(recog_esd).not(diodevss_exc)
+diodevss_2kv_c = diodevss_2kv_c_.interacting(diodevss_2kv_c_.extents.interacting(diodevss_2kv_b, 1, 1))
+
+# diodevss_4kv
+diodevss_4kv_b = diodevss_2kv_b_.interacting(diodevss_2kv_b_.extents.interacting(diodevss_2kv_e, 2, 2))
+diodevss_4kv_c = diodevss_2kv_c_.interacting(diodevss_2kv_c_.extents.interacting(diodevss_4kv_b, 1, 1))
+diodevss_4kv_e = diodevss_4kv_b.extents.sized(-0.15.um)
+diodevss_4kv_e_1x1 = diodevss_4kv_e.middle.sized(0.499.um)
+diodevss_4kv_te = cont_drw.and(diodevss_2kv_e).not_interacting(diodevss_4kv_b)
+diodevss_4kv_tb = cont_drw.and(diodevss_4kv_b).not_interacting(diodevss_2kv_e)
+
+#=======================
+# ----- idiode-ESD -----
+#=======================
+
+# idiodevdd_2kv
+idiodevdd_2kv_e = pactiv.and(nw_idiode).and(recog_esd).not(idiodevdd_exc)
+idiodevdd_2kv_e_1x1 = idiodevdd_2kv_e.middle.sized(0.499.um)
+idiodevdd_2kv_b_ = nactiv.and(nw_idiode).and(recog_esd).not(idiodevdd_exc)
+idiodevdd_2kv_b = idiodevdd_2kv_b_.interacting(idiodevdd_2kv_b_.extents.interacting(idiodevdd_2kv_e, 1, 1))
+idiodevdd_2kv_tb = cont_drw.and(idiodevdd_2kv_b).not_interacting(idiodevdd_2kv_e)
+idiodevdd_2kv_c_ = pactiv.and(pwell).and(recog_esd).not(idiodevdd_exc)
+idiodevdd_2kv_c = idiodevdd_2kv_c_.interacting(idiodevdd_2kv_c_.extents.interacting(idiodevdd_2kv_b, 1, 1))
+
+# idiodevdd_4kv
+idiodevdd_4kv_b = idiodevdd_2kv_b_.interacting(idiodevdd_2kv_b_.extents.interacting(idiodevdd_2kv_e, 2, 2))
+idiodevdd_4kv_c = idiodevdd_2kv_c_.interacting(idiodevdd_2kv_c_.extents.interacting(idiodevdd_4kv_b, 1, 1))
+idiodevdd_4kv_e = idiodevdd_4kv_b.extents.sized(-0.15.um)
+idiodevdd_4kv_e_1x1 = idiodevdd_4kv_e.middle.sized(0.499.um)
+idiodevdd_4kv_te = cont_drw.and(idiodevdd_2kv_e).not_interacting(idiodevdd_4kv_b)
+idiodevdd_4kv_tb = cont_drw.and(idiodevdd_4kv_b).not_interacting(idiodevdd_2kv_e)
+
+# idiodevss_2kv
+idiodevss_2kv_e = nactiv.and(pwell).and(nbulay_drw).and(recog_esd).not(idiodevss_exc)
+idiodevss_2kv_e_1x1 = idiodevss_2kv_e.middle.sized(0.499.um)
+idiodevss_2kv_b_ = pactiv.and(pwell).and(nbulay_drw).and(recog_esd).not(idiodevss_exc)
+idiodevss_2kv_b = idiodevss_2kv_b_.interacting(idiodevss_2kv_b_.extents.interacting(idiodevss_2kv_e, 1, 1))
+idiodevss_2kv_tb = cont_drw.and(idiodevss_2kv_b).not_interacting(idiodevss_2kv_e)
+idiodevss_2kv_c_ = nactiv.and(nwell_iso).and(recog_esd).not(idiodevss_exc)
+idiodevss_2kv_c = idiodevss_2kv_c_.interacting(idiodevss_2kv_c_.extents.interacting(idiodevss_2kv_b, 1, 1))
+
+# idiodevss_4kv
+idiodevss_4kv_b = idiodevss_2kv_b_.interacting(idiodevss_2kv_b_.extents.interacting(idiodevss_2kv_e, 2, 2))
+idiodevss_4kv_c = idiodevss_2kv_c_.interacting(idiodevss_2kv_c_.extents.interacting(idiodevss_4kv_b, 1, 1))
+idiodevss_4kv_e = idiodevss_4kv_b.extents.sized(-0.15.um)
+idiodevss_4kv_e_1x1 = idiodevss_4kv_e.middle.sized(0.499.um)
+idiodevss_4kv_te = cont_drw.and(idiodevss_2kv_e).not_interacting(idiodevss_4kv_b)
+idiodevss_4kv_tb = cont_drw.and(idiodevss_4kv_b).not_interacting(idiodevss_2kv_e)
+
+#======================
+# ----- MOSCL-ESD -----
+#======================
+
+nmoscl_exc = esd_exclude.join(pwell_block)
+
+# nmoscl_2
+nmoscl_2_patt = glob_to_case_insensitive_glob("nmoscl_2")
+
+gate_moscl = ngate_hv_base.and(salblock_drw).and(nbulay_drw)
+nmoscl_2_n_ = recog_esd.interacting(text_drw.texts(nmoscl_2_patt))
+nmoscl_2_n = nmoscl_2_n_.interacting(gate_moscl, 12)
+nmoscl_2_n_port = nwell_drw.and(nmoscl_2_n)
+nmoscl_2_p_ = ptap.and(nbulay_drw).inside(nmoscl_2_n_)
+# Using box with area 1x1 to be used as a reference to (m)
+nmoscl_2_p =nmoscl_2_p_.middle(as_boxes).sized(0.499.um)
+
+# nmoscl_4
+nmoscl_4_patt = glob_to_case_insensitive_glob("nmoscl_4")
+
+gate_moscl = ngate_hv_base.and(salblock_drw).and(nbulay_drw)
+nmoscl_4_n_ = recog_esd.interacting(text_drw.texts(nmoscl_4_patt))
+nmoscl_4_n = nmoscl_4_n_.interacting(gate_moscl, 24)
+nmoscl_4_n_port = nwell_drw.and(nmoscl_4_n)
+nmoscl_4_p_ = ptap.and(nbulay_drw).inside(nmoscl_4_n_)
+# Using box with area 1x1 to be used as a reference to (m)
+nmoscl_4_p =nmoscl_4_p_.middle(as_boxes).sized(0.499.um)
+
+#===============================
+# ---- Inductor DERIVATIONS ----
+#===============================
+
+logger.info('Starting Inductor DERIVATIONS')
+
+ind_exc = gatpoly.join(nsd_drw).join(nbulay_drw)
+ .join(thickgateox_drw).join(emwind_drw).join(emwihv_drw)
+ .join(salblock_drw).join(polyres_drw).join(mim_drw)
+ .join(extblock_drw).join(res_drw).join(activ_mask)
+ .join(recog_diode).join(recog_esd).join(substrate_drw)
+
+# General
+la_patt = glob_to_case_insensitive_glob("LA")
+lb_patt = glob_to_case_insensitive_glob("LB")
+lc_patt = glob_to_case_insensitive_glob("LC")
+ind2_patt = glob_to_case_insensitive_glob("inductor2*")
+ind3_patt = glob_to_case_insensitive_glob("inductor3*")
+
+ind_edges = ind_drw.edges
+ind_core_ = topmetal2.join(topmetal1).and(ind_drw).merged.not(ind_exc)
+ind_ports_ = ind_pin.and(ind_core_).interacting(ind_edges)
+ind_port_la = ind_ports_.interacting(ind_text.texts(la_patt))
+ind_la_tm1 = ind_port_la.and(topmetal1)
+ind_port_lb = ind_ports_.interacting(ind_text.texts(lb_patt))
+ind_lb_tm1 = ind_port_lb.and(topmetal1)
+ind_port_lc = ind_ports_.interacting(ind_text.texts(lc_patt))
+ind_lc_tm2 = ind_port_lc.and(topmetal2)
+
+# inductor2
+ind2_ports = ind_port_la.join(ind_port_lb)
+ind2_core = ind_core_.interacting(ind_port_la, 1).interacting(ind_port_lb, 1)
+ind2_mk_ = ind_drw.interacting(text_drw.texts(ind2_patt))
+ind2_mk = ind2_mk_.interacting(ind2_core).interacting(ind2_ports).not_interacting(ind_port_lc)
+ind2_sub1 = pwell.and(ind_drw).interacting(ind2_core)
+ind2_sub2 = pwell_block.and(ind_drw).interacting(ind2_core).sized(1.nm)
+ind2_well = nwell_drw.and(ind_drw).interacting(ind2_core).sized(-1.nm)
+ind2_sub = ind2_sub1.join(ind2_sub2).join(ind2_well)
+# inductor3
+ind3_ports = ind_la_tm1.join(ind_lb_tm1).join(ind_lc_tm2)
+ind3_core = ind_core_.interacting(ind_lb_tm1, 1).interacting(ind_lb_tm1, 1).interacting(ind_lc_tm2, 1)
+ind3_mk_ = ind_drw.interacting(text_drw.texts(ind3_patt))
+ind3_mk = ind3_mk_.interacting(ind3_core).interacting(ind3_ports)
+ind3_sub1 = pwell.and(ind_drw).interacting(ind3_core)
+ind3_sub2 = pwell_block.and(ind_drw).interacting(ind3_core).sized(1.nm)
+ind3_well = nwell_drw.and(ind_drw).interacting(ind3_core).sized(-1.nm)
+ind3_sub = ind3_sub1.join(ind3_sub2).join(ind3_well)
+
+#===============================
+# ------ Taps DERIVATIONS ------
+#===============================
+
+logger.info('Starting Taps DERIVATIONS')
+
+taps_exclude = gatpoly.join(nsd_drw).join(trans_drw)
+ .join(emwind_drw).join(emwihv_drw).join(salblock_drw)
+ .join(polyres_drw).join(extblock_drw).join(res_drw)
+ .join(activ_mask).join(recog_diode).join(recog_esd)
+ .join(ind_drw).join(ind_pin)
+
+# === ntap1 ===
+ntap1_exc = pwell.join(psd_drw).join(taps_exclude)
+
+ntap1_tie = nactiv.and(ntap1_mk).extents.not(ntap1_exc)
+ntap1_well = ntap1_mk.covering(ntap1_tie)
+
+# === ptap1 ===
+ptap1_exc = nwell_drw.join(taps_exclude)
+
+ptap1_tie = pactiv.and(ptap1_mk).extents.not(ptap1_exc)
+ptap1_sub = pwell.covering(ptap1_tie)
+
+#================================================
+#------------ DEVICES CONNECTIVITY --------------
+#================================================
+
+logger.info('Starting GF180 LVS connectivity setup')
+
+#================================
+# ----- GENERAL CONNECTIONS -----
+#================================
+
+logger.info('Starting GF180 LVS connectivity setup (Inter-layer)')
+
+# Inter-layer
+connect(pwell_sub, pwell)
+connect(pwell, ptap)
+connect(nwell_drw, ntap)
+connect(ntap, cont_drw)
+connect(ptap, cont_drw)
+connect(poly_con, cont_drw)
+connect(nsd_fet, cont_drw)
+connect(psd_fet, cont_drw)
+connect(cont_drw, metal1_con)
+connect(metal1_con, via1_drw)
+connect(via1_drw, metal2_con)
+connect(metal2_con, via2_drw)
+connect(via2_drw, metal3_con)
+connect(metal3_con, via3_drw)
+connect(via3_drw, metal4_con)
+connect(metal4_con, via4_drw)
+connect(via4_drw, metal5_con)
+connect(metal5_con, topvia1_n_cap)
+connect(topvia1_n_cap, topmetal1_con)
+connect(topmetal1_con, topvia2_drw)
+connect(topvia2_drw, topmetal2_con)
+
+# salicide connection
+connect(nsd_fet, nsd_ptap_abutt)
+connect(nsd_ptap_abutt, ptap)
+connect(psd_fet, psd_ntap_abutt)
+connect(psd_ntap_abutt, ntap)
+
+# Attaching labels
+connect(metal1_con, metal1_text)
+connect(metal2_con, metal2_text)
+connect(metal3_con, metal3_text)
+connect(metal4_con, metal4_text)
+connect(metal5_con, metal5_text)
+connect(topmetal1_con, topmetal1_text)
+connect(topmetal2_con, topmetal2_text)
+
+logger.info('Starting SG13G2 LVS connectivity setup (Global)')
+
+#================================
+# ----- MOSFET CONNECTIONS ------
+#================================
+
+logger.info('Starting LVS MOSFET CONNECTIONS')
+# Covered in general connections
+
+#================================
+# ---- RF-MOSFET CONNECTIONS ----
+#================================
+
+logger.info('Starting LVS RF-MOSFET CONNECTIONS')
+# Covered in general connections
+
+#================================
+# ------ BJT CONNECTIONS --------
+#================================
+
+logger.info('Starting LVS BJT CONNECTIONS')
+
+# =============
+# ---- NPN ----
+# =============
+
+# General
+connect(npn_sub, pwell)
+
+# npn13G2 nodes connections
+connect(npn13G2_te, npn13G2_e_pin)
+connect(npn13G2_tc, npn13G2_c_pin)
+connect(npn13G2_tb, npn13G2_b_pin)
+connect(npn13G2_e_pin, cont_drw)
+connect(npn13G2_c_pin, cont_drw)
+connect(npn13G2_b_pin, cont_drw)
+connect(npn_sub, pwell)
+connect(npn13G2_e_pin, emwind_drw)
+connect(emwind_drw, metal1_con)
+
+# npn13G2L nodes connections
+connect(npn13G2l_te, npn13G2l_e_pin)
+connect(npn13G2l_tc, npn13G2l_c_pin)
+connect(npn13G2l_tb, npn13G2l_b_pin)
+connect(npn13G2l_e_pin, cont_drw)
+connect(npn13G2l_c_pin, cont_drw)
+connect(npn13G2l_b_pin, cont_drw)
+connect(npn_sub, pwell)
+
+# npn13G2V nodes connections
+connect(npn13G2v_te, npn13G2v_e_pin)
+connect(npn13G2v_tc, npn13G2v_c_pin)
+connect(npn13G2v_tb, npn13G2v_b_pin)
+connect(npn13G2v_e_pin, cont_drw)
+connect(npn13G2v_c_pin, cont_drw)
+connect(npn13G2v_b_pin, cont_drw)
+connect(npn_sub, pwell)
+
+# =============
+# ---- PNP ----
+# =============
+
+# pnp_mpa nodes connections
+connect(pnp_mpa_e, cont_drw)
+connect(pnp_mpa_b, cont_drw)
+connect(pnp_mpa_c, cont_drw)
+
+#================================
+# ----- DIODE CONNECTIONS -------
+#================================
+
+logger.info('Starting LVS DIODE CONNECTIONS')
+
+# dantenna diode
+connect(dantenna_n, cont_drw)
+connect(dantenna_p, pwell)
+
+# dantenna diode
+connect(dpantenna_n, nwell_drw)
+connect(dpantenna_p, cont_drw)
+
+# dantenna diode
+connect(schottcky_p_1x1, schottcky_p)
+connect(schottcky_p, metal1_con)
+connect(schottcky_n, schottcky_n_port)
+connect(schottcky_n_port, schottcky_n_con)
+connect(schottcky_n_con, metal1_con)
+
+#================================
+# ------- RES CONNECTIONS -------
+#================================
+
+logger.info('Starting RESISTOR CONNECTIONS')
+
+# === rsil ===
+connect(rsil_ports, cont_drw)
+
+# === rppd ===
+connect(rppd_ports, cont_drw)
+
+# === rhigh ===
+connect(rhigh_ports, cont_drw)
+
+# === Metal Res ===
+# Added in general connections
+
+#==================================
+# -------- CAP CONNECTIONS --------
+#==================================
+
+logger.info('Starting LVS CAP CONNECTIONS')
+
+# === cap_mim ===
+connect(cmim_btm, metal5_con)
+connect(cmim_top, mim_via)
+connect(mim_via, topmetal1_con)
+
+# === rfcmim ===
+connect(rfmim_btm, metal5_con)
+connect(rfmim_top, mim_via)
+connect(rfmim_sub, ptap)
+
+# === svarivap ===
+connect(varicap_ports, cont_drw)
+connect(varicap_ports, text_drw)
+connect(varicap_sub, ptap)
+
+#================================
+# ------- ESD CONNECTIONS -------
+#================================
+
+logger.info('Starting ESD CONNECTIONS')
+
+#======================
+# ----- diode-ESD -----
+#======================
+
+# diodevdd_2kv
+connect(diodevdd_2kv_e_1x1, diodevdd_2kv_e)
+connect(diodevdd_2kv_e, cont_drw)
+connect(diodevdd_2kv_b, diodevdd_2kv_tb)
+connect(diodevdd_2kv_tb, cont_drw)
+connect(diodevdd_2kv_c, cont_drw)
+
+# diodevdd_4kv
+connect(diodevdd_4kv_e_1x1, diodevdd_4kv_e)
+connect(diodevdd_4kv_e, diodevdd_4kv_te)
+connect(diodevdd_4kv_te, cont_drw)
+connect(diodevdd_4kv_b, diodevdd_4kv_tb)
+connect(diodevdd_4kv_tb, cont_drw)
+connect(diodevdd_4kv_c, cont_drw)
+
+# diodevss_2kv
+connect(diodevss_2kv_e_1x1, diodevss_2kv_e)
+connect(diodevss_2kv_e, cont_drw)
+connect(diodevss_2kv_b, diodevss_2kv_tb)
+connect(diodevss_2kv_tb, cont_drw)
+connect(diodevss_2kv_c, cont_drw)
+
+# diodevss_4kv
+connect(diodevss_4kv_e_1x1, diodevss_4kv_e)
+connect(diodevss_4kv_e, diodevss_4kv_te)
+connect(diodevss_4kv_te, cont_drw)
+connect(diodevss_4kv_b, diodevss_4kv_tb)
+connect(diodevss_4kv_tb, cont_drw)
+connect(diodevss_4kv_c, cont_drw)
+
+#=======================
+# ----- idiode-ESD -----
+#=======================
+
+# idiodevdd_2kv
+connect(idiodevdd_2kv_e_1x1, idiodevdd_2kv_e)
+connect(idiodevdd_2kv_e, cont_drw)
+connect(idiodevdd_2kv_b, idiodevdd_2kv_tb)
+connect(idiodevdd_2kv_tb, cont_drw)
+connect(idiodevdd_2kv_c, cont_drw)
+
+# idiodevdd_4kv
+connect(idiodevdd_4kv_e_1x1, idiodevdd_4kv_e)
+connect(idiodevdd_4kv_e, idiodevdd_4kv_te)
+connect(idiodevdd_4kv_te, cont_drw)
+connect(idiodevdd_4kv_b, idiodevdd_4kv_tb)
+connect(idiodevdd_4kv_tb, cont_drw)
+connect(idiodevdd_4kv_c, cont_drw)
+
+# idiodevss_2kv
+connect(idiodevss_2kv_e_1x1, idiodevss_2kv_e)
+connect(idiodevss_2kv_e, cont_drw)
+connect(idiodevss_2kv_b, idiodevss_2kv_tb)
+connect(idiodevss_2kv_tb, cont_drw)
+connect(idiodevss_2kv_c, cont_drw)
+
+# idiodevss_4kv
+connect(idiodevss_4kv_e_1x1, idiodevss_4kv_e)
+connect(idiodevss_4kv_e, idiodevss_4kv_te)
+connect(idiodevss_4kv_te, cont_drw)
+connect(idiodevss_4kv_b, idiodevss_4kv_tb)
+connect(idiodevss_4kv_tb, cont_drw)
+connect(idiodevss_4kv_c, cont_drw)
+
+#======================
+# ----- MOSCL-ESD -----
+#======================
+
+# nmoscl_2
+connect(nmoscl_2_n, nmoscl_2_n_port)
+connect(nmoscl_2_n_port, cont_drw)
+connect(nmoscl_2_p, nmoscl_2_p_)
+connect(nmoscl_2_p_, ptap)
+
+# nmoscl_4
+connect(nmoscl_4_n, nmoscl_4_n_port)
+connect(nmoscl_4_n_port, cont_drw)
+connect(nmoscl_4_p, nmoscl_4_p_)
+connect(nmoscl_4_p_, ptap)
+
+#=================================
+# ----- Inductor CONNECTIONS -----
+#=================================
+
+logger.info('Starting Inductor CONNECTIONS')
+
+# ind2
+connect(ind2_ports, ind_pin)
+connect(ind_pin, ind_text)
+connect(ind_pin, topmetal2_con)
+connect(ind2_sub, pwell)
+connect(ind2_sub, nwell_drw)
+
+# ind3
+connect(ind3_ports, ind_pin)
+connect(ind_pin, topmetal1_con)
+connect(ind3_sub, pwell)
+connect(ind3_sub, nwell_drw)
+
+#================================
+# ------- Taps CONNECTIONS ------
+#================================
+
+logger.info('Starting LVS Taps CONNECTIONS')
+
+# ntap1
+connect(ntap1_tie, cont_drw)
+connect(ntap1_well, nwell_drw)
+
+# ptap1
+connect(ptap1_tie, cont_drw)
+connect(ptap1_sub, pwell)
+
+#================================================
+#------------- DEVICES EXTRACTION ---------------
+#================================================
+
+logger.info('Starting SG13G2 LVS DEVICES EXTRACTION')
+
+#================================
+# ----- MOSFET EXTRACTION -------
+#================================
+
+logger.info('Starting MOSFET EXTRACTION')
+
+# ==============
+# ---- NMOS ----
+# ==============
+
+
+logger.info('Starting NMOS EXTRACTION')
+
+# nmos - LV
+logger.info('Extraction of NMOS-LV transistor')
+extract_devices(mos4('sg13_lv_nmos'),
+ { 'SD' => nsd_fet,
+ 'G' => ngate_lv,
+ 'tS' => nsd_fet,
+ 'tD' => nsd_fet,
+ 'tG' => poly_con,
+ 'W' => pwell })
+
+# nmos - HV
+logger.info('Extraction of NMOS-HV transistor')
+extract_devices(mos4('sg13_hv_nmos'),
+ { 'SD' => nsd_fet,
+ 'G' => ngate_hv,
+ 'tS' => nsd_fet,
+ 'tD' => nsd_fet,
+ 'tG' => poly_con,
+ 'W' => pwell })
+
+# ==============
+# ---- PMOS ----
+# ==============
+
+logger.info('Starting PMOS EXTRACTION')
+
+# pmos - LV
+logger.info('Extraction of PMOS-LV transistor')
+extract_devices(mos4('sg13_lv_pmos'),
+ { 'SD' => psd_fet,
+ 'G' => pgate_lv,
+ 'tS' => psd_fet,
+ 'tD' => psd_fet,
+ 'tG' => poly_con,
+ 'W' => nwell_drw })
+
+# pmos - HV
+logger.info('Extraction of PMOS-HV transistor')
+extract_devices(mos4('sg13_hv_pmos'),
+ { 'SD' => psd_fet,
+ 'G' => pgate_hv,
+ 'tS' => psd_fet,
+ 'tD' => psd_fet,
+ 'tG' => poly_con,
+ 'W' => nwell_drw })
+
+#================================
+# ---- RF-MOSFET EXTRACTION -----
+#================================
+
+logger.info('Starting RF-MOSFET EXTRACTION')
+
+# ===============
+# --- RF-NMOS ---
+# ===============
+
+# rfnmos - LV
+logger.info('Extraction of RF-NMOS-LV transistor')
+extract_devices(mos4('rfnmos'),
+ { 'SD' => nsd_fet,
+ 'G' => rfngate_lv,
+ 'W' => pwell,
+ 'tS' => nsd_fet,
+ 'tD' => nsd_fet,
+ 'tG' => poly_con,
+ 'tW' => ptap,
+ })
+
+# rfnmos - HV
+logger.info('Extraction of RF-NMOS-HV transistor')
+extract_devices(mos4('rfnmoshv'),
+ { 'SD' => nsd_fet,
+ 'G' => rfngate_hv,
+ 'W' => pwell,
+ 'tS' => nsd_fet,
+ 'tD' => nsd_fet,
+ 'tG' => poly_con,
+ 'tW' => ptap,
+ })
+
+# ===============
+# --- RF-PMOS ---
+# ===============
+
+# rfpmos - LV
+logger.info('Extraction of RF-PMOS-LV transistor')
+extract_devices(mos4('rfpmos'),
+ { 'SD' => psd_fet,
+ 'G' => rfpgate_lv,
+ 'tS' => psd_fet,
+ 'tD' => psd_fet,
+ 'tG' => poly_con,
+ 'W' => nwell_drw,
+ 'tW' => ntap,
+ })
+
+# rfpmos - HV
+logger.info('Extraction of RF-PMOS-HV transistor')
+extract_devices(mos4('rfpmoshv'),
+ { 'SD' => psd_fet,
+ 'G' => rfpgate_hv,
+ 'tS' => psd_fet,
+ 'tD' => psd_fet,
+ 'tG' => poly_con,
+ 'W' => nwell_drw,
+ 'tW' => ntap,
+ })
+
+#================================
+# ------- BJT EXTRACTION --------
+#================================
+
+logger.info('Starting BJT EXTRACTION')
+
+# =============
+# ---- NPN ----
+# =============
+
+logger.info('Starting NPN-BJT EXTRACTION')
+
+logger.info('Extraction of npn13G2 BJT transistor')
+extract_devices(bjt4('npn13G2', CustomBJT4), {
+ 'C' => npn13G2_c,
+ 'B' => npn13G2_b,
+ 'E' => npn13G2_e,
+ 'S' => npn_sub,
+ 'tC' => npn13G2_tc,
+ 'tB' => npn13G2_tb,
+ 'tE' => npn13G2_te,
+ 'tS' => npn_sub
+ })
+
+logger.info('Extraction of npn13G2L BJT transistor')
+extract_devices(bjt4('npn13G2l', CustomBJT4), {
+ 'C' => npn13G2l_c,
+ 'B' => npn13G2l_b,
+ 'E' => npn13G2l_e,
+ 'S' => npn_sub,
+ 'tC' => npn13G2l_tc,
+ 'tB' => npn13G2l_tb,
+ 'tE' => npn13G2l_te,
+ 'tS' => npn_sub
+ })
+
+logger.info('Extraction of npn13G2V BJT transistor')
+extract_devices(bjt4('npn13G2v', CustomBJT4), {
+ 'C' => npn13G2v_c,
+ 'B' => npn13G2v_b,
+ 'E' => npn13G2v_e,
+ 'S' => npn_sub,
+ 'tC' => npn13G2v_tc,
+ 'tB' => npn13G2v_tb,
+ 'tE' => npn13G2v_te,
+ 'tS' => npn_sub
+ })
+
+# =============
+# ---- PNP ----
+# =============
+
+logger.info('Starting PNP-BJT EXTRACTION')
+
+# pnp_mpa BJT
+logger.info('Extracting pnpMPA BJT')
+extract_devices(bjt3('pnpMPA', CustomBJT3), { 'C' => pnp_mpa_c.extents,
+ 'B' => pnp_mpa_b.extents,
+ 'E' => pnp_mpa_e,
+ 'tC' => pnp_mpa_c,
+ 'tB' => pnp_mpa_b,
+ 'tE' => pnp_mpa_e })
+
+#================================
+# ------ DIODE EXTRACTION -------
+#================================
+
+logger.info('Starting DIODE EXTRACTION')
+
+# dantenna diode
+logger.info('Extracting dantenna diode')
+extract_devices(diode('dantenna', EnDiode), { 'N' => dantenna_n, 'P' => dantenna_p })
+
+# dpantenna diode
+logger.info('Extracting dpantenna diode')
+extract_devices(diode('dpantenna', EnDiode), { 'N' => dpantenna_n, 'P' => dpantenna_p })
+
+# schottky_nbl1 diode
+logger.info('Extracting schottky_nbl1 diode')
+extract_devices(bjt3('schottky_nbl1', Esd3Term), { 'C' => schottcky_sub,
+ 'B' => schottcky_n_port.extents,
+ 'E' => schottcky_p_1x1,
+ 'tC' => ptap,
+ 'tB' => schottcky_n_port,
+ 'tE' => schottcky_p_1x1 })
+
+#================================
+# ---- RESISTOR EXTRACTIONS -----
+#================================
+
+logger.info('Starting RESISTOR EXTRACTION')
+
+# ==============
+# ---- POLY ----
+# ==============
+
+# rsil
+logger.info('Extracting rsil resistor')
+extract_devices(GeneralNTerminalExtractor.new('rsil', 2), {
+ 'core' => rsil_res,
+ 'ports' => rsil_ports,
+ 'meas_mk' => polyres_drw,
+ 'dev_mk' => polyres_drw.interacting(rsil_res),
+ 'sub_mk' => pwell.join(nwell_drw)
+ })
+# rppd
+logger.info('Extracting rppd resistor')
+extract_devices(GeneralNTerminalExtractor.new('rppd', 2), {
+ 'core' => rppd_res,
+ 'ports' => rppd_ports,
+ 'meas_mk' => polyres_drw,
+ 'dev_mk' => polyres_drw.interacting(rppd_res),
+ 'sub_mk' => pwell.join(nwell_drw)
+ })
+
+# rhigh
+logger.info('Extracting rhigh resistor')
+extract_devices(GeneralNTerminalExtractor.new('rhigh', 2), {
+ 'core' => rhigh_res,
+ 'ports' => rhigh_ports,
+ 'meas_mk' => polyres_drw,
+ 'dev_mk' => polyres_drw.interacting(rhigh_res),
+ 'sub_mk' => pwell.join(nwell_drw)
+ })
+
+# ===============
+# ---- METAL ----
+# ===============
+
+# RM1
+logger.info('Extracting res_metal1 resistor')
+extract_devices(resistor('res_metal1', 1.0, RES2), { 'R' => res_metal1, 'C' => metal1_con })
+
+# RM2
+logger.info('Extracting res_metal2 resistor')
+extract_devices(resistor('res_metal2', 1.0, RES2), { 'R' => res_metal2, 'C' => metal2_con })
+
+# RM3
+logger.info('Extracting res_metal3 resistor')
+extract_devices(resistor('res_metal3', 1.0, RES2), { 'R' => res_metal3, 'C' => metal3_con })
+
+# RM4
+logger.info('Extracting res_metal4 resistor')
+extract_devices(resistor('res_metal4', 1.0, RES2), { 'R' => res_metal4, 'C' => metal4_con })
+
+# RM5
+logger.info('Extracting res_metal5 resistor')
+extract_devices(resistor('res_metal5', 1.0, RES2), { 'R' => res_metal5, 'C' => metal5_con })
+
+# RTM1
+logger.info('Extracting res_topmetal1 resistor')
+extract_devices(resistor('res_topmetal1', 1.0, RES2), { 'R' => res_topmetal1, 'C' => topmetal1_con })
+
+# RTM2
+logger.info('Extracting res_topmetal2 resistor')
+extract_devices(resistor('res_topmetal2', 1.0, RES2), { 'R' => res_topmetal2, 'C' => topmetal2_con })
+
+#==================================
+# --------- CAP EXTRACTION --------
+#==================================
+
+logger.info('Starting CAP EXTRACTION')
+
+# === cap_cmim ===
+logger.info('Extracting cap_cmim device')
+extract_devices(MIMCAPExtractor.new('cap_cmim'), {
+ 'core' => cmim_top,
+ 'top_mim' => cmim_top,
+ 'btm_mim' => cmim_btm,
+ 'meas_mk' => cmim_dev,
+ 'dev_mk' => cmim_dev,
+ })
+
+# === rfcmim ===
+logger.info('Extracting rfcmim device')
+extract_devices(MIMCAPExtractor.new('rfcmim'), {
+ 'core' => rfmim_top,
+ 'top_mim' => rfmim_top,
+ 'btm_mim' => rfmim_btm,
+ 'dev_mk' => rfmim_area.covering(rfmim_dev),
+ 'meas_mk' => rfmeas_mk,
+ 'sub_mk' => rfmim_sub,
+ })
+
+# === svaricap ===
+logger.info('Extracting sg13_hv_svaricap varactor')
+extract_devices(GeneralNTerminalExtractor.new('sg13_hv_svaricap', 3), {
+ 'core' => varicap_core,
+ 'ports' => varicap_ports,
+ 'meas_mk' => activ,
+ 'dev_mk' => varicap_dev_mk,
+ 'sub_mk' => varicap_sub
+ })
+
+#================================
+# ------- ESD EXTRACTION --------
+#================================
+
+logger.info('Starting ESD EXTRACTION')
+
+#======================
+# ----- diode-ESD -----
+#======================
+
+# diodevdd_2kv
+logger.info('Extracting diodevdd_2kv ESD device')
+extract_devices(bjt3('diodevdd_2kv', Esd3Term), { 'C' => diodevdd_2kv_c.extents,
+ 'B' => diodevdd_2kv_b.extents,
+ 'E' => diodevdd_2kv_e_1x1,
+ 'tC' => diodevdd_2kv_c,
+ 'tB' => diodevdd_2kv_b,
+ 'tE' => diodevdd_2kv_e_1x1 })
+
+# diodevdd_4kv
+logger.info('Extracting diodevdd_4kv ESD device')
+extract_devices(bjt3('diodevdd_4kv', Esd3Term), { 'C' => diodevdd_4kv_c.extents,
+ 'B' => diodevdd_4kv_b.extents,
+ 'E' => diodevdd_4kv_e_1x1,
+ 'tC' => diodevdd_4kv_c,
+ 'tB' => diodevdd_4kv_b,
+ 'tE' => diodevdd_4kv_e_1x1 })
+
+# diodevss_2kv
+logger.info('Extracting diodevss_2kv ESD device')
+extract_devices(bjt3('diodevss_2kv', Esd3Term), { 'C' => diodevss_2kv_c.extents,
+ 'B' => diodevss_2kv_b.extents,
+ 'E' => diodevss_2kv_e_1x1,
+ 'tC' => diodevss_2kv_c,
+ 'tB' => diodevss_2kv_b,
+ 'tE' => diodevss_2kv_e_1x1 })
+
+# diodevss_4kv
+logger.info('Extracting diodevss_4kv ESD device')
+extract_devices(bjt3('diodevss_4kv', Esd3Term), { 'C' => diodevss_4kv_c.extents,
+ 'B' => diodevss_4kv_b.extents,
+ 'E' => diodevss_4kv_e_1x1,
+ 'tC' => diodevss_4kv_c,
+ 'tB' => diodevss_4kv_b,
+ 'tE' => diodevss_4kv_e_1x1 })
+
+#=======================
+# ----- idiode-ESD -----
+#=======================
+
+# idiodevdd_2kv
+logger.info('Extracting idiodevdd_2kv ESD device')
+extract_devices(bjt3('idiodevdd_2kv', Esd3Term), { 'C' => idiodevdd_2kv_c.extents,
+ 'B' => idiodevdd_2kv_b.extents,
+ 'E' => idiodevdd_2kv_e_1x1,
+ 'tC' => idiodevdd_2kv_c,
+ 'tB' => idiodevdd_2kv_b,
+ 'tE' => idiodevdd_2kv_e_1x1 })
+
+# idiodevdd_4kv
+logger.info('Extracting idiodevdd_4kv ESD device')
+extract_devices(bjt3('idiodevdd_4kv', Esd3Term), { 'C' => idiodevdd_4kv_c.extents,
+ 'B' => idiodevdd_4kv_b.extents,
+ 'E' => idiodevdd_4kv_e_1x1,
+ 'tC' => idiodevdd_4kv_c,
+ 'tB' => idiodevdd_4kv_b,
+ 'tE' => idiodevdd_4kv_e_1x1 })
+
+# idiodevss_2kv
+logger.info('Extracting idiodevss_2kv ESD device')
+extract_devices(bjt3('idiodevss_2kv', Esd3Term), { 'C' => idiodevss_2kv_c.extents,
+ 'B' => idiodevss_2kv_b.extents,
+ 'E' => idiodevss_2kv_e_1x1,
+ 'tC' => idiodevss_2kv_c,
+ 'tB' => idiodevss_2kv_b,
+ 'tE' => idiodevss_2kv_e_1x1 })
+
+# idiodevss_4kv
+logger.info('Extracting idiodevss_4kv ESD device')
+extract_devices(bjt3('idiodevss_4kv', Esd3Term), { 'C' => idiodevss_4kv_c.extents,
+ 'B' => idiodevss_4kv_b.extents,
+ 'E' => idiodevss_4kv_e_1x1,
+ 'tC' => idiodevss_4kv_c,
+ 'tB' => idiodevss_4kv_b,
+ 'tE' => idiodevss_4kv_e_1x1 })
+
+#======================
+# ----- MOSCL-ESD -----
+#======================
+
+# nmoscl_2
+logger.info('Extracting nmoscl_2 ESD device')
+extract_devices(diode('nmoscl_2', Esd2Term), { 'N' => nmoscl_2_n, 'P' => nmoscl_2_p })
+
+# nmoscl_4
+logger.info('Extracting nmoscl_4 ESD device')
+extract_devices(diode('nmoscl_4', Esd2Term), { 'N' => nmoscl_4_n, 'P' => nmoscl_4_p })
+
+#=================================
+# ----- Inductor EXTRACTIONS -----
+#=================================
+
+logger.info('Starting Inductor EXTRACTION')
+
+# ind2
+logger.info('Extracting Inductor2 device')
+extract_devices(GeneralNTerminalExtractor.new('inductor', 2), {
+ 'core' => ind2_core,
+ 'ports' => ind2_ports,
+ 'meas_mk' => topmetal2.and(ind2_core),
+ 'dev_mk' => ind2_mk,
+ 'sub_mk' => ind2_sub
+ })
+
+# ind3
+logger.info('Extracting Inductor3 device')
+extract_devices(GeneralNTerminalExtractor.new('inductor3', 3), {
+ 'core' => ind3_core,
+ 'ports' => ind3_ports,
+ 'meas_mk' => topmetal2.and(ind3_core),
+ 'dev_mk' => ind3_mk,
+ 'sub_mk' => ind3_sub
+ })
+
+#================================
+# ------- Taps EXTRACTIONS ------
+#================================
+
+logger.info('Starting Taps EXTRACTION')
+
+# ntap1
+logger.info('Extracting ntap1 device')
+extract_devices(diode('ntap1', CustomTap), { 'N' => ntap1_tie, 'P' => ntap1_well })
+
+# ptap1
+logger.info('Extracting ptap1 device')
+extract_devices(diode('ptap1', CustomTap), { 'N' => ptap1_tie, 'P' => ptap1_sub })
+
+#==================================================
+# ------------ COMPARISON PREPARATIONS ------------
+#==================================================
+
+logger.info('Starting SG13G2 LVS Options Preparations')
+
+# === Extract Netlist Only ===
+netlist if NET_ONLY
+return if NET_ONLY
+
+# === Aligns the extracted netlist vs. the schematic ===
+logger.info('Starting SG13G2 LVS Alignment')
+align
+
+#=== NETLIST OPTIONS ===
+logger.info('Starting SG13G2 LVS Simplification')
+# SIMPLIFY
+netlist.simplify if SIMPLIFY
+schematic.simplify if SIMPLIFY
+
+# TOP_LVL_PINS
+netlist.make_top_level_pins if TOP_LVL_PINS
+schematic.make_top_level_pins if TOP_LVL_PINS
+
+# COMBINE_DEVICES
+netlist.combine_devices if COMBINE_DEVICES
+schematic.combine_devices if COMBINE_DEVICES
+
+# PURGE
+netlist.purge if PURGE
+schematic.purge if PURGE
+
+# PURGE_NETS
+netlist.purge_nets if PURGE_NETS
+schematic.purge_nets if PURGE_NETS
+
+#=== IGNORE EXTREME VALUES ===
+max_res(1e9)
+min_caps(1e-18)
+
+# === COMPARISON ===
+logger.info('Starting SG13G2 LVS Comparison')
+compare
+
+#================================================
+#------------- COMPARISON RESULTS ---------------
+#================================================
+
+if !compare
+ logger.info('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
+ logger.error("ERROR : Netlists don't match")
+ logger.info('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
+else
+ logger.info('==========================================')
+ logger.info('INFO : Congratulations! Netlists match.')
+ logger.info('==========================================')
+end
+
+exec_end_time = Time.now
+run_time = exec_end_time - exec_start_time
+logger.info(format('LVS Total Run time %f seconds', run_time))
+ ]]>
+
+
diff --git a/ihp-sg13g2/libs.tech/klayout/tech/macros/sg13g2_density_report.lym b/ihp-sg13g2/libs.tech/klayout/tech/macros/sg13g2_density_report.lym
new file mode 100644
index 00000000..0cc144f4
--- /dev/null
+++ b/ihp-sg13g2/libs.tech/klayout/tech/macros/sg13g2_density_report.lym
@@ -0,0 +1,166 @@
+
+
+ Density Report
+ 0.1
+ misc
+
+
+
+ false
+ false
+ 0
+
+ true
+ Run Density Report
+ sg13g2_menu>end("SG13G2 PDK").end
+ dsl
+ drc-dsl-xml
+ # layer inputs
+
+###################### Layer assignment #######################
+
+# total area limited by prBoundary
+# HACK: use 235/4 since we currently have no prBoundary (189/0) drawn
+prBoundary = input("235/4")
+
+
+# Activ
+activ_draw = input("1/0")
+activ_fill = input("1/22")
+
+# GatPoly
+GatPoly_draw = input("5/0")
+GatPoly_fill = input("5/22")
+
+# metal1
+metal1_draw = input("8/0")
+metal1_fill = input("8/22")
+
+# metal2
+metal2_draw = input("10/0")
+metal2_fill = input("10/22")
+
+# metal3
+metal3_draw = input("30/0")
+metal3_fill = input("30/22")
+
+# metal4
+metal4_draw = input("50/0")
+metal4_fill = input("50/22")
+
+# metal5
+metal5_draw = input("67/0")
+metal5_fill = input("67/22")
+
+# TopMetal1
+TopMetal1_draw = input("126/0")
+TopMetal1_fill = input("126/22")
+
+# TopMetal2
+TopMetal2_draw = input("134/0")
+TopMetal2_fill = input("134/22")
+
+
+###################### area calculation ########################
+
+# total
+area_total = prBoundary.area.round(3)
+
+# Activ
+area_activ_fill = activ_fill.area.round(3)
+area_activ_draw = activ_draw.area.round(3)
+area_activ = area_activ_fill + area_activ_draw
+tf_activ = (area_activ/area_total*100.0).round(3)
+
+# GatPoly
+area_GatPoly_fill = GatPoly_fill.area.round(3)
+area_GatPoly_draw = GatPoly_draw.area.round(3)
+area_GatPoly = area_GatPoly_fill + area_GatPoly_draw
+tf_GatPoly = (area_GatPoly/area_total*100.0).round(3)
+
+# metal 1
+area_metal1_fill = metal1_fill.area.round(3)
+area_metal1_draw = metal1_draw.area.round(3)
+area_metal1 = area_metal1_fill + area_metal1_draw
+tf_metal1 = (area_metal1/area_total*100.0).round(3)
+
+# metal 2
+area_metal2_fill = metal2_fill.area.round(3)
+area_metal2_draw = metal2_draw.area.round(3)
+area_metal2 = area_metal2_fill + area_metal2_draw
+tf_metal2 = (area_metal2/area_total*100.0).round(3)
+
+# metal 3
+area_metal3_fill = metal3_fill.area.round(3)
+area_metal3_draw = metal3_draw.area.round(3)
+area_metal3 = area_metal3_fill + area_metal3_draw
+tf_metal3 = (area_metal3/area_total*100.0).round(3)
+
+# metal 4
+area_metal4_fill = metal4_fill.area.round(3)
+area_metal4_draw = metal4_draw.area.round(3)
+area_metal4 = area_metal4_fill + area_metal4_draw
+tf_metal4 = (area_metal4/area_total*100.0).round(3)
+
+# metal 5
+area_metal5_fill = metal5_fill.area.round(3)
+area_metal5_draw = metal5_draw.area.round(3)
+area_metal5 = area_metal5_fill + area_metal5_draw
+tf_metal5 = (area_metal5/area_total*100.0).round(3)
+
+# TopMetal 1
+area_TopMetal1_fill = TopMetal1_fill.area.round(3)
+area_TopMetal1_draw = TopMetal1_draw.area.round(3)
+area_TopMetal1 = area_TopMetal1_fill + area_TopMetal1_draw
+tf_TopMetal1 = (area_TopMetal1/area_total*100.0).round(3)
+
+# TopMetal 2
+area_TopMetal2_fill = TopMetal2_fill.area.round(3)
+area_TopMetal2_draw = TopMetal2_draw.area.round(3)
+area_TopMetal2 = area_TopMetal2_fill + area_TopMetal2_draw
+tf_TopMetal2 = (area_TopMetal2/area_total*100.0).round(3)
+
+
+# output
+puts "Layer areas and percetages"
+puts "------------------------------------------------\n\n"
+
+puts "Total Area = #{area_total}um^2\n\n"
+
+# Activ
+puts "Activ Area = #{area_activ}um^2"
+puts "Activ % = #{tf_activ}% Min = 35 Max = 55\n\n"
+
+# GatPoly
+puts "GatPoly Area = #{area_GatPoly}um^2"
+puts "GatPoly % = #{tf_GatPoly}% Min = 15\n\n"
+
+# metal 1
+puts "Metal1 Area = #{area_metal1}um^2"
+puts "Metal1 % = #{tf_metal1}% Min = 35 Max = 60\n\n"
+
+# metal 2
+puts "Metal2 Area = #{area_metal2}um^2"
+puts "Metal2 % = #{tf_metal2}% Min = 35 Max = 60\n\n"
+
+# metal 3
+puts "Metal3 Area = #{area_metal3}um^2"
+puts "Metal3 % = #{tf_metal3}% Min = 35 Max = 60\n\n"
+
+# metal 4
+puts "Metal4 Area = #{area_metal4}um^2"
+puts "Metal4 % = #{tf_metal4}% Min = 35 Max = 60\n\n"
+
+# metal 5
+puts "Metal5 Area = #{area_metal5}um^2"
+puts "Metal5 % = #{tf_metal5}% Min = 35 Max = 60\n\n"
+
+# TopMetal 1
+puts "TopMetal1 Area = #{area_TopMetal1}um^2"
+puts "TopMetal1 % = #{tf_TopMetal1}% Min = 25 Max = 70\n\n"
+
+# TopMetal 2
+puts "TopMetal2 Area = #{area_TopMetal2}um^2"
+puts "TopMetal2 % = #{tf_TopMetal2}% Min = 25 Max = 70\n\n"
+
+
diff --git a/ihp-sg13g2/libs.tech/klayout/tech/scripts/sealring.py b/ihp-sg13g2/libs.tech/klayout/tech/scripts/sealring.py
new file mode 100644
index 00000000..1dcf83da
--- /dev/null
+++ b/ihp-sg13g2/libs.tech/klayout/tech/scripts/sealring.py
@@ -0,0 +1,70 @@
+"""Module to automatically generate a sealring and create a new GDS file. Can be used in
+Klayout's batch mode. For example:
+
+klayout -n sg13g2 -zz -r sealring.py \
+ -rd width=1300.0 -rd height=1300.0 -rd output=macros/sealring.gds.gz
+
+"""
+# pylint: disable=import-error
+import pathlib
+import sys
+import re
+import pya
+import klayout.db
+
+LIB = 'SG13_dev'
+PCELL = 'sealring'
+
+def generate_sealring(width: float, heigth: float, output: str):
+ """Function to create a new layout, add the sealring PCell to sealring_top
+ and save it somewhere on the filesystem.
+
+ :param width: Width (X-Axis) of the sealring.
+ :type width: float
+ :param height: Heigth (Y-Axis) of the sealring.
+ :type heigth: float
+ :param output: Path and name of the file where the sealring should be written to.
+ :type output: str
+
+ """
+ layout = klayout.db.Layout(True)
+ layout.dbu = 0.001
+
+ lib = pya.Library.library_by_name(LIB)
+ pcell_decl = lib.layout().pcell_declaration(PCELL)
+
+ # Remove space around the sealring from width/height arguments.
+ params = pcell_decl.params_as_hash(pcell_decl.get_parameters())
+ edge_box = float(re.sub('[a-zA-Z]+', '', params['edgeBox'].default))
+ width = float(width) - edge_box * 2
+ heigth = float(heigth) - edge_box * 2
+
+ top_cell = layout.cell(layout.add_cell("sealring_top"))
+ pcell = layout.add_pcell_variant(lib, pcell_decl.id(), {'w': f'{width}u', 'l': f'{heigth}u'})
+ layout.cell(pcell)
+ top_cell.insert(klayout.db.CellInstArray(pcell, klayout.db.Trans()))
+
+ # Create directory where the sealring should be written to.
+ pathlib.Path(output).parent.mkdir(parents=True, exist_ok=True)
+
+ layout.write(output)
+
+try:
+ width
+except NameError:
+ print("Missing width argument. Please define '-rd width='")
+ sys.exit(1)
+
+try:
+ height
+except NameError:
+ print("Missing height argument. Please define '-rd height='")
+ sys.exit(1)
+
+try:
+ output
+except NameError:
+ print("Missing output argument. Please define '-rd output='")
+ sys.exit(1)
+
+generate_sealring(width, height, output) # pylint: disable=undefined-variable
diff --git a/ihp-sg13g2/libs.tech/klayout/tech/sg13g2.lyt b/ihp-sg13g2/libs.tech/klayout/tech/sg13g2.lyt
index dccddc67..488e57bf 100644
--- a/ihp-sg13g2/libs.tech/klayout/tech/sg13g2.lyt
+++ b/ihp-sg13g2/libs.tech/klayout/tech/sg13g2.lyt
@@ -20,6 +20,7 @@
sg13g2.lyp
true
+ 0.01,0.005!
1
@@ -82,8 +83,8 @@
true
default
false
-
- merged.lef
+ sg13g2.map
+
false
diff --git a/ihp-sg13g2/libs.tech/klayout/tech/sg13g2.map b/ihp-sg13g2/libs.tech/klayout/tech/sg13g2.map
new file mode 100644
index 00000000..26143741
--- /dev/null
+++ b/ihp-sg13g2/libs.tech/klayout/tech/sg13g2.map
@@ -0,0 +1,154 @@
+#************************************************************************#
+#************************************************************************#
+# File : sg13g2.map
+# DATE : September 28, 2022
+#*************************************************************************
+#*************************************************************************
+#
+# Copyright 2023 IHP PDK Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#*************************************************************************
+#-------------------------------------------------------------------------
+# EDI Stream layer mapping table for SG13
+# Version: 1.0
+# Date: 22 Aug 2023
+# Use only in combination with valid GDSII data of all used blocks!
+#-------------------------------------------------------------------------
+#EDI Layer Name EDI Layer Type GDS Layer Number GDS Layer Type
+#============== ============== ================ ==============
+
+Metal1 NET 8 0
+Metal1 SPNET 8 0
+Metal1 PIN 8 2
+Metal1 LEFPIN 8 2
+Metal1 FILL 8 22
+Metal1 LEFOBS 8 4
+Metal1 VIA 8 0
+
+#NAME Metal1/NET 20 0
+#NAME Metal1/SPNET 20 0
+NAME Metal1/PIN 8 25
+#NAME Metal1/LEFPIN 20 0
+
+Via1 PIN 19 0
+Via1 LEFPIN 19 0
+Via1 VIA 19 0
+
+Metal2 NET 10 0
+Metal2 SPNET 10 0
+Metal2 PIN 10 2
+Metal2 LEFPIN 10 2
+Metal2 FILL 10 22
+Metal2 VIA 10 0
+Metal2 LEFOBS 10 4
+
+#NAME Metal2/NET 21 0
+#NAME Metal2/SPNET 21 0
+NAME Metal2/PIN 10 25
+#NAME Metal2/LEFPIN 21 0
+
+Via2 PIN 29 0
+Via2 LEFPIN 29 0
+Via2 VIA 29 0
+
+
+Metal3 NET 30 0
+Metal3 SPNET 30 0
+Metal3 PIN 30 2
+Metal3 LEFPIN 30 2
+Metal3 FILL 30 22
+Metal3 VIA 30 0
+Metal3 LEFOBS 30 4
+
+#NAME Metal3/NET 22 0
+#NAME Metal3/SPNET 22 0
+NAME Metal3/PIN 30 25
+#NAME Metal3/LEFPIN 22 0
+
+Via3 PIN 49 0
+Via3 LEFPIN 49 0
+Via3 VIA 49 0
+
+
+Metal4 NET 50 0
+Metal4 SPNET 50 0
+Metal4 PIN 50 2
+Metal4 LEFPIN 50 2
+Metal4 FILL 50 22
+Metal4 VIA 50 0
+Metal4 LEFOBS 50 4
+
+#NAME Metal4/NET 23 0
+#NAME Metal4/SPNET 23 0
+NAME Metal4/PIN 50 25
+#NAME Metal4/LEFPIN 23 0
+
+Via4 PIN 66 0
+Via4 LEFPIN 66 0
+Via4 VIA 66 0
+
+
+Metal5 NET 67 0
+Metal5 SPNET 67 0
+Metal5 PIN 67 2
+Metal5 LEFPIN 67 2
+Metal5 FILL 67 22
+Metal5 VIA 67 0
+Metal5 LEFOBS 67 4
+
+#NAME Metal5/NET 70 0
+#NAME Metal5/SPNET 70 0
+NAME Metal5/PIN 67 25
+#NAME Metal5/LEFPIN 70 0
+
+TopVia1 PIN 125 0
+TopVia1 LEFPIN 125 0
+TopVia1 VIA 125 0
+
+TopMetal1 NET 126 0
+TopMetal1 SPNET 126 0
+TopMetal1 PIN 126 2
+TopMetal1 LEFPIN 126 2
+TopMetal1 FILL 126 22
+TopMetal1 VIA 126 0
+TopMetal1 LEFOBS 126 4
+
+#NAME TopMetal1/NET 130 0
+#NAME TopMetal1/SPNET 130 0
+NAME TopMetal1/PIN 126 25
+#NAME TopMetal1/LEFPIN 130 0
+
+TopVia2 PIN 133 0
+TopVia2 LEFPIN 133 0
+TopVia2 VIA 133 0
+
+TopMetal2 NET 134 0
+TopMetal2 SPNET 134 0
+TopMetal2 PIN 134 2
+TopMetal2 LEFPIN 134 2
+TopMetal2 FILL 134 22
+TopMetal2 VIA 134 0
+TopMetal2 LEFOBS 135 4
+
+#NAME TopMetal2/NET 137 0
+#NAME TopMetal2/SPNET 137 0
+NAME TopMetal2/PIN 134 25
+#NAME TopMetal2/LEFPIN 137 0
+
+NAME COMP 63 0
+
+COMP ALL 235 0
+
+DIEAREA ALL 235 4
diff --git a/ihp-sg13g2/libs.tech/pycell/cmim_code.py b/ihp-sg13g2/libs.tech/pycell/cmim_code.py
deleted file mode 100644
index fad3af8e..00000000
--- a/ihp-sg13g2/libs.tech/pycell/cmim_code.py
+++ /dev/null
@@ -1,112 +0,0 @@
-########################################################################
-#
-# Copyright 2023 IHP PDK Authors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-########################################################################
-__version__ = '$Revision: #3 $'
-
-from cni.dlo import *
-from utility_functions import *
-from geometry import *
-
-class cmim(DloGen):
-
- @classmethod
- def defineParamSpecs(self, specs):
- # define parameters and default values
- techparams = specs.tech.getTechParams()
-
- CDFVersion = techparams['CDFVersion']
- minLW = techparams['cmim_minLW']
- defLW = techparams['cmim_defLW']
- caspec = techparams['cmim_caspec']
- cmax = techparams['cmim_maxC']
- model = techparams['cmim_model']
-
- specs('cdf_version', CDFVersion, 'CDF Version')
- specs('Display', 'Selected', 'Display', ChoiceConstraint(['All', 'Selected']))
- specs('Calculate', 'w&l', 'Calculate', ChoiceConstraint(['C', 'w', 'l', 'w&l']))
- specs('model', model, 'Model name')
-
- C = CbCapCalc('C', 0, Numeric(defLW), Numeric(defLW), 'cmim')
- specs('C', eng_string(C), 'C')
-
- specs('w', defLW, 'Width')
- specs('l', defLW, 'Length')
-
- specs('Cspec', caspec, 'Cspec [F/sqm]')
- specs('Wmin', minLW, 'Wmin')
- specs('Lmin', minLW, 'Lmin')
- specs('Cmax', cmax, 'Cmax')
-
- specs('ic', '', 'Initial condition')
- specs('m', '1', 'Multiplier')
- specs('trise', '', 'Temp rise from ambient')
-
- def setupParams(self, params):
- # process parameter values entered by user
- self.w = eng_string_to_float(params['w'])*1e6
- self.l = eng_string_to_float(params['l'])*1e6
-
- def genLayout(self):
- self.grid = self.tech.getGridResolution()
- self.techparams = self.tech.getTechParams()
- self.epsilon = self.techparams['epsilon1']
-
- self.generateVias()
-
- # generate rectangle layout
- x1 = self.techparams['Mim_d']-self.techparams['TV1_d']+self.xoffset
- x2 = self.xcont_cnt
- y1 = self.techparams['Mim_d']-self.techparams['TV1_d']+self.yoffset
- y2 = self.ycont_cnt
- caplayerBBox = Box(0, 0, self.w, self.l)
- topMetalBBox = Box(x1, y1, x2, y2)
- bottomMetalBBox = Box(-self.techparams['Mim_c'], -self.techparams['Mim_c'], self.w + self.techparams['Mim_c'], self.l + self.techparams['Mim_c'])
-
- Rect(Layer('MIM'), caplayerBBox)
- self.bottomMetal = Rect(Layer('Metal5'), bottomMetalBBox)
- self.topMetal= Rect(Layer('TopMetal1'), topMetalBBox)
-
- self.createPins()
-
- def createPins(self):
- self.addPin('PLUS', 'PLUS', self.topMetal.getBBox(), Layer('TopMetal1','pin'))
- self.addPin('MINUS', 'MINUS', self.bottomMetal.getBBox(), Layer('Metal5','pin'))
-
- def generateVias(self):
- cont_over = self.techparams['Mim_d']
- cont_dist = 0.84
- cont_size = self.techparams['TV1_a']
-
- xanz=((self.w-cont_over-cont_over+cont_dist)//(cont_size+cont_dist)+self.epsilon)
- w1 = xanz*(cont_size+cont_dist)-cont_dist+cont_over+cont_over
- self.xoffset=GridFix((self.w-w1)/2)
-
- yanz = ((self.l-cont_over-cont_over+cont_dist)//(cont_size+cont_dist)+self.epsilon)
- l1=yanz*(cont_size+cont_dist)-cont_dist+cont_over+cont_over
- self.yoffset=GridFix((self.l-l1)/2)
-
- ycont_cnt=cont_over+self.yoffset
- while ycont_cnt+cont_size+cont_over <= self.l+self.epsilon:
- xcont_cnt=cont_over+self.xoffset
- while xcont_cnt+cont_size+cont_over <= self.w+self.epsilon:
- via = Box(xcont_cnt, ycont_cnt, xcont_cnt+cont_size, ycont_cnt+cont_size)
- Rect(Layer('Vmim'), via)
- xcont_cnt=xcont_cnt+cont_size+cont_dist
-
- ycont_cnt=ycont_cnt+cont_size+cont_dist
- self.xcont_cnt=xcont_cnt+self.techparams['TV1_d']-cont_dist
- self.ycont_cnt=ycont_cnt+self.techparams['TV1_d']-cont_dist
diff --git a/ihp-sg13g2/libs.tech/pycell/geometry.py b/ihp-sg13g2/libs.tech/pycell/geometry.py
deleted file mode 100644
index e5217e12..00000000
--- a/ihp-sg13g2/libs.tech/pycell/geometry.py
+++ /dev/null
@@ -1,1691 +0,0 @@
-########################################################################
-#
-# Copyright 2023 IHP PDK Authors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-########################################################################
-
-
-__version__ = "$Revision: #3 $"
-
-from cni.dlo import *
-from cni.geo import fgOr
-from cni.geo import fgAnd
-from cni.geo import fgXor
-from cni.geo import fgNot
-from cni.geo import fgMerge
-from utility_functions import *
-from math import *
-
-#***********************************************************************************************************************
-# nth
-#***********************************************************************************************************************
-def nth(index, mlist):
- if type(mlist) is Box:
- if index == 0 :
- lw = mlist.lowerLeft()
- x1 = lw.getX();
- return x1
- elif index == 1:
- lw = mlist.lowerLeft()
- y1 = lw.getY();
- return y1
- elif index == 2:
- ur = mlist.upperRight()
- x2 = ur.getX();
- return x2
- elif index == 3:
- ur = mlist.upperRight()
- y2 = ur.getY();
- return y2
-
- return mlist[index]
-
-#***********************************************************************************************************************
-# dbDeleteObject
-#***********************************************************************************************************************
-def dbDeleteObject(obj):
- obj.destroy()
-
-#***********************************************************************************************************************
-# dbLayerOr
-#***********************************************************************************************************************
-def dbLayerOr(layerId, id1, id2 = None):
- if type(layerId) == str :
- layerId = Layer(layerId)
-
- if id2 == None :
- id2 = id1
-
- idOr = id1.fgOr(id2, layerId)
-
- return idOr
-
-#***********************************************************************************************************************
-# dbLayerOrList
-#***********************************************************************************************************************
-def dbLayerOrList(layerId, shapes):
- if type(layerId) == str :
- layerId = Layer(layerId)
-
- id1 = shapes[0]
- for index in range(1, listlen(shapes)) :
- id2 = nth(index, shapes)
- idOr = dbLayerOr(layerId, id1, id2)
- if index > 0 :
- dbDeleteObject(id1)
- id1 = idOr
-
- return idOr
-
-#***********************************************************************************************************************
-# dbLayerAnd
-#***********************************************************************************************************************
-def dbLayerAnd(layerId, id1, id2):
- if type(layerId) == str :
- layerId = Layer(layerId)
-
- idAnd = id1.fgAnd(id2, layerId)
-
- return idAnd
-
-#***********************************************************************************************************************
-# dbLayerAndList
-#***********************************************************************************************************************
-def dbLayerAndList(layerId, shapes):
- if type(layerId) == str :
- layerId = Layer(layerId)
-
- idAnd = shapes[0]
- for id in shapes[1:] :
- idAnd = fgAnd(idAnd, id, layerId)
-
- return idAnd
-
-#***********************************************************************************************************************
-# dbLayerXor
-#***********************************************************************************************************************
-def dbLayerXor(layerId, id1, id2):
- if type(layerId) == str :
- layerId = Layer(layerId)
-
- xorId = id1.fgXor(id2, layerId)
-
- return xorId
-
-#***********************************************************************************************************************
-# dbLayerXorList
-#***********************************************************************************************************************
-def dbLayerXorList(layerId, shapes):
- if type(layerId) == str :
- layerId = Layer(layerId)
-
- xorId = shapes[0]
- for id in shapes[1:] :
- xorId = fgXor(xorId, id, layerId)
-
- return xorId
-
-#***********************************************************************************************************************
-# dbLayerNot
-#***********************************************************************************************************************
-def dbLayerNot(layerId, id1, id2):
- if type(layerId) == str :
- layerId = Layer(layerId)
-
- notId = id1.fgNot(id2, layerId)
-
- return notId
-
-#***********************************************************************************************************************
-# dbLayerNotList
-#***********************************************************************************************************************
-def dbLayerNotList(layerId, shapes):
- if type(layerId) == str :
- layerId = Layer(layerId)
-
- notId = shapes[0]
- for id in shapes[1:] :
- notId = fgNot(notId, id, layerId)
-
- return notId
-
-#***********************************************************************************************************************
-# dbLayerMerge
-#***********************************************************************************************************************
-def dbLayerMerge(self, layerId):
- if type(layerId) == str :
- layerId = Layer(layerId)
-
- shapes = self.getLeafComps()
- mergeId = shapes[0].fgMerge(layerId)
-
- return mergeId
-
-#***********************************************************************************************************************
-# dbCopyShape
-#***********************************************************************************************************************
-def dbLayerSize(self, layerId, shapes, size, numPoints, grid = 0) :
- for id in shapes :
- id.fgSize(ShapeFilter(), size, layerId, grid)
-
-#***********************************************************************************************************************
-# dbCopyShape
-#***********************************************************************************************************************
-def dbCopyShape(fig, pnt, rot):
- copyId = fig.clone()
-
- dbMoveFig(copyId, pnt, rot)
-
- return copyId
-
-#***********************************************************************************************************************
-# dbMoveFig
-#***********************************************************************************************************************
-def dbMoveFig(fig, pnt, rot) :
- if rot :
- fig.transform(Transform(0, 0, strToOrient(rot)))
-
- if pnt :
- fig.moveBy(pnt.x, pnt.y)
-
-#***********************************************************************************************************************
-# dbLayerInside
-# layer - new layer for cloned shape
-#***********************************************************************************************************************
-def dbLayerInside(self, layer, idlist, id):
-
- if type(layer) == str :
- layer = Layer(layer)
-
- pnts = id.getPoints()
-
- mlist = list()
- for item in idlist :
- if type(item) == Rect :
- if pnts.containsPoint(Point(item.left, item.bottom)) and pnts.containsPoint(Point(item.left, item.top)) and pnts.containsPoint(Point(item.right, item.bottom)) and pnts.containsPoint(Point(item.right, item.top)) :
- it = item.clone()
- it.layer = layer
- mlist.append(it)
- else :
- pnts1 = item.getPoints()
- yes = False
- for pnt in pnts1 :
- if pnts.containsPoint(pnt) :
- yes = True
- else :
- yes = False
- break
-
- if yes :
- it = item.clone()
- it.layer = layer
- mlist.append(it)
-
- #idOr = id.fgOr(item, layer)
- #if len(idOr.getComps()) == 1 :
- # shape = idOr.getComp(0)
- # if shape.getNumPoints() == 3 :
- # mlist.append(item.clone())
- #
- #idOr.destroy()
-
- return mlist
-
-#***********************************************************************************************************************
-# dbLayerOutside
-#***********************************************************************************************************************
-def dbLayerOutside(self, layer, idlist, id):
- if type(layer) == str :
- layer = Layer(layer)
-
- if type(id) == Rect :
- pnts = PointList([Point(id.left, id.bottom), Point(id.left, id.top), Point(id.right, id.bottom), Point(id.right, id.top)])
- else :
- pnts = id.getPoints()
-
- mlist = list()
- for item in idlist :
- if type(item) == Rect :
- if pnts.containsPoint(Point(item.left, item.bottom)) and pnts.containsPoint(Point(item.left, item.top)) and pnts.containsPoint(Point(item.right, item.bottom)) and pnts.containsPoint(Point(item.right, item.top)) :
- pass
- else :
- mlist.append(item.clone())
- else :
- pnts1 = item.getPoints()
- yes = False
- for pnt in pnts1 :
- if pnts.containsPoint(pnt) :
- yes = False
- break
- else :
- yes = True
-
- if yes :
- it = item.clone()
- it.layer = layer
- mlist.append(it)
-
- return mlist
-
-#***********************************************************************************************************************
-# dbCreateRect
-#***********************************************************************************************************************
-def dbCreateRect(self, layerId, bBox):
- if type(layerId) == str :
- layerId = Layer(layerId)
-
- rectId = Rect(layerId, bBox)
- return rectId
-
-#***********************************************************************************************************************
-# dbCreatePolygon
-#***********************************************************************************************************************
-def dbCreatePolygon(self, layerId, pointList):
- if type(layerId) is str :
- layerId = Layer(layerId)
-
- if type(pointList) is list :
- points = PointList()
-
- pointIndex = 0
- pointValue = 0
- for p in pointList :
- if pointIndex == 0 :
- pointValue = p
- elif pointIndex == 1 :
- point = Point(pointValue, p)
- points.append(point)
- pointIndex = -1
-
- pointIndex = pointIndex + 1
-
- pointList = points.compress()
- else :
- pointList = pointList.compress()
-
- polyId = Polygon(layerId, pointList)
- return polyId
-
-#***********************************************************************************************************************
-# dbCreatePath
-#***********************************************************************************************************************
-def dbCreatePath(self, layerId, pointList, width, style=PathStyle.TRUNCATE):
- if type(layerId) == str :
- layerId = Layer(layerId)
-
- pointList = pointList.compress()
-
- pathId = Path(layerId, width, pointList, style)
- return pathId
-
-#***********************************************************************************************************************
-# dbCreateDonut
-#***********************************************************************************************************************
-def dbCreateDonut(self, layerId, pnt, outRad, inRad):
- if type(layerId) == str :
- layerId = Layer(layerId)
-
- donutId = Donut(layerId, pnt, outRad, inRad)
- return donutId
-
-#***********************************************************************************************************************
-# dbCreateEllipse
-#***********************************************************************************************************************
-def dbCreateEllipse(self, layerId, bbox):
- if type(layerId) == str :
- layerId = Layer(layerId)
-
- ellipseId = Ellipse(layerId, bbox)
-
- return ellipseId
-
-#***********************************************************************************************************************
-# dbConvertEllipseToPolygon
-#***********************************************************************************************************************
-def dbConvertEllipseToPolygon(self, ellipse, numPoints, grid):
- points = Ellipse.genPolygonPoints(ellipse.getBBox(), numPoints, grid)
- polyId = dbCreatePolygon(self, ellipse.layer, points)
-
- return polyId
-
-#***********************************************************************************************************************
-# dbCreateLabel
-#***********************************************************************************************************************
-def dbCreateLabel(self, layerId, point, text, align, rotation, font, size):
- text = Text(layerId, text, point, size)
-
- text.setAlignment(strToAlignt(align))
- text.setOrientation(strToOrient(rotation))
-
- """
- rect = text.getBBox()
- lw = rect.lowerLeft()
- ur = rect.upperRight()
-
- x1 = lw.getX()
- x2 = ur.getX()
- y1 = lw.getY()
- y2 = ur.getY()
-
- if y1 > y2:
- temp = y1
- y1 = y2
- y2 = temp
-
- if x1 > x2:
- temp = x1
- x1 = x2
- x2 = temp
-
- shiftX = (x2-x1)/2
- shiftY = (y2-y1)/2
- text.setFont(font)
- text.setAlignment(align)
-
- if rotation is "R0":
- text.setOrientation(Orientation.R0)
- text.setOrigin(Point(x1-shiftX, y2+shiftY))
- elif rotation is "R90":
- text.setOrigin(Point(x1-shiftY, y2-shiftX))
- text.setOrientation(Orientation.R90)
- """
- return text
-
-#***********************************************************************************************************************
-# dbCreateNet
-#***********************************************************************************************************************
-def dbCreateNet(name, typ=SignalType.SIGNAL):
- net = Net.find(name)
- if not net :
- net = Net(name, typ)
-
- return net
-
-#***********************************************************************************************************************
-# dbCreateTerm
-#***********************************************************************************************************************
-def dbCreateTerm(self, name, typ=TermType.INPUT_OUTPUT):
- term = Term.find(name)
- if not term :
- term = self.addTerm(name, typ)
-
- return term
-
-#***********************************************************************************************************************
-# dbCreatePin
-#***********************************************************************************************************************
-def dbCreatePin(self, name, shape):
- pin = self.addPin(name, name, shape.getBBox(shape.layer), shape.layer)
- if not (shape.getNet() or shape.getPin()) :
- pin.addShape(shape)
-
- return pin
-
-#***********************************************************************************************************************
-# MkPin
-#***********************************************************************************************************************
-def MkPin(self, termName, termIndex, bBox, layerId, label=False, labelHight = -1):
- if type(layerId) == str :
- layerId = Layer(layerId, 'pin')
-
- bBox = bBox.fix()
-
- self.addPin(termName, termName, bBox, layerId)
-
- pcInst = dbCreateRect(self, layerId, bBox) # 17.6.11 GG
-
- # pin label
- if label and termName :
- if labelHight == -1 :
- pcLabelHeight = 0.5*min(bBox.getWidth(), abs(bBox.getHeight()))
- else :
- pcLabelHeight = labelHight
- dbCreateLabel(self, layerId, bBox.getCenter(), termName, 'centerCenter', 'R0', Font.EURO_STYLE, pcLabelHeight)
-
-#***********************************************************************************************************************
-# dbCreateVia
-#***********************************************************************************************************************
-def dbCreateVia(self, ViaDef, pnt, rot, params):
- via = StdVia(ViaDef.getName())
-
- via.setOrientation(strToOrient(rot))
- via.setOrigin(pnt)
-
- vp = via.getParams()
- if 'cutLayer' in params :
- cutLayer = params['cutLayer']
- else :
- cutLayer = vp.cutLayer
- if 'cutSize' in params :
- cutSize = params['cutSize']
- else :
- cutSize = vp.cutSize
- if 'cutSpace' in params :
- cutSpace = params['cutSpace']
- else :
- cutSpace = vp.cutSpace
- if 'implant1Ext' in params :
- implant1Ext = params['implant1Ext']
- else :
- implant1Ext = vp.implant1Ext
- if 'implant2Ext' in params :
- implant2Ext = params['implant2Ext']
- else :
- implant2Ext = vp.implant2Ext
- if 'layer1Ext' in params :
- layer1Ext = params['layer1Ext']
- else :
- layer1Ext = vp.layer1Ext
- if 'layer1Offset' in params :
- layer1Offset = params['layer1Offset']
- else :
- layer1Offset = vp.layer1Offset
- if 'layer2Ext' in params :
- layer2Ext = params['layer2Ext']
- else :
- layer2Ext = vp.layer2Ext
- if 'layer2Offset' in params :
- layer2Offset = params['layer2Offset']
- else :
- layer2Offset = vp.layer2Offset
- if 'numHVCuts' in params :
- numHVCuts = params['numHVCuts']
- else :
- numHVCuts = vp.numHVCuts
- if 'originOffset' in params :
- originOffset = params['originOffset']
- else :
- originOffset = vp.originOffset
-
- vp = ViaParam(vp,
- layer1Ext,
- layer2Ext,
- implant1Ext,
- implant2Ext,
- layer1Offset,
- layer2Offset,
- originOffset,
- cutSpace,
- cutSize,
- cutLayer,
- numHVCuts)
-
- via.setParams(vp)
-
- return via
-
-#***********************************************************************************************************************
-# DrawRing
-#***********************************************************************************************************************
-def DrawRing(self, layer, rl, rr, rb, rt, rw, rh) :
- dbCreatePolygon(self, layer, PointList([Point(rl,rb), Point(rr,rb),
- Point(rr,rt), Point(rl,rt),
- Point(rl,rb+rh), Point(rl+rw,rb+rh),
- Point(rl+rw,rt-rh), Point(rr-rw,rt-rh),
- Point(rr-rw,rb+rh), Point(rl,rb+rh)]))
-
-#***********************************************************************************************************************
-# ihpBuildCont
-#***********************************************************************************************************************
-def ihpBuildCont(self, layer1, layer2, layer3, width1, width3, length3, pathpnts, terminal, pinlabel,
- layer2_enc, offset, chop, layer3_space) :
-
- # pinlabel is a boolean that determines whether a label will be created
- # terminal is the pin name string
-
- bBox = Box(pathpnts.left-(width1/2), pathpnts.bottom, pathpnts.right+(width1/2), pathpnts.top)
-
- if terminal :
- do_pins = True
- else :
- do_pins = False
-
-
- # paths in layers 1&2 with subrectanges in layer3 and label in layer2
- if (layer3 and layer2 and layer1 and (layer1 != layer2)) :
- fig = dbCreateRect(self, layer2, bBox)
- pin_fig = dbCreateRect(self, layer2, Box(bBox.left+layer2_enc, bBox.bottom+layer2_enc, bBox.right-layer2_enc, bBox.top-layer2_enc))
-
- contactArray(self, layer2, layer3,
- bBox.left, bBox.bottom, bBox.right, bBox.top,
- layer2_enc, offset, width3, layer3_space)
-
- else : # paths in layers 1&2 with no subrectanges and label in layer2
- if ( (not layer3) and layer2 and layer1 and (layer1 != layer2) ) :
- fig = dbCreateRect(self, layer1, bBox)
- pin_fig = dbCreateRect(self, layer2, Box(bBox.left+layer2_enc, bBox.bottom+layer2_enc, bBox.right-layer2_enc, bBox.top-layer2_enc))
-
- else : # path in layer2 and rectangles in layer3 (one layer path and subrectangles)
- if( (not layer1) and (layer3 != layer2) ) :
- fig = dbCreateRect(self, layer2, bBox)
- pin_fig = fig
- contactArray(self, layer2, layer3,
- bBox.left, bBox.bottom, bBox.right, bBox.top,
- layer2_enc, offset, width3, layer3_space)
-
- else : # paths in layer 1 (one layer path)
- if layer1 != layer2 :
- fig = dbCreateRect(self, layer1, bBox)
- pin_fig = fig
-
- return [pin_fig, fig]
-
-#***********************************************************************************************************************
-# buildCont
-#***********************************************************************************************************************
-def buildCont(self, layer1, layer2, layer3, width1, width3, length3, pathpnts, terminal, pinlabel, layer2_enc, offset, chop, layer3_space) :
- # pinlabel is a boolean that determines whether a label will be created
- # terminal is the pin name string
-
- if terminal :
- do_pins = True
- else :
- do_pins = False
-
- if pathpnts[0].x > pathpnts[1].x :
- x = pathpnts[0].x
- pathpnts[0].x = pathpnts[1].x
- pathpnts[1].x = x
- if pathpnts[0].y > pathpnts[1].y :
- y = pathpnts[0].y
- pathpnts[0].y = pathpnts[1].y
- pathpnts[1].y = y
-
- if pathpnts[0].x == pathpnts[1].x :
- pathl = abs(pathpnts[0].y - pathpnts[1].y)
- hor = False
- elif pathpnts[0].y == pathpnts[1].y :
- pathl = abs(pathpnts[0].x - pathpnts[1].x)
- hor = True
- else :
- print 'Warning: Incline path is not allowed for buildCont procedure'
- return
-
- count = pathl/(length3+layer3_space+offset)
- if count - int(count) > 0.5 :
- count = int(count) + 1
- start = 0
- if pinlabel :
- start = 1
-
- # paths in layers 1&2 with subrectanges in layer3 and label in layer2
- if layer3 and layer2 and layer1 and (layer1 != layer2) :
- # rodCreatePath
- fig = dbCreatePath(self, layer1, pathpnts, width1)
- if pinlabel :
- if hor :
- MkPin(self, terminal, 0, Box((pathpnts[0].x+offset), pathpnts[0].y-width3/2, (pathpnts[0].x+offset)+width3, pathpnts[0].y+width3/2), layer2, pinlabel, layer2, length3)
- else :
- MkPin(self, terminal, 0, Box(pathpnts[0].x-width3/2, (pathpnts[0].y+offset), pathpnts[0].x+width3/2, (pathpnts[0].y+offset)+length3), layer2, pinlabel, layer2, length3)
-
- # subRect
- box = fig.getBBox()
- if hor :
- box.expandDir(Direction.WEST, -offset)
- box.expandDir(Direction.EAST, -offset)
- else :
- box.expandDir(Direction.NORTH, -offset)
- box.expandDir(Direction.SOUTH, -offset)
- Rect.fillBBoxWithRects(layer3, box, width3, length3, layer3_space, layer3_space, GapStyle.DISTRIBUTE)
-
- # rodCreateRect
- pin_fig = list()
- if do_pins :
- pin = MkPin(self, terminal, 0, fig.bbox.expand(-layer2_enc), layer1)
- else :
- pin = dbCreateRect(self, layer1, fig.bbox.expand(-layer2_enc))
- pin_fig.append(pin)
-
- #rodAlign(?alignObj, pin_fig, ?alignHandle, "centerCenter", ?refObj, fig, ?refHandle, "centerCenter")
- else : # paths in layers 1&2 with no subrectanges and label in layer2
- if not layer3 and layer2 and layer1 and (layer1 != layer2) :
- # rodCreatePath
- fig = dbCreatePath(self, layer1, pathpnts, width1)
- if pinlabel :
- if hor :
- MkPin(self, terminal, 0, Box((pathpnts[0].x+offset), pathpnts[0].y-width3/2, (pathpnts[0].x+offset)+width3, pathpnts[0].y+width3/2), layer2, pinlabel, layer2, length3, 'R0', 'centerLeft', Font.ROMAN)
- else :
- MkPin(self, terminal, 0, Box(pathpnts[0].x-width3/2, (pathpnts[0].y+offset), pathpnts[0].x+width3/2, (pathpnts[0].y+offset)+length3), layer2, pinlabel, layer2, length3, 'R0', 'centerLeft', Font.ROMAN)
-
- # encSubPath
- dbCreatePath(self, layer2, pathpnts, width1-(2*layer2_enc))
-
- # rodCreateRect
- pin_fig = list()
- if do_pins :
- pin = MkPin(self, terminal, 0, fig.bbox, layer1)
- else :
- pin = dbCreateRect(self, layer1, fig.bbox)
- pin_fig.append(pin)
-
- #rodAlign(?alignObj, pin_fig, ?alignHandle, "centerCenter", ?refObj, fig, ?refHandle, "centerCenter")
- else : # path in layer2 and rectangles in layer3 (one layer path and subrectangles)
- if not layer1 and layer3 != layer2 :
- # rodCreatePath
- fig = dbCreatePath(self, layer2, pathpnts, width1)
- if pinlabel :
- if hor :
- MkPin(self, terminal, 0, Box((pathpnts[0].x+offset), pathpnts[0].y-width3/2, (pathpnts[0].x+offset)+width3, pathpnts[0].y+width3/2), layer2)
- else :
- MkPin(self, terminal, 0, Box(pathpnts[0].x-width3/2, (pathpnts[0].y+offset), pathpnts[0].x+width3/2, (pathpnts[0].y+offset)+length3), layer2)
-
- # subRect
- box = fig.getBBox()
- if hor :
- box.expandDir(Direction.WEST, -offset)
- box.expandDir(Direction.EAST, -offset)
- else :
- box.expandDir(Direction.NORTH, -offset)
- box.expandDir(Direction.SOUTH, -offset)
- Rect.fillBBoxWithRects(layer3, box, width3, length3, layer3_space, layer3_space, GapStyle.DISTRIBUTE)
-
- # rodCreateRect
- pin_fig = list()
- if do_pins :
- pin = MkPin(self, terminal, 0, fig.bbox, layer2)
- else :
- pin = dbCreateRect(self, layer2, fig.bbox)
- pin_fig.append(pin)
-
- #rodAlign(?alignObj, pin_fig, ?alignHandle, "centerCenter", ?refObj, fig, ?refHandle, "centerCenter")
- else : # paths in layer 1 (one layer path)
- if layer1 != layer2 :
- # rodCreatePath
- fig = dbCreatePath(self, layer1, pathpnts, width1)
- if pinlabel :
- if hor :
- MkPin(self, terminal, 0, Box((pathpnts[0].x+offset), pathpnts[0].y-width3/2, (pathpnts[0].x+offset)+width3, pathpnts[0].y+width3/2), layer1)
- else :
- MkPin(self, terminal, 0, Box(pathpnts[0].x-width3/2, (pathpnts[0].y+offset), pathpnts[0].x+width3/2, (pathpnts[0].y+offset)+length3), layer1)
-
- # rodCreateRect
- pin_fig = list()
- if do_pins :
- pin = MkPin(self, terminal, 0, fig.bbox, layer1)
- else :
- pin = dbCreateRect(self, layer1, fig.bbox)
- pin_fig.append(pin)
-
- #rodAlign(?alignObj, pin_fig, ?alignHandle, "centerCenter", ?refObj, fig, ?refHandle, "centerCenter")
-
- return [pin_fig, fig]
-
-#***********************************************************************************************************************
-# MetalCont
-#***********************************************************************************************************************
-def MetalCont(self, p1_x, p1_y, p2_x, p2_y, _layer2, _layer3, _width1, _width3, _length3, _offset, _layer3_space) :
- pathLayer = _layer2
- width = _width1
- subRectLayer = _layer3
- srect_w = _width3
- srect_l = _length3
- srect_o = _offset
- srect_space = _layer3_space
- boxRectLayer = _layer2
- boxRectDelta = 0.0
-
- mlist = ulist[Rect]()
- __w2 = width/2
- if p1_x == p2_x :
- x_left = p1_x-__w2
- x_right = p1_x+__w2
- if p1_y < p2_y :
- y_bot = p1_y
- y_top = p2_y
- else :
- y_bot = p2_y
- y_top = p1_y
-
- _sw2 = srect_w/2
- _yl = p1_x-_sw2
- _xr = p1_x+_sw2
- _yges = y_top-y_bot-2*srect_o
- _nrect = floor((_yges+srect_space)/(srect_l+srect_space))
-
- if _nrect > 1 : # calculate new space and do a loop
- _rsp = (_yges-_nrect*srect_l)/(_nrect-1)
- _yy = y_bot+srect_o
- while _yy+srect_l <= y_top-srect_o+0.0001 :
- id = dbCreateRect(self, subRectLayer, Box(tog(_yl), tog(_yy), tog(_xr), tog(_yy+srect_l)))
- mlist.append(id )
- _yy = _yy+srect_l+_rsp
-
- else :
- if _nrect == 1 : # center a single rect
- _ymb = (y_top+y_bot-srect_l)/2
- id = dbCreateRect(self, subRectLayer, Box(tog(_yl), tog(_ymb), tog(_xr), tog(_ymb+srect_l)))
- mlist.append(id)
-
- else :
- if p1_y == p2_y :
- y_bot = p1_y-__w2
- y_top = p1_y+__w2
- if p1_x < p2_x :
- x_left = p1_x
- x_right = p2_x
- else :
- x_left = p2_x
- x_right = p1_x
-
- _sw2 = srect_w/2
- _yb = p1_y-_sw2
- _yt = p1_y+_sw2
- _xges = x_right-x_left-2*srect_o
- _nrect = floor((_xges+srect_space)/(srect_l+srect_space))
-
- if _nrect > 1 : # calculate new space and do a loop
- _rsp = (_xges-_nrect*srect_l)/(_nrect-1)
- _xx = x_left+srect_o
- while _xx+srect_l <= x_right-srect_o+0.0001 :
- id = dbCreateRect(self, subRectLayer, Box(tog(_xx), tog(_yb), tog(_xx+srect_l), tog(_yt)))
- mlist.append(id)
- _xx = _xx+srect_l+_rsp
-
- else :
- if _nrect == 1 : # center a single rect
- _xml = (x_left+x_right-srect_l)/2
- id = dbCreateRect(self, subRectLayer, Box(tog(_xml), tog(_yb), tog(_xml+srect_l), tog(_yt)))
- mlist.append(id)
-
- else :
- return mlist
-
- if pathLayer != "" :
- id = dbCreateRect(self, pathLayer, Box(tog(x_left), tog(y_bot), tog(x_right), tog(y_top)))
- mlist.append(id)
-
- return mlist
-
-#***********************************************************************************************************************
-# DrawContArray
-#***********************************************************************************************************************
-def DrawContArray(self, layer, bbox, size, space, over):
- epsilon = self.techparams['epsilon1']
-
- bbox = bbox.fix()
-
- x1 = bbox.left
- x2 = bbox.right
- y1 = bbox.bottom
- y2 = bbox.top
-
- xanz = fix((x2-x1-2*over+space+epsilon)/(size+space))
- yanz = fix((y2-y1-2*over+space+epsilon)/(size+space))
-
- name = self.tech.name().split()[0]
- if name == 'SG13_dev' :
- cont_layer = 'Cont'
- cont_dist_big = self.techparams['Cnt_b1']
- cont_dist_big_nr = self.techparams['Cnt_b1_nr']
-
- # now check, if it is cont and more than 4 rows/lines
- if layer.name==cont_layer and xanz>=cont_dist_big_nr and yanz>=cont_dist_big_nr :
- # it has to be bigger space between contacts
- space = cont_dist_big
- # it has to be bigger space between contacts
- xanz = fix((x2-x1-2*over+space+epsilon)/(size+space))
- yanz = fix((y2-y1-2*over+space+epsilon)/(size+space))
-
- xmin = xanz*(size+space)-space+2*over
- ymin = yanz*(size+space)-space+2*over
- xoff = (x2-x1-xmin)/2
- xoff = GridFix(xoff)
- yoff = (y2-y1-ymin)/2
- yoff = GridFix(yoff)
-
- for j in range(int(yanz)):
- for i in range(int(xanz)):
- dbCreateRect(self, layer, Box(x1+xoff+over+(size+space)*i, y1+yoff+over+(size+space)*j,
- x1+xoff+over+(size+space)*i+size, y1+yoff+over+(size+space)*j+size))
-
- return Box(x1+xoff+over, y1+yoff+over,
- x1+xoff+over+xanz*size+(xanz-1)*space,
- y1+yoff+over+yanz*size+(yanz-1)*space)
-
-#***********************************************************************************************************************
-# contactArray
-#***********************************************************************************************************************
-def contactArray(self, pathLayer, contLayer, xl, yl, xh, yh, ox, oy, ws, ds):
- eps = self.tech.getTechParams()['epsilon1']
-
- w = xh-xl
- h = yh-yl
-
- mlist = list()
-
- nx = floor((w-ox*2+ds)/(ws+ds)+eps)
- if (nx <= 0) :
- return mlist
-
- dsx = 0
- if (nx == 1) :
- dsx = 0
- else :
- dsx = (w-ox*2-ws*nx)/(nx-1)
-
- ny = floor((h-oy*2+ds)/(ws+ds)+eps)
- if (ny <= 0) :
- return mlist
-
- dsy = 0
- if (ny == 1) :
- dsy = 0
- else :
- dsy = (h-oy*2-ws*ny)/(ny-1)
-
- x = 0
- if (nx == 1) :
- x = (w-ws)/2
- else :
- x = ox
-
- if pathLayer :
- mlist.append(dbCreateRect(self, pathLayer, Box(xl, yl, xh, yh)))
-
- for i in range(int(nx)) :
- #for(i=1; i<=nx; i++) {
- y = 0
- if ny == 1 :
- y = (h-ws)/2
- else :
- y = oy
-
- for j in range(int(ny)) :
- #for(j=1; j<=ny; j++) {
- mlist.append(dbCreateRect(self, contLayer, Box(xl+tog(x), yl+tog(y), xl+tog(x+ws), yl+tog(y+ws))))
- y = y+ws+dsy
-
- x = x+ws+dsx
-
- if pathLayer :
- mlist.append(dbCreateRect(self, pathLayer, Box(xl, yl, xh, yh)))
-
- return mlist
-
-
-#***********************************************************************************************************************
-# DrawContRowMid
-#***********************************************************************************************************************
-def DrawContRowMid(self, layer, x0, y0, x1, y1, size, space, drawMid, GRID, EPSILON):
- IGRID = 1/GRID
-
- dx = 0.0
- dy = 0.0
- xShift = 0.0
- yShift = 0.0
-
- x0 = int(x0*IGRID+EPSILON)*GRID
- x1 = int(x1*IGRID+EPSILON)*GRID
- y0 = int(y0*IGRID+EPSILON)*GRID
- y1 = int(y1*IGRID+EPSILON)*GRID
-
- if (x1-x0 > 0.0):
- dx = size+space
-
- if (x1-x0 < 0.0):
- dx = -(size+space)
-
- if (y1-y0 > 0.0):
- dy = size+space
-
- if (y1-y0 < 0.0):
- dy = -(size+space)
-
- if (nonzero(dx) and nonzero(dy)):
- delta = int(space*(1.0-1.0/math.sqrt(2.0)-0.01)*IGRID-EPSILON)*GRID
- if (dx > 0.0):
- dx = dx-delta
- else:
- dx = dx+delta
-
- if (dy > 0.0):
- dy = dy-delta
- else:
- dy = dy+delta
-
- xofs = 0.0
- yofs = 0.0
-
- if ((dy > 0.0) and iszero(dx)):
- xofs = int(-size/2.0*IGRID+EPSILON)*GRID
- yofs = 0.0
- xShift = 0.0
- yShift = 1
-
- if ((dx > 0.0) and (dy>0.0)):
- xofs = 0.0
- yofs = 0.0
- xShift = 1.0
- yShift = 1.0
-
- if ((dx > 0.0) and iszero(dy)):
- xofs = 0.0
- yofs = int(-size/2.0*IGRID+EPSILON)*GRID
- xShift = 1.0
- yShift = 0.0
-
- if ((dx > 0.0) and (dy < 0.0)):
- xofs = 0.0
- yofs = int(-size*IGRID+EPSILON)*GRID
- xShift = 1.0
- yShift = -1.0
-
- if ((dy < 0.0) and iszero(dx)):
- xofs = int(-size/2.0*IGRID+EPSILON)*GRID
- yofs = -size
- xShift = 0.0
- yShift = -1.0
-
- if ((dy < 0.0) and (dx < 0.0)):
- xofs = -size
- yofs = -size
- xShift = -1.0
- yShift = -1.0
-
- if ((dx < 0.0) and iszero (dy)):
- xofs = -size # -fix(size/3.0*IGRID)*GRID
- yofs = int(-size/2.0*IGRID+EPSILON)*GRID
- xShift = -1.0
- yShift = 0.0
-
- if ((dx < 0.0) and (dy > 0.0)):
- xofs = -size
- yofs = 0.0
- xShift = -1.0
- yShift = 1.0
-
- len = max (abs(x1-x0), abs(y1-y0))
- orglen = len
- len = len-space
- sstep = max(abs(dx), abs(dy))
- anz = int((len+(sstep-size)+EPSILON)/sstep)
- ovhd = orglen - (anz-1)*sstep - size
-
- if drawMid:
- x0 = Snap(x0+(xShift*ovhd/2))
- y0 = Snap(y0+(yShift*ovhd/2))
-
- for i in range (anz):
- dbCreateRect(self, layer, Box(xofs+x0+dx*i, yofs+y0+dy*i, xofs+x0+dx*i+size, yofs+y0+dy*i+size))
-
-#***********************************************************************************************************************
-# myBox: safe version of Box that works with x2,y2 smaller also
-#***********************************************************************************************************************
-def myBox(x1,y1,x2,y2):
- if x1 1 : # vertical space between fillers
- hns = (H-nry*hs)/(nry-1)
- else :
- hns = 0.
-
- nrx = floor((W+dx)/(ws+dx))
- if nrx > 1 : # horizontal space between fillers
- wns = (W-nrx*ws)/(nrx-1)
- else :
- wns = 0.
-
- if dir == 'u' :
- if nrx >= nry :
- dir = 'h'
- else :
- dir = 'v'
-
- if dir == 'h' : # row-wise
- if offset > 0 :
- off = (ws+dx)*0.5
- else :
- off = 0.
-
- y = yl
- for i in range(1, int(nry)+1) :
- togy = tog(y)
- x = xl
- nr = nrx
- if offset != 0 and evenp(i+offset-1) and nr > 1 :
- nr = nr-1
- x = x+off
-
- for j in range(1, int(nr)+1) :
- togx = tog(x)
- id = dbCreateRect(self, layer, Box(togx, togy, togx+ws, togy+hs))
- if retlist :
- cons(idlist, id)
- x = x+wns+ws
-
- y = y+hns+hs
-
- else : # column-wise
- if offset > 0 :
- off = (hs+dy)*0.5
- else :
- 0
- x = xl
- for i in range(1, int(nrx)+1) :
- togx = tog(x)
- y = yl
- nr = nry
- if offset != 0 and evenp(i+offset-1) :
- nr = nr-1
- y = y+off
-
- for j in range(1, int(nr)+1) :
- togy = tog(y)
- id = dbCreateRect(self, layer, Box(togx, togy, togx+ws, togy+hs))
- if retlist :
- cons(idlist, id)
- y = y+hns+hs
-
- x = x+wns+ws
-
- # if
-
- return idlist
-
-#***********************************************************************************************************************
-# generateCorner
-#***********************************************************************************************************************
-def generateCorner(self, corner_startx, corner_starty, corner_width, corner_length, corner_steps, corner_end, offset, layer):
- item_list = list()
- for cnt in range(corner_steps) :
- rect = dbCreateRect(self, Layer(layer, 'drawing'), Box(corner_startx - corner_width * (cnt + 1), corner_starty + offset + (corner_length - corner_width) * cnt,
- corner_startx - corner_width * cnt, corner_starty+corner_length + offset + (corner_length-corner_width) * cnt))
- cons(item_list, rect)
-
- rect = dbCreateRect(self, Layer(layer, 'drawing'), Box(corner_startx - corner_width * (corner_steps + 1), corner_starty + offset + (corner_length - corner_width) * corner_steps,
- corner_startx - corner_width * corner_steps, corner_end))
- cons(item_list, rect)
-
- return item_list
-
-#***********************************************************************************************************************
-# combineLayerAndDelete
-#***********************************************************************************************************************
-def combineLayerAndDelete(self, item_list, groupId, layer):
-
- shapes = dbLayerOrList(Layer(layer, 'drawing'), item_list)
-
- size = len(shapes.getComps())
- for i in range(size) :
- cons(groupId, shapes.getComp(i))
-
- for item in item_list :
- item.destroy()
-
- return groupId
-
-#***********************************************************************************************************************
-# ihpCopyFig
-#***********************************************************************************************************************
-def ihpCopyFig(groupId, pnt, rot):
- newList = list()
- for item in groupId :
- cons(newList, dbCopyShape(item, pnt, rot))
-
- return newList
-
-#**************************************************************************************************************
-# bondpadOctagonPoints
-#**************************************************************************************************************
-def bondpadOctagonPoints(rx, ry, off):
- return PointList([Point(-rx , -ry+off), Point(-rx , ry-off ),
- Point(-rx+off, ry ), Point(rx-off , ry ),
- Point(rx , ry-off ), Point(rx , -ry+off),
- Point(rx-off , -ry ), Point(-rx+off, -ry )])
-
-#**************************************************************************************************************
-# bondpadOctagonRingPoints
-#**************************************************************************************************************
-def bondpadOctagonRingPoints(rx, ry, off, rxi, ryi, offi):
- return PointList([Point(-rx , 0 ), Point(-rx , ry-off ),
- Point(-rx+off , ry ), Point(rx-off , ry ),
- Point(rx , ry-off ), Point(rx , -ry+off ),
- Point(rx-off , -ry ), Point(-rx+off , -ry ),
- Point(-rx , -ry+off ), Point(-rx , 0 ),
- Point(-rxi , 0 ), Point(-rxi , -ryi+offi),
- Point(-rxi+offi, -ryi ), Point(rxi-offi , -ryi ),
- Point(rxi , -ryi+offi), Point(rxi , ryi-offi ),
- Point(rxi-offi , ryi ), Point(-rxi+offi, ryi ),
- Point(-rxi , ryi-offi ), Point(-rxi , 0 )])
-
-#**************************************************************************************************************
-# bondpadStretchedCircle
-#**************************************************************************************************************
-def bondpadStretchedCircle(self, layer, rx, ry, grid):
- if type(layer) == str :
- layer = Layer(layer)
-
- if rx == ry :
- id1 = dbCreateEllipse(self, layer, Box(-rx, -rx, rx, rx))
- id = dbConvertEllipseToPolygon(self, id1, 64, grid)
- return id
-
- if rx > ry :
- id1 = dbCreateEllipse(self, layer, Box(-rx, -ry -rx+ry*2, ry))
- id2 = dbCreateEllipse(self, layer, Box(rx-ry*2, -ry, rx, ry))
- id3 = dbCreateRect(self, layer, Box(ry-rx, -ry, rx-ry, ry))
- id = dbLayerOrList(layer, [id1, id2, id3])
- dbDeleteObject(id1)
- dbDeleteObject(id2)
- dbDeleteObject(id3)
- return id[0]
-
- id1 = dbCreateEllipse(self, layer, Box(-rx, -ry, rx, -ry+rx*2))
- id2 = dbCreateEllipse(self, layer, Box(-rx, ry-rx*2, rx, ry))
- id3 = dbCreateRect(self, layer, Box(-rx, rx-ry, rx, ry-rx))
- id = dbLayerOr(layer, [id1, id2, id3])
- dbDeleteObject(id1)
- dbDeleteObject(id2)
- dbDeleteObject(id3)
-
- return id[0]
-
-#***********************************************************************************************************************
-# geoMerge
-#***********************************************************************************************************************
-def geoMerge(self, layer) :
- if type(layer) == str :
- layer = Layer(layer)
-
- idlst = list()
- shapes = self.getLeafComps()
- for id in shapes :
- if id.layer == layer :
- idlst.append(id)
-
- if idlst :
- dbLayerOrList(layer, idlst)
- for id in idlst :
- id.destroy()
-
-#***********************************************************************************************************************
-# geoRing
-#***********************************************************************************************************************
-def geoRing(self, layer, rl, rr, rb, rt, rw, rh):
- if type(layer) == str :
- layer = Layer(layer)
-
- dbCreatePolygon(self, layer, PointList([Point(rl-rw, rb-rw), Point(rr+rw, rb-rw), Point(rr+rw, rt+rh), Point(rl-rw, rt+rh), Point(rl-rw, rb),
- Point(rl, rb), Point(rl, rt), Point(rr, rt), Point(rr, rb), Point(rl-rw, rb), Point(rl-rw, rb-rw)]))
-
-#**************************************************************************************************************
-# ihpGetRectHash
-#**************************************************************************************************************
-def ihpGetRectHash(g_value) :
- mlist = list()
- mlist.append(g_value)
- mlist.append(10001)
- return mlist
-
-#**************************************************************************************************************
-# ihpGetAskewHash
-#**************************************************************************************************************
-def ihpGetAskewHash(g_value) :
- mlist = list()
- mlist.append(g_value)
- mlist.append(10002)
- return mlist
-
-#**************************************************************************************************************
-# ihpGetOptionPair
-#**************************************************************************************************************
-def ihpGetOptionPair(g_index, g_options) :
- pair = list()
- iterIndex = 0
-
- for i in range(fix(listlen(g_options))) :
- if iterIndex == g_index :
- if (i+1) < listlen(g_options) :
- pair = pylist(nth(i, g_options), nth(i+1, g_options))
- return pair
-
- if isOdd(i) :
- iterIndex = iterIndex + 1
-
- return pair
-
-#**************************************************************************************************************
-# ihpIsRectOpt
-#**************************************************************************************************************
-def ihpIsRectOpt(g_index, g_options) :
- rValue = 0
- if (g_options != 0) and (g_index < listlen(g_options)) :
- testOpt = ihpGetOptionPair(g_index, g_options)
- if listlen(testOpt) == 2 :
- testHash = nth(1, testOpt);
- hashValue = nth(1, ihpGetRectHash(0));
-
- if testHash == hashValue :
- rValue = 1;
-
-
-
- return rValue;
-
-#**************************************************************************************************************
-# ihpIsAskewOpt
-#**************************************************************************************************************
-def ihpIsAskewOpt(g_index, g_options) :
- rValue = 0
- if (g_options != 0) and (g_index < listlen(g_options)) :
- testOpt = ihpGetOptionPair(g_index, g_options)
- if listlen(testOpt) == 2 :
- testHash = nth(1, testOpt);
- hashValue = nth(1, ihpGetAskewHash(0));
-
- if testHash == hashValue :
- rValue = 1;
-
-
-
- return rValue;
-
-#**************************************************************************************************************
-# ihpGetDrawOptValue
-#**************************************************************************************************************
-def ihpGetDrawOptValue(g_index, g_drwOptions) :
- rValue = 0
-
- if g_index < listlen(g_drwOptions) :
- testOpt = ihpGetOptionPair(g_index, g_drwOptions);
- if listlen(testOpt) == 2 :
- rValue = nth(0, testOpt);
-
- return(rValue);
-
-#**************************************************************************************************************
-# ihpGetSideSkewDrawingOptions
-#**************************************************************************************************************
-def ihpGetSideSkewDrawingOptions(g_value) :
- return pylist(ihpGetAskewHash(g_value),
- ihpGetRectHash(0), ihpGetRectHash(0),
- ihpGetAskewHash(g_value));
-
-#**************************************************************************************************************
-# ihpGetLeftSkewDrawingOptions
-#**************************************************************************************************************
-def ihpGetLeftSkewDrawingOptions(g_value) :
- return pylist(ihpGetRectHash(0),
- ihpGetRectHash(0), ihpGetRectHash(0),
- ihpGetAskewHash(g_value));
-
-#**************************************************************************************************************
-# ihpGetInnerSkewDrawingOptions
-#**************************************************************************************************************
-def ihpGetInnerSkewDrawingOptions(g_value) :
- return pylist(ihpGetRectHash(0),
- ihpGetAskewHash(g_value), ihpGetAskewHash(g_value),
- ihpGetRectHash(0));
-
-#**************************************************************************************************************
-# ihpGetNormalizedList
-#**************************************************************************************************************
-def ihpGetNormalizedList(theList) :
- if type(theList) is PointList :
- return theList
-
- normalized = list()
-
- if is_list(theList) :
- for i in range(fix(listlen(theList))) :
- item = nth(i, theList)
-
- itemList = ihpGetNormalizedList(item)
- for j in range(fix(listlen(itemList))) :
- elem = nth(j, itemList)
- if listlen(normalized) :
- normalized = cons(normalized, pylist(elem))
- else :
- normalized = list()
- normalized.append(elem)
-
-
- else :
- if listlen(normalized) :
- normalized = append(normalized, list(theList))
- else :
- normalized = list()
- normalized.append(theList)
-
- return normalized
-
-#**************************************************************************************************************
-# ihpGetShapeBBox
-#**************************************************************************************************************
-def ihpGetShapeBBox(shapeId) :
- shapeList = ihpGetNormalizedList(shapeId)
-
- bbox = Box(0, 0, 0, 0)
-
- if is_list(shapeList) == 0 :
- return bbox
-
- if listlen(shapeList) == 0 :
- return bbox
-
- #initialize componetnts first
- currentId = nth(0, shapeList);
- rect = currentId.getBBox()
-
- x1 = rect.getLeft()
- x2 = rect.getRight()
- y1 = rect.getBottom()
- y2 = rect.getTop()
-
- # compute min and max Point1(X1, Y1) and Point2(X2, Y2)
- for i in range(fix(listlen(shapeList))) :
- currentId = nth(i, shapeList)
-
- crect = currentId.getBBox()
- cx1 = crect.getLeft()
- cx2 = crect.getRight()
- cy1 = crect.getBottom()
- cy2 = crect.getTop()
-
- x1 = min2(x1, cx1)
- y1 = min2(y1, cy1)
- x2 = max2(x2, cx2)
- y2 = max2(y2, cy2)
-
- return Box(x1, y1, x2, y2)
-
-#***********************************************************************************************************************
-# ihpCreatedExtendedShape
-#***********************************************************************************************************************
-def ihpCreatedExtendedShape(g_cvId, g_layerId, g_shapeId, g_extend = None, g_options = None) :
- options = g_options
- if g_options == None :
- options = list(ihpGetRectHash(0))
-
- shapeList = ihpGetNormalizedList(g_shapeId)
-
- theShapes = list();
- for i in range(fix(listlen(shapeList))) :
- shapeId = nth(i, shapeList);
- theShapes = cons(theShapes, pylist(ihpCreateExtendedShapeByPoints(g_cvId, g_layerId, shapeId, g_extend, g_options)));
-
- return theShapes
-
-#**************************************************************************************************************
-# ihpCreateExtendedShapeByPoints
-#**************************************************************************************************************
-def ihpCreateExtendedShapeByPoints(g_cvId, g_layerId, g_shapeId, g_extend, g_drawOptions) :
- points = PointList()
-
- bbox = ihpGetShapeBBox(g_shapeId)
-
- x1 = nth(0, bbox)
- y1 = nth(1, bbox)
- x2 = nth(2, bbox)
- y2 = nth(3, bbox)
-
- if type(g_extend) is list :
- left = nth(2, g_extend)
- bottom = nth(1, g_extend)
- right = nth(3, g_extend)
- top = nth(0, g_extend)
- if type(g_extend) is Box :
- left = g_extend.getRight()
- bottom = g_extend.getBottom()
- right = g_extend.getTop()
- top = g_extend.getLeft()
- else :
- left = g_extend
- bottom = g_extend
- right = g_extend
- top = g_extend
-
- # extend the requested shape
- x1 = x1 - left;
- y1 = y1 - bottom;
- x2 = x2 + right;
- y2 = y2 + top;
-
- optionList = ihpGetNormalizedList(g_drawOptions)
-
- if ihpIsRectOpt(0, optionList) == 1 and ihpIsRectOpt(1, optionList) == 1 and ihpIsRectOpt(2, optionList) == 1 and ihpIsRectOpt(3, optionList) == 1 :
- points.append(Point(x1, y1))
- points.append(Point(x2, y2))
- else :
- if ihpIsAskewOpt(0, optionList) == 1 :
- points.append(Point(x1 + ihpGetDrawOptValue(0, optionList), y1))
- points.append(Point(x1, y1 + ihpGetDrawOptValue(0, optionList)))
- else :
- points.append(Point(x1, y1))
-
- if ihpIsAskewOpt(1, optionList) == 1 :
- points.append(Point(x1, y2 - ihpGetDrawOptValue(1, optionList)))
- points.append(Point(x1 + ihpGetDrawOptValue(1, optionList), y2))
- else :
- points.append(Point(x1, y2))
-
- if ihpIsAskewOpt(2, optionList) == 1 :
- points.append(Point(x2 - ihpGetDrawOptValue(2, optionList), y2))
- points.append(Point(x2, y2 - ihpGetDrawOptValue(2, optionList)))
- else :
- points.append(Point(x2, y2))
-
- if ihpIsAskewOpt(3, optionList) == 1 :
- points.append(Point(x2, y1 + ihpGetDrawOptValue(3, optionList)))
- points.append(Point(x2 - ihpGetDrawOptValue(3, optionList), y1))
- else :
- points.append(Point(x2, y1));
-
- return dbCreatePolygon(g_cvId, g_layerId, ihpGetNormalizedList(points))
-
-#**************************************************************************************************************
-# ihpSurroundShapeWithRing
-#**************************************************************************************************************
-def ihpSurroundShapeWithRing(g_cvId, g_layerId, g_shapeId, g_extend, g_ringWidth) :
- left = g_extend
- bottom = g_extend
- right = g_extend
- top = g_extend
-
- if type(g_extend) is list :
- left = nth(2, g_extend)
- bottom = nth(1, g_extend)
- right = nth(3, g_extend)
- top = nth(0, g_extend)
- if type(g_extend) is Box :
- left = g_extend.getRight()
- bottom = g_extend.getBottom()
- right = g_extend.getTop()
- top = g_extend.getLeft()
- else :
- left = g_extend
- bottom = g_extend
- right = g_extend
- top = g_extend
-
- shape1 = ihpCreatedExtendedShape(g_cvId, g_layerId, g_shapeId, Box(top, bottom, left, right))
- shape2 = ihpCreatedExtendedShape(g_cvId, g_layerId, g_shapeId, Box(top + g_ringWidth, bottom + g_ringWidth,
- left + g_ringWidth, right + g_ringWidth))
- hallo = dbLayerXor(g_layerId, car(shape1), car(shape2))
-
- dbDeleteObject(car(shape1));
- dbDeleteObject(car(shape2));
-
- return(hallo.getComp(0));
-
-#**************************************************************************************************************
-# ihpCreateContactArrayInShape
-#**************************************************************************************************************
-def ihpCreateContactArrayInShape(g_cvId, g_layer, g_shapeId, g_baseShape, g_size, g_rect, g_drcMinOverlap = None, g_drcMinSpace = None) :
-
- if g_drcMinOverlap == None :
- g_drcMinOverlap = 0.07
-
- if g_drcMinSpace == None :
- g_drcMinSpace = 0.18
-
- if g_baseShape != None :
- bbox = ihpGetShapeBBox(g_baseShape)
- width = abs(nth(0, bbox) - nth(2, bbox))
- height = abs(nth(1, bbox) - nth(3, bbox))
-
- if type(g_size) is list :
- width = nth(0, g_size)
- height = nth(1, g_size)
-
- top = g_drcMinOverlap;
- bottom = g_drcMinOverlap;
- left = g_drcMinOverlap;
- right = g_drcMinOverlap;
- xspace = g_drcMinSpace;
- yspace = g_drcMinSpace;
-
- if type(g_drcMinSpace) is list :
- xspace = car(g_drcMinSpace)
- yspace = cadr(g_drcMinSpace)
-
- if type(g_drcMinOverlap) is list :
- top = car(g_drcMinOverlap)
- bottom = cadr(g_drcMinOverlap)
- left = caddr(g_drcMinOverlap)
- right = cadddr(g_drcMinOverlap)
-
- if type(g_shapeId) != list :
- g_shapeId = list(g_shapeId)
-
- snapGrid = g_cvId.tech.getGridResolution()
-
- contactList = list()
- for i in range(fix(listlen(g_shapeId))) :
- shape = nth(i, g_shapeId)
-
- if type(shape) == Polygon :
- continue
-
- bbox = ihpGetShapeBBox(shape)
- rectWidth = abs(nth(2, bbox) - nth(0, bbox) - left - right)
- rectHeight = abs(nth(3, bbox) - nth(1, bbox) - top - bottom)
-
- center = pylist((nth(0, bbox) + left + nth(2, bbox) - right)*0.5, (nth(0, bbox) + bottom + nth(3, bbox) - top)*0.5)
-
- columns = fix((rectWidth+xspace)/(1.0*(width + xspace)))
- rows = fix((rectHeight+yspace)/(1.0*(height + yspace)))
-
- if columns > 0 and rows > 0 :
- contacts = ihpPerformContactPlacementInShape(g_cvId, g_layer, shape, pylist(columns, rows),
- pylist(width, height, xspace, yspace, left, bottom, center, snapGrid));
- contactList = append(contactList, contacts);
-
- return contactList
-
-#**************************************************************************************************************
-# ihpPerformContactPlacementInShape
-#**************************************************************************************************************
-def ihpPerformContactPlacementInShape(g_cvId, g_layer, g_shapeId, g_table, g_dimentions) :
-
- contactList = list()
-
- if type(g_table) != list or listlen(g_table) != 2 :
- return contactList
-
- if type(g_dimentions) != list or listlen(g_dimentions) != 7 :
- return contactList
-
- columns = nth(0, g_table)
- rows = nth(1, g_table)
-
- width = nth(0, g_dimentions)
- height = nth(1, g_dimentions)
- xspace = nth(2, g_dimentions)
- yspace = nth(3, g_dimentions)
- left = nth(4, g_dimentions)
- bottom = nth(5, g_dimentions)
- center = nth(6, g_dimentions)
- snapGrid = nth(7, g_dimentions)
-
- bbox = ihpGetShapeBBox(shape);
-
- xLoc = car(center)-((columns*(width+xspace)-xspace)*0.5);
- xLoc = fix(xLoc/snapGrid)*snapGrid;
- if xLoc < (nth(0, bbox) + left) :
- xLoc = xLoc+snapGrid
- xLoc = fix(xLoc/snapGrid)*snapGrid
-
- yLoc = cadr(center)-((rows*(height+yspace)-yspace)*0.5)
- yLoc = fix(yLoc/snapGrid)*snapGrid
-
- if yLoc < (nth(1, bbox) + bottom) :
- yLoc = yLoc+snapGrid
- yLoc = fix(yLoc/snapGrid)*snapGrid
-
- for i in range(fix(listlen(rows-1))) :
- for j in range(fix(listlen(columns-1))) :
- xOrig = xLoc + (j * (width + xspace))
- xOrig = fix(xOrig / snapGrid)* snapGrid
- yOrig = yLoc + (i * (height + yspace))
- yOrig = fix(yOrig / snapGrid)* snapGrid
-
- contactId = dbCreateRect(cvid, layer, Box(xOrig, yOrig, (xOrig + width), (yOrig + height)))
- contactList = append(newrects, list(contactId))
-
- return(contactList)
diff --git a/ihp-sg13g2/libs.tech/pycell/nmos_code.py b/ihp-sg13g2/libs.tech/pycell/nmos_code.py
deleted file mode 100644
index 0c3c798d..00000000
--- a/ihp-sg13g2/libs.tech/pycell/nmos_code.py
+++ /dev/null
@@ -1,259 +0,0 @@
-########################################################################
-#
-# Copyright 2023 IHP PDK Authors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-########################################################################
-__version__ = "$Revision: #3 $"
-
-from cni.dlo import *
-from thermal import *
-from geometry import *
-from utility_functions import *
-
-import math
-
-class nmos(DloGen):
-
- @classmethod
- def defineParamSpecs(cls, specs):
- techparams = specs.tech.getTechParams()
-
- CDFVersion = techparams['CDFVersion']
- model = 'sg13_lv_nmos'
- defL = techparams['nmos_defL']
- defW = techparams['nmos_defW']
- defNG = techparams['nmos_defNG']
- minL = techparams['nmos_minL']
- minW = techparams['nmos_minW']
-
- specs('cdf_version', CDFVersion, 'CDF Version')
- specs('Display', 'Selected', 'Display', ChoiceConstraint(['All', 'Selected']))
- specs('model', model, 'Model name')
-
- specs('w' , defW, 'Width')
- specs('ws', eng_string(Numeric(defW)/Numeric(defNG)), 'SingleWidth')
- specs('l' , defL, 'Length')
- specs('Wmin', minW, 'Wmin')
- specs('Lmin', minL, 'Lmin')
- specs('ng', defNG, 'Number of Gates')
-
- specs('m', '1', 'Multiplier')
- specs('trise', '', 'Temp rise from ambient')
-
- def setupParams(self, params):
- # process parameter values entered by user
- self.w = Numeric(params['w'])*1e6
- self.ng = Numeric(params['ng'])
- self.l = Numeric(params['l'])*1e6
-
- def genLayout(self):
- w = self.w
- ng = self.ng
- l = self.l
-
- techparams = self.tech.getTechParams()
- self.techparams = techparams
- self.epsilon = techparams['epsilon1']
-
- Cell = self.__class__.__name__
- typ = 'N'
- hv = False
-
- epsilon = techparams['epsilon1']
- #grid = techGetMfgGridResolution(tfId)
- grid = techparams['grid']
- metall_layer = Layer('Metal1')
- metall_layer_pin = Layer('Metal1', 'pin')
- ndiff_layer = Layer('Activ')
- pdiff_layer = Layer('Activ')
- pdiffx_layer = Layer('pSD')
- poly_layer = Layer('GatPoly')
- poly_layer_pin = Layer('GatPoly', 'pin')
- well_layer = Layer('NWell')
- well2_layer = Layer('nBuLay')
- textlayer = Layer('TEXT')
- locint_layer = Layer('Cont')
- tgo_layer = Layer('ThickGateOx')
- endcap = techparams['M1_c1']
- cont_size = techparams['Cnt_a']
- cont_dist = techparams['Cnt_b']
- cont_Activ_overRec = techparams['Cnt_c']
- cont_metall_over = techparams['M1_c']
- psd_pActiv_over = techparams['pSD_c']
- nwell_pActiv_over = techparams['NW_c']
- #minNwellForNBuLay = techparams['NW_g']
- well2_over = techparams['NW_NBL']
- gatpoly_Activ_over = techparams['Gat_c']
- gatpoly_cont_dist = techparams['Cnt_f']
- smallw_gatpoly_cont_dist = techparams['Cnt_c']
- psd_PFET_over = techparams['pSD_i']
- pdiffx_poly_over_orth = 0.48
-
- wmin = Numeric(techparams['nmos_minW'])
- lmin = Numeric(techparams['nmos_minL'])
-
- contActMin = 2*techparams['Cnt_c']+techparams['Cnt_a']
- thGateOxGat = techparams['TGO_c']
- thGateOxAct = techparams['TGO_a']
-
- dbReplaceProp(self, "pin#", 5)
-
- ng = math.floor(Numeric(ng)+epsilon)
-
- w = w/ng
- w = GridFix(w)
- l = GridFix(l)
-
- if endcap < cont_metall_over :
- endcap = cont_metall_over
-
- if hv :
- labelhv = 'HV'
- else :
- labelhv = ''
-
- smallMetAdd = cont_size + (2*cont_metall_over)
- if (w < contActMin-epsilon) :
- gatpoly_cont_dist = smallw_gatpoly_cont_dist
-
- xdiff_beg = 0
- ydiff_beg = 0
- ydiff_end = w
- if w < wmin-epsilon :
- hiGetAttention()
- print('Width < '+str(wmin))
- w = wmin
-
- if l < lmin-epsilon :
- hiGetAttention()
- print('Length < '+str(lmin))
- l = lmin
-
- if ng < 1 :
- hiGetAttention()
- print('Minimum one finger')
- ng = 1
-
- xanz = fix((w-2*cont_Activ_overRec+cont_dist)/(cont_size+cont_dist)+epsilon)
- w1 = xanz*(cont_size+cont_dist)-cont_dist+cont_Activ_overRec+cont_Activ_overRec
- xoffset = (w-w1)/2
- xoffset = GridFix(xoffset)
- diffoffset = 0
- if w < contActMin :
- xoffset = 0
- diffoffset = (contActMin-w)/2
- diffoffset = Snap(diffoffset)
-
- # get the number of contacts
- lcon = w-2*cont_Activ_overRec
- distc = cont_size+cont_dist
- ncont = fix((w-2*cont_Activ_overRec+cont_dist)/(cont_size+cont_dist)+epsilon)
- if zerop(ncont) :
- ncont = 1
-
- diff_cont_offset = GridFix((w-2*cont_Activ_overRec-ncont*cont_size-(ncont-1)*cont_dist)/2)
-
- # draw the cont row
- xcont_beg = xdiff_beg+cont_Activ_overRec
- ycont_beg = ydiff_beg+cont_Activ_overRec
- ycont_cnt = ycont_beg+diffoffset+diff_cont_offset
- xcont_end = xcont_beg+cont_size
-
- # draw Metal rect
- # calculate bot and top cont position
- yMet1 = ycont_cnt-endcap
- yMet2 = ycont_cnt+cont_size+( ncont-1)*distc +endcap
- # is metal1 overlapping Activ?
- yMet1 = min(yMet1, ydiff_beg+diffoffset)
- yMet2 = max(yMet2, ydiff_end+diffoffset)
- dbCreateRect(self, metall_layer, Box(xcont_beg-cont_metall_over, yMet1, xcont_end+cont_metall_over, yMet2))
-
- # draw contacts
- # LI and Metall
- contactArray(self, 0, locint_layer, xcont_beg, ydiff_beg, xcont_end, ydiff_end+diffoffset*2, 0, cont_Activ_overRec, cont_size, cont_dist)
-
- if w > contActMin : # smallW
- MkPin(self, 'S', 3, Box(xcont_beg-cont_metall_over, yMet1, xcont_end+cont_metall_over, yMet2), metall_layer_pin)
- else :
- MkPin(self, 'S', 3, Box(xcont_beg-cont_metall_over, yMet1, xcont_end+cont_metall_over, yMet2), metall_layer_pin)
-
- if typ == 'N' :
- dbCreateRect(self, ndiff_layer, Box(xcont_beg-cont_Activ_overRec, ycont_beg-cont_Activ_overRec, xcont_end+cont_Activ_overRec, ycont_beg+cont_size+cont_Activ_overRec))
- else :
- dbCreateRect(self, pdiff_layer, Box(xcont_beg-cont_Activ_overRec, ycont_beg-cont_Activ_overRec, xcont_end+cont_Activ_overRec, ycont_beg+cont_size+cont_Activ_overRec))
-
- for i in range(int(ng)) :
- # draw the poly line
- xpoly_beg = xcont_end+gatpoly_cont_dist
- ypoly_beg = ydiff_beg-gatpoly_Activ_over
- xpoly_end = xpoly_beg+l
- ypoly_end = ydiff_end+gatpoly_Activ_over
- dbCreateRect(self, poly_layer, Box(xpoly_beg, ypoly_beg+diffoffset, xpoly_end, ypoly_end+diffoffset))
-
- ihpAddThermalMosLayer(self, Box(xpoly_beg, ypoly_beg+diffoffset, xpoly_end, ypoly_end+diffoffset), True, Cell)
-
- if i == 0 :
- dbCreateLabel(self, Layer('TEXT', 'drawing'), Point((xpoly_beg+xpoly_end)/2, (ypoly_beg+ypoly_end)/2+diffoffset), 'nmos'+labelhv, 'centerCenter', 'R90', Font.EURO_STYLE, 0.09)
-
- if zerop(i) :
- MkPin(self, 'G', 2, Box(xpoly_beg, ypoly_beg+diffoffset, xpoly_end, ypoly_end+diffoffset), poly_layer_pin)
-
- # for every gate
- if typ == 'P' :
- dbCreateRect(self, pdiffx_layer, Box(xpoly_beg-pdiffx_poly_over_orth, ypoly_beg-psd_PFET_over+gatpoly_Activ_over+diffoffset, xpoly_end+pdiffx_poly_over_orth, ypoly_end+psd_PFET_over-gatpoly_Activ_over+diffoffset))
-
- # draw the second cont row
- xcont_beg = xpoly_end+gatpoly_cont_dist
- ycont_beg = ydiff_beg+cont_Activ_overRec
- ycont_cnt = ycont_beg+diffoffset+diff_cont_offset
- xcont_end = xcont_beg+cont_size
-
- dbCreateRect(self, metall_layer, Box(xcont_beg-cont_metall_over, yMet1, xcont_end+cont_metall_over, yMet2))
-
- # draw contacts
- # LI and Metall
- contactArray(self, 0, locint_layer, xcont_beg, ydiff_beg, xcont_end, ydiff_end+diffoffset*2, 0, cont_Activ_overRec, cont_size, cont_dist)
-
- if zerop(i) :
- if (w > contActMin) :
- MkPin(self, 'D', 1, Box(xcont_beg-cont_metall_over, yMet1, xcont_end+cont_metall_over, yMet2), metall_layer)
- else :
- MkPin(self, 'D', 1, Box(xcont_beg-cont_metall_over, yMet1, xcont_end+cont_metall_over, yMet2), metall_layer)
-
-
- if typ == 'N' :
- dbCreateRect(self, ndiff_layer, Box(xcont_beg-cont_Activ_overRec, ycont_beg-cont_Activ_overRec, xcont_end+cont_Activ_overRec, ycont_beg+cont_size+cont_Activ_overRec))
- else :
- dbCreateRect(self, pdiff_layer, Box(xcont_beg-cont_Activ_overRec, ycont_beg-cont_Activ_overRec, xcont_end+cont_Activ_overRec, ycont_beg+cont_size+cont_Activ_overRec))
-
-
- # now finish drawing the diffusion
- xdiff_end = xcont_end+cont_Activ_overRec
- if typ == 'N' :
- dbCreateRect(self, ndiff_layer, Box(xdiff_beg, ydiff_beg+diffoffset, xdiff_end, ydiff_end+diffoffset))
- else :
- dbCreateRect(self, pdiff_layer, Box(xdiff_beg, ydiff_beg+diffoffset, xdiff_end, ydiff_end+diffoffset))
- dbCreateRect(self, pdiffx_layer, Box(xdiff_beg-psd_pActiv_over, ydiff_beg-psd_pActiv_over+diffoffset, xdiff_end+psd_pActiv_over, ydiff_end+psd_pActiv_over+diffoffset))
- # draw minimum nWell
- nwell_offset = max(0, GridFix((contActMin-w)/2+0.5*grid))
- dbCreateRect(self, well_layer, Box(xdiff_beg-nwell_pActiv_over, ydiff_beg-nwell_pActiv_over+diffoffset-nwell_offset, xdiff_end+nwell_pActiv_over, ydiff_end+nwell_pActiv_over+diffoffset+nwell_offset))
- # draw nBuLay if nWell is large enough
- # wmin=2.88 -> only width musdt be checked
- if (ydiff_end+nwell_pActiv_over+diffoffset+nwell_offset)-(ydiff_beg-nwell_pActiv_over+diffoffset-nwell_offset) > minNwellForNBuLay :
- dbCreateRect(self, well2_layer, Box(xdiff_beg-nwell_pActiv_over+well2_over, ydiff_beg-nwell_pActiv_over+diffoffset-nwell_offset+well2_over, xdiff_end+nwell_pActiv_over-well2_over, ydiff_end+nwell_pActiv_over+diffoffset+nwell_offset-well2_over))
-
- if hv :
- dbCreateRect(self, Layer('ThickGateOx', 'drawing'), Box(xdiff_beg-thGateOxAct, ydiff_beg-gatpoly_Activ_over-thGateOxGat, xdiff_end+thGateOxAct, ydiff_end+gatpoly_Activ_over+thGateOxGat))
-
diff --git a/ihp-sg13g2/libs.tech/pycell/npn13G2_base_code.py b/ihp-sg13g2/libs.tech/pycell/npn13G2_base_code.py
deleted file mode 100644
index 880deb32..00000000
--- a/ihp-sg13g2/libs.tech/pycell/npn13G2_base_code.py
+++ /dev/null
@@ -1,151 +0,0 @@
-########################################################################
-#
-# Copyright 2023 IHP PDK Authors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-########################################################################
-__version__ = "$Revision: #3 $"
-
-from cni.dlo import *
-from thermal import *
-from geometry import *
-from utility_functions import *
-
-import math
-
-class npn13G2_base(DloGen):
-
- @classmethod
- def defineParamSpecs(cls, specs):
- specs('STI', '0.44u')
- specs('baspolyx', '0.3u')
- specs('bipwinx', '0.07u')
- specs('bipwiny', '0.1u')
- specs('empolyx', '0.15u')
- specs('empolyy', '0.18u')
- specs('le', '0.9u')
- specs('we', '0.07u')
- specs('Nx', 1)
- specs('Text', 'npn13G2')
- specs('CMetY1', '0.0')
- specs('CMetY2', '0.0')
-
- def setupParams(self, params):
- # process parameter values entered by user
- self.STI = Numeric(params['STI'])
- self.baspolyx = Numeric(params['baspolyx'])
- self.bipwinx = Numeric(params['bipwinx'])
- self.bipwiny = Numeric(params['bipwiny'])
- self.empolyx = Numeric(params['empolyx'])
- self.empolyy = Numeric(params['empolyy'])
- self.le = Numeric(params['le'])
- self.we = Numeric(params['we'])
- self.Nx = Numeric(params['Nx'])
- self.Text = params['Text']
- self.CMetY1 = Numeric(params['CMetY1'])
- self.CMetY2 = Numeric(params['CMetY2'])
-
- def genLayout(self):
- STI = self.STI
- baspolyx = self.baspolyx
- bipwinx = self.bipwinx
- bipwiny = self.bipwiny
- empolyx = self.empolyx
- empolyy = self.empolyy
- le = self.le
- we = self.we
- Nx = self.Nx
- Text = self.Text
- CMetY1 = self.CMetY1
- CMetY2 = self.CMetY2
-
- STI = Numeric(STI)*1e6
- baspolyx = Numeric(baspolyx)*1e6
- bipwinx = Numeric(bipwinx)*1e6
- bipwiny = Numeric(bipwiny)*1e6
- empolyx = Numeric(empolyx)*1e6
- empolyy = Numeric(empolyy)*1e6
- le = Numeric(le)*1e6
- we = Numeric(we)*1e6;
-
- Cell = 'npn13G2_base'
-
- stepX = 1.85
- stretchX = stepX*(Nx-1)
- bipwinxoffset = ((2 * (bipwinx - 0.04)) / 2)
- empolyxoffset = ((2 * (empolyx - 0.15)) / 2)
- baspolyxoffset = ((2 * (baspolyx - 0.3)) / 2)
- STIoffset = ((2 * (STI - 0.44)) / 2)
- bipwinyoffset = ((2 * (bipwiny - 0.1)) / 2)
- empolyyoffset = ((2 * (empolyy - 0.18)) / 2)
- nSDBlockShift = 0.43 - le
- leoffset = 0
- if le < 0.5 :
- pcStepY = 0.41
- yOffset = 0.20
- else :
- pcStepY = 0.41
- yOffset = 0.20
-
- if we <= 0.9 :
- pcRepeatY = 3
- else :
- pcRepeatY = 4
-
- pcRepeatY = 4
- if Nx > 1 :
- CMetY1 = -1.01 - we/2 - leoffset - bipwinyoffset - empolyyoffset
- CMetY2 = -0.57 - we/2 - leoffset - bipwinyoffset - empolyyoffset
- else :
- CMetY1 = -0.8 - we/2 - leoffset - bipwinyoffset - empolyyoffset
- CMetY2 = -0.56 - we/2 - leoffset - bipwinyoffset - empolyyoffset
-
- pcPurpose = 'drawing'
- for pcIndexX in range(int(math.floor(Nx))) :
- pcLayer = Layer('Via1')
- for pcIndexY in range(int((math.floor(pcRepeatY)))) :
- pcInst = dbCreateRect(self, Layer('Via1', 'drawing'), Box((stepX*pcIndexX)-0.3, ((-0.30-yOffset-leoffset-bipwinyoffset-empolyyoffset)+(pcIndexY*pcStepY))-0.2, (stepX*pcIndexX)-0.11, ((-0.11-yOffset-leoffset-bipwinyoffset-empolyyoffset)+(pcIndexY*pcStepY))-0.2))
- pcInst = dbCreateRect(self, Layer('Via1', 'drawing'), Box((stepX*pcIndexX)+0.11, ((-0.3-yOffset-leoffset-bipwinyoffset-empolyyoffset)+(pcIndexY*pcStepY))-0.2, (stepX*pcIndexX)+0.3, ((-0.11-yOffset-leoffset-bipwinyoffset-empolyyoffset)+(pcIndexY*pcStepY))-0.2))
-
- pcLayer = Layer('Metal1')
- pcInst = dbCreateRect(self, Layer('Metal1', 'drawing'), Box(stepX*pcIndexX-0.35, (-0.32-we/2-leoffset-bipwinyoffset-empolyyoffset), stepX*pcIndexX+0.35, (0.335+we/2+leoffset+bipwinyoffset+empolyyoffset)))
- pcLayer = Layer('Cont')
- pcInst = dbCreateRect(self, Layer('Cont', 'drawing'), Box(stepX*pcIndexX-0.79-le/2, (-0.76-we/2-leoffset-bipwinyoffset-empolyyoffset), stepX*pcIndexX+0.79+le/2, (-0.6-we/2-leoffset-bipwinyoffset-empolyyoffset)))
- pcInst = dbCreateRect(self, Layer('Cont', 'drawing'), Box(stepX*pcIndexX-0.76, (0.77+we/2-leoffset-bipwinyoffset-empolyyoffset), stepX*pcIndexX+0.76, (0.61+we/2-leoffset-bipwinyoffset-empolyyoffset)))
- pcLayer = Layer('EmWind')
- pcInst = dbCreateRect(self, Layer('EmWind', 'drawing'), Box(stepX*pcIndexX-le/2, (-we/2-leoffset), stepX*pcIndexX+le/2, (we/2+leoffset)))
-
- #ihpAddThermalBjtLayer(pcCellView, Box((stepX*pcIndexX-le/2)-0.05, , -we/2 - leoffset, -0.05, (stepX*pcIndexX+le/2)+0.05, , we/2 + leoffset, +0.05), t, Cell)
- pcInst = dbCreateRect(self, Layer('EmWind', 'drawing'), Box(stepX*pcIndexX-le/2, (-we/2-leoffset), stepX*pcIndexX+le/2, (we/2+leoffset)))
- pcLayer = Layer('Activ')
- xl = stepX*pcIndexX-0.06
- xh = xl+0.12
- yl = -0.24-leoffset
- yh = -yl
- pcInst = dbCreatePolygon(self, Layer('Activ', 'mask'), PointList([Point(xh+0.865, yl-0.74), Point(xl-0.865, yl-0.74), Point(xl-0.865, yh+0.38), Point(xl-0.385, yh+0.38), Point(xl-0.175, yh+0.59), Point(xh+0.175, yh+0.59), Point(xh+0.385, yh+0.38), Point(xh+0.865, yh+0.38)]))
- pcLayer = Layer('Activ')
- pcInst = dbCreateRect(self, Layer('Activ', 'drawing'), Box((stepX*pcIndexX-0.89-le/2-empolyxoffset-baspolyxoffset-STIoffset), (-0.83-we/2-leoffset-bipwinyoffset-empolyyoffset), (stepX*pcIndexX+0.89+le/2+empolyxoffset+baspolyxoffset+STIoffset), (-0.89-we/2+0.36-leoffset-bipwinyoffset-empolyyoffset)))
- pcLayer = Layer('nSD')
- pcInst = dbCreatePolygon(self, Layer('nSD', 'block'), PointList([Point((stepX * pcIndexX + 0.94 + le/2 + empolyxoffset + baspolyxoffset + STIoffset), (1.98 + we/2 + leoffset + bipwinyoffset + empolyyoffset)), Point((stepX * pcIndexX + 0.94 + le/2 + empolyxoffset + baspolyxoffset + STIoffset), (0.45 + we/2 + leoffset + bipwinyoffset + empolyyoffset)), Point((stepX * pcIndexX + 0.52 + le/2 + empolyxoffset + baspolyxoffset + STIoffset), (0.03 + we/2 + leoffset + bipwinyoffset + empolyyoffset)), Point((stepX * pcIndexX + 0.52 + le/2 + empolyxoffset + baspolyxoffset + STIoffset), ( - 0.6 - we/2 + leoffset + bipwinyoffset + empolyyoffset + nSDBlockShift)), Point((stepX * pcIndexX + 0.27 + le/2 + empolyxoffset + baspolyxoffset + STIoffset), (- 0.85 - we/2 + leoffset + bipwinyoffset + empolyyoffset + nSDBlockShift)), Point((stepX * pcIndexX - 0.27 - le/2 - empolyxoffset - baspolyxoffset - STIoffset), (- 0.85 - we/2 + leoffset + bipwinyoffset + empolyyoffset + nSDBlockShift)), Point((stepX * pcIndexX - 0.52 - le/2 - empolyxoffset - baspolyxoffset - STIoffset), (- 0.6 - we/2 + leoffset + bipwinyoffset + empolyyoffset + nSDBlockShift)), Point((stepX * pcIndexX - 0.52 - le/2 - empolyxoffset - baspolyxoffset - STIoffset), (0.03 + we/2 + leoffset + bipwinyoffset + empolyyoffset) ), Point((stepX * pcIndexX - 0.94 - le/2 - empolyxoffset - baspolyxoffset - STIoffset), (0.45 + we/2 + leoffset + bipwinyoffset + empolyyoffset)), Point((stepX * pcIndexX - 0.94 - le/2 - empolyxoffset - baspolyxoffset - STIoffset), (1.98 + we/2 + leoffset + bipwinyoffset + empolyyoffset))]))
-
- pcLayer = Layer('Metal1')
- pcInst = dbCreateRect(self, Layer('Metal1', 'drawing'), Box(-0.89-le/2, CMetY1, stretchX+0.89+le/2, CMetY2))
- pcInst = dbCreateRect(self, Layer('Metal1', 'drawing'), Box(-0.94-le/2, (0.57+we/2+leoffset+bipwinyoffset+empolyyoffset), stretchX+0.94+le/2, (0.81+we/2+leoffset+bipwinyoffset+empolyyoffset)))
- pcLayer = Layer('Metal2')
- pcInst = dbCreateRect(self, Layer('Metal2', 'drawing'), Box(-0.89-le/2, (-0.32-we/2-leoffset-bipwinyoffset-empolyyoffset), stretchX+0.89+le/2, (0.335+we/2+leoffset+bipwinyoffset+empolyyoffset)))
- pcLayer = Layer('TEXT')
- pcLabelText = self.Text
- pcLabelHeight = 0.35
- pcInst = dbCreateLabel(self, Layer('TEXT', 'drawing'), Point(0.015, (-1.86 - we/2 - leoffset - bipwinyoffset - empolyyoffset)), pcLabelText, 'centerCenter', 'R0', Font.EURO_STYLE, pcLabelHeight)
- pcInst.setDrafting(True)
diff --git a/ihp-sg13g2/libs.tech/pycell/npn13G2_code.py b/ihp-sg13g2/libs.tech/pycell/npn13G2_code.py
deleted file mode 100644
index e200a964..00000000
--- a/ihp-sg13g2/libs.tech/pycell/npn13G2_code.py
+++ /dev/null
@@ -1,169 +0,0 @@
-########################################################################
-#
-# Copyright 2023 IHP PDK Authors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-########################################################################
-__version__ = "$Revision: #3 $"
-
-from cni.dlo import *
-from thermal import *
-from geometry import *
-from utility_functions import *
-
-import math
-
-class npn13G2(DloGen):
-
- @classmethod
- def defineParamSpecs(cls, specs):
- techparams = specs.tech.getTechParams()
-
- CDFVersion = techparams['CDFVersion']
- model = techparams['npn13G2_model']
-
- specs('cdf_version', CDFVersion, 'CDF Version')
- specs('Display', 'Selected', 'Display', ChoiceConstraint(['All', 'Selected']))
- specs('model', model, 'Model name')
-
- specs('Nx', 1, 'x-Multiplier', RangeConstraint(1, 10))
- specs('Ny', 1, 'y-Multiplier', ChoiceConstraint([1]))
- specs('le', '0.9u', "Emitter Length")
- specs('we', '0.07u', "Emitter Width")
- specs('STI', '0.44u', 'STI')
- specs('baspolyx', '0.30u', 'baspolyx')
- specs('bipwinx', '0.07u', 'bipwinx')
- specs('bipwiny', '0.1u', 'bipwiny')
- specs('empolyx', '0.15u', 'empolyx')
- specs('empolyy', '0.18u', 'empolyy')
-
- specs('Icmax', '3m', 'Ic,max@Uce=2V (50%@0.5V)')
- specs('Iarea', '3m', 'Ic,max/squm@Uce=2V')
- specs('area', '1', 'Area Factor')
- specs('bn', 'sub!', 'Bulk node connection')
- specs('Vbe', '', 'Base-emitter voltag')
- specs('Vce', '', 'Collector-emitter voltage')
- specs('m', '1', 'Multiplier')
- specs('trise', '', 'Temp rise from ambient')
-
- def setupParams(self, params):
- # process parameter values entered by user
- self.params = params
- self.STI = Numeric(params['STI'])
- self.baspolyx = Numeric(params['baspolyx'])
- self.bipwinx = Numeric(params['bipwinx'])
- self.bipwiny = Numeric(params['bipwiny'])
- self.empolyx = Numeric(params['empolyx'])
- self.empolyy = Numeric(params['empolyy'])
- self.le = params['le']
- self.we = params['we']
- self.Nx = params['Nx']
- self.Ny = params['Ny']
- self.masterCell = 'npn13G2_base'
- self.masterView = 'layout'
- self.masterOrient = 'MX'
- self.masterLib = 'SG13_dev'
-
- def genLayout(self):
- STI = self.STI
- baspolyx = self.baspolyx
- bipwinx = self.bipwinx
- bipwiny = self.bipwiny
- empolyx = self.empolyx
- empolyy = self.empolyy
- le = Numeric(self.le)
- Nx = Numeric(self.Nx)
- we = Numeric(self.we)
- Ny = Numeric(self.Ny)
-
- STI = Numeric(STI)*1e6
- baspolyx = Numeric(baspolyx)*1e6
- bipwinx = Numeric(bipwinx)*1e6
- bipwiny = Numeric(bipwiny)*1e6
- empolyx = Numeric(empolyx)*1e6
- empolyy = Numeric(empolyy)*1e6
- le = Numeric(le)*1e6
- we = Numeric(we)*1e6
-
- a = le
- le = we
- we = a
- ActivShift = 0.01
- ActivShift = 0.0
- PWellBlockShift = -0.01
- stepX = 1.85
- stretchX = stepX*(Nx-1)
- bipwinyoffset = (2 * (bipwiny - 0.1) - 0) / 2
- empolyyoffset = (2 * (empolyy - 0.18)) / 2
-
- if le < 0.5 :
- leoffset = 0
- else :
- leoffset = 0
-
- name = self.masterLib + '/' + self.masterCell +'/' + self.masterView
- if Dlo.exists(name) :
- pcMaster = Instance(name)
- params = pcMaster.getParams()
- params['le'] = self.le
- params['Nx'] = self.Nx
- params['we'] = self.we
- pcMaster.setParams(params)
- pcMaster.setOrientation(strToOrient(self.masterOrient))
- pcMaster.setOrigin(Point(0, 0))
- else :
- print('(OA) Design "' + name + '" was not found')
-
- pcLayer = 'TRANS'
- pcPurpose = 'drawing'
- dbCreatePolygon(self, Layer(pcLayer, pcPurpose), PointList([Point(stretchX+2.45, (2.43 + we/2 + leoffset + bipwinyoffset + empolyyoffset)),
- Point(-2.45, (2.43 + we/2 + leoffset + bipwinyoffset + empolyyoffset)),
- Point(-2.45, (-1.98 - we/2 - leoffset - bipwinyoffset - empolyyoffset)),
- Point(stretchX+2.45, (-1.98 - we/2 - leoffset - bipwinyoffset - empolyyoffset))]))
- pcLayer = 'pSD'
- dbCreatePolygon(self, Layer(pcLayer, pcPurpose), PointList([Point(stretchX+3.35, (3.33 + we/2 + leoffset + bipwinyoffset + empolyyoffset)),
- Point(stretchX+2.45, (3.33 + we/2 + leoffset + bipwinyoffset + empolyyoffset)),
- Point(stretchX+2.45, (-1.98 - we/2 - leoffset - bipwinyoffset - empolyyoffset)),
- Point(-2.45, (-1.98 - we/2 - leoffset - bipwinyoffset - empolyyoffset)),
- Point(-2.45, (2.43 + we/2 + leoffset + bipwinyoffset + empolyyoffset)),
- Point(stretchX+2.45, (2.43 + we/2 + leoffset + bipwinyoffset + empolyyoffset)),
- Point(stretchX+2.45, (3.33 + we/2 + leoffset + bipwinyoffset + empolyyoffset)),
- Point(-3.35, (3.33 + we/2 + leoffset + bipwinyoffset + empolyyoffset)),
- Point(-3.35, (-2.88 - we/2 - leoffset - bipwinyoffset - empolyyoffset)),
- Point(stretchX+3.35, (-2.88 - we/2 - leoffset - bipwinyoffset - empolyyoffset))]))
- pcLayer = 'Activ'
- dbCreatePolygon(self, Layer(pcLayer, pcPurpose), PointList([Point(stretchX+3.15+ActivShift, (3.13 + we/2 + leoffset + bipwinyoffset + empolyyoffset+ActivShift)),
- Point(stretchX+2.65+ActivShift, (3.13 + we/2 + leoffset + bipwinyoffset + empolyyoffset+ActivShift)),
- Point(stretchX+2.65+ActivShift, (-2.18 - we/2 - leoffset - bipwinyoffset - empolyyoffset-ActivShift)),
- Point(-2.65-ActivShift, (-2.18 - we/2 - leoffset - bipwinyoffset - empolyyoffset-ActivShift)),
- Point(-2.65-ActivShift, (2.63 + we/2 + leoffset + bipwinyoffset + empolyyoffset+ActivShift)),
- Point(stretchX+2.65+ActivShift, (2.63 + we/2 + leoffset + bipwinyoffset + empolyyoffset+ActivShift)),
- Point(stretchX+2.65+ActivShift, (3.13 + we/2 + leoffset + bipwinyoffset + empolyyoffset+ActivShift)),
- Point(-3.15-ActivShift, (3.13 + we/2 + leoffset + bipwinyoffset + empolyyoffset+ActivShift)),
- Point(-3.15-ActivShift, (-2.68 - we/2 - leoffset - bipwinyoffset - empolyyoffset-ActivShift)),
- Point(stretchX+3.15+ActivShift, (-2.68 - we/2 - leoffset - bipwinyoffset - empolyyoffset-ActivShift))]))
- if Nx > 1 :
- MkPin(self, 'C', 1, Box(-0.89-le/2, (0.57+we/2-leoffset-bipwinyoffset-empolyyoffset), (stretchX+0.89+le/2), (1.01+we/2-leoffset-bipwinyoffset-empolyyoffset)), Layer('Metal1', 'pin'))
- else :
- MkPin(self, 'C', 1, Box(-0.89-le/2, (0.56+we/2+leoffset+bipwinyoffset+empolyyoffset), (stretchX+0.89+le/2), (0.8+we/2+leoffset+bipwinyoffset+empolyyoffset)), Layer('Metal1', 'pin'))
-
- MkPin(self, 'B', 2, Box(-0.94-le/2, (-0.81-we/2-leoffset-bipwinyoffset-empolyyoffset), (stretchX+0.94+le/2), (-0.57-we/2-leoffset-bipwinyoffset-empolyyoffset)), Layer('Metal1', 'pin'))
- MkPin(self, 'E', 3, Box(-0.71-le/2, (0.32+we/2+leoffset+bipwinyoffset+empolyyoffset), stretchX+0.71+le/2, (-0.335-we/2-leoffset-bipwinyoffset-empolyyoffset)), Layer('Metal2', 'pin'))
-
- pcLayer = 'TEXT'
- pcLabelText = 'Ae={Ae}um2'.format(Ae=Nx*Ny*le*we)
- pcLabelHeight = 0.35
- pcInst = dbCreateLabel(self, Layer(pcLayer, pcPurpose), Point(-1.977, -2.546), pcLabelText, 'lowerLeft', 'R90', Font.EURO_STYLE, pcLabelHeight)
- #setSGq(pcInst, "normalLabel", labelType)
-
diff --git a/ihp-sg13g2/libs.tech/pycell/rhigh_code.py b/ihp-sg13g2/libs.tech/pycell/rhigh_code.py
deleted file mode 100644
index 905f5669..00000000
--- a/ihp-sg13g2/libs.tech/pycell/rhigh_code.py
+++ /dev/null
@@ -1,491 +0,0 @@
-########################################################################
-#
-# Copyright 2023 IHP PDK Authors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-########################################################################
-__version__ = '$Revision: #3 $'
-
-from cni.dlo import *
-from geometry import *
-from thermal import *
-from utility_functions import *
-
-import math
-
-class rhigh(DloGen):
-
- @classmethod
- def defineParamSpecs(cls, specs):
- # define parameters and default values
- techparams = specs.tech.getTechParams()
-
- SG13_TECHNOLOGY = techparams["techName"]
- suffix = ""
- if 'SG13G2' in SG13_TECHNOLOGY :
- suffix = 'G2'
- if 'SG13G3' in SG13_TECHNOLOGY :
- suffix = 'G3'
-
- CDFVersion = techparams['CDFVersion']
- model = techparams['rhigh_model']
- rspec = techparams['rhigh_rspec']
- rkspec = techparams['rhigh_rkspec']
- rzspec = techparams['rhigh_rzspec']
- defL = techparams['rhigh_defL']
- defW = techparams['rhigh_defW']
- defB = techparams['rhigh_defB']
- defPS = techparams['rhigh_defPS']
- minL = techparams['rhigh_minL']
- minW = techparams['rhigh_minW']
- minPS = techparams['rhigh_minPS']
- eps = techparams['epsilon2']
-
- specs('cdf_version', CDFVersion, 'CDF Version')
- specs('Display', 'Selected', 'Display', ChoiceConstraint(['All', 'Selected']))
- specs('Calculate', 'l', 'Calculate', ChoiceConstraint(['R', 'w', 'l']))
- specs('Recommendation', 'No', 'Recommendation', ChoiceConstraint(['Yes', 'No']))
- specs('model', model, 'Model name')
-
- resistance = CbResCalc('R', 0, defL, defW, defB, defPS, 'rhigh')
- specs('R', eng_string(resistance), 'R')
-
- specs('w', defW, 'Width')
- specs('l', defL, 'Length')
- specs('b', defB, 'Bends')
- specs('ps', defPS, 'Poly Space')
-
- imax = CbResCurrent(Numeric(defW), eps, 'rhigh'+suffix)
- specs('Imax', imax, 'Imax')
- specs('bn', 'sub!', 'Bulk node connection')
- specs('Wmin', minW, 'Wmin')
- specs('Lmin', minL, 'Lmin')
- specs('PSmin', minPS, 'PSmin')
- specs('Rspec', rspec, 'Rspec [Ohm/sq]')
- specs('Rkspec', rkspec, 'Rkspec [Ohm/cont]')
- specs('Rzspec', rzspec, 'Rzspec [Ohm*m]')
- specs('tc1', '-2300e-6', 'Temperature coefficient 1')
- specs('tc2', '2.1e-6', 'Temperature coefficient 2')
- specs('PWB', 'No', 'PWell Blockage', ChoiceConstraint(['Yes', 'No']))
- specs('m', '1', 'Multiplier')
- specs('trise', '0.0', 'Temp rise from ambient')
-
- def setupParams(self, params):
- # process parameter values entered by user
- self.l = Numeric(params['l'])
- self.w = Numeric(params['w'])
- self.b = int(params['b'])
- self.ps = Numeric(params['ps'])
- #self.resistance = Numeric(params['R'])
-
- self.grid = self.tech.getGridResolution()
- self.techparams = self.tech.getTechParams()
- self.epsilon = self.techparams['epsilon1']
-
- def genLayout(self):
- #*************************************************************************
- #*
- #* Cell Properties
- #*
- #*************************************************************************
- dbReplaceProp(self, 'ivCellType', 'graphic')
- dbReplaceProp(self, 'viewSubType', 'maskLayoutParamCell')
- dbReplaceProp(self, 'instNamePrefix', 'R')
- dbReplaceProp(self, 'function', 'resistor')
- dbReplaceProp(self, 'pcellVersion', '$Revision: 1.0 $')
- dbReplaceProp(self, 'pin#', 3)
-
- #*************************************************************************
- #*
- #* Layer Definitions
- #*
- #*************************************************************************
- contpolylayer = Layer('GatPoly')
- bodypolylayer = Layer('PolyRes')
- sallayer = Layer('SalBlock')
- locintlayer = Layer('Cont')
- extBlocklayer = Layer('EXTBlock')
- metlayer = Layer('Metal1')
- textlayer = Layer('TEXT', 'drawing')
- nsdlayer = Layer('nSD')
- psdlayer = Layer('pSD')
-
- #*************************************************************************
- #*
- #* Generic Design Rule Definitions
- #*
- #*************************************************************************
- metover = self.techparams['M1_c']
- salover = self.techparams['Sal_c']
- salover1 = self.techparams['Sal_c']
- salspace = self.techparams['Sal_d']
- psdover1 = self.techparams['Rppd_b']
- consize = self.techparams['Cnt_a']
- conspace = self.techparams['Cnt_b']
- endcap = self.techparams['M1_c1']
- endcap2 = self.techparams['M1_c1']
- polyover = self.techparams['Cnt_d']
- grid = self.techparams['grid']
- contbar_min_len = self.techparams['CntB_a1']
- contbar_poly_over = self.techparams['CntB_d']
-
- #*************************************************************************
- #*
- #* Device Specific Design Rule Definitions
- #*
- #*************************************************************************
- psdover = self.techparams['Rhi_c']
- nsdover = self.techparams['Rhi_c']
- li_salblock = self.techparams['Rhi_d']
- poly_cont_len = consize+polyover # self.techparams['rhigh_poly_cont_len'] # 0.57
-
- # **************** Internal / External *********************************
- # use internalCode True for internal PCell
- internalCode = True
- # **************** Internal / External *********************************
- salblock_nsd_enc = 0.0
- li_poly_over = 0.0
- contactpush = 0.0
- resshort = 0.0
- gridnumber = 0.0
- contoverlay = 0.0
- lcor = 0.0
- psmin = Numeric(self.techparams['rhigh_minPS'])*1e6
-
- #*************************************************************************
- #*
- #* Instances For Mosaic Fills
- #*
- #*************************************************************************
- Cell = self.__class__.__name__
- #*************************************************************************
- #*
- #* Main body of code
- #*
- #*************************************************************************
-
- l = Numeric(self.l)*1e6;
- w = Numeric(self.w)*1e6;
- b = fix(self.b + self.epsilon)
- ps = Numeric(self.ps)*1e6;
-
- # GGa Attention: Poly must be 2*Cnt_a + Cnt_b + 2*Cnt_d Min Size of Cont + 2* GatPolyEnclosure. Might be dogbone
- wcontact = w
-
- # 10.12.07 GGa added block for internal code
- drawbar = False
-
- if internalCode :
- if wcontact-2*contbar_poly_over + self.epsilon >= contbar_min_len :
- drawbar = True
-
- if psdover1 > psdover :
- psdover = psdover1
-
- if salover1 > salover :
- salover = salover1
-
- nsdover = psdover
- # GGa dogbone has to be on grid, so make difference in gridsteps
- contoverlay = wcontact - w
- if contoverlay > 0 :
- # is dogbone: keep on checking for lay on grid
- # Distance per side
- contoverlay = contoverlay/2
- # gridpoints per side?
- gridnumber = contoverlay/grid
- # make to fixnumber
- gridnumber = round(gridnumber + self.epsilon)
- # need more gridpoints to lay on grip?
- if (gridnumber*grid*100) < contoverlay :
- gridnumber += 1
-
- contoverlay = gridnumber*grid
- wcontact = w+2*contoverlay
- # if
-
- # Insertionpoint for contact is at (0-contoverlay:0)
- xpos1 = 0-contoverlay
- ypos1 = 0
- xpos2 = xpos1+wcontact
- ypos2 = 0
- dir = -1
- stripes = b+1
- endcap = max(endcap, endcap2)
- metover = max(endcap2, metover)
-
- # set contacts out of resistor-square?
- # GridFix because 0.40000 < (0.20000+0.2000). Works with GridFix
- lsumold = 0.0
- lsumnew = 0.0
- lcor = 0.0
- if GridFix(ps) < GridFix((salover+salspace)) and stripes > 2 :
- contactpush = contactpush+w+salover
- resshort = GridFix((2*contactpush)/stripes)+grid
- lsumold = l*stripes
- l = l-resshort
- lsumnew = l*stripes+contactpush*2
- # need to push out contact2?
- lcor = lsumold-lsumnew
-
- # 05.05.06 GGa Check, if contacts have to be asymmetric
- # Some cases need to have asym contacts:
- # 2 stripes and low ps and are not pushed out of resistor
- if zerop(contactpush) and (ps-2*contoverlay <= psmin) and onep(b) :
- asymcont = True
- else :
- asymcont = False
-
- # set all parts up to get 0:0 at beginning of resistorbody:
- ypos1 = ypos1-contactpush*dir
- ypos2 = ypos2-contactpush*dir
-
- # *********************************************************
- # draw res contact #1 -> realise Overlap by dogbone to keep burdens, when needed
- # BOT Contact area
- # *********************************************************
- # set xpos1/xpos2 to left for contacts when Stripes>1 and ps<
- if asymcont :
- xpos1 = xpos1-contoverlay
- xpos2 = xpos2-contoverlay
-
- # *********************************************************
- # gatpolyarea between salBlock and contact
- dbCreateRect(self, contpolylayer, Box(xpos1, ypos1+contactpush*dir, xpos2, ypos2+(contactpush+poly_cont_len+li_salblock)*dir))
-
- # *********************************************************
- # nSD/pSD EXTBlock
- dbCreateRect(self, psdlayer, Box(xpos1-psdover, ypos1+(contactpush-psdover)*dir, xpos2+psdover, ypos2+(contactpush+poly_cont_len+li_salblock+psdover)*dir))
- dbCreateRect(self, nsdlayer, Box(xpos1-psdover, ypos1+(contactpush-psdover)*dir, xpos2+psdover, ypos2+(contactpush+poly_cont_len+li_salblock+psdover)*dir))
- dbCreateRect(self, extBlocklayer, Box(xpos1-psdover, ypos1+(contactpush-psdover)*dir, xpos2+psdover, ypos2+(contactpush+poly_cont_len+li_salblock+psdover)*dir))
-
- # contact area
- # number parallel contacts ncont, distance distc:
- wcon = wcontact-2.0*polyover
- distc = consize+conspace
- ncont = floor((wcon+conspace)/distc + self.epsilon)
- if ncont < 1 :
- ncont = 1
- distr = GridFix((wcon-ncont*distc+conspace)*0.5)
-
- # *********************************************************
- # draw contact
- if drawbar :
- # can only be in internal version
- dbCreateRect(self, locintlayer, Box(xpos1+contbar_poly_over, ypos2+(contactpush+li_salblock+li_poly_over)*dir, xpos2-contbar_poly_over, ypos2+(contactpush+consize+li_salblock+li_poly_over)*dir))
- else :
- for i in range(ncont) :
- dbCreateRect(self, locintlayer, Box(xpos1+polyover+distr+i*distc, ypos2+(contactpush+li_salblock+li_poly_over)*dir, xpos1+polyover+distr+i*distc+consize, ypos2+(contactpush+consize+li_salblock+li_poly_over)*dir))
-
- # 26.6.08 GG: new metal block
- dbCreateRect(self, metlayer, Box(xpos1+contbar_poly_over-endcap, ypos2+(contactpush+li_salblock+li_poly_over-metover)*dir, xpos2-contbar_poly_over+endcap, ypos2+(contactpush+consize+li_salblock+li_poly_over+metover)*dir))
- MkPin(self, 'PLUS', 1, Box(xpos1+contbar_poly_over-endcap, ypos2+(contactpush+li_salblock+li_poly_over-metover)*dir, xpos2-contbar_poly_over+endcap, ypos2+(contactpush+consize+li_salblock+li_poly_over+metover)*dir), metlayer)
-
- # set xpos1/xpos2 back to right for resistorbody
- if asymcont :
- xpos1 = xpos1+contoverlay
- xpos2 = xpos2+contoverlay
-
- # *********************************************************
- # resistorbody:
- # *********************************************************
- dir = 1
- xpos1 = xpos1+contoverlay
- xpos2 = xpos1+w-contoverlay
- ypos2 = ypos1+(l-resshort)*dir
-
- # *********************************************************
- # normal contatcs or outlying contacts?
- if contactpush > 0 :
- # *********************************************************
- # draw salblock and pSD over resistor and bends
- # Sal Block over stripes and bends
- dbCreateRect(self, sallayer, Box(xpos1-salover, ypos1-contactpush*dir, xpos1+stripes*(w+ps)-ps+salover, ypos1+l+w+salover))
- # 09.02.07 GGa added EXTBlock
- dbCreateRect(self, extBlocklayer, Box(xpos1-salover, ypos1-contactpush*dir, xpos1+stripes*(w+ps)-ps+salover, ypos1+l+w+salover))
- # pSD over Stripes and bend
- dbCreateRect(self, psdlayer, Box(xpos1-psdover, ypos1-(contactpush-salblock_nsd_enc)*dir, xpos1+stripes*(w+ps)-ps+psdover, ypos1+(l+w+psdover)*dir))
- # nsdBlock over Stripes and Bends
- dbCreateRect(self, nsdlayer, Box(xpos1-nsdover, ypos1-(contactpush-salblock_nsd_enc)*dir, xpos1+stripes*(w+ps)-ps+nsdover, ypos1+(l+w+nsdover)*dir))
-
- # *********************************************************
- # maybe draw extra salblock for longer last stripe
- if lcor > 0 :
- if oddp(stripes) :
- # draw new rect topright
- # SalBlock
- dbCreateRect(self, sallayer, Box(xpos1+stripes*(w+ps)-ps-w-salover, ypos1+l+w+salover, xpos1+stripes*(w+ps)-ps+salover, ypos1+l+w+salover+lcor))
- # 09.02.07 GGa added EXTBlock
- dbCreateRect(self, extBlocklayer, Box(xpos1+stripes*(w+ps)-ps-w-salover, ypos1+l+w+salover, xpos1+stripes*(w+ps)-ps+salover, ypos1+l+w+salover+lcor))
- # pSD
- dbCreateRect(self, psdlayer, Box(xpos1+stripes*(w+ps)-ps-w-psdover, ypos1+l+w+salover-salblock_nsd_enc, xpos1+stripes*(w+ps)-ps+psdover, ypos1+l+w+salover+lcor-salblock_nsd_enc))
- # nSD
- dbCreateRect(self, nsdlayer, Box(xpos1+stripes*(w+ps)-ps-w-nsdover, ypos1+l+w+salover-salblock_nsd_enc, xpos1+stripes*(w+ps)-ps+nsdover, ypos1+l+w+salover+lcor-salblock_nsd_enc))
- else : # draw new rect bottom right
- dbCreateRect(self, sallayer, Box(xpos1+stripes*(w+ps)-ps-w-salover, ypos1-contactpush-lcor, xpos1+stripes*(w+ps)-ps+salover, ypos1-contactpush))
- # 09.02.07 GGa added EXTBlock
- dbCreateRect(self, extBlocklayer, Box(xpos1+stripes*(w+ps)-ps-w-salover, ypos1-contactpush-lcor, xpos1+stripes*(w+ps)-ps+salover, ypos1-contactpush))
- dbCreateRect(self, psdlayer, Box(xpos1+stripes*(w+ps)-ps-w-psdover, ypos1-contactpush-lcor+salblock_nsd_enc, xpos1+stripes*(w+ps)-ps+psdover, ypos1-contactpush+salblock_nsd_enc))
- dbCreateRect(self, nsdlayer, Box(xpos1+stripes*(w+ps)-ps-w-nsdover, ypos1-contactpush-lcor+salblock_nsd_enc, xpos1+stripes*(w+ps)-ps+nsdover, ypos1-contactpush+salblock_nsd_enc))
- # if oddp(stripes)
- # if lcor>0
- # *********************************************************
- else : # normal SalBlock
- # *********************************************************
- if onep(stripes) : # only one Stripe->other nSD/pSD
- # *********************************************************
- # one Stripe, only one SalBlock and shorter nSD/pSD
- # draw salblock and pSD over resistor
- dbCreateRect(self, sallayer, Box(xpos1-salover, ypos1, xpos1+stripes*(w+ps)-ps+salover, ypos2))
- # 09.02.07 GGa added EXTBlock
- dbCreateRect(self, extBlocklayer, Box(xpos1-salover, ypos1, xpos1+stripes*(w+ps)-ps+salover, ypos2))
- dbCreateRect(self, psdlayer, Box(xpos1-psdover, ypos1+salblock_nsd_enc*dir, xpos1+stripes*(w+ps)-ps+psdover, ypos2-salblock_nsd_enc))
- dbCreateRect(self, nsdlayer, Box(xpos1-nsdover, ypos1+dir*salblock_nsd_enc, xpos1+stripes*(w+ps)-ps+nsdover, ypos2-salblock_nsd_enc))
- else : # other nSD/pSD Blockcover Bends
- # draw salblock and pSD over resistor
- dbCreateRect(self, sallayer, Box(xpos1-salover, ypos1, xpos1+stripes*(w+ps)-ps+salover, ypos2))
- # 09.02.07 GGa added EXTBlock
- dbCreateRect(self, extBlocklayer, Box(xpos1-salover, ypos1, xpos1+stripes*(w+ps)-ps+salover, ypos2))
- dbCreateRect(self, psdlayer, Box(xpos1-psdover, ypos1+salblock_nsd_enc*dir, xpos1+stripes*(w+ps)-ps+psdover, ypos2))
- dbCreateRect(self, nsdlayer, Box(xpos1-nsdover, ypos1+dir*salblock_nsd_enc, xpos1+stripes*(w+ps)-ps+nsdover, ypos2))
- if oddp(stripes) : # draw salblock and pSD over resistor
- # odd stripesnumber
- dbCreateRect(self, sallayer, Box(xpos1+w+ps-salover, ypos1, xpos1+stripes*(w+ps)-ps+salover, ypos1-w-salover))
- # 09.02.07 GGa added EXTBlock
- dbCreateRect(self, extBlocklayer, Box(xpos1-salover, ypos2, xpos1+(stripes-1)*(w+ps)-ps+salover, ypos2+w+salover))
- dbCreateRect(self, sallayer, Box(xpos1+w+ps-salover, ypos1, xpos1+stripes*(w+ps)-ps+salover, ypos1-w-salover))
- # 09.02.07 GGa added EXTBlock
- dbCreateRect(self, extBlocklayer, Box(xpos1+w+ps-salover, ypos1, xpos1+stripes*(w+ps)-ps+salover, ypos1-w-salover))
- dbCreateRect(self, psdlayer, Box(xpos1-psdover, ypos2, xpos1+(stripes-1)*(w+ps)-ps+psdover, ypos2+w+psdover))
- dbCreateRect(self, psdlayer, Box(xpos1+w+ps-psdover, ypos1+salblock_nsd_enc, xpos1+stripes*(w+ps)-ps+psdover, ypos1-w-psdover))
- dbCreateRect(self, nsdlayer, Box(xpos1-nsdover, ypos2, xpos1+(stripes-1)*(w+ps)-ps+nsdover, ypos2+w+nsdover))
- dbCreateRect(self, nsdlayer, Box(xpos1+w+ps-nsdover, ypos1+salblock_nsd_enc, xpos1+stripes*(w+ps)-ps+nsdover, ypos1-w-nsdover))
- else : # unodd stripesnumber
- dbCreateRect(self, sallayer, Box(xpos1-salover, ypos2, xpos1+stripes*(w+ps)-ps+salover, ypos2+w+salover))
- # 09.02.07 GGa added EXTBlock
- dbCreateRect(self, extBlocklayer, Box(xpos1-salover, ypos2, xpos1+stripes*(w+ps)-ps+salover, ypos2+w+salover))
- dbCreateRect(self, psdlayer, Box(xpos1-psdover, ypos2, xpos1+stripes*(w+ps)-ps+psdover, ypos2+w+psdover))
- dbCreateRect(self, nsdlayer, Box(xpos1-nsdover, ypos2, xpos1+stripes*(w+ps)-ps+nsdover, ypos2+w+nsdover))
- if stripes > 2 :
- dbCreateRect(self, sallayer, Box(xpos1+w+ps-salover, ypos1, xpos1+(stripes-1)*(w+ps)-ps+salover, ypos1-w-salover))
- # 09.02.07 GGa added EXTBlock
- dbCreateRect(self, extBlocklayer, Box(xpos1+w+ps-salover, ypos1, xpos1+(stripes-1)*(w+ps)-ps+salover, ypos1-w-salover))
- dbCreateRect(self, psdlayer, Box(xpos1+w+ps-psdover, ypos1+salblock_nsd_enc, xpos1+(stripes-1)*(w+ps)-ps+psdover, ypos1-w-psdover))
- dbCreateRect(self, nsdlayer, Box(xpos1+w+ps-nsdover, ypos1+salblock_nsd_enc, xpos1+(stripes-1)*(w+ps)-ps+nsdover, ypos1-w-nsdover))
- # if stripes > 2
- # if odd(stripes)
- # if onep(stripes)
- # if contactspush > 0
-
- # *********************************************************
- # GatPoly parts
-
- for i in range(1, int(stripes)+1) :
- xpos2 = xpos1+w
- ypos2 = ypos1+l*dir
- # -----------------
- # draw long res line
- if i == 1 :
- dbCreateRect(self, bodypolylayer, Box(xpos1, ypos1-contactpush*dir, xpos2, ypos2))
- ihpAddThermalResLayer(self, Box(xpos1, ypos1-contactpush*dir, xpos2, ypos2), True, Cell)
- dbCreateRect(self, psdlayer, Box(xpos1-psdover, ypos1-contactpush*dir, xpos2+psdover, ypos2))
- dbCreateRect(self, nsdlayer, Box(xpos1-psdover, ypos1-contactpush*dir, xpos2+psdover, ypos2))
- else :
- # Last Stripe has to be longer
- if i == stripes :
- dbCreateRect(self, bodypolylayer, Box(xpos1, ypos1, xpos2, ypos2+(contactpush+lcor)*dir))
- ihpAddThermalResLayer(self, Box(xpos1, ypos1, xpos2, ypos2+(contactpush+lcor)*dir), True, Cell)
- dbCreateRect(self, psdlayer, Box(xpos1-psdover, ypos1, xpos2+psdover, ypos2+(contactpush+lcor)*dir))
- dbCreateRect(self, nsdlayer, Box(xpos1-psdover, ypos1, xpos2+psdover, ypos2+(contactpush+lcor)*dir))
- else :
- # all other stripes
- dbCreateRect(self, bodypolylayer, Box(xpos1, ypos1, xpos2, ypos2))
- ihpAddThermalResLayer(self, Box(xpos1, ypos1, xpos2, ypos2), True, Cell)
-
-
- if i < stripes : # connectionparts
- ypos1 = ypos2+w*dir
- xpos2 = xpos1+2*w+ps
- ypos2 = ypos1-w*dir
- dir *= -1
- dbCreateRect(self, bodypolylayer, Box(xpos1, ypos1, xpos2, ypos2))
- ihpAddThermalResLayer(self, Box(xpos1, ypos1, xpos2, ypos2), True, Cell)
- xpos1 = xpos1+w+ps
- ypos1 = ypos2
- # for
-
- # x1,y1,x2,y2,dir are updated, so the code of first contact can be used
- # (Except Pin Informations)
-
- # *********************************************************
- # TOP Contact Area
- #draw res contact -> realise Overlap with dogbone, to keep burdens
- # set x1 x2 to dogbone,:
- #contact has to be out of symetric
-
- if asymcont :
- xpos1 = xpos1
- xpos2 = xpos2+contoverlay+contoverlay
- else : # leave, where ist is
- xpos1 = xpos1-contoverlay
- xpos2 = xpos2+contoverlay
-
- # *********************************************************
- # pSD and SalBlock
- # between res and cont
- dbCreateRect(self, contpolylayer, Box(xpos1, ypos2+(lcor+contactpush)*dir, xpos2, ypos2+(lcor+contactpush+poly_cont_len+li_salblock)*dir))
- # *********************************************************
- # 26.6.08 GG: nSD/pSD added
- dbCreateRect(self, psdlayer, Box(xpos1-psdover, ypos2+(lcor+contactpush-psdover)*dir, xpos2+psdover, ypos2+(lcor+contactpush+poly_cont_len+li_salblock+psdover)*dir))
- dbCreateRect(self, nsdlayer, Box(xpos1-psdover, ypos2+(lcor+contactpush-psdover)*dir, xpos2+psdover, ypos2+(lcor+contactpush+poly_cont_len+li_salblock+psdover)*dir))
- # 11.02.09 GGa added EXTBlockLayer
- dbCreateRect(self, extBlocklayer, Box(xpos1-psdover, ypos2+(lcor+contactpush-psdover)*dir, xpos2+psdover, ypos2+(lcor+contactpush+poly_cont_len+li_salblock+psdover)*dir))
-
- # *********************************************************
- # contacts
- # 10.12.07 GGa added internal code block
- if drawbar :
- # can only be in internal version
- lastCont = dbCreateRect(self, locintlayer, Box(xpos1+contbar_poly_over, ypos2+(lcor+contactpush+li_salblock+li_poly_over)*dir, xpos2-contbar_poly_over, ypos2+(lcor+contactpush+consize+li_salblock+li_poly_over)*dir))
- else :
- for i in range(ncont) :
- lastCont = dbCreateRect(self, locintlayer, Box(xpos1+polyover+distr+i*distc, ypos2+(lcor+contactpush+li_salblock+li_poly_over)*dir, xpos1+polyover+distr+i*distc+consize, ypos2+(lcor+contactpush+consize+li_salblock+li_poly_over)*dir))
-
- # 26.6.08 GG: new metal block
- # *********************************************************
- # Metal and pin
- bBox = lastCont.getBBox()
- dbCreateRect(self, metlayer, Box(bBox.left-endcap, bBox.bottom-endcap, bBox.right+endcap, bBox.top+endcap))
-
- MkPin(self, 'MINUS', 2, Box(bBox.left-endcap, bBox.bottom-endcap, bBox.right+endcap, bBox.top+endcap), metlayer)
-
- # *********************************************************
- # draw the label
- # GGa 08.05.06 added lcalc
- # create virtuel l for CbResCalc
- lcalc = (l*stripes+contactpush*2+lcor)/stripes
- resistance = CbResCalc('R', 0, lcalc*1e-6, w*1e-6, b, ps*1e-6, Cell)
- labeltext = 'rpnd r={0:.3f}'.format(resistance)
- labelpos = Point(w/2, l/2)
- labelheight = 0.1
- if w > l :
- rot = 'R0'
- else :
- rot = 'R90'
-
- lbl = dbCreateLabel(self, textlayer, labelpos, labeltext, 'centerCenter', rot, Font.EURO_STYLE, labelheight)
- lsizex = lbl.bbox.getWidth()
- lsizey = lbl.bbox.getHeight()
- scale = min(w/lsizex, (l+2*poly_cont_len)/lsizey)
- #SetSGq(lbl scale height)
diff --git a/ihp-sg13g2/libs.tech/pycell/rppd_code.py b/ihp-sg13g2/libs.tech/pycell/rppd_code.py
deleted file mode 100644
index 9898ed64..00000000
--- a/ihp-sg13g2/libs.tech/pycell/rppd_code.py
+++ /dev/null
@@ -1,476 +0,0 @@
-########################################################################
-#
-# Copyright 2023 IHP PDK Authors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-########################################################################
-__version__ = '$Revision: #3 $'
-
-from cni.dlo import *
-from thermal import *
-from geometry import *
-from utility_functions import *
-
-import math
-
-class rppd(DloGen):
-
- @classmethod
- def defineParamSpecs(cls, specs):
- # define parameters and default values
- techparams = specs.tech.getTechParams()
-
- SG13_TECHNOLOGY = techparams["techName"]
- suffix = ""
- if 'SG13G2' in SG13_TECHNOLOGY :
- suffix = 'G2'
- if 'SG13G3' in SG13_TECHNOLOGY :
- suffix = 'G3'
-
- CDFVersion = techparams['CDFVersion']
- model = techparams['rppd_model']
- rspec = techparams['rppd'+suffix+'_rspec']
- rkspec = techparams['rppd_rkspec']
- rzspec = techparams['rppd_rzspec']
- defL = techparams['rppd_defL']
- defW = techparams['rppd_defW']
- defB = techparams['rppd_defB']
- defPS = techparams['rppd_defPS']
- minL = techparams['rppd_minL']
- minW = techparams['rppd_minW']
- minPS = techparams['rppd_minPS']
- eps = techparams['epsilon2']
-
- specs('cdf_version', CDFVersion, 'CDF Version')
- specs('Display', 'Selected', 'Display', ChoiceConstraint(['All', 'Selected']))
- specs('Calculate', 'l', 'Calculate', ChoiceConstraint(['R', 'w', 'l']))
- specs('Recommendation', 'No', 'Recommendation', ChoiceConstraint(['Yes', 'No']))
- specs('model', model, 'Model name')
-
- resistance = CbResCalc('R', 0, defL, defW, defB, defPS, 'rppd')
- specs('R', eng_string(resistance), 'R')
-
- specs('w', defW, 'Width')
- specs('l', defL, 'Length')
- specs('b', defB, 'Bends')
- specs('ps', defPS, 'Poly Space')
-
- imax = CbResCurrent(Numeric(defW), eps, 'rppd'+suffix)
- specs('Imax', imax, 'Imax')
- specs('bn', 'sub!', 'Bulk node connection')
- specs('Wmin', minW, 'Wmin')
- specs('Lmin', minL, 'Lmin')
- specs('PSmin', minPS, 'PSmin')
- specs('Rspec', rspec, 'Rspec [Ohm/sq]')
- specs('Rkspec', rkspec, 'Rkspec [Ohm/cont]')
- specs('Rzspec', rzspec, 'Rzspec [Ohm*m]')
- specs('tc1', '170e-6', 'Temperature coefficient 1')
- specs('tc2', '0.4e-6', 'Temperature coefficient 2')
- specs('PWB', 'No', 'PWell Blockage', ChoiceConstraint(['Yes', 'No']))
- specs('m', '1', 'Multiplier')
- specs('trise', '0.0', 'Temp rise from ambient')
-
- def setupParams(self, params):
- self.grid = self.tech.getGridResolution()
- self.techparams = self.tech.getTechParams()
- self.epsilon = self.techparams['epsilon1']
-
- self.b = fix(int(params['b']) + self.epsilon)
- self.w = Numeric(params['w'])*1e6
- self.l = Numeric(params['l'])*1e6
- self.ps = Numeric(params['ps'])*1e6
- #self.resistance = Numeric(params['R'])
-
- def genLayout(self):
- psdlayer = Layer('pSD')
- textlayer = Layer('TEXT')
- metlayer = Layer('Metal1')
- locintlayer = Layer('Cont')
- sallayer = Layer('SalBlock')
- contpolylayer = Layer('GatPoly')
- bodypolylayer = Layer('PolyRes')
- extBlocklayer = Layer('EXTBlock')
- metlayer_pin = Layer('Metal1', 'pin')
-
- lcor = 0.0
- resshort = 0.0
- gridnumber = 0.0
- contoverlay = 0.0
- contactpush = 0.0
- li_poly_over = 0.0
-
- internalCode = True
- Cell = self.__class__.__name__
-
- grid = self.techparams['grid']
- endcap = self.techparams['M1_c1']
- consize = self.techparams['Cnt_a']
- conspace = self.techparams['Cnt_b']
- polyover = self.techparams['Cnt_d']
- psdover1 = self.techparams['pSD_n']
- psdNotch = self.techparams['pSD_b']
- psdover1 = self.techparams['Rppd_b']
- li_salblock = self.techparams['Sal_e']
- salover = self.techparams['Sal_c']
- salspace = self.techparams['Sal_d']
- psdover = self.techparams['Rppd_b']
- contbar_min_len = self.techparams['CntB_a1']
- contbar_poly_over = self.techparams['CntB_d']
- metover = self.techparams[Cell + '_met_over_cont']
- poly_cont_len = consize + polyover # techParam('Cnt_a')+techParam('Cnt_d')
- wmin = eng_string_to_float(self.techparams[Cell + '_minW'])*1e6
- lmin = eng_string_to_float(self.techparams[Cell + '_minL'])*1e6
- psmin = eng_string_to_float(self.techparams[Cell + '_minPS'])*1e6
-
- wcontact = self.w
- drawbar = False
-
- # Resistor gets 2 Pins, procedure needs '3' to understand '2'
- dbReplaceProp(self, 'pin#', 3)
-
- if internalCode :
- if wcontact-2*contbar_poly_over + self.epsilon >= contbar_min_len:
- drawbar = True
-
- if psdover1 > psdover:
- psdover = psdover1
-
- # dogbone has to be on grid, so make difference in gridsteps
- contoverlay = wcontact - self.w
- if contoverlay > 0:
- # is dogbone: keep on checking for lay on grid
- # Distance per side
- contoverlay = contoverlay/2
- # gridpoints per side?
- gridnumber = contoverlay/self.grid
- gridnumber = round(gridnumber + self.epsilon)
- # need more gridpoints to lay on grip?
- if (gridnumber*grid*100) < contoverlay:
- gridnumber += 1
-
- # set contoverlay to new length
- contoverlay = gridnumber*grid
- wcontact = w+2*contoverlay
-
- # Insertionpoint for contact is at (0-contoverlay:0)
- xpos1 = 0-contoverlay
- ypos1 = 0
- xpos2 = xpos1+wcontact
- ypos2 = 0
- dir = -1
- stripes = self.b+1
-
- if self.w < wmin-self.epsilon:
- self.w = wmin
- hiGetAttention()
- print('Width < '+str(wmin))
-
- if self.l < lmin-self.epsilon:
- self.l = lmin
- hiGetAttention()
- print('Length < '+str(lmin))
-
- if self.ps < psmin-self.epsilon:
- ps = psmin
- hiGetAttention()
- print('poly space < '+str(psmin))
-
- # set contacts out of resitor-square?
- lcor = 0.0
- lsumnew = 0.0
- lsumold = 0.0
-
- if GridFix(self.ps) < GridFix((salover+salspace)) and stripes>2:
- contactpush = contactpush+self.w+salover
- resshort = GridFix((2*contactpush)/stripes)+grid
- lsumold = self.l*stripes
- self.l = self.l-resshort
- lsumnew = self.l*stripes+contactpush*2
- lcor = lsumold-lsumnew
-
- # Check, if contacts have to be asymmetric
- # Some cases need to have asym contacts:
- # 2 stripes and low ps and are not pushed out of resistor
- if zerop(contactpush) is 1 and self.ps-2*contoverlay <= psmin and onep(self.b) is 1:
- asymcont = True
- else :
- asymcont = False
-
- # set all parts up to get 0:0 at beginning of resistorbody:
- ypos1 = ypos1-contactpush*dir
- ypos2 = ypos2-contactpush*dir
-
- # **************************************************************
- # draw res contact #1 (bottom)
- # **************************************************************
- # draw res contact #1 -> realise Overlap by dogbone to keep burdens, when needed
- # set xpos1/xpos2 to left for contacts when Stripes>1 and ps<
-
- if asymcont :
- xpos1 = xpos1-contoverlay
- xpos2 = xpos2-contoverlay
-
- # **************************************************************
- # Gat PolyPart of bottom ContactArea
- # gatpolyarea between salBlock and contact
- dbCreateRect(self, contpolylayer, Box(xpos1, ypos1+contactpush*dir, xpos2,
- ypos2+(contactpush+li_salblock)*dir))
- # gatpolyarea right, left and under contact
- dbCreateRect(self, contpolylayer, Box(xpos1, ypos1+(contactpush+li_salblock)*dir,
- xpos2, ypos2+(contactpush+poly_cont_len+li_salblock)*dir))
- # **************************************************************
- # pSD Part of bottom ContactArea
- if contactpush == 0.0:
- dbCreateRect(self, psdlayer, Box(xpos1-psdover, ypos2+contactpush*dir,
- xpos2+psdover, ypos2+(li_salblock+psdover+poly_cont_len+contactpush)*dir))
- else :
- dbCreateRect(self, psdlayer, Box(xpos1-psdover, ypos2+(contactpush-salover+psdover)*dir,
- xpos2+psdover, ypos2+(li_salblock+psdover+poly_cont_len+contactpush)*dir))
-
- # **************************************************************
- # EXTBlock
- # draw ExtBlock for bottom Cont Area
- dbCreateRect(self, extBlocklayer, Box(xpos1-psdover, ypos2+contactpush*dir,
- xpos2+psdover, ypos2+(li_salblock+psdover+poly_cont_len+contactpush)*dir))
-
- # **************************************************************
- # contact area
- # number parallel contacts ncont, distance distc:
- wcon = wcontact-2.0*polyover
- distc = consize+conspace;
- ncont = math.floor((wcon+conspace)/distc + self.epsilon)
- if ncont < 1:
- ncont = 1
-
- distr = GridFix((wcon-ncont*distc+conspace)*0.5);
-
- # draw contact
- # block for internal PCell
- if drawbar :
- dbCreateRect(self, locintlayer, Box(xpos1+contbar_poly_over, ypos2+(contactpush+li_salblock+li_poly_over)*dir,
- xpos2-contbar_poly_over, ypos2+(contactpush+consize+li_salblock+li_poly_over)*dir))
- else :
- for i in range(int(ncont)):
- dbCreateRect(self, locintlayer, Box(xpos1+polyover+distr+i*distc, ypos2+(contactpush+li_salblock+li_poly_over)*dir,
- xpos1+polyover+distr+i*distc+consize, ypos2+(contactpush+consize+li_salblock+li_poly_over)*dir))
-
- # **************************************************************
- # Metal and pin
- ypos1 = ypos2+(contactpush+li_salblock+li_poly_over-metover)*dir
- ypos2 = ypos2+(contactpush+consize+li_salblock+li_poly_over+metover)*dir
- # new metal block
- dbCreateRect(self, metlayer, Box(xpos1+contbar_poly_over-endcap, ypos1, xpos2-contbar_poly_over+endcap, ypos2))
-
- MkPin(self, 'PLUS', 1, Box(xpos1+contbar_poly_over-endcap, ypos1,
- xpos2-contbar_poly_over+endcap, ypos2), metlayer_pin)
-
- # set xpos1/xpos2 back to right for resistorbody
- if asymcont :
- xpos1=xpos1+contoverlay
- xpos2=xpos2+contoverlay
-
- ypos1 = 0.0 - contactpush*dir
-
- # **************************************************************
- # resistorbody:
- # **************************************************************
- dir = 1;
- xpos1 = xpos1+contoverlay
- xpos2 = xpos1+self.w-contoverlay;
- ypos2 = ypos1+(self.l-resshort)*dir;
- # **************************************************************
- # normal contatcs or outlying contacts?
- if contactpush > 0 : # Contacts are out of Resitorsquare->draw rectangle
- # **************************************************************
- # draw one salblock and pSD over resistor and bends
- # Sal Block over stripes and bends
- dbCreateRect(self, sallayer, Box(xpos1-salover, ypos1-contactpush,
- xpos1+stripes*(self.w+self.ps)-self.ps+salover, ypos1+self.l+self.w+salover))
-
- dbCreateRect(self, extBlocklayer, Box(xpos1-salover, ypos1-contactpush,
- xpos1+stripes*(self.w+self.ps)-self.ps+salover, ypos1+self.l+self.w+salover))
- # pSD over Stripes and bends
- # lower bends are salover obove 0.0, need to have psdover, so this psd has to be psdover-salover under 0.0
- dbCreateRect(self, psdlayer, Box(xpos1-psdover, ypos1-contactpush+salover-psdover,
- xpos1+stripes*(self.w+self.ps)-self.ps+psdover, ypos1+self.l+self.w+psdover))
-
- yyy = ypos1-contactpush+salover-psdover
- # maybe draw extra salblock for longer last stripe
- if lcor > 0:
- if oddp(stripes) :
- # draw new rect topright
- dbCreateRect(self, sallayer, Box(xpos1+stripes*(self.w+self.ps)-self.ps-self.w-salover, ypos1+self.l+self.w+salover,
- xpos1+stripes*(self.w+self.ps)-self.ps+salover, ypos1+self.l+self.w+salover+lcor))
- dbCreateRect(self, extBlocklayer, Box(xpos1+stripes*(self.w+self.ps)-self.ps-self.w-salover, ypos1+self.l+self.w+salover,
- xpos1+stripes*(self.w+self.ps)-self.ps+salover, ypos1+self.l+self.w+salover+lcor))
- dbCreateRect(self, psdlayer, Box(xpos1+stripes*(self.w+self.ps)-self.ps-self.w-psdover, ypos1+self.l+self.w+psdover,
- xpos1+stripes*(self.w+self.ps)-self.ps+psdover, ypos1+self.l+self.w+salover+lcor))
-
- else : # draw new rect bottom right
- dbCreateRect(self, sallayer, Box(xpos1+stripes*(self.w+self.ps)-self.ps-self.w-salover, ypos1-contactpush-lcor,
- xpos1+stripes*(self.w+self.ps)-self.ps+salover, ypos1-contactpush))
- dbCreateRect(self, extBlocklayer, Box(xpos1+stripes*(self.w+self.ps)-self.ps-self.w-salover, ypos1-contactpush-lcor,
- xpos1+stripes*(self.w+self.ps)-self.ps+salover, ypos1-contactpush))
- dbCreateRect(self, psdlayer, Box(xpos1+stripes*(self.w+self.ps)-self.ps-self.w-psdover, ypos1-contactpush-lcor,
- xpos1+stripes*(self.w+self.ps)-self.ps+psdover, yyy))
- else : # normal SalBlock, Conts in Resistorsquare
- # draw salblock and pSD over resistor
- dbCreateRect(self, sallayer, Box(xpos1-salover, ypos1, xpos1+stripes*(self.w+self.ps)-self.ps+salover, ypos2))
- dbCreateRect(self, extBlocklayer, Box(xpos1-salover, ypos1, xpos1+stripes*(self.w+self.ps)-self.ps+salover, ypos2))
- dbCreateRect(self, psdlayer, Box(xpos1-psdover, ypos1, xpos1+stripes*(self.w+self.ps)-self.ps+psdover, ypos2))
-
- if stripes > 1 : # cover Bends
- if oddp(stripes) : # odd stripesnumber
- dbCreateRect(self, sallayer, Box(xpos1-salover, ypos2,
- xpos1+(stripes-1)*(self.w+self.ps)-ps+salover, ypos2+self.w+salover))
- dbCreateRect(self, extBlocklayer, Box(xpos1-salover, ypos2,
- xpos1+(stripes-1)*(self.w+self.ps)-self.ps+salover, ypos2+self.w+salover))
- dbCreateRect(self, sallayer, Box(xpos1+self.w+self.ps-salover, ypos1,
- xpos1+stripes*(self.w+self.ps)-self.ps+salover, ypos1-self.w-salover))
- dbCreateRect(self, extBlocklayer, Box(xpos1+self.w+self.ps-salover, ypos1,
- xpos1+stripes*(self.w+self.ps)-self.ps+salover, ypos1-self.w-salover))
- dbCreateRect(self, psdlayer, Box(xpos1-psdover, ypos2-psdover,
- xpos1+(stripes-1)*(self.w+self.ps)-self.ps+psdover, ypos2+self.w+psdover))
- dbCreateRect(self, psdlayer, Box(xpos1+self.w+self.ps-psdover, ypos1,
- xpos1+stripes*(self.w+self.ps)-self.ps+psdover, ypos1-self.w-psdover))
- else : # unodd stripesnumber
- dbCreateRect(self, sallayer, Box(xpos1-salover, ypos2,
- xpos1+stripes*(self.w+self.ps)-self.ps+salover, ypos2+self.w+salover))
- dbCreateRect(self, extBlocklayer, Box(xpos1-salover, ypos2,
- xpos1+stripes*(self.w+self.ps)-self.ps+salover, ypos2+self.w+salover))
- dbCreateRect(self, psdlayer, Box(xpos1-psdover, ypos2,
- xpos1+stripes*(self.w+self.ps)-self.ps+psdover, ypos2+self.w+psdover))
-
- if stripes > 2:
- dbCreateRect(self, sallayer, Box(xpos1+self.w+self.ps-salover, ypos1,
- xpos1+(stripes-1)*(self.w+self.ps)-self.ps+salover, ypos1-self.w-salover))
- dbCreateRect(self, extBlocklayer, Box(xpos1+self.w+self.ps-salover, ypos1,
- xpos1+(stripes-1)*(self.w+self.ps)-self.ps+salover, ypos1-self.w-salover))
- dbCreateRect(self, psdlayer, Box(xpos1+self.w+self.ps-psdover, ypos1,
- xpos1+(stripes-1)*(self.w+self.ps)-self.ps+psdover, ypos1-self.w-psdover))
-
- # **************************************************************
- # Resistorbody GatPoly part
- for j in range(int(stripes)):
- i = j + 1
- xpos2=xpos1+self.w;
- ypos2=ypos1+self.l*dir;
- #-----------------
- # draw long res line
- if i == 1 : # first part has to be longer
- dbCreateRect(self, bodypolylayer, Box(xpos1, ypos1-contactpush*dir, xpos2, ypos2))
- ihpAddThermalResLayer(self, Box(xpos1, ypos1-contactpush*dir, xpos2, ypos2), True, Cell);
- else :
- if i == stripes : # Last Stripe has to be longer
- dbCreateRect(self, bodypolylayer, Box(xpos1, ypos1, xpos2, ypos2+(contactpush+lcor)*dir))
- ihpAddThermalResLayer(self, Box(xpos1, ypos1, xpos2, ypos2+(contactpush+lcor)*dir), True, Cell);
- else : # all other stripes
- dbCreateRect(self, bodypolylayer, Box(xpos1, ypos1, xpos2, ypos2))
- ihpAddThermalResLayer(self, Box(xpos1, ypos1, xpos2, ypos2), True, Cell);
-
- if i < stripes : # connectionparts
- ypos1 = ypos2+self.w*dir
- xpos2 = xpos1+2*self.w+self.ps
- ypos2 = ypos1-self.w*dir
- dir = dir*-1;
-
- # draw res bend
- dbCreateRect(self, bodypolylayer, Box(xpos1, ypos1, xpos2, ypos2))
- ihpAddThermalResLayer(self, Box(xpos1, ypos1, xpos2, ypos2), True, Cell);
-
- xpos1 = xpos1+self.w+self.ps
- ypos1 = ypos2
-
- # **************************************************************
- # contact area (Top)
- # **************************************************************
- if asymcont : # contact has to be out of symetric
- xpos1 = xpos1
- xpos2 = xpos2+contoverlay+contoverlay
- else :
- xpos1 = xpos1-contoverlay
- xpos2 = xpos2+contoverlay
- # **************************************************************
- # pSD and SalBlock
- # between res and cont
- dbCreateRect(self, contpolylayer, Box(xpos1, ypos2+(lcor+contactpush)*dir,
- xpos2, ypos2+(lcor+contactpush+li_salblock)*dir))
- # cont
- dbCreateRect(self, contpolylayer, Box(xpos1, ypos2+(lcor+contactpush+li_salblock)*dir,
- xpos2, ypos2+(lcor+contactpush+poly_cont_len+li_salblock)*dir))
- # psd
- dbCreateRect(self, psdlayer, Box(xpos1-psdover, ypos2+(lcor+contactpush)*dir,
- xpos2+psdover, ypos2+(lcor+contactpush+li_salblock+psdover+poly_cont_len)*dir))
-
- # **************************************************************
- # EXTBlock
- # draw ExtBlock for bottom Cont Area
- dbCreateRect(self, extBlocklayer, Box(xpos1-psdover, ypos2+(lcor+contactpush)*dir,
- xpos2+psdover, ypos2+(lcor+contactpush+li_salblock+psdover+poly_cont_len)*dir))
-
- # **************************************************************
- # contacts
- # codeblock for internal PCel
- if drawbar : # can only be in internal code
- dbCreateRect(self, locintlayer, Box(xpos1+contbar_poly_over, ypos2+(contactpush+li_salblock+li_poly_over+lcor)*dir,
- xpos2-contbar_poly_over, ypos2+(contactpush+consize+li_salblock+li_poly_over+lcor)*dir))
- else :
- for i in range(ncont):
- dbCreateRect(self, locintlayer, Box(xpos1+polyover+distr+i*distc,
- ypos2+(lcor+contactpush+li_salblock+li_poly_over)*dir,
- xpos1+polyover+distr+i*distc+consize,
- ypos2+(lcor+contactpush+consize+li_salblock+li_poly_over)*dir))
- # **************************************************************
- # Metal and Pin
-
- # metal block
- dbCreateRect(self, metlayer, Box(xpos1+contbar_poly_over-endcap,
- ypos2+(contactpush+li_salblock+li_poly_over-metover+lcor)*dir,
- xpos2-contbar_poly_over+endcap,
- ypos2+(contactpush+consize+li_salblock+li_poly_over+metover+lcor)*dir))
-
- MkPin(self, 'MINUS', 2, Box(xpos1+contbar_poly_over-endcap, ypos2+(contactpush+li_salblock+li_poly_over-metover+lcor)*dir,
- xpos2-contbar_poly_over+endcap, ypos2+(contactpush+consize+li_salblock+li_poly_over+metover+lcor)*dir), metlayer_pin)
-
- # fill notches in pas layer
- if (self.ps-2.0*psdover < psdNotch) and (self.ps-2.0*psdover > 0.0):
- if stripes > 1:
- dbCreateRect(self, psdlayer, Box(self.w+psdover, 0, self.w+self.ps-psdover, -li_salblock-poly_cont_len-psdover))
-
- if stripes > 2:
- xpos1 = xpos1 - self.w - self.ps
- dbCreateRect(self, psdlayer, Box(xpos1+w+psdover, ypos2, xpos1+self.w+self.ps-psdover, ypos2+dir*(li_salblock+poly_cont_len+psdover)))
-
- # **************************************************************
- # now draw the label
- # lcalc
- # create virtuel l for CbResCalc
- lcalc = (self.l*stripes+contactpush*2+lcor)/stripes
- resistance = CbResCalc('R', 0, lcalc*1e-6, self.w*1e-6, self.b, self.ps*1e-6, Cell)
- labeltext = 'rpnd r={0:.3f}'.format(resistance)
-
- labelpos = Point(self.w/2, self.l/2)
-
- # label scaling. Should always fit into bBox of device
- labelheight = 0.1
- if self.w > self.l:
- rot = 'R0'
- else :
- rot = 'R90'
-
- lbl = dbCreateLabel(self, textlayer, labelpos, labeltext, 'centerCenter', rot, Font.EURO_STYLE, labelheight)
- lsizex = lbl.bbox.getWidth()
- lsizey = lbl.bbox.getHeight()
- scale = min(self.w/lsizex, (self.l+2*poly_cont_len)/lsizey)
- #SetSGq(lbl scale height)
diff --git a/ihp-sg13g2/libs.tech/pycell/rsil_code.py b/ihp-sg13g2/libs.tech/pycell/rsil_code.py
deleted file mode 100644
index 2797a253..00000000
--- a/ihp-sg13g2/libs.tech/pycell/rsil_code.py
+++ /dev/null
@@ -1,339 +0,0 @@
-########################################################################
-#
-# Copyright 2023 IHP PDK Authors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-########################################################################
-__version__ = '$Revision: #3 $'
-
-from cni.dlo import *
-from geometry import *
-from thermal import *
-from utility_functions import *
-
-import math
-
-class rsil(DloGen):
-
- @classmethod
- def defineParamSpecs(self, specs):
- # define parameters and default values
- techparams = specs.tech.getTechParams()
-
- SG13_TECHNOLOGY = techparams["techName"]
- suffix = ""
- if 'SG13G2' in SG13_TECHNOLOGY :
- suffix = 'G2'
- if 'SG13G3' in SG13_TECHNOLOGY :
- suffix = 'G3'
-
- CDFVersion = techparams['CDFVersion']
- model = techparams['rsil_model']
- rspec = techparams['rsil'+suffix+'_rspec']
- rkspec = techparams['rsil_rkspec']
- rzspec = techparams['rsil_rzspec']
- defL = techparams['rsil_defL']
- defW = techparams['rsil_defW']
- defB = techparams['rsil_defB']
- defPS = techparams['rsil_defPS']
- minL = techparams['rsil_minL']
- minW = techparams['rsil_minW']
- minPS = techparams['rsil_minPS']
- eps = techparams['epsilon2']
- if 'SG13G2' in SG13_TECHNOLOGY :
- defR = '17.248'
- else :
- defR = '16.923'
-
- specs('cdf_version', CDFVersion, 'CDF Version')
- specs('Display', 'Selected', 'Display', ChoiceConstraint(['All', 'Selected']))
- specs('Calculate', 'l', 'Calculate', ChoiceConstraint(['R', 'w', 'l']))
- specs('Recommendation', 'No', 'Recommendation', ChoiceConstraint(['Yes', 'No']))
- specs('model', model, 'Model name')
-
- resistance = CbResCalc('R', 0, defL, defW, defB, defPS, 'rsil')
- specs('R', eng_string(resistance), 'R')
-
- specs('w', defW, 'Width')
- specs('l', defL, 'Length')
- specs('b', defB, 'Bends')
- specs('ps', defPS, 'Poly Space')
-
- imax = CbResCurrent(Numeric(defW), eps, 'rsil'+suffix)
- specs('Imax', imax, 'Imax')
- specs('bn', 'sub!', 'Bulk node connection')
- specs('Wmin', minW, 'Wmin')
- specs('Lmin', minL, 'Lmin')
- specs('PSmin', minPS, 'PSmin')
- specs('Rspec', rspec, 'Rspec [Ohm/sq]')
- specs('Rkspec', rkspec, 'Rkspec [Ohm/cont]')
- specs('Rzspec', rzspec, 'Rzspec [Ohm*m]')
- specs('tc1', '3100e-6', 'Temperature coefficient 1')
- specs('tc2', '0.30e-6', 'Temperature coefficient 2')
- specs('PWB', 'No', 'PWell Blockage', ChoiceConstraint(['Yes', 'No']))
- specs('m', '1', 'Multiplier')
- specs('trise', '0.0', 'Temp rise from ambient')
-
- def setupParams(self, params):
- # process parameter values entered by user
- self.params = params
- self.l = Numeric(params['l'])
- self.w = Numeric(params['w'])
- self.b = int(params['b'])
- self.ps = Numeric(params['ps'])
- self.resistance = Numeric(params['R'])
-
- def genLayout(self):
- l = self.l
- w = self.w
- b = self.b
- ps = self.ps
-
- self.techparams = self.tech.getTechParams()
- self.epsilon = self.techparams['epsilon1']
- self.grid = self.tech.getGridResolution() # needed for Dogbone
-
- contpolylayer = 'GatPoly'
- bodypolylayer = 'PolyRes'
- reslayer = 'RES'
- extBlocklayer = 'EXTBlock'
- locintlayer = 'Cont'
- metlayer = 'Metal1'
- textlayer = 'TEXT'
-
- internalCode = True
- Cell = self.__class__.__name__
-
- metover = self.techparams[Cell+'_met_over_cont']
- consize = self.techparams['Cnt_a'] # min and max size of Cont
- conspace = self.techparams['Cnt_b'] # min ContSpace
- polyover = self.techparams['Cnt_d'] # min GatPoly enclosure of Cont
- li_poly_over = self.techparams['Rsil_b'] # min RES Spacing to Cont
- ext_over = self.techparams['Rsil_e'] # min EXTBlock enclosure of RES
- endcap = self.techparams['M1_c1']
- poly_cont_len = li_poly_over+consize+polyover # end of RES to end of poly
- contbar_poly_over = self.techparams['CntB_d'] # min length of LI-Bar
- contbar_min_len = self.techparams['CntB_a1'] # min length of LI-Bar
-
- wmin = eng_string_to_float(self.techparams[Cell+'_minW'])*1e6 # min Width
- lmin = eng_string_to_float(self.techparams[Cell+'_minL'])*1e6 # Min Length
- psmin = eng_string_to_float(self.techparams[Cell+'_minPS'])*1e6 # min PolySpace
-
- gridnumber = 0.0
- contoverlay = 0.0
-
- #dbReplaceProp(pcCV, 'pin#', 'int', 3)
- l = Numeric(l)*1e6
- w = Numeric(w)*1e6
- b = fix(b + self.epsilon)
- ps = Numeric(ps)*1e6
- wcontact = w
- drawbar = False
-
- if internalCode == True :
- if wcontact-2*contbar_poly_over + self.epsilon >= contbar_min_len :
- drawbar = True
-
- if metover < endcap :
- metover = endcap
-
- contoverlay = wcontact - w
- if contoverlay > 0 :
- contoverlay = contoverlay/2
- gridnumber = contoverlay/grid
- gridnumber = round(gridnumber + self.epsilon)
- if (gridnumber*grid*100) < contoverlay :
- gridnumber += 1
-
- contoverlay = gridnumber*grid
- wcontact = w+2*contoverlay
-
- # insertion point is at (0,0) - contoverlay
- xpos1 = 0-contoverlay
- ypos1 = 0
- xpos2 = xpos1+wcontact
- ypos2 = 0
- Dir = -1
- stripes = b+1
- if w < wmin-self.epsilon :
- w = wmin
- hiGetAttention()
- print('Width < '+str(wmin))
-
- if l < lmin-self.epsilon :
- l = lmin
- hiGetAttention()
- print('Length < '+str(lmin))
-
- if ps < psmin-self.epsilon :
- ps = psmin
- hiGetAttention()
- print('poly space < '+str(psmin))
-
- # **************************************************************
- # draw res contact #1 (bottom)
- # **************************************************************
-
- # set xpos1/xpos2 to left for contacts
- xpos1 = xpos1-contoverlay
- xpos2 = xpos2-contoverlay
- # Gat PolyPart of bottom ContactArea
- dbCreateRect(self, contpolylayer, Box(xpos1, ypos1, xpos2, ypos2+poly_cont_len*Dir))
-
- # number parallel conts: ncont, distance: distc:
- wcon = wcontact-2.0*polyover
- distc = consize+conspace
- ncont = fix((wcon+conspace)/distc + self.epsilon)
- if ncont < 1 :
- ncont = 1
-
- distr = GridFix((wcon-ncont*distc+conspace)*0.5)
-
- # **************************************************************
- # draw Cont squares or bars of bottom ContactArea
- # LI and Metal
- # always dot contacts, autogenerated LI
- if drawbar == True :
- dbCreateRect(self, locintlayer, Box(xpos1+contbar_poly_over, ypos2+li_poly_over*Dir, xpos2-contbar_poly_over, ypos2+(consize+li_poly_over)*Dir))
- else :
- for i in range(ncont) :
- dbCreateRect(self, locintlayer, Box(xpos1+polyover+distr+i*distc, ypos2+li_poly_over*Dir, xpos1+polyover+distr+i*distc+consize, ypos2+(consize+li_poly_over)*Dir))
-
-
- # **************************************************************
- # draw MetalRect and Pin of bottom Contact Area
- ypos1 = ypos2+(li_poly_over-metover)*Dir
- ypos2 = ypos2+(consize+li_poly_over+metover)*Dir
- dbCreateRect(self, metlayer, Box(xpos1+contbar_poly_over-endcap, ypos1, xpos2-contbar_poly_over+endcap, ypos2))
- MkPin(self, 'PLUS', 1, Box(xpos1+contbar_poly_over-endcap, ypos1, xpos2-contbar_poly_over+endcap, ypos2), metlayer)
-
- # **************************************************************
- # Resistorbody
- # **************************************************************
- Dir = 1
- # set xpos1 & xpos2 correct with contoverlay
- xpos1 = xpos1+contoverlay
- ypos1 = 0
- xpos2 = xpos1+w-contoverlay
- ypos2 = ypos1+l*Dir
-
- # **************************************************************
- # GatPoly and PolyRes
- # major structures ahead -> here: not applicable
- for i in range(1, int(stripes)+1) :
- xpos2 = xpos1+w
- ypos2 = ypos1+l*Dir
- # draw long res line
- # when dogbone and bends>0 shift long res line to inner contactline
- if stripes > 1 :
- if i == 1 :
- # fist stripe move to right
- xpos1 = xpos1+contoverlay
- xpos2 = xpos2+contoverlay
-
- # all vertical ResPoly and GatPoly Parts
- dbCreateRect(self, bodypolylayer, Box(xpos1, ypos1, xpos2, ypos2))
- dbCreateRect(self, reslayer, Box(xpos1, ypos1, xpos2, ypos2))
-
- ihpAddThermalResLayer(self, Box(xpos1, ypos1, xpos2, ypos2), True, Cell)
-
- # **************************************************************
- # EXTBlock
- if i == 1 :
- dbCreateRect(self, extBlocklayer, Box(xpos1-ext_over, ypos1, xpos2+ext_over, ypos2))
- else :
- dbCreateRect(self, extBlocklayer, Box(xpos1-ext_over, ypos1, xpos2+ext_over, ypos2))
-
- # **************************************************************
- # hor connection parts
- if i < stripes : # Connections parts
- ypos1 = ypos2+w*Dir
- xpos2 = xpos1+2*w+ps
- ypos2 = ypos1-w*Dir
- Dir *= -1
- # draw res bend
- dbCreateRect(self, bodypolylayer, Box(xpos1, ypos1, xpos2, ypos2))
- dbCreateRect(self, reslayer, Box(xpos1, ypos1, xpos2, ypos2))
- # decide in which direction the part is drawn
- if oddp(i) :
- dbCreateRect(self, extBlocklayer, Box(xpos1-ext_over, ypos1+ext_over, xpos2+ext_over, ypos2-ext_over))
- else :
- dbCreateRect(self, extBlocklayer, Box(xpos1-ext_over, ypos1-ext_over, xpos2+ext_over, ypos2+ext_over))
-
- xpos1 = xpos1+w+ps
- ypos1 = ypos2
-
-
- # x1,y1,x2,y2,dir are updated, use code from first contact, only pin is different
- # **************************************************************
- # draw res contact (Top)
- # **************************************************************
- # set x1 x2 to dogbone,:
- if stripes > 1 :
- xpos1 = xpos1
- xpos2 = xpos2+contoverlay+contoverlay
- else :
- xpos1 = xpos1-contoverlay
- xpos2 = xpos2+contoverlay
-
- # **************************************************************
- # GatPoly Part
- dbCreateRect(self, contpolylayer, Box(xpos1, ypos2, xpos2, ypos2+poly_cont_len*Dir))
-
- # draw contacts
- # LI and Metal
- # always dot contacts with auto-generated LI
-
- # **************************************************************
- # EXTBlock
- # draw ExtBlock for bottom Cont Area
- dbCreateRect(self, extBlocklayer, Box(xpos1-ext_over, ypos1, xpos2+ext_over, ypos2+ext_over*Dir+poly_cont_len*Dir))
-
- # **************************************************************
- # ExtBlock Part
- # added internal code
- if drawbar == True :
- # can only be in internal PCell
- dbCreateRect(self, locintlayer, Box(xpos1+contbar_poly_over, ypos2+li_poly_over*Dir, xpos2-contbar_poly_over, ypos2+(consize+li_poly_over)*Dir))
- else :
- for i in range(ncont) :
- dbCreateRect(self, locintlayer, Box(xpos1+polyover+distr+i*distc, ypos2+li_poly_over*Dir, xpos1+polyover+distr+i*distc+consize, ypos2+(consize+li_poly_over)*Dir))
-
- # **************************************************************
- # Metal ans Pin Part
- # new metal block
- ypos1 = ypos2+(li_poly_over-metover)*Dir
- ypos2 = ypos2+(consize+li_poly_over+metover)*Dir
- dbCreateRect(self, metlayer, Box(xpos1+contbar_poly_over-endcap, ypos1, xpos2-contbar_poly_over+endcap, ypos2))
- MkPin(self, 'MINUS', 2, Box(xpos1+contbar_poly_over-endcap, ypos1, xpos2-contbar_poly_over+endcap, ypos2), metlayer)
-
- # **************************************************************
- # now draw the label
- resistance = CbResCalc('R', 0, l*1e-6, w*1e-6, b, ps*1e-6, Cell)
- labeltext = '{0} r={1:.3f}'.format(Cell, resistance)
- labelpos = Point(w/2, l/2)
-
- # label scaling. Should always fit into bBox of device
- labelheight = 0.1 # use 1.0 to avoid later multiplication
- if w > l :
- rot = 'R0'
- else :
- rot = 'R90'
-
- # lbl
- lbl = dbCreateLabel(self, Layer(textlayer, 'drawing'), labelpos, labeltext, 'centerCenter', rot, Font.EURO_STYLE, labelheight)
- lsizex = lbl.bbox.getWidth()
- lsizey = lbl.bbox.getHeight()
- scale = min(w/lsizex, (l+2*poly_cont_len)/lsizey)
- #SetSGq(lbl scale height)
diff --git a/ihp-sg13g2/libs.tech/pycell/sealring_code.py b/ihp-sg13g2/libs.tech/pycell/sealring_code.py
deleted file mode 100644
index f9b25191..00000000
--- a/ihp-sg13g2/libs.tech/pycell/sealring_code.py
+++ /dev/null
@@ -1,238 +0,0 @@
-########################################################################
-#
-# Copyright 2024 IHP PDK Authors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-########################################################################
-__version__ = '$Revision: #3 $'
-
-from cni.dlo import *
-from geometry import *
-from utility_functions import *
-
-import math
-
-class sealring(DloGen):
-
- @classmethod
- def defineParamSpecs(cls, specs):
- techparams = specs.tech.getTechParams()
-
- CDFVersion = techparams['CDFVersion']
-
- specs('cdf_version', CDFVersion, 'CDF Version')
- specs('Display', 'Selected', 'Display', ChoiceConstraint(['All', 'Selected']))
-
- specs('l', '150u', 'Length(X-Axis)')
- specs('w', '150u', 'Width(Y-Axis)')
- specs('wfill', '30u', 'Filler ring width')
- specs('addLabel', 'nil', 'Add sub! label', ChoiceConstraint(['nil', 't']))
- specs('addSlit', 'nil' , 'Add Slit', ChoiceConstraint(['nil', 't']))
-
- specs('Lmin', '150u', 'Lmin')
- specs('Wmin', '150u', 'Wmin')
-
- def setupParams(self, params):
- # process parameter values entered by user
- self.params = params
- self.l = params['l']
- self.w = params['w']
- self.wfill = params['wfill']
- self.addLabel = params['addLabel']
- self.addSlit = params['addSlit']
-
- def genLayout(self):
- techparams = self.tech.getTechParams()
- self.techparams = techparams
- self.epsilon = techparams['epsilon1']
-
- l = self.l
- w = self.w
- wfill = self.wfill
- addLabel = self.addLabel
- addSlit = self.addSlit
-
- corneroffset = self.techparams['Seal_k']
- cont_size = self.techparams['Cnt_a']
- vian_size = self.techparams['Vn_a']
- TV1_size = self.techparams['TV1_a']
- TV2_size = self.techparams['TV2_a']
-
- # PCell Code
-
- w = Numeric(w)*1e6;
- l = Numeric(l)*1e6;
- wfill = Numeric(wfill)*1e6;
-
- maxMetalWidth = 4.2
- maxMetalLength = maxMetalWidth * 2
- corner_width = 4.2
- metalOffset = 3 + corner_width
- viaOffset = 5.1 + corner_width
- corner_length = corner_width * 2
- corner_starty = 0 # start at the bottom right
- corner_steps = 4
- corner_end = 28.2 # end of the bottom right and top left
- corner_startx = corner_end - (corner_end - corner_width * (corner_steps + 1))
- metal_startx = corner_end - (corner_end - maxMetalWidth * (corner_steps + 1)) + metalOffset
-
- # Sealring Corner
- layers = ['Activ', 'pSD', 'EdgeSeal', 'Metal1', 'Metal2', 'Metal3', 'Metal4', 'Metal5', 'TopMetal1', 'TopMetal2']
- vias = ['Cont', 'Via1', 'Via2', 'Via3', 'Via4', 'TopVia1', 'TopVia2']
-
- item_list = list()
- groupId = list()
-
- # Passiv
- layerobj = dbCreateRect(self, Layer('Passiv', 'drawing'), Box(corner_startx, corner_starty, corner_end, corner_width))
- item_list.append(layerobj)
- layerobj = generateCorner(self, corner_startx, corner_starty, corner_width, corner_length, corner_steps, corner_end, 0, 'Passiv')
- item_list += layerobj
- groupId = combineLayerAndDelete(self, item_list, groupId, 'Passiv')
-
- item_list = []
-
- # Metals
- for layer in layers :
- layerobj = generateCorner(self, metal_startx, corner_starty, maxMetalWidth, maxMetalLength, corner_steps, corner_end, metalOffset, layer)
- groupId = combineLayerAndDelete(self, layerobj, groupId, layer)
-
- # Vias
- for layer in vias :
- if layer == 'TopVia1' :
- viaWidth = TV1_size
- viaLength = 4.2
- elif layer == 'TopVia2' :
- viaWidth = TV2_size
- viaLength = 4.2
- elif layer == 'Cont' :
- viaWidth = cont_size
- viaLength = 4.2
- else :
- viaWidth = vian_size
- viaLength = 4.2
-
- via_startx = corner_end - (corner_end - maxMetalWidth * (corner_steps + 1)) + metalOffset - maxMetalWidth/2-0.1
- layerobj = dbCreateRect(self, layer, Box(via_startx, viaOffset, via_startx+viaWidth, viaOffset+viaLength))
- cons(item_list, layerobj)
-
- viaGroupId = layerobj
-
- for cnt in range(1, corner_steps+1) :
- layerobj = dbCopyShape(viaGroupId, Point(2 * viaOffset + viaLength * cnt + viaWidth-0.1, -viaLength*(cnt-1)), 'R90')
- cons(item_list, layerobj)
- layerobj = dbCopyShape(viaGroupId, Point(-maxMetalWidth*(cnt-1), maxMetalWidth*(cnt-1)-0.1), 'R0')
- cons(item_list, layerobj)
-
- layerobj = dbCreateRect(self, layer, Box(via_startx, viaOffset-0.1, corner_end, viaOffset-0.1+viaWidth))
- cons(item_list, layerobj)
- layerobj = dbCreateRect(self, layer, Box(viaOffset-0.1, corner_end - maxMetalWidth/2-0.1, viaOffset-0.1+viaWidth, corner_end))
- cons(item_list, layerobj)
- groupId = combineLayerAndDelete(self, item_list, groupId, layer)
-
- item_list = []
-
- # Copy Corners
- ihpCopyFig(groupId, Point(l, w), 'R180')
- ihpCopyFig(groupId, Point(l, 0), 'R90')
- ihpCopyFig(groupId, Point(0, w), 'R270')
-
- # end PCell Code
-
- # Straight Lines
- dbCreateRect(self, Layer('Passiv', 'drawing'), Box(0.0, corner_end, corner_width, w - corner_end))
- dbCreateRect(self, Layer('Passiv', 'drawing'), Box(corner_end, 0.0, l - corner_end, corner_width))
- dbCreateRect(self, Layer('Passiv', 'drawing'), Box(l, corner_end, l - corner_width, w - corner_end))
- dbCreateRect(self, Layer('Passiv', 'drawing'), Box(corner_end, w, l - corner_end, w - corner_width))
-
- for layer in layers :
- dbCreateRect(self, Layer(layer, 'drawing'), Box(metalOffset, corner_end, metalOffset + corner_width, w - corner_end))
- dbCreateRect(self, Layer(layer, 'drawing'), Box(corner_end, metalOffset, l - corner_end, metalOffset + corner_width))
- dbCreateRect(self, Layer(layer, 'drawing'), Box(l - metalOffset, corner_end, l - corner_width - metalOffset, w - corner_end))
- dbCreateRect(self, Layer(layer, 'drawing'), Box(corner_end, w - metalOffset, l - corner_end, w - corner_width - metalOffset))
-
- for layer in vias :
- if layer == 'TopVia1' :
- viaWidth = TV1_size
- viaLength = 4.2
- elif layer == 'TopVia2' :
- viaWidth = TV2_size
- viaLength = 4.2
- elif layer == 'Cont' :
- viaWidth = cont_size
- viaLength = 4.2
- else :
- viaWidth = vian_size
- viaLength = 4.2
-
- dbCreateRect(self, Layer(layer, 'drawing'), Box(viaOffset-0.1, corner_end, viaOffset + viaWidth - 0.1, w - corner_end))
- dbCreateRect(self, Layer(layer, 'drawing'), Box(corner_end, viaOffset-0.1, l - corner_end, viaOffset + viaWidth - 0.1))
- dbCreateRect(self, Layer(layer, 'drawing'), Box(l - viaOffset+0.1, corner_end, l - viaWidth - viaOffset + 0.1, w - corner_end))
- dbCreateRect(self, Layer(layer, 'drawing'), Box(corner_end, w - viaOffset+0.1, l - corner_end, w - viaWidth - viaOffset + 0.1))
-
-
- if wfill > 0. : # draw fillers
- distance_edgeseal = self.techparams['MFil_c']
- id = dbCreatePolygon(self, 'Metal1', PointList([Point(metalOffset, metalOffset), Point(metalOffset, metalOffset+16.8), Point(metalOffset+16.8, metalOffset)]))
- # ActFiller and GatFiller
- distance_edgeseal = self.techparams['GFil_d']
- fillerList = DrawFillers(self, Layer('Activ', 'filler'), metalOffset-wfill, -wfill+0.8+metalOffset, l-metalOffset, metalOffset-distance_edgeseal-0.8, 3.4, 3.4, 1.6, 1.6, 'h', 1, True)
- item_list = DrawFillers(self, Layer('GatPoly', 'filler'), metalOffset-wfill+1, -wfill+metalOffset, l-metalOffset-1, metalOffset-distance_edgeseal, 1.4, 5, 3.6, 0, 'h', 1, True)
- fillerList += item_list
- item_list = DrawFillers(self, Layer('Activ', 'filler'), metalOffset-wfill+1, metalOffset-0.9, metalOffset-1.8, w+wfill-metalOffset, 3.4, 3.4, 1.6, 1.6, 'v', 1, True)
- fillerList += item_list
- item_list = DrawFillers(self, Layer('GatPoly', 'filler'), metalOffset-wfill+0.2, metalOffset+0.1, metalOffset-1.0, w+wfill-metalOffset-1.0, 5, 1.4, 0, 3.6, 'v', 1, True)
- fillerList += item_list
-
- # M1Filler - M5Filler
- layers = ['Metal1', 'Metal2', 'Metal3', 'Metal4', 'Metal5']
- filler_height = self.techparams['MFil_a1']
- filler_width = self.techparams['MFil_a2']
- filler_space = 1.2
- distance_edgeseal = self.techparams['MFil_c']
- distance_edgeseal = self.techparams['MFil_b']
- for layer in layers :
- item_list = DrawFillers(self, Layer(layer, 'filler'), metalOffset-wfill, -wfill+metalOffset, l-metalOffset, metalOffset-distance_edgeseal , filler_width, filler_height, filler_space, filler_space, 'h', 1, True)
- fillerList += item_list
- item_list = DrawFillers(self, Layer(layer, 'filler'), metalOffset-wfill, metalOffset+0.8, metalOffset-filler_space, w+wfill-metalOffset, filler_height, filler_width, filler_space, filler_space, 'v', 1, True)
- fillerList += item_list
- idlist = DrawFillers(self, Layer(layer, 'filler'), metalOffset, metalOffset, metalOffset+16.8, metalOffset+16.8, filler_height, filler_height, filler_space, filler_space, 'h', 0, True)
- item_list = dbLayerInside(self, Layer(layer, 'filler'), idlist, id)
- fillerList += item_list
- for i in idlist :
- dbDeleteObject(i)
-
- # TopMet1Filler
- filler_height = self.techparams['TM1Fil_a']
- filler_width = self.techparams['TM1Fil_a1']
- filler_space = 3.
- distance_edgeseal = self.techparams['TM1Fil_c']
-
- item_list = DrawFillers(self, Layer('TopMetal1', 'filler'), metalOffset-wfill, -wfill+metalOffset, l-metalOffset, metalOffset-distance_edgeseal, filler_width, filler_height, filler_space, filler_space, 'h', 1, True)
- fillerList += item_list
- item_list = DrawFillers(self, Layer('TopMetal1', 'filler'), metalOffset-wfill, metalOffset+0.8, metalOffset-filler_space, w+wfill-metalOffset, filler_height, filler_width, filler_space, filler_space, 'v', 1, True)
- fillerList += item_list
- item_list = dbCreateRect(self, Layer('TopMetal1', 'filler'), Box(metalOffset, metalOffset, metalOffset+5, metalOffset+5))
- fillerList.append(item_list)
- # TopMet2Filler
- item_list = DrawFillers(self, Layer('TopMetal2', 'filler'), metalOffset-wfill, -wfill+metalOffset, l-metalOffset, metalOffset-distance_edgeseal, filler_width, filler_height, filler_space, filler_space, 'h', 1, True)
- fillerList += item_list
- item_list = DrawFillers(self, Layer('TopMetal2', 'filler'), metalOffset-wfill, metalOffset+0.8, metalOffset-filler_space, w+wfill-metalOffset, filler_height, filler_width, filler_space, filler_space, 'v', 1, True)
- fillerList += item_list
- item_list = dbCreateRect(self, Layer('TopMetal2', 'filler'), Box(metalOffset, metalOffset, metalOffset+5, metalOffset+5))
- fillerList.append(item_list)
-
- dbDeleteObject(id)
-
- ihpCopyFig(fillerList, Point(l, w), 'R180')
diff --git a/ihp-sg13g2/libs.tech/pycell/utility_functions.py b/ihp-sg13g2/libs.tech/pycell/utility_functions.py
deleted file mode 100644
index 4d93b983..00000000
--- a/ihp-sg13g2/libs.tech/pycell/utility_functions.py
+++ /dev/null
@@ -1,663 +0,0 @@
-########################################################################
-#
-# Copyright 2023 IHP PDK Authors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-########################################################################
-import math
-import StringIO
-
-from cni.dlo import Tech, Numeric
-from cni.dlo import Orientation, Location, Layer
-
-nil = 0
-
-tech = Tech.get('SG13_dev')
-techparams = tech.getTechParams()
-
-SG13_TECHNOLOGY = tech.name()
-
-SG13_EPSILON = techparams['epsilon1'] # for rounding purposes
-SG13_GRID = tech.getGridResolution()
-if SG13_GRID == 0.0 :
- SG13_GRID = techparams['grid']
-SG13_IGRID = 1.0/SG13_GRID # inverse grid
-
-#***********************************************************************************************************************
-# LeQp2
-#***********************************************************************************************************************
-def LeQp2(a, b, eps):
-
- if type(a) == str :
- a = eng_string_to_float(a)
- if type(b) == str :
- b = eng_string_to_float(b)
-
- return a <= b*(1-eps)
-
-#***********************************************************************************************************************
-# LeQp23
-#***********************************************************************************************************************
-def LeQp3(a, b, c, eps):
-
- if type(a) == str :
- a = eng_string_to_float(a)
- if type(b) == str :
- b = eng_string_to_float(b)
- if type(c) == str :
- c = eng_string_to_float(c)
-
- return a >= b-c*eps
-
-#***********************************************************************************************************************
-# fix
-#***********************************************************************************************************************
-def fix(value):
- if type(value) == float:
- return int(math.floor(value))
- else :
- return value
-
-#***********************************************************************************************************************
-# floor
-#***********************************************************************************************************************
-def floor(value):
- return int(math.floor(value))
-
-#***********************************************************************************************************************
-# car
-#***********************************************************************************************************************
-def car(value):
- return value[0]
-
-#***********************************************************************************************************************
-# cdr
-#***********************************************************************************************************************
-def cdr(value):
- return value[1:]
-
-#***********************************************************************************************************************
-# caar
-#***********************************************************************************************************************
-def caar(value):
- lw = value.lowerLeft()
- x1 = lw.getX();
- return x1
-
-#***********************************************************************************************************************
-# cadar
-#***********************************************************************************************************************
-def cadar(value):
- lw = value.lowerLeft()
- y1 = lw.getY();
- return y1
-
-#***********************************************************************************************************************
-# caadr
-#***********************************************************************************************************************
-def caadr(value):
- ur = value.upperRight()
- x2 = ur.getX()
- return x2
-
-#***********************************************************************************************************************
-# cadadr
-#***********************************************************************************************************************
-def cadadr(value):
- ur = value.upperRight()
- y2 = ur.getY()
- return y2
-
-#***********************************************************************************************************************
-# cons
-#***********************************************************************************************************************
-def cons(mlist, value):
- if type(mlist) != list and type(value) is list :
- value.append(mlist)
- return value
-
- if type(value) is list :
- mlist = value + mlist
- else :
- mlist.insert(0, value)
-
- return mlist
-
-#***********************************************************************************************************************
-# oddp
-#***********************************************************************************************************************
-def oddp(value):
- return bool(value & 1)
-
-#***********************************************************************************************************************
-# evenp
-#***********************************************************************************************************************
-def evenp(value):
- return not (bool(value & 1))
-
-#***********************************************************************************************************************
-# onep
-#***********************************************************************************************************************
-def onep(value):
- if value == 1:
- return 1
- else :
- return 0
-
-#***********************************************************************************************************************
-# zerop
-#***********************************************************************************************************************
-def zerop(value):
- if value == 0:
- return 1
- else :
- return 0
-
-#***********************************************************************************************************************
-# sprintf
-#***********************************************************************************************************************
-def sprintf(fmt, *args):
- buf = StringIO.StringIO()
- buf.write(fmt % args)
- return buf.getvalue()
-
-#***********************************************************************************************************************
-# strcat
-#***********************************************************************************************************************
-def strcat(*args):
- lst=[]
- for arg in args:
- lst.append(arg)
- return ' '.join(lst)
-
-#***********************************************************************************************************************
-# eng_string
-#***********************************************************************************************************************
-def eng_string( x, sig_figs=3, si=True):
- """
- Returns float/int value formatted in a simplified engineering format -
- using an exponent that is a multiple of 3.
-
- sig_figs: number of significant figures
-
- si: if true, use SI suffix for exponent, e.g. k instead of e3, n instead of
- e-9 etc.
- """
- x = float(x)
- sign = ''
- if x < 0:
- x = -x
- sign = '-'
- if x == 0:
- exp = 0
- exp3 = 0
- x3 = 0
- else:
- exp = int(math.floor(math.log10( x )))
- exp3 = exp - ( exp % 3)
- x3 = x / ( 10 ** exp3)
- x3 = round( x3, -int( math.floor(math.log10( x3 )) - (sig_figs-1)) )
- if x3 == int(x3): # prevent from displaying .0
- x3 = int(x3)
-
- if si and exp3 >= -24 and exp3 <= 24 and exp3 != 0:
- exp3_text = 'yzafpnum kMGTPEZY'[ exp3 // 3 + 8]
- elif exp3 == 0:
- exp3_text = ''
- else:
- exp3_text = 'e%s' % exp3
-
- return ( '%s%s%s') % ( sign, x3, exp3_text)
-
-#***********************************************************************************************************************
-# eng_string_to_float
-#***********************************************************************************************************************
-def eng_string_to_float(x):
- """
- Returns float/int value from formatted simplified engineering format
-
-
- si: if true, use SI suffix for exponent, e.g. k instead of e3, n instead of
- e-9 etc.
- """
-
- eng = x[-1:]
- exp = -1
-
- for i in 'yzafpnum kMGTPEZY':
- exp += 1
- if i is eng:
- break
-
- exp = (exp - 8) * 3
-
- try:
- int(eng)
- return eval(x)
- except:
- pass
-
- number_string = x[:-1]
- number = 0
-
- try:
- number = float(number_string)
- except:
- raise ValueError
-
- return number * (10**exp)
-
-#***********************************************************************************************************************
-# GridFix
-#***********************************************************************************************************************
-def GridFix(x):
- return fix(x*SG13_IGRID+SG13_EPSILON)*SG13_GRID # always use "nice" numbers, as 1/grid may be irrational
-
-#***********************************************************************************************************************
-# LayerGridFix
-#***********************************************************************************************************************
-def LayerGridFix(layerId, value):
- if type(layerId) == str :
- layerId = Layer(layerId)
-
- # take grid for used layer from tf
- grid = layerId.getGridResolution()
- # to avoid error if grid for used layer was not found
- if grid == 0 :
- grid = SG13_GRID
-
- igrid = 1.0/grid # inverse grid
- fix(value*igrid+SG13_EPSILON)*grid # always use "nice" numbers, as 1/grid may be irrational
-
- return value
-
-def tog(x):
- return GridFix(x);
-
-def Snap(x):
- return GridFix(x);
-
-def nonzero (x):
- return (abs(x)>=1e-10)
-
-def iszero (x):
- return (abs(x)<1e-10)
-
-#***********************************************************************************************************************
-# hiGetAttention - rings the bell in the keyboard or terminal
-#***********************************************************************************************************************
-def hiGetAttention():
- print('\a')
-
-#***********************************************************************************************************************
-# strToOrient
-#***********************************************************************************************************************
-def strToOrient(value):
- if value == 'R0' :
- return Orientation.R0
-
- if value == 'R90' :
- return Orientation.R90
-
- if value == 'R180' :
- return Orientation.R180
-
- if value == 'R270' :
- return Orientation.R270
-
- if value == 'MY' :
- return Orientation.MY
-
- if value == 'MYR90' :
- return Orientation.MYR90
-
- if value == 'MX' :
- return Orientation.MX
-
- if value == 'MXR90' :
- return Orientation.MXR90
-
-#***********************************************************************************************************************
-# strToAlignt
-#***********************************************************************************************************************
-def strToAlignt(value):
- if value == 'lowerLeft' :
- return Location.LOWER_LEFT
-
- if value == 'centerLeft' :
- return Location.CENTER_LEFT
-
- if value == 'uperLeft' :
- return Location.UPPER_LEFT
-
- if value == 'lowerCenter' :
- return Location.LOWER_CENTER
-
- if value == 'centerCenter' :
- return Location.CENTER_CENTER
-
- if value == 'upperCenter' :
- return Location.UPPER_CENTER
-
- if value == 'lowerCenter' :
- return Location.LOWER_CENTER
-
- if value == 'centerRight' :
- return Location.CENTER_RIGHT
-
- if value == 'upperRight' :
- return Location.UPPER_RIGHT
-
-#***********************************************************************************************************************
-# strToBool
-#***********************************************************************************************************************
-def strToBool(val):
- if val == 'nil' :
- return False
- elif val.upper() == 'FALSE' :
- return False
- elif val.upper() == 'NO' :
- return False
- elif val == '0' :
- return False
- elif val == '' :
- return False
-
- return True
-
-#***********************************************************************************************************************
-# checkForYes
-#***********************************************************************************************************************
-def checkForYes(value):
- if type(value) == str :
- val = value.lower()
- if val == 't' or val == '1' or val == 'yes' or val == 'y' :
- return True
- else :
- return False
- else :
- if type(value) == bool :
- return value
- else :
- return value != 0
-
-#****************************************************************************************************
-# inductor_minD
-#****************************************************************************************************
-def inductor_minD(w, s, nr, grid):
- sqrt2 = math.sqrt(2)
- dmin = 0
-
- if nr == 1 :
- dmin = GridFix((s+w+w)*(1+sqrt2)/2+grid*2)*2
- elif nr == 2 :
- dmin = GridFix((GridFix(w/sqrt2+s/2)+GridFix(s*0.4143)+0.02+w)*2*(1+sqrt2)+0.01)
- elif nr > 2 :
- dmin = GridFix(((GridFix(w/sqrt2+s/2)+GridFix(s*0.4143))*2+2*s+4*w)*(1+sqrt2))
-
- return dmin
-
-#***********************************************************************************************************************
-# resCalc - used for rsil, rhigh, rpnd, rppd
-#***********************************************************************************************************************
-def resCalc(self, cell):
-
- global techparams
-
- lwd = Numeric(techparams[cell+'_lwd'])
- rspec = Numeric(techparams[cell+'_rspec'])
- rzspec = Numeric(techparams[cell+'_rzspec'])
- kappa = Numeric(techparams[cell+'_kappa'])
-
- weff = self.w+lwd
- r = self.l/weff*(self.b+1)*rspec + (2.0/kappa*weff+self.ps)*self.b/weff*rspec + 2.0/self.w*rzspec
-
- return round(r*1e03)/1e03
-
-#****************************************************************************************************
-# CbResCalc
-#****************************************************************************************************
-def CbResCalc(calc, r, l, w, b, ps, cell):
-
- global techparams
- global SG13_TECHNOLOGY
-
- suffix = ''
- if 'SG13G2' in SG13_TECHNOLOGY :
- suffix = 'G2'
- if 'SG13G3' in SG13_TECHNOLOGY :
- suffix = 'G3'
-
- rspec = Numeric(techparams[cell+suffix+'_rspec']) # specific body res. per sq. (float)
- rkspec = Numeric(techparams[cell+'_rkspec']) # res. per single contact (float)
- rzspec = Numeric(techparams[cell+'_rzspec']) * 1e6 # transition res. per um width between contact area and body (float)
- lwd = Numeric(techparams[cell+suffix+'_lwd']) * 1e6 # line width delta [um] (both edges, positiv value adds to w)
- kappa = 1.85
- if cell+'_kappa' in techparams :
- kappa = Numeric(techparams[cell+'_kappa'])
- poly_over_cont = techparams['Cnt_d'] # strcat(cell '_poly_over_cont'))
- cont_size = techparams['Cnt_a'] # techGetSpacingRule(tfId 'minWidth' 'Cont') # size of contact array [um]
- cont_space = techparams['Cnt_b'] # techGetSpacingRule(tfId 'minSpacing' 'Cont')
- cont_dist = cont_space+cont_size
- minW = Numeric(techparams[cell+'_minW'])
-
- # must check for string arguments and convert to float
- if type(r) == str :
- r=Numeric(r)
- if type(l) == str :
- l=Numeric(l)
- if type(w) == str :
- w=Numeric(w)
- if type(b) == str :
- b=Numeric(b)
- if type(ps) == str :
- ps=Numeric(ps)
-
- if LeQp3(w, minW, '1u', techparams['epsilon1']) : # 6.8.03 GG: wmin -> minW,HS: Function'LeQp' 28.9.2004
- w = minW # avoid divide by zero errors in case of problems ; 21.7.03 GG: eps -> minW
-
- w = w * 1e6 # um (needed for contact calculation);HS 4.10.2004
- l = l * 1e6
- ps = ps * 1e6
-
- # here: all dimensions given in [um]!
- result = 0
-
- if calc == 'R' :
- weff = w+lwd
- #result = l/weff*(b+1)*rspec+(2.0/kappa*weff+ps)*b/weff*rspec+2.0/weff*rzspec+2.0*(rkspec/ncont)
- result = l/weff*(b+1)*rspec+(2.0/kappa*weff+ps)*b/weff*rspec+2.0/w*rzspec
- elif calc == 'l' :
- weff = w+lwd
- #result = (weff*(r-2.0*rkspec/ncont)-b*(2.0/kappa*weff+ps)*rspec-2.0*rzspec)/(rspec*(b+1))*1.0e-6 ; in [m]
- result = (weff*r-b*(2.0/kappa*weff+ps)*rspec-2.0*weff/w*rzspec)/(rspec*(b+1))*1.0e-6 # in [m]
- elif calc == 'w' :
- tmp = r-2*b*rspec/kappa
- p = (r*lwd-l*(b+1)*rspec-(2*lwd/kappa+ps)*b*rspec-2*rzspec)/tmp
- q = -2*lwd*rzspec/tmp
- w = -p/2+sqrt(p*p/4-q)
- result = Snap(w)*1e-6 # -> [m]
-
- return result
-
-#***********************************************************************************************************************
-# CbResCurrent
-#***********************************************************************************************************************
-def CbResCurrent(w, eps, cell) : # w must be float in [m], i is given as a string
-
- global techparams
-
- ikspec = Numeric(techparams[cell+'_ikspec'])
- ipspec = Numeric(techparams[cell+'_ipspec'])
- poly_over_cont = techparams['Cnt_d']
- cont_size = techparams['Cnt_a']
- cont_space = techparams['Cnt_b']
- cont_dist = cont_space+cont_size
-
- ncont = fix( (w*1.0e6-2.0*poly_over_cont+cont_space+eps)/cont_dist ) # max. nr. of contacts across resistor width
- if ncont < 1 :
- ncont = 1
-
- ilim_cont = ikspec*ncont
- ilim_poly = w*ipspec
-
- ilim = ilim_poly
- return str(ilim*1000)+'m'
-
-#***********************************************************************************************************************
-# CbCapCalc
-#***********************************************************************************************************************
-def CbCapCalc(calc, c, l, w, cell) :
-
- global techparams
-
- caspec = Numeric(techparams[cell+'_caspec'])*1e-12 # specific cap per sq. [um] (float)
- cpspec = Numeric(techparams[cell+'_cpspec'])*1e-6 # specific cap. per [um] perimeter (float)
- lwd = Numeric(techparams[cell+'_lwd']) # line width delta [m] ; 30.7.05 GG: fixed
-
- if type(c) == str :
- c = Numeric(c)
- if type(l) == str :
- l = Numeric(l)
- if type(w) == str :
- w = Numeric(w)
-
- w = w * 1e6 # um (needed for contact calculation)
- l = l * 1e6
- lwd = lwd * 1e6
-
- result = 0
- if calc == 'C' :
- leff = l+lwd
- weff = w+lwd
- result = leff*weff*caspec + 2.0*(leff+weff)*cpspec
- elif calc == 'l' :
- weff = w+lwd
- result = ((c-2.0*weff*cpspec)/(caspec*weff+2.0*cpspec) - lwd) * 1.0e-6
- elif calc == 'w' :
- leff = l+lwd
- result = ((c-2.0*leff*cpspec)/(caspec*leff+2.0*cpspec) - lwd) * 1.0e-6
- elif calc == 'lw' :
- result = ( -2.0*cpspec/caspec + sqrt(4.0*cpspec*cpspec/(caspec*caspec) + c/caspec) - lwd) * 1.0e-6
-
- return result
-
-#***********************************************************************************************************************
-# CbTapCalc
-#***********************************************************************************************************************
-def CbTapCalc(calc, r, l, w, cell) :
-
- global techparams
-
- raspec = Numeric(techparams[cell+'_raspec'])*1.0e12 ;# specific res per sq. [um] (float)
- rpspec = Numeric(techparams[cell+'_rpspec'])*1.0e6 ;# specific res. per [um] perimeter (float)
-
- w = w*1.0e6 ;# um (needed for contact calculation)
- l = l*1.0e6
- a = l*w
- p = 2.0*(l+w)
-
- result = 0
- if calc == 'R' :
- result = 1.0/(1.0/(raspec/a) + 1.0/(rpspec/p))
- elif calc == 'l' :
- result = (raspec*rpspec- r*raspec*2.0*w)/(r*raspec*2.0+r*rpspec*w)*1.0e-6
- elif calc == 'w' :
- result = (raspec*rpspec- r*raspec*2.0*l)/(r*raspec*2.0+r*rpspec*l)*1.0e-6
- elif calc == 'wl' :
- result = ((-4.0*r*raspec + sqrt(16.0*r*r*raspec*raspec + 4.0*r*rpspec*rpspec*raspec))/(2.0*r*rpspec))*1.0e-6
-
- return result
-
-#***********************************************************************************************************************
-# CbDiodeCalc
-#***********************************************************************************************************************
-def CbDiodeCalc(calc, a, l, w, cell) :
-
- global techparams
-
- minL = Numeric(techparams[cell+'_minL'])
- minW = Numeric(techparams[cell+'_minW'])
-
- if calc != 'w' and calc != 'wl' :
- if w < minW :
- print("w {0} too small\n".format(w))
- if calc != 'l' and calc != 'wl' :
- if l < minL :
- print("l {0} too small\n".format(l))
-
- if type(a) == str :
- a = Numeric(a)
- if type(l) == str :
- l = Numeric(l)
- if type(w) == str :
- w = Numeric(w)
-
- w = w*1.0e6 # um (needed for contact calculation)
- l = l*1.0e6
-
- result = 0
- if calc == 'a' :
- result = w*l*1.0e-12
- elif calc == 'p' :
- result = (w+l)*2.0e-6
- elif calc == 'l' :
- result = (a/w)*1.0e6
- elif calc == 'w' :
- result = (a/l)*1.0e6
- elif calc == 'wl' :
- result = sqrt(a)
-
- return result
-
-def listlen(mlist) :
- return len(mlist)
-
-def isOdd(x) :
- if x == 0 :
- return 0
-
- if (x % 2) != 0 :
- return 1
-
- return 0
-
-def isEven(x) :
- if x == 0 :
- return 1
-
- if (x % 2) == 0 :
- return 1
-
- return 0
-
-def is_list(x) :
- if type (x) is list :
- return 1
-
- return 0
-
-def min2(a, b) :
- return min(a, b)
-
-def max2(a, b) :
- return max(a, b)
-
-def pylist(*args) :
- mlist = list()
-
- for key in args :
- mlist.append(key)
-
- return mlist
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/cap_cmim.sym b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/cap_cmim.sym
index aca15232..a73cbfce 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/cap_cmim.sym
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/cap_cmim.sym
@@ -1,5 +1,5 @@
v {xschem version=3.1.0 file_version=1.2
-* Copyright 2023 IHP PDK Authors
+* Copyright 2024 IHP PDK Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,8 +15,14 @@ v {xschem version=3.1.0 file_version=1.2
}
G {}
K {type=capacitor
-format="@spiceprefix@name @pinlist @model W=@W L=@L MF=@MF"
-template="name=C1 model=cap_cmim W=7.0e-6 L=7.0e-6 MF=1 spiceprefix=X"
+format="@spiceprefix@name @pinlist @model w=@w l=@l m=@m"
+template="name=C1
+model=cap_cmim
+w=7.0e-6
+l=7.0e-6
+m=1
+spiceprefix=X"
+drc="mim_drc @name @symname @model @w @l"
}
V {}
S {}
@@ -30,8 +36,8 @@ A 4 -0 23.75 21.25 61.92751306414704 56.14497387170592 {}
T {c0} 5 -27.5 0 0 0.15 0.15 {layer=7}
T {c1} 5 18.75 0 0 0.15 0.15 {layer=7}
T {@name} 15 -28.75 0 0 0.2 0.2 {}
-T {@W / @L} 15 6.25 0 0 0.2 0.2 {layer=13}
+T {@w / @l} 15 6.25 0 0 0.2 0.2 {layer=13}
T {@model} 15 -11.25 0 0 0.2 0.2 {}
-T {tcleval(C=[ev \{@MF * (@W * @L * 1.5e-3 + 2*( @W + @L ) * 40e-12)\}])} -7.5 8.75 0 1 0.2 0.2 {layer=13}
-T {MF=@MF} 15 16.25 0 0 0.2 0.2 {layer=13}
+T {tcleval(C=[ev \{@m * (@w * @l * 1.5e-3 + 2*( @w + @l ) * 40e-12)\}])} -7.5 8.75 0 1 0.2 0.2 {layer=13}
+T {m=@m} 15 16.25 0 0 0.2 0.2 {layer=13}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/cap_rfcmim.sym b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/cap_rfcmim.sym
index b952c1bc..372ae325 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/cap_rfcmim.sym
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/cap_rfcmim.sym
@@ -16,8 +16,14 @@ v {xschem version=3.1.0 file_version=1.2
G {}
K {type=capacitor
-format="@spiceprefix@name @pinlist @model W=@W L=@L wfeed=@wfeed"
-template="name=C1 model=cap_rfcmim W=10.0e-6 L=10.0e-6 wfeed=5.0e-6 spiceprefix=X"
+format="@spiceprefix@name @pinlist @model w=@w l=@l wfeed=@wfeed"
+template="name=C1
+model=cap_rfcmim
+w=10.0e-6
+l=10.0e-6
+wfeed=5.0e-6
+spiceprefix=X"
+drc="mim_drc @name @symname @model @w @l"
}
V {}
S {}
@@ -32,8 +38,8 @@ A 4 -0 23.75 21.25 61.92751306414704 56.14497387170592 {}
T {c0} 5 -27.5 0 0 0.15 0.15 {layer=7}
T {c1} 5 18.75 0 0 0.15 0.15 {layer=7}
T {@name} 15 -28.75 0 0 0.2 0.2 {}
-T {@W / @L} 15 6.25 0 0 0.2 0.2 {layer=13}
+T {@w / @l} 15 6.25 0 0 0.2 0.2 {layer=13}
T {@model} 15 -11.25 0 0 0.2 0.2 {}
-T {tcleval(C=[ev \{(@W * @L * 1.5e-3 + 2*( @W + @L ) * 40e-12)\}])} -7.5 8.75 0 1 0.2 0.2 {layer=13}
+T {tcleval(C=[ev \{(@w * @l * 1.5e-3 + 2*( @w + @l ) * 40e-12)\}])} -7.5 8.75 0 1 0.2 0.2 {layer=13}
T {bn} -25 -7.5 0 0 0.15 0.15 {layer=7}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/dantenna.sym b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/dantenna.sym
index b149a4bc..2e4ff306 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/dantenna.sym
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/dantenna.sym
@@ -16,12 +16,15 @@ v {xschem version=3.1.0 file_version=1.2
}
G {}
K {type=diode
-format="@name @pinlist @model l=@l w=@w"
-template="name=XD1
+lvs_format="@spiceprefix@name @pinlist @model l=@l w=@w"
+format="@spiceprefix@name @pinlist @model l=@l w=@w"
+template="name=D1
model=dantenna
-l=780n
-w=780n
+l=0.78u
+w=0.78u
+spiceprefix=X
"
+drc="diode_drc @name @symname @model @w @l"
}
V {}
S {}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/dpantenna.sym b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/dpantenna.sym
index 87e91483..f9c481fc 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/dpantenna.sym
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/dpantenna.sym
@@ -16,12 +16,15 @@ v {xschem version=3.1.0 file_version=1.2
}
G {}
K {type=diode
-format="@name @pinlist @model l=@l w=@w"
-template="name=XD1
+lvs_format="@spiceprefix@name @pinlist @model l=@l w=@w"
+format="@spiceprefix@name @pinlist @model l=@l w=@w"
+template="name=D1
model=dpantenna
-l=780n
-w=780n
+l=0.78u
+w=0.78u
+spiceprefix=X
"
+drc="diode_drc @name @symname @model @w @l"
}
V {}
S {}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/npn13G2.sym b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/npn13G2.sym
index 70b1b54c..6916065c 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/npn13G2.sym
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/npn13G2.sym
@@ -16,11 +16,14 @@ v {xschem version=3.1.0 file_version=1.2
}
G {}
K {type=vertical_npn
+lvs_format="@spiceprefix@name @pinlist @model le=@le we=70.0n m=@Nx"
format="@spiceprefix@name @pinlist @model Nx=@Nx"
template="name=Q1
model=npn13G2
spiceprefix=X
-Nx=1"
+Nx=1
+le=900e-9"
+drc="hbt_drc @name @symname @model @Nx @le"
}
V {}
S {}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/npn13G2l.sym b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/npn13G2l.sym
index fe1a432d..c296c145 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/npn13G2l.sym
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/npn13G2l.sym
@@ -1,4 +1,4 @@
-v {xschem version=3.1.0 file_version=1.2
+v {xschem version=3.4.5 file_version=1.2
* Copyright 2023 IHP PDK Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,12 +16,14 @@ v {xschem version=3.1.0 file_version=1.2
}
G {}
K {type=vertical_npn
-format="@spiceprefix@name @pinlist @model Nx=@Nx El=@El"
+lvs_format="@spiceprefix@name @pinlist @model le=@le we=70.0n m=@Nx"
+format="@spiceprefix@name @pinlist @model Nx=@Nx le=@le"
template="name=Q1
model=npn13G2l
spiceprefix=X
Nx=1
-El=1"
+le=1.0e-6"
+drc="hbt_drc @name @symname @model @Nx @le"
}
V {}
S {}
@@ -39,4 +41,4 @@ T {Nx=@Nx} 32.5 1.25 0 0 0.2 0.2 {layer=13}
T {@model} 22.5 -15 0 0 0.2 0.2 {}
T {S} 10 -5 0 0 0.2 0.2 {}
T {@spiceprefix@name} 22.5 -27.5 0 0 0.2 0.2 {}
-T {El=@El} 32.5 11.25 0 0 0.2 0.2 {layer=13}
+T {le=@le} 32.5 11.25 0 0 0.2 0.2 {layer=13}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/npn13G2v.sym b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/npn13G2v.sym
index ecd72060..c08f5336 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/npn13G2v.sym
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/npn13G2v.sym
@@ -1,4 +1,4 @@
-v {xschem version=3.1.0 file_version=1.2
+v {xschem version=3.4.5 file_version=1.2
* Copyright 2023 IHP PDK Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,11 +16,15 @@ v {xschem version=3.1.0 file_version=1.2
}
G {}
K {type=vertical_npn
-format="@spiceprefix@name @pinlist @model Nx=@Nx"
+lvs_format="@spiceprefix@name @pinlist @model le=@le we=70.0n m=@Nx"
+format="@spiceprefix@name @pinlist @model Nx=@Nx le=@le"
template="name=Q1
model=npn13G2v
spiceprefix=X
-Nx=1"
+Nx=1
+le=1.0e-6
+"
+drc="hbt_drc @name @symname @model @Nx @le"
}
V {}
S {}
@@ -34,7 +38,8 @@ B 5 -22.5 -2.5 -17.5 2.5 {name=B dir=in pinnumber=1}
B 5 17.5 27.5 22.5 32.5 {name=E dir=inout pinnumber=2}
B 5 17.5 -2.5 22.5 2.5 {name=S dir=in pinnumber=1}
P 4 4 20 30 13.75 13.75 3.75 23.75 20 30 {fill=true}
-T {Nx=@Nx} 22.5 11.25 0 0 0.2 0.2 {layer=13}
+T {Nx=@Nx} 22.5 1.25 0 0 0.2 0.2 {layer=13}
T {@model} 22.5 -15 0 0 0.2 0.2 {}
T {S} 10 -5 0 0 0.2 0.2 {}
T {@spiceprefix@name} 22.5 -27.5 0 0 0.2 0.2 {}
+T {le=@le} 22.5 11.25 0 0 0.2 0.2 {layer=13}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/rhigh.sym b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/rhigh.sym
index aa0716bf..e9acd419 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/rhigh.sym
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/rhigh.sym
@@ -16,15 +16,16 @@ v {xschem version=3.4.5 file_version=1.2
}
G {}
K {type=res
-format="@spiceprefix@name @pinlist @model w=@W l=@L m=@m b=@b"
+format="@spiceprefix@name @pinlist @model w=@w l=@l m=@m b=@b"
template="name=R1
-W=0.5e-6
-L=0.5e-6
+w=0.5e-6
+l=0.5e-6
model=rhigh
spiceprefix=X
b=0
m=1
"
+drc="res_drc @name @symname @model @w @l"
}
V {}
S {}
@@ -42,10 +43,10 @@ L 4 -7.5 -17.5 0 -20 {}
L 4 0 -30 0 -20 {}
B 5 -2.5 27.5 2.5 32.5 {name=M dir=inout propag=1 pinnumber=2}
B 5 -2.5 -32.5 2.5 -27.5 {name=P dir=inout propag=0 pinnumber=1}
-T {W/L = @W / @L} 15 -3.75 0 0 0.2 0.2 {layer=13}
+T {w/l = @w / @l} 15 -3.75 0 0 0.2 0.2 {layer=13}
T {@model} 15 -16.25 0 0 0.2 0.2 {}
T {@spiceprefix@name} 15 -28.75 0 0 0.2 0.2 {}
-T {tcleval(R=[ ev \{ ( 1.6e-4 / @W + 1360.0 * ( (@b + 1)*@L + ( 1.081*( @W - 0.04e-6 ) + 0.18e-6 )*@b ) / ( @W - 0.04e-6 ) ) / @m \} ] )} 15 30 0 0 0.2 0.2 {layer=13}
+T {tcleval(R=[ ev \{ ( 1.6e-4 / @w + 1360.0 * ( (@b + 1)*@l + ( 1.081*( @w - 0.04e-6 ) + 0.18e-6 )*@b ) / ( @w - 0.04e-6 ) ) / @m \} ] )} 15 30 0 0 0.2 0.2 {layer=13}
T {} 15 20 0 0 0.2 0.2 {}
T {b=@b} 15 6.25 0 0 0.2 0.2 {layer=13}
T {m=@m} 15 16.25 0 0 0.2 0.2 {layer=13}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/rppd.sym b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/rppd.sym
index f56ce94e..4e001026 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/rppd.sym
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/rppd.sym
@@ -16,15 +16,16 @@ v {xschem version=3.4.5 file_version=1.2
}
G {}
K {type=res
-format="@spiceprefix@name @pinlist @model w=@W l=@L m=@m b=@b"
+format="@spiceprefix@name @pinlist @model w=@w l=@l m=@m b=@b"
template="name=R1
-W=0.5e-6
-L=0.5e-6
+w=0.5e-6
+l=0.5e-6
model=rppd
spiceprefix=X
b=0
m=1
"
+drc="res_drc @name @symname @model @w @l"
}
V {}
S {}
@@ -42,10 +43,10 @@ L 4 -7.5 -17.5 0 -20 {}
L 4 0 -30 0 -20 {}
B 5 -2.5 27.5 2.5 32.5 {name=M dir=inout propag=1 pinnumber=2}
B 5 -2.5 -32.5 2.5 -27.5 {name=P dir=inout propag=0 pinnumber=1}
-T {W/L = @W / @L} 15 -3.75 0 0 0.2 0.2 {layer=13}
+T {w/l = @w / @l} 15 -3.75 0 0 0.2 0.2 {layer=13}
T {@model} 15 -16.25 0 0 0.2 0.2 {}
T {@spiceprefix@name} 15 -28.75 0 0 0.2 0.2 {}
-T {tcleval(R=[ ev \{ ( 70.0e-6 / @W + 260.0 * ( (@b + 1)*@L + ( 1.081*( @W + 6.0e-9 ) + 0.18e-6 )*@b ) / ( @W + 6.0e-9 ) ) / @m \} ] )} 15 30 0 0 0.2 0.2 {layer=13}
+T {tcleval(R=[ ev \{ ( 70.0e-6 / @w + 260.0 * ( (@b + 1)*@l + ( 1.081*( @w + 6.0e-9 ) + 0.18e-6 )*@b ) / ( @w + 6.0e-9 ) ) / @m \} ] )} 15 30 0 0 0.2 0.2 {layer=13}
T {} 15 20 0 0 0.2 0.2 {}
T {b=@b} 15 6.25 0 0 0.2 0.2 {layer=13}
T {m=@m} 15 16.25 0 0 0.2 0.2 {layer=13}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/rsil.sym b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/rsil.sym
index efb51454..4877fcf7 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/rsil.sym
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/rsil.sym
@@ -16,15 +16,16 @@ v {xschem version=3.4.5 file_version=1.2
}
G {}
K {type=res
-format="@spiceprefix@name @pinlist @model w=@W l=@L m=@m b=@b"
+format="@spiceprefix@name @pinlist @model w=@w l=@l m=@m b=@b"
template="name=R1
-W=0.5e-6
-L=0.5e-6
+w=0.5e-6
+l=0.5e-6
model=rsil
spiceprefix=X
b=0
m=1
"
+drc="res_drc @name @symname @model @w @l"
}
V {}
S {}
@@ -42,10 +43,10 @@ L 4 -7.5 -17.5 0 -20 {}
L 4 0 -30 0 -20 {}
B 5 -2.5 27.5 2.5 32.5 {name=M dir=inout propag=1 pinnumber=2}
B 5 -2.5 -32.5 2.5 -27.5 {name=P dir=inout propag=0 pinnumber=1}
-T {W/L = @W / @L} 15 -3.75 0 0 0.2 0.2 {layer=13}
+T {w/l = @w / @l} 15 -3.75 0 0 0.2 0.2 {layer=13}
T {@model} 15 -16.25 0 0 0.2 0.2 {}
T {@spiceprefix@name} 15 -28.75 0 0 0.2 0.2 {}
-T {tcleval(R=[ ev \{ ( 9.0e-6 / @W + 7.0 * ( (@b + 1)*@L + ( 1.081*( @W + 1.0e-8 ) + 0.18e-6 )*@b ) / ( @W + 1.0e-8 ) ) / @m \} ] )} 15 30 0 0 0.2 0.2 {layer=13}
+T {tcleval(R=[ ev \{ ( 9.0e-6 / @w + 7.0 * ( (@b + 1)*@l + ( 1.081*( @w + 1.0e-8 ) + 0.18e-6 )*@b ) / ( @w + 1.0e-8 ) ) / @m \} ] )} 15 30 0 0 0.2 0.2 {layer=13}
T {} 15 20 0 0 0.2 0.2 {}
T {b=@b} 15 6.25 0 0 0.2 0.2 {layer=13}
T {m=@m} 15 16.25 0 0 0.2 0.2 {layer=13}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_hv_nmos.sym b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_hv_nmos.sym
index a7904a85..8786f64f 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_hv_nmos.sym
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_hv_nmos.sym
@@ -16,16 +16,18 @@ v {xschem version=3.4.4 file_version=1.2
}
G {}
K {type=nmos
-lvs_format="@name @pinlist @model L=@L W=@W ng=@ng m=@m"
-format="@spiceprefix@name @pinlist @model W=@W L=@L ng=@ng m=@m"
+lvs_format="@spiceprefix@name @pinlist @model l=@l w=@w ng=@ng m=@m"
+format="@spiceprefix@name @pinlist @model w=@w l=@l ng=@ng m=@m"
template="name=M1
-L=0.45u
-W=1.0u
+l=0.45u
+w=1.0u
ng=1
m=1
model=sg13_hv_nmos
spiceprefix=X
-"}
+"
+drc="fet_drc @name @symname @model @w @l @ng"
+}
V {}
S {}
E {}
@@ -35,7 +37,7 @@ L 4 20 17.5 20 30 {}
L 4 7.5 17.5 20 17.5 {}
L 4 7.5 -17.5 20 -17.5 {}
L 4 -20 -0 2 -0 {}
-B 4 2 -14 3 16 {}
+B 4 2 -16 3 16 {}
B 5 17.5 27.5 22.5 32.5 {name=D dir=inout}
B 5 -22.5 -2.5 -17.5 2.5 {name=G dir=in}
B 5 17.5 -32.5 22.5 -27.5 {name=S dir=inout}
@@ -50,5 +52,5 @@ T {G} -10 -10 0 1 0.15 0.15 {layer=7}
T {@model} 30 31.25 2 1 0.2 0.2 {}
T {m=@m} 31.25 -26.25 0 0 0.2 0.2 { layer=13}
T {ng=@ng} 31.25 -18.75 0 0 0.2 0.2 {layer=13}
-T {L=@L} 31.25 -8.75 0 0 0.2 0.2 {layer=13}
-T {W=@W} 31.25 1.25 0 0 0.2 0.2 { layer=13}
+T {l=@l} 31.25 -8.75 0 0 0.2 0.2 {layer=13}
+T {w=@w} 31.25 1.25 0 0 0.2 0.2 { layer=13}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_hv_pmos.sym b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_hv_pmos.sym
index 958300ca..f560ff73 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_hv_pmos.sym
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_hv_pmos.sym
@@ -16,16 +16,18 @@ v {xschem version=3.4.4 file_version=1.2
}
G {}
K {type=pmos
-lvs_format="@name @pinlist @model L=@L W=@W ng=@ng m=@m"
-format="@spiceprefix@name @pinlist @model W=@W L=@L ng=@ng m=@m"
+lvs_format="@spiceprefix@name @pinlist @model l=@l w=@w ng=@ng m=@m"
+format="@spiceprefix@name @pinlist @model w=@w l=@l ng=@ng m=@m"
template="name=M1
-L=0.45u
-W=1.0u
+l=0.45u
+w=1.0u
ng=1
m=1
model=sg13_hv_pmos
spiceprefix=X
-"}
+"
+drc="fet_drc @name @symname @model @w @l @ng"
+}
V {}
S {}
E {}
@@ -50,5 +52,5 @@ T {G} -10 -10 0 1 0.15 0.15 {layer=7}
T {@model} 30 31.25 2 1 0.2 0.2 {}
T {m=@m} 31.25 -26.25 0 0 0.2 0.2 { layer=13}
T {ng=@ng} 31.25 -18.75 0 0 0.2 0.2 {layer=13}
-T {L=@L} 31.25 -8.75 0 0 0.2 0.2 {layer=13}
-T {W=@W} 31.25 1.25 0 0 0.2 0.2 { layer=13}
+T {l=@l} 31.25 -8.75 0 0 0.2 0.2 {layer=13}
+T {w=@w} 31.25 1.25 0 0 0.2 0.2 { layer=13}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_hv_rf_nmos.sym b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_hv_rf_nmos.sym
new file mode 100644
index 00000000..71d30f19
--- /dev/null
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_hv_rf_nmos.sym
@@ -0,0 +1,58 @@
+v {xschem version=3.1.0 file_version=1.2
+* Copyright 2023 IHP PDK Authors
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* https://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+
+}
+G {}
+K {type=nmos
+lvs_format="@spiceprefix@name @pinlist @model l=@l w=@w ng=@ng m=@m"
+format="@spiceprefix@name @pinlist @model w=@w l=@l ng=@ng m=@m rfmode=@rfmode"
+template="name=M1
+l=0.35u
+w=1.0u
+ng=1
+m=1
+rfmode=1
+model=sg13_hv_nmos
+spiceprefix=X
+"
+drc="fet_drc @name @symname @model @w @l @ng"
+}
+V {}
+S {}
+E {}
+L 4 7.5 -22.5 7.5 22.5 {}
+L 4 20 -30 20 -17.5 {}
+L 4 20 17.5 20 30 {}
+L 4 7.5 17.5 20 17.5 {}
+L 4 7.5 -17.5 20 -17.5 {}
+L 4 -20 -0 2 -0 {}
+B 4 2 -16 3 16 {}
+B 5 17.5 27.5 22.5 32.5 {name=D dir=inout}
+B 5 -22.5 -2.5 -17.5 2.5 {name=G dir=in}
+B 5 17.5 -32.5 22.5 -27.5 {name=S dir=inout}
+B 5 19.921875 -0.078125 20.078125 0.078125 {name=B dir=in}
+P 4 4 12.5 -15 17.5 -17.5 12.5 -20 12.5 -15 {fill=true}
+P 5 4 15 -2.5 20 0 15 2.5 15 -2.5 {fill=true}
+T {@name} 5 -30 0 1 0.2 0.2 {}
+T {D} 22.5 17.5 0 0 0.15 0.15 {layer=7}
+T {S} 22.5 -17.5 2 1 0.15 0.15 {layer=7}
+T {B} 20 -10 0 0 0.15 0.15 {layer=7}
+T {G} -10 -10 0 1 0.15 0.15 {layer=7}
+T {@model} 30 31.25 2 1 0.2 0.2 {}
+T {m=@m} 31.25 -26.25 0 0 0.2 0.2 { layer=13}
+T {ng=@ng} 31.25 -18.75 0 0 0.2 0.2 { layer=13}
+T {l=@l} 31.25 -8.75 0 0 0.2 0.2 {layer=13}
+T {w=@w} 31.25 1.25 0 0 0.2 0.2 { layer=13}
+T {rfmode=@rfmode} 31.25 -36.25 0 0 0.2 0.2 { layer=13}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_hv_rf_pmos.sym b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_hv_rf_pmos.sym
new file mode 100644
index 00000000..65e0f396
--- /dev/null
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_hv_rf_pmos.sym
@@ -0,0 +1,58 @@
+v {xschem version=3.4.4 file_version=1.2
+* Copyright 2023 IHP PDK Authors
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* https://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+
+}
+G {}
+K {type=pmos
+lvs_format="@spiceprefix@name @pinlist @model L=@L W=@W ng=@ng m=@m rfmode=@rfmode"
+format="@spiceprefix@name @pinlist @model W=@W L=@L ng=@ng m=@m rfmode=@rfmode"
+template="name=M1
+L=0.45u
+W=1.0u
+ng=1
+m=1
+rfmode=1
+model=sg13_hv_pmos
+spiceprefix=X
+"
+drc="fet_drc @name @symname @model @w @l @ng"
+}
+V {}
+S {}
+E {}
+L 4 7.5 -22.5 7.5 22.5 {}
+L 4 20 -30 20 -17.5 {}
+L 4 20 17.5 20 30 {}
+L 4 7.5 17.5 20 17.5 {}
+L 4 7.5 -17.5 20 -17.5 {}
+L 4 -20 -0 2 -0 {}
+B 4 2 -16 3 16 {}
+B 5 17.5 27.5 22.5 32.5 {name=D dir=inout}
+B 5 -22.5 -2.5 -17.5 2.5 {name=G dir=in}
+B 5 17.5 -32.5 22.5 -27.5 {name=S dir=inout}
+B 5 19.921875 -0.078125 20.078125 0.078125 {name=B dir=in}
+P 4 4 12.5 -20 7.5 -17.5 12.5 -15 12.5 -20 {fill=true}
+P 5 4 15 -2.5 20 0 15 2.5 15 -2.5 {fill=true}
+T {@name} 5 -30 0 1 0.2 0.2 {}
+T {D} 22.5 17.5 0 0 0.15 0.15 {layer=7}
+T {S} 22.5 -17.5 2 1 0.15 0.15 {layer=7}
+T {B} 20 -10 0 0 0.15 0.15 {layer=7}
+T {G} -10 -10 0 1 0.15 0.15 {layer=7}
+T {@model} 30 31.25 2 1 0.2 0.2 {}
+T {m=@m} 31.25 -26.25 0 0 0.2 0.2 { layer=13}
+T {ng=@ng} 31.25 -18.75 0 0 0.2 0.2 { layer=13}
+T {L=@L} 31.25 -8.75 0 0 0.2 0.2 {layer=13}
+T {W=@W} 31.25 1.25 0 0 0.2 0.2 { layer=13}
+T {rfmode=@rfmode} 31.25 -36.25 0 0 0.2 0.2 { layer=13}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_lv_nmos.sym b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_lv_nmos.sym
index ada14bb6..040a123e 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_lv_nmos.sym
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_lv_nmos.sym
@@ -1,5 +1,5 @@
v {xschem version=3.4.4 file_version=1.2
-* Copyright 2023 IHP PDK Authors
+* Copyright 2024 IHP PDK Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,16 +16,19 @@ v {xschem version=3.4.4 file_version=1.2
}
G {}
K {type=nmos
-lvs_format="@name @pinlist @model L=@L W=@W ng=@ng m=@m"
-format="@spiceprefix@name @pinlist @model W=@W L=@L ng=@ng m=@m"
+lvs_format="@spiceprefix@name @pinlist @model l=@l w=@w ng=@ng m=@m"
+format="@spiceprefix@name @pinlist @model w=@w l=@l ng=@ng m=@m"
template="name=M1
-L=0.45u
-W=1.0u
+l=0.45u
+w=1.0u
ng=1
m=1
model=sg13_lv_nmos
spiceprefix=X
-"}
+"
+drc="fet_drc @name @symname @model @w @l @ng"
+}
+
V {}
S {}
E {}
@@ -50,5 +53,5 @@ T {G} -10 -10 0 1 0.15 0.15 {layer=7}
T {@model} 30 31.25 2 1 0.2 0.2 {}
T {m=@m} 31.25 -26.25 0 0 0.2 0.2 { layer=13}
T {ng=@ng} 31.25 -18.75 0 0 0.2 0.2 { layer=13}
-T {L=@L} 31.25 -8.75 0 0 0.2 0.2 {layer=13}
-T {W=@W} 31.25 1.25 0 0 0.2 0.2 { layer=13}
+T {l=@l} 31.25 -8.75 0 0 0.2 0.2 {layer=13}
+T {w=@w} 31.25 1.25 0 0 0.2 0.2 { layer=13}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_lv_pmos.sym b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_lv_pmos.sym
index 44ada49a..b1f6b3f4 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_lv_pmos.sym
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_lv_pmos.sym
@@ -16,16 +16,18 @@ v {xschem version=3.4.4 file_version=1.2
}
G {}
K {type=pmos
-lvs_format="@name @pinlist @model L=@L W=@W ng=@ng m=@m"
-format="@spiceprefix@name @pinlist @model W=@W L=@L ng=@ng m=@m"
+lvs_format="@name @pinlist @model l=@l w=@w ng=@ng m=@m"
+format="@spiceprefix@name @pinlist @model w=@w l=@l ng=@ng m=@m"
template="name=M1
-L=0.45u
-W=1.0u
+l=0.45u
+w=1.0u
ng=1
m=1
model=sg13_lv_pmos
spiceprefix=X
-"}
+"
+drc="fet_drc @name @symname @model @w @l @ng"
+}
V {}
S {}
E {}
@@ -50,5 +52,5 @@ T {G} -10 -10 0 1 0.15 0.15 {layer=7}
T {@model} 30 31.25 2 1 0.2 0.2 {}
T {m=@m} 31.25 -26.25 0 0 0.2 0.2 { layer=13}
T {ng=@ng} 31.25 -18.75 0 0 0.2 0.2 { layer=13}
-T {L=@L} 31.25 -8.75 0 0 0.2 0.2 {layer=13}
-T {W=@W} 31.25 1.25 0 0 0.2 0.2 { layer=13}
+T {l=@l} 31.25 -8.75 0 0 0.2 0.2 {layer=13}
+T {w=@w} 31.25 1.25 0 0 0.2 0.2 { layer=13}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_lv_rf_nmos.sym b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_lv_rf_nmos.sym
index 46cf93b0..251da73b 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_lv_rf_nmos.sym
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_lv_rf_nmos.sym
@@ -16,17 +16,19 @@ v {xschem version=3.1.0 file_version=1.2
}
G {}
K {type=nmos
-lvs_format="@name @pinlist @model L=@L W=@W ng=@ng m=@m"
-format="@spiceprefix@name @pinlist @model W=@W L=@L ng=@ng m=@m rfmode=@rfmode"
+lvs_format="@spiceprefix@name @pinlist @model l=@l w=@w ng=@ng m=@m"
+format="@spiceprefix@name @pinlist @model w=@w l=@l ng=@ng m=@m rfmode=@rfmode"
template="name=M1
-L=0.35u
-W=1.0u
+l=0.35u
+w=1.0u
ng=1
m=1
rfmode=1
model=sg13_lv_nmos
spiceprefix=X
-"}
+"
+drc="fet_drc @name @symname @model @w @l @ng"
+}
V {}
S {}
E {}
@@ -51,6 +53,6 @@ T {G} -10 -10 0 1 0.15 0.15 {layer=7}
T {@model} 30 31.25 2 1 0.2 0.2 {}
T {m=@m} 31.25 -26.25 0 0 0.2 0.2 { layer=13}
T {ng=@ng} 31.25 -18.75 0 0 0.2 0.2 { layer=13}
-T {L=@L} 31.25 -8.75 0 0 0.2 0.2 {layer=13}
-T {W=@W} 31.25 1.25 0 0 0.2 0.2 { layer=13}
+T {l=@l} 31.25 -8.75 0 0 0.2 0.2 {layer=13}
+T {w=@w} 31.25 1.25 0 0 0.2 0.2 { layer=13}
T {rfmode=@rfmode} 31.25 -36.25 0 0 0.2 0.2 { layer=13}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_lv_rf_pmos.sym b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_lv_rf_pmos.sym
index bf67aa12..a8b2b510 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_lv_rf_pmos.sym
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_pr/sg13_lv_rf_pmos.sym
@@ -16,7 +16,7 @@ v {xschem version=3.4.4 file_version=1.2
}
G {}
K {type=pmos
-lvs_format="@name @pinlist @model L=@L W=@W ng=@ng m=@m rfmode=@rfmode"
+lvs_format="@spiceprefix@name @pinlist @model L=@L W=@W ng=@ng m=@m rfmode=@rfmode"
format="@spiceprefix@name @pinlist @model W=@W L=@L ng=@ng m=@m rfmode=@rfmode"
template="name=M1
L=0.45u
@@ -26,7 +26,9 @@ m=1
rfmode=1
model=sg13_lv_pmos
spiceprefix=X
-"}
+"
+drc="fet_drc @name @symname @model @w @l @ng"
+}
V {}
S {}
E {}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/IHP_testcases.sch b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/IHP_testcases.sch
index b3f691c0..2a0d9794 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/IHP_testcases.sch
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/IHP_testcases.sch
@@ -1,4 +1,4 @@
-v {xschem version=3.4.4 file_version=1.2
+v {xschem version=3.4.5 file_version=1.2
* Copyright 2023 IHP PDK Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/ac_lv_nmosrf.sch b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/ac_lv_nmosrf.sch
index d16951b6..4ffdeeba 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/ac_lv_nmosrf.sch
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/ac_lv_nmosrf.sch
@@ -1,4 +1,4 @@
-v {xschem version=3.4.4 file_version=1.2
+v {xschem version=3.4.5 file_version=1.2
}
G {}
K {}
@@ -125,65 +125,61 @@ C {devices/title.sym} -130 260 0 0 {name=l5 author="Copyright 2023 IHP PDK Autho
C {devices/launcher.sym} -210 -300 0 0 {name=h5
descr="load waves Ctrl + left click"
tclcommand="xschem raw_read $netlist_dir/ac_lv_nmosrf.raw ac"}
-C {sg13g2_pr/sg13_lv_rf_nmos.sym} 140 -40 2 1 {name=M1
-L=0.35u
-W=1.0u
-ng=1
+C {devices/lab_pin.sym} 150 -110 1 0 {name=p1 sig_type=std_logic lab=Vout1}
+C {devices/gnd.sym} -170 60 0 0 {name=l6 lab=GND}
+C {devices/gnd.sym} -300 60 0 0 {name=l7 lab=GND}
+C {devices/vsource.sym} -300 10 0 0 {name=Vgs1 value="dc 0.75 ac 0.01 "}
+C {devices/vsource.sym} -40 -30 0 0 {name=Vds2 value=1.5}
+C {devices/gnd.sym} -40 60 0 0 {name=l8 lab=GND}
+C {devices/gnd.sym} -120 60 0 0 {name=l9 lab=GND}
+C {devices/lab_pin.sym} -180 -100 1 0 {name=p2 sig_type=std_logic lab=Vout2}
+C {sg13g2_pr/rppd.sym} -250 -30 3 0 {name=R1
+w=0.5e-6
+l=0.5e-6
+model=rppd
+spiceprefix=X
+b=0
m=1
-rfmode=1
-model=sg13_lv_nmos
+}
+C {sg13g2_pr/rppd.sym} -110 -100 3 0 {name=R2
+w=0.5e-6
+l=0.5e-6
+model=rppd
spiceprefix=X
+b=0
+m=1
}
-C {sg13g2_pr/rppd.sym} 220 -110 3 0 {name=R1
-W=0.2e-6
-L=0.5e-5
+C {sg13g2_pr/rppd.sym} 80 -40 3 0 {name=R3
+w=0.5e-6
+l=0.5e-6
model=rppd
spiceprefix=X
+b=0
m=1
-R=7.0
-Imax=0.3e-6
}
-C {devices/lab_pin.sym} 150 -110 1 0 {name=p1 sig_type=std_logic lab=Vout1}
-C {sg13g2_pr/rppd.sym} 80 -40 3 0 {name=R2
-W=0.2e-6
-L=0.5e-5
+C {sg13g2_pr/rppd.sym} 220 -110 3 0 {name=R4
+w=0.5e-6
+l=0.5e-6
model=rppd
spiceprefix=X
+b=0
m=1
-R=7.0
-Imax=0.3e-6
}
-C {devices/gnd.sym} -170 60 0 0 {name=l6 lab=GND}
-C {devices/gnd.sym} -300 60 0 0 {name=l7 lab=GND}
-C {devices/vsource.sym} -300 10 0 0 {name=Vgs1 value="dc 0.75 ac 0.01 "}
-C {devices/vsource.sym} -40 -30 0 0 {name=Vds2 value=1.5}
-C {devices/gnd.sym} -40 60 0 0 {name=l8 lab=GND}
-C {devices/gnd.sym} -120 60 0 0 {name=l9 lab=GND}
-C {sg13g2_pr/sg13_lv_rf_nmos.sym} -190 -30 2 1 {name=M2
-L=0.35u
-W=1.0u
+C {sg13g2_pr/sg13_lv_rf_nmos.sym} -190 -30 2 1 {name=M1
+l=0.35u
+w=1.0u
ng=1
m=1
rfmode=0
model=sg13_lv_nmos
spiceprefix=X
}
-C {sg13g2_pr/rppd.sym} -110 -100 3 0 {name=R3
-W=0.2e-6
-L=0.5e-5
-model=rppd
-spiceprefix=X
+C {sg13g2_pr/sg13_lv_rf_nmos.sym} 140 -40 2 1 {name=M2
+l=0.35u
+w=1.0u
+ng=1
m=1
-R=7.0
-Imax=0.3e-6
-}
-C {devices/lab_pin.sym} -180 -100 1 0 {name=p2 sig_type=std_logic lab=Vout2}
-C {sg13g2_pr/rppd.sym} -250 -30 3 0 {name=R4
-W=0.2e-6
-L=0.5e-5
-model=rppd
+rfmode=1
+model=sg13_lv_nmos
spiceprefix=X
-m=1
-R=7.0
-Imax=0.3e-6
}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/ac_mim_cap.sch b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/ac_mim_cap.sch
index 0a1ea33a..74b17ccd 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/ac_mim_cap.sch
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/ac_mim_cap.sch
@@ -1,4 +1,4 @@
-v {xschem version=3.4.4 file_version=1.2
+v {xschem version=3.4.5 file_version=1.2
* Copyright 2021 Stefan Frederik Schippers
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -39,8 +39,8 @@ dataset=-1
unitx=1
logx=1
logy=1
-y1=-1.4
-y2=-2.5e-07
+y1=-0.26
+y2=-7.3e-07
color=4
node=mag
rainbow=1}
@@ -92,8 +92,8 @@ m=1}
C {devices/gnd.sym} 690 -230 0 0 {name=l5 lab=GND}
C {devices/lab_pin.sym} 370 -400 1 0 {name=p1 sig_type=std_logic lab=in}
C {devices/lab_pin.sym} 690 -390 1 0 {name=p2 sig_type=std_logic lab=out}
-C {sg13g2_pr/cap_cmim.sym} 530 -380 1 0 {name=C1 model=cap_cmim W=7.0e-6 L=7.0e-6 MF=1 spiceprefix=X}
C {devices/launcher.sym} 200 -740 0 0 {name=h5
descr="load waves"
tclcommand="xschem raw_read $netlist_dir/ac_mim_cap.raw ac"
}
+C {sg13g2_pr/cap_cmim.sym} 530 -380 1 0 {name=C1 model=cap_cmim w=10.0e-6 l=70.0e-6 m=1 spiceprefix=X}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_diode_op.sch b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_diode_op.sch
index 0ddc79fd..82541c69 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_diode_op.sch
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_diode_op.sch
@@ -1,4 +1,4 @@
-v {xschem version=3.4.4 file_version=1.2
+v {xschem version=3.4.5 file_version=1.2
}
G {}
K {}
@@ -67,23 +67,25 @@ write dc_diode_op.raw
wrdata dc_diode.csv I(Vmda) I(Vmdp)
.endc
"}
-C {sg13g2_pr/dantenna.sym} -350 10 2 0 {name=XD1
-model=dantenna
-l=780n
-w=780n
-}
C {devices/title.sym} -360 130 0 0 {name=l5 author="Copyright 2023 IHP PDK Authors"}
C {devices/launcher.sym} -470 -260 0 0 {name=h5
descr="Load IV curve"
tclcommand="xschem raw_read $netlist_dir/dc_diode_op.raw dc"
}
C {devices/gnd.sym} -170 50 0 0 {name=l3 lab=GND}
-C {sg13g2_pr/dpantenna.sym} -170 10 2 0 {name=XD2
-model=dpantenna
-l=780n
-w=780n
-}
C {devices/gnd.sym} -350 50 0 0 {name=l1 lab=GND}
C {devices/vsource.sym} -500 -10 0 0 {name=V1 value=0.7}
C {devices/ammeter.sym} -350 -60 0 0 {name=Vmda}
C {devices/ammeter.sym} -170 -60 0 0 {name=Vmdp}
+C {sg13g2_pr/dpantenna.sym} -350 10 2 0 {name=D2
+model=dpantenna
+l=0.78u
+w=0.78u
+spiceprefix=X
+}
+C {sg13g2_pr/dantenna.sym} -170 10 2 0 {name=D1
+model=dantenna
+l=0.78u
+w=0.78u
+spiceprefix=X
+}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_hbt_13g2.sch b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_hbt_13g2.sch
index e9a10a10..222a3786 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_hbt_13g2.sch
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_hbt_13g2.sch
@@ -1,4 +1,4 @@
-v {xschem version=3.4.4 file_version=1.2
+v {xschem version=3.4.5 file_version=1.2
}
G {}
K {}
@@ -7,7 +7,7 @@ S {}
E {}
B 2 -280 -540 520 -140 {flags=graph
-y2=0.0026
+y2=0.017
ypos1=0
ypos2=2
divy=5
@@ -24,7 +24,7 @@ logx=0
logy=0
color=4
node=i(Vc)
-y1=-5.5e-05
+y1=-0.00023
rainbow=0}
T {Nx - number of emitters} -210 110 0 0 0.2 0.2 {}
N -300 60 -300 80 {
@@ -76,9 +76,10 @@ C {devices/launcher.sym} 70 -70 0 0 {name=h5
descr="load waves"
tclcommand="xschem raw_read $netlist_dir/test_npn_13G2.raw dc"
}
+C {devices/isource.sym} -300 30 2 0 {name=I0 value=1u}
+C {devices/ammeter.sym} -110 -80 1 0 {name=Vc}
C {sg13g2_pr/npn13G2.sym} -190 -10 0 0 {name=Q1
model=npn13G2
spiceprefix=X
-Nx=1}
-C {devices/isource.sym} -300 30 2 0 {name=I0 value=1u}
-C {devices/ammeter.sym} -110 -80 1 0 {name=Vc}
+Nx=1
+le=0.9e-6}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_hv_nmos.sch b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_hv_nmos.sch
index 47fb68d5..4b3fd329 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_hv_nmos.sch
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_hv_nmos.sch
@@ -1,4 +1,4 @@
-v {xschem version=3.4.4 file_version=1.2
+v {xschem version=3.4.5 file_version=1.2
}
G {}
K {}
@@ -75,12 +75,12 @@ C {devices/launcher.sym} -200 -160 0 0 {name=h5
descr="load waves Ctrl + left click"
tclcommand="xschem raw_read $netlist_dir/dc_hv_nmos.raw dc"
}
+C {devices/ammeter.sym} 80 -70 1 0 {name=Vd}
C {sg13g2_pr/sg13_hv_nmos.sym} 0 0 2 1 {name=M1
-L=0.45u
-W=1.0u
+l=0.45u
+w=1.0u
ng=1
m=1
model=sg13_hv_nmos
spiceprefix=X
}
-C {devices/ammeter.sym} 80 -70 1 0 {name=Vd}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_hv_pmos.sch b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_hv_pmos.sch
index 8be1d68b..ca5b5cd1 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_hv_pmos.sch
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_hv_pmos.sch
@@ -1,4 +1,4 @@
-v {xschem version=3.4.4 file_version=1.2
+v {xschem version=3.4.5 file_version=1.2
}
G {}
K {}
@@ -6,19 +6,20 @@ V {}
S {}
E {}
B 2 150 -510 950 -110 {flags=graph
-y1=0
-y2=1.1e-05
+y1=-1.1e-05
+y2=0
ypos1=0
ypos2=2
divy=5
subdivy=1
unity=1
-x1=0
-x2=-2
+x1=-2
+x2=0
divx=5
subdivx=1
-node=i(vds)
-color=4
+node="i(vds)
+i(vd)"
+color="4 4"
dataset=-1
unitx=1
logx=0
@@ -77,8 +78,8 @@ descr="load waves"
tclcommand="xschem raw_read $netlist_dir/dc_hv_pmos.raw dc"
}
C {sg13g2_pr/sg13_hv_pmos.sym} 0 0 2 1 {name=M1
-L=0.45u
-W=1.0u
+l=0.45u
+w=1.0u
ng=1
m=1
model=sg13_hv_pmos
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_logic_not.sch b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_logic_not.sch
index e67ff877..4c90701d 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_logic_not.sch
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_logic_not.sch
@@ -98,16 +98,16 @@ descr="load waves Ctrl + left click"
tclcommand="xschem raw_read $netlist_dir/dc_logic_not.raw dc"
}
C {sg13g2_pr/sg13_lv_nmos.sym} 0 30 2 1 {name=M1
-L=0.45u
-W=1.0u
+l=0.45u
+w=1.0u
ng=1
m=1
model=sg13_lv_nmos
spiceprefix=X
}
C {sg13g2_pr/sg13_lv_pmos.sym} 0 -70 0 0 {name=M2
-L=0.45u
-W=1.0u
+l=0.45u
+w=1.0u
ng=1
m=1
model=sg13_lv_pmos
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_lv_nmos.sch b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_lv_nmos.sch
index 23a0c16d..667b8852 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_lv_nmos.sch
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_lv_nmos.sch
@@ -1,4 +1,4 @@
-v {xschem version=3.4.4 file_version=1.2
+v {xschem version=3.4.5 file_version=1.2
}
G {}
K {}
@@ -73,12 +73,12 @@ C {devices/launcher.sym} 310 90 0 0 {name=h5
descr="load waves Ctrl + left click"
tclcommand="xschem raw_read $netlist_dir/dc_lv_nmos.raw dc"
}
+C {devices/ammeter.sym} 80 -70 1 0 {name=Vd}
C {sg13g2_pr/sg13_lv_nmos.sym} 0 0 2 1 {name=M1
-L=0.45u
-W=1.0u
-ng=1
+l=0.13u
+w=12.7u
+ng=2
m=1
model=sg13_lv_nmos
spiceprefix=X
}
-C {devices/ammeter.sym} 80 -70 1 0 {name=Vd}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_lv_pmos.sch b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_lv_pmos.sch
index 33f44c63..4a8f3ff5 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_lv_pmos.sch
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_lv_pmos.sch
@@ -1,4 +1,4 @@
-v {xschem version=3.4.4 file_version=1.2
+v {xschem version=3.4.5 file_version=1.2
}
G {}
K {}
@@ -81,8 +81,8 @@ descr="load waves"
tclcommand="xschem raw_read $netlist_dir/dc_lv_pmos.raw dc"
}
C {sg13g2_pr/sg13_lv_pmos.sym} 0 0 2 1 {name=M1
-L=0.45u
-W=1.0u
+l=0.45u
+w=5.0u
ng=1
m=1
model=sg13_lv_pmos
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_mos_cs_temp.sch b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_mos_cs_temp.sch
index 56040879..9f41aa8f 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_mos_cs_temp.sch
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_mos_cs_temp.sch
@@ -1,4 +1,4 @@
-v {xschem version=3.4.4 file_version=1.2
+v {xschem version=3.4.5 file_version=1.2
}
G {}
K {}
@@ -38,9 +38,7 @@ N -20 50 30 50 {
lab=GND}
N 80 50 80 140 {
lab=GND}
-N -70 50 -60 50 {
-lab=Vgs1}
-N -130 50 -70 50 {
+N -90 50 -60 50 {
lab=Vgs1}
N -20 0 -20 20 {
lab=Vgs1}
@@ -50,11 +48,7 @@ N 240 50 290 50 {
lab=GND}
N 290 50 290 140 {
lab=GND}
-N 190 50 200 50 {
-lab=Vgs2}
-N 130 50 190 50 {
-lab=Vgs2}
-N 240 0 240 20 {
+N 170 50 200 50 {
lab=Vgs2}
N 640 80 640 140 {
lab=GND}
@@ -62,9 +56,7 @@ N 640 50 690 50 {
lab=GND}
N 690 50 690 140 {
lab=GND}
-N 590 50 600 50 {
-lab=Vgs3}
-N 530 50 590 50 {
+N 560 50 600 50 {
lab=Vgs3}
N 640 0 640 20 {
lab=Vgs3}
@@ -74,11 +66,7 @@ N 870 50 920 50 {
lab=GND}
N 920 50 920 140 {
lab=GND}
-N 820 50 830 50 {
-lab=Vgs4}
-N 760 50 820 50 {
-lab=Vgs4}
-N 870 0 870 20 {
+N 790 50 830 50 {
lab=Vgs4}
N -90 0 -20 0 {
lab=Vgs1}
@@ -90,7 +78,7 @@ N -20 -40 -20 0 {
lab=Vgs1}
N 240 -120 240 -100 {
lab=GND}
-N 240 -40 240 0 {
+N 240 -10 240 20 {
lab=Vgs2}
N 640 -30 640 0 {
lab=Vgs3}
@@ -98,7 +86,7 @@ N 640 -110 640 -90 {
lab=GND}
N 870 -110 870 -90 {
lab=GND}
-N 870 -30 870 0 {
+N 870 -10 870 20 {
lab=Vgs4}
N 560 0 560 50 {
lab=Vgs3}
@@ -114,6 +102,18 @@ N 170 -10 240 -10 {
lab=Vgs2}
N 30 50 30 140 {
lab=GND}
+N -130 50 -90 50 {
+lab=Vgs1}
+N 530 50 560 50 {
+lab=Vgs3}
+N 760 50 790 50 {
+lab=Vgs4}
+N 870 -30 870 -10 {
+lab=Vgs4}
+N 130 50 170 50 {
+lab=Vgs2}
+N 240 -40 240 -10 {
+lab=Vgs2}
C {devices/code_shown.sym} -320 -630 0 0 {name=MODEL only_toplevel=true
format="tcleval( @value )"
value="
@@ -125,7 +125,7 @@ value="
.savecurrents
.param temp=27
.control
-* pre_osdi ./psp103_nqs.osdi
+pre_osdi ./psp103_nqs.osdi
save all
dc temp -40 125 1
write mos_temp.raw
@@ -140,8 +140,8 @@ descr="load waves Ctrl + left click"
tclcommand="xschem raw_read $netlist_dir/mos_temp.raw dc"
}
C {sg13g2_pr/sg13_lv_nmos.sym} -40 50 2 1 {name=M1
-L=1.0u
-W=2.0u
+l=1.0u
+w=2.0u
ng=1
m=1
model=sg13_lv_nmos
@@ -152,8 +152,8 @@ C {devices/gnd.sym} 240 140 0 0 {name=l6 lab=GND}
C {devices/gnd.sym} 290 140 0 0 {name=l7 lab=GND}
C {devices/lab_pin.sym} 130 50 0 0 {name=p5 sig_type=std_logic lab=Vgs2}
C {sg13g2_pr/sg13_hv_nmos.sym} 220 50 2 1 {name=M2
-L=1.0u
-W=2.0u
+l=1.0u
+w=2.0u
ng=1
m=1
model=sg13_hv_nmos
@@ -166,16 +166,16 @@ C {devices/gnd.sym} 870 140 0 0 {name=l10 lab=GND}
C {devices/gnd.sym} 920 140 0 0 {name=l11 lab=GND}
C {devices/lab_pin.sym} 760 50 0 0 {name=p9 sig_type=std_logic lab=Vgs4}
C {sg13g2_pr/sg13_lv_pmos.sym} 620 50 2 1 {name=M3
-L=1.0u
-W=2.0u
+l=1.0u
+w=2.0u
ng=1
m=1
model=sg13_lv_pmos
spiceprefix=X
}
C {sg13g2_pr/sg13_hv_pmos.sym} 850 50 2 1 {name=M4
-L=1.0u
-W=2.0u
+l=1.0u
+w=2.0u
ng=1
m=1
model=sg13_hv_pmos
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_mos_temp.sch b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_mos_temp.sch
index f0e8119d..bf41022d 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_mos_temp.sch
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_mos_temp.sch
@@ -132,8 +132,8 @@ descr="load waves Ctrl + left click"
tclcommand="xschem raw_read $netlist_dir/mos_temp.raw dc"
}
C {sg13g2_pr/sg13_lv_nmos.sym} -40 110 2 1 {name=M1
-L=0.35u
-W=1.0u
+l=0.35u
+w=1.0u
ng=1
m=1
model=sg13_lv_nmos
@@ -150,8 +150,8 @@ C {devices/lab_pin.sym} 80 110 0 0 {name=p5 sig_type=std_logic lab=Vgs}
C {devices/ammeter.sym} 190 30 0 0 {name=Vm2}
C {devices/lab_pin.sym} 190 -20 2 0 {name=p6 sig_type=std_logic lab=Vds}
C {sg13g2_pr/sg13_hv_nmos.sym} 170 110 2 1 {name=M2
-L=0.35u
-W=1.0u
+l=0.35u
+w=1.0u
ng=1
m=1
model=sg13_hv_nmos
@@ -168,16 +168,16 @@ C {devices/lab_pin.sym} 760 110 0 0 {name=p9 sig_type=std_logic lab=Vgsp}
C {devices/ammeter.sym} 870 30 0 0 {name=Vm4}
C {devices/lab_pin.sym} 870 -20 2 0 {name=p10 sig_type=std_logic lab=Vdsp}
C {sg13g2_pr/sg13_lv_pmos.sym} 640 110 2 1 {name=M3
-L=0.35u
-W=1.0u
+l=0.35u
+w=1.0u
ng=1
m=1
model=sg13_lv_pmos
spiceprefix=X
}
C {sg13g2_pr/sg13_hv_pmos.sym} 850 110 2 1 {name=M4
-L=0.35u
-W=1.0u
+l=0.35u
+w=1.0u
ng=1
m=1
model=sg13_hv_pmos
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_res_temp.sch b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_res_temp.sch
index 751bc475..a46ed3dd 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_res_temp.sch
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/dc_res_temp.sch
@@ -95,30 +95,27 @@ C {devices/gnd.sym} 240 90 0 0 {name=l2 lab=GND}
C {devices/ammeter.sym} 240 -40 0 0 {name=Vppd}
C {devices/gnd.sym} 420 90 0 0 {name=l4 lab=GND}
C {devices/ammeter.sym} 420 -40 0 0 {name=Vrh}
+C {sg13g2_pr/rsil.sym} 90 40 0 0 {name=R1
+w=0.5e-6
+l=1.5e-6
+model=rsil
+spiceprefix=X
+b=0
+m=1
+}
C {sg13g2_pr/rppd.sym} 240 40 0 0 {name=R2
-W=0.5e-6
-L=2.5e-6
+w=0.5e-6
+l=0.5e-6
model=rppd
spiceprefix=X
+b=0
m=1
-R=7.0
-Imax=0.3e-6
}
C {sg13g2_pr/rhigh.sym} 420 40 0 0 {name=R3
-W=0.5e-6
-L=2.0e-6
+w=0.5e-6
+l=0.5e-6
model=rhigh
spiceprefix=X
-m=1
-R=1360.0
-Imax=0.3e-6
-}
-C {sg13g2_pr/rsil.sym} 90 40 0 0 {name=R1
-W=0.5e-5
-L=0.5e-5
-model=rsil
-spiceprefix=X
b=0
m=1
-
}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/mc_hv_nmos_cs_loop.sch b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/mc_hv_nmos_cs_loop.sch
index cbc4de0e..74fdac23 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/mc_hv_nmos_cs_loop.sch
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/mc_hv_nmos_cs_loop.sch
@@ -78,8 +78,8 @@ C {devices/isource.sym} 480 -150 0 0 {name=I0 value=10u}
C {devices/gnd.sym} 480 -200 2 0 {name=l2 lab=GND}
C {devices/lab_pin.sym} 380 -100 0 0 {name=p1 sig_type=std_logic lab=Vgs}
C {sg13g2_pr/sg13_hv_nmos.sym} 460 -50 2 1 {name=M1
-L=1.0u
-W=2.0u
+l=1.0u
+w=2.0u
ng=1
m=1
model=sg13_hv_nmos
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/mc_hv_pmos_cs_loop.sch b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/mc_hv_pmos_cs_loop.sch
index bce4ec87..bd64efd3 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/mc_hv_pmos_cs_loop.sch
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/mc_hv_pmos_cs_loop.sch
@@ -77,8 +77,8 @@ C {devices/isource.sym} 480 -150 2 0 {name=I0 value=10u}
C {devices/gnd.sym} 480 -200 2 0 {name=l2 lab=GND}
C {devices/lab_pin.sym} 380 -100 0 0 {name=p1 sig_type=std_logic lab=Vgs}
C {sg13g2_pr/sg13_hv_pmos.sym} 460 -50 2 1 {name=M1
-L=1.0u
-W=2.0u
+l=1.0u
+w=2.0u
ng=1
m=1
model=sg13_hv_pmos
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/mc_lv_nmos_cs_loop.sch b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/mc_lv_nmos_cs_loop.sch
index d18094d0..59506d14 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/mc_lv_nmos_cs_loop.sch
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/mc_lv_nmos_cs_loop.sch
@@ -76,8 +76,8 @@ C {devices/isource.sym} 480 -150 0 0 {name=I0 value=10u}
C {devices/gnd.sym} 480 -200 2 0 {name=l2 lab=GND}
C {devices/lab_pin.sym} 380 -100 0 0 {name=p1 sig_type=std_logic lab=Vgs}
C {sg13g2_pr/sg13_lv_nmos.sym} 460 -50 2 1 {name=M1
-L=1.0u
-W=2.0u
+l=1.0u
+w=2.0u
ng=1
m=1
model=sg13_lv_nmos
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/mc_lv_pmos_cs_loop.sch b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/mc_lv_pmos_cs_loop.sch
index 7a0cfc63..8252dcba 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/mc_lv_pmos_cs_loop.sch
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/mc_lv_pmos_cs_loop.sch
@@ -77,8 +77,8 @@ C {devices/isource.sym} 480 -150 2 0 {name=I0 value=10u}
C {devices/gnd.sym} 480 -200 2 0 {name=l2 lab=GND}
C {devices/lab_pin.sym} 380 -100 0 0 {name=p1 sig_type=std_logic lab=Vgs}
C {sg13g2_pr/sg13_lv_pmos.sym} 460 -50 2 1 {name=M1
-L=1.0u
-W=2.0u
+l=1.0u
+w=2.0u
ng=1
m=1
model=sg13_lv_pmos
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/mc_mim_cap_ac.sch b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/mc_mim_cap_ac.sch
index 371a8066..f734c33a 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/mc_mim_cap_ac.sch
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/mc_mim_cap_ac.sch
@@ -76,4 +76,4 @@ m=1}
C {devices/gnd.sym} 420 -270 0 0 {name=l5 lab=GND}
C {devices/lab_pin.sym} 100 -440 1 0 {name=p1 sig_type=std_logic lab=in}
C {devices/lab_pin.sym} 420 -430 1 0 {name=p2 sig_type=std_logic lab=out}
-C {sg13g2_pr/cap_cmim.sym} 260 -420 1 0 {name=C1 model=cap_cmim W=7.0e-6 L=7.0e-6 MF=1 spiceprefix=X}
+C {sg13g2_pr/cap_cmim.sym} 260 -420 1 0 {name=C1 model=cap_cmim w=7.0e-6 l=7.0e-6 MF=1 spiceprefix=X}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/mc_res_op.sch b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/mc_res_op.sch
index a46e119d..72ccb551 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/mc_res_op.sch
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/mc_res_op.sch
@@ -1,4 +1,4 @@
-v {xschem version=3.4.4 file_version=1.2
+v {xschem version=3.4.5 file_version=1.2
}
G {}
K {}
@@ -91,8 +91,8 @@ C {devices/gnd.sym} 760 100 0 0 {name=l2 lab=GND}
C {devices/ammeter.sym} 760 -30 0 0 {name=Vppd}
C {devices/gnd.sym} 940 100 0 0 {name=l4 lab=GND}
C {sg13g2_pr/rhigh.sym} 940 50 0 0 {name=R3
-W=1.0e-6
-L=1.0e-6
+w=1.0e-6
+l=1.0e-6
model=rhigh
spiceprefix=X
m=1
@@ -101,8 +101,8 @@ Imax=0.11e-4
}
C {devices/ammeter.sym} 940 -30 0 0 {name=Vrh}
C {sg13g2_pr/rsil.sym} 610 50 0 0 {name=R1
-W=0.5e-6
-L=0.5e-5
+w=0.5e-6
+l=0.5e-5
model=rsil
spiceprefix=X
m=1
@@ -110,8 +110,8 @@ R=7.0
Imax=0.3e-6
}
C {sg13g2_pr/rppd.sym} 760 50 0 0 {name=R2
-W=0.5e-6
-L=0.5e-6
+w=0.5e-6
+l=0.5e-6
model=rppd
spiceprefix=X
m=1
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/sp_mim_cap.sch b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/sp_mim_cap.sch
index aa7ec63b..8d9c44c5 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/sp_mim_cap.sch
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/sp_mim_cap.sch
@@ -141,4 +141,4 @@ C {devices/launcher.sym} 900 -650 0 0 {name=h5
descr="load waves"
tclcommand="xschem raw_read $netlist_dir/sp_mim_cap.raw ac"
}
-C {sg13g2_pr/cap_cmim.sym} 530 -380 1 0 {name=C1 model=cap_cmim W=7.0e-6 L=7.0e-6 MF=1 spiceprefix=X}
+C {sg13g2_pr/cap_cmim.sym} 530 -380 1 0 {name=C1 model=cap_cmim w=7.0e-6 l=7.0e-6 MF=1 spiceprefix=X}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/sp_rfmim_cap.sch b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/sp_rfmim_cap.sch
index 559101ee..b7ef5731 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/sp_rfmim_cap.sch
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/sp_rfmim_cap.sch
@@ -1,4 +1,4 @@
-v {xschem version=3.4.4 file_version=1.2
+v {xschem version=3.4.5 file_version=1.2
* Copyright 2021 Stefan Frederik Schippers
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -167,4 +167,9 @@ descr="load waves"
tclcommand="xschem raw_read $netlist_dir/sp_rfmim_cap.raw ac"
}
C {devices/gnd.sym} 530 -230 0 0 {name=l2 lab=GND}
-C {sg13g2_pr/cap_rfcmim.sym} 530 -380 3 0 {name=C1 model=cap_rfcmim W=7.0e-6 L=7.0e-6 wfeed=5.0e-6 spiceprefix=X}
+C {sg13g2_pr/cap_rfcmim.sym} 530 -380 3 0 {name=C1
+model=cap_rfcmim
+w=2.0e-6
+l=2.0e-6
+wfeed=5.0e-6
+spiceprefix=X}
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/tran_logic_nand.sch b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/tran_logic_nand.sch
index bb45bd76..a57d83b1 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/tran_logic_nand.sch
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/tran_logic_nand.sch
@@ -153,7 +153,7 @@ value="
pre_osdi ./psp103_nqs.osdi
save all
tran 50p 20n
-meas tran tdelay TRIG v(b) VAL=0.9 FALL=1 TARG v(out) VAL=0.9 RISE=1
+meas tran tdelay TRIG v(b) VAl=0.9 FALl=1 TARG v(out) VAl=0.9 RISE=1
write tran_logic_nand.raw
.endc
"}
@@ -169,16 +169,16 @@ descr="load waves Ctrl + left click"
tclcommand="xschem raw_read $netlist_dir/tran_logic_nand.raw tran"
}
C {sg13g2_pr/sg13_lv_nmos.sym} 80 40 2 1 {name=M1
-L=0.45u
-W=1.0u
+l=0.45u
+w=1.0u
ng=1
m=1
model=sg13_lv_nmos
spiceprefix=X
}
C {sg13g2_pr/sg13_lv_pmos.sym} -70 -190 0 0 {name=M2
-L=0.45u
-W=1.0u
+l=0.45u
+w=1.0u
ng=1
m=1
model=sg13_lv_pmos
@@ -187,16 +187,16 @@ spiceprefix=X
C {devices/lab_pin.sym} -190 40 0 0 {name=p1 sig_type=std_logic lab=A}
C {devices/lab_pin.sym} 240 -90 2 0 {name=p2 sig_type=std_logic lab=out}
C {sg13g2_pr/sg13_lv_pmos.sym} 160 -190 0 0 {name=M3
-L=0.45u
-W=1.0u
+l=0.45u
+w=1.0u
ng=1
m=1
model=sg13_lv_pmos
spiceprefix=X
}
C {sg13g2_pr/sg13_lv_nmos.sym} 80 -40 2 1 {name=M4
-L=0.45u
-W=1.0u
+l=0.45u
+w=1.0u
ng=1
m=1
model=sg13_lv_nmos
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/tran_logic_not.sch b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/tran_logic_not.sch
index 47f012d9..bd09c652 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/tran_logic_not.sch
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/tran_logic_not.sch
@@ -1,4 +1,4 @@
-v {xschem version=3.4.4 file_version=1.2
+v {xschem version=3.4.5 file_version=1.2
}
G {}
K {}
@@ -68,7 +68,7 @@ N -230 -80 -230 -30 {
lab=in}
N -160 -50 -160 -30 {
lab=out}
-C {devices/code_shown.sym} -290 190 0 0 {name=MODEL only_toplevel=true
+C {devices/code_shown.sym} -300 170 0 0 {name=MODEL only_toplevel=true
format="tcleval( @value )"
value="
.lib $::SG13G2_MODELS/cornerMOSlv.lib mos_tt
@@ -81,7 +81,7 @@ value="
pre_osdi ./psp103_nqs.osdi
save all
tran 50p 20n
-meas tran tdelay TRIG v(in) VAL=0.9 FALL=1 TARG v(out) VAL=0.9 RISE=1
+meas tran tdelay TRIG v(in) VAl=0.9 FALl=1 TARG v(out) VAl=0.9 RISE=1
write tran_logic_not.raw
.endc
"}
@@ -97,16 +97,16 @@ descr="load waves Ctrl + left click"
tclcommand="xschem raw_read $netlist_dir/tran_logic_not.raw tran"
}
C {sg13g2_pr/sg13_lv_nmos.sym} -180 20 2 1 {name=M1
-L=0.45u
-W=1.0u
+l=0.45u
+w=1.0u
ng=1
m=1
model=sg13_lv_nmos
spiceprefix=X
}
C {sg13g2_pr/sg13_lv_pmos.sym} -180 -80 0 0 {name=M2
-L=0.45u
-W=1.0u
+l=0.45u
+w=1.0u
ng=1
m=1
model=sg13_lv_pmos
diff --git a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/tran_mim_cap.sch b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/tran_mim_cap.sch
index eff379d3..0ef32e27 100644
--- a/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/tran_mim_cap.sch
+++ b/ihp-sg13g2/libs.tech/xschem/sg13g2_tests/tran_mim_cap.sch
@@ -1,4 +1,4 @@
-v {xschem version=3.4.4 file_version=1.2
+v {xschem version=3.4.5 file_version=1.2
* Copyright 2021 Stefan Frederik Schippers
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -101,4 +101,9 @@ C {devices/launcher.sym} 780 -450 0 0 {name=h5
descr="load waves"
tclcommand="xschem raw_read $netlist_dir/test_mim_cap.raw tran"
}
-C {sg13g2_pr/cap_cmim.sym} 40 -220 0 0 {name=C2 model=cap_cmim W=7.0e-6 L=7.0e-6 MF=1 spiceprefix=X}
+C {sg13g2_pr/cap_cmim.sym} 40 -220 0 0 {name=C2
+model=cap_cmim
+w=7.0e-6
+l=7.0e-6
+m=1
+spiceprefix=X}
diff --git a/ihp-sg13g2/libs.tech/xschem/xschemrc b/ihp-sg13g2/libs.tech/xschem/xschemrc
index b8e09394..0ff48a00 100755
--- a/ihp-sg13g2/libs.tech/xschem/xschemrc
+++ b/ihp-sg13g2/libs.tech/xschem/xschemrc
@@ -430,3 +430,180 @@ append XSCHEM_LIBRARY_PATH :${PDK_ROOT}/${PDK}/libs.tech/xschem
if { [info exists ::env(XSCHEM_USER_LIBRARY_PATH) ] } {
append XSCHEM_LIBRARY_PATH :$env(XSCHEM_USER_LIBRARY_PATH)
}
+
+############################################################### DRC checks #######################################
+# IHP SG13G2 mosfets dimension checks
+proc fet_drc {instance symbol model w l ng } {
+ set res {}
+ # strip off the "u" suffix
+ regsub {u$} $w {} w
+ regsub {u$} $l {} l
+ # puts "$instance $model $symbol w=$w l=$l nf=$nf"
+ if { [string is double $w] && [string is double $l] && [string is integer $ng]} {
+
+ # calculate finger width
+ set w [expr { double($w) / double($ng)}]
+
+ switch -regexp $model {
+ {sg13_lv_nmos$} {
+ if { $w < 0.13 } {
+ append res "${instance} ($model): finger width is too small, w/ng = $w, min. w/ng > 0.13u" \n
+ }
+ if { $w > 10.0 } {
+ append res "${instance} ($model): finger width is too big, w/ng = $w, max. w/ng < 10.0u" \n
+ }
+ if { $l < 0.13 } {
+ append res "${instance} ($model): length is too small, l = $l, min l > 0.13u" \n
+ }
+ }
+ {sg13_lv_pmos$} {
+ if { $w < 0.13 } {
+ append res "${instance} ($model): finger width is too small, w/ng = $w, min. w/ng > 0.13u" \n
+ }
+ if { $w > 10.0 } {
+ append res "${instance} ($model): finger width is too big, w/ng = $w, max. w/ng < 10.0u" \n
+ }
+ if { $l < 0.13 } {
+ append res "${instance} ($model): length is too small, l = $l, min. l > 0.13u" \n
+ }
+ }
+ {sg13_hv_nmos$} {
+ if { $w < 0.45 } {
+ append res "${instance} ($model): finger width is too small, w/ng = $w, min w/ng > 0.45u" \n
+ }
+ if { $w > 10.0 } {
+ append res "${instance} ($model): finger width is too big, w/ng = $w, max. w/ng < 10.0u" \n
+ }
+ if { $l < 0.13 } {
+ append res "${instance} ($model): length is too small, l = $l, min. l > 0.13u" \n
+ }
+ }
+ {sg13_hv_pmos$} {
+ if { $w < 0.4 } {
+ append res "${instance} ($model): finger width is too small, w/ng = $w, min. w/ng > 0.4u" \n
+ }
+ if { $w > 10.0 } {
+ append res "${instance} ($model): finger width is too big, w/ng = $w, max. w/ng < 10.0u" \n
+ }
+ if { $l < 0.13 } {
+ append res "${instance} ($model): length is too small, l = $l, min. l > 0.13u" \n
+ }
+ }
+ } ;# switch
+ }
+ return $res
+}
+# IHP SG13G2 resistors dimension checks
+proc res_drc {instance symbol model w l } {
+ set res {}
+ # puts "$instance $model $symbol w=$w l=$l nf=$nf"
+ if { [string is double $w] && [string is double $l] } {
+
+ if { $w < 0.5e-6 } {
+ append res "${instance} ($model): resistor width is too small, w = $w, min. w > 0.5u" \n
+ }
+
+ if { $l < 0.5e-6 } {
+ append res "${instance} ($model): resistor length is too small, l = $l, min. l > 0.5u" \n
+ }
+ }
+ return $res
+}
+# IHP SG13G2 MiM capacitor dimension checks
+proc mim_drc {instance symbol model w l } {
+ set res {}
+
+ if { [string is double $w] && [string is double $l] } {
+ set area [expr { double($w) * double($l) * 1.0e+12}]
+
+ if { $w < 1.14e-6 } {
+ append res "${instance} ($model): MiM capacitor width is too small, w = $w, min. w > 1.14 um" \n
+ }
+
+ if { $area < 1.3 } {
+ append res "${instance} ($model): MiM capacitor area is too small, area = $area, min. area > 1.3 um2" \n
+ }
+
+ if { $area > 5625.0 } {
+ append res "${instance} ($model): MiM capacitor area is too big, area = $area, max. area < 5625.0 um2" \n
+ }
+ }
+ return $res
+}
+# IHP SG13G2 HBT dimension checks
+proc hbt_drc {instance symbol model Nx le } {
+ set res {}
+ # puts "$instance $model $symbol w=$w l=$l nf=$nf"
+ if { [string is integer $Nx] && [string is double $le]} {
+
+
+ switch -regexp $model {
+ {npn13G2$} {
+ if { $Nx < 1 } {
+ append res "${instance} ($model): Number of emmiters Nx = $Nx must be in range 1-10" \n
+ }
+ if { $Nx > 10 } {
+ append res "${instance} ($model): Number of emitters Nx = $Nx must be in range 1-10" \n
+ }
+ }
+ {npn13G2l$} {
+ if { $Nx < 1 } {
+ append res "${instance} ($model): Number of emmiters Nx = $Nx must be in range 1-4" \n
+ }
+ if { $Nx > 4 } {
+ append res "${instance} ($model): Number of emitters Nx = $Nx must be in range 1-4" \n
+ }
+ if { $le < 1.0e-6 } {
+ append res "${instance} ($model): Emitter length le = $le too small, min. le > 1.0 um" \n
+ }
+ if { $le > 2.5e-6 } {
+ append res "${instance} ($model): Emitter length le = $le too big, max. le < 2.5 um" \n
+ }
+ }
+ {npn13G2v$} {
+ if { $Nx < 1 } {
+ append res "${instance} ($model): Number of emmiters Nx = $Nx must be in range 1-8" \n
+ }
+ if { $Nx > 8 } {
+ append res "${instance} ($model): Number of emitters Nx = $Nx must be in range 1-8" \n
+ }
+ if { $le < 1.0e-6 } {
+ append res "${instance} ($model): Emitter length le = $le too small, min. le > 1.0 um" \n
+ }
+ if { $le > 5.0e-6 } {
+ append res "${instance} ($model): Emitter length le = $le too big, max. le < 5.0 um" \n
+ }
+ } ;# switch
+ }
+ }
+ return $res
+}
+# IHP SG13G2 HBT diodes checks
+proc diode_drc {instance symbol model w l } {
+ set res {}
+ regsub {u$} $w {} w
+ regsub {u$} $l {} l
+ # puts "$instance $model $symbol w=$w l=$l nf=$nf"
+ if { [string is double $w] && [string is double $l]} {
+
+ switch -regexp $model {
+ {dantenna} {
+ if { $w < 0.78 } {
+ append res "${instance} ($model): Diode width w = $w too small, min w > 0.78 um" \n
+ }
+ if { $l < 0.78 } {
+ append res "${instance} ($model): Diode length l = $l too small, min l > 0.78 um" \n
+ }
+ }
+ {dpantenna} {
+ if { $w < 0.78 } {
+ append res "${instance} ($model): Diode width w = $w too small, min w > 0.78 um" \n
+ }
+ if { $l < 0.78 } {
+ append res "${instance} ($model): Diode length l = $l too small, min l > 0.78 um" \n
+ }
+ }
+ } ;# switch
+ }
+ return $res
+}