add fullcustom part

This commit is contained in:
Pierre Guillod 2023-04-10 10:16:55 +02:00
parent 9adedb5142
commit 7ad3cfc3bf
Signed by: pierre
GPG key ID: B00B454469924EDF
3 changed files with 286 additions and 0 deletions

19
fullcustom/README.md Normal file
View file

@ -0,0 +1,19 @@
# Fullcustom analog design
## Environment
Make sure Anaconda is installed and that you are in the `freechips/fullcustom` directory. The fullcustom environment can be created, updated and activated using:
```sh
conda env create
conda activate fullcustom
conda update --all
```
## Notebook
The notebook can be openend as follows:
```sh
jupyter notebook
```

View file

@ -0,0 +1,20 @@
name: fullcustom
channels:
- defaults
dependencies:
- python=3.7
- pip=22.3.1
- pip:
- gdstk==0.9.37
- conda-forge::notebook=5.7.11
# Drawing
- litex-hub::magic=8.3.389_0_g1d8fcca
# Simulation
- conda-forge::pyspice
# Process Development Kits (PDKs)
- litex-hub::open_pdks.sky130a=1.0.404_0_gbb4b48f
#- litex-hub::open_pdks.gf180mcuc=1.0.404_0_gbb4b48f
# Simulation
- conda-forge::pyspice

View file

@ -0,0 +1,247 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "9quLG8jhYqwq"
},
"source": [
"# Fullcustom analog design demo using Magic"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The environment path must be retrieved in order to provide _Magic_ with the technology files."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ghmpRJhL3ac3"
},
"outputs": [],
"source": [
"import os\n",
"CONDA_PREFIX = os.environ['CONDA_PREFIX']"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "CQdALyHZ9Z01"
},
"source": [
"## Sources"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Graphic Design System file (GDS)\n",
"\n",
"A GDS file is drawn by hand:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "hhpUJrMBmlfj",
"outputId": "bb1109ea-5d45-4a35-e81e-5f0fca3bea9f"
},
"outputs": [],
"source": [
"%%script magic -dnull -noconsole -rcfile {CONDA_PREFIX}/share/pdk/sky130A/libs.tech/magic/sky130A.magicrc\n",
"cellname rename (UNNAMED) mosfet\n",
"\n",
"box 0 0 950nm 650nm\n",
"paint ndiffusion\n",
"\n",
"box 400nm -600nm 550nm 1200nm\n",
"paint polysilicon\n",
"\n",
"box 0 0 400nm 650nm\n",
"label source\n",
"port make 3\n",
"\n",
"box 550nm 0 950nm 650nm\n",
"label drain\n",
"port make 1\n",
"\n",
"box 400nm -600nm 550nm 0\n",
"label gate\n",
"port make 2\n",
"\n",
"extract\n",
"ext2spice lvs\n",
"ext2spice cthresh 0\n",
"ext2spice\n",
"\n",
"gds labels no\n",
"gds write mosfet.gds"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Display layout\n",
"\n",
"The implemented layout can be retrieved as follows:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 611
},
"id": "xjz3IYz55vu2",
"outputId": "8b2b0d37-abc2-4446-a9b9-8dd4b8d7bfe7"
},
"outputs": [],
"source": [
"import gdstk\n",
"import IPython.display\n",
"\n",
"library = gdstk.read_gds('mosfet.gds')\n",
"top_cells = library.top_level()\n",
"top_cells[0].write_svg('mosfet.svg', scaling=200)\n",
"IPython.display.SVG('mosfet.svg')"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "YZdXQnCJ9h_o"
},
"source": [
"## Simulation"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### PySPICE"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"_PySPICE_ is used for analog simulation of the circuit."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 927
},
"id": "9scIFl1w7Lk6",
"outputId": "47f12782-4e69-471f-8101-6abfdc041a28"
},
"outputs": [],
"source": [
"from PySpice.Spice.Netlist import Circuit, SubCircuit, SubCircuitFactory\n",
"from PySpice.Unit import *\n",
"import matplotlib.pyplot as plt\n",
"\n",
"circuit = Circuit('mosfet0')\n",
"circuit.lib(f'{CONDA_PREFIX}/share/pdk/sky130A/libs.tech/ngspice/sky130.lib.spice', 'tt')\n",
"circuit.include('mosfet.spice')\n",
"circuit.X('mosfet0', 'mosfet', 'DRAIN', 'GATE', 'VGND')\n",
"circuit.V('gnd', 'VGND', 0, 0)\n",
"circuit.V('dd', 'VPWR', 'VGND', 1.8)\n",
"circuit.R('', 'VPWR', 'DRAIN', '10k')\n",
"circuit.PulseVoltageSource('Vin', 'GATE', 'VGND',\n",
" initial_value=0@u_V, pulsed_value=1.8@u_V,\n",
" rise_time=10@u_ps, fall_time=10@u_ps,\n",
" pulse_width=1@u_ns, period=2@u_ns, delay_time=1@u_ns)\n",
"simulator = circuit.simulator()\n",
"analysis = simulator.transient(step_time=10@u_ps, end_time=2@u_ns)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Plot the waveform"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The output waveform can be plotted:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": false
},
"outputs": [],
"source": [
"fig, ax = plt.subplots(figsize=(20, 10))\n",
"ax.set_title('mosfet')\n",
"ax.set_xlabel('time in 1e-14s')\n",
"ax.set_ylabel('voltage in V')\n",
"ax.plot(analysis.GATE)\n",
"ax.plot(analysis.DRAIN)\n",
"ax.legend(('GATE', 'DRAIN'))\n",
"plt.tight_layout()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# References\n",
"Inspired from:\n",
"“Silicon Notebooks.” CHIPS Alliance, Apr. 08, 2023. Accessed: Apr. 10, 2023. [Online]. Available: https://github.com/chipsalliance/silicon-notebooks/blob/b65134a43b01ae31423f7ee87110740b2257ac42/analog-inverter-magic.ipynb (Apache License 2.0)"
]
}
],
"metadata": {
"colab": {
"collapsed_sections": [],
"include_colab_link": true,
"name": "analog-inverter-magic.ipynb",
"provenance": []
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.12"
}
},
"nbformat": 4,
"nbformat_minor": 1
}