From f011515ebccb7af965eb125bb753f68f3221f4e6 Mon Sep 17 00:00:00 2001 From: PhillipRambo Date: Tue, 22 Apr 2025 14:58:44 +0200 Subject: [PATCH] change gmid content --- .gitignore | 1 + .../module_0_foundations/gmid_repo/README.md | 431 --- .../__pycache__/gmid_launcher.cpython-310.pyc | Bin 836 -> 0 bytes .../figures/nmos_current_density.svg | 2262 ------------- .../figures/nmos_current_density_filtered.svg | 2522 -------------- .../figures/nmos_current_density_options.svg | 2330 ------------- .../figures/nmos_custom_expression_1.svg | 2973 ----------------- .../figures/nmos_custom_expression_2.svg | 2404 ------------- .../gmid_repo/figures/nmos_gain_plot.svg | 2439 -------------- .../figures/nmos_output_characteristics.svg | 2045 ------------ .../gmid_repo/figures/nmos_plot_by_sweep.svg | 1739 ---------- .../gmid_repo/figures/nmos_quick_plot.svg | 2371 ------------- .../gmid_repo/figures/nmos_quick_plot2.svg | 1309 -------- .../gmid_repo/gmid_launcher.py | 38 - .../gmid_repo/matplotlib_style/style.mplstyle | 55 - .../gmid_repo/mosplot/__init__.py | 4 - .../__pycache__/__init__.cpython-310.pyc | Bin 310 -> 0 bytes .../__pycache__/hspice_parser.cpython-310.pyc | Bin 19415 -> 0 bytes .../ngspice_parser.cpython-310.pyc | Bin 2193 -> 0 bytes .../mosplot/parsers/hspice_parser.py | 615 ---- .../mosplot/parsers/ngspice_parser.py | 63 - .../lookup_table_generator.cpython-310.pyc | Bin 11993 -> 0 bytes .../src/__pycache__/main.cpython-310.pyc | Bin 19043 -> 0 bytes .../src/__pycache__/manu_man.cpython-310.pyc | Bin 4331 -> 0 bytes .../mosplot/src/lookup_table_generator.py | 336 -- .../gmid_repo/mosplot/src/main.py | 706 ---- .../gmid_repo/mosplot/src/manu_man.py | 140 - .../module_0_foundations/gmid_repo/setup.py | 14 - .../scripting/gmid_test.ipynb | 114 +- modules/module_0_foundations/sg13_nmos_lv.py | 58 + modules/module_0_foundations/sg13_pmos_lv.py | 58 + .../part_1_OTA/scripting/OTA_low_gain.ipynb | 209 +- .../part_1_OTA/testbenches/ota_testbench.sch | 26 +- 33 files changed, 286 insertions(+), 24976 deletions(-) delete mode 100644 modules/module_0_foundations/gmid_repo/README.md delete mode 100644 modules/module_0_foundations/gmid_repo/__pycache__/gmid_launcher.cpython-310.pyc delete mode 100644 modules/module_0_foundations/gmid_repo/figures/nmos_current_density.svg delete mode 100644 modules/module_0_foundations/gmid_repo/figures/nmos_current_density_filtered.svg delete mode 100644 modules/module_0_foundations/gmid_repo/figures/nmos_current_density_options.svg delete mode 100644 modules/module_0_foundations/gmid_repo/figures/nmos_custom_expression_1.svg delete mode 100644 modules/module_0_foundations/gmid_repo/figures/nmos_custom_expression_2.svg delete mode 100644 modules/module_0_foundations/gmid_repo/figures/nmos_gain_plot.svg delete mode 100644 modules/module_0_foundations/gmid_repo/figures/nmos_output_characteristics.svg delete mode 100644 modules/module_0_foundations/gmid_repo/figures/nmos_plot_by_sweep.svg delete mode 100644 modules/module_0_foundations/gmid_repo/figures/nmos_quick_plot.svg delete mode 100644 modules/module_0_foundations/gmid_repo/figures/nmos_quick_plot2.svg delete mode 100644 modules/module_0_foundations/gmid_repo/gmid_launcher.py delete mode 100644 modules/module_0_foundations/gmid_repo/matplotlib_style/style.mplstyle delete mode 100644 modules/module_0_foundations/gmid_repo/mosplot/__init__.py delete mode 100644 modules/module_0_foundations/gmid_repo/mosplot/__pycache__/__init__.cpython-310.pyc delete mode 100644 modules/module_0_foundations/gmid_repo/mosplot/parsers/__pycache__/hspice_parser.cpython-310.pyc delete mode 100644 modules/module_0_foundations/gmid_repo/mosplot/parsers/__pycache__/ngspice_parser.cpython-310.pyc delete mode 100644 modules/module_0_foundations/gmid_repo/mosplot/parsers/hspice_parser.py delete mode 100644 modules/module_0_foundations/gmid_repo/mosplot/parsers/ngspice_parser.py delete mode 100644 modules/module_0_foundations/gmid_repo/mosplot/src/__pycache__/lookup_table_generator.cpython-310.pyc delete mode 100644 modules/module_0_foundations/gmid_repo/mosplot/src/__pycache__/main.cpython-310.pyc delete mode 100644 modules/module_0_foundations/gmid_repo/mosplot/src/__pycache__/manu_man.cpython-310.pyc delete mode 100644 modules/module_0_foundations/gmid_repo/mosplot/src/lookup_table_generator.py delete mode 100644 modules/module_0_foundations/gmid_repo/mosplot/src/main.py delete mode 100644 modules/module_0_foundations/gmid_repo/mosplot/src/manu_man.py delete mode 100644 modules/module_0_foundations/gmid_repo/setup.py create mode 100644 modules/module_0_foundations/sg13_nmos_lv.py create mode 100644 modules/module_0_foundations/sg13_pmos_lv.py diff --git a/.gitignore b/.gitignore index e4df3b01..b6e28286 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,5 @@ modules/module_3_8_bit_SAR_ADC/part_2_digital_comps/bootstrap_switch/python/ *.so *.out *.vcd +*.npz diff --git a/modules/module_0_foundations/gmid_repo/README.md b/modules/module_0_foundations/gmid_repo/README.md deleted file mode 100644 index 2e0ecc33..00000000 --- a/modules/module_0_foundations/gmid_repo/README.md +++ /dev/null @@ -1,431 +0,0 @@ -# Modified gmid Script for IHP Open PDK - -This repository contains a modified version of the original [gmid](https://github.com/medwatt/gmid) script, adapted specifically for use with the IHP Open PDK. - -## Acknowledgements - -We extend our thanks to [medwatt](https://github.com/medwatt) for providing a robust environment for generating GmID lookup tables with NgSpice. - -## Credits - -All credit for the original repository and script goes to [medwatt](https://github.com/medwatt). - -## Changes and Enhancements - -- **Terminal GUI**: A terminal-based GUI was developed to facilitate easy selection of MOSFETs in the IHP Open PDK for generating LUTs. -- **LUT Class**: The lookup table generator was modified to ensure compatibility with the IHP Open PDK netlisting format. -- **Automation Handling**: A dedicated handling script was created to automate the GUI process for improved workflow. - - - - -# MOSFET Characterization in Python - -## Motivation - -This tool has the following goals: - -1. Provide an easy way of creating plots of MOSFET parameters, such as those - used in the gm/ID design methodology. - -2. Provide a tool that does not depend on any proprietary software or require - licensing fees. - -3. Open source so that it can be easily modified/extended by the user. - -## Installation - -### Requirements - -This tools is written in Python and requires the following: - -- `Numpy`, `Scipy`, and `Matplotlib` for data analysis and plotting. - -- [`ngspice`](https://ngspice.sourceforge.io/) or `hspice` for generating the - lookup table. - - -### Installation - -- Clone this repository: `git clone https://github.com/medwatt/gmid.git`. - -- Inside the directory, invoke: `pip install .`. - - -## Generating a Lookup Table - -Before any plots can be made, a lookup table of all the relevant parameters -must first be created. This is done by instantiating an object from the -`LookupTableGenerator` and then building the table with the `build` method. An -example is given below. - -```python -from mosplot import LookupTableGenerator - -obj = LookupTableGenerator( - description="freepdk 45nm ngspice", - simulator="ngspice", - simulator_path="/usr/bin/ngspice", # optional - model_paths=[ - "/home/username/gmid/models/NMOS_VTH.lib", - "/home/username/gmid/models/PMOS_VTH.lib", - ], - model_names={ - "nmos": "NMOS_VTH", - "pmos": "PMOS_VTH", - }, - vsb=(0, 1.0, 0.1), - vgs=(0, 1.0, 0.01), - vds=(0, 1.0, 0.01), - width=10e-6, - lengths=[50e-9, 100e-9, 200e-9, 400e-9, 800e-9, 1.6e-6, 3.2e-6, 6.4e-6], -) -obj.build("/home/username/gmid/lookup_tables/freepdk_45nm_ngspice.npy") -``` - -A summary of some of the parameters is given below: - -- The simulator used is specified with the `simulator` parameter. At the - moment, only `ngspice` and `hspice` are supported. If you're using windows or - some linux distribution where `ngspice` and `hspice` are named differently, - you will have to pass the full path to the binary to the `simulator_path` - variable. - -- The lookup_table will be generated for a specific transistor model. Provide - the location of the model files as a list using the `model_paths` parameter. - Since it is possible to have more than one model definition inside a file, - you need to specify the model name. This is done via the `model_names` - parameter, where the keys are always `"nmos"` and `"pmos` and their values - are the names of the models to be used. - -- If there's a specific need to pass in some custom SPICE commands, these - should be done via the `raw_spice` parameter (not shown in the example above). - -- To generate a lookup table, the bulk, gate, and drain voltages relative to - the source have to be swept over a range of voltages. Specify the range in - the form `(start, stop, step)`. The smaller the step size, the bigger is the - size of the lookup table. - -- The `lengths` can be provided as a list of discrete values or a 1-dimensional - `numpy` array. - -- Only a single `width` should be provided. The assumption here is that the - parameters of the MOSFET scale linearly with the width. Because of this - assumption, all parameters that are width-dependent must be de-normalized - with respect to the current or width that you're working with. - -- The directory where the generated lookup table is saved is passed directly to - the `build` method. - -## Using the Tool - -Because of the interactive nature of designing analog circuits, using this -script within a `jupyter` notebook is highly recommended. - -### Imports - -We begin by making the following imports: - -```python -import numpy as np -from mosplot import load_lookup_table, LoadMosfet -``` - -The `load_lookup_table` function loads a lookup table such as the one generated -in the previous section. - -```python -lookup_table = load_lookup_table("path/to/lookup-table.npy") -``` - -The `LoadMosfet` class contains methods that can be used to generate plots -seamlessly. If you plan to modify the style of the plots or plot things -differently, you will also have to import `matplotlib`. - -```python -import matplotlib.pyplot as plt -plt.style.use('path/to/style') -``` - -### Making Simple Plots - -We start by creating an object called `nmos` that selects the NMOS -from the lookup table and sets the source-bulk and drain-source voltages to -some fixed values. Since the data is 4-dimensional, it is necessary to fix two -of the variables at a time to enable 2-dimensional plotting. - -```python -nmos = LoadMosfet(lookup_table=lookup_table, mos="nmos", vsb=0.0, vds=0.5, vgs=(0.3, 1)) -``` - -The above code filters the table at `vsb=0.0` and `vds=0.5` for all `lengths` -and for `vgs` values between `(0.3, 1)`. You can also include a step such as -`(0.3, 1, 0.02)`. If you want all values of `vgs`, either set it to `None` or -don't include it. - -Methods are available to create the most commonly-used plots in the gm/ID -methodology so that you don't have to type them. These are: - -- `current_density_plot()`: this plots $I_{D}/W$ vs $g_{m}/I_{D}$. -- `gain_plot()`: this plots $g_m / g_{ds}$ vs $g_{m}/I_{D}$. -- `transit_frequency_plot()`: this plots $f_{T}$ vs $g_{m}/I_{D}$. -- `early_voltage_plot()`: this plots $V_{A}$, vs $g_{m}/I_{D}$. - -For example, the plot of $I_{D}/W$ vs $g_{m}/I_{D}$ is shown below. - -```python -nmos.current_density_plot() -``` - -![current density plot](./figures/nmos_current_density.svg) - -When the lookup table includes a lot of lengths, the plot can become crowded. -You can pass a list of lengths to plot with the `length` parameter. - -Use `nmos.lengths` to get a list of all the lengths in the lookup table. - -``` -array([5.0e-08, 1.0e-07, 2.0e-07, 4.0e-07, 8.0e-07, 1.6e-06, 3.2e-06, - 6.4e-06]) -``` - -Pass a filtered list to the `current_density_plot` method. - -```python -nmos.current_density_plot( - lengths = [5.0e-08, 1.0e-07, 2.0e-07] -) -``` - -![current density plot](./figures/nmos_current_density_filtered.svg) - -Note that the tool does its best to determine how to scale the axes. For -example, in the last plot, a `log` scale was chosen for the y-axis. We can -easily overwrite that, as well as other things. - -```python -nmos.current_density_plot( - lengths = [5.0e-08, 1.0e-07, 2.0e-07], - y_scale = 'linear', - x_limit = (5, 20), - y_limit = (0, 300), - save_fig="path/to/save/figure/with/extension" -) -``` - -![current density plot](./figures/nmos_current_density_options.svg) - -### Plotting by Expression - -Now, suppose we want to plot something completely custom. The example below -shows how. - -```python -nmos.plot_by_expression( - x_expression = nmos.vgs_expression, - y_expression = { - "variables": ["id", "gds"], - "function": lambda x, y: x / y, - "label": "$I_D / g_{ds} (A/S)$" - }, -) -``` - -![custom expression](./figures/nmos_custom_expression_1.svg) - -For this example, we want $V_{\mathrm{GS}}$ on the x-axis. Since $V_{\mathrm{GS}}$ is such a -commonly-used expression, it is already defined in the code. Other -commonly-used expressions are also defined, such as: - -- `gmid_expression` -- `vgs_expression` -- `vds_expression` -- `vsb_expression` -- `gain_expression` -- `current_density_expression` -- `transist_frequency_expression` -- `early_voltage_expression` - -For the y-axis, we want a custom expression that uses the parameters $I_D$ and -$g_{\mathrm{ds}}$. This can be done by defining a dictionary that specifies the -variables needed and how to calculate the required parameter. The `label` field -is optional. The function field is also optional if we want to just plot the -parameter, as shown in the example below. - -```python -nmos.plot_by_expression( - x_expression = nmos.vgs_expression, - # y_expression = nmos.id_expression, ## same as below - y_expression = { - "variables": ["id"], - "label": "$I_D (A)$" - } -) -``` - -![custom expression](./figures/nmos_custom_expression_2.svg) - -## Looking Up Values - -While having plots is a good way to visualize trends, we might also just be -interested in the raw value. - -![gain expression](./figures/nmos_gain_plot.svg) - -Looking at the figure above, it's hard to read the exact value on the y-axis -for a particular value on the x-axis, especially more so when the scale is -logarithmic. Also, what if we need to read the value for a length that -is not defined in our lookup table? - -There are two ways to go about this: - -- Zoom in and click on the plot. This prints out the `x` and `y` - coordinates. Note, in jupyter notebooks, you need to execute `%matplotlib - widget` or `%matplotlib qt` to interact with the plot. - -- Use a lookup method to get a more precise value. - -### Lookup Using Interpolation - -The snippet below shows how we can lookup the `gain` given the `length` and -`gmid`. The returned value is calculated using interpolation from the available -data. The accuracy of the result depends on how far the points are from those -defined in the table. - -```python -x = nmos.interpolate( - x_expression=nmos.lengths_expression, - x_value=100e-9, - y_expression=nmos.gmid_expression, - y_value=15, - z_expression=nmos.gain_expression, -) -``` - -The above code evaluates the `gain` at a single point. Suppose we want to know -the `gmid` or `length` for which `0.08 <= vdsat < 0.12` and `1e6 <= gds < 4e-6`. -The snippet below shows how. - -```python -x = nmos.interpolate( - x_expression=nmos.vdsat_expression, - x_value=(0.08, 0.12, 0.01), - y_expression=nmos.gds_expression, - y_value=(1e-6, 4e-6, 1e-6), - z_expression=nmos.gmid_expression, - # z_expression=nmos.length_expression, -) - # 1e-6 -array([[17.95041245, 17.89435802, 17.47526426], # 0.08 - [16.87609489, 16.76595338, 16.53927928], - [14.77585736, 15.09803158, 14.9483348 ], - [14.12540234, 14.05481451, 14.04265227]]) -``` - -### Lookup By Expression - -`lookup_expression_from_table()` simply looks up an expression from the -table. It doesn't use any interpolation. So, make sure that the values you -are looking up are present in the table. - -```python -x = nmos.lookup_expression_from_table( - lengths=100e-9, - vsb=0, - vds=(0.0, 1, 0.01), - vgs=(0.0, 1.01, 0.2), - primary="vds", - expression=nmos.current_density_expression, -) -``` - -## Plotting Methods - -### Plot by Sweep - -The `plot_by_sweep` method is extremely flexible and can be used to create -all sorts of plots. For example, the snippet below shows how to plot the -traditional output characteristic plot of a MOSFET. - -```python -nmos.plot_by_sweep( - lengths=180e-9, - vsb = 0, - vds = (0.0, 1, 0.01), # you can also set to `None` - vgs = (0.0, 1.01, 0.2), - x_expression_expression = nmos.vds_expression, - y_expression_expression = nmos.id_expression, - primary = "vds", - x_eng_format=True, - y_eng_format=True, - y_scale='linear', -) -``` - -![output characteristic](./figures/nmos_output_characteristics.svg) - -### Quick Plot - -Let's say we want to see how $V_{\mathrm{DS}_{\mathrm{SAT}}}$ (the drain-source -voltage required to enter saturation) compares with $V_{\mathrm{OV}}$ and -$V^{\star} = \frac{2}{g_m / I_D}$ in a single plot. We can generate each of -these plots individually, as we did before, but ask the method to return the -plot data so that we can combine them in a single plot. Note that you can also -use `lookup_expression_from_table()` to return the required data if you don't -want to see the plot. - -```python -vdsat = nmos.plot_by_expression( - lengths=[45e-9], - x_expression = nmos.vgs_expression, - y_expression = nmos.vdsat_expression, - return_result = True, -) - -vov = nmos.plot_by_expression( - lengths=[45e-9], - x_expression = nmos.vgs_expression, - y_expression = { - "variables": ["vgs", "vth"], - "function": lambda x, y: x - y, - }, - return_result = True, -) - -vstar = nmos.plot_by_expression( - lengths=[45e-9], - x_expression = nmos.vgs_expression, - y_expression = { - "variables": ["gm", "id"], - "function": lambda x, y: 2 / (x/y), - }, - return_result=True, -) -``` - -The result is returned in a tuple in the form `(x_data, y_data)`. We can then -make any custom plot using `matplotlib`. Nevertheless, there's a method called -`quick_plot()` that formats the plot in the same way as the generated plots. -`quick_plot()` accepts `numpy` arrays, or a list of `x` and `y` values, as -shown in the example below. - -```python -nmos.quick_plot( - x = [vdsat[0], vstar[0], vov[0]], - y = [vdsat[1], vstar[1], vov[1]], - legend = ["$V_{\\mathrm{DS}_{\\mathrm{SAT}}}$", "$V^{\\star}$", "$V_{\\mathrm{OV}}$"], - x_limit = (0.1, 1), - y_limit = (0, 0.6), - x_label = "$V_{\\mathrm{GS}}$", - y_label = "$V$", -) -``` - -![qucik plot](./figures/nmos_quick_plot.svg) - -# Acknowledgment - -- Parsing the output from `hspice` is done using - [this](https://github.com/HMC-ACE/hspiceParser) script. - -- If you find this tool useful, it would be nice if you cite it. diff --git a/modules/module_0_foundations/gmid_repo/__pycache__/gmid_launcher.cpython-310.pyc b/modules/module_0_foundations/gmid_repo/__pycache__/gmid_launcher.cpython-310.pyc deleted file mode 100644 index be42a3a48ac76cd3a5c98da92d4aba018c1641ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 836 zcmZ8eJ&)8d5Vhlc?bq!V2V4adG-)<}0HFg43J}d9is&RO8~b*{#!h5AoE9b3(()gm zzW#MZ2|_uO*t=R(;BLI#S7PD=SJmHmm21Wj>5fg zSW`$Q5HBJ0djNy>s7D6x(WTep-ZNf@_xO_Zr1$&45I7I|u#ftQkTyHBsb#trB}=QpMrxdoI=xb0 z72C?SZpwl$n_UvB0932c0emo0z61BIHdwV~#geIwVT77p!)-7ywToj*9d{MEsn|`8 zZ^bC*ta28snS&Dta{x=~)rap$-G}_olRF{?+74)yx3bu91w5@U@=`jg`Y}L=$M^&< zutz+6cZa`ECh82DY)q+}qSTomiCQ;RZEm!k{;!r=6-$xJ7CPmT0k@_cZgL+&=|K4i c9t`h11q0HI41GEG4}ud1L+0dfB*mh diff --git a/modules/module_0_foundations/gmid_repo/figures/nmos_current_density.svg b/modules/module_0_foundations/gmid_repo/figures/nmos_current_density.svg deleted file mode 100644 index 4794aa66..00000000 --- a/modules/module_0_foundations/gmid_repo/figures/nmos_current_density.svg +++ /dev/null @@ -1,2262 +0,0 @@ - - - - - - - - 2023-11-07T10:57:11.324023 - image/svg+xml - - - Matplotlib v3.8.0, https://matplotlib.org/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/modules/module_0_foundations/gmid_repo/figures/nmos_current_density_filtered.svg b/modules/module_0_foundations/gmid_repo/figures/nmos_current_density_filtered.svg deleted file mode 100644 index 15ea90a8..00000000 --- a/modules/module_0_foundations/gmid_repo/figures/nmos_current_density_filtered.svg +++ /dev/null @@ -1,2522 +0,0 @@ - - - - - - - - 2023-11-07T10:58:38.762276 - image/svg+xml - - - Matplotlib v3.8.0, https://matplotlib.org/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/modules/module_0_foundations/gmid_repo/figures/nmos_current_density_options.svg b/modules/module_0_foundations/gmid_repo/figures/nmos_current_density_options.svg deleted file mode 100644 index dba28229..00000000 --- a/modules/module_0_foundations/gmid_repo/figures/nmos_current_density_options.svg +++ /dev/null @@ -1,2330 +0,0 @@ - - - - - - - - 2023-11-07T11:00:16.184541 - image/svg+xml - - - Matplotlib v3.8.0, https://matplotlib.org/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/modules/module_0_foundations/gmid_repo/figures/nmos_custom_expression_1.svg b/modules/module_0_foundations/gmid_repo/figures/nmos_custom_expression_1.svg deleted file mode 100644 index c6b9fabc..00000000 --- a/modules/module_0_foundations/gmid_repo/figures/nmos_custom_expression_1.svg +++ /dev/null @@ -1,2973 +0,0 @@ - - - - - - - - 2023-11-07T11:01:12.285212 - image/svg+xml - - - Matplotlib v3.8.0, https://matplotlib.org/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/modules/module_0_foundations/gmid_repo/figures/nmos_custom_expression_2.svg b/modules/module_0_foundations/gmid_repo/figures/nmos_custom_expression_2.svg deleted file mode 100644 index 53e2efd7..00000000 --- a/modules/module_0_foundations/gmid_repo/figures/nmos_custom_expression_2.svg +++ /dev/null @@ -1,2404 +0,0 @@ - - - - - - - - 2023-11-07T11:07:25.240509 - image/svg+xml - - - Matplotlib v3.8.0, https://matplotlib.org/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/modules/module_0_foundations/gmid_repo/figures/nmos_gain_plot.svg b/modules/module_0_foundations/gmid_repo/figures/nmos_gain_plot.svg deleted file mode 100644 index 543bc867..00000000 --- a/modules/module_0_foundations/gmid_repo/figures/nmos_gain_plot.svg +++ /dev/null @@ -1,2439 +0,0 @@ - - - - - - - - 2023-11-09T23:43:09.194887 - image/svg+xml - - - Matplotlib v3.8.0, https://matplotlib.org/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/modules/module_0_foundations/gmid_repo/figures/nmos_output_characteristics.svg b/modules/module_0_foundations/gmid_repo/figures/nmos_output_characteristics.svg deleted file mode 100644 index 2aadfbdc..00000000 --- a/modules/module_0_foundations/gmid_repo/figures/nmos_output_characteristics.svg +++ /dev/null @@ -1,2045 +0,0 @@ - - - - - - - - 2023-11-02T16:08:38.335943 - image/svg+xml - - - Matplotlib v3.8.0, https://matplotlib.org/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/modules/module_0_foundations/gmid_repo/figures/nmos_plot_by_sweep.svg b/modules/module_0_foundations/gmid_repo/figures/nmos_plot_by_sweep.svg deleted file mode 100644 index 79d30548..00000000 --- a/modules/module_0_foundations/gmid_repo/figures/nmos_plot_by_sweep.svg +++ /dev/null @@ -1,1739 +0,0 @@ - - - - - - - - 2023-11-02T15:41:01.451027 - image/svg+xml - - - Matplotlib v3.8.0, https://matplotlib.org/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/modules/module_0_foundations/gmid_repo/figures/nmos_quick_plot.svg b/modules/module_0_foundations/gmid_repo/figures/nmos_quick_plot.svg deleted file mode 100644 index d25d864b..00000000 --- a/modules/module_0_foundations/gmid_repo/figures/nmos_quick_plot.svg +++ /dev/null @@ -1,2371 +0,0 @@ - - - - - - - - 2023-11-02T14:58:52.693797 - image/svg+xml - - - Matplotlib v3.8.0, https://matplotlib.org/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/modules/module_0_foundations/gmid_repo/figures/nmos_quick_plot2.svg b/modules/module_0_foundations/gmid_repo/figures/nmos_quick_plot2.svg deleted file mode 100644 index 4a8724bd..00000000 --- a/modules/module_0_foundations/gmid_repo/figures/nmos_quick_plot2.svg +++ /dev/null @@ -1,1309 +0,0 @@ - - - - - - - - 2023-11-02T15:45:04.279117 - image/svg+xml - - - Matplotlib v3.8.0, https://matplotlib.org/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/modules/module_0_foundations/gmid_repo/gmid_launcher.py b/modules/module_0_foundations/gmid_repo/gmid_launcher.py deleted file mode 100644 index 4c0b84c9..00000000 --- a/modules/module_0_foundations/gmid_repo/gmid_launcher.py +++ /dev/null @@ -1,38 +0,0 @@ -from mosplot import LookupTableGenerator -from mosplot.src.manu_man import description_menu, sweeping_menu, input_selection, transistor_menu -import os - -def main(): - pdk_type = input_selection() - model, transistor_model = transistor_menu() # model is a dictionary - description, simulator, model_path = description_menu(model) - vsb, vgs, vds, width, lengths = sweeping_menu() - - # Create the LookupTableGenerator object with all parameters - obj = LookupTableGenerator( - simdisc=transistor_model, - description=description, - simulator=simulator, - model_paths=model_path, - model_names=model, # Directly use the model dictionary - vsb=vsb, - vgs=vgs, - vds=vds, - width=width, - lengths=lengths, - ) - - - - file_name = f"{description}" - file_path = os.path.join('LUTs', file_name) - - - os.makedirs('LUTs', exist_ok=True) - - obj.build(file_path) - - -if __name__ == "__main__": - main() - diff --git a/modules/module_0_foundations/gmid_repo/matplotlib_style/style.mplstyle b/modules/module_0_foundations/gmid_repo/matplotlib_style/style.mplstyle deleted file mode 100644 index e6816080..00000000 --- a/modules/module_0_foundations/gmid_repo/matplotlib_style/style.mplstyle +++ /dev/null @@ -1,55 +0,0 @@ -# Matplotlib style for scientific plotting -# This is the base style for "SciencePlots" -# see: https://github.com/garrettj403/SciencePlots - -# Set color cycle: blue, green, yellow, red, violet, gray -axes.prop_cycle : cycler('color', ['0C5DA5', '00B945', 'FF9500', 'FF2C00', '845B97', '474747', '9e9e9e']) - -# Set default figure size -figure.figsize : 3.5, 2.625 - -# Set x axis -xtick.direction : in -xtick.major.size : 3 -xtick.major.width : 0.5 -xtick.minor.size : 1.5 -xtick.minor.width : 0.5 -xtick.minor.visible : True -xtick.top : True - -# Set y axis -ytick.direction : in -ytick.major.size : 3 -ytick.major.width : 0.5 -ytick.minor.size : 1.5 -ytick.minor.width : 0.5 -ytick.minor.visible : True -ytick.right : True - -# Set line widths -axes.linewidth : 0.5 -grid.linewidth : 0.5 -lines.linewidth : 1. - -# Remove legend frame -legend.frameon : False - -# Always save as 'tight' -savefig.bbox : tight -savefig.pad_inches : 0.05 -savefig.transparent : True - -# Increase global font size -font.size : 14 - -# Use sans-serif fonts -font.sans-serif : cm -font.family : sans-serif - -# Use CM Sans Serif for math text -axes.formatter.use_mathtext : True -mathtext.fontset : cm - -# Use LaTeX for math formatting -text.usetex : True -text.latex.preamble : \usepackage{amsmath} \usepackage{amssymb} diff --git a/modules/module_0_foundations/gmid_repo/mosplot/__init__.py b/modules/module_0_foundations/gmid_repo/mosplot/__init__.py deleted file mode 100644 index 4117c367..00000000 --- a/modules/module_0_foundations/gmid_repo/mosplot/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from .src.main import LoadMosfet, load_lookup_table -from .src.lookup_table_generator import LookupTableGenerator - -__all__ = ['LoadMosfet', 'load_lookup_table', 'LookupTableGenerator'] diff --git a/modules/module_0_foundations/gmid_repo/mosplot/__pycache__/__init__.cpython-310.pyc b/modules/module_0_foundations/gmid_repo/mosplot/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index 352e607a9753ee13a03f5f9417c57e52870894fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 310 zcmYk1u}%ab5Qc%>yW3pu5>2e^u2P!g1&pz?Ic>DsW`e@48)0VyT;c23`361J_ddQE|+sg^|SigzSI0sDFlt9;$ooOR4p zue_a@`i{xTC#U05Vdxwe8{blU$4&aT2ri2xIpQ$JGR*lx!5bdBk-y7vI gjt-Lo=!ZT5tjCw!TzE7)XD`cd;*@a27JMOo0V(=WssI20 diff --git a/modules/module_0_foundations/gmid_repo/mosplot/parsers/__pycache__/hspice_parser.cpython-310.pyc b/modules/module_0_foundations/gmid_repo/mosplot/parsers/__pycache__/hspice_parser.cpython-310.pyc deleted file mode 100644 index fc9f6666175bba9350d3f4c84ec6fe11e1cdd441..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19415 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 D@xEJ* diff --git a/modules/module_0_foundations/gmid_repo/mosplot/parsers/__pycache__/ngspice_parser.cpython-310.pyc b/modules/module_0_foundations/gmid_repo/mosplot/parsers/__pycache__/ngspice_parser.cpython-310.pyc deleted file mode 100644 index c75925d7c0152aac651e6b4eb527195c07f7fed2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2193 zcmaJCO>Z1E)b@Pr>}K=PG>sZm&~PZpO3?<2kPr${B@o;qlvY9%%4o9oY^R;|Ol)t` zjb>jz{aEH6FyW9f_zFpex>LTrko%rCBG!r`_=0bHST$~PsQQ}81^%5+cmLwuw z(C1f#Ksrcrwo~M4)wKsKCN-JRE;7eP=m3Bs%Z-eC;whddS=`l6X91FVJKT>|8t=k| zr|1`?6nQF*)`;@7C!|husdWv|PTuRql4~E}yf8p-F&pga^iV{)u#Fx(7)M#EO^aGr zi!6Ce6gZju{ocl{yeBpa0S0OzH@dx)Z}f7Fift4z(3IYg6K_Nlyj=`z5Jjm>O%$Ou zl}SFGqld4b<+t{fw}TFwju`;Z0~l8Q8MxDsl5%>)9{u<&Ny(6P$GJ^i zzcxY1czuN&(P6EE8x_zZ8}3rxMN9np`Gr*0a27HFibBmN!vioyN4O_0my zLGHUCcLC%+GBcwlo~#gl4)()u+DX9Sz99f{7+!Zuu(drd7v&lAZ4Qr z_|ijXOerbd(R|59=f(svw0%q{kyO&X+0O~T;1ZV{Il$+XZo;mScZmMw066jc0_K$7 zT8_U2w_@&wCjkt1QyHs4sN#b#fxOo3a7UQFlA-ArnF#YFG`B>E$+8|oJ|Wf!PX=a0 z*b^qk<92u*8O@-0d8Q2uD1Te+^)22SE{^nhz706 zq74GFH5B{hYNEtmU&zj2^=4~5gtK^8pB(M4<$cov`imDVQ@hunVkh|E39e9EK`*`w zwUe4BnCl9u8td$|m=zX`!fJn|ogg<7&%@Mj!O|rqxj8?i5Pt&sOviM@#$@Dh$cm9W zCO@z}h&{aM#k!NGEzbt%h%A*tVHdETHYzQw&qXKa0#MWnx&mvzZE5rvfTU1ZfK?w* z*i>v|6I%o{lVWQX@Tx=kgt3dq{_)|JGiw_kjWCzmn_1q8Gra}CRLGeoUPH;)gDVpo zLkeY2R;uD(AqhJ%jHx+bQ46@B16xcj!v@W(5S@w2NUro&_(xcWsnLy>hz-EqRlF;x z4~EteE67m`$44`JA<8nDhCF#z?!Vr^@3@{6dj4snAd=0utg9>U=pZU+3+oX%ff#U+!bo^tNv45Dyp1IH6 zw-;AP)1#{OVo&MyTMB&du zy^l*3^cM@7qA=>!Zv+!RAfWPGMQb_Wn0~JqsI@8ES@&(QIeB)gDpxGffGo0q0moA> Ak^lez diff --git a/modules/module_0_foundations/gmid_repo/mosplot/parsers/hspice_parser.py b/modules/module_0_foundations/gmid_repo/mosplot/parsers/hspice_parser.py deleted file mode 100644 index 242d284b..00000000 --- a/modules/module_0_foundations/gmid_repo/mosplot/parsers/hspice_parser.py +++ /dev/null @@ -1,615 +0,0 @@ -""" -Author: Raphael Gonzalez (RAffA), Mathew Spencer -github: RaffaGonzo - - -Copyright 2021 Raphael Gonzalez, Mathew Spencer - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -""" -import struct -from os.path import basename, split, join -from os import mkdir -from shutil import rmtree -import pickle -import sys - -COUNT = 0 - -def read_data_block(data_block, vrsn): - data_format = {'9601': (' 1 - assert COUNT > 0 # for debugging - - func_dict = {'tr': general_make_dict, - 'sw': general_make_dict, - 'ac': ac_make_dict} - - return func_dict[ext](var_lst, data_lst, header_str, MULTI_SWEEP_FLAG) - -def write_to_file(write_path, file_content, ext=None): - if type(file_content) == str: - with open(write_path, 'w+') as file: - file.write(file_content) - elif ext == 'mat': - sio.savemat(write_path, file_content) - else: - with open(write_path, 'wb') as file: - pickle.dump(file_content, file, protocol=pickle.HIGHEST_PROTOCOL) - -def get_outfile_name(path, ext=None): - file_name = basename(path) - outfile_name = file_name.replace('.', '_') - if ext is not None: - outfile_name += f'.{ext}' - return outfile_name - -def import_export_binary(path, ext, from_ext): - """ - this function will import *.tr*, *.sw*, and *.ac* binary and put a similarly named csv, matlab *.m, or python.pickle file/ folder of files in the same directory - :param path: (str) path to the *.tr* binary to be imported - :param ext: (str) the extension of the output file [only options *.m, *.csv, and *.pickle] - :return: None - """ - dict_to_pickle_dict = lambda dict_data: dict_data - - ext_dict = {'m': dict_to_matlab_str, - 'csv': dict_to_csv_str, - 'pickle': dict_to_pickle_dict, - 'mat': dict_to_mat_obj} - try: - header, data = read_binary_signal_file(path) - main_dict, sweep_flag, sweep_var_name, sweep_values = write_to_dict(data, header, from_ext) - # use sweep_flag to tell if it should be a folder of csvs or single file - if sweep_flag and ext == 'csv': - content = '' - fpath = path + '_' + sweep_var_name + '(' - outfile_name = get_outfile_name(path, ext) - folder_name = get_outfile_name(outfile_name) # gets rid of dot - og_path = str(split(fpath)[0]) - path = join(og_path, folder_name) - try: - mkdir(path) - except FileExistsError: # this will overwrite an existing folder with the same name - rmtree(path) - mkdir(path) - - for i in range(len(list(main_dict.values())[0])): - temp_dict = {} - for key in main_dict.keys(): - temp_dict[key] = [main_dict[key][i]] - file_name = get_outfile_name(fpath) + str(sweep_values[i]) + ').csv' - full_path = join(path, file_name) - content = dict_to_csv_str(temp_dict) - write_to_file(full_path, content) - else: - outfile_name = get_outfile_name(path, ext) - dir_path, _ = split(path) - file_path = join(str(dir_path), outfile_name) - content = ext_dict[ext](main_dict) - write_to_file(file_path, content, ext) - return main_dict, content - - except KeyError: - raise ValueError('the extension must NOT have the "." in it ex: "csv" | the only extension options are m, csv, and pickle') - except FileNotFoundError as err: - print(err) - -def import_export_ascii(path, ext): - dict_to_pickle_dict = lambda dict_data: dict_data - - ext_dict = {'m': dict_to_matlab_str, - 'csv': dict_to_csv_str, - 'pickle': dict_to_pickle_dict, - 'mat': dict_to_mat_obj} - try: - main_dict = signal_file_ascii_read(path) - content_obj = ext_dict[ext](main_dict) - sweep_flag = len(list(main_dict.values())[0]) > 1 - sweep_var_name = '' - sweep_values = [] - for key, val in main_dict.items(): - if len(val[0]) == 1 and sweep_flag: - sweep_var_name = key - sweep_values = sum(val, []) - break - if sweep_flag and ext == 'csv': - fpath = f'{path}_{sweep_var_name}(' - outfile_name = get_outfile_name(path, ext) - folder_name = get_outfile_name(outfile_name) # gets rid of dot - og_path = str(split(fpath)[0]) - path = join(og_path, folder_name) - try: - mkdir(path) - except FileExistsError: # this will overwrite an existing folder with the same name - rmtree(path) - mkdir(path) - - for i in range(len(list(main_dict.values())[0])): - temp_dict = {} - for key in main_dict.keys(): - temp_dict[key] = [main_dict[key][i]] - file_name = get_outfile_name(fpath) + str(sweep_values[i]) + ').csv' - full_path = join(path, file_name) - content = dict_to_csv_str(temp_dict) - write_to_file(full_path, content) - else: - outfile_name = get_outfile_name(path, ext) - dir_path, _ = split(path) - file_path = join(str(dir_path), outfile_name) - write_to_file(file_path, content_obj, ext) - return main_dict, content_obj - except KeyError: - raise ValueError('the only extension options are "m," "csv," or "pickle"') - except FileNotFoundError as err: - print(err) - -def usage(): - usage_str = """Usage: - python Hspice_parse - - *** note: This parser only supports the 2001, 9601 formats - designated by ".option post_version=9601" for example - - supported input file types are: - - AC simulations *.ac* - - DC sweeps *.sw* - - Transient simulations *.tr* - - supported output file types are: - - CSV note that if there are multiple sweeps in the input - file this option will output a folder of CSVs - - pickle - - matlab's *.m - - -h or --help to get this message - """ - print(usage_str) - -def get_from_ext(path): # this function is for auto detecting the input file extention - file_name = basename(path) - name_components = file_name.split('.') - entire_ext = name_components[-1] - return entire_ext[:2] # returns the first two chars of the extension i.e. "ac" "sw" "tr" and ignores the numbers after - -def reformat(sweep_lst): - """ - This function will change the original output of signal_file_ascii_read() to the format that - the write to dict function makes. - :param sweep_lst: list of dictionaries - :return: dictionary of 2D lists - """ - rtn_dict = {key: [] for key in sweep_lst[0].keys()} - for sweep in sweep_lst: - for key, value in sweep.items(): - rtn_dict[key].append(value) - return rtn_dict - -###################### ascii parsing ################### -# author: Mathew Spencer - -# class simulation_result(): -# """All the results germane to a single hSpice simulation including -# results, measures, parameters, temperature and alter number. -# -# Contains dicts called 'results' 'measures' 'parameters' and -# 'misc' each of which is keyed with named values and has values -# corresponding to the results. -# """ -# pass - - -# class sweep_result(): -# """Aggregates the results of individual simulations -# """ -# pass - -def signal_file_ascii_read(post2file): - """Accepts a raw sweep or measure file from spice in ASCII format - (.tr*, .sw*, .mt*, etc.) and returns a list of dicts containing the - signal and parameter names as keys. Signal name keys have an array - containing the simulation results as values. Parameter name keys have - the parameter as a value. There is one dict in the array for each - simulation sweep point.""" - - ## Preamble part of header - f = open(post2file) - l = f.readline() # 1st line contains string w/ # of variables - nauto = int(l[0:4]) - nprobe = int(l[4:8]) - nsweepparam = int(l[8:12]) - l = f.readline() # 2nd and 3rd lines are copyright and stuff - l = f.readline() - ndataset = int(l.split()[-1]) # 3rd line ends with the number of data sets - - ## Number and name part of header - l = f.readline() # 4th line+ useful, but may be wrapped - while l.find('$&%#') == -1: - l = l + f.readline() - l = l.replace('\n', '') - simparams = l.split()[:-1] # Throw away terminator string - datatypes = simparams[0:nauto + nprobe] # NOTUSED - varnames = simparams[nauto + nprobe:2 * (nauto + nprobe)] - paramnames = simparams[2 * (nauto + nprobe):] - - # Transform varnames and paramnames for Matlab - varnames = [x.partition('(')[0] if x.startswith('x') else x for x in varnames] - varnames = [x.replace('(', '_') for x in varnames] - varnames = [x.replace('.', '_') for x in varnames] - varnames = [x.replace(':', '_') for x in varnames] - paramnames = [x.replace(':', '_') for x in paramnames] - paramnames = ['param_' + x for x in paramnames] - - # Read data block - all_sweep_results = [] - l = f.readline().strip() - while l: - # Set up data storage structure - this_sweep_result = {} - for name in varnames: - this_sweep_result[name] = [] - for name in paramnames: - this_sweep_result[name] = 0 - - ## Data block for one sweep - numbers = [] - fieldwidth = l.find('E') + 4 - while True: - lastrow = l.find('0.1000000E+31') != -1 - while l: - numbers.append(float(l[0:fieldwidth])) - l = l[fieldwidth:] - if lastrow: - break - else: - l = f.readline().strip() - numbers = numbers[:-1] # throw away terminator - params = numbers[:nsweepparam] - for index in range(len(varnames)): - this_sweep_result[varnames[index]] = numbers[nsweepparam + index::nauto + nprobe] - this_sweep_result.update(zip(paramnames, [[x] for x in params])) - all_sweep_results.append(this_sweep_result) - l = f.readline().strip() - - f.close() - return reformat(all_sweep_results) - -def signal_array_to_matlab_string(signal_array, accum=True): # Todo: This should be obsolete now! - """ Takes in a signal array produced by signal_file_read and returns a string that - is suitable for inclusion in a .m file to be loaded into matlab. Makes 2D arrays - for DC and AC sims. 1D arrays numbered by sweep for transients b/c length uneven. - """ - matlab_string = '' - if accum: - # first, slice across the signal array to gather like signals into 2D arrays - signal_accumulation = signal_array[0] - for name, signal in signal_accumulation.items(): - signal_accumulation[name] = ['%.5e' % x for x in signal] - for simulation_result in signal_array[1:]: - for name, signal in simulation_result.items(): - signal_accumulation[name].extend([';'] + ['%.5e' % x for x in signal]) - # Second write out to a .m file string - for name, signal in signal_accumulation.items(): - matlab_string = matlab_string + name + '= [' + ' '.join(signal) + '];\n' - else: - # some cases, esp transient sims, can't be accumulated b/c different sizes - matlab_string = '' - signal_accumulation = signal_array[0] - for name, signal in signal_accumulation.items(): - signal_accumulation[name] = [['%.5e' % x for x in signal]] - for simulation_result in signal_array[1:]: - for name, signal in simulation_result.items(): - signal_accumulation[name].append(['%.5e' % x for x in signal]) - for name, signal_list in signal_accumulation.items(): - matlab_string = matlab_string + name + '={' - for signal in signal_list: - matlab_string = matlab_string + '[ ' + ' '.join(signal) + '];\n' - matlab_string = matlab_string + '};' - return matlab_string - -def measure_file_read(measure_file): - """Reads a measure file and resturns a dict keyed on the names of the columns - with values that are a list of results""" - f = open(measure_file) - l = f.readline().strip() # 1st line auto generated - param_count = int(l.split('PARAM_COUNT=')[-1].strip()) - l = f.readline().strip() # 2nd line is the comment - l = f.readline().strip() # 3rd line starts var names, last is alter# - while (l.find('alter#') == -1): - l = l + ' ' + f.readline().strip() - l = l.replace('#', '') - varnames = l.split() - varnum = len(varnames) - measure_result = {name: [] for name in varnames} - l = f.readline().strip() # 4th line starts data clumps to EOF - - while l: - vals = l.split() - if len(vals) != varnum: # accumulate results over multiple lines - l = l + ' ' + f.readline().strip() - else: # then write to measure dict - for name, val in zip(varnames, vals): - if val == 'failed': # skip over failed measures - val = 0 # silent failures are the best kind! - measure_result[name].append([float(val)]) # todo that I added [] to make the lists 2D not sure if necessary - l = f.readline().strip() - f.close() - return measure_result - -def measure_result_to_matlab_string(measure_result): # this should be obsolete now - matlab_string = '' - for name, signal in measure_result.items(): - matlab_string = matlab_string + name + '= [' + ' '.join(['%.5e' % x for x in signal]) + '];\n' - return matlab_string -# end of Spencer's (lightly modified) code - -def is_binary(file_path): - with open(file_path) as file: - try: - file.readline() - return False # this means that it is ascii - except UnicodeDecodeError: - return True # this means that it is binary - -def import_export(path, ext): - if is_binary(path): - from_ext = get_from_ext(path) - import_export_binary(path, ext, from_ext) - else: - import_export_ascii(path, ext) - -if __name__ == '__main__': - import sys - try: - if sys.argv[1] == '-h' or sys.argv[1] == '--help' or sys.argv[1] == '-help': - usage() - else: - path = sys.argv[1] - extension = sys.argv[2] - if extension == 'mat': - try: - import scipy.io as sio - import numpy as np - except ImportError: - print("To use Matlab's .mat extension, you must have Scipy and Numpy installed on your machine. See https://www.scipy.org/install.html and https://numpy.org/install for details.") - exit(1) - import_export(path, extension) - except: - usage() - resp_str = '\n\n This command needs the path to the file for import and the extension of the file being output.\n The extension can be either m, csv, or pickle. No other extensions are supported with this file at this time. If you are seeing this message, then something went wrong.' - print(resp_str) diff --git a/modules/module_0_foundations/gmid_repo/mosplot/parsers/ngspice_parser.py b/modules/module_0_foundations/gmid_repo/mosplot/parsers/ngspice_parser.py deleted file mode 100644 index a285e037..00000000 --- a/modules/module_0_foundations/gmid_repo/mosplot/parsers/ngspice_parser.py +++ /dev/null @@ -1,63 +0,0 @@ -import numpy as np - -class NgspiceRawFileReader: - def __init__(self): - self.bsize_sp = 512 - self.mdata_list = [ - b"title", - b"date", - b"plotname", - b"flags", - b"no. variables", - b"no. points", - b"dimensions", - b"command", - b"option", - ] - - def read_file(self, fname): - """Read ngspice binary raw files. Return tuple of the data, and the - plot metadata. The dtype of the data contains field names. This is - not very robust yet, and only supports ngspice. - >>> darr, mdata = rawread('test.py') - >>> darr.dtype.names - >>> plot(np.real(darr['frequency']), np.abs(darr['v(out)'])) - """ - with open(fname, "rb") as fp: - plot = {} - arrs = [] - plots = [] - while True: - mdata = fp.readline(self.bsize_sp).split(b":", maxsplit=1) - if len(mdata) == 2: - key = mdata[0].lower() - if key in self.mdata_list: - plot[key] = mdata[1].strip() - elif key == b"variables": - nvars = int(plot[b"no. variables"]) - npoints = int(plot[b"no. points"]) - varspecs = [ - fp.readline(self.bsize_sp).strip().decode("ascii").split() - for _ in range(nvars) - ] - plot["varnames"], plot["varunits"] = zip( - *[(spec[1], spec[2]) for spec in varspecs] - ) - elif key == b"binary": - rowdtype = np.dtype( - { - "names": plot["varnames"], - "formats": [ - np.complex_ - if b"complex" in plot[b"flags"] - else np.float_ - ] - * nvars, - } - ) - arrs.append(np.fromfile(fp, dtype=rowdtype, count=npoints)) - plots.append(plot.copy()) - fp.readline() # Read to the end of line - else: - break - return (arrs, plots) diff --git a/modules/module_0_foundations/gmid_repo/mosplot/src/__pycache__/lookup_table_generator.cpython-310.pyc b/modules/module_0_foundations/gmid_repo/mosplot/src/__pycache__/lookup_table_generator.cpython-310.pyc deleted file mode 100644 index ae9e0e2c2cdad1af5c33449c108460aa1152ba96..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11993 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 W3z+LJPD*S2L+!&WZz8ql?EeM*nC}Jv diff --git a/modules/module_0_foundations/gmid_repo/mosplot/src/__pycache__/main.cpython-310.pyc b/modules/module_0_foundations/gmid_repo/mosplot/src/__pycache__/main.cpython-310.pyc deleted file mode 100644 index b0996d4aaa2e896e202db997f37df49cd605bb0f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19043 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 O9GlN02)GivufLx_<8!&6mklc8= zyPg@!)`A3DNI=rZKK7}0-~1E$ANmXSwLk$qwLsB_x+vQ3%q}TXk_7}MG1ook%$aka zXl7>0!0(^G|7-ioMZ@?DEyjNq79XL>b#%;NW?*!UM}}!Iixm!yM<%nGgVAC|R>D|d zWmdsxv#A}UHhlyvqh_Xd>^Gk@OTw!aZvjgJ zYe{1{2M}Ao(6{@gRsq6U-mcln!ktKjT)2V%*j4+Gk{2X%V|y)6s)-F5M9)(D?sH!y zZ$AjQC%N0~L=gtn!E{9JmYaMx|IR~&6FissvMKyn`B8YwO-o^0;yf-$E6LT*qn_LG z_B1ugLwAgaoUaM>kzEu>b!h*%gzh&G{TC&u&*+8pwQj_E0hjsM zSZ}nVUdTMUkX&nbeTFYG4kEQCMRTp|g}ny4dc2=jHrqVp&ttJwC5FlHtY0q~$vcdX zWYXyJuvgyZB-~(okw_zcapnqy>8U9D$Nj-zZJtkZ6iS z`H0GBre#L_iy3qaG?_&=#>W_ct=8E77=NwS5$P^Dk3X`p|C>KDigWmr@@)R3JR-Y# zy?j!BDsnljzE(^fKa6`y&^1yg7JjJGf*0Ayt1 z^`=?ToU()qv?kizpe|{s3WeByK|_6zLm}*HTAP6Se#KBGn*x;Gw_jK<4GsBI zf=r4Efec@q&x~-^Hk7^pg$bWWKz7(Pg}cv<(0pb*-O@A=Y$5!b|f2iueqOV7R#dZhm-)6gv`{S#!1@ie->}ZLTE0xF5o> zedcPjcUzI@daCYD1a}xI=Wf{RK1L9AC67JfDbC!-`$!4ht|#5=yxy*_xa%wK2KxH? zMy*~e3#5Gb5Zs-M)KR@S;Ax@j#i`Q@B2T3bqN%Uasa=ZMcZGkfWHMxye+UtA?f{-vN>&ObZTCg@agdjVk`uf34Ta75R+w*bmz$BJeT(!{p{& zoy2x`e(YYC$`fkEl`4v<=W)%A1Z7X|UL)7P<|0-+?fL4KtA&^rDP3|VE`Wm(rJwA4 zD@r50kH00}hZ*P3e5N|Cj!;8gY^?Lun{Vbl`O#4E8Lk%c3B7wn5vGx8ev)uK`DJ!= zz{9rczy!1@td6W>#m#KugLN?S!xi_Y9&0Pd()4;Nx<(e~(rlG-DC{b$A8gu6E@ww* zmE^Z0@cc*=Ajw1RVUepob#v!^Ugu!E%%hOQBovhm6TT6RBMz6<~MM* zZ;VA_+4!CH6s~q0s9#xv>e|%wQGZlMlwr_hI~kmg@qb|yo>K*mAXm)5|nVh zMAJMk8sZA($>xx&q0-N?niF;~j2rb@B`p9?M+I>e5T79-9KEizBFe(8HXm`-$ zpV8$nB;*!tDU|r>Rb=TTUO>LNj8v)f2yA`TKckT^$?(GT^LGr!RPaOp_l<-|d8(pd)*z3akRN**0!wylmr&ZbB z_(3DsYtSlLyb;!)cQ@+c_^z0vBTvy8vS`N>bZB*&4(*EhGwBR(m~qlMlaqWm%UEY~ z0vU}coWTPq(C!ggsi3z)t)MGr?Z`SUqLMD}Mdm?U;B}mEuRRi_+= start) & (data <= end))[0] - if len(target) == 3: # if it contains a step - step = int(target[2] / (data[1] - data[0])) - indices = indices[::step] - # lengths must be handled separately since they are provided as list of values - elif var == "lengths" and isinstance(target, (list, np.ndarray)): - # filter by lengths - mask = np.isin(self.lookup_table["lengths"], np.array(target)) - indices = np.nonzero(mask)[0] - indices = np.array(indices, dtype=int) - else: - # by eliminating all float variables, we will be left with one variable - # that is not a float, and that will be the secondary variable - variables[var] = True - index = (np.abs(data - target)).argmin() - return np.array([index]), data[index] - - return indices, data[indices] - - secondary_idx = None - variables = {"lengths": False, "vsb": False, "vgs": False, "vds": False} - if primary: - variables[primary] = True - - indices_and_values = { - "lengths": get_indices("lengths", lengths) if lengths is not None else (slice(None), lookup_table["lengths"]), - "vsb": get_indices("vsb", vsb) if vsb is not None else (slice(None), lookup_table["vsb"]), - "vgs": get_indices("vgs", vgs) if vgs is not None else (slice(None), lookup_table["vgs"]), - "vds": get_indices("vds", vds) if vds is not None else (slice(None), lookup_table["vds"]), - } - - slice_indices = [] - filter_values = [] - for idx, item in enumerate(variables.keys()): - slice_indices.append(indices_and_values[item][0]) - filter_values.append(indices_and_values[item][1]) - slice_indices = tuple(slice_indices) - - def slice_me(a, slices): - x = a[slices[0], :, :, :] - x = x[:, slices[1], :, :] - x = x[:, :, slices[2], :] - x = x[:, :, :, slices[3]] - return x - - # extract the data based on the indices - extracted_table = {} - if not parameters: - parameters = lookup_table["parameter_names"] - - for p in parameters: - if p in lookup_table: - x = np.squeeze(slice_me(lookup_table[p], slice_indices)) - if x.ndim > 1 and x.shape[0] > x.shape[1]: - extracted_table[p] = x.T - else: - extracted_table[p] = x - - one_key = next(iter(extracted_table)) - extracted_table["width"] = np.array(self.width) - extracted_table["lengths"], _ = tile_arrays(filter_values[0], extracted_table[one_key]) - extracted_table["vsb"], _ = tile_arrays(filter_values[1], extracted_table[one_key]) - extracted_table["vgs"], _ = tile_arrays(filter_values[2], extracted_table[one_key]) - extracted_table["vds"], _ = tile_arrays(filter_values[3], extracted_table[one_key]) - - if primary and secondary_idx: - secondary_idx = list(variables.values()).index(False) - - return secondary_idx, filter_values, extracted_table - - ################################################################################ - # Plotting Methods # - ################################################################################ - def __generate_plot_labels(self): - variables_labels = ["lengths", "vsb", "vgs", "vds"] - model_name = self.lookup_table[self.mos]["model_name"] - title_label = [] - - for i, v in enumerate(self.filtered_variables): - if not isinstance(v, np.ndarray): - label = variables_labels[i] - title_label.append(f"V_{{ \\mathrm{{ { (label[1:]).upper() } }} }}") - title_label.append(v) - - self.plot_labels = {} - self.plot_labels["title"] = f"{model_name}, " + "$%s=%.2f$, $%s=%.2f$" % tuple(title_label) - - legend_formatter = EngFormatter(unit="m") - self.plot_labels["lengths"] = [legend_formatter.format_eng(sw) for sw in self.lengths] - - def __plot_settings( - self, - y: np.ndarray, - x_limit: tuple = (), - y_limit: tuple = (), - x_scale: str = "", - y_scale: str = "", - x_eng_format: bool = False, - y_eng_format: bool = False, - x_label: str = "", - y_label: str = "", - title: str = "", - save_fig: str = "", - ): - fig, ax = plt.subplots(1, 1, figsize=FIG_SIZE, tight_layout=True) - fig.canvas.mpl_connect( - "button_press_event", - lambda event: on_canvas_click(event, fig, ax), - ) - fig.canvas.mpl_connect( - "key_press_event", - lambda event: clear_annotations_and_dots(fig) if event.key == "d" else None, - ) - - ax.set_title(title) - ax.grid(True, which="both", ls="--", color=GRID_COLOR) - ax.set_xlabel(x_label) - ax.set_ylabel(y_label) - - if x_limit: - ax.set_xlim(*x_limit) - - if y_limit: - ax.set_ylim(*y_limit) - - if x_scale: - ax.set_xscale(x_scale) - - if y_scale: - ax.set_yscale(y_scale) - else: - # TODO: this might not always give expected result - if np.max(y) / np.min(y) > 1000: - ax.set_yscale("log") - - # set engineering format if specified - if y_eng_format: - ax.yaxis.set_major_formatter(EngFormatter(unit="")) - if x_eng_format: - ax.xaxis.set_major_formatter(EngFormatter(unit="")) - - return fig, ax - - def __plot(self, x, y, fig, ax, legend, save_fig): - if isinstance(x, np.ndarray) and isinstance(y, np.ndarray) and x.ndim == y.ndim: - ax.plot(x.T, y.T, lw=LINE_WIDTH, picker=True) - - elif isinstance(x, (list, tuple)) and isinstance(y, (list, tuple)): - for x_, y_ in zip(x, y): - if x_.ndim == 1 and x_.shape[0] != y_.shape[0]: - ax.plot(x_, y_.T, lw=LINE_WIDTH, picker=True) - else: - ax.plot(x_, y_, lw=LINE_WIDTH, picker=True) - - elif x.ndim == 1: - if x.shape[0] != y.shape[0]: - ax.plot(x, y.T, lw=LINE_WIDTH, picker=True) - else: - ax.plot(x, y, lw=LINE_WIDTH, picker=True) - - elif y.ndim == 1: - if y.shape[0] != x.shape[0]: - ax.plot(x.T, y, lw=LINE_WIDTH, picker=True) - else: - ax.plot(x, y, lw=LINE_WIDTH, picker=True) - - - if legend: - ax.legend(legend, loc="center left", bbox_to_anchor=(1, 0.5)) - - if save_fig: - ax.figure.savefig(save_fig, bbox_inches="tight") - - def plot_by_expression( - self, - *, - x_expression: dict, - y_expression: dict, - lengths: tuple = (), - x_limit: tuple = (), - y_limit: tuple = (), - x_scale: str = "", - y_scale: str = "", - x_eng_format: bool = False, - y_eng_format: bool = False, - title: str = None, - save_fig: str = "", - return_result: bool = False, - ): - extracted_table = self.extracted_table - - # plot labels - self.__generate_plot_labels() - if title is not None: - self.plot_labels["title"] = title - - # filter by lengths - mask = np.isin(self.lengths, np.array(lengths)) - indices = np.nonzero(mask)[0] - length_indices = np.array(indices, dtype=int) - - if length_indices.size > 0: - legend = [self.plot_labels["lengths"][i] for i in length_indices] - else: - legend = self.plot_labels["lengths"] - - x, x_label = self.__calculate_from_expression(x_expression, extracted_table, length_indices) - y, y_label = self.__calculate_from_expression(y_expression, extracted_table, length_indices) - - fig, ax = self.__plot_settings( - y, - x_limit, - y_limit, - x_scale, - y_scale, - x_eng_format, - y_eng_format, - x_label, - y_label, - self.plot_labels["title"], - save_fig, - ) - - self.__plot(x, y, fig, ax, legend, save_fig) - - if return_result: - return x, y - - def plot_by_sweep( - self, - *, - lengths, - vsb, - vgs, - vds, - primary, - x_expression, - y_expression, - title: str = "", - x_limit: tuple = (), - y_limit: tuple = (), - x_scale: str = "", - y_scale: str = "", - x_eng_format: bool = False, - y_eng_format: bool = False, - save_fig: str = "", - return_result: bool = False, - ): - secondary_variable_idx, filtered_variables, extracted_table = self.extract_2d_table( - lookup_table=self.lookup_table[self.mos], lengths=lengths, vsb=vsb, vgs=vgs, vds=vds, primary=primary - ) - - x, x_label = self.__calculate_from_expression(x_expression, extracted_table) - y, y_label = self.__calculate_from_expression(y_expression, extracted_table) - - fig, ax = self.__plot_settings( - y, - x_limit, - y_limit, - x_scale, - y_scale, - x_eng_format, - y_eng_format, - x_label, - y_label, - title, - save_fig, - ) - - if secondary_variable_idx: - legend_formatter = EngFormatter(unit="") - legend = [legend_formatter.format_eng(sw) for sw in filtered_variables[secondary_variable_idx]] - else: - legend = None - - self.__plot(x, y, fig, ax, legend, save_fig) - - if return_result: - return x, y - - def quick_plot( - self, - x: np.ndarray | list | tuple, - y: np.ndarray | list | tuple, - *, - x_label: str = "", - y_label: str = "", - x_limit: tuple = (), - y_limit: tuple = (), - x_scale: str = "", - y_scale: str = "", - x_eng_format: bool = False, - y_eng_format: bool = False, - legend: list = [], - title: str = None, - save_fig: str = "", - ): - """ - Make quick plots. As a reminder, when `x` and `y` are of size m x n, pass - them to this function as x.T and y.T - """ - fig, ax = self.__plot_settings( - y, - x_limit, - y_limit, - x_scale, - y_scale, - x_eng_format, - y_eng_format, - x_label, - y_label, - title, - save_fig, - ) - - self.__plot(x, y, fig, ax, legend, save_fig) - - # }}} - - ################################################################################ - # Expression Handling # - ################################################################################ - def __calculate_from_expression( - self, - expression: dict, - table: dict, - filter_by_rows: np.ndarray = np.array([]), - ): - if isinstance(expression, dict): - var_list = [] - for v in expression["variables"]: - var = table[v] - if filter_by_rows.size > 0 and var.ndim > 1: - var_list.append((np.take(var, filter_by_rows, 0))) - else: - var_list.append(var) - - if "function" in expression: - values = expression["function"](*var_list) - else: - values = var_list[0] - - try: - return values, expression["label"] - except KeyError: - return values, "" - else: - return expression, None - - def __common_expressions(self): - # create attributes for parameters from the lookup table - LABEL_TABLE = { - "lengths": ["\\mathrm{Length}", "m"], - "vsb": ["V_{\\mathrm{SB}}", "V"], - "vgs": ["V_{\\mathrm{GS}}", "V"], - "vds": ["V_{\\mathrm{DS}}", "V"], - "id": ["I_{D}", "A"], - "vth": ["V_{\\mathrm{TH}}", "V"], - "vdsat": ["V_{\\mathrm{DS_{\\mathrm{SAT}}}}", "V"], - "gm": ["g_{m}", "S"], - "gmbs": ["g_{\\mathrm{mbs}}", "S"], - "gds": ["g_{\\mathrm{ds}}", "S"], - "cgg": ["c_{\\mathrm{gg}}", "F"], - "cgs": ["c_{\\mathrm{gs}}", "F"], - "cbg": ["c_{\\mathrm{bg}}", "F"], - "cgd": ["c_{\\mathrm{gd}}", "F"], - "cdd": ["c_{\\mathrm{dd}}", "F"], - } - for parameter, (label, unit) in LABEL_TABLE.items(): - if parameter in self.parameters or parameter in ["lengths", "vsb", "vgs", "vds"]: - setattr( - self, - f"{parameter}_expression", - {"variables": [parameter], "label": f"${label}\ ({unit})$"}, - ) - - self.gmid_expression = { - "variables": ["gm", "id"], - "function": lambda x, y: x / y, - "label": "$g_m/I_D (S/A)$", - } - self.vstar_expression = { - "variables": ["gm", "id"], - "function": lambda x, y: (2 * y) / x, - "label": "$V^{\\star} (V)$", - } - self.gain_expression = { - "variables": ["gm", "gds"], - "function": lambda x, y: x / y, - "label": "$g_{m}/g_{\\mathrm{ds}}$", - } - self.current_density_expression = { - "variables": ["id", "width"], - "function": lambda x, y: x / y, - "label": "$I_{D}/W (A/m)$", - } - self.transist_frequency_expression = { - "variables": ["gm", "cgg"], - "function": lambda x, y: x / (2 * np.pi * y), - "label": "$f_{T} (\\mathrm{Hz})$", - } - self.early_voltage_expression = { - "variables": ["id", "gds"], - "function": lambda x, y: x / y, - "label": "$V_{A} (V)$", - } - self.rds_expression = { - "variables": ["gds"], - "function": lambda x: 1 / x, - "label": "$r_{\\mathrm{ds}} (\\Omega)$", - } - - def __common_plot_methods(self): - PLOT_METHODS = { - "current_density_plot": [self.gmid_expression, self.current_density_expression], - "gain_plot": [self.gmid_expression, self.gain_expression], - "transit_frequency_plot": [self.gmid_expression, self.transist_frequency_expression], - "early_voltage_plot": [self.gmid_expression, self.early_voltage_expression], - } - - # This is not ideal since I need to keep track of the signature of `plot_by_expression`. - # I can use `partial` from `functools` here, but it doesn't hide the bound variables, which I don't like. - def create_plot_method(self, x_expression, y_expression): - def plot_method( - self, - lengths: tuple = (), - x_limit: tuple = (), - y_limit: tuple = (), - x_scale: str = "", - y_scale: str = "", - x_eng_format: bool = False, - y_eng_format: bool = False, - title: str = None, - save_fig: str = "", - return_result: bool = False, - ): - return self.plot_by_expression( - x_expression=x_expression, - y_expression=y_expression, - lengths=lengths, - x_scale=x_scale, - y_scale=y_scale, - x_limit=x_limit, - y_limit=y_limit, - x_eng_format=x_eng_format, - y_eng_format=y_eng_format, - title=title, - save_fig=save_fig, - return_result=return_result, - ) - - return plot_method - - for method_name, (x, y) in PLOT_METHODS.items(): - setattr(LoadMosfet, method_name, create_plot_method(self, x_expression=x, y_expression=y)) - - ################################################################################ - # Lookup Methods # - ################################################################################ - def interpolate(self, *, x_expression, x_value, y_expression, y_value, z_expression): - """ - Given (1) a value from x_expression, - (2) a value from y_expression, - find value of z_expression using interpolation. - - Args: - x_expression (dict): expression of how to calculate the points on the x-axis - x_value (float, dict): value(s) inside the domain of x_expression - y_expression (dict): expression of how to calculate the points on the y-axis - y_value (float, dict): value(s) inside the domain of y_expression - z_expression (dict): expression of how to calculate the value you're looking for - - Returns: - value of expression you're looking for - - Example: - x = nmos.interpolate( - x_expression=nmos.vgs_expression, - x_value=0.65, - y_expression=nmos.gmid_expression, - y_value=15, - z_expression=nmos.lengths_expression, - ) - """ - x_array, _ = self.__calculate_from_expression(x_expression, self.extracted_table) - y_aray, _ = self.__calculate_from_expression(y_expression, self.extracted_table) - z_array, _ = self.__calculate_from_expression(z_expression, self.extracted_table) - - points = np.column_stack((x_array.ravel(), y_aray.ravel())) - - if isinstance(x_value, (tuple, np.ndarray)) and isinstance(y_value, (int, float)): - if isinstance(x_value, tuple): - x = np.arange(*x_value) - else: - x = x_value - evaluate_at = np.column_stack((x, np.full(x.shape, y_value))) - elif isinstance(y_value, (tuple, np.ndarray)) and isinstance(x_value, (int, float)): - if isinstance(y_value, tuple): - y = np.arange(*y_value) - else: - y = y_value - evaluate_at = np.column_stack((np.full(y.shape, x_value), y)) - elif isinstance(x_value, tuple) and isinstance(y_value, tuple): - x = np.arange(*x_value) - y = np.arange(*y_value) - X, Y = np.meshgrid(x, y) - evaluate_at = np.dstack((X, Y)).transpose(1, 0, 2) - else: - evaluate_at = np.array([x_value, y_value]) - - z_value = griddata(points, z_array.ravel(), evaluate_at, method='cubic', rescale=True) - return z_value - - - def lookup_expression_from_table(self, *, lengths, vsb, vgs, vds, primary, expression): - """ - Calculate a parameter using the entire table. - No interpolation is used. - - Args: - lengths (float, list, ndarray): length(s) of the mosfet - vsb (float, tuple): source-body voltage, tuple of the form (start, stop, step) - vgs (float, tuple): gate-source voltage, tuple of the form (start, stop, step) - vds (float, tuple): drain-source voltage, tuple of the form (start, stop, step) - primary (str): name of the primary sweep source: "lengths", "vsb", "vgs", or "vds" - expression(dict): expression of how to calculate the value you're looking for - - Example: - x = nmos.lookup_expression_from_table( - lengths=100e-9, - vsb=0, - vds=(0.0, 1, 0.01), - vgs=(0.0, 1.01, 0.2), - primary="vds", - expression=nmos.current_density_expression, - ) - """ - parameters = expression["variables"].copy() - remove_from_parameters = ["width", "length"] - for item in remove_from_parameters: - if item in parameters: - parameters.remove(item) - _, _, extracted_table = self.extract_2d_table(lookup_table=self.lookup_table[self.mos], parameters=parameters, lengths=lengths, vsb=vsb, vgs=vgs, vds=vds, primary=primary) - x, _ = self.__calculate_from_expression(expression, extracted_table) - return x diff --git a/modules/module_0_foundations/gmid_repo/mosplot/src/manu_man.py b/modules/module_0_foundations/gmid_repo/mosplot/src/manu_man.py deleted file mode 100644 index 8e23d954..00000000 --- a/modules/module_0_foundations/gmid_repo/mosplot/src/manu_man.py +++ /dev/null @@ -1,140 +0,0 @@ -from pick import pick - -def description_menu(model): - Options_1 = ["Corner lib typical", "Corner lib fast", "Corner lib slow", "Exit"] - title_1 = "Please choose the corner lib: " - discription = input("Please enter a discription: ") - simulator = "ngspice" - _, index = pick(Options_1, title_1) - if index == 0: - print("You have chosen Corner lib typical") - print(model) - if any('lv' in value for value in model.values()): - model_path = ["cornerMOSlv.lib mos_tt",] - else: - model_path = ["cornerMOShv.lib mos_tt",] - elif index == 1: - print("You have chosen Corner lib fast") - if any('lv' in value for value in model.values()): - model_path = ["cornerMOSlv.lib mos_ff",] - else: - model_path = ["cornerMOShv.lib mos_ff",] - elif index == 2: - print("You have chosen Corner lib slow") - if any('lv' in value for value in model.values()): - model_path = ["cornerMOSlv.lib mos_ss",] - else: - model_path = ["cornerMOShv.lib mos_ss",] - elif index == 3: - print("You have chosen to exit") - exit() - - return discription, simulator, model_path - -def sweeping_menu(): - def get_floats(prompt): - while True: - user_input = input(prompt) - if user_input.lower() == 'exit': - return 'exit' - try: - return tuple(map(float, user_input.split(','))) - except ValueError: - print("Invalid input format. Please enter three numbers separated by commas (e.g., 0, 1, 0.01).") - - # Prompt for VSB - while True: - vsb = get_floats("Enter VSB (start, stop, step) or type 'exit' to quit: ") - if vsb == 'exit': - return 'Exited' - elif len(vsb) == 3: - break - - # Prompt for VGS - while True: - vgs = get_floats("Enter VGS (start, stop, step) or type 'exit' to quit: ") - if vgs == 'exit': - return 'Exited' - elif len(vgs) == 3: - break - - # Prompt for VDS - while True: - vds = get_floats("Enter VDS (start, stop, step) or type 'exit' to quit: ") - if vds == 'exit': - return 'Exited' - elif len(vds) == 3: - break - - # Prompt for width - while True: - width_input = input("Enter width value (e.g., 10e-6) or type 'exit' to quit: ") - if width_input.lower() == 'exit': - return 'Exited' - try: - width = float(width_input) - break - except ValueError: - print("Invalid width input. Please enter a valid number (e.g., 10e-6).") - - # Prompt for lengths or auto-generate - while True: - lengths_input = input("Enter lengths (comma-separated, e.g., 500e-9, 600e-9), or type 'auto' for auto-generation: ") - if lengths_input.lower() == 'exit': - return 'Exited' - elif lengths_input.lower() == 'auto': - try: - start = float(input("Enter start value for lengths: ")) - increment = float(input("Enter increment value: ")) - count = int(input("Enter number of increments: ")) - lengths = [start + i * increment for i in range(count)] - break - except ValueError: - print("Invalid input for auto-generation. Try again.") - else: - try: - lengths = [float(i) for i in lengths_input.split(',')] - break - except ValueError: - print("Invalid lengths input. Please enter comma-separated numbers.") - - return vsb, vgs, vds, width, lengths - - - - -def input_selection(): - # Simply return "ihp_open_pdk" without asking for input - return "ihp_open_pdk" - - - -def transistor_menu(): - Options = ["NMOS_LV", "PMOS_LV", "NMOS_HV", "PMOS_HV", "Exit"] - title = "Please choose the transistor model: " - option, index = pick(Options, title) - - if index == 0: - print("You have chosen NMOS_LV") - model = {"nmos": "sg13_lv_nmos"} - simulation_description = "*n.xm1.nsg13_lv_nmos" - return model, simulation_description - elif index == 1: - print("You have chosen PMOS_LV") - model = {"pmos": "sg13_lv_pmos"} - simulation_description = "*n.xm1.nsg13_lv_pmos" - return model, simulation_description - elif index == 2: - print("You have chosen NMOS_HV") - model = {"nmos": "sg13_hv_nmos"} - simulation_description = "*n.xm1.nsg13_hv_nmos" - return model, simulation_description - elif index == 3: - print("You have chosen PMOS_HV") - model = {"pmos": "sg13_hv_pmos"} - simulation_description = "*n.xm1.nsg13_hv_pmos" - return model, simulation_description - elif index == 4: - print("You have chosen to exit") - exit() - return model, simulation_description diff --git a/modules/module_0_foundations/gmid_repo/setup.py b/modules/module_0_foundations/gmid_repo/setup.py deleted file mode 100644 index 9f5bbf2b..00000000 --- a/modules/module_0_foundations/gmid_repo/setup.py +++ /dev/null @@ -1,14 +0,0 @@ -from setuptools import setup - -setup( - name='mosplot', - version='0.1.0', - description='A python tool for making plots of mosfet parameters.', - author='Mohamed Watfa', - author_email='medwatt@hotmail.com', - install_requires=[ - 'numpy', - 'matplotlib', - 'scipy' - ], -) diff --git a/modules/module_0_foundations/scripting/gmid_test.ipynb b/modules/module_0_foundations/scripting/gmid_test.ipynb index b6103dc5..0447ad1d 100644 --- a/modules/module_0_foundations/scripting/gmid_test.ipynb +++ b/modules/module_0_foundations/scripting/gmid_test.ipynb @@ -2,39 +2,14 @@ "cells": [ { "cell_type": "code", - "execution_count": 8, - "id": "fe26dc38-6623-48db-820a-cf131ac9a268", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Successfully imported from src.main!\n" - ] - } - ], - "source": [ - "import os\n", - "import sys\n", - "sys.path.append(os.path.abspath('../gmid_repo/mosplot/src'))\n", - "\n", - "try:\n", - " from main import load_lookup_table, LoadMosfet\n", - " print(\"Successfully imported from src.main!\")\n", - "except ImportError as e:\n", - " print(f\"Error importing directly from src.main: {e}\")" - ] - }, - { - "cell_type": "code", - "execution_count": 9, + "execution_count": 101, "id": "9f325daf-eb3b-4cf7-8ffe-b9b94e7f66ea", "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "import numpy as np\n", + "from mosplot.plot import load_lookup_table, Mosfet, Expression\n", "import ipywidgets as widgets\n", "from ipywidgets import interactive\n", "from ipywidgets import interactive_output, HBox, VBox\n", @@ -43,33 +18,52 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 102, "id": "b5b31aca-47bf-4461-8e50-16c20f03b337", "metadata": {}, "outputs": [], "source": [ - "nmos_lv_path = '../gmid_repo/LUTs/nmos_lv_lut_tt.npy'\n", - "pmos_lv_path = '../gmid_repo/LUTs/pmos_lv_lut_tt.npy'\n", - "\n", - "\n", - "lookup_table_nmos = load_lookup_table(nmos_lv_path)\n", - "lookup_table_pmos = load_lookup_table(pmos_lv_path)" + "lookup_table_nmos = load_lookup_table('../sg13_nmos_lv_LUT.npz')\n", + "lookup_table_pmos = load_lookup_table('../sg13_pmos_lv_LUT.npz')" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 103, + "id": "a03cd944-2432-457c-9b88-486ab781fde6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "dict_keys(['sg13_lv_nmos ', 'sg13_lv_pmos', 'description', 'simulator', 'parameter_names', 'device_parameters'])\n" + ] + } + ], + "source": [ + "print(lookup_table.keys())" + ] + }, + { + "cell_type": "code", + "execution_count": 108, "id": "743dc381-0d35-4aa9-847c-c42c80c17786", "metadata": {}, "outputs": [], "source": [ - "nmos = LoadMosfet(lookup_table=lookup_table_nmos, mos=\"nmos\", vsb=0.0, vds=0.6)\n", - "pmos = LoadMosfet(lookup_table=lookup_table_pmos, mos=\"pmos\", vsb=0.0, vds=-0.6, vgs=(-1.2, -0.15))\n" + "nmos = Mosfet(lookup_table=lookup_table_nmos, mos=\"sg13_lv_nmos \", vbs=0.0, vds=0.6)\n", + "pmos = Mosfet(lookup_table=lookup_table_pmos, mos=\"sg13_lv_pmos\", vbs=0.0, vds=-0.6, vgs=(-1.2, -0.15))\n", + "\n", + "rows_0, cols_0 = np.shape(nmos.extracted_table['gm']) # just for getting the shape of the data\n", + "rows_1, cols_1 = np.shape(pmos.extracted_table['gm']) # just for getting the shape of the data\n", + "reshaped_lengths_nmos = np.tile(nmos.length[:, np.newaxis], (1, cols_0))\n", + "reshaped_lengths_pmos = np.tile(pmos.length[:, np.newaxis], (1, cols_1))" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 109, "id": "b27d5fca-3436-4df7-895f-f6a4bbd7a80d", "metadata": { "jupyter": { @@ -263,19 +257,19 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 110, "id": "b7cc630f-b385-47a6-a6f9-ac0d10effffe", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "29f64ef5153445daad7e300c3c91e7f1", + "model_id": "f4bd29dd4a254e499496ceb2f8444c8f", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "VBox(children=(Dropdown(description='Length:', layout=Layout(width='500px'), options=('Show All', '0.20 μm', '…" + "VBox(children=(Dropdown(description='Length:', layout=Layout(width='500px'), options=('Show All', '0.13 μm', '…" ] }, "metadata": {}, @@ -283,13 +277,13 @@ } ], "source": [ - "width_values = nmos.extracted_table['width']\n", + "width_values = nmos.width\n", "id_values = nmos.extracted_table['id']\n", "gm_values = nmos.extracted_table['gm']\n", "gds_values = nmos.extracted_table['gds']\n", "vgs_values= nmos.extracted_table['vgs']\n", "\n", - "plot_data_vs_data(gm_values/id_values, gm_values/gds_values, vgs_values, nmos.extracted_table['lengths'], 'gm/id', 'gm/gds')" + "plot_data_vs_data(gm_values/id_values, gm_values/gds_values, vgs_values, reshaped_lengths_nmos, 'gm/id', 'gm/gds')" ] }, { @@ -302,19 +296,19 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 111, "id": "3727c42d-a4bf-4eb0-bc11-6e859ae41324", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "9d62db56b7f240f9bd379086729554c4", + "model_id": "25e14d69e1084f71a4f21a94fe991a02", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "VBox(children=(Dropdown(description='Length:', layout=Layout(width='500px'), options=('Show All', '0.20 μm', '…" + "VBox(children=(Dropdown(description='Length:', layout=Layout(width='500px'), options=('Show All', '0.13 μm', '…" ] }, "metadata": {}, @@ -322,38 +316,14 @@ } ], "source": [ - "width_values = pmos.extracted_table['width']\n", + "width_values = pmos.width\n", "id_values = pmos.extracted_table['id']\n", "gm_values = pmos.extracted_table['gm']\n", "gds_values = pmos.extracted_table['gds']\n", "vgs_values= pmos.extracted_table['vgs']\n", "\n", - "plot_data_vs_data(gm_values/id_values, gm_values/gds_values, vgs_values, pmos.extracted_table['lengths'], 'gm/id', 'gm/gds')" + "plot_data_vs_data(gm_values/id_values, gm_values/gds_values, vgs_values, reshaped_lengths_pmos, 'gm/id', 'gm/gds')" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "efd31595-ac9a-4bcd-aa34-8ed796fb0eb6", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5707b58d-d36f-44c6-af55-238127aea52d", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fcc3617a-3c04-448c-a988-c30ea2603d7f", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/modules/module_0_foundations/sg13_nmos_lv.py b/modules/module_0_foundations/sg13_nmos_lv.py new file mode 100644 index 00000000..a6a32a21 --- /dev/null +++ b/modules/module_0_foundations/sg13_nmos_lv.py @@ -0,0 +1,58 @@ +from mosplot.lookup_table_generator.simulators import NgspiceSimulator, HspiceSimulator +from mosplot.lookup_table_generator import LookupTableGenerator, TransistorSweep +# One of `include_paths` or `lib_mappings` must be specified. +# The rest are optional. + +ngspice = NgspiceSimulator( + # Provide path to simulator if simulator is not in system path. + simulator_path="ngspice", + + # Default simulation temperature. Override if needed. + temperature=27, + + # All parameters are saved by default. Override if needed. + parameters_to_save=["id", "vth", "vdsat", "gm","gds","vgs"], + + + # Files to include with `.LIB`. + lib_mappings = [ + ("/home/pedersen/IHP-Open-PDK/ihp-sg13g2/libs.tech/ngspice/models/cornerMOSlv.lib", " mos_tt") + ], + + # If the transistor is defined inside a subcircuit in + # the library files, you must specify the symbol used (first entry) + # and the hierarchical name (second entry). Override if needed. + mos_spice_symbols = ("XM1", "n.xm1.nsg13_lv_nmos"), + + + + # Specify the width. For devices that do not take a width, + # you can specify other parameters such as the number of fingers. + # The keys are exactly those recognized by the model. + device_parameters = { + "w": 10e-6, + } +) + +nmos_sweep = TransistorSweep( + mos_type="nmos", + vgs=(0, 1.2, 0.01), + vds=(0, 1.2, 0.01), + vbs=(0, -1.2, -0.1), + length = [130e-9, 260e-9, 390e-9, 520e-9, 650e-9, 780e-9, 910e-9, 1040e-9, 1170e-9, 1300e-9, 1430e-9, 1560e-9, 1690e-9, 1820e-9, 1950e-9, 2080e-9, 2210e-9, 2340e-9, 2470e-9, 2600e-9, 2730e-9, 2860e-9, 2990e-9, 3120e-9, 3250e-9, 3380e-9, 3510e-9, 3640e-9, 3770e-9, 3900e-9, 4030e-9, 4160e-9, 4290e-9, 4420e-9, 4550e-9, 4680e-9, 4810e-9, 4940e-9, 5070e-9, 5200e-9, 5330e-9, 5460e-9, 5590e-9, 5720e-9, 5850e-9, 5980e-9, 6110e-9, 6240e-9, 6370e-9, 6500e-9, 6630e-9, 6760e-9, 6890e-9, 7020e-9, 7150e-9, 7280e-9, 7410e-9, 7540e-9, 7670e-9, 7800e-9, 7930e-9, 8060e-9, 8190e-9, 8320e-9, 8450e-9, 8580e-9, 8710e-9, 8840e-9, 8970e-9, 9100e-9, 9230e-9, 9360e-9, 9490e-9, 9620e-9, 9750e-9, 9880e-9] +) + + +obj = LookupTableGenerator( + description="sg13_nmos_lv", + simulator=ngspice, + model_sweeps={ + "sg13_lv_nmos ": nmos_sweep, + }, + n_process=2, +) + +# obj.op_simulation() +obj.build("./sg13_nmos_lv_LUT") + + diff --git a/modules/module_0_foundations/sg13_pmos_lv.py b/modules/module_0_foundations/sg13_pmos_lv.py new file mode 100644 index 00000000..6346516e --- /dev/null +++ b/modules/module_0_foundations/sg13_pmos_lv.py @@ -0,0 +1,58 @@ +from mosplot.lookup_table_generator.simulators import NgspiceSimulator, HspiceSimulator +from mosplot.lookup_table_generator import LookupTableGenerator, TransistorSweep +# One of `include_paths` or `lib_mappings` must be specified. +# The rest are optional. + +ngspice = NgspiceSimulator( + # Provide path to simulator if simulator is not in system path. + simulator_path="ngspice", + + # Default simulation temperature. Override if needed. + temperature=27, + + # All parameters are saved by default. Override if needed. + parameters_to_save=["id", "vth", "vdsat", "gm","gds","vgs"], + + + # Files to include with `.LIB`. + lib_mappings = [ + ("/home/pedersen/IHP-Open-PDK/ihp-sg13g2/libs.tech/ngspice/models/cornerMOSlv.lib", " mos_tt") + ], + + # If the transistor is defined inside a subcircuit in + # the library files, you must specify the symbol used (first entry) + # and the hierarchical name (second entry). Override if needed. + mos_spice_symbols = ("XM1", "n.xm1.nsg13_lv_pmos"), + + + + # Specify the width. For devices that do not take a width, + # you can specify other parameters such as the number of fingers. + # The keys are exactly those recognized by the model. + device_parameters = { + "w": 10e-6, + } +) + +# Define a sweep object for PMOS transistors. +pmos_sweep = TransistorSweep( + mos_type="pmos", + vgs=(0, -1.2, -0.01), + vds=(0, -1.2, -0.01), + vbs=(0, 1.2, 0.1), + length = [130e-9, 260e-9, 390e-9, 520e-9, 650e-9, 780e-9, 910e-9, 1040e-9, 1170e-9, 1300e-9, 1430e-9, 1560e-9, 1690e-9, 1820e-9, 1950e-9, 2080e-9, 2210e-9, 2340e-9, 2470e-9, 2600e-9, 2730e-9, 2860e-9, 2990e-9, 3120e-9, 3250e-9, 3380e-9, 3510e-9, 3640e-9, 3770e-9, 3900e-9, 4030e-9, 4160e-9, 4290e-9, 4420e-9, 4550e-9, 4680e-9, 4810e-9, 4940e-9, 5070e-9, 5200e-9, 5330e-9, 5460e-9, 5590e-9, 5720e-9, 5850e-9, 5980e-9, 6110e-9, 6240e-9, 6370e-9, 6500e-9, 6630e-9, 6760e-9, 6890e-9, 7020e-9, 7150e-9, 7280e-9, 7410e-9, 7540e-9, 7670e-9, 7800e-9, 7930e-9, 8060e-9, 8190e-9, 8320e-9, 8450e-9, 8580e-9, 8710e-9, 8840e-9, 8970e-9, 9100e-9, 9230e-9, 9360e-9, 9490e-9, 9620e-9, 9750e-9, 9880e-9] +) + +obj = LookupTableGenerator( + description="sg13_omos_lv", + simulator=ngspice, + model_sweeps={ + "sg13_lv_pmos" : pmos_sweep, + }, + n_process=2, +) + +# obj.op_simulation() +obj.build("./sg13_pmos_lv_LUT") + + diff --git a/modules/module_1_bandgap_reference/part_1_OTA/scripting/OTA_low_gain.ipynb b/modules/module_1_bandgap_reference/part_1_OTA/scripting/OTA_low_gain.ipynb index 1219acbf..58874e6b 100644 --- a/modules/module_1_bandgap_reference/part_1_OTA/scripting/OTA_low_gain.ipynb +++ b/modules/module_1_bandgap_reference/part_1_OTA/scripting/OTA_low_gain.ipynb @@ -2,37 +2,13 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Successfully imported from src.main!\n" - ] - } - ], - "source": [ - "import os\n", - "import sys\n", - "sys.path.append(os.path.abspath('../../../module_0_foundations/gmid_repo/mosplot/src'))\n", - "\n", - "try:\n", - " from main import load_lookup_table, LoadMosfet\n", - " print(\"Successfully imported from src.main!\")\n", - "except ImportError as e:\n", - " print(f\"Error importing directly from src.main: {e}\")" - ] - }, - { - "cell_type": "code", - "execution_count": 2, + "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "import numpy as np\n", + "from mosplot.plot import load_lookup_table, Mosfet, Expression\n", "import ipywidgets as widgets\n", "from ipywidgets import interactive\n", "from ipywidgets import interactive_output, HBox, VBox\n", @@ -41,31 +17,54 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ - "nmos_lv_path = '../../../module_0_foundations/gmid_repo/LUTs/nmos_lv_lut_tt.npy'\n", - "pmos_lv_path = '../../../module_0_foundations/gmid_repo/LUTs/pmos_lv_lut_tt.npy'\n", + "lookup_table_nmos = load_lookup_table('../../../module_0_foundations/sg13_nmos_lv_LUT.npz')\n", + "lookup_table_pmos = load_lookup_table('../../../module_0_foundations/sg13_pmos_lv_LUT.npz')" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "dict_keys(['sg13_lv_nmos ', 'description', 'simulator', 'parameter_names', 'device_parameters'])\n" + ] + } + ], + "source": [ + "print(lookup_table_nmos.keys())" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "nmos = Mosfet(lookup_table=lookup_table_nmos, mos=\"sg13_lv_nmos \", vbs=0.0, vds=0.6)\n", + "pmos = Mosfet(lookup_table=lookup_table_pmos, mos=\"sg13_lv_pmos\", vbs=0.0, vds=-0.6, vgs=(-1.2, -0.15))\n", "\n", - "lookup_table_pmos = load_lookup_table(pmos_lv_path)\n", - "lookup_table_nmos = load_lookup_table(nmos_lv_path)" + "rows_0, cols_0 = np.shape(nmos.extracted_table['gm']) # just for getting the shape of the data\n", + "rows_1, cols_1 = np.shape(pmos.extracted_table['gm']) # just for getting the shape of the data\n", + "reshaped_lengths_nmos = np.tile(nmos.length[:, np.newaxis], (1, cols_0))\n", + "reshaped_lengths_pmos = np.tile(pmos.length[:, np.newaxis], (1, cols_1))" ] }, { "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "nmos = LoadMosfet(lookup_table=lookup_table_nmos, mos=\"nmos\", vsb=0.0, vds=0.6)\n", - "pmos = LoadMosfet(lookup_table=lookup_table_pmos, mos=\"pmos\", vsb=-0.2, vds=-0.6, vgs=(-1.2, -0.1))" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, + "execution_count": 24, + "metadata": { + "jupyter": { + "source_hidden": true + } + }, "outputs": [], "source": [ "def plot_data_vs_data(x_values, y_values, z_values, length, x_axis_name, y_axis_name='y', y_multiplier=1, log=False):\n", @@ -265,7 +264,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 25, "metadata": {}, "outputs": [], "source": [ @@ -279,7 +278,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 26, "metadata": {}, "outputs": [], "source": [ @@ -289,18 +288,18 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "c19c949de81145fbb8f56ff8c2747ab1", + "model_id": "ea4f549168444a6da3039c78cb0ef5f0", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "VBox(children=(Dropdown(description='Length:', layout=Layout(width='500px'), options=('Show All', '0.20 μm', '…" + "VBox(children=(Dropdown(description='Length:', layout=Layout(width='500px'), options=('Show All', '0.13 μm', '…" ] }, "metadata": {}, @@ -308,19 +307,22 @@ } ], "source": [ - "nmos_M6 = LoadMosfet(lookup_table=lookup_table_nmos, mos=\"nmos\", vsb=0, vds=0.6)\n", - "width_values_M6 = nmos_M6.extracted_table['width']\n", + "nmos_M6 = Mosfet(lookup_table=lookup_table_nmos, mos=\"sg13_lv_nmos \", vbs=0, vds=0.6)\n", + "rows_0, cols_0 = np.shape(nmos_M6.extracted_table['gm'])\n", + "reshaped_lengths_nmos_M6 = np.tile(nmos_M6.length[:, np.newaxis], (1, cols_0))\n", + "\n", + "width_values_M6 = nmos_M6.width\n", "id_values_M6 = nmos_M6.extracted_table['id']\n", "gm_values_M6 = nmos_M6.extracted_table['gm']\n", "gds_values_M6 = nmos_M6.extracted_table['gds']\n", "vgs_values_M6 = nmos_M6.extracted_table['vgs']\n", "\n", - "plot_data_vs_data(gm_values_M6/id_values_M6, gm_values_M6/gds_values_M6, vgs_values_M6, nmos_M6.extracted_table['lengths'], 'gm/id', 'gm/gds')" + "plot_data_vs_data(gm_values_M6/id_values_M6, gm_values_M6/gds_values_M6, vgs_values_M6, reshaped_lengths_nmos_M6, 'gm/id', 'gm/gds')" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 13, "metadata": {}, "outputs": [ { @@ -329,7 +331,7 @@ "7.949913192125772e-05" ] }, - "execution_count": 9, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -346,7 +348,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -369,18 +371,18 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "1fec87aafa2d4d009fc5065b0c919616", + "model_id": "c13371af34b44b4fbcd6d05b532d361f", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "VBox(children=(Dropdown(description='Select Length:', options=('Show All', '0.20 μm', '0.25 μm', '0.30 μm', '0…" + "VBox(children=(Dropdown(description='Length:', layout=Layout(width='500px'), options=('Show All', '0.13 μm', '…" ] }, "metadata": {}, @@ -388,19 +390,24 @@ } ], "source": [ - "pmos_M7 = LoadMosfet(lookup_table=lookup_table_pmos, mos=\"pmos\", vsb=0, vds=-0.6, vgs=(-1.2, -0.1))\n", - "width_values_M7 = pmos_M7.extracted_table['width']\n", + "pmos_M7 = Mosfet(lookup_table=lookup_table_pmos, mos=\"sg13_lv_pmos\", vbs=0, vds=-0.6, vgs=(-1.2, -0.1))\n", + "rows_0, cols_0 = np.shape(pmos_M7.extracted_table['gm'])\n", + "reshaped_lengths_pmos_M7 = np.tile(pmos_M7.length[:, np.newaxis], (1, cols_0))\n", + "\n", + "width_values_M7 = pmos_M7.width\n", "id_values_M7 = pmos_M7.extracted_table['id']\n", "gm_values_M7 = pmos_M7.extracted_table['gm']\n", "gds_values_M7 = pmos_M7.extracted_table['gds']\n", "vgs_values_M7 = pmos_M7.extracted_table['vgs']\n", "\n", - "plot_data_vs_data(gm_values_M7/id_values_M7, gm_values_M7/gds_values_M7, vgs_values_M7, pmos_M7.extracted_table['lengths'], 'gm/id', 'gds')\n" + "plot_data_vs_data(gm_values_M7/id_values_M7, gm_values_M7/gds_values_M7, vgs_values_M7, reshaped_lengths_pmos_M7, 'gm/id', 'gds')\n", + "\n", + "\n" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 39, "metadata": {}, "outputs": [], "source": [ @@ -411,7 +418,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 40, "metadata": {}, "outputs": [ { @@ -434,18 +441,18 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "d9ae4f5537e44eb98cb8f43a99ace9e6", + "model_id": "2eca17df295841629e74fb72e1cff63f", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "VBox(children=(Dropdown(description='Select Length:', options=('Show All', '0.20 μm', '0.30 μm', '0.40 μm', '0…" + "VBox(children=(Dropdown(description='Length:', layout=Layout(width='500px'), options=('Show All', '0.13 μm', '…" ] }, "metadata": {}, @@ -454,12 +461,12 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "86826b2d41334c9f97fc4c71228b844b", + "model_id": "88996c8fb302472b8fb5add0523f26dc", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "VBox(children=(Dropdown(description='Select Length:', options=('Show All', '0.20 μm', '0.25 μm', '0.30 μm', '0…" + "VBox(children=(Dropdown(description='Length:', layout=Layout(width='500px'), options=('Show All', '0.13 μm', '…" ] }, "metadata": {}, @@ -467,13 +474,13 @@ } ], "source": [ - "plot_data_vs_data(gm_values_M6/id_values_M6,id_values_M6/width_values_M6, vgs_values_M6, nmos_M6.extracted_table['lengths'], 'gm/id', 'M6 id/W', log=True)\n", - "plot_data_vs_data(gm_values_M7/id_values_M7, id_values_M7/width_values_M7,vgs_values_M7, pmos_M7.extracted_table['lengths'], 'gm/id', 'M7 id/W', log=True)" + "plot_data_vs_data(gm_values_M6/id_values_M6,id_values_M6/width_values_M6, vgs_values_M6, reshaped_lengths_nmos_M6, 'gm/id', 'M6 id/W', log=True)\n", + "plot_data_vs_data(gm_values_M7/id_values_M7, id_values_M7/width_values_M7,vgs_values_M7, reshaped_lengths_pmos_M7, 'gm/id', 'M7 id/W', log=True)" ] }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 42, "metadata": {}, "outputs": [ { @@ -543,7 +550,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 43, "metadata": {}, "outputs": [ { @@ -552,7 +559,7 @@ "2.0004294796936965e-06" ] }, - "execution_count": 16, + "execution_count": 43, "metadata": {}, "output_type": "execute_result" } @@ -570,7 +577,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 44, "metadata": {}, "outputs": [ { @@ -590,7 +597,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 45, "metadata": {}, "outputs": [ { @@ -618,18 +625,18 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "653d5df7f39548198c9e9ad5b226e0ed", + "model_id": "5d7b576ad312473eaeab532b93f3e92f", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "VBox(children=(Dropdown(description='Select Length:', options=('Show All', '0.20 μm', '0.25 μm', '0.30 μm', '0…" + "VBox(children=(Dropdown(description='Length:', layout=Layout(width='500px'), options=('Show All', '0.13 μm', '…" ] }, "metadata": {}, @@ -638,12 +645,12 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "45eaee19c87c4d629180ab7b63eae94a", + "model_id": "e116eacdd44e4571b3f183da0118a4fa", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "VBox(children=(Dropdown(description='Select Length:', options=('Show All', '0.20 μm', '0.30 μm', '0.40 μm', '0…" + "VBox(children=(Dropdown(description='Length:', layout=Layout(width='500px'), options=('Show All', '0.13 μm', '…" ] }, "metadata": {}, @@ -651,8 +658,13 @@ } ], "source": [ - "pmos_M12 = LoadMosfet(lookup_table=lookup_table_pmos, mos=\"pmos\", vsb=-0.2, vds=-0.6, vgs=(-1.2, -0.1))\n", - "nmos_M34 = LoadMosfet(lookup_table=lookup_table_nmos, mos=\"nmos\", vsb=0, vds=0.6)\n", + "pmos_M12 = Mosfet(lookup_table=lookup_table_pmos, mos=\"sg13_lv_pmos\", vbs=-0.2, vds=-0.6, vgs=(-1.2, -0.1))\n", + "nmos_M34 = Mosfet(lookup_table=lookup_table_nmos, mos=\"sg13_lv_nmos \", vbs=0, vds=0.6)\n", + "rows_0, cols_0 = np.shape(nmos_M34.extracted_table['gm']) # just for getting the shape of the data\n", + "rows_1, cols_1 = np.shape(pmos_M12.extracted_table['gm']) # just for getting the shape of the data\n", + "reshaped_lengths_nmos_M34 = np.tile(nmos_M34.length[:, np.newaxis], (1, cols_0))\n", + "reshaped_lengths_pmos_M12 = np.tile(pmos_M12.length[:, np.newaxis], (1, cols_1))\n", + "\n", "\n", "id_values_M12 = pmos_M12.extracted_table['id']\n", "gm_values_M12 = pmos_M12.extracted_table['gm']\n", @@ -664,13 +676,13 @@ "gds_values_M34 = nmos_M34.extracted_table['gds']\n", "vgs_values_M34 = nmos_M34.extracted_table['vgs']\n", "\n", - "plot_data_vs_data(gm_values_M12/id_values_M12, gm_values_M12/gds_values_M12, vgs_values_M12, pmos_M12.extracted_table['lengths'], 'gm/id', 'm12 gm/gds')\n", - "plot_data_vs_data(gm_values_M34/id_values_M34, gm_values_M34/gds_values_M34, vgs_values_M34, nmos_M34.extracted_table['lengths'], 'gm/id', 'm34 gm/gds')" + "plot_data_vs_data(gm_values_M12/id_values_M12, gm_values_M12/gds_values_M12, vgs_values_M12, reshaped_lengths_pmos_M12, 'gm/id', 'm12 gm/gds')\n", + "plot_data_vs_data(gm_values_M34/id_values_M34, gm_values_M34/gds_values_M34, vgs_values_M34, reshaped_lengths_nmos_M34, 'gm/id', 'm34 gm/gds')" ] }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 48, "metadata": {}, "outputs": [ { @@ -697,18 +709,18 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "777232b20ad64f47aaa584c273a69fe7", + "model_id": "4cca567128c14cb68100041e1a57c919", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "VBox(children=(Dropdown(description='Select Length:', options=('Show All', '0.20 μm', '0.25 μm', '0.30 μm', '0…" + "VBox(children=(Dropdown(description='Length:', layout=Layout(width='500px'), options=('Show All', '0.13 μm', '…" ] }, "metadata": {}, @@ -717,12 +729,12 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "7e6503685d4f4eadb9a22f5e2fd505c1", + "model_id": "6c92cedcecfb47f491e2b860b0c65a31", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "VBox(children=(Dropdown(description='Select Length:', options=('Show All', '0.20 μm', '0.30 μm', '0.40 μm', '0…" + "VBox(children=(Dropdown(description='Length:', layout=Layout(width='500px'), options=('Show All', '0.13 μm', '…" ] }, "metadata": {}, @@ -730,16 +742,16 @@ } ], "source": [ - "width_values_M12 = pmos_M12.extracted_table['width']\n", - "width_values_M34 = nmos_M34.extracted_table['width']\n", + "width_values_M12 = pmos_M12.width\n", + "width_values_M34 = nmos_M34.width\n", "\n", - "plot_data_vs_data(gm_values_M12/id_values_M12,id_values_M12/width_values_M12, vgs_values_M12, pmos_M12.extracted_table['lengths'], 'gm/id', 'M12 id/W', log=True)\n", - "plot_data_vs_data(gm_values_M34/id_values_M34, id_values_M34/width_values_M34,vgs_values_M34, nmos_M34.extracted_table['lengths'], 'gm/id', 'M34 id/W', log=True)\n" + "plot_data_vs_data(gm_values_M12/id_values_M12,id_values_M12/width_values_M12, vgs_values_M12, reshaped_lengths_pmos_M12, 'gm/id', 'M12 id/W', log=True)\n", + "plot_data_vs_data(gm_values_M34/id_values_M34, id_values_M34/width_values_M34,vgs_values_M34, reshaped_lengths_nmos_M34, 'gm/id', 'M34 id/W', log=True)\n" ] }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 51, "metadata": {}, "outputs": [ { @@ -792,7 +804,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 52, "metadata": {}, "outputs": [ { @@ -894,6 +906,13 @@ "\"\"\"\n", "print(summary)" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/modules/module_1_bandgap_reference/part_1_OTA/testbenches/ota_testbench.sch b/modules/module_1_bandgap_reference/part_1_OTA/testbenches/ota_testbench.sch index ad4c3d64..6c472580 100644 --- a/modules/module_1_bandgap_reference/part_1_OTA/testbenches/ota_testbench.sch +++ b/modules/module_1_bandgap_reference/part_1_OTA/testbenches/ota_testbench.sch @@ -12,7 +12,7 @@ ypos2=2 divy=5 subdivy=4 unity=1 -x1=-1.75 +x1=-0.22184875 divx=5 subdivx=8 @@ -38,16 +38,16 @@ y2=33.964 y1=-136.006 color=4 node=ph(vout) -x2=5.25} +x2=-0.22184875} B 2 680 -1295 1480 -895 {flags=graph -y1=33 -y2=74 +y1=27 +y2=71 ypos1=0 ypos2=2 divy=5 subdivy=1 unity=1 -x1=-1.75 +x1=-0.22184875 divx=5 subdivx=8 @@ -59,7 +59,7 @@ dataset=-1 unitx=1 logx=1 logy=0 -x2=5.25} +x2=-0.22184875} B 2 1535 -1295 2335 -895 {flags=graph y1=37 y2=86 @@ -68,7 +68,7 @@ ypos2=2 divy=5 subdivy=1 unity=1 -x1=-1.75 +x1=-0.22184875 divx=5 subdivx=8 @@ -80,18 +80,18 @@ dataset=-1 unitx=1 logx=1 logy=0 -x2=5.25 +x2=-0.22184875 color=4 node=cmrr} B 2 1525 -875 2325 -475 {flags=graph -y1=0.05 -y2=28 +y1=0.055 +y2=30 ypos1=0 ypos2=2 divy=5 subdivy=1 unity=1 -x1=-1.75 +x1=-0.22184875 divx=5 subdivx=8 @@ -103,7 +103,7 @@ dataset=-1 unitx=1 logx=1 logy=0 -x2=5.25 +x2=-0.22184875 color=4 node=psrr} N 775 -265 775 -235 { @@ -235,7 +235,7 @@ footprint=1206 device="ceramic capacitor"} C {gnd.sym} 530 -335 0 0 {name=l5 lab=GND} C {iopin.sym} 620 -410 0 0 {name=p7 lab=vout} -C {devices/code_shown.sym} -445 -290 0 0 {name=MODEL only_toplevel=false +C {devices/code_shown.sym} -415 -290 0 0 {name=MODEL only_toplevel=false format="tcleval( @value )" value=" .lib $::SG13G2_MODELS/cornerCAP.lib cap_typ