Skip to content

Commit eb98b8f

Browse files
Add LAPLACE Transfer Sources documentation and update references in existing articles
1 parent 328aaae commit eb98b8f

7 files changed

Lines changed: 372 additions & 2 deletions

File tree

src/docs/articles/behavioral-source.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,5 @@ SpiceSharpParser supports these analog behavioral modeling constructs:
6161
`LAPLACE` support is currently limited to `E` and `G` voltage-controlled sources with `V(node)` or `V(node1,node2)` input. `B`, `F`, `H`, function-like `VALUE={LAPLACE(...)}` syntax, `M=`, `TD=`, and `DELAY=` are not supported yet.
6262

6363
`M=` is a multiplier on sources/devices where supported, usually equivalent to multiple parallel instances or a scaled effective contribution. For LAPLACE sources, put that factor directly in `H(s)` for now.
64+
65+
For the transfer-function math, DC gain, frequency response, and worked examples, see [LAPLACE Transfer Sources](laplace.md).

src/docs/articles/intro.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,5 +102,5 @@ SpiceSharpParser supports a comprehensive set of SPICE statements and devices. S
102102
- **Parameters**: `.PARAM`, `.FUNC`, `.LET`, `.SPARAM`
103103
- **Circuit structure**: `.SUBCKT`, `.INCLUDE`, `.LIB`, `.GLOBAL`
104104
- **Simulation control**: `.STEP`, `.MC`, `.TEMP`, `.OPTIONS`, `.IC`, `.NODESET`
105-
- **Behavioral modeling**: `VALUE`, `TABLE`, `POLY(n)`, `B` sources, `E`/`G` source `LAPLACE`
105+
- **Behavioral modeling**: `VALUE`, `TABLE`, `POLY(n)`, `B` sources, `E`/`G` source `LAPLACE`; see [LAPLACE Transfer Sources](laplace.md)
106106
- **Devices**: R, L, C, K, D, Q, M, J, V, I, E, F, G, H, B, S, W, T, X

src/docs/articles/laplace.md

