add cad files

* inverter top level
* PMOS instance
* NMOS instance
This commit is contained in:
Pierre Guillod 2023-04-11 23:22:54 +02:00
parent d2be91dc51
commit 92422165ef
Signed by: pierre
GPG key ID: B00B454469924EDF
7 changed files with 290 additions and 88 deletions

View file

View file

@ -0,0 +1,27 @@
magic
tech sky130A
magscale 1 2
timestamp 1681238406
<< metal1 >>
rect 12 149 74 330
rect 112 -202 170 62
rect 12 -461 74 -280
rect 208 -364 271 233
use sky130_fd_pr__nfet_01v8_EDB9KC *sky130_fd_pr__nfet_01v8_EDB9KC_0
timestamp 1681237416
transform 1 0 141 0 1 -322
box -211 -252 211 252
use sky130_fd_pr__pfet_01v8_M479BZ sky130_fd_pr__pfet_01v8_M479BZ_0
timestamp 1681237537
transform 1 0 141 0 1 191
box -211 -261 211 261
<< labels >>
flabel metal1 12 149 74 330 0 FreeMono 160 90 0 0 VDD
port 1 nsew
flabel metal1 12 -461 74 -280 0 FreeMono 160 90 0 0 VSS
port 2 nsew
flabel metal1 112 -140 170 -34 0 FreeMono 160 0 0 0 I
port 3 nsew
flabel metal1 208 -140 271 -34 0 FreeMono 160 0 0 0 O
port 4 nsew
<< end >>

View file

@ -0,0 +1,82 @@
magic
tech sky130A
magscale 1 2
timestamp 1681237416
<< error_p >>
rect -29 114 29 120
rect -29 80 -17 114
rect -29 74 29 80
<< pwell >>
rect -211 -252 211 252
<< nmos >>
rect -15 -42 15 42
<< ndiff >>
rect -73 30 -15 42
rect -73 -30 -61 30
rect -27 -30 -15 30
rect -73 -42 -15 -30
rect 15 30 73 42
rect 15 -30 27 30
rect 61 -30 73 30
rect 15 -42 73 -30
<< ndiffc >>
rect -61 -30 -27 30
rect 27 -30 61 30
<< psubdiff >>
rect -175 182 175 216
rect -175 120 -141 182
rect 141 120 175 182
rect -175 -182 -141 -120
rect 141 -182 175 -120
rect -175 -216 -79 -182
rect 79 -216 175 -182
<< psubdiffcont >>
rect -175 -120 -141 120
rect 141 -120 175 120
rect -79 -216 79 -182
<< poly >>
rect -33 114 33 130
rect -33 80 -17 114
rect 17 80 33 114
rect -33 64 33 80
rect -15 42 15 64
rect -15 -68 15 -42
<< polycont >>
rect -17 80 17 114
<< locali >>
rect -175 182 175 216
rect -175 120 -141 182
rect 141 120 175 182
rect -33 80 -17 114
rect 17 80 33 114
rect -61 30 -27 46
rect -61 -46 -27 -30
rect 27 30 61 46
rect 27 -46 61 -30
rect -175 -182 -141 -120
rect 141 -182 175 -120
rect -175 -216 -79 -182
rect 79 -216 175 -182
<< viali >>
rect -17 80 17 114
rect -61 -30 -27 30
rect 27 -30 61 30
<< metal1 >>
rect -29 114 29 120
rect -29 80 -17 114
rect 17 80 29 114
rect -29 74 29 80
rect -67 30 -21 42
rect -67 -30 -61 30
rect -27 -30 -21 30
rect -67 -42 -21 -30
rect 21 30 67 42
rect 21 -30 27 30
rect 61 -30 67 30
rect 21 -42 67 -30
<< properties >>
string FIXED_BBOX -158 -199 158 199
string gencell sky130_fd_pr__nfet_01v8
string library sky130
string parameters w 0.420 l 0.150 m 1 nf 1 diffcov 100 polycov 100 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.15 wmin 0.42 compatible {sky130_fd_pr__nfet_01v8 sky130_fd_pr__nfet_01v8_lvt sky130_fd_bs_flash__special_sonosfet_star sky130_fd_pr__nfet_g5v0d10v5 sky130_fd_pr__nfet_05v0_nvt sky130_fd_pr__nfet_03v3_nvt} full_metal 1 viasrc 100 viadrn 100 viagate 100 viagb 0 viagr 0 viagl 0 viagt 0
<< end >>

