Skip to content

Commit

Permalink
Add a simple MOSFET model
Browse files Browse the repository at this point in the history
  • Loading branch information
martinholters committed Feb 21, 2019
1 parent 2e40b10 commit 5eb39c6
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 3 deletions.
1 change: 1 addition & 0 deletions docs/src/elements.md
Expand Up @@ -26,6 +26,7 @@ currentprobe
```@docs
diode
bjt
mosfet
```

## Integrated Circuits
Expand Down
54 changes: 52 additions & 2 deletions src/elements.jl
@@ -1,9 +1,9 @@
# Copyright 2015, 2016, 2017, 2018 Martin Holters
# Copyright 2015, 2016, 2017, 2018, 2019 Martin Holters
# See accompanying license file.

export resistor, potentiometer, capacitor, inductor, transformer,
voltagesource, currentsource,
voltageprobe, currentprobe, diode, bjt, opamp
voltageprobe, currentprobe, diode, bjt, mosfet, opamp


"""
Expand Down Expand Up @@ -437,6 +437,56 @@ Pins: `base`, `emitter`, `collector`
pins = [:base; :emitter; :base; :collector])
end

@doc doc"""
mosfet(typ; vt=0.7, α=2e-5)
Creates a MOSFET transistor with the simple model
$i_D=\begin{cases}
0 & \text{if } v_{GS} \le v_T \\
\alpha \cdot (v_{GS} - v_T - \tfrac{1}{2}v_{DS})\cdot v_{DS}
& \text{if } v_{DS} \le v_{GS} - v_T \cap v_{GS} > v_T \\
\frac{\alpha}{2} \cdot (v_{GS} - v_T)^2 & \text{otherwise.}
\end{cases}$
The `typ` parameter chooses between NMOS (`:n`) and PMOS (`:p`). The threshold
voltage `vt` is given in Volt, `α` (in A/V²) in a constant depending on the
physics and dimensions of the device.
Pins: `gate`, `source`, `drain`
""" function mosfet(typ; vt=0.7, α=2e-5)
if typ == :n
polarity = 1
elseif typ == :p
polarity = -1
else
throw(ArgumentError("Unknown mosfet type $(typ), must be :n or :p"))
end
return Element(mv=[-1 0; 0 -1; 0 0; 0 0],
mi=[0 0; 0 0; 0 -1; 1 0],
mq=polarity*[1 0 0; 0 1 0; 0 0 1; 0 0 0],
u0=polarity*[-vt; 0; 0; 0],
pins=[:gate, :source, :drain, :source],
nonlinear_eq=quote
let vg=q[1], vds=q[2], id=q[3] # vg = vgs-vt
if vg <= 0
res[1] = -id
J[1,1] = 0
J[1,2] = 0
elseif vds <= vg
res[1] = $α * (vg-0.5*vds)*vds - id
J[1,1] = $α*vds
J[1,2] = $α * (vg-vds)
else # 0 < vg < vds
res[1] = $/2) * vg^2 - id
J[1,1] = $α*vg
J[1,2] = 0
end
J[1,3] = -1
end
end)
end

"""
opamp()
Expand Down
16 changes: 15 additions & 1 deletion test/runtests.jl
@@ -1,4 +1,4 @@
# Copyright 2015, 2016, 2017, 2018 Martin Holters
# Copyright 2015, 2016, 2017, 2018, 2019 Martin Holters
# See accompanying license file.

include("checklic.jl")
Expand Down Expand Up @@ -427,6 +427,20 @@ end
end
end

@testset "MOSFET" begin
for (typ, pol) in ((:n, 1), (:p, -1))
circ = @circuit begin
vgs = voltagesource(), [-] == gnd
vds = voltagesource(), [-] == gnd
J = mosfet(typ, vt=1, α=1e-4), [gate] == vgs[+], [drain] == vds[+]
out = currentprobe(), [+] == J[source], [-] == gnd
end
model = DiscreteModel(circ, 1);
y = run!(model, pol*[0 1 2 2 2; 5 5 0.5 1 1.5])
@test y == pol*[0 0 1e-4*(1-0.5/2)*0.5 1e-4*(1-1/2)*1 1e-4/2*1^2]
end
end

function checksteady!(model)
x_steady = steadystate!(model)
for s in model.solvers
Expand Down

0 comments on commit 5eb39c6

Please sign in to comment.