Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .github/workflows/skill-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Tessl Skill Review β€” runs on PRs that change any SKILL.md; posts scores as one PR comment.
# Docs: https://github.com/tesslio/skill-review
name: Tessl Skill Review

on:
pull_request:
branches: [main]
paths:
- "**/SKILL.md"

jobs:
review:
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: read
steps:
- uses: actions/checkout@v4
- uses: tesslio/skill-review@main
# Optional quality gate (off by default β€” do not enable unless user asked):
# with:
# fail-threshold: 70
30 changes: 14 additions & 16 deletions gmoverid/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,29 +101,27 @@ On Windows prefer `Microsoft YaHei`; on Linux/macOS verify the font is installed

### Core Idea of the gm/ID Methodology

**gm/ID (transconductance efficiency) is the pivot quantity linking circuit specifications to device dimensions.**
**gm/ID (transconductance efficiency) links circuit specs to device dimensions** via simulation-generated lookup tables, replacing error-prone long-channel equations (gm = 2Id/Vov) that fail in advanced nodes (≀ 180 nm).

Traditional design relies on long-channel model equations (gm = 2Id/Vov) to compute device sizes; errors are severe in advanced nodes (≀ 180 nm). The gm/ID method abandons equations in favor of simulation-generated design charts (lookup tables), using gm/ID as the single independent variable to express all key device performance parameters:
gm/ID maps to four W-independent quantities β€” generate the chart once at unit width, use for any W:

```
gm/ID ──► Id/W (current-density curve β†’ determines W)
──► fT (transit frequency β†’ determines speed)
──► gmΒ·ro (intrinsic gain β†’ determines gain ceiling)
──► Vgs (uniquely determines the bias point)
```

All four curves are **independent of transistor width W** β€” devices of different W share exactly the same Id/W, fT, and gmΒ·ro values at the same gm/ID point. This is the foundation of the methodology: the design chart needs to be generated only once (at unit width), and it applies directly to any W.
| gm/ID maps to | Determines |
|---------------|-----------|
| Id/W (current density) | Transistor width W |
| fT (transit frequency) | Speed |
| gmΒ·ro (intrinsic gain) | Gain ceiling |
| Vgs (gate-source voltage) | Bias point |

**gm/ID is the trade-off axis for three design objectives:**
**gm/ID is the trade-off axis:**

| Design priority | Direction of gm/ID | Reason |
|----------------|:-----------------:|--------|
| High speed (fT↑) | Low gm/ID (strong inversion) | High Vov β†’ fast |
| High gain (gmΒ·ro↑) | High gm/ID (weak/moderate inversion) | Closer to subthreshold |
| Low power (Id↓, same W) | High gm/ID | Id/W decreases as gm/ID increases |
| Minimum area (W↓, same Id) | Low gm/ID | Id/W decreases as gm/ID increases |
| High speed (fT↑) | Low (strong inversion) | High Vov β†’ fast |
| High gain (gmΒ·ro↑) | High (weak/moderate inversion) | Closer to subthreshold |
| Low power (Id↓, same W) | High | Id/W decreases with rising gm/ID |
| Minimum area (W↓, same Id) | Low | Id/W decreases with rising gm/ID |

> Note: area and power optimization point in opposite directions β€” this is the central trade-off in gm/ID design.
> Area and power optimization point in opposite directions β€” this is the central trade-off in gm/ID design.

---

Expand Down
214 changes: 24 additions & 190 deletions ngspice/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: ngspice
description: "ngspice simulation tutorial and template skill. Provides nine standard simulation examples: (1) Transient β€” RC charging voltage and current; (2) DC β€” NMOS Id-Vds family curves; (3) AC β€” RC low-pass filter frequency response; (4) Noise β€” RC filter output noise spectral density and kT/C; (5) Transient β€” sample-and-hold switch comparison; (6) Transient β€” kT/C noise time-domain statistical measurement; (7) DC β€” NMOS current mirror output characteristics; (8) AC β€” common-source amplifier frequency response; (9) DC β€” transmission gate on-resistance. Built-in PTM 180/45/22nm models included."
description: "ngspice circuit simulation tutorial and template skill for analog and mixed-signal design. Provides nine ready-to-run simulation examples covering transient, DC, AC, and noise analyses: RC charging, NMOS Id-Vds family curves, RC low-pass filter frequency response, noise spectral density and kT/C, sample-and-hold switch comparison, kT/C noise time-domain statistics, NMOS current mirror, common-source amplifier frequency response, and transmission gate on-resistance. Built-in PTM 180/45/22nm MOSFET models included. Use when the user wants to simulate a circuit with ngspice, run SPICE analysis, model transistor behavior, perform analog circuit simulation, generate IV curves, analyze frequency response, measure noise, or needs a netlist template for any standard simulation type."
---

