This repository contains GM/ID extraction data and related interactive scripts to get started with gm/id-based design using the IHP130 PDK. It enables users to perform circuit simulations, extract key transistor parameters, and generate insightful plots quickly and efficiently.
-
Clone the Repository:
git clone https://github.com/chennakeshavadasa/gmid_IHP130.git cd gmid_IHP130
-
Set up a virtual Environment
python -m venv venv venv\Scripts\activate # On Windows # source venv/bin/activate # On Linux/macOS
-
Install Dependancies
pip install -r requirements.txt
This script is designed to process and visualize gm/ID design data for various transistor types (e.g., HV_NMOS, LV_PMOS). It allows designers to analyze device behavior across lengths and optimize operating points using interactive plots and numerical optimization.
The raw .txt
files contain electrical characteristics for multiple transistor lengths. The get_data()
function extracts and cleans this data for further analysis.
def get_data(data: List, key: str) -> pd.DataFrame:
...
for i, file_path in enumerate(data):
with open(f'{gmid_data}/{key}/{file_path}', 'r') as file:
...
filtered_entry = [val for i, val in enumerate(entry) if i < 3 or i % 2 == 0]
...
All transistor lengths are labeled using the labels
list (e.g., '0.13u'
, '0.25u'
, ...).
Once the raw data is loaded, additional performance metrics are computed:
- Vov (Vgs - Vth) – Overdrive voltage
- gm/ID – Transconductance efficiency
- gm/gds – Maximum Voltage Gain
- id/W – Current Density
- ft – Transit frequency
- Capacitance ratios –
Cgd/Cgg
andCgs/Cgg
df['Vov'] = df['Vgs'] - df['Vth']
df['gm/id'] = df['gm'] / df['id_val']
df['gm/gds'] = df['gm'] / df['gds']
df['ft'] = df['gm'] / (2 * np.pi * df['Cgg'])
The plot_interactive()
function creates responsive graphs across transistor lengths for various electrical metrics:
plot_interactive(df, 'Vgs', 'gm/id', 'Vgs', 'gm/id', f'{df["Device"].unique()[0]} gm/id versus Vgs')
plot_interactive(df, 'gm/id', 'gm/gds', 'gm/id', 'gm/gds', f'{df["Device"].unique()[0]} gm/gds versus gm/id')
plot_interactive(df, 'gm/id', 'id/W', 'gm/id', 'id/W', f'{df["Device"].unique()[0]} id/W versus gm/id')
Each trace represents a different transistor length, color-coded for clarity. Log-scaling and SI formatting are included for better readability.
Using SciPy's optimization, the script finds the device operating point closest to the target design metrics:
- Target
gm/ID
(e.g., 15) - Target
gm/gds
(e.g., ≥ 100) - Weighted error minimization
def objective_function(x):
error_A = w1 * (x[0] - gm_id_target) ** 2
error_B = w2 * (x[1] - gm_gds_target) ** 2
return error_A + error_B
Optimization result:
result = minimize(objective_function, x0, method='L-BFGS-B', bounds=bounds)
The closest matching data row is retrieved:
df['distance'] = np.sqrt(
w1 * (df['gm/id'] - optimized_gm_id) ** 2 +
w2 * (df['gm/gds'] - optimized_gm_gds) ** 2
)
closest_row = df.loc[df['distance'].idxmin()]
Final output includes key performance metrics:
print("\nClosest Matching Row:\n", closest_row[['Device', 'Length', 'gm/id', 'gm/gds', 'id/W', 'ft']])