gf180-hdl21 7.0.0
Global Foundries 180nm MCU PDK Package for Hdl21
Requires Python: <3.13,>=3.7
Keywords: PDK, EDA, analog, circuit


# GF 180 MCU - Hdl21 PDK Module

Hdl21 PDK package for the open-source Global Foundries 180nm MCU PDK.  
https://pypi.org/project/gf180-hdl21/

## About This Technology 

The GF180MCU open source PDK is a collaboration between Google and GlobalFoundries to provide a fully open source process design kit (PDK) and related resources to enable the creation of designs manufacturable at GlobalFoundries's facility on their 0.18um 3.3V/6V MCU process technology.

## Installation

Install from PyPi via: 

```
pip install gf180-hdl21
```

And then import the package as `gf180-hdl21`: 

```python
import gf180_hdl21
```

## Development 

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

## PDK `Install` Data

Silicon process technologies generally require non-Python data to execute simulations and other tasks. Gf180 is no different. *Those files are not distributed as part of this package.* The `Gf180` package defines an Hdl21 `PdkInstallation` type `gf180.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 180nm PDK: 
https://anaconda.org/litex-hub/open_pdks.gf180mcuC

Installable with `conda` via: 

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

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/gf180mcuC/libs.tech/ngspice/sm141064.Model"

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

Note the conda-based installation supports simulation solely with [ngspice](https://ngModel.sourceforge.io/). Gf180 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.

If you would prefer a local installation, another great method is to use the Volare open_pdk build manager.

## About this PDK Package

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

There are two major ways to instantiate PDK components offered in this PDK module:

1. Compilation

We first show an example of how this is done using MOSFETs:

```python
import hdl21 as h
import gf180_hdl21

# Use Hdl21 PDK-agnostic Mos primitive
mosfet = h.Mos(tp=h.MosType.NMOS,family=h.MosFamily.CORE)
# This now the correct Gf180 ExternalModule
gf180_hdl21.compile(mosfet) 
```

But this will also work for other components, but these devices don't enjoy the same flexibility as MOSFETs, eg.:

```python
import hdl21 as h
import gf180_hdl21

# Use Hdl21 PDK-agnostic resistors
resistor = h.Resistor(model="rm1")
# This is now the correct Gf180 External module
gf180.compile(resistor) 
```

2. Direct Reference

All Gf180 `ExternalModule`s are stored in the `modules` namespace that makes up the bulk of the PDK module. You can use it to reference `ExternalModule`s directly via component name:

```python
import gf180_hdl21
from gf180_hdl21.primitives as g

p = gf180_hdl21.GF180MosParams(w=3*µ, l=3*µ)

# This is the ExternalModule we want
mosfet = g.PFET_3p3V(p)
```

The complete 180nm design kit includes hundreds of devices. 
A subset are targets for conversion from generic Hdl21 `Primitives`. 

We include them below, two general attributes to note, the first is "Component Name" which is the name that we give the component in the PDK module.

The second is the "Model Name" which refers to the underlying subcircuit or model name found in the Gf180 SPICE files, should you want to look up the device in the PDK documentation itself.

### MOSFETs

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

a = Mos(tp=MosType.NMOS,family=MosFamily.CORE)
gf180_hdl21.compile(a) # a is now an instance of gf180.primitives.NFET_3p3V
```
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 gf180_hdl21 import GF180MosParams as p
import gf180_hdl21.primitives as g

a = g.NFET_3p3V(p(w=0.2*µ,nf=1))
```

| Component Name | Mos Type | Mos Family | Model Name   | Ports      |
| -------------- | -------- | ---------- | ------------- | ---------- |
| PFET_3p3V      | PMOS     | CORE       | pfet_03v3     | d, g, s, b |
| NFET_3p3V      | NMOS     | CORE       | nfet_03v3     | d, g, s, b |
| NFET_6p0V      | NMOS     | IO         | nfet_06v0     | d, g, s, b |
| PFET_6p0V      | PMOS     | IO         | pfet_06v0     | d, g, s, b |
| NFET_3p3V_DSS  | NMOS     | NONE       | nfet_03v3_dss | d, g, s, b |
| PFET_3p3V_DSS  | PMOS     | NONE       | pfet_03v3_dss | d, g, s, b |
| NFET_6p0V_DSS  | NMOS     | NONE       | nfet_06v0_dss | d, g, s, b |
| PFET_6p0V_DSS  | PMOS     | NONE       | pfet_06v0_dss | d, g, s, b |
| NFET_6p0V_NAT  | NMOS     | NONE       | nfet_06v0_nvt | d, g, s, b |

### Resistors

Resistors are not offered with PDK-agnostic compilation and so must be referred to directly with the correct paramtype:
```python
from hdl21.prefix import µ
from gf180_hdl21 import GF180ResParams as p
from gf180_hdl21.primitives import NPLUS_U