Lines changed: 362 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,362 @@
1+
# LAPLACE Transfer Sources
2+
3+
`LAPLACE` sources model a linear transfer function in the Laplace domain. They are useful when you know the desired gain, poles, zeros, or filter response and want to describe it directly instead of building the same behavior from resistors, capacitors, inductors, or op-amp subcircuits.
4+
5+
SpiceSharpParser supports voltage-controlled `E` and `G` source LAPLACE forms.
6+
7+
## Mental Model
8+
9+
A LAPLACE source applies a transfer function to an input signal:
10+
11+
```text
12+
Y(s) = H(s) * X(s)
13+
H(s) = N(s) / D(s)
14+
```
15+
16+
Where:
17+
18+
| Term | Meaning |
19+
|------|---------|
20+
| `s` | Laplace-domain variable |
21+
| `X(s)` | Input signal in the Laplace domain |
22+
| `Y(s)` | Output signal in the Laplace domain |
23+
| `H(s)` | Transfer function |
24+
| `N(s)` | Numerator polynomial |
25+
| `D(s)` | Denominator polynomial |
26+
27+
For DC operating point analysis, the source is evaluated at:
28+
29+
```text
30+
s = 0
31+
```
32+
33+
For AC frequency analysis at frequency `f` in hertz, the source is evaluated at:
34+
35+
```text
36+
s = j * omega
37+
omega = 2 * pi * f
38+
```
39+
40+
So the frequency response is:
41+
42+
```text
43+
H(j * omega)
44+
```
45+
46+
This value is complex. Its magnitude tells you the gain at that frequency, and its angle tells you the phase shift.
47+
48+
## Supported Syntax
49+
50+
The supported input expression is a voltage probe:
51+
52+
```spice
53+
V(node)
54+
V(node1,node2)
55+
```
56+
57+
`V(node)` means `V(node,0)`. `V(node1,node2)` means the differential voltage `V(node1) - V(node2)`.
58+
59+
### E Source
60+
61+
An `E` LAPLACE source is a voltage-controlled voltage source:
62+
63+
```text
64+
V(out+,out-) = H(s) * V(ctrl+,ctrl-)
65+
```
66+
67+
Supported spellings:
68+
69+
```spice
70+
E<name> <out+> <out-> LAPLACE {V(<ctrl+>)} = {<transfer>}
71+
E<name> <out+> <out-> LAPLACE {V(<ctrl+>)} {<transfer>}
72+
E<name> <out+> <out-> LAPLACE = {V(<ctrl+>)} {<transfer>}
73+
E<name> <out+> <out-> LAPLACE {V(<ctrl+>,<ctrl->)} = {<transfer>}
74+
```
75+
76+
### G Source
77+
78+
A `G` LAPLACE source is a voltage-controlled current source:
79+
80+
```text
81+
I(out+ -> out-) = H(s) * V(ctrl+,ctrl-)
82+
```
83+
84+
For a grounded load resistor connected from `out` to `0`, a positive transconductance usually produces a negative output voltage because the source current is defined from `out+` to `out-`:
85+
86+
```text
87+
V(out) = -Iout * Rload
88+
```
89+
90+
Supported spellings:
91+
92+
```spice
93+
G<name> <out+> <out-> LAPLACE {V(<ctrl+>)} = {<transfer>}
94+
G<name> <out+> <out-> LAPLACE {V(<ctrl+>)} {<transfer>}
95+
G<name> <out+> <out-> LAPLACE = {V(<ctrl+>)} {<transfer>}
96+
G<name> <out+> <out-> LAPLACE {V(<ctrl+>,<ctrl->)} = {<transfer>}
97+
```
98+
99+
## Transfer Polynomials
100+
101+
The transfer expression must be a rational polynomial in `s`:
102+
103+
```text
104+
H(s) = (b0 + b1*s + b2*s^2 + ...) / (a0 + a1*s + a2*s^2 + ...)
105+
```
106+
107+
SpiceSharpParser stores coefficients in ascending powers of `s`:
108+
109+
```text
110+
1 + s*tau -> [1, tau]
111+
s^2 + 1 -> [1, 0, 1]
112+
wc / (s + wc) -> numerator [wc], denominator [wc, 1]
113+
```
114+
115+
The transfer must be proper: the numerator degree cannot be greater than the denominator degree. This keeps the source physically usable by the runtime transfer-function behavior.
116+
117+
The DC gain is found by setting `s = 0`:
118+
119+
```text
120+
H(0) = N(0) / D(0)
121+
```
122+
123+
Examples:
124+
125+
```text
126+
1/(1+s*tau) -> H(0) = 1
127+
wc/(s+wc) -> H(0) = 1
128+
s/(s+wc) -> H(0) = 0
129+
10*wc/(s+wc) -> H(0) = 10
130+
```
131+
132+
Transfers with singular DC gain, such as `1/s`, are rejected.
133+
134+
## Magnitude And Phase
135+
136+
For AC analysis, substitute `s = j*omega`:
137+
138+
```text
139+
H(j*omega) = real + j*imag
140+
```
141+
142+
Magnitude:
143+
144+
```text
145+
|H(j*omega)| = sqrt(real^2 + imag^2)
146+
```
147+
148+
Phase:
149+
150+
```text
151+
phase = atan2(imag, real)
152+
```
153+
154+
### Low-Pass Example
155+
156+
First-order low-pass:
157+
158+
```text
159+
H(s) = 1 / (1 + s*tau)
160+
```
161+
162+
The cutoff frequency is:
163+
164+
```text
165+
fc = 1 / (2*pi*tau)
166+
wc = 2*pi*fc = 1/tau
167+
```
168+
169+
At cutoff:
170+
171+
```text
172+
H(j*wc) = 1 / (1 + j)
173+
= 0.5 - j*0.5
174+
|H| = 1 / sqrt(2)
175+
phase = -pi/4
176+
```
177+
178+
Equivalent form:
179+
180+
```text
181+
H(s) = wc / (s + wc)
182+
```
183+
184+
### High-Pass Example
185+
186+
First-order high-pass:
187+
188+
```text
189+
H(s) = s / (s + wc)
190+
```
191+
192+
At cutoff:
193+
194+
```text
195+
H(j*wc) = j / (1 + j)
196+
= 0.5 + j*0.5
197+
|H| = 1 / sqrt(2)
198+
phase = +pi/4
199+
```
200+
201+
## Worked Examples
202+
203+
### Unity Low-Pass E Source
204+
205+
```spice
206+
* Unity DC gain, one-pole low-pass
207+
.PARAM tau=1u
208+
VIN IN 0 1
209+
ELOW OUT 0 LAPLACE {V(IN)} = {1/(1+s*tau)}
210+
RLOAD OUT 0 1k
211+
.OP
212+
.SAVE V(OUT)
213+
.END
214+
```
215+
216+
At `.OP`, `s = 0`, so:
217+
218+
```text
219+
H(0) = 1/(1+0*tau) = 1
220+
V(OUT) = 1 * V(IN) = 1 V
221+
```
222+
223+
### Parameterized Low-Pass AC Response
224+
225+
```spice
226+
* Cutoff at 1 kHz
227+
.PARAM fc=1k
228+
.PARAM wc={2*PI*fc}
229+
VIN IN 0 AC 1
230+
ELOW OUT 0 LAPLACE {V(IN)} = {wc/(s+wc)}
231+
RLOAD OUT 0 1k
232+
.AC DEC 20 10 100k
233+
.MEAS AC vm_fc FIND VM(OUT) AT=1k
234+
.MEAS AC vp_fc FIND VP(OUT) AT=1k
235+
.END
236+
```
237+
238+
At `f = fc`, expect:
239+
240+
```text
241+
VM(OUT) ~= 0.707
242+
VP(OUT) ~= -pi/4 ~= -0.785
243+
```
244+
245+
### High-Pass AC Response
246+
247+
```spice
248+
.PARAM fc=1k
249+
.PARAM wc={2*PI*fc}
250+
VIN IN 0 AC 1
251+
EHIGH OUT 0 LAPLACE {V(IN)} = {s/(s+wc)}
252+
RLOAD OUT 0 1k
253+
.AC DEC 20 10 100k
254+
.MEAS AC vm_fc FIND VM(OUT) AT=1k
255+
.MEAS AC vp_fc FIND VP(OUT) AT=1k
256+
.END
257+
```
258+
259+
At `f = fc`, expect:
260+
261+
```text
262+
VM(OUT) ~= 0.707
263+
VP(OUT) ~= +pi/4 ~= +0.785
264+
```
265+
266+
### Inverting Low-Pass
267+
268+
```spice
269+
.PARAM gain=10
270+
.PARAM fc=1k
271+
.PARAM wc={2*PI*fc}
272+
VIN IN 0 AC 1
273+
EINV OUT 0 LAPLACE {V(IN)} = {-gain*wc/(s+wc)}
274+
RLOAD OUT 0 1k
275+
.AC DEC 20 10 100k
276+
.END
277+
```
278+
279+
At DC:
280+
281+
```text
282+
H(0) = -gain
283+
```
284+
285+
The negative sign adds 180 degrees of phase inversion to the low-pass response.
286+
287+
### G Source Through A Load
288+
289+
```spice
290+
* 1 mS low-pass transconductance into a 1 k load
291+
.PARAM gm=1m
292+
.PARAM tau=1u
293+
VIN IN 0 1
294+
GLOW OUT 0 LAPLACE {V(IN)} = {gm/(1+s*tau)}
295+
RLOAD OUT 0 1k
296+
.OP
297+
.SAVE V(OUT)
298+
.END
299+
```
300+
301+
At `.OP`:
302+
303+
```text
304+
Iout = gm * V(IN) = 1m * 1 = 1 mA
305+
V(OUT) = -Iout * RLOAD = -1m * 1k = -1 V
306+
```
307+
308+
The negative voltage comes from the current direction of the `G` source and the grounded load.
309+
310+
### Differential Input
311+
312+
```spice
313+
VINP INP 0 2
314+
VINN INN 0 0.5
315+
EDIFF OUT 0 LAPLACE {V(INP,INN)} = {1/(1+s*1u)}
316+
RLOAD OUT 0 1k
317+
.OP
318+
.SAVE V(OUT)
319+
.END
320+
```
321+
322+
At `.OP`:
323+
324+
```text
325+
V(INP,INN) = V(INP) - V(INN) = 1.5 V
326+
H(0) = 1
327+
V(OUT) = 1.5 V
328+
```
329+
330+
## Equivalent Supported Spellings
331+
332+
These three lines are equivalent:
333+
334+
```spice
335+
E1 OUT 0 LAPLACE {V(IN)} = {1/(1+s*1u)}
336+
E1 OUT 0 LAPLACE {V(IN)} {1/(1+s*1u)}
337+
E1 OUT 0 LAPLACE = {V(IN)} {1/(1+s*1u)}
338+
```
339+
340+
The same spelling variants are supported for `G` sources.
341+
342+
## Common Mistakes
343+
344+
| Mistake | Why it fails | Use instead |
345+
|---------|--------------|-------------|
346+
| `1/s` | Singular DC gain at `s = 0` | Use a finite DC-gain transfer |
347+
| `s` | Improper transfer: numerator order is greater than denominator order | Use `s/(s+wc)` |
348+
| `sin(s)` | Not a rational polynomial in `s` | Use polynomial/rational expressions only |
349+
| `V(a)-V(b)` | Input expression shape is unsupported | Use `V(a,b)` |
350+
| `I(Vsense)` | Current-controlled LAPLACE is not supported yet | Use supported `E`/`G` voltage input forms |
351+
| `M=2` | LAPLACE multiplier option is not supported yet | Put the multiplier in `H(s)`, for example `{2/(1+s*tau)}` |
352+
| `TD=1n` or `DELAY=1n` | Delay syntax is not supported yet | Omit delay |
353+
| `VALUE={LAPLACE(...)}` | Function-like LAPLACE syntax is not supported yet | Use source-level `E`/`G ... LAPLACE ...` |
354+
355+
## Current Limitations
356+
357+
- Only `E` and `G` voltage-controlled LAPLACE sources are supported.
358+
- Only `V(node)` and `V(node1,node2)` input expressions are supported.
359+
- `B`, `F`, and `H` LAPLACE forms are not supported yet.
360+
- Function-like `VALUE={LAPLACE(...)}` syntax is not supported yet.
361+
- `M=`, `TD=`, `DELAY=`, and explicit internal-state options are not supported yet.
362+
- Transfers must be finite, proper rational polynomials in `s` with non-singular DC gain.

src/docs/articles/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@
9797
href: ccvs.md
9898
- name: B — Behavioral Source
9999
href: behavioral-source.md
100+
- name: LAPLACE Transfer Sources
101+
href: laplace.md
100102

101103
- name: Semiconductors
102104
items:

src/docs/articles/vccs.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ Current limitations:
6363

6464
For LAPLACE sources, `M=` is recognized but not supported yet. Until it is implemented, put the multiplier directly in the transfer expression, for example `{m*gm*wc/(s+wc)}`.
6565

66+
For the transfer-function math, current-source sign convention, frequency response, and phase examples, see [LAPLACE Transfer Sources](laplace.md).
67+
6668
## Examples
6769

6870
```spice

0 commit comments

Comments
 (0)