|
1 | | -# Copyright 2015, 2016, 2017, 2018, 2019 Martin Holters |
| 1 | +# Copyright 2015, 2016, 2017, 2018, 2019, 2020 Martin Holters |
2 | 2 | # See accompanying license file. |
3 | 3 |
|
4 | 4 | export resistor, potentiometer, capacitor, inductor, transformer, |
@@ -394,49 +394,75 @@ Pins: `base`, `emitter`, `collector` |
394 | 394 | end |
395 | 395 |
|
396 | 396 | @doc doc""" |
397 | | - mosfet(typ; vt=0.7, α=2e-5) |
| 397 | + mosfet(typ; vt=0.7, α=2e-5, λ=0) |
398 | 398 |
|
399 | 399 | Creates a MOSFET transistor with the simple model |
400 | 400 |
|
401 | 401 | $i_D=\begin{cases} |
402 | 402 | 0 & \text{if } v_{GS} \le v_T \\ |
403 | 403 | \alpha \cdot (v_{GS} - v_T - \tfrac{1}{2}v_{DS})\cdot v_{DS} |
| 404 | + \cdot (1 + \lambda v_{DS}) |
404 | 405 | & \text{if } v_{DS} \le v_{GS} - v_T \cap v_{GS} > v_T \\ |
405 | | - \frac{\alpha}{2} \cdot (v_{GS} - v_T)^2 & \text{otherwise.} |
| 406 | + \frac{\alpha}{2} \cdot (v_{GS} - v_T)^2 \cdot (1 + \lambda v_{DS}) |
| 407 | + & \text{otherwise.} |
406 | 408 | \end{cases}$ |
407 | 409 |
|
408 | 410 | The `typ` parameter chooses between NMOS (`:n`) and PMOS (`:p`). The threshold |
409 | | -voltage `vt` is given in Volt, `α` (in A/V²) in a constant depending on the |
410 | | -physics and dimensions of the device. |
| 411 | +voltage `vt` is given in Volt, `α` (in A/V²) is a constant depending on the |
| 412 | +physics and dimensions of the device, and `λ` (in V⁻¹) controls the channel |
| 413 | +length modulation. |
| 414 | +
|
| 415 | +Optionally, it is possible to specify tuples of coefficients for `vt` and `α`. |
| 416 | +These will be used as polynomials in $v_{GS}$ to determine $v_T$ and $\alpha$, |
| 417 | +respectively. E.g. with `vt=(0.7, 0.1, 0.02)`, the $v_{GS}$-dpendent threshold |
| 418 | +voltage $v_T = 0.7 + 0.1\cdot v_{GS} + 0.02\cdot v_{GS}^2$ will be used. |
411 | 419 |
|
412 | 420 | Pins: `gate`, `source`, `drain` |
413 | | -""" function mosfet(typ; vt=0.7, α=2e-5) |
| 421 | +""" function mosfet(typ; vt=0.7, α=2e-5, λ=0) |
414 | 422 | if typ == :n |
415 | 423 | polarity = 1 |
416 | 424 | elseif typ == :p |
417 | 425 | polarity = -1 |
418 | 426 | else |
419 | 427 | throw(ArgumentError("Unknown mosfet type $(typ), must be :n or :p")) |
420 | 428 | end |
421 | | - return Element(mv=[-1 0; 0 -1; 0 0; 0 0], |
422 | | - mi=[0 0; 0 0; 0 -1; 1 0], |
423 | | - mq=polarity*[1 0 0; 0 1 0; 0 0 1; 0 0 0], |
424 | | - u0=polarity*[-vt; 0; 0; 0], |
425 | | - ports=[:gate => :source, :drain => :source], |
426 | | - nonlinear_eq = @inline function (q) |
427 | | - vg, vds, id=q # vg = vgs-vt |
428 | | - if vg <= 0 |
429 | | - res = @SVector [-id] |
430 | | - J = @SMatrix [0.0 0.0 -1.0] |
431 | | - elseif vds <= vg |
432 | | - res = @SVector [α * (vg-0.5*vds)*vds - id] |
433 | | - J = @SMatrix [α*vds α*(vg-vds) -1.0] |
434 | | - else # 0 < vg < vds |
435 | | - res = @SVector [(α/2) * vg^2 - id] |
436 | | - J = @SMatrix [α*vg 0.0 -1.0] |
437 | | - end |
438 | | - return (res, J) |
439 | | - end) |
| 429 | + vt = (vt...,) |
| 430 | + α = (α...,) |
| 431 | + dvt = vt[2:end] .* (1:length(vt)-1...,) |
| 432 | + dα = α[2:end] .* (1:length(α)-1...,) |
| 433 | + let polarity = polarity, α = α, vt = vt |
| 434 | + return Element(mv=[-1 0; 0 -1; 0 0; 0 0], |
| 435 | + mi=[0 0; 0 0; 0 -1; 1 0], |
| 436 | + mq=polarity*[1 0 0; 0 1 0; 0 0 1; 0 0 0], |
| 437 | + ports=[:gate => :source, :drain => :source], |
| 438 | + nonlinear_eq = @inline function (q) |
| 439 | + vgs, vds, id = q |
| 440 | + α´ = evalpoly(polarity*vgs, α) |
| 441 | + if !isempty(dα) |
| 442 | + dα´_dvgs = evalpoly(polarity*vgs, dα) |
| 443 | + else |
| 444 | + dα´_dvgs = 0 |
| 445 | + end |
| 446 | + vt´ = evalpoly(polarity*vgs, vt) |
| 447 | + if !isempty(dvt) |
| 448 | + dvt´_dvgs = evalpoly(polarity*vgs, dvt) |
| 449 | + else |
| 450 | + dvt´_dvgs = 0 |
| 451 | + end |
| 452 | + λ´ = vds ≥ 0 ? λ : zero(λ) |
| 453 | + if vgs <= vt´ |
| 454 | + res = @SVector [-id] |
| 455 | + J = @SMatrix [0.0 0.0 -1.0] |
| 456 | + elseif vds <= vgs - vt´ # && vgs > vt´ |
| 457 | + res = @SVector [α´ * (vgs-vt´-0.5*vds)*vds*(1+λ´*vds) - id] |
| 458 | + J = @SMatrix [α´*(1-dvt´_dvgs)*vds*(1+λ´*vds) + dα´_dvgs * (vgs-vt´-0.5*vds)*vds*(1+λ´*vds) α´*(vgs-vt´+vds*(2*λ´*(vgs-vt´-0.75*vds)-1)) -1.0] |
| 459 | + else # 0 < vgs - vt´ < vds |
| 460 | + res = @SVector [(α´/2) * (vgs-vt´)^2*(1+λ´*vds) - id] |
| 461 | + J = @SMatrix [α´*(vgs-vt´)*(1-dvt´_dvgs)*(1+λ´*vds) + dα´_dvgs/2 * (vgs-vt´)^2*(1+λ´*vds) λ´*α´/2*(vgs-vt´)^2 -1.0] |
| 462 | + end |
| 463 | + return (res, J) |
| 464 | + end) |
| 465 | + end |
440 | 466 | end |
441 | 467 |
|
442 | 468 | @doc doc""" |
|
0 commit comments