
# Sky130 Hdl21

Hdl21 PDK package for the open-source SkyWater 130nm PDK.  
https://pypi.org/project/sky130-hdl21/


## About This Technology 

SkyWater 130nm is the first notable silicon PDK to be released as open-source software. 
The Sky130 effort is heavily community driven, with leadership from Google and eFabless.

Related Projects: 

* skywater-pdk 
* open_pdks
* the slack
* ... FIXME ...


## About this PDK Package

`sky130_hdl21` defines a set of `hdl21.ExternalModule`s comprising the essential devices of the SkyWater 130nm open-source PDK, '
and an `compile` method for converting process-portable `hdl21.Primitive` elements into these modules. 


## Installation

Install from PyPi via: 

```
pip install sky130-hdl21
```

And then import the package as `sky130_hdl21`: 

```python
import sky130_hdl21
assert sky130_hdl21.primitives is not None # etc
```

## PDK `Install` Data

Silicon process technologies generally require non-Python data to execute simulations and other tasks. Sky130 is no different. *Those files are not distributed as part of this package.* The `sky130` package defines an Hdl21 `PdkInstallation` type `sky130.Install`, which includes references to any such out-of-Python data, generally in the form of filesystem paths. See the [Hdl21 PDK docs](https://github.com/dan-fritchman/Hdl21#process-technologies) for more background. 

A helpful resource for installing the non-Python portions of the 130nm PDK: 
https://anaconda.org/litex-hub/open_pdks.sky130a

Installable with `conda` via: 

```
conda install -y -c litex-hub open_pdks.sky130a
```

Using the conda-based installation, a typical [sitepdks](https://github.com/dan-fritchman/Hdl21#pdk-installations-and-sites) module might look like:

```python
CONDA_PREFIX = os.environ.get("CONDA_PREFIX")
model_lib = Path(CONDA_PREFIX) / "share/pdk/sky130A/libs.tech/ngspice/sky130.lib.spice"

import sky130_hdl21
sky130_hdl21.install = sky130_hdl21.Install(model_lib=model_lib)
```

Note the conda-based installation supports simulation solely with [ngspice](https://ngspice.sourceforge.io/). Sky130 models compatible with Sandia Labs' [Xyce](https://xyce.sandia.gov/) have been generated by the community, but are less straightforward to find, install, and revision control.

## List of Available Devices

It is important to emphasize that all PDK units are written in microns (μm). We recommend consulting the [SKY130 Device Detail Documentation](https://skywater-pdk.readthedocs.io/en/main/rules/device-details.html) which can provide additional information on these additional components.

1. [MOSFETs](#mosfets)
2. [Generic Resistors](#generic-resistors)
3. [Precision Resistors](#precision-resistors)
4. [Diodes](#diodes)
5. [Bipolar Junction Transistors](#bipolar-junction-transistors)
6. [Capacitors](#capacitors)
7. [Digital Cells](#digital-cells)

### MOSFETs

MOSFETs can be defined using either width (W), length (L) and number of fingers (NF), the SKY130-HDL21 PDK module offers the following components, all with the junction terminals (d,g,s,b) with the exception of NMOS_ISO_20p0V

MOSFETs in Hdl21 are designed to be PDK-agnostic, making it possible select the desired MOS using either model compilation:
```python
import sky130_hdl21
from hdl21.primitives import Mos, MosType, MosFamily, MosVth

a = Mos(vth=MosVth.STD,tp=MosType.NMOS,family=MosFamily.CORE)
sky130_hdl21.compile(a) # a is now an instance of sky130.primitives.NMOS_1p8V_STD
```
Or can be referenced directly using the component name listed below from the `primitives` submodule.

NOTE: If any dimensions are not supplied to the params object, the PDK module will assume the minimal viable dimension of the component that you choose.
```python
from hdl21.prefix import µ
from sky130_hdl21_hdl21 import sky130MosParams as p
import sky130_hdl21.primitives as s

a = s.NMOS_1p8V_STD(p(w=0.2*µ,nf=1))
```

| Component Key      | MosType | MosVth | MosFamily | Component Name                 | Description                     |
|--------------------|---------|--------|-----------|--------------------------------|---------------------------------|
| NMOS_1p8V_STD      | NMOS    | STD    | CORE      | sky130_fd_pr__nfet_01v8        | Standard 1.8V NMOS transistor   |
| NMOS_1p8V_LOW      | NMOS    | LOW    | CORE      | sky130_fd_pr__nfet_01v8_lvt    | Low threshold 1.8V NMOS         |
| PMOS_1p8V_STD      | PMOS    | STD    | CORE      | sky130_fd_pr__pfet_01v8        | Standard 1.8V PMOS transistor   |
| PMOS_1p8V_HIGH     | PMOS    | HIGH   | CORE      | sky130_fd_pr__pfet_01v8_hvt    | High threshold 1.8V PMOS        |
| PMOS_1p8V_LOW      | PMOS    | LOW    | CORE      | sky130_fd_pr__pfet_01v8_lvt    | Low threshold 1.8V PMOS         |
| PMOS_5p5V_D10_STD  | PMOS    | STD    | IO        | sky130_fd_pr__pfet_g5v0d10v5    | Standard 5.5V PMOS with D10     |
| NMOS_5p5V_D10_STD  | NMOS    | STD    | IO        | sky130_fd_pr__nfet_g5v0d10v5    | Standard 5.5V NMOS with D10     |
| PMOS_5p5V_D16_STD  | PMOS    | STD    | IO        | sky130_fd_pr__pfet_g5v0d16v0    | Standard 5.5V PMOS with D16     |
| NMOS_20p0V_STD     | NMOS    | STD    | NONE      | sky130_fd_pr__nfet_20v0        | Standard 20V NMOS transistor    |
| NMOS_20p0V_LOW     | NMOS    | ZERO   | NONE      | sky130_fd_pr__nfet_20v0_zvt    | Zero threshold 20V NMOS         |
| NMOS_ISO_20p0V     | NMOS    | STD    | NONE      | sky130_fd_pr__nfet_20v0_iso    | 5-Terminal Isolated 20V NMOS transistor with an extra terminal called "sub"   |
| PMOS_20p0V         | PMOS    | STD    | NONE      | sky130_fd_pr__pfet_20v0        | Standard 20V PMOS transistor    |
| NMOS_3p3V_NAT      | NMOS    | NATIVE | NONE      | sky130_fd_pr__nfet_03v3_nvt    | Native 3.3V NMOS transistor     |
| NMOS_5p0V_NAT      | NMOS    | NATIVE | NONE      | sky130_fd_pr__nfet_05v0_nvt    | Native 5.0V NMOS transistor     |
| NMOS_20p0V_NAT     | NMOS    | NATIVE | NONE      | sky130_fd_pr__nfet_20v0_nvt    | Native 20V NMOS transistor      |
| ESD_NMOS_1p8V       | NMOS    | STD      | CORE   | sky130_fd_pr__esd_nfet_01v8         | Native ESD 1.8V NMOS, , standard Vth, core family |
| ESD_NMOS_5p5V_D10   | NMOS    | STD      | IO     | sky130_fd_pr__esd_nfet_g5v0d10v5     | ESD NMOS, 5.5V, standard Vth, IO family, D10 variant |
| ESD_NMOS_5p5V_NAT   | NMOS    | NATIVE   | IO     | sky130_fd_pr__esd_nfet_g5v0d10v5_nvt | ESD NMOS, 5.5V, native Vth, IO family, D10 variant |
| ESD_PMOS_5p5V       | PMOS    | STD      | IO     | sky130_fd_pr__esd_pfet_g5v0d10v5     | ESD PMOS, 5.5V, standard Vth, IO family |
### Generic Resistors

Generic resistors are resistors composed of materials used in the Sky130 process and can be defined using either width (W), length (L), 3-terminal resistors are formed of substrates and have an additional substrate terminal.

Generic esistors are not offered with PDK-agnostic compilation and so must be referred to directly with the correct paramtype:
```python
from hdl21.prefix import µ
from sky130_hdl21_hdl21 import Sky130GenResParams as p
from sky130_hdl21_hdl21.primitives import GEN_PO

a = GEN_PO(p(l=0.3 * µ, w=0.18 * µ))
```

| Component Key | Component Name               | Number of Terminals | Description                          |
|---------------|-------------------------------|---------------------|--------------------------------------|
| GEN_PO        | sky130_fd_pr__res_generic_po | 2 (p,n)                  | Generic 2-terminal poly resistor     |
| GEN_L1        | sky130_fd_pr__res_generic_l1 | 2 (p,n)                  | Generic 2-terminal local-interconnect resistor  |
| GEN_M1        | sky130_fd_pr__res_generic_m1 | 2 (p,n)                  | Generic 2-terminal metal-1 resistor  |
| GEN_M2        | sky130_fd_pr__res_generic_m2 | 2 (p,n)                  | Generic 2-terminal metal-2 resistor  |
| GEN_M3        | sky130_fd_pr__res_generic_m3 | 2 (p,n)                  | Generic 2-terminal metal-3 resistor  |
| GEN_M4        | sky130_fd_pr__res_generic_m4 | 2 (p,n)                  | Generic 2-terminal metal-4 resistor  |
| GEN_M5        | sky130_fd_pr__res_generic_m5 | 2 (p,n)                  | Generic 2-terminal metal-5 resistor  |
| GEN_ND        | sky130_fd_pr__res_generic_nd | 3 (p,n,b)                  | Generic 3-terminal N-diff resistor   |
| GEN_PD        | sky130_fd_pr__res_generic_pd | 3 (p,n,b)                  | Generic 3-terminal P-diff resistor   |
| GEN_ISO_PW    | sky130_fd_pr__res_iso_pw     | 3 (p,n,b)                  | Generic 3-terminal isolated PW resistor |

### Precision Resistors

Precision resistors are made of polysilicon and have a fixed width in the SKY130 PDK, and can be defined in HDL only using the "L" parameter. All devices have junction terminals (p,n,b).

**NOTE: UNITS ARE ASSUMED TO BE IN MICRONS FOR PRECISION RESISTORS**

```python
from hdl21.prefix import µ
from sky130_hdl21 import Sky130PrecResParams as p
from sky130_hdl21.primitives import GEN_PO

# NOTE: We assume the units are in microns here
a = GEN_PO(p(L=0.3))
```

| Component Key | Component Name                    | Description                 |
|---------------|------------------------------------|-----------------------------|
| PP_PREC_0p35  | sky130_fd_pr__res_high_po_0p35    | Precision P+ 0.35μm resistor   |
| PP_PREC_0p69  | sky130_fd_pr__res_high_po_0p69    | Precision P+ 0.69μm resistor   |
| PP_PREC_1p41  | sky130_fd_pr__res_high_po_1p41    | Precision P+ 1.41μm resistor   |
| PP_PREC_2p85  | sky130_fd_pr__res_high_po_2p85    | Precision P+ 2.85μm resistor   |
| PP_PREC_5p73  | sky130_fd_pr__res_high_po_5p73    | Precision P+ 5.73μm resistor   |
| PM_PREC_0p35  | sky130_fd_pr__res_xhigh_po_0p35   | Precision P- 0.35μm resistor |
| PM_PREC_0p69  | sky130_fd_pr__res_xhigh_po_0p69   | Precision P- 0.69μm resistor |
| PM_PREC_1p41  | sky130_fd_pr__res_xhigh_po_1p41   | Precision P- 1.41μm resistor |
| PM_PREC_2p85  | sky130_fd_pr__res_xhigh_po_2p85   | Precision P- 2.85μm resistor |
| PM_PREC_5p73  | sky130_fd_pr__res_xhigh_po_5p73   | Precision P- 5.73μm resistor |

### Diodes

Diodes in HDL21 are defined using width (W) and length (L) which are then converted into area and junction perimeter behind the scenes. All devices have junction terminals (p,n).

**NOTE: DUE TO ANOTHER INTERESTING SCALING QUIRK, MEASUREMENTS FOR DIODES ARE MULTIPLIED BY 1e12 IN SKY130**

```python
from hdl21.prefix import MEGA, TERA
from sky130_hdl21 import Sky130DiodeParams as par
from sky130_hdl21.primitives import PWND_5p5V

a = PWND_5p5V(par(area=0.3 * TERA, pj=1.2 * MEGA))
```

| Component Key  | Component Name                             | Description                      |
|----------------|--------------------------------------------|----------------------------------|
| PWND_5p5V      | sky130_fd_pr__diode_pw2nd_05v5             | PW2ND diode, 5.5V                |
| PWND_11p0V     | sky130_fd_pr__diode_pw2nd_11v0             | PW2ND diode, 11.0V               |
| PWND_5p5V_NAT  | sky130_fd_pr__diode_pw2nd_05v5_nvt         | PW2ND diode, 5.5V, native VT     |
| PWND_5p5V_LVT  | sky130_fd_pr__diode_pw2nd_05v5_lvt         | PW2ND diode, 5.5V, low VT        |
| PDNW_5p5V      | sky130_fd_pr__diode_pd2nw_05v5             | PD2NW diode, 5.5V                |
| PDNW_11p0V     | sky130_fd_pr__diode_pd2nw_11v0             | PD2NW diode, 11.0V               |
| PDNW_5p5V_HVT  | sky130_fd_pr__diode_pd2nw_05v5_hvt         | PD2NW diode, 5.5V, high VT       |
| PDNW_5p5V_LVT  | sky130_fd_pr__diode_pd2nw_05v5_lvt         | PD2NW diode, 5.5V, low VT        |
| PX_RF_PSNW     | sky130_fd_pr__model__parasitic__rf_diode_ps2nw | RF parasitic PS2NW diode      |
| PX_RF_PWDN     | sky130_fd_pr__model__parasitic__rf_diode_pw2dn | RF parasitic PW2DN diode      |
| PX_PWDN        | sky130_fd_pr__model__parasitic__diode_pw2dn    | Parasitic PW2DN diode          |
| PX_PSDN        | sky130_fd_pr__model__parasitic__diode_ps2dn    | Parasitic PS2DN diode          |
| PX_PSNW        | sky130_fd_pr__model__parasitic__diode_ps2nw    | Parasitic PS2NW diode          |

### Bipolar Junction Transistors

Bipolar Junction Transistors in the SKY130 PDK are defined as static devices and do not yet have parametric cells. As such, no parameters can be passed apart from "m" for parallel multiplicity of components:

```python
from sky130_hdl21 import Sky130BipolarParams as par
from sky130_hdl21.primitives import NPN_5p0V_1x2

a = NPN_5p0V_1x2(par(m=2))
```

| Component Key      | Component Name                     | Number of Terminals | Description                     |
|--------------------|------------------------------------|---------------------|---------------------------------|
| NPN_5p0V_1x2       | sky130_fd_pr__npn_05v5_W1p00L2p00  | 4 (c,b,e,s)                   | NPN BJT, 5.0V, 1x2μm       |
| NPN_11p0V_1x1      | sky130_fd_pr__npn_11v0_W1p00L1p00  | 4 (c,b,e,s)                  | NPN BJT, 11.0V, 1x1μm      |
| NPN_5p0V_1x1       | sky130_fd_pr__npn_05v5_W1p00L1p00  | 4 (c,b,e,s)                  | NPN BJT, 5.0V, 1x1μm       |
| PNP_5p0V_0p68x0p68 | sky130_fd_pr__pnp_05v5_W0p68L0p68 | 3 (c,b,e)                  | PNP BJT, 5.0V, 0.68x0.68μm       |
| PNP_5p0V_3p40x3p40 | sky130_fd_pr__pnp_05v5_W3p40L3p40 | 3 (c,b,e)                  | PNP BJT, 5.0V, 3.4x3.4μm       |

### Capacitors

Capacitors in SKY130 come in 4 flavours, the MiM capacitor, the Varactor, the Vertical Parallel Plate transistor and the Vertical Perpendicular Plate capacitor, the latter two accept no arguments and their dimensions are fixed, whereas the first two allow their width and length to be defined:

MiM caps:
```python
from hdl21.prefix import µ
from sky130_hdl21 import Sky130MimCapParams as par
from sky130_hdl21.primitives import MIM_M3

a = MIM_M3(w=2 * µ, l=2 * µ)
```

Varicaps:
```python
from hdl21.prefix import µ
from sky130_hdl21 import Sky130VarCapParams as par
from sky130_hdl21.primitives import VAR_LVT

a = VAR_LVT(w=2 * µ, l=2 * µ)
```

Vertical-Perpendicular/Parallel Plates:
```python
from sky130_hdl21 import Sky130VPPParams as par
from sky130_hdl21.primitives import VPP_PARA_5

a = VPP_PARA_5(m=1)
```

| Component Key  | Component Name                           | Number of Terminals | Capacitor Type | Description                             |
|----------------|------------------------------------------|---------------------|---------------|-----------------------------------------|
| MIM_M3         | sky130_fd_pr__cap_mim_m3_1               | 2 (p,n)                  | MiM           | MiM capacitor, M3 layer                 |
| MIM_M4         | sky130_fd_pr__cap_mim_m3_2               | 2 (p,n)                  | MiM           | MiM capacitor, M4 layer                 |
| VAR_LVT        | sky130_fd_pr__cap_var_lvt                | 3 (p,n,b)                   | Varactor      | Varactor, LVT variant                   |
| VAR_HVT        | sky130_fd_pr__cap_var_hvt                | 3 (p,n,b)                   | Varactor      | Varactor, HVT variant                   |
| VPP_PARA_1     | sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_noshield_o2 | 3         | VPP (Parallel)| VPP parallel capacitor, 4.4x4.6 µm, M1M2 |
| VPP_PARA_2     | sky130_fd_pr__cap_vpp_02p4x04p6_m1m2_noshield          | 3 (p,n,b)                   | VPP (Parallel)     | VPP parallel capacitor, 2.4x4.6 µm, M1M2                  |
| VPP_PARA_3     | sky130_fd_pr__cap_vpp_08p6x07p8_m1m2_noshield          | 3 (p,n,b)                   | VPP (Parallel)     | VPP parallel capacitor, 8.6x7.8 µm, M1M2                  |
| VPP_PARA_4     | sky130_fd_pr__cap_vpp_04p4x04p6_m1m2_noshield          | 3 (p,n,b)                   | VPP (Parallel)     | VPP parallel capacitor, 4.4x4.6 µm, M1M2                  |
| VPP_PARA_5     | sky130_fd_pr__cap_vpp_11p5x11p7_m1m2_noshield          | 3 (p,n,b)                   | VPP (Parallel)     | VPP parallel capacitor, 11.5x11.7 µm, M1M2                |
| VPP_PARA_6     | sky130_fd_pr__cap_vpp_44p7x23p1_pol1m1m2m3m4m5_noshield | 3 (p,n,b)                   | VPP (Parallel)     | VPP parallel capacitor, 44.7x23.1 µm, POL1M1M2M3M4M5       |
| VPP_PARA_7     | sky130_fd_pr__cap_vpp_02p7x06p1_m1m2m3m4_shieldl1_fingercap | 3 (p,n,b)               | VPP (Parallel)     | VPP parallel capacitor, 2.7x6.1 µm, M1M2M3M4, shield L1, finger cap |
| VPP_PARA_8     | sky130_fd_pr__cap_vpp_02p9x06p1_m1m2m3m4_shieldl1_fingercap2 | 3 (p,n,b)             | VPP (Parallel)     | VPP parallel capacitor, 2.9x6.1 µm, M1M2M3M4, shield L1, finger cap 2 |
| VPP_PARA_9     | sky130_fd_pr__cap_vpp_02p7x11p1_m1m2m3m4_shieldl1_fingercap | 3 (p,n,b)             | VPP (Parallel)     | VPP parallel capacitor, 2.7x11.1 µm, M1M2M3M4, shield L1, finger cap |
| VPP_PARA_10    | sky130_fd_pr__cap_vpp_02p7x21p1_m1m2m3m4_shieldl1_fingercap | 3 (p,n,b)             | VPP (Parallel)     | VPP parallel capacitor, 2.7x21.1 µm, M1M2M3M4, shield L1, finger cap |
| VPP_PARA_11    | sky130_fd_pr__cap_vpp_02p7x41p1_m1m2m3m4_shieldl1_fingercap | 3 (p,n,b)            | VPP (Parallel)     | VPP parallel capacitor, 2.7x41.1 µm, M1M2M3M4, shield L1, finger cap |
| VPP_PERP_1     | sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldm5    | 4 (p,n,t,b)                   | VPP (Perpendicular)| VPP perpendicular capacitor, 11.5x11.7 µm, L1M1M2M3M4, shield M5 |
| VPP_PERP_2     | sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3m4_shieldpom5  | 4 (p,n,t,b)                   | VPP (Perpendicular)| VPP perpendicular capacitor, 11.5x11.7 µm, L1M1M2M3M4, shield PoM5 |
| VPP_PERP_3     | sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3m4_shieldl1m5    | 4 (p,n,t,b)                   | VPP (Perpendicular)| VPP perpendicular capacitor, 11.5x11.7 µm, M1M2M3M4, shield L1M5 |
| VPP_PERP_4     | sky130_fd_pr__cap_vpp_04p4x04p6_m1m2m3_shieldl1m5_floatm4 | 4 (p,n,t,b)               | VPP (Perpendicular)| VPP perpendicular capacitor, 4.4x4.6 µm, M1M2M3, shield L1M5, floating M4 |
| VPP_PERP_5     | sky130_fd_pr__cap_vpp_08p6x07p8_m1m2m3_shieldl1m5_floatm4 | 4 (p,n,t,b)               | VPP (Perpendicular)| VPP perpendicular capacitor, 8.6x7.8 µm, M1M2M3, shield L1M5, floating M4 |
| VPP_PERP_6     | sky130_fd_pr__cap_vpp_11p5x11p7_m1m2m3_shieldl1m5_floatm4 | 4 (p,n,t,b)               | VPP (Perpendicular)| VPP perpendicular capacitor, 11.5x11.7 µm, M1M2M3, shield L1M5, floating M4 |
| VPP_PERP_7     | sky130_fd_pr__cap_vpp_11p5x11p7_l1m1m2m3_shieldm4      | 4 (p,n,t,b)                   | VPP (Perpendicular)| VPP perpendicular capacitor, 11.5x11.7 µm, L1M1M2M3, shield M4 |
| VPP_PERP_8     | sky130_fd_pr__cap_vpp_06p8x06p1_l1m1m2m3_shieldpom4    | 4 (p,n,t,b)                   | VPP (Perpendicular)| VPP perpendicular capacitor, 6.8x6.1 µm, L1M1M2M3, shield PoM4 |
| VPP_PERP_9     | sky130_fd_pr__cap_vpp_06p8x06p1_m1m2m3_shieldl1m4      | 4 (p,n,t,b)                   | VPP (Perpendicular)| VPP perpendicular capacitor, 6.8x6.1 µm, M1M2M3, shield L1M4 |
| VPP_PERP_10    | sky130_fd_pr__cap_vpp_11p3x11p8_l1m1m2m3m4_shieldm5_nhvtop | 4 (p,n,t,b)             | VPP (Perpendicular)| VPP perpendicular capacitor, 11.3x11.8 µm, L1M1M2M3M4, shield M5, NHV top |

### Digital Cells

The full range of SKY130's Standard Cell Libraries also work with the Sky130 PDK, they are far too numerous to name here but excellent documentation is available at:  https://diychip.org/sky130/ . We allow users to select from each of the libraries using the following import statements:

| Library Name | Import Statement |
|--------------|------------------|
| sky130_fd_sc_hd | `import sky130.digital_cells.high_density as hd` |
| sky130_fd_sc_hdll | `import sky130.digital_cells.low_leakage as hdll` |
| sky130_fd_sc_hs | `import sky130.digital_cells.high_speed as hs` |
| sky130_fd_sc_hvl | `import sky130.digital_cells.high_voltage as hvl` |
| sky130_fd_sc_lp | `import sky130.digital_cells.low_power as lp` |
| sky130_fd_sc_ls | `import sky130.digital_cells.low_speed as ls` |
| sky130_fd_sc_ms | `import sky130.digital_cells.medium_speed as ms` |

If you like to load all the digital simultaneously, you can also import the entire digital library by calling `from sky130_hdl21.digital_cells import *`, although - this can take a while.

Each component is reflects the naming in DIYChip's documentation as well as their ports, for example:

```python
import sky130_hdl21.digital_cells.high_density as hd
from sky130_hdl21 import Sky130LogicParams as param
p = param()
simple_or = hd.or2_0(p)
```

## Development 

```
pip install -e ".[dev]"
```
