IHP-AnalogAcademy/modules/module_1_bandgap_reference/scripting/test.ipynb

309 lines
11 KiB
Plaintext

{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "54ce5e7b-3a0f-4df1-ab58-7e93856acec9",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"#for windows\n",
"import sys\n",
"sys.path.append(r'C:\\Users\\pedersen\\gmid') # path to gmid repository\n",
"# ------\n",
"import matplotlib.pyplot as plt\n",
"from mosplot import load_lookup_table, LoadMosfet # make sure that mosplot can be found in the python path\n",
"import ipywidgets as widgets\n",
"from ipywidgets import interactive\n",
"from ipywidgets import interactive_output, HBox, VBox\n",
"import matplotlib.ticker as ticker "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4982b065-4d01-496e-8c46-3f9862bc07c5",
"metadata": {},
"outputs": [],
"source": [
"def plot_data_vs_data(x_values, y_values, length, x_axis_name, y_axis_name='y', y_multiplier=1, log=False):\n",
" x_values_flat = np.array(x_values).flatten() \n",
" y_values_flat = np.array(y_values, dtype=np.float64).flatten() \n",
" length_flat = np.array(length).flatten()\n",
"\n",
" unique_lengths = np.unique(length_flat)\n",
" unique_lengths_in_micro = unique_lengths * 1e6\n",
" \n",
" def update_plot(selected_length, x_value=None, y_value=None):\n",
" plt.figure(figsize=(8, 6)) # Ensure the plot is drawn fresh for each update\n",
"\n",
" if selected_length == \"Show All\":\n",
" mask = np.ones_like(length_flat, dtype=bool)\n",
" else:\n",
" selected_length_in_micro = float(selected_length.replace(' μm', ''))\n",
" tolerance = 0.1 \n",
" mask = np.abs(length_flat * 1e6 - selected_length_in_micro) < tolerance \n",
"\n",
" x_values_for_length = x_values_flat[mask]\n",
" y_values_for_length = y_values_flat[mask] * y_multiplier \n",
" length_for_length = length_flat[mask] * 1e6 \n",
"\n",
" if selected_length == \"Show All\":\n",
" for length_value in np.unique(length_for_length):\n",
" mask_all = (length_for_length == length_value)\n",
" plt.plot(x_values_for_length[mask_all], y_values_for_length[mask_all])\n",
"\n",
" min_length = np.min(unique_lengths_in_micro)\n",
" max_length = np.max(unique_lengths_in_micro)\n",
" plt.title(f'{y_axis_name} vs {x_axis_name} (Length from {min_length:.2f} μm to {max_length:.2f} μm)')\n",
"\n",
" else:\n",
" plt.plot(x_values_for_length, y_values_for_length)\n",
" plt.title(f'{y_axis_name} vs {x_axis_name} for {selected_length}')\n",
"\n",
" plt.xlabel(f'{x_axis_name}')\n",
" plt.ylabel(f'{y_axis_name}')\n",
"\n",
" if log:\n",
" plt.yscale('log')\n",
" plt.gca().yaxis.set_major_locator(ticker.LogLocator(base=10, subs=[], numticks=10))\n",
" plt.gca().yaxis.set_major_formatter(ticker.FuncFormatter(lambda x, _: f'$10^{int(np.log10(x))}$'))\n",
" plt.ylabel(f'{y_axis_name} (Log Base 10)') \n",
" \n",
" if y_value is not None and x_value_widget.disabled:\n",
" closest_index = np.abs(y_values_for_length - y_value).argmin()\n",
" closest_x = x_values_for_length[closest_index]\n",
" closest_y = y_values_for_length[closest_index]\n",
"\n",
" plt.scatter(closest_x, closest_y, color='blue', label=f'Point ({closest_x:.2f}, {closest_y:.2f})')\n",
" print(f\"The corresponding {x_axis_name} value for {y_axis_name} = {closest_y:.2f} is: {closest_x:.2f}\")\n",
" elif x_value is not None and y_value_widget.disabled:\n",
" closest_index = np.abs(x_values_for_length - x_value).argmin()\n",
" closest_x = x_values_for_length[closest_index]\n",
" closest_y = y_values_for_length[closest_index]\n",
" \n",
" plt.scatter(closest_x, closest_y, color='red', label=f'Point ({closest_x:.2f}, {closest_y:.2f})')\n",
" print(f\"The corresponding {y_axis_name} value for {x_axis_name} = {closest_x:.2f} is: {closest_y:.2f}\")\n",
"\n",
" plt.grid(True)\n",
" plt.legend()\n",
" plt.show()\n",
"\n",
" dropdown_options = [\"Show All\"] + [f'{length:.2f} μm' for length in unique_lengths_in_micro]\n",
" length_widget = widgets.Dropdown(\n",
" options=dropdown_options,\n",
" value=dropdown_options[0], \n",
" description='Select Length:',\n",
" )\n",
" \n",
" x_value_widget = widgets.FloatText(\n",
" value=np.mean(x_values_flat),\n",
" description=f\"Select {x_axis_name}:\",\n",
" disabled=False\n",
" )\n",
" \n",
" y_value_widget = widgets.FloatText(\n",
" value=None,\n",
" description=f\"Set {y_axis_name}:\",\n",
" disabled=True\n",
" )\n",
" \n",
" select_x_or_y_widget = widgets.Checkbox(\n",
" value=True,\n",
" description=f\"Select {x_axis_name} (uncheck for {y_axis_name})\",\n",
" )\n",
" \n",
" def toggle_x_or_y(change):\n",
" if change['new']:\n",
" x_value_widget.disabled = False\n",
" y_value_widget.disabled = True\n",
" else:\n",
" x_value_widget.disabled = True\n",
" y_value_widget.disabled = False\n",
" \n",
" select_x_or_y_widget.observe(toggle_x_or_y, names='value')\n",
"\n",
" output = interactive_output(update_plot, {\n",
" 'selected_length': length_widget, \n",
" 'x_value': x_value_widget, \n",
" 'y_value': y_value_widget\n",
" })\n",
"\n",
" display(VBox([length_widget, select_x_or_y_widget, HBox([x_value_widget, y_value_widget]), output]))\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3ec44e96-94a7-4aab-8dae-17dee091935e",
"metadata": {},
"outputs": [],
"source": [
"#pmos_lv_path = '/home/pedersen/gmid/models/gmoveridpypmos_gmid_final.npy'\n",
"#nmos_lv_path = '/home/pedersen/gmid/models/gmoveridpynmos_final_gmid.npy'\n",
"\n",
"# Windows paths\n",
"pmos_lv_path = r'C:\\Users\\pedersen\\Desktop\\OpenDesingCourse\\no_touch_files\\gmoveridpypmos_gmid_final.npy'\n",
"nmos_lv_path =r'C:\\Users\\pedersen\\Desktop\\OpenDesingCourse\\no_touch_files\\gmoveridpynmos_final_gmid.npy'"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "5f4e7bb2-ca5d-4a5a-a075-2249cfc9cfd6",
"metadata": {},
"outputs": [],
"source": [
"lookup_table_pmos = load_lookup_table(pmos_lv_path)\n",
"lookup_table_nmos = load_lookup_table(nmos_lv_path)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "134210f0-f439-453a-851a-db41cda3015b",
"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, vds=-0.6, vgs=(-1.2, -0.1))"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "d3b19fee",
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "eff5ad7f83e545f982959759e1fd06be",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"VBox(children=(Dropdown(description='Select Length:', options=('Show All', '0.13 μm', '0.26 μm', '0.39 μm', '0…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"vgs_nmos = nmos.extracted_table['vgs']\n",
"id_values = nmos.extracted_table['id']\n",
"plot_data_vs_data(vgs_nmos, id_values, nmos.extracted_table['lengths'], 'Vgs', 'Id[mu A]', y_multiplier=1e6, log=True)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "dc67ba80-b9d7-4bc4-9167-22968d9cc33a",
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "48e7de4c24964abb9d633c2daff1c51a",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"VBox(children=(Dropdown(description='Select Length:', options=('Show All', '0.13 μm', '0.26 μm', '0.39 μm', '0…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"id_values = nmos.extracted_table['id']\n",
"length = nmos.extracted_table['lengths']\n",
"gm = nmos.extracted_table['gm']\n",
"gds = nmos.extracted_table['gds']\n",
"gmro = gm/gds\n",
"gmid = gm/id_values\n",
"\n",
"plot_data_vs_data(gmid, gm/gds, length,'gmid','gmro')"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "2d8f8985-f28f-41d7-8915-07f97574b5ac",
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "96e6bc75e82842159a1ae66652d4d8c8",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"VBox(children=(Dropdown(description='Select Length:', options=('Show All', '0.13 μm', '0.26 μm', '0.39 μm', '0…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"id_values = nmos.extracted_table['id']\n",
"width = nmos.extracted_table['width']\n",
"length = nmos.extracted_table['lengths']\n",
"gm = nmos.extracted_table['gm']\n",
"gmid = gm/id_values\n",
"\n",
"plot_data_vs_data(gmid, id_values/width, length,'gmid','id/width', log = True)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "d57db53e",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Width = 2.4999999999999998e-05\n"
]
}
],
"source": [
"id = 16e-6\n",
"gmid = 9.86\n",
"length = 1.3e-6\n",
"id_over_width = 0.64\n",
"width = id/id_over_width\n",
"print(f\"Width = {width:}\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.5"
}
},
"nbformat": 4,
"nbformat_minor": 5
}