View file

@ -0,0 +1,82 @@
magic
tech sky130A
magscale 1 2
timestamp 1681237537
<< error_p >>
rect -29 -89 29 -83
rect -29 -123 -17 -89
rect -29 -129 29 -123
<< nwell >>
rect -211 -261 211 261
<< pmos >>
rect -15 -42 15 42
<< pdiff >>
rect -73 30 -15 42
rect -73 -30 -61 30
rect -27 -30 -15 30
rect -73 -42 -15 -30
rect 15 30 73 42
rect 15 -30 27 30
rect 61 -30 73 30
rect 15 -42 73 -30
<< pdiffc >>
rect -61 -30 -27 30
rect 27 -30 61 30
<< nsubdiff >>
rect -175 191 -79 225
rect 79 191 175 225
rect -175 129 -141 191
rect 141 129 175 191
rect -175 -191 -141 -129
rect 141 -191 175 -129
rect -175 -225 175 -191
<< nsubdiffcont >>
rect -79 191 79 225
rect -175 -129 -141 129
rect 141 -129 175 129
<< poly >>
rect -15 42 15 73
rect -15 -73 15 -42
rect -33 -89 33 -73
rect -33 -123 -17 -89
rect 17 -123 33 -89
rect -33 -139 33 -123
<< polycont >>
rect -17 -123 17 -89
<< locali >>
rect -175 191 -79 225
rect 79 191 175 225
rect -175 129 -141 191
rect 141 129 175 191
rect -61 30 -27 46
rect -61 -46 -27 -30
rect 27 30 61 46
rect 27 -46 61 -30
rect -33 -123 -17 -89
rect 17 -123 33 -89
rect -175 -191 -141 -129
rect 141 -191 175 -129
rect -175 -225 175 -191
<< viali >>
rect -61 -30 -27 30
rect 27 -30 61 30
rect -17 -123 17 -89
<< metal1 >>
rect -67 30 -21 42
rect -67 -30 -61 30
rect -27 -30 -21 30
rect -67 -42 -21 -30
rect 21 30 67 42
rect 21 -30 27 30
rect 61 -30 67 30
rect 21 -42 67 -30
rect -29 -89 29 -83
rect -29 -123 -17 -89
rect 17 -123 29 -89
rect -29 -129 29 -123
<< properties >>
string FIXED_BBOX -158 -208 158 208
string gencell sky130_fd_pr__pfet_01v8
string library sky130
string parameters w 0.42 l 0.15 m 1 nf 1 diffcov 100 polycov 100 guard 1 glc 1 grc 1 gtc 1 gbc 1 tbcov 100 rlcov 100 topc 1 botc 1 poverlap 0 doverlap 1 lmin 0.15 wmin 0.42 compatible {sky130_fd_pr__pfet_01v8 sky130_fd_pr__pfet_01v8_lvt sky130_fd_pr__pfet_01v8_hvt sky130_fd_pr__pfet_g5v0d10v5} full_metal 1 viasrc 100 viadrn 100 viagate 100 viagb 0 viagr 0 viagl 0 viagt 0
<< end >>

View file

View file

View file

