Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

General Fixes and Notebook update #313

Merged
merged 11 commits into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 14 additions & 13 deletions docker/conda/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,22 @@ RUN wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh \
ENV PATH=/usr/bin/miniconda3/bin:${PATH}
RUN conda update conda --all -y
RUN conda install python=3.10 \
yosys \
open_pdks.sky130a \
open_pdks.gf180mcuC \
magic \
netgen \
openroad \
-c litex-hub \
-c conda-forge \
-c anaconda \
-y
yosys \
open_pdks.sky130a \
open_pdks.gf180mcuC \
magic \
netgen \
openroad \
-c litex-hub \
-c conda-forge \
-c anaconda \
-y
ENV PDK_ROOT=/usr/bin/miniconda3/share/pdk/

RUN wget https://www.klayout.org/downloads/Ubuntu-22/klayout_0.28.12-1_amd64.deb
RUN dpkg -i klayout_0.28.12-1_amd64.deb
RUN strip --remove-section=.note.ABI-tag /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
RUN wget https://www.klayout.org/downloads/Ubuntu-22/klayout_0.28.17-1_amd64.deb
RUN dpkg -i klayout_0.28.17-1_amd64.deb
RUN pip install glayout
#RUN strip --remove-section=.note.ABI-tag /usr/lib/x86_64-linux-gnu/libQt5Core.so.5

COPY ./scripts /scripts