# ngspice Simulation Skill
Expand Down Expand Up @@ -100,202 +100,36 @@ All paths resolve automatically via `Path(__file__).resolve().parent` β€” no con

---

## Example 1: Transient β€” RC Charging
## Simulation Examples

**Circuit:** R + C to ground, 1V DC step input, initial Vcap = 0.
Nine ready-to-run examples are included, each following the pattern: netlist template (`.cir.tmpl`) β†’ simulation engine (`simulate_*.py`) β†’ plotting (`plot_*.py`) β†’ entry point (`run_*.py`).

**Configurations:**
| # | Type | Example | Entry point | Output plot | Key sanity check |
|---|------|---------|-------------|-------------|-----------------|
| 1 | Transient | RC charging (1kΞ©/10kΞ© + 1pF) | `run_tran_rc_charging.py` | `plots/tran_rc_charging.png` | V reaches 63.2% at t = Ο„ |
| 2 | DC | NMOS Id-Vds family curves (180nm) | `run_dc_nmos_iv.py` | `plots/nmos_dc_iv.png` | Saturation region visible, Vgs=1.0V β†’ Id β‰ˆ 2.45mA |
| 3 | AC | RC low-pass filter bandwidth | `run_ac_rc_filter.py` | `plots/rc_ac_bw.png` (top) | βˆ’3dB at fc = 1/(2Ο€RC); βˆ’20dB/dec roll-off |
| 4 | Noise | RC filter output noise spectral density | `run_ac_rc_filter.py` | `plots/rc_ac_bw.png` (bottom) | √(kT/C) = 64.3¡Vrms (1pF) |
| 5 | Transient | Sample-and-hold NMOS vs ideal switch | `run_tran_sample_hold.py` | `plots/sample_hold_compare.png` | Clock feedthrough visible in NMOS, absent in ideal |
| 6 | Transient | kT/C noise time-domain statistics | `run_tran_ktc_noise.py` | `plots/tran_ktc_noise_hist.png` | Οƒ β‰ˆ 64Β΅V (1pF), Gaussian histogram |
| 7 | DC | NMOS current mirror output (180nm) | `run_dc_current_mirror.py` | `plots/dc_current_mirror.png` | Iout β‰ˆ 100Β΅A in saturation, CLM slope visible |
| 8 | AC | Common-source amplifier frequency response | `run_ac_cs_amp.py` | `plots/ac_cs_amp_bode.png` | |Av| β‰ˆ 12.9dB, βˆ’3dB β‰ˆ 132MHz |
| 9 | DC | Transmission gate Ron (180/45/22nm) | `run_dc_tgate_ron.py` | `plots/dc_tgate_ron.png` | Min Ron: 38Ξ© (180nm), 52Ξ© (45nm), 103Ξ© (22nm) |

| Config | R | C | Ο„ = RC |
|--------|---|---|--------|
| 1 | 1 kΞ© | 1 pF | **1 ns** |
| 2 | 10 kΞ© | 1 pF | **10 ns** |

**Simulation:** `.tran` to 10Ο„ (slow config), UIC + IC=0.

**Output:** `plots/tran_rc_charging.png` (top panel: voltage; bottom panel: current).

**Sanity checks:**
- V(out) = Vin Γ— (1 βˆ’ e^(βˆ’t/Ο„)); reaches 63.2% at t = Ο„
- I = Vin/R Γ— e^(βˆ’t/Ο„); initial current = 1V/1kΞ© = 1mA (or 100Β΅A for 10kΞ©)
- Capacitor essentially fully charged (>99%) after 5Ο„

