From d93c0cba5f4bf1c4dc7b2474de76fe08e4d514f7 Mon Sep 17 00:00:00 2001 From: Martin Holters Date: Tue, 17 Dec 2019 15:39:08 +0100 Subject: [PATCH 1/8] Reflect that Julia 1.0 is the minimum required version in docs (#11) The README and the Getting started section still recommended at least version 0.6, but current ACME requires at least 1.0. --- README.md | 2 +- docs/src/gettingstarted.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7659289d..cddf9aa3 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Schematics"](http://www.eurasip.org/Proceedings/Eusipco/Eusipco2015/papers/15701 ## Installation If you have not done so already, [download and install -Julia](http://julialang.org/downloads/). (Any version starting with 0.6 should +Julia](http://julialang.org/downloads/). (Any version starting with 1.0 should be fine; earlier ACME versions support Julia starting with version 0.3.) To install ACME, start Julia and run: diff --git a/docs/src/gettingstarted.md b/docs/src/gettingstarted.md index 8fc198ef..0c6417d3 100644 --- a/docs/src/gettingstarted.md +++ b/docs/src/gettingstarted.md @@ -3,7 +3,7 @@ ## Installation If you have not done so already, [download and install -Julia](http://julialang.org/downloads/). (Any version starting with 0.6 should +Julia](http://julialang.org/downloads/). (Any version starting with 1.0 should be fine; earlier ACME versions also support Julia 0.3 and later.) To install ACME, start Julia and run: From 77c55deec210d7288c055c79d8aa6dbb5ddb7cac Mon Sep 17 00:00:00 2001 From: Martin Holters Date: Tue, 17 Dec 2019 16:17:45 +0100 Subject: [PATCH 2/8] Bump Documenter and add ACME to docs project (#12) * Bump Documenter to 0.24.3 * Add ACME (and dependencies) to docs/Project.toml and docs/Manifest.toml Instead of issuing a `Pkg.develop` on CI, commit the result, but with relative path and without version. Note that the dependencies still need to be updated manually every once in a while. --- .travis.yml | 2 +- docs/Manifest.toml | 57 +++++++++++++++++++++++++++++++++++----------- docs/Project.toml | 3 ++- 3 files changed, 47 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index a8e1d98f..e1bd7afd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ jobs: stage: "Documentation" julia: 1.0 script: - - julia --project=docs/ -e 'using Pkg; Pkg.instantiate(); Pkg.develop(PackageSpec(path=pwd()))' + - julia --project=docs/ -e 'using Pkg; Pkg.instantiate()' - julia --project=docs/ docs/make.jl - <<: *docs julia: 1.1 diff --git a/docs/Manifest.toml b/docs/Manifest.toml index bfdcca24..3629e36f 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -1,3 +1,8 @@ +[[ACME]] +deps = ["IterTools", "LinearAlgebra", "Markdown", "OrderedCollections", "ProgressMeter", "SparseArrays", "StaticArrays", "Statistics"] +path = ".." +uuid = "ca8b7239-ccd3-5cce-807f-2072f3f0d108" + [[Base64]] uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" @@ -10,26 +15,26 @@ deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" [[DocStringExtensions]] -git-tree-sha1 = "0513f1a8991e9d83255e0140aace0d0fc4486600" +deps = ["LibGit2", "Markdown", "Pkg", "Test"] +git-tree-sha1 = "88bb0edb352b16608036faadcc071adda068582a" uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.8.0" - - [DocStringExtensions.deps] - LibGit2 = "76f85450-5226-5b5a-8eaa-529ad045b433" - Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a" - Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" - Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +version = "0.8.1" [[Documenter]] -deps = ["Base64", "DocStringExtensions", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "REPL", "Test", "Unicode"] -git-tree-sha1 = "1b6ae3796f60311e39cd1770566140d2c056e87f" +deps = ["Base64", "Dates", "DocStringExtensions", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "REPL", "Test", "Unicode"] +git-tree-sha1 = "885467cebde4639a3d81953652cc53ff5a73cb87" uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "0.23.3" +version = "0.24.3" [[InteractiveUtils]] deps = ["LinearAlgebra", "Markdown"] uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +[[IterTools]] +git-tree-sha1 = "05110a2ab1fc5f932622ffea2a003221f4782c18" +uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +version = "1.3.0" + [[JSON]] deps = ["Dates", "Mmap", "Parsers", "Unicode"] git-tree-sha1 = "b34d7cef7b337321e97d22242c3c2b91f476748e" @@ -56,11 +61,17 @@ uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" [[Mmap]] uuid = "a63ad114-7e13-5084-954f-fe012c677804" +[[OrderedCollections]] +deps = ["Random", "Serialization", "Test"] +git-tree-sha1 = "c4c13474d23c60d20a67b217f1d7f22a40edf8f1" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.1.0" + [[Parsers]] deps = ["Dates", "Test"] -git-tree-sha1 = "ef0af6c8601db18c282d092ccbd2f01f3f0cd70b" +git-tree-sha1 = "0139ba59ce9bc680e2925aec5b7db79065d60556" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "0.3.7" +version = "0.3.10" [[Pkg]] deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] @@ -70,6 +81,12 @@ uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" deps = ["Unicode"] uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" +[[ProgressMeter]] +deps = ["Distributed", "Printf"] +git-tree-sha1 = "ea1f4fa0ff5e8b771bf130d87af5b7ef400760bd" +uuid = "92933f4c-e287-5a05-a399-4b506db050ca" +version = "1.2.0" + [[REPL]] deps = ["InteractiveUtils", "Markdown", "Sockets"] uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" @@ -87,6 +104,20 @@ uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" [[Sockets]] uuid = "6462fe0b-24de-5631-8697-dd941f90decc" +[[SparseArrays]] +deps = ["LinearAlgebra", "Random"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[StaticArrays]] +deps = ["LinearAlgebra", "Random", "Statistics"] +git-tree-sha1 = "5a3bcb6233adabde68ebc97be66e95dcb787424c" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "0.12.1" + +[[Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + [[Test]] deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/docs/Project.toml b/docs/Project.toml index 1c87e8fc..029216c1 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,5 +1,6 @@ [deps] +ACME = "ca8b7239-ccd3-5cce-807f-2072f3f0d108" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" [compat] -Documenter = "=0.23.3" +Documenter = "=0.24.3" From d2baf72049665e01d3f2df58500735792cb65b26 Mon Sep 17 00:00:00 2001 From: Julia TagBot <50554310+JuliaTagBot@users.noreply.github.com> Date: Sun, 9 Feb 2020 01:39:15 +0700 Subject: [PATCH 3/8] Install TagBot as a GitHub Action (#15) --- .github/workflows/TagBot.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .github/workflows/TagBot.yml diff --git a/.github/workflows/TagBot.yml b/.github/workflows/TagBot.yml new file mode 100644 index 00000000..d77d3a0c --- /dev/null +++ b/.github/workflows/TagBot.yml @@ -0,0 +1,11 @@ +name: TagBot +on: + schedule: + - cron: 0 * * * * +jobs: + TagBot: + runs-on: ubuntu-latest + steps: + - uses: JuliaRegistries/TagBot@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} From 6ae1e2036f92cd9449e0e3b90f28d6f918b99798 Mon Sep 17 00:00:00 2001 From: Martin Holters Date: Thu, 20 Feb 2020 17:42:06 +0100 Subject: [PATCH 4/8] Add Github action for CompatHelper (#16) --- .github/workflows/compathelper.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/workflows/compathelper.yml diff --git a/.github/workflows/compathelper.yml b/.github/workflows/compathelper.yml new file mode 100644 index 00000000..cd20a0d8 --- /dev/null +++ b/.github/workflows/compathelper.yml @@ -0,0 +1,19 @@ +name: CompatHelper + +on: + schedule: + - cron: '0 0 * * *' + +jobs: + CompatHelper: + runs-on: ubuntu-latest + steps: + - uses: julia-actions/setup-julia@v1 + with: + version: 1.3 + - name: Pkg.add("CompatHelper") + run: julia -e 'using Pkg; Pkg.add("CompatHelper")' + - name: CompatHelper.main() + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: julia -e 'using CompatHelper; CompatHelper.main()' From 5a016fb85988e0f27c2ac98040f726769f9f4317 Mon Sep 17 00:00:00 2001 From: Martin Holters Date: Fri, 28 Feb 2020 09:12:30 +0100 Subject: [PATCH 5/8] Fix usage of outdated Julia syntax in README.md (#19) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cddf9aa3..c053d658 100644 --- a/README.md +++ b/README.md @@ -109,7 +109,7 @@ row per input (just one in the example) and one column per sample. So for a sinusoid at 1 kHz lasting one second, we do ```Julia -y = run!(model, sin(2π*1000/44100*(0:44099).')) +y = run!(model, [sin(2π*1000/44100*n) for c in 1:1, n in 0:44099]) ``` The output `y` now likewise is a matrix with one row for the one probe we have From 59016e4c93092c2db3ea6d9cadb5824c947506f7 Mon Sep 17 00:00:00 2001 From: Martin Holters Date: Fri, 28 Feb 2020 11:29:48 +0100 Subject: [PATCH 6/8] Build documentation using a Github action (#20) Replace the Travis configuration for documentation building with a Github action. --- .github/workflows/Documentation.yml | 32 +++++++++++++++++++++++++++++ .travis.yml | 16 --------------- 2 files changed, 32 insertions(+), 16 deletions(-) create mode 100644 .github/workflows/Documentation.yml diff --git a/.github/workflows/Documentation.yml b/.github/workflows/Documentation.yml new file mode 100644 index 00000000..3abfa993 --- /dev/null +++ b/.github/workflows/Documentation.yml @@ -0,0 +1,32 @@ +name: Documentation + +on: + push: + branches: + - develop + tags: '*' + pull_request: + +jobs: + build: + name: build on Julia ${{ matrix.julia-version }} + runs-on: ubuntu-latest + strategy: + matrix: + julia-version: ['1.0', '1.1', '1.2', '1.3', 'nightly'] + steps: + - uses: actions/checkout@v2 + - uses: julia-actions/setup-julia@v1 + with: + version: ${{ matrix.julia-version }} + - name: Install dependencies + run: julia --project=docs -e 'using Pkg; Pkg.instantiate()' + - name: Build and deploy + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # For authentication with GitHub Actions token + DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} # For authentication with SSH deploy key + run: julia --project=docs/ docs/make.jl + - uses: actions/upload-artifact@v1 + with: + name: docs + path: docs/build diff --git a/.travis.yml b/.travis.yml index e1bd7afd..64cbabe4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,19 +15,3 @@ notifications: on_start: never codecov: true coveralls: true -jobs: - include: - - &docs - stage: "Documentation" - julia: 1.0 - script: - - julia --project=docs/ -e 'using Pkg; Pkg.instantiate()' - - julia --project=docs/ docs/make.jl - - <<: *docs - julia: 1.1 - - <<: *docs - julia: 1.2 - - <<: *docs - julia: 1.3 - - <<: *docs - julia: nightly From 41641a5d826e8015ba5386ecab0abca2bf4f7729 Mon Sep 17 00:00:00 2001 From: Martin Holters Date: Fri, 6 Mar 2020 09:31:16 +0100 Subject: [PATCH 7/8] Add a Github CI action (#13) --- .github/workflows/ci.yml | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..ffd5ecf5 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,35 @@ +name: CI + +on: + push: + branches: + - develop + - master + tags: '*' + pull_request: + +jobs: + test: + name: Test on Julia ${{ matrix.julia-version }} - ${{ matrix.os }} - ${{ matrix.julia-arch }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + julia-version: ['1.0', '1.1', '1.2', '1.3', 'nightly'] + julia-arch: [x64, x86] + os: [ubuntu-latest, windows-latest, macOS-latest] + exclude: + - os: macOS-latest + julia-arch: x86 + steps: + - uses: actions/checkout@v1.0.0 + - uses: julia-actions/setup-julia@v1.0.1 + with: + version: ${{ matrix.julia-version }} + arch: ${{ matrix.julia-arch }} + - uses: julia-actions/julia-runtest@v0.1.0 + - uses: julia-actions/julia-uploadcodecov@v0.1.0 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + - uses: julia-actions/julia-uploadcoveralls@v0.1.0 + env: + COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }} From 3832ccafb952ee2ca0a27286c091d613062c23fd Mon Sep 17 00:00:00 2001 From: Martin Holters Date: Tue, 10 Mar 2020 16:37:16 +0100 Subject: [PATCH 8/8] Extend MOSFET model (#21) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Include channel length modulation and allow `vt` and `α` to vary with the gate-source voltage by specifying polynomial coefficients. Co-authored-by: Lasse Köper --- Project.toml | 2 ++ docs/Manifest.toml | 16 +++++++++- src/ACME.jl | 3 +- src/elements.jl | 76 +++++++++++++++++++++++++++++++--------------- test/runtests.jl | 25 ++++++++++++++- 5 files changed, 94 insertions(+), 28 deletions(-) diff --git a/Project.toml b/Project.toml index 2ee0b813..52ef20aa 100644 --- a/Project.toml +++ b/Project.toml @@ -3,6 +3,7 @@ uuid = "ca8b7239-ccd3-5cce-807f-2072f3f0d108" version = "0.9.3-DEV" [deps] +Compat = "34da2185-b29b-5c13-b0c7-acf172513d20" IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a" @@ -13,6 +14,7 @@ StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" [compat] +Compat = "3.7" IterTools = "1" OrderedCollections = "1" ProgressMeter = "0.6, 0.7, 0.8, 0.9, 1" diff --git a/docs/Manifest.toml b/docs/Manifest.toml index 3629e36f..00da65c6 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -1,15 +1,25 @@ [[ACME]] -deps = ["IterTools", "LinearAlgebra", "Markdown", "OrderedCollections", "ProgressMeter", "SparseArrays", "StaticArrays", "Statistics"] +deps = ["Compat", "IterTools", "LinearAlgebra", "Markdown", "OrderedCollections", "ProgressMeter", "SparseArrays", "StaticArrays", "Statistics"] path = ".." uuid = "ca8b7239-ccd3-5cce-807f-2072f3f0d108" [[Base64]] uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +[[Compat]] +deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "SHA", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] +git-tree-sha1 = "2e23d71ad695ec28ca58ddd44869f07afa33cc76" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "3.7.0" + [[Dates]] deps = ["Printf"] uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +[[DelimitedFiles]] +deps = ["Mmap"] +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" + [[Distributed]] deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" @@ -101,6 +111,10 @@ uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" [[Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +[[SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + [[Sockets]] uuid = "6462fe0b-24de-5631-8697-dd941f90decc" diff --git a/src/ACME.jl b/src/ACME.jl index 112e25b9..cb701d89 100644 --- a/src/ACME.jl +++ b/src/ACME.jl @@ -1,10 +1,11 @@ -# Copyright 2015, 2016, 2017, 2018, 2019 Martin Holters +# Copyright 2015, 2016, 2017, 2018, 2019, 2020 Martin Holters # See accompanying license file. module ACME export DiscreteModel, run!, steadystate, steadystate!, linearize, ModelRunner +using Compat: evalpoly using SparseArrays: SparseMatrixCSC, blockdiag, dropzeros!, findnz, nonzeros, sparse, spzeros using LinearAlgebra: BLAS, I, axpy!, lu, rmul! diff --git a/src/elements.jl b/src/elements.jl index df9b42a4..597fbded 100644 --- a/src/elements.jl +++ b/src/elements.jl @@ -1,4 +1,4 @@ -# Copyright 2015, 2016, 2017, 2018, 2019 Martin Holters +# Copyright 2015, 2016, 2017, 2018, 2019, 2020 Martin Holters # See accompanying license file. export resistor, potentiometer, capacitor, inductor, transformer, @@ -394,23 +394,31 @@ Pins: `base`, `emitter`, `collector` end @doc doc""" - mosfet(typ; vt=0.7, α=2e-5) + mosfet(typ; vt=0.7, α=2e-5, λ=0) 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} + \cdot (1 + \lambda 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.} + \frac{\alpha}{2} \cdot (v_{GS} - v_T)^2 \cdot (1 + \lambda v_{DS}) + & \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. +voltage `vt` is given in Volt, `α` (in A/V²) is a constant depending on the +physics and dimensions of the device, and `λ` (in V⁻¹) controls the channel +length modulation. + +Optionally, it is possible to specify tuples of coefficients for `vt` and `α`. +These will be used as polynomials in $v_{GS}$ to determine $v_T$ and $\alpha$, +respectively. E.g. with `vt=(0.7, 0.1, 0.02)`, the $v_{GS}$-dpendent threshold +voltage $v_T = 0.7 + 0.1\cdot v_{GS} + 0.02\cdot v_{GS}^2$ will be used. Pins: `gate`, `source`, `drain` -""" function mosfet(typ; vt=0.7, α=2e-5) +""" function mosfet(typ; vt=0.7, α=2e-5, λ=0) if typ == :n polarity = 1 elseif typ == :p @@ -418,25 +426,43 @@ Pins: `gate`, `source`, `drain` 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], - ports=[:gate => :source, :drain => :source], - nonlinear_eq = @inline function (q) - vg, vds, id=q # vg = vgs-vt - if vg <= 0 - res = @SVector [-id] - J = @SMatrix [0.0 0.0 -1.0] - elseif vds <= vg - res = @SVector [α * (vg-0.5*vds)*vds - id] - J = @SMatrix [α*vds α*(vg-vds) -1.0] - else # 0 < vg < vds - res = @SVector [(α/2) * vg^2 - id] - J = @SMatrix [α*vg 0.0 -1.0] - end - return (res, J) - end) + vt = (vt...,) + α = (α...,) + dvt = vt[2:end] .* (1:length(vt)-1...,) + dα = α[2:end] .* (1:length(α)-1...,) + let polarity = polarity, α = α, vt = vt + 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], + ports=[:gate => :source, :drain => :source], + nonlinear_eq = @inline function (q) + vgs, vds, id = q + α´ = evalpoly(polarity*vgs, α) + if !isempty(dα) + dα´_dvgs = evalpoly(polarity*vgs, dα) + else + dα´_dvgs = 0 + end + vt´ = evalpoly(polarity*vgs, vt) + if !isempty(dvt) + dvt´_dvgs = evalpoly(polarity*vgs, dvt) + else + dvt´_dvgs = 0 + end + λ´ = vds ≥ 0 ? λ : zero(λ) + if vgs <= vt´ + res = @SVector [-id] + J = @SMatrix [0.0 0.0 -1.0] + elseif vds <= vgs - vt´ # && vgs > vt´ + res = @SVector [α´ * (vgs-vt´-0.5*vds)*vds*(1+λ´*vds) - id] + 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] + else # 0 < vgs - vt´ < vds + res = @SVector [(α´/2) * (vgs-vt´)^2*(1+λ´*vds) - id] + J = @SMatrix [α´*(vgs-vt´)*(1-dvt´_dvgs)*(1+λ´*vds) + dα´_dvgs/2 * (vgs-vt´)^2*(1+λ´*vds) λ´*α´/2*(vgs-vt´)^2 -1.0] + end + return (res, J) + end) + end end @doc doc""" diff --git a/test/runtests.jl b/test/runtests.jl index 1c269ad4..b5748896 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,9 +1,10 @@ -# Copyright 2015, 2016, 2017, 2018, 2019 Martin Holters +# Copyright 2015, 2016, 2017, 2018, 2019, 2020 Martin Holters # See accompanying license file. include("checklic.jl") using ACME +using Compat: evalpoly, only using Test: @test, @test_broken, @test_logs, @test_throws, @testset using FFTW: rfft using ProgressMeter @@ -518,6 +519,28 @@ end 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 + for (typ, pol) in ((:n, 1), (:p, -1)), α in (1e-4, (0.0205, -0.0017)), + vt in (1, (1.2078, 0.3238), (-1.2454, -0.199, -0.0483)) + circ = @circuit begin + vgs = voltagesource(), [-] == gnd + vds = voltagesource(), [-] == gnd + J = mosfet(typ, vt=vt, α=α, λ=0.05), [gate] == vgs[+], [drain] == vds[+] + out = currentprobe(), [+] == J[source], [-] == gnd + end + model = DiscreteModel(circ, 1); + for vgs in range(0, stop=5, length=10), vds in range(0, stop=5, length=10) + y = only(run!(model, pol*hcat([vgs; vds]))) + α´ = evalpoly(pol*vgs, (α...,)) + vt´ = evalpoly(pol*vgs, (vt...,)) + if vgs ≤ vt´ + @test y == 0 + elseif vds ≤ vgs - vt´ + @test y ≈ pol * α´ * (vgs - vt´ - vds / 2) * vds * (1 + 0.05 * vds) + else + @test y ≈ pol * α´ / 2 * (vgs - vt´)^2 * (1 + 0.05 * vds) + end + end + end end @testset "op amp" begin