a = NPLUS_U(p(r_length=0.3 * µ, r_width=0.18 * µ))
```

| Component Name  | Model Name     | Ports   |
| --------------- | --------------- | ------- |
| NPLUS_U         | nplus_u         | p, n, b |
| PPLUS_U         | pplus_u         | p, n, b |
| NPLUS_S         | nplus_s         | p, n, b |
| PPLUS_S         | pplus_s         | p, n, b |
| NWELL           | nwell           | p, n, b |
| NPOLYF_U        | npolyf_u        | p, n, b |
| PPOLYF_U        | ppolyf_u        | p, n, b |
| NPOLYF_S        | npolyf_s        | p, n, b |
| PPOLYF_S        | ppolyf_s        | p, n, b |
| PPOLYF_U_1K     | ppolyf_u_1k     | p, n, b |
| PPOLYF_U_2K     | ppolyf_u_2k     | p, n, b |
| PPOLYF_U_1K_6P0 | ppolyf_u_1k_6p0 | p, n, b |
| PPOLYF_U_2K_6P0 | ppolyf_u_2k_6p0 | p, n, b |
| PPOLYF_U_3K     | ppolyf_u_3k     | p, n, b |
| RM1             | rm1             | p, n    |
| RM2             | rm2             | p, n    |
| RM3             | rm3             | p, n    |
| TM6K            | tm6k            | p, n    |
| TM9K            | tm9k            | p, n    |
| TM11K           | tm11k           | p, n    |
| TM30K           | tm30k           | p, n    |

### Diodes

Diodes are not offered with PDK-agnostic compilation and so must be referred to directly with the correct paramtype:
```python
from hdl21.prefix import µ, p
from gf180_hdl21 import GF180DiodeParams as par
from gf180_hdl21.primitives import NDSPS_3p3V

a = NDSPS_3p3V(par(area=0.3 * p, pj=1.2 * µ))
```

| Component Name | Model Name      | Ports |
| -------------- | ---------------- | ----- |
| ND2PS_3p3V     | diode_nd2ps_03v3 | p, n  |
| PD2NW_3p3V     | diode_pd2nw_03v3 | p, n  |
| ND2PS_6p0V     | diode_nd2ps_06v0 | p, n  |
| PD2NW_6p0V     | diode_pd2nw_06v0 | p, n  |
| NW2PS_3p3V     | diode_nw2ps_03v3 | p, n  |
| NW2PS_6p0V     | diode_nw2ps_06v0 | p, n  |
| PW2DW          | diode_pw2dw      | p, n  |
| DW2PS          | diode_dw2ps      | p, n  |
| Schottky       | sc_diode         | p, n  |

### BJTs

BJTs are not offered with PDK-agnostic compilation and so must be referred to directly with the correct paramtype:
```python
from hdl21.prefix import µ, p
from gf180_hdl21 import GF180BipolarParams as par
from gf180_hdl21.primitives import PNP_10p0x0p42

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

| Component Name | Model Name     | Ports      |
| -------------- | --------------- | ---------- |
| PNP_10p0x0p42  | pnp_10p00x00p42 | c, b, e    |
| PNP_5p0x0p42   | pnp_05p00x00p42 | c, b, e    |
| PNP_10p0x10p0  | pnp_10p00x10p00 | c, b, e    |
| PNP_5p0x5p0    | pnp_05p00x05p00 | c, b, e    |
| NPN_10p0x10p0  | npn_10p00x10p00 | c, b, e, s |
| NPN_5p0x5p0    | npn_05p00x05p00 | c, b, e, s |
| NPN_0p54x16p0  | npn_00p54x16p00 | c, b, e, s |
| NPN_0p54x8p0   | npn_00p54x08p00 | c, b, e, s |
| NPN_0p54x4p0   | npn_00p54x04p00 | c, b, e, s |
| NPN_0p54x2p0   | npn_00p54x02p00 | c, b, e, s |

### Capacitors

Capacitors are not offered with PDK-agnostic compilation and so must be referred to directly with the correct paramtype:
```python
from hdl21.prefix import µ
from gf180_hdl21 import GF180CapParams as par
from gf180_hdl21.primitives import MIM_1p5fF

a = MIM_1p5fF(par(c_width=1 * µ, c_length=1 * µ))
```

| Component Name  | Model Name     | Ports |
| --------------- | --------------- | ----- |
| MIM_1p5fF       | cap_mim_1f5fF   | p, n  |
| MIM_1p0fF       | cap_mim_1f0fF   | p, n  |
| MIM_2p0fF       | cap_mim_2f0fF   | p, n  |
| PMOS_3p3V       | cap_pmos_03v3   | p, n  |
| NMOS_6p0V       | cap_nmos_06v0   | p, n  |
| PMOS_6p0V       | cap_pmos_06v0   | p, n  |
| NMOS_3p3V       | cap_nmos_03v3   | p, n  |
| NMOS_Nwell_3p3V | cap_nmos_03v3_b | p, n  |
| PMOS_Pwell_3p3V | cap_pmos_03v3_b | p, n  |
| NMOS_Nwell_6p0V | cap_nmos_06v0_b | p, n  |
| PMOS_Pwell_6p0V | cap_pmos_06v0_b | p, n  |

### Digital Cells

The PDK is also distributed with two standard cell libraries that we call `seven_track` and  `nine_track`. These are distributed with `gf180-hdl21` as separate name spaces that can be accessed in a similar manner to `modules`:

```python
from gf180_hdl21.digital_cells.seven_track as d7
from gf180_hdl21.digital_cells.nine_track as d9
```

These cells are named in their spice files in `libs.ref` of a normal `open_pdk` install as `gf_180_fd_sc_******__device`, to find the corresponding device in the digital name space, use `device`, eg.

```python
from gf180_hdl21.digital_cells.seven_track as d7
from gf180_hdl21 import GF180LogicParams as p
simple_and_gate = d7.and2_1(p())
```

The devices in all are too numerous to cover here, but are covered in great detail in the [official PDK documentation](https://gf180mcu-pdk.readthedocs.io/en/latest/digital/Digital.html).