**Files:** `tran_rc_charging.cir.tmpl` β†’ `simulate_tran_rc_charging.py` β†’ `plot_tran_rc_charging.py` β†’ `run_tran_rc_charging.py`
> Examples 3 & 4 share a single entry script (same circuit, natural teaching flow). Example 1 is the simplest β€” use it to verify ngspice is installed correctly.

---

## Example 2: DC β€” NMOS Id-Vds Family Curves

**Circuit:** PTM 180nm NMOS, W=10Β΅m, L=0.18Β΅m.

**Simulation:** `.dc Vds 0 1.8 0.01`, Vgs = {0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8} V.

**Output:** `plots/nmos_dc_iv.png`.

**Sanity checks:**
- Vgs = 0.4V (near Vth β‰ˆ 0.4V): Id β‰ˆ 59 Β΅A (near threshold / weak inversion)
- Vgs = 0.6V, Vds = 0.9V (saturation): Id β‰ˆ 561 Β΅A, Id/W β‰ˆ 56 Β΅A/Β΅m
- Vgs = 1.0V, Vds = 0.9V (saturation): Id β‰ˆ 2.45 mA, Id/W β‰ˆ 245 Β΅A/Β΅m
- Saturation region clearly visible (curves flatten for Vds > Vgs βˆ’ Vth)

**Files:** `dc_nmos_iv.cir.tmpl` β†’ `simulate_dc_nmos_iv.py` β†’ `plot_dc_nmos_iv.py` β†’ `run_dc_nmos_iv.py`

---

## Example 3: AC β€” RC Low-Pass Filter Bandwidth

**Circuit:** R + C to ground, AC source amplitude 1V.

**Configurations:**

| Config | R | C | fc = 1/(2Ο€RC) |
|--------|---|---|--------------|
| 1 | 1 kΞ© | 1 pF | **159.2 MHz** |
| 2 | 10 kΞ© | 1 pF | **15.92 MHz** |

**Simulation:** `.ac dec 100 1Meg 10G`.

**Output:** `plots/rc_ac_bw.png` (top panel: gain).

**Sanity checks:**
- βˆ’3 dB point matches theoretical fc: 159.2 MHz (1kΞ©), 15.92 MHz (10kΞ©)
- Roll-off above fc: βˆ’20 dB/decade (first-order filter)
- Low-frequency gain = 0 dB

---

## Example 4: Noise β€” RC Filter Output Noise

**Circuit:** same as AC example (R + C to ground).

**Simulation:** `.noise v(out) Vin dec 100 1Meg 10G`.

**Output:** `plots/rc_ac_bw.png` (bottom panel: noise spectral density).

**Sanity checks:**
- White noise floor = √(4kTR): **4.07 nV/√Hz** (R=1kΩ), **12.87 nV/√Hz** (R=10kΩ)
- Integrated noise = √(kT/C): **64.3 Β΅Vrms** (C=1pF) β€” classic kT/C noise
- Noise bandwidth = Ο€/2 Γ— fc (first-order filter)
- Noise rolls off at βˆ’20 dB/decade above fc

> AC and noise share a single entry script `run_ac_rc_filter.py` (same circuit, natural teaching flow).

---

## Example 5: Transient β€” Sample-and-Hold Switch Comparison

**Circuit:** NMOS switch (180nm, W=4Β΅m) + Csamp=1pF, 10MHz sinusoidal input, 100MHz clock.

**Simulation:** `.tran 0.1n 250n`.

**Output:** `plots/sample_hold_compare.png`.

**Model comparison:**

| Model | Ron | Characteristics |
|-------|-----|----------------|
| 180nm NMOS | ~400 Ξ© | real parasitics |
| Ideal switch SPICE subckt | 50 Ξ© | no parasitics |

**Sanity checks:**
- Hold voltage remains flat during switch OFF (1pF capacitor charge conservation)
- 180nm NMOS Ron β‰ˆ 400Ξ© β†’ acquisition time constant Ο„ = Ron Γ— C = 400 Γ— 1p = 0.4 ns
- Clock feedthrough (Ξ”V = Cov/Csamp Γ— Vclk) visible as small step at clock edges
- Ideal switch shows no clock feedthrough or charge injection