Expand Down
2 changes: 2 additions & 0 deletions docker/conda/packages.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ libx11-dev
libx11-6
libxaw7-dev
libreadline6-dev
libz-dev
libgit2-dev
12 changes: 7 additions & 5 deletions docs/source/notebooks/glayout/GLayout_Cells.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@
"source": [
"## Introduction\n",
"Welcome!\n",
"This notebook serves as an introduction to the GDSFactory-based layout automation tool **GLayout** and an example two-stage Operational Amplifier (Op-Amp) generator, as a part of [OpenFASoC](https://github.com/idea-fasoc/OpenFASOC).\n",
"This notebook serves as an introduction to the GDSFactory-based layout automation tool **GLayout** and an example two-stage Operational Amplifier (Op-Amp) generator, as a part of [OpenFASoC](https://github.com/idea-fasoc/OpenFASOC). \n",
"\n",
"This Notebook will run as-is on Google Collab, or you can run locally by using the install steps in [this document](https://docs.google.com/document/d/e/2PACX-1vRL8ksIvB-fHaqWgkgBPDUznOcDmmFhNrvzPNx9GSSkZyfhJYexEI9gBZCJ0SNNnHdUrAf1EBOeU182/pub). If you choose a local install, skip part 1 of this notebook.\n",
"\n",
"### List of Generators\n",
"\n",
Expand Down Expand Up @@ -407,7 +409,7 @@
},
"outputs": [],
"source": [
"from glayout.flow.components.diff_pair import diff_pair\n",
"from glayout.flow.blocks.diff_pair import diff_pair\n",
"# Used to display the results in a grid (notebook only)\n",
"left = widgets.Output()\n",
"leftSPICE = widgets.Output()\n",
Expand Down Expand Up @@ -453,7 +455,7 @@
},
"outputs": [],
"source": [
"from glayout.flow.components.differential_to_single_ended_converter import differential_to_single_ended_converter\n",
"from glayout.flow.blocks.differential_to_single_ended_converter import differential_to_single_ended_converter\n",
"# Used to display the results in a grid (notebook only)\n",
"left = widgets.Output()\n",
"leftSPICE = widgets.Output()\n",
Expand Down Expand Up @@ -530,7 +532,7 @@
},
"outputs": [],
"source": [
"from glayout.flow.components.opamp import opamp\n",
"from glayout.flow.blocks.opamp import opamp\n",
"\n",
"# Select which PDK to use\n",
"pdk = sky130\n",
Expand Down Expand Up @@ -590,4 +592,4 @@
},
"nbformat": 4,
"nbformat_minor": 0
}
}
1 change: 1 addition & 0 deletions docs/source/notebooks/glayout/GLayout_Cmirror.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"cells":[{"cell_type":"markdown","metadata":{"id":"aK2t7aSWNojQ"},"source":["# GLayout Current Mirror Tutorial\n"]},{"cell_type":"markdown","metadata":{"id":"view-in-github"},"source":["<a href=\"https://colab.research.google.com/github/idea-fasoc/OpenFASOC/blob/main/docs/source/notebooks/glayout/GLayout_Cmirror.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>\n"]},{"cell_type":"markdown","metadata":{"id":"xjDewsT5Y4lP"},"source":["```\n","OpenFASOC Team, Feb 2024\n","SPDX-License-Identifier: Apache-2.0\n","```"]},{"cell_type":"markdown","metadata":{"id":"-Xp4cEjkeHIx"},"source":["## Introduction\n","Welcome!\n","This notebook serves as an introduction to the GDSFactory-based layout automation tool **GLayout** and an example producing a VIA to explain grules and glayers, as a part of [OpenFASoC](https://github.com/idea-fasoc/OpenFASOC). \n","\n","This Notebook will run as-is on Google Collab, or you can run locally by using the install steps in [this document](https://docs.google.com/document/d/e/2PACX-1vRL8ksIvB-fHaqWgkgBPDUznOcDmmFhNrvzPNx9GSSkZyfhJYexEI9gBZCJ0SNNnHdUrAf1EBOeU182/pub). If you choose a local install, skip part 1 of this notebook.\n"]},{"cell_type":"markdown","metadata":{"id":"j4dNshkgMM4I"},"source":["## Installation On Google Collab\n","### 1. Clone the repository and install dependencies\n","**Python Dependencies**\n","* [`gdsfactory`](https://github.com/gdsfactory/gdsfactory): Provides the backend for GDS manipulation.\n","* [`sky130`](https://github.com/gdsfactory/skywater130): The Skywater 130nm PDK Python package for GDSFactory to use in this demo.\n","* [`gf180`](https://github.com/gdsfactory/gf180): The GF 180nm PDK Python package for GDSFactory to use in this demo.\n","* [`gdstk`](https://heitzmann.github.io/gdstk/): (installed as a part of gdsfactory) Used for converting GDS files into SVG images for viewing.\n","* [`svgutils`](https://svgutils.readthedocs.io/en/latest/): To scale the SVG image.\n","\n","**System Dependencies**\n","* [`klayout`](https://klayout.de/): For DRC (Design Rule Checking).\n"]},{"cell_type":"markdown","metadata":{"id":"bANz_LDB8TQW"},"source":["#### 1.1. Installing the binary dependency `klayout` using micromamba\n","**You only need to run this once**"]},{"cell_type":"code","execution_count":null,"metadata":{"id":"JzDjayJIMSHe","scrolled":true},"outputs":[],"source":["# Setup the environment for the OpenFASOC GDSFactory generator\n","# You only need to run this block once!\n","\n","# Clone OpenFASoC\n","!git clone https://github.com/idea-fasoc/OpenFASOC\n","# Install python dependencies\n","!pip install sky130\n","!pip install gf180 prettyprinttree svgutils\n","!pip install gdsfactory==7.7.0\n","\n","import pathlib\n","import os\n","# Install KLayout (via conda)\n","!curl -Ls https://micro.mamba.pm/api/micromamba/linux-64/latest | tar -xvj bin/micromamba\n","conda_prefix_path = pathlib.Path('conda-env')\n","CONDA_PREFIX = str(conda_prefix_path.resolve())\n","%env CONDA_PREFIX={CONDA_PREFIX}\n","\n","!bin/micromamba create --yes --prefix $CONDA_PREFIX\n","# Install from the litex-hub channel\n","!bin/micromamba install --yes --prefix $CONDA_PREFIX \\\n"," --channel litex-hub \\\n"," --channel main \\\n"," klayout\n"]},{"cell_type":"markdown","metadata":{"id":"B6dO3W3m8TQZ"},"source":["#### 1.2. Adding the `klayout` binary to the system path, then goto the GLayout directory\n","**You need to run this each time you restart the kernel**"]},{"cell_type":"code","execution_count":null,"metadata":{"id":"Izl4QURo8TQa"},"outputs":[],"source":["# Setup the environment for the OpenFASOC GDSFactory generator\n","\n","# Adding micro-mamba binary directory to the PATH\n","# This directory contains Klayout\n","import pathlib\n","import os\n","conda_prefix_path = pathlib.Path('conda-env')\n","CONDA_PREFIX = str(conda_prefix_path.resolve())\n","%env CONDA_PREFIX={CONDA_PREFIX}\n","# Add conda packages to the PATH\n","PATH = os.environ['PATH']\n","%env PATH={PATH}:{CONDA_PREFIX}/bin\n","\n","%cd /content/OpenFASOC/openfasoc/generators/glayout"]},{"cell_type":"markdown","metadata":{"id":"e-sbwZb_8TQb"},"source":["#### 1.3. Importing Libraries and Utility Functions"]},{"cell_type":"code","execution_count":null,"metadata":{"id":"Nc7wGAz68TQb"},"outputs":[],"source":["from glayout.flow.pdk.sky130_mapped import sky130_mapped_pdk as sky130\n","from glayout.flow.pdk.gf180_mapped import gf180_mapped_pdk as gf180\n","import gdstk\n","import svgutils.transform as sg\n","import IPython.display\n","from IPython.display import clear_output\n","import ipywidgets as widgets\n","\n","# Redirect all outputs here\n","hide = widgets.Output()\n","\n","def display_gds(gds_file, scale = 3):\n"," # Generate an SVG image\n"," top_level_cell = gdstk.read_gds(gds_file).top_level()[0]\n"," top_level_cell.write_svg('out.svg')\n"," # Scale the image for displaying\n"," fig = sg.fromfile('out.svg')\n"," fig.set_size((str(float(fig.width) * scale), str(float(fig.height) * scale)))\n"," fig.save('out.svg')\n","\n"," # Display the image\n"," IPython.display.display(IPython.display.SVG('out.svg'))\n","\n","def display_component(component, scale = 3):\n"," # Save to a GDS file\n"," with hide:\n"," component.write_gds(\"out.gds\")\n"," display_gds('out.gds', scale)\n"]},{"cell_type":"markdown","metadata":{"id":"ywJ1Xc5K395z"},"source":["# Current Mirror Layout Design using GLayout API\n","\n","## Overview\n","\n","This document provides a detailed tutorial on using the GLayout API to design and generate a layout for a PMOS current mirror circuit. It outlines the steps to initialize the layout components, place the devices, make necessary adjustments, route the connections, and generate the final layout for visualization.\n","\n","## Prerequisites\n","\n","Ensure that you have the following installed:\n","- Python environment with access to GLayout API.\n","- GDSFactory package for handling generic layout components.\n","- A PDK (Process Design Kit) appropriate for the technology node you're working on (e.g., `gf180` in this example).\n","\n","## Step-by-Step Guide\n","\n","### Step 1: Setting up the Environment\n","\n","**1.1 Import Required Modules**\n","Begin by importing the necessary classes and functions from the GLayout and GDSFactory packages:\n","\n"]},{"cell_type":"code","execution_count":null,"metadata":{"id":"idb2xYtJqwna"},"outputs":[],"source":["from glayout.flow.primitives.guardring import tapring\n","from glayout.flow.primitives.fet import pmos\n","from glayout.flow.pdk.util.comp_utils import evaluate_bbox, prec_center\n","from glayout.flow.pdk.mappedpdk import MappedPDK\n","from glayout.flow.routing.straight_route import straight_route\n","from glayout.flow.routing.c_route import c_route\n","from gdsfactory import Component\n","from glayout.pdk.gf180_mapped import gf180_mapped_pdk"]},{"cell_type":"markdown","metadata":{"id":"fy1-h5NTq0US"},"source":["### Step 2: Define the Current Mirror Function\n","\n","**2.1 Initialize the Current Mirror Component**\n","Within your Python script, start by defining the `currentMirror` function that takes in a `MappedPDK` object:\n","```python\n","def currentMirror(pdk: MappedPDK):\n"," currMirrComp = Component()\n","```\n","\n","**2.2 Create the Transistor Instances**\n","Use the PDK to instantiate two PMOS transistors, a reference and a mirror, with specified modifications:\n","```python\n"," pfet_ref = pmos(with_substrate_tap=False, with_dummy=(False, True))\n"," pfet_mir = pmos(with_substrate_tap=False, with_dummy=(True, False))\n","```\n","\n","**2.3 Add Transistors to the Component**\n","Insert the transistors into the current mirror component and position them:\n","```python\n"," cref_ref = currMirrComp << pfet_ref\n"," cmir_ref = currMirrComp << pfet_mir\n"," cref_ref.movex(evaluate_bbox(pfet_mir)[0] + max_metal_separation(pdk))\n","```\n","\n","**2.4 Add and Position the Tap Ring**\n","Incorporate a tap ring and ensure it encloses the transistors with additional padding to satisfy design rules:\n","```python\n"," tap_ring = tapring(pdk, enclosed_rectangle=evaluate_bbox(currMirrComp.flatten(), padding=pdk.get_grule(\"nwell\", \"active_diff\")[\"min_enclosure\"]))\n"," shift_amount = -prec_center(currMirrComp.flatten())[0]\n"," tring_ref = currMirrComp << tap_ring\n"," tring_ref.movex(destination=shift_amount)\n","```\n","\n","**2.5 Route the Connections**\n","Create routes between the ports:\n","```python\n"," currMirrComp << straight_route(pdk, cref_ref.ports[\"multiplier_0_source_E\"], cmir_ref.ports[\"multiplier_0_source_E\"])\n"," currMirrComp << straight_route(pdk, cref_ref.ports[\"multiplier_0_gate_E\"], cmir_ref.ports[\"multiplier_0_gate_E\"])\n"," currMirrComp << c_route(pdk, cref_ref.ports[\"multiplier_0_gate_E\"], cref_ref.ports[\"multiplier_0_drain_E\"])\n","\n"," return currMirrComp\n","```\n","\n","### Step 3: Visualizing the Layout\n","\n","**3.1 Generate and View the Layout**\n","Finally, visualize the generated layout by calling the `currentMirror` function and using the `.show()` method:\n","```python\n","# To visualize the layout\n","currentMirror(gf180).show()\n","```"]},{"cell_type":"markdown","metadata":{"id":"EFtjsVAixzzr"},"source":["Create the final design cell with the following code block:"]},{"cell_type":"code","execution_count":null,"metadata":{"id":"DGCUq98Qx58n"},"outputs":[],"source":["def currentMirror(pdk: MappedPDK):\n"," currMirrComp = Component()\n"," pfet_ref = pmos(pdk, with_substrate_tap=False, with_dummy=(False, True))\n"," pfet_mir = pmos(pdk, with_substrate_tap=False, with_dummy=(True, False))\n"," cref_ref = currMirrComp << pfet_ref\n"," cmir_ref = currMirrComp << pfet_mir\n"," pdk.util_max_metal_seperation()\n"," cref_ref.movex(evaluate_bbox(pfet_mir)[0] + pdk.util_max_metal_seperation())\n"," tap_ring = tapring(pdk, enclosed_rectangle=evaluate_bbox(currMirrComp.flatten(), padding=pdk.get_grule(\"nwell\", \"active_diff\")[\"min_enclosure\"]))\n"," shift_amount = -prec_center(currMirrComp.flatten())[0]\n"," tring_ref = currMirrComp << tap_ring\n"," tring_ref.movex(destination=shift_amount)\n"," currMirrComp << straight_route(pdk, cref_ref.ports[\"multiplier_0_source_E\"], cmir_ref.ports[\"multiplier_0_source_E\"])\n"," currMirrComp << straight_route(pdk, cref_ref.ports[\"multiplier_0_gate_E\"], cmir_ref.ports[\"multiplier_0_gate_E\"])\n"," currMirrComp << c_route(pdk, cref_ref.ports[\"multiplier_0_gate_E\"], cref_ref.ports[\"multiplier_0_drain_E\"])\n"," return currMirrComp\n","\n","currentMirror(gf180_mapped_pdk).write_gds(\"cmirror_example.gds\")\n","display_gds(\"cmirror_example.gds\")"]},{"cell_type":"markdown","metadata":{"id":"gLC6QYRbxk-v"},"source":["## Conclusion\n","\n","Following these steps results in a PMOS current mirror layout being composed and visualized. The tap ring encloses the transistors and the routing utilities are used to create the required connections respecting the design rules specified by the PDK.\n","\n","Each function call and module used here directly corresponds to a specific structure or operation within the context of the PDK and the layout process. This example provides a foundation upon which more complex circuits can be designed using the powerful features of the GLayout API."]}],"metadata":{"colab":{"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.11.7"},"vscode":{"interpreter":{"hash":"397704579725e15f5c7cb49fe5f0341eb7531c82d19f2c29d197e8b64ab5776b"}}},"nbformat":4,"nbformat_minor":0}
Loading