@ -6,14 +6,9 @@
"id": "9quLG8jhYqwq" "id": "9quLG8jhYqwq"
}, },
"source": [ "source": [
"# Fullcustom analog design demo using Magic" "# Fullcustom analog design demo using Magic\n",
] "\n",
}, "The environment path must be retrieved in order to provide _Magic_ with the technology files:"
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The environment path must be retrieved in order to provide _Magic_ with the technology files."
] ]
}, },
{ {
@ -28,22 +23,17 @@
"CONDA_PREFIX = os.environ['CONDA_PREFIX']" "CONDA_PREFIX = os.environ['CONDA_PREFIX']"
] ]
}, },
{
"cell_type": "markdown",
"metadata": {
"id": "CQdALyHZ9Z01"
},
"source": [
"## Sources"
]
},
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Graphic Design System file (GDS)\n", "## Source files\n",
"\n", "\n",
"A GDS file is drawn by hand:" "### Using the _Magic_ VLSI layout tool\n",
"\n",
"[_Magic_](http://opencircuitdesign.com/magic/) cells (`.mag`) are used to store and manage the layouts. They can be edited using _Magic_ commands or using _Magic_'s GUI.\n",
"\n",
"An existing _inverter_ design as well as its dependencies is imported and converted to _Graphic Design System_ (`.gds`) file for viewing and manufacturing and a _SPICE_ (`.spice`) file for simulation:"
] ]
}, },
{ {
@ -54,47 +44,32 @@
"base_uri": "https://localhost:8080/" "base_uri": "https://localhost:8080/"
}, },
"id": "hhpUJrMBmlfj", "id": "hhpUJrMBmlfj",
"outputId": "bb1109ea-5d45-4a35-e81e-5f0fca3bea9f" "outputId": "bb1109ea-5d45-4a35-e81e-5f0fca3bea9f",
"scrolled": true
}, },
"outputs": [], "outputs": [],
"source": [ "source": [
"%%script magic -dnull -noconsole -rcfile {CONDA_PREFIX}/share/pdk/sky130A/libs.tech/magic/sky130A.magicrc\n", "%%script magic -dnull -noconsole -rcfile {CONDA_PREFIX}/share/pdk/sky130A/libs.tech/magic/sky130A.magicrc\n",
"cellname rename (UNNAMED) mosfet\n",
"\n", "\n",
"box 0 0 950nm 650nm\n", "load cad/mag/inverter.mag\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", "\n",
"extract\n", "extract\n",
"ext2spice lvs\n", "ext2spice lvs\n",
"ext2spice cthresh 0\n", "ext2spice cthresh 0\n",
"ext2spice\n", "ext2spice rthresh 0\n",
"ext2spice -o cad/spice/inverter.spice\n",
"\n", "\n",
"gds labels no\n", "gds labels no\n",
"gds write mosfet.gds" "gds write cad/gds/inverter.gds"
] ]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Display layout\n", "### Display the inverter layout\n",
"\n", "\n",
"The implemented layout can be retrieved as follows:" "The `.gds` file can be converted to vector graphics for displaying:"
] ]
}, },
{ {
@ -113,33 +88,21 @@
"import gdstk\n", "import gdstk\n",
"import IPython.display\n", "import IPython.display\n",
"\n", "\n",
"library = gdstk.read_gds('mosfet.gds')\n", "library = gdstk.read_gds('cad/gds/inverter.gds')\n",
"top_cells = library.top_level()\n", "top_cells = library.top_level()\n",
"top_cells[0].write_svg('mosfet.svg', scaling=200)\n", "top_cells[0].write_svg('cad/svg/inverter.svg', scaling=100)\n",
"IPython.display.SVG('mosfet.svg')" "IPython.display.SVG('cad/svg/inverter.svg')"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "YZdXQnCJ9h_o"
},
"source": [
"## Simulation"
] ]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### PySPICE" "## Simulation\n",
] "\n",
}, "### Using _SPICE_ simulation engine\n",
{ "\n",
"cell_type": "markdown", "[_PySPICE_](https://pyspice.fabrice-salvaire.fr/releases/v1.4/overview.html) is a _Python_ implementation of several _SPICE_ simulation engines. The _SPICE_ engines are used to simulate analog circuits. A top-level test bench circuit must be built:"
"metadata": {},
"source": [
"_PySPICE_ is used for analog simulation of the circuit."
] ]
}, },
{ {
@ -157,34 +120,38 @@
"source": [ "source": [
"from PySpice.Spice.Netlist import Circuit, SubCircuit, SubCircuitFactory\n", "from PySpice.Spice.Netlist import Circuit, SubCircuit, SubCircuitFactory\n",
"from PySpice.Unit import *\n", "from PySpice.Unit import *\n",
"import matplotlib.pyplot as plt\n",
"\n", "\n",
"circuit = Circuit('mosfet0')\n", "# Declare the top-level circuit\n",
"circuit = Circuit('Inverter')\n",
"# Link to technology libraries\n",
"circuit.lib(f'{CONDA_PREFIX}/share/pdk/sky130A/libs.tech/ngspice/sky130.lib.spice', 'tt')\n", "circuit.lib(f'{CONDA_PREFIX}/share/pdk/sky130A/libs.tech/ngspice/sky130.lib.spice', 'tt')\n",
"circuit.include('mosfet.spice')\n", "\n",
"circuit.X('mosfet0', 'mosfet', 'DRAIN', 'GATE', 'VGND')\n", "# Import and instantiate the CUT (Circuit Under Test)\n",
"circuit.V('gnd', 'VGND', 0, 0)\n", "circuit.include('cad/spice/inverter.spice')\n",
"circuit.V('dd', 'VPWR', 'VGND', 1.8)\n", "circuit.X('Inverter', 'inverter', 'VDD','VSS','I','O');\n",
"circuit.R('', 'VPWR', 'DRAIN', '10k')\n", "\n",
"circuit.PulseVoltageSource('Vin', 'GATE', 'VGND',\n", "# Add voltage sources\n",
"circuit.V('VSS', 'VSS', 0, 0)\n",
"circuit.V('VDD', 'VDD', 'VSS', 1.8)\n",
"# Add pulse source\n",
"circuit.PulseVoltageSource(\n",
" 'I', 'I', 'VSS',\n",
" initial_value=0@u_V, pulsed_value=1.8@u_V,\n", " initial_value=0@u_V, pulsed_value=1.8@u_V,\n",
" rise_time=10@u_ps, fall_time=10@u_ps,\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", " pulse_width=40@u_ps, period=160@u_ps, delay_time=10@u_ps\n",
")\n",
"\n",
"# Create the simulation and simulate\n",
"simulator = circuit.simulator()\n", "simulator = circuit.simulator()\n",
"analysis = simulator.transient(step_time=10@u_ps, end_time=2@u_ns)" "analysis = simulator.transient(step_time=1@u_ps, end_time=160@u_ps)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Plot the waveform"
] ]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Plot the waveform\n",
"\n",
"The output waveform can be plotted:" "The output waveform can be plotted:"
] ]
}, },
@ -196,22 +163,66 @@
}, },
"outputs": [], "outputs": [],
"source": [ "source": [
"fig, ax = plt.subplots(figsize=(20, 10))\n", "import matplotlib.pyplot as plt\n",
"ax.set_title('mosfet')\n", "import numpy as np\n",
"ax.set_xlabel('time in 1e-14s')\n", "fig, ax = plt.subplots(figsize=(8,5))\n",
"ax.set_ylabel('voltage in V')\n", "ax.grid(visible=True, which='major', axis='both');\n",
"ax.plot(analysis.GATE)\n", "ax.grid(visible=True, which='minor', axis='both', linestyle=\"--\");\n",
"ax.plot(analysis.DRAIN)\n", "ax.set_yticks(np.linspace(-1.0,2.5,8,endpoint=True));\n",
"ax.legend(('GATE', 'DRAIN'))\n", "ax.set_yticks(np.linspace(-1.0,2.5,36,endpoint=True),minor=True);\n",
"ax.set_xticks(np.linspace(0e-12,160e-12,9,endpoint=True));\n",
"ax.set_xticks(np.linspace(0e-12,160e-12,17,endpoint=True),minor=True);\n",
"ax.set_title('Inverter - Transient Simulation')\n",
"ax.set_xlabel('Time [s]')\n",
"ax.set_ylabel('Signal [V]')\n",
"ax.plot(analysis.time,analysis.I)\n",
"ax.plot(analysis.time,analysis.O)\n",
"ax.legend(('Input (I)', 'Output (O)'))\n",
"plt.tight_layout()\n", "plt.tight_layout()\n",
"plt.show()" "plt.show()"
] ]
}, },
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Graphical editor\n",
"\n",
"_Magic_ can be started specifying only one file (`.magicrc`) that sets everything up (layers, macros, DRC rules, etc.)! Both a console and a GUI are started. Some functions are only accessible using the command-line interface or using keybindings."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!magic -rcfile {CONDA_PREFIX}/share/pdk/sky130A/libs.tech/magic/sky130A.magicrc"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# To have fun going further...\n",
"\n",
"Here are a couple ideas to spend a good time exploring those beautiful pieces of software:\n",
"\n",
" * Characterize an NMOS device or a PMOS device by applying voltage pulses on the different pads.\n",
" * Start _Magic_ on another PDK and design another inverter.\n",
" * Vary the devices' geometry; try to make the pull-up and the pull-down waveforms symmetrical.\n",
" \n",
" **Do not hesitate to open the `.mag` files to see how they are built and to adapt from them!**\n",
" \n",
" > Good luck and read the docs. 😉"
]
},
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"# References\n", "# References\n",
"\n",
"Inspired from:\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)" "“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)"
] ]