**Files:** `tran_sample_hold_nmos/ideal.cir.tmpl` β†’ `simulate_tran_sample_hold.py` β†’ `plot_tran_sample_hold.py` β†’ `run_tran_sample_hold.py`

---

## Example 6: Transient β€” kT/C Noise Time-Domain Statistics

**Circuit:** noisy R (400Ξ©, equivalent switch Ron) + Csamp; DC input 0.9V. A `trnoise` voltage source injects thermal noise into the resistor.

**Principle:** Resistor thermal noise density 4kTR, bandwidth-limited by RC, gives capacitor noise variance = kT/C. Sample v(out) every 5Ο„ over a long transient to obtain 10000 independent samples.

**Configurations:**

| Csamp | Ο„ = RC | √(kT/C) theoretical |
|-------|--------|---------------------|
| 1 pF | 0.4 ns | **64.3 Β΅Vrms** |
| 100 fF | 0.04 ns | **203.5 Β΅Vrms** |

**Output:** `plots/tran_ktc_noise_hist.png` (noise trace + histogram + fitted Gaussian + statistics summary).

**Sanity checks:**
- 1 pF: measured Οƒ β‰ˆ 64 Β΅V (Β±10% statistical variation)
- 100 fF: measured Οƒ β‰ˆ 203 Β΅V (Β±10% statistical variation)
- Histogram is Gaussian; fitted curve matches theoretical √(kT/C)
- Measured/theoretical ratio in [0.85, 1.15]

**Files:** `tran_ktc_noise.cir.tmpl` β†’ `simulate_tran_ktc_noise.py` β†’ `plot_tran_ktc_noise.py` β†’ `run_tran_ktc_noise.py`

---

## Example 7: DC β€” NMOS Current Mirror Output Characteristics

**Circuit:** PTM 180nm NMOS 1:1 current mirror; M1 diode-connected (reference), M2 output.

**Parameters:** W=10Β΅m, L=0.5Β΅m (longer channel for better matching), Iref=100Β΅A.

**Simulation:** `.dc Vout 0 1.8 0.01`.

**Output:** `plots/dc_current_mirror.png` (Iout vs Vout + mirror ratio).

**Sanity checks:**
- Vout > Vov (β‰ˆ0.2V), M2 in saturation: Iout β‰ˆ 100 Β΅A
- Channel-length modulation causes Iout to increase slightly with Vout (slope β‰ˆ 1/ro)
- Output resistance ro β‰ˆ VA/Id β‰ˆ 50–100 kΞ©
- Vout < Vov: M2 enters triode, Iout < Iref

**Files:** `dc_current_mirror.cir.tmpl` β†’ `simulate_dc_current_mirror.py` β†’ `plot_dc_current_mirror.py` β†’ `run_dc_current_mirror.py`

---

## Example 8: AC β€” Common-Source NMOS Amplifier Frequency Response

**Circuit:** PTM 180nm NMOS common-source amplifier with resistive load and load capacitance.

**Parameters:** W=10Β΅m, L=0.18Β΅m, Vgs=0.6V, Rd=2kΞ©, CL=1pF, VDD=1.8V.

**Simulation:** `.ac dec 100 1k 100G`.

**Output:** `plots/ac_cs_amp_bode.png` (gain Bode plot + phase).

**Sanity checks:**
- DC gain |Av| = gm Γ— Rd β‰ˆ 12.9 dB
- βˆ’3 dB frequency β‰ˆ 132 MHz (theoretical 1/(2Ο€RdCL) β‰ˆ 80 MHz; higher in practice due to MOSFET parasitic capacitance)
- Low-frequency phase β‰ˆ 180Β° (inverting amplifier)
- High-frequency roll-off at βˆ’20 dB/decade (single pole)

**Files:** `ac_cs_amp.cir.tmpl` β†’ `simulate_ac_cs_amp.py` β†’ `plot_ac_cs_amp.py` β†’ `run_ac_cs_amp.py`

---

## Example 9: DC β€” Transmission Gate On-Resistance

**Circuit:** NMOS + PMOS complementary transmission gate, W/L=100, fully on (clk=VDD, clkb=0).

**Method:** Apply 10mV across the gate, sweep Vpass; Ron = 10mV / I.

**Technology node comparison:**

