LTspice Circuit Simulation Guide
SPICE Fundamentals
Netlist Structure
* Title line (first line, always a comment)
<components>
<directives>
.END
.END must be last line. No statements after it.
+ at start of line continues previous statement.
- Comments:
* (full line) or ; (inline).
Component Syntax
<ref> <node+> <node-> <value>
R1 in out 10k
C1 out 0 100n
V1 in 0 AC 1 PULSE(0 5 0 1n 1n 0.5m 1m)
Value Notation — CRITICAL
| Suffix |
Meaning |
Value |
| f |
femto |
1e-15 |
| p |
pico |
1e-12 |
| n |
nano |
1e-9 |
| u |
micro |
1e-6 |
| m |
milli |
1e-3 |
| k |
kilo |
1e3 |
| MEG |
mega |
1e6 |
| G |
giga |
1e9 |
| T |
tera |
1e12 |
M means milli, not mega. Use MEG for 1e6.
1M = 0.001, not 1000000. Unrecognized suffix letters are silently ignored:
no error, just a wrong value.
Waveform Sources
PULSE(Vinitial Vpulse Tdelay Trise Tfall Ton Tperiod Ncycles)
SINE(Voffset Vamp Freq Td Theta Phi Ncycles)
EXP(V1 V2 Td1 Tau1 Td2 Tau2)
SFFM(Voff Vamp Fcar MDI Fsig)
PWL(t1 v1 t2 v2 ...)
PWL file=<filename>
PWL extras (LTspice-specific):
- Relative time:
PWL(0 1 +1 2 +1 3) — times become 0, 1, 2
- Repetition:
REPEAT FOR n (...) ENDREPEAT or REPEAT FOREVER (...) ENDREPEAT
- Scaling:
VALUE_SCALE_FACTOR=x, TIME_SCALE_FACTOR=x
- Trigger:
TRIGGER <expression> — output stuck at first value when expression is false
Directives
.tran 5m ; transient, 5ms stop
.tran 0 5m 0 10u ; tstep, tstop, tstart, tmaxstep
.tran 0 5m 0 10u startup ; LTspice-only: ramp sources from zero
.ac dec 200 10 100k ; AC sweep, 200pts/decade, 10Hz-100kHz
.dc V1 0 5 0.01 ; DC sweep V1, 0-5V, 10mV step
.op ; DC operating point
.noise V(out) V1 dec 200 10 100k ; noise analysis
.tf V(out) V1 ; DC transfer function
.include /path/to/model.lib ; include library
.ic V(node)=1.5 ; initial conditions (used with UIC)
.nodeset V(node)=1.5 ; hint for DC operating point solver
.ic forces node voltages at t=0 (use with .tran ... UIC). .nodeset is a suggestion to help the OP solver converge — the solver can override it. Mixing them up causes wrong initial states or convergence failures.
.MEAS Syntax
.meas TRAN vmax MAX V(out)
.meas TRAN vpp PP V(out)
.meas TRAN trise TRIG V(out) VAL=0.1 RISE=1 TARG V(out) VAL=0.9 RISE=1
.meas AC fc WHEN mag(V(out)/V(in))=0.707
.meas AC gain_1k FIND mag(V(out)) AT=1k
.meas TRAN avg_out AVG V(out) FROM=1m TO=5m
.meas TRAN energy INTEG V(out)*I(R1)
Important behavior:
- RISE/FALL/CROSS numbering starts at 1, not 0.
- If TRIG event never occurs, measurement silently fails (no error, no warning).
- Without
TD= parameter, TARG matches from t=0 — can hit wrong edge.
- AC measurements use 65k point ceiling — exceeding this silently reduces resolution.
- WHEN/AT measurements return the crossing time (.tran) or frequency (.ac) in the result's
at field; the headline values scalar is the constant target level, not the crossing point.
General notes
- Node "0" vs "00": Different nodes. Ground is
0 (or GND).
- Impedance ratios: Beyond ~1e16 cause numerical issues (64-bit doubles).
- Parameter sweep:
.step param <name> <start> <stop> <increment>
- Parameter list:
.step param <name> list <v1> <v2> ...
LTspice-Specific
Parameters and Expressions
.param Rval=10k
.param fc={1/(2*pi*R1*C1)}
.func myfn(x) {x*2}
- Component values referencing params must use braces:
R1 in out {Rval}
.param using other params must use braces: .param x={y*2}
.func body uses braces: .func myfn(x) {x*2}
- B source expressions: do not wrap the expression itself in curly braces — parameters inside B source expressions do use braces:
B1 out 0 V=V(in)*{Rval}
Behavioral Sources (B sources)
Four types:
B1 out 0 V=<expression> ; voltage source
B2 out 0 I=<expression> [Rpar=x] [Cpar=x] ; current source
B3 out 0 R=<expression> ; resistor (undocumented)
B4 out 0 P=<expression> [VprXover=x] ; power sink (undocumented)
Conditional: IF(cond, true, false), not ternary ?: (that's ngspice).
B source expressions must be single-line in schematics (netlists can use + continuation).
Operator precedence:
~, ! (boolean NOT)
** (exponentiation) — ^ is XOR except in Laplace expressions
*, /
+, -
==, >=, <=, >, < (comparisons → boolean)
^ (XOR), | (OR), & (AND)
Boolean: >0.5 is True, ≤0.5 is False.
Math functions:
- Trig:
sin, cos, tan, asin, acos, atan, atan2(y,x), hypot(y,x)
- Hyperbolic:
sinh, cosh, tanh, asinh, acosh, atanh
- Exp/log:
exp, ln, log (base e), log10
- Power:
sqrt, pow(x,y), pwr(x,y) (sign-preserving), pwrs(x,y), square
- Rounding:
round, int, floor, ceil
- Limits:
min, max, limit(x,lo,hi), uplim(x,pos,z), dnlim(x,neg,z)
- Logic:
buf, inv
- Lookup:
table(x,x1,y1,x2,y2,...) — monotonic x required
Time-domain functions:
ddt(x) — time derivative
idt(x[,ic[,assert]]) — integral; assert≠0 resets
sdt(x) — alternate integral
delay(x,y) — delay by y seconds
uramp(x) — ramp: x if x>0, else 0
u(x), stp(x) — unit step (undocumented)
Random: rand(x) (sharp), random(x) (smooth), white(x) (noise ±0.5)
Special variables: time, pi, boltz (1.38e-23), planck (6.63e-34), echarge (1.60e-19), kelvin (-273.15), Gmin (1e-12)
Laplace filter:
B1 out 0 V=V(in) Laplace=1/(1+s/{2*pi*fc})
In Laplace expressions, ^ means exponentiation (not XOR). Response must roll off at high frequencies.
Important behavior:
^ is XOR in normal expressions, exponentiation only in Laplace. Use ** for power.
R=<expr> behavioral resistor: value must never reach zero (causes convergence failure).
NoJacob flag exists but "greatly increases risk of convergence problems" — avoid.
Monte Carlo
LTspice has no built-in .mc directive — use .step + mc():
.step param run 1 100 1
R1 in out {mc(10k, 0.1)} ; uniform dist, 10k +/-10%
mc(nominal, tolerance) — uniform between nom*(1-tol) and nom*(1+tol).
Convergence
.options gmin=1e-10 ; min conductance on diode/transistor junctions
.options abstol=1e-10 ; absolute current tolerance (default 1e-12)
.options reltol=0.003 ; relative tolerance (never exceed 0.003)
.options cshunt=1e-15 ; capacitance from every node to ground
.options method=gear ; alternate integration method
Circuit design tips:
- p/n junctions should have some series resistance and parallel capacitance.
- Avoid strict ideal voltage sources — add realistic parasitics.
- Impedance ratios beyond 1e16 cause numerical issues.
- Be suspicious of circuits needing
cshunt — may indicate unrealistic models.
Hidden defaults (LTspice-specific):
Gfarad — default parallel conductance on capacitors (1e-12). Disable: .options Gfarad=0
DampInductors — default parallel resistance on inductors (ON). Disable: .options DampInductors=0
Gfloat — shunt conductance on floating nodes (1e-12 default)
- Inductor coupling factor K may be exactly
1.0 — the LTspice docs recommend starting at 1 to avoid leakage ringing; use a value just under 1 only if uic on .tran causes trouble at K=±1
.options Flags (LTspice-specific)
| Flag |
Effect |
List |
Dump flattened netlist to error log |
DampInductors=0|1 |
Toggle parallel inductor damping |
Thev_Induc=0|1 |
Toggle 1mOhm series inductor resistance |
Gfarad=<value> |
Capacitor default parallel conductance |
Gfloat=<value> |
Floating-node shunt conductance |
TopologyCheck=2 |
Beta circuit matrix optimizations |
baudrate=<rate> |
Enable eye diagram plotting |
Subcircuits
.subckt myfilter in out params: R=10k C=100n
R1 in out {R}
C1 out 0 {C}
.ends myfilter
.include <path> — include file contents verbatim.
.lib <path> — same as .include in LTspice (no section argument needed).
- Model aliasing:
.model 3904 ako: 2N3904 — inherit and override parameters.
- Model stepping:
.step param STM list 3904 2222 with Q1: {STM}.
Design workflow
Design and iterate over .cir netlists: plain text, no placement overhead, fast to edit and simulate. Build .asc schematics after the circuit design is final or when the user needs a schematic for review. Do not use the .asc tools for routine design iteration.
Device operating points (gm/gds/vth/…) work on both simulators for .op. On LTspice, put .op in the deck; the server adds .options logopinfo to LTspice .op runs (writing it yourself is harmless), and the operating_point recipe reads the log's Semiconductor Device Operating Points block, which LTspice writes only under that option and only for .op. On ngspice, .save @m1[gm] @m1[gds] (one parameter per bracket) puts them in the raw. operating_point reads both the same way via the m1.gm shorthand. A swept gm (the gm/ID sizing table from .dc + .save @m1[gm]) needs ngspice, because logopinfo is .op-only; on LTspice differentiate the drain current (d(Id(M1))) instead. See the ngspice skill and the spice://guide resource.
.asc Schematics
.asc files are structured text. Do not edit them by hand; use edit_schematic (or LTspice's GUI). It routes wires orthogonally and checks for pin collisions and wire junction overlaps. Start a new sheet with base="blank", place components with the add_component op, which returns placed pins, bounding box, and overlap warnings. The other mutations (move/remove a component, set an attribute, add or remove a net label, remove a wire) are ops on the same call, so batch them in one transaction.
Delegate the build when you can. Placement and wiring is detailed, mechanical work. Done inline alongside design work, it tends to end up as pins tagged with net labels instead of routed wires. If subagents are available, hand the schematic build to one whose only brief is the layout guidance in spice://guide: give it the final netlist, require edit_schematic (never a hand-written .asc), and have it verify before returning: verify_circuit against the source netlist, and inspect(kind="net") showing no multi-label shorts.
- Component attributes: Value, Value2, SpiceLine, SpiceLine2.
- Export to netlist for direct text editing when needed.
- Bus notation:
Data[0:7] creates 8 nets (cosmetic — netlister flattens to individual nets).
Common symbol pin offsets (at R0)
| Symbol |
Pins (name: x,y) |
Size (WxH) |
| nmos |
D:(48,0) G:(0,80) S:(48,96) |
48x96 |
| pmos |
D:(48,0) G:(0,80) S:(48,96) |
48x96 |
| voltage |
+:(0,16) -:(0,96) |
64x80 |
| current |
+:(0,0) -:(0,80) |
64x80 |
| res |
A:(16,16) B:(16,96) |
32x80 |
| cap |
A:(16,0) B:(16,64) |
32x64 |
Rotations transform pin (x,y) as: R90→(-y,x), R180→(-x,-y), R270→(y,-x), M0→(-x,y), M180→(x,-y). Use inspect(kind="symbol") for exact positions.
MOSFET orientation conventions
| Rotation |
Gate side |
D/S vertical |
Typical use |
| R0 |
Left |
D top, S bottom |
NMOS (drain up) |
| M0 |
Right |
D top, S bottom |
NMOS mirrored (symmetric diff pair) |
| M180 |
Left |
D bottom, S top |
PMOS (source to VDD at top) |
| R180 |
Right |
D bottom, S top |
PMOS mirrored (gate faces right) |
Choose orientation based on where the gate connects:
- Gate wire must not cross through the component's own body. Pick the rotation that puts the gate on the side facing the signal source.
- Example: if M3's gate connects to M5 on the right → use M0 (gate right), not R0 (gate left).
- For diff pairs: M1 at R0 (gate left, toward Vinp), M2 at M0 (gate right, toward Vinn).
- For PMOS current mirrors: M4a at R180 (gate right, toward center), M4b at M180 (gate left, toward center) — gates face each other.
- Use
inspect(kind="symbol") with the intended rotation to verify pin directions before placing.
Schematic layout best practices
Component placement:
- Tier alignment: Matched/mirrored transistors (diff pairs, current mirrors, bias mirrors) must share the same y-coordinate. Plan horizontal tiers: VDD rail → PMOS loads → diff pair → tail/bias → VSS.
- Drain/source alignment on each branch: Within a vertical branch (e.g., PMOS load stacked above NMOS input), position components so the drain pin of the upper device is on the same x-column as the drain pin of the lower device. This eliminates horizontal jogs between stacked transistors.
- Pin-to-rail alignment: Place voltage/current sources so their pins land directly on the rail they connect to — no wire through the source body. For a VDD source, position it so the
+ pin y-coordinate equals the VDD rail y-coordinate. Use inspect(kind="symbol") to compute the exact placement origin from the desired pin position (e.g., for voltage + at y=128, place origin at y=128-16=112).
- Minimum 128 units vertical spacing between pin levels of adjacent tiers (e.g., between PMOS drain y and NMOS drain y). This leaves room for horizontal buses and net labels between tiers. With MOSFET bbox height of 96, plan tier origins ~192 units apart.
- Bias circuit alignment: Bias devices (e.g., M5/Ibias) should share the y-level of their functional counterpart (e.g., M3 tail current source).
- Plan the full layout before placing: Decide VDD rail y, tier y-coordinates, and bus y-coordinates first. Verify that buses fit between bounding boxes of adjacent tiers. Use
inspect(kind="symbol") to check bbox extents at the intended rotation.
Wiring:
- All wires must be orthogonal — strictly horizontal or vertical. Never route diagonal wires. Use waypoints in
wire_pins for L-shaped or multi-segment routes.
- Horizontal buses must route outside all component bounding boxes. Use
inspect(kind="symbol") to check bbox extents. For PMOS M180 with bbox top at y=160, a gate bus at y=176 is inside the bbox — route at y=144 (between VDD rail and bbox top) instead. Plan bus y-coordinates before placing components.
- Vertical wires must not pass through component bodies to reach a bus. When connecting a drain to a horizontal bus, jog the wire horizontally outside the bbox first, then route vertically to the bus. Example for PMOS M180 diode connection: route drain (400,256) → right to (448,256) → up to (448,144) → along bus to label, not straight up through the body at x=400.
- Leave room for buses between tiers. The minimum 128-unit tier spacing must account for bounding box height plus bus clearance. For PMOS M180 (bbox height 96), if VDD rail is at y=128 and PMOS origins at y=288: bbox occupies y=192–288, bus fits at y=144–160 (between rail and bbox top).
- Heed
wire_pins warnings and errors: the tool refuses diagonal wires, pin collisions, and wire junction overlaps. Non-blocking warnings (long runs, bbox crossings) should still be addressed.
- Read the
wiring profile edit_schematic returns (pins_wired/pins_label_only out of pins_total). pins_label_only high with wire_segments near zero means you tagged pins with net-labels instead of drawing wires. That is a wiring list, not a routed schematic, and whether it connects as intended depends only on the label names, which the profile does not check. Draw wires with wire_pins for local nets; reserve net-labels for ground, power rails, and distant nets. Also heed the label_over_component warning (a net-label anchored inside a symbol's bounding box).
Ground and net labels:
- Local ground flags: Place a ground (
0) label directly at each grounded pin via an edit_schematic add_net_label op. Never route wires to a distant ground flag.
- One ground per pin: Each component's ground connection gets its own
add_net_label op at the pin's coordinates — do not share ground flags between components.
- Do not use
wire_pins with net:0 when multiple ground labels exist — the tool errors on ambiguous net references. Place ground flags directly at pin coordinates with an add_net_label op (net="0", pin="M3.S") — no wire needed when the flag is on the pin.
- Named nets (VDD, outp, etc.): Repeating the same net label at distant pins ties them together — the netlister merges same-name labels into one net (correct, not a short), and no routing is needed. Wire nearby pins with
wire_pins. Caveat: once a name carries duplicate labels, wire_pins with net:NAME is ambiguous — target a component pin (Ref.Pin) instead.
Sources:
- Voltage source polarity:
+ pin is at the top (smaller y), - at bottom. For VDD sources, + connects to the supply rail, - to ground.
- Current source direction: Current flows from
+ (top) to - (bottom) externally. Place with + on the higher-voltage rail.
Models:
- Model names must not collide with type keywords: Use
NMOS_3V3 not NMOS for .model names when the symbol Value is also a MOSFET type.
Other LTspice Quirks
- Unicode mu: LTspice replaces
u with Unicode mu (µ) in saved files. Can corrupt netlists on copy/paste.
startup keyword: LTspice-only in .tran. Ramps sources from zero. Not portable.
- A-devices (mixed-signal primitives like
SRflop, Counter, OTA): LTspice-proprietary.
*!LTspice: <directive>: Treated as a directive, not a comment — despite * prefix.
- Area multipliers: Undocumented
m=<value> works on R, Q, J in addition to documented devices.
- Capacitor multiplier:
x<number> instead of m=<number> (e.g., x2).
1---2name: ltspice3description: Use when writing or editing LTspice circuit netlists (.cir, .net, .sp), working with LTspice schematics (.asc), or interpreting simulation results (.raw, .log). Covers LTspice-specific SPICE syntax, behavioral sources, waveform sources, .MEAS, parameters, convergence, and the conditions that cause silent errors. Use this skill whenever the user mentions LTspice, circuit simulation, filter design, frequency response, transient analysis, or any SPICE netlist work targeting LTspice.4---56# LTspice Circuit Simulation Guide78## SPICE Fundamentals910### Netlist Structure1112```spice13* Title line (first line, always a comment)14<components>15<directives>16.END17```1819- `.END` must be last line. No statements after it.20- `+` at start of line continues previous statement.21- Comments: `*` (full line) or `;` (inline).2223### Component Syntax2425```26<ref> <node+> <node-> <value>27R1 in out 10k28C1 out 0 100n29V1 in 0 AC 1 PULSE(0 5 0 1n 1n 0.5m 1m)30```3132### Value Notation — CRITICAL3334| Suffix | Meaning | Value |35|-|-|-|36| f | femto | 1e-15 |37| p | pico | 1e-12 |38| n | nano | 1e-9 |39| u | micro | 1e-6 |40| m | milli | 1e-3 |41| k | kilo | 1e3 |42| MEG | mega | 1e6 |43| G | giga | 1e9 |44| T | tera | 1e12 |4546**`M` means milli, not mega. Use `MEG` for 1e6.**47`1M` = 0.001, not 1000000. Unrecognized suffix letters are silently ignored:48no error, just a wrong value.4950### Waveform Sources5152```spice53PULSE(Vinitial Vpulse Tdelay Trise Tfall Ton Tperiod Ncycles)54SINE(Voffset Vamp Freq Td Theta Phi Ncycles)55EXP(V1 V2 Td1 Tau1 Td2 Tau2)56SFFM(Voff Vamp Fcar MDI Fsig)57PWL(t1 v1 t2 v2 ...)58PWL file=<filename>59```6061**PWL extras (LTspice-specific):**62- Relative time: `PWL(0 1 +1 2 +1 3)` — times become 0, 1, 263- Repetition: `REPEAT FOR n (...) ENDREPEAT` or `REPEAT FOREVER (...) ENDREPEAT`64- Scaling: `VALUE_SCALE_FACTOR=x`, `TIME_SCALE_FACTOR=x`65- Trigger: `TRIGGER <expression>` — output stuck at first value when expression is false6667### Directives6869```spice70.tran 5m ; transient, 5ms stop71.tran 0 5m 0 10u ; tstep, tstop, tstart, tmaxstep72.tran 0 5m 0 10u startup ; LTspice-only: ramp sources from zero73.ac dec 200 10 100k ; AC sweep, 200pts/decade, 10Hz-100kHz74.dc V1 0 5 0.01 ; DC sweep V1, 0-5V, 10mV step75.op ; DC operating point76.noise V(out) V1 dec 200 10 100k ; noise analysis77.tf V(out) V1 ; DC transfer function78.include /path/to/model.lib ; include library79.ic V(node)=1.5 ; initial conditions (used with UIC)80.nodeset V(node)=1.5 ; hint for DC operating point solver81```8283`.ic` forces node voltages at t=0 (use with `.tran ... UIC`). `.nodeset` is a suggestion to help the OP solver converge — the solver can override it. Mixing them up causes wrong initial states or convergence failures.8485### .MEAS Syntax8687```spice88.meas TRAN vmax MAX V(out)89.meas TRAN vpp PP V(out)90.meas TRAN trise TRIG V(out) VAL=0.1 RISE=1 TARG V(out) VAL=0.9 RISE=191.meas AC fc WHEN mag(V(out)/V(in))=0.70792.meas AC gain_1k FIND mag(V(out)) AT=1k93.meas TRAN avg_out AVG V(out) FROM=1m TO=5m94.meas TRAN energy INTEG V(out)*I(R1)95```9697**Important behavior:**98- RISE/FALL/CROSS numbering starts at **1**, not 0.99- If TRIG event never occurs, measurement silently fails (no error, no warning).100- Without `TD=` parameter, TARG matches from t=0 — can hit wrong edge.101- AC measurements use **65k point ceiling** — exceeding this silently reduces resolution.102- WHEN/AT measurements return the crossing time (.tran) or frequency (.ac) in the result's `at` field; the headline `values` scalar is the constant target level, not the crossing point.103104### General notes105106- **Node "0" vs "00"**: Different nodes. Ground is `0` (or `GND`).107- **Impedance ratios**: Beyond ~1e16 cause numerical issues (64-bit doubles).108- **Parameter sweep**: `.step param <name> <start> <stop> <increment>`109- **Parameter list**: `.step param <name> list <v1> <v2> ...`110111---112113## LTspice-Specific114115### Parameters and Expressions116117```spice118.param Rval=10k119.param fc={1/(2*pi*R1*C1)}120.func myfn(x) {x*2}121```122123- Component values referencing params must use braces: `R1 in out {Rval}`124- `.param` using other params must use braces: `.param x={y*2}`125- `.func` body uses braces: `.func myfn(x) {x*2}`126- B source expressions: do not wrap the expression itself in curly braces — parameters inside B source expressions do use braces: `B1 out 0 V=V(in)*{Rval}`127128### Behavioral Sources (B sources)129130Four types:131132```spice133B1 out 0 V=<expression> ; voltage source134B2 out 0 I=<expression> [Rpar=x] [Cpar=x] ; current source135B3 out 0 R=<expression> ; resistor (undocumented)136B4 out 0 P=<expression> [VprXover=x] ; power sink (undocumented)137```138139**Conditional:** `IF(cond, true, false)`, not ternary `?:` (that's ngspice).140B source expressions must be single-line in schematics (netlists can use `+` continuation).141142**Operator precedence:**1431. `~`, `!` (boolean NOT)1442. `**` (exponentiation) — `^` is XOR except in Laplace expressions1453. `*`, `/`1464. `+`, `-`1475. `==`, `>=`, `<=`, `>`, `<` (comparisons → boolean)1486. `^` (XOR), `|` (OR), `&` (AND)149150Boolean: >0.5 is True, ≤0.5 is False.151152**Math functions:**153- Trig: `sin`, `cos`, `tan`, `asin`, `acos`, `atan`, `atan2(y,x)`, `hypot(y,x)`154- Hyperbolic: `sinh`, `cosh`, `tanh`, `asinh`, `acosh`, `atanh`155- Exp/log: `exp`, `ln`, `log` (base e), `log10`156- Power: `sqrt`, `pow(x,y)`, `pwr(x,y)` (sign-preserving), `pwrs(x,y)`, `square`157- Rounding: `round`, `int`, `floor`, `ceil`158- Limits: `min`, `max`, `limit(x,lo,hi)`, `uplim(x,pos,z)`, `dnlim(x,neg,z)`159- Logic: `buf`, `inv`160- Lookup: `table(x,x1,y1,x2,y2,...)` — monotonic x required161162**Time-domain functions:**163- `ddt(x)` — time derivative164- `idt(x[,ic[,assert]])` — integral; assert≠0 resets165- `sdt(x)` — alternate integral166- `delay(x,y)` — delay by y seconds167- `uramp(x)` — ramp: x if x>0, else 0168- `u(x)`, `stp(x)` — unit step (undocumented)169170**Random:** `rand(x)` (sharp), `random(x)` (smooth), `white(x)` (noise ±0.5)171172**Special variables:** `time`, `pi`, `boltz` (1.38e-23), `planck` (6.63e-34), `echarge` (1.60e-19), `kelvin` (-273.15), `Gmin` (1e-12)173174**Laplace filter:**175```spice176B1 out 0 V=V(in) Laplace=1/(1+s/{2*pi*fc})177```178In Laplace expressions, `^` means exponentiation (not XOR). Response must roll off at high frequencies.179180**Important behavior:**181- `^` is **XOR** in normal expressions, exponentiation only in Laplace. Use `**` for power.182- `R=<expr>` behavioral resistor: value must never reach zero (causes convergence failure).183- `NoJacob` flag exists but "greatly increases risk of convergence problems" — avoid.184185### Monte Carlo186187LTspice has no built-in `.mc` directive — use `.step` + `mc()`:188189```spice190.step param run 1 100 1191R1 in out {mc(10k, 0.1)} ; uniform dist, 10k +/-10%192```193194`mc(nominal, tolerance)` — uniform between `nom*(1-tol)` and `nom*(1+tol)`.195196### Convergence197198```spice199.options gmin=1e-10 ; min conductance on diode/transistor junctions200.options abstol=1e-10 ; absolute current tolerance (default 1e-12)201.options reltol=0.003 ; relative tolerance (never exceed 0.003)202.options cshunt=1e-15 ; capacitance from every node to ground203.options method=gear ; alternate integration method204```205206**Circuit design tips:**207- p/n junctions should have some series resistance and parallel capacitance.208- Avoid strict ideal voltage sources — add realistic parasitics.209- Impedance ratios beyond 1e16 cause numerical issues.210- Be suspicious of circuits needing `cshunt` — may indicate unrealistic models.211212**Hidden defaults (LTspice-specific):**213- `Gfarad` — default parallel conductance on capacitors (1e-12). Disable: `.options Gfarad=0`214- `DampInductors` — default parallel resistance on inductors (ON). Disable: `.options DampInductors=0`215- `Gfloat` — shunt conductance on floating nodes (1e-12 default)216- Inductor coupling factor K may be exactly `1.0` — the LTspice docs recommend starting at 1 to avoid leakage ringing; use a value just under 1 only if `uic` on `.tran` causes trouble at K=±1217218### .options Flags (LTspice-specific)219220| Flag | Effect |221|-|-|222| `List` | Dump flattened netlist to error log |223| `DampInductors=0\|1` | Toggle parallel inductor damping |224| `Thev_Induc=0\|1` | Toggle 1mOhm series inductor resistance |225| `Gfarad=<value>` | Capacitor default parallel conductance |226| `Gfloat=<value>` | Floating-node shunt conductance |227| `TopologyCheck=2` | Beta circuit matrix optimizations |228| `baudrate=<rate>` | Enable eye diagram plotting |229230### Subcircuits231232```spice233.subckt myfilter in out params: R=10k C=100n234R1 in out {R}235C1 out 0 {C}236.ends myfilter237```238239- `.include <path>` — include file contents verbatim.240- `.lib <path>` — same as .include in LTspice (no section argument needed).241- Model aliasing: `.model 3904 ako: 2N3904` — inherit and override parameters.242- Model stepping: `.step param STM list 3904 2222` with `Q1: {STM}`.243244### Design workflow245246**Design and iterate over `.cir` netlists**: plain text, no placement overhead, fast to edit and simulate. Build `.asc` schematics after the circuit design is final or when the user needs a schematic for review. Do not use the `.asc` tools for routine design iteration.247248**Device operating points (gm/gds/vth/…) work on both simulators for `.op`.** On LTspice, put `.op` in the deck; the server adds `.options logopinfo` to LTspice `.op` runs (writing it yourself is harmless), and the `operating_point` recipe reads the log's *Semiconductor Device Operating Points* block, which LTspice writes only under that option and only for `.op`. On ngspice, `.save @m1[gm] @m1[gds]` (one parameter per bracket) puts them in the raw. `operating_point` reads both the same way via the `m1.gm` shorthand. A **swept** gm (the gm/ID sizing table from `.dc` + `.save @m1[gm]`) needs ngspice, because `logopinfo` is `.op`-only; on LTspice differentiate the drain current (`d(Id(M1))`) instead. See the ngspice skill and the `spice://guide` resource.249250### .asc Schematics251252`.asc` files are structured text. Do not edit them by hand; use `edit_schematic` (or LTspice's GUI). It routes wires orthogonally and checks for pin collisions and wire junction overlaps. Start a new sheet with `base="blank"`, place components with the `add_component` op, which returns placed pins, bounding box, and overlap warnings. The other mutations (move/remove a component, set an attribute, add or remove a net label, remove a wire) are ops on the same call, so batch them in one transaction.253254**Delegate the build when you can.** Placement and wiring is detailed, mechanical work. Done inline alongside design work, it tends to end up as pins tagged with net labels instead of routed wires. If subagents are available, hand the schematic build to one whose only brief is the layout guidance in `spice://guide`: give it the final netlist, require `edit_schematic` (never a hand-written `.asc`), and have it verify before returning: `verify_circuit` against the source netlist, and `inspect(kind="net")` showing no multi-label shorts.255256- Component attributes: Value, Value2, SpiceLine, SpiceLine2.257- Export to netlist for direct text editing when needed.258- Bus notation: `Data[0:7]` creates 8 nets (cosmetic — netlister flattens to individual nets).259260#### Common symbol pin offsets (at R0)261262| Symbol | Pins (name: x,y) | Size (WxH) |263|-|-|-|264| nmos | D:(48,0) G:(0,80) S:(48,96) | 48x96 |265| pmos | D:(48,0) G:(0,80) S:(48,96) | 48x96 |266| voltage | +:(0,16) -:(0,96) | 64x80 |267| current | +:(0,0) -:(0,80) | 64x80 |268| res | A:(16,16) B:(16,96) | 32x80 |269| cap | A:(16,0) B:(16,64) | 32x64 |270271Rotations transform pin (x,y) as: R90→(-y,x), R180→(-x,-y), R270→(y,-x), M0→(-x,y), M180→(x,-y). Use `inspect(kind="symbol")` for exact positions.272273#### MOSFET orientation conventions274275| Rotation | Gate side | D/S vertical | Typical use |276|-|-|-|-|277| R0 | Left | D top, S bottom | NMOS (drain up) |278| M0 | Right | D top, S bottom | NMOS mirrored (symmetric diff pair) |279| M180 | Left | D bottom, S top | PMOS (source to VDD at top) |280| R180 | Right | D bottom, S top | PMOS mirrored (gate faces right) |281282**Choose orientation based on where the gate connects:**283- Gate wire must not cross through the component's own body. Pick the rotation that puts the gate on the side facing the signal source.284- Example: if M3's gate connects to M5 on the right → use M0 (gate right), not R0 (gate left).285- For diff pairs: M1 at R0 (gate left, toward Vinp), M2 at M0 (gate right, toward Vinn).286- For PMOS current mirrors: M4a at R180 (gate right, toward center), M4b at M180 (gate left, toward center) — gates face each other.287- Use `inspect(kind="symbol")` with the intended rotation to verify pin directions before placing.288289#### Schematic layout best practices290291**Component placement:**292- **Tier alignment**: Matched/mirrored transistors (diff pairs, current mirrors, bias mirrors) must share the same y-coordinate. Plan horizontal tiers: VDD rail → PMOS loads → diff pair → tail/bias → VSS.293- **Drain/source alignment on each branch**: Within a vertical branch (e.g., PMOS load stacked above NMOS input), position components so the drain pin of the upper device is on the same x-column as the drain pin of the lower device. This eliminates horizontal jogs between stacked transistors.294- **Pin-to-rail alignment**: Place voltage/current sources so their pins land directly on the rail they connect to — no wire through the source body. For a VDD source, position it so the `+` pin y-coordinate equals the VDD rail y-coordinate. Use `inspect(kind="symbol")` to compute the exact placement origin from the desired pin position (e.g., for voltage `+` at y=128, place origin at y=128-16=112).295- **Minimum 128 units vertical spacing between pin levels** of adjacent tiers (e.g., between PMOS drain y and NMOS drain y). This leaves room for horizontal buses and net labels between tiers. With MOSFET bbox height of 96, plan tier origins ~192 units apart.296- **Bias circuit alignment**: Bias devices (e.g., M5/Ibias) should share the y-level of their functional counterpart (e.g., M3 tail current source).297- **Plan the full layout before placing**: Decide VDD rail y, tier y-coordinates, and bus y-coordinates first. Verify that buses fit between bounding boxes of adjacent tiers. Use `inspect(kind="symbol")` to check bbox extents at the intended rotation.298299**Wiring:**300- **All wires must be orthogonal** — strictly horizontal or vertical. Never route diagonal wires. Use waypoints in `wire_pins` for L-shaped or multi-segment routes.301- **Horizontal buses must route outside all component bounding boxes.** Use `inspect(kind="symbol")` to check bbox extents. For PMOS M180 with bbox top at y=160, a gate bus at y=176 is inside the bbox — route at y=144 (between VDD rail and bbox top) instead. Plan bus y-coordinates before placing components.302- **Vertical wires must not pass through component bodies to reach a bus.** When connecting a drain to a horizontal bus, jog the wire horizontally outside the bbox first, then route vertically to the bus. Example for PMOS M180 diode connection: route drain (400,256) → right to (448,256) → up to (448,144) → along bus to label, not straight up through the body at x=400.303- **Leave room for buses between tiers.** The minimum 128-unit tier spacing must account for bounding box height plus bus clearance. For PMOS M180 (bbox height 96), if VDD rail is at y=128 and PMOS origins at y=288: bbox occupies y=192–288, bus fits at y=144–160 (between rail and bbox top).304- **Heed `wire_pins` warnings and errors**: the tool refuses diagonal wires, pin collisions, and wire junction overlaps. Non-blocking warnings (long runs, bbox crossings) should still be addressed.305- **Read the `wiring` profile `edit_schematic` returns** (`pins_wired`/`pins_label_only` out of `pins_total`). `pins_label_only` high with `wire_segments` near zero means you tagged pins with net-labels instead of drawing wires. That is a wiring list, not a routed schematic, and whether it connects as intended depends only on the label names, which the profile does not check. Draw wires with `wire_pins` for local nets; reserve net-labels for ground, power rails, and distant nets. Also heed the `label_over_component` warning (a net-label anchored inside a symbol's bounding box).306307**Ground and net labels:**308- **Local ground flags**: Place a ground (`0`) label directly at each grounded pin via an `edit_schematic` `add_net_label` op. Never route wires to a distant ground flag.309- **One ground per pin**: Each component's ground connection gets its own `add_net_label` op at the pin's coordinates — do not share ground flags between components.310- **Do not use `wire_pins` with `net:0`** when multiple ground labels exist — the tool errors on ambiguous net references. Place ground flags directly at pin coordinates with an `add_net_label` op (`net="0", pin="M3.S"`) — no wire needed when the flag is on the pin.311- **Named nets (VDD, outp, etc.)**: Repeating the same net label at distant pins ties them together — the netlister merges same-name labels into one net (correct, not a short), and no routing is needed. Wire nearby pins with `wire_pins`. Caveat: once a name carries duplicate labels, `wire_pins` with `net:NAME` is ambiguous — target a component pin (`Ref.Pin`) instead.312313**Sources:**314- **Voltage source polarity**: `+` pin is at the top (smaller y), `-` at bottom. For VDD sources, `+` connects to the supply rail, `-` to ground.315- **Current source direction**: Current flows from `+` (top) to `-` (bottom) externally. Place with `+` on the higher-voltage rail.316317**Models:**318- **Model names must not collide with type keywords**: Use `NMOS_3V3` not `NMOS` for `.model` names when the symbol Value is also a MOSFET type.319320### Other LTspice Quirks321322- **Unicode mu**: LTspice replaces `u` with Unicode mu (µ) in saved files. Can corrupt netlists on copy/paste.323- **`startup` keyword**: LTspice-only in `.tran`. Ramps sources from zero. Not portable.324- **A-devices** (mixed-signal primitives like `SRflop`, `Counter`, `OTA`): LTspice-proprietary.325- **`*!LTspice: <directive>`**: Treated as a directive, not a comment — despite `*` prefix.326- **Area multipliers**: Undocumented `m=<value>` works on R, Q, J in addition to documented devices.327- Capacitor multiplier: `x<number>` instead of `m=<number>` (e.g., `x2`).