| Node | VDD | L | W | Model |
|------|-----|---|---|-------|
| 180nm | 1.8V | 0.18Β΅m | 18Β΅m | PTM BSIM3v3 |
| 45nm HP | 1.0V | 45nm | 4.5Β΅m | PTM BSIM4 |
| 22nm HP | 0.8V | 22nm | 2.2Β΅m | PTM BSIM4 |

**Output:** `plots/dc_tgate_ron.png` (Ron vs Vpass, log scale, 3 curves).

**Sanity checks:**
- 180nm: min Ron β‰ˆ 38 Ξ©; lowest resistance in the mid-Vpass range
- 45nm HP: min Ron β‰ˆ 52 Ξ©
- 22nm HP: min Ron β‰ˆ 103 Ξ© (lower VDD limits gate drive)
- Ron rises at Vpass near 0 and VDD (NMOS / PMOS turning off respectively)
- Complementary structure ensures conduction across the full Vpass range
## Troubleshooting and Error Recovery

**Files:** `dc_tgate_ron.cir.tmpl` β†’ `simulate_dc_tgate_ron.py` β†’ `plot_dc_tgate_ron.py` β†’ `run_dc_tgate_ron.py`
| Symptom | Likely cause | Fix |
|---------|-------------|-----|
| `ngspice: command not found` | ngspice not installed or not in PATH | See `references/installation.md` for platform-specific install instructions |
| `Error: can't open ...` in ngspice output | Model file path not resolved | Verify `models/` directory was copied alongside scripts; check `spath()` on Windows |
| Simulation hangs or takes very long | Convergence failure or step size too small | Add `.options reltol=1e-3 abstol=1e-12` to netlist; reduce sweep range |
| `KeyError` in Python template rendering | `{...}` inside SPICE comment lines | Remove or escape braces in comment lines of `.cir.tmpl` files |
| Plot shows flat lines or NaN | Simulation produced no valid data | Check `logs/` for ngspice error messages; verify netlist syntax |
| GBK encoding error on Windows | Python default encoding mismatch | Set `PYTHONUTF8=1` environment variable before running |

---

Expand Down
10 changes: 6 additions & 4 deletions transistor-models/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: transistor-models
description: "Complete PTM (Predictive Technology Model) MOSFET model library from mec.umn.edu/ptm, covering all nodes: bulk conventional 180/130/90/65nm, bulk HP/LP 45/32/22nm (BSIM4), and PTM-MG multi-gate FinFET 7/10/14/16/20nm (BSIM-CMG, HP + LSTP). No manual downloads required after installing this skill. Independent of the gmoverid skill β€” can be used directly in any ngspice/HSPICE project."
description: "Complete PTM (Predictive Technology Model) MOSFET model library for circuit simulation, covering all nodes: bulk conventional 180/130/90/65nm, bulk HP/LP 45/32/22nm (BSIM4), and PTM-MG multi-gate FinFET 7/10/14/16/20nm (BSIM-CMG, HP + LSTP). No manual downloads required after installing this skill. Independent of the gmoverid skill β€” can be used directly in any ngspice/HSPICE project. Use when the user needs transistor models or SPICE models for circuit simulation, asks about process technology nodes, wants to set up a new SPICE simulation project, needs MOSFET device models for analog or digital design, or references PTM, BSIM, or FinFET models."
---

# Transistor Models Skill β€” Complete PTM Library
Expand Down Expand Up @@ -138,6 +138,8 @@ Full parameter table in `references/model_params.md`.

If you have your own `.lib` file (foundry PDK or measured):
1. Copy it into the project `models/` directory.
2. Find the `.model` name inside the file (e.g. `.model mynmos NMOS level=54`).
3. Instantiate using that name: `M1 d g s b mynmos W=... L=...`
4. Configure sweep ranges based on `vth0`, `tox`, etc.
2. Verify the file was copied: `ls -la models/` and confirm the `.lib` file is present and non-empty.
3. Find the `.model` name inside the file (e.g. `.model mynmos NMOS level=54`).
4. Instantiate using that name: `M1 d g s b mynmos W=... L=...`
5. Run a quick DC operating-point check (`.op`) to verify the model loads without errors before running full simulations.
6. Configure sweep ranges based on `vth0`, `tox`, etc.