SPICEでは,使用できる関数が限られています. 特に,プログラム言語でいう if 文の機能がなく, どんな場合でも一本の式にまとめなければなりません. よく使う数式とSPICEによる表現の対応を以下に示します.
| max(a, 0) |
|
URAMP(a) |
| max(a, b) |
|
b+URAMP(a-b) または a+URAMP(b-a) |
| min(a, b) |
|
a-URAMP(a-b) または b-URAMP(b-a) |
![]() |
|
U(a-b)*c+(1-U(a-b))*d |
シミュレーションの速度を少しでも速くするため, 定数の計算はモデルをジェネレートする前にRの内部で行います.
1 *
2 * Generic triode model: 6L6T
3 * Copyright 2003--2006 by Ayumi Nakabayashi, All rights reserved.
4 * Version 3.01, Generated on Wed Mar 22 17:21:06 2006
5 .SUBCKT 6L6T A G K
6 BGG GG 0 V=V(G,K)+0.91804059
7 BEP EP 0 V=URAMP(V(A,K))+1e-10
8 BEG EG 0 V=URAMP(V(G,K))+1e-10
9 BM1 M1 0 V=(0.10751078*(URAMP(V(EP)-1e-10)+1e-10))^-1.743575
10 BM2 M2 0 V=(0.4624527*(URAMP(V(GG)+V(EP)/4.9999386)+1e-10))^3.243575
11 BP P 0 V=0.0016883841*(URAMP(V(GG)+V(EP)/10.811784)+1e-10)^1.5
12 BIK IK 0 V=U(V(GG))*V(P)+(1-U(V(GG)))*0.0021948901*V(M1)*V(M2)
13 BIG IG 0 V=0.0022135943*V(EG)^1.5*(V(EG)/(V(EP)+V(EG))*1.2+0.4)
14 BIAK A K I=URAMP(V(IK,IG)-URAMP(V(IK,IG)-(0.00056920996*V(EP)^1.5)))+1e-10*V(A,K)
15 BIGK G K I=V(IG)
16 * CAPS
17 CGA G A 4.4p
18 CGK G K 5.7p
19 CAK A K 5.9p
20 .ENDS
このサブ回路の内容は,図B.9のとおりです.
図の下側にある電圧源は,数式の途中結果を表しています.
リストの6行目は式(B.23)に,
9
12行目は式(B.28)に,
13行目は式(B.29)に,
14行目は式(B.31)に相当します.
プレート-カソード間には,
10 GΩ 相当の抵抗成分を入れています.
こうすることにより,差動回路やSRPPやカスコード接続で直流的にノードが浮くのを防ぐことができます.
V(M1)*V(M2) などは1行で書けそうな気がしますが,
SPICEのバグのせいで計算ができません.
また,URAMP の結果は0以上なので,累乗(^)しても問題ないはずですが,これも計算不能になるので 1e-10 を加えています.
1 *
2 * Generic pentode model: 6L6
3 * Copyright 2003--2006 by Ayumi Nakabayashi, All rights reserved.
4 * Version 3.01, Generated on Wed Mar 22 17:21:06 2006
5 .SUBCKT 6L6 A G2 G1 K
6 BGG GG 0 V=V(G1,K)+0.91804059
7 BEP EP 0 V=URAMP(V(A,K))+1e-10
8 BEG EG 0 V=URAMP(V(G1,K))+1e-10
9 BEG2 EG2 0 V=URAMP(V(G2,K))+1e-10
10 BM1 M1 0 V=(0.10751078*(URAMP(V(EG2)-1e-10)+1e-10))^-1.743575
11 BM2 M2 0 V=(0.4624527*(URAMP(V(GG)+V(EG2)/4.9999386)+1e-10))^3.243575
12 BP P 0 V=0.0016883841*(URAMP(V(GG)+V(EG2)/10.811784)+1e-10)^1.5
13 BIK IK 0 V=U(V(GG))*V(P)+(1-U(V(GG)))*0.0021948901*V(M1)*V(M2)
14 BIG IG 0 V=0.0022135943*V(EG)^1.5*(V(EG)/(V(EP)+V(EG))*1.2+0.4)
15 BIK2 IK2 0 V=V(IK,IG)*(1-0.4*(EXP(-V(EP)/V(EG2)*15)-EXP(-15)))
16 BIG2T IG2T 0 V=V(IK2)*(0.942171668*(1-V(EP)/(V(EP)+10))^1.5+0.057828332)
17 BIK3 IK3 0 V=V(IK2)*(V(EP)+2180)/(V(EG2)+2180)
18 BIK4 IK4 0 V=V(IK3)-URAMP(V(IK3)-(0.00056920996*(V(EP)+URAMP(V(EG2,EP)))^1.5))
19 BIP IP 0 V=URAMP(V(IK4,IG2T)-URAMP(V(IK4,IG2T)-(0.00056920996*V(EP)^1.5)))
20 BIAK A K I=V(IP)+1e-10*V(A,K)
21 BIG2 G2 K I=URAMP(V(IK4,IP))
22 BIGK G1 K I=V(IG)
23 * CAPS
24 CGA G1 A 0.6p
25 CGK G1 K 5.7p
26 C12 G1 G2 3.8p
27 CAK A K 5.9p
28 .ENDS
サブ回路の内容は,図B.10のとおりです.
1 "r2spice" <-
2 function(p, mn, fn, mode="triode", ...)
3 {
4 # RのパラメータをSPICE 3のサブ回路に変換する
5 # p: Rのパラメータ
6 # mn: SPICEのサブ回路名
7 # fn: SPICEのファイル名(拡張子をのぞく)
8 # mode: 出力するモデルの種類("triode" or "pentode")
9 # ...: 電極間容量等
10
11 Paste <- function(...) paste(sep="", ...)
12 sig <- function(x) signif(x,8)
13 version <- Paste("* Version 3.01, Generated on ", date())
14 a <- 1/(1 - p$alpha)
15 b <- 1.5 - a
16 c <- 3 * p$alpha - 1
17 mum <- a / 1.5 * p$muc
18 G.p <- p$G * (c * a / 3)^b
19 Ig.ratio <- if (is.null(p$Ig.ratio)) 0.5/(1 + 1/mum)^1.5 else p$Ig.ratio
20 G.lim <- if (is.null(p$G.lim)) G.p * (1 + 1/mum)^1.5 else p$G.lim
21 tubetype <- if (is.null(p$pentode.chara)) "triode" else "pentode"
22 caps <- cap(tubetype=tubetype, ...)
23 Cgpt <- caps$Cgpt * 1e12
24 Cgkt <- round(caps$Cgkt * 1e12, 1)
25 Cpkt <- round(caps$Cpkt * 1e12, 1)
26 if (tubetype == "pentode") {
27 Cgpt <- round(caps$Cgpt * 1e12, 1)
28 Cgp <- caps$Cgp * 1e12
29 Cgk <- round(caps$Cgk * 1e12, 1)
30 Cpk <- round(caps$Cpk * 1e12, 1)
31 Cg1g2 <- round(caps$Cg1g2 * 1e12, 1)
32 }
33
34 # Spice 3f4 用のモデルを出力
35 s <- NULL
36 s[1] <- "*"
37 s[3] <- "* Copyright 2003--2006 by Ayumi Nakabayashi, All rights reserved."
38 s[4] <- version
39 if (mode == "triode") {
40 s[2] <- Paste("* Generic triode model: ", mn)
41 s[5] <- Paste(".SUBCKT ", mn, " A G K")
42 s[6] <- Paste("BGG GG 0 V=V(G,K)+", p$Ego)
43 s[7] <- "BEP EP 0 V=URAMP(V(A,K))+1e-10"
44 s[8] <- "BEG EG 0 V=URAMP(V(G,K))+1e-10"
45 s[9] <- Paste("BM1 M1 0 V=(", sig(c/2/p$muc), "*(URAMP(V(EP)-1e-10)+1e-10))^", sig(b))
46 s[10]<- Paste("BM2 M2 0 V=(", sig(1.5/a), "*(URAMP(V(GG)+V(EP)/", p$muc, ")+1e-10))^", sig(a))
47 s[11]<- Paste("BP P 0 V=", sig(G.p), "*(URAMP(V(GG)+V(EP)/", sig(mum), ")+1e-10)^1.5")
48 s[12]<- Paste("BIK IK 0 V=U(V(GG))*V(P)+(1-U(V(GG)))*", p$G, "*V(M1)*V(M2)")
49 s[13]<- Paste("BIG IG 0 V=", sig(Ig.ratio*G.lim), "*V(EG)^1.5*(V(EG)/(V(EP)+V(EG))*1.2+0.4)")
50 s[14]<- Paste("BIAK A K I=URAMP(V(IK,IG)-URAMP(V(IK,IG)-(", sig((1-Ig.ratio)*G.lim), "*V(EP)^1.5)))+1e-10*V(A,K)")
51 s[15]<- "BIGK G K I=V(IG)"
52 s[16]<- "* CAPS"
53 s[17]<- Paste("CGA G A ", Cgpt, "p")
54 s[18]<- Paste("CGK G K ", Cgkt, "p")
55 s[19]<- Paste("CAK A K ", Cpkt, "p")
56 s[20]<- ".ENDS"
57 } else {
58 s[2] <- Paste("* Generic pentode model: ", mn)
59 s[5] <- Paste(".SUBCKT ", mn, " A G2 G1 K")
60 s[6] <- Paste("BGG GG 0 V=V(G1,K)+", p$Ego)
61 s[7] <- "BEP EP 0 V=URAMP(V(A,K))+1e-10"
62 s[8] <- "BEG EG 0 V=URAMP(V(G1,K))+1e-10"
63 s[9] <- "BEG2 EG2 0 V=URAMP(V(G2,K))+1e-10"
64 s[10]<- Paste("BM1 M1 0 V=(", sig(c/2/p$muc), "*(URAMP(V(EG2)-1e-10)+1e-10))^", sig(b))
65 s[11]<- Paste("BM2 M2 0 V=(", sig(1.5/a), "*(URAMP(V(GG)+V(EG2)/", p$muc, ")+1e-10))^", sig(a))
66 s[12]<- Paste("BP P 0 V=", sig(G.p), "*(URAMP(V(GG)+V(EG2)/", sig(mum), ")+1e-10)^1.5")
67 s[13]<- Paste("BIK IK 0 V=U(V(GG))*V(P)+(1-U(V(GG)))*", p$G, "*V(M1)*V(M2)")
68 s[14]<- Paste("BIG IG 0 V=", sig(Ig.ratio*G.lim), "*V(EG)^1.5*(V(EG)/(V(EP)+V(EG))*1.2+0.4)")
69 s[15]<- "BIK2 IK2 0 V=V(IK,IG)*(1-0.4*(EXP(-V(EP)/V(EG2)*15)-EXP(-15)))"
70 s[16]<- Paste("BIG2T IG2T 0 V=V(IK2)*(", 1-p$g2.r, "*(1-V(EP)/(V(EP)+10))^1.5+", p$g2.r, ")")
71 s[17]<- Paste("BIK3 IK3 0 V=V(IK2)*(V(EP)+", -p$Ea, ")/(V(EG2)+", -p$Ea, ")")
72 s[18]<- Paste("BIK4 IK4 0 V=V(IK3)-URAMP(V(IK3)-(", sig((1-Ig.ratio)*G.lim), "*(V(EP)+URAMP(V(EG2,EP)))^1.5))")
73 s[19]<- Paste("BIP IP 0 V=URAMP(V(IK4,IG2T)-URAMP(V(IK4,IG2T)-(", sig((1-Ig.ratio)*G.lim), "*V(EP)^1.5)))")
74 s[20]<- "BIAK A K I=V(IP)+1e-10*V(A,K)"
75 s[21]<- "BIG2 G2 K I=URAMP(V(IK4,IP))"
76 s[22]<- "BIGK G1 K I=V(IG)"
77 s[23]<- "* CAPS"
78 s[24]<- Paste("CGA G1 A ", Cgp, "p")
79 s[25]<- Paste("CGK G1 K ", Cgk, "p")
80 s[26]<- Paste("C12 G1 G2 ", Cg1g2, "p")
81 s[27]<- Paste("CAK A K ", Cpk, "p")
82 s[28]<- ".ENDS"
83 }
84 filename <- paste(fn, ".inc", sep="")
85 cat("Writing", filename, "\n")
86 write(s, file=filename)
87
88 # SIMetrix用のモデルを出力
89 s <- NULL
90 s[1] <- "*"
91 s[3] <- "* Copyright 2003--2006 by Ayumi Nakabayashi, All rights reserved."
92 s[4] <- "* Thanks to Tooru Kuroda."
93 s[5] <- version
94 if (mode == "triode") {
95 s[2] <- Paste("* Generic triode model: ", mn)
96 s[6] <- Paste(".SUBCKT ", mn, " A G K")
97 s[7] <- Paste(".param GG {(V(G,K)+", p$Ego, ")}")
98 s[8] <- ".param EP {URAMP(V(A,K))}"
99 s[9] <- ".param EG {URAMP(V(G,K))}"
100 s[10]<- Paste(".param M1 {((", sig(c/2/p$muc), "*EP)^", sig(b), ")}")
101 s[11]<- Paste(".param M2 {((", sig(1.5/a), "*URAMP(GG+EP/", p$muc, "))^", sig(a), ")}")
102 s[12]<- Paste(".param P {(", sig(G.p), "*URAMP(GG+EP/", sig(mum), ")^1.5)}")
103 s[13]<- Paste(".param IK {(U(GG)*P+(1-U(GG))*", p$G, "*M1*M2)}")
104 s[14]<- Paste(".param IG {(", sig(Ig.ratio*G.lim), "*EG^1.5*(EG/(EP+EG)*1.2+0.4))}")
105 s[15]<- Paste("BIAK A K I=URAMP(IK-IG-URAMP(IK-IG-", sig((1-Ig.ratio)*G.lim), "*EP^1.5))+1e-10*V(A,K)")
106 s[16]<- "BIGK G K I=IG"
107 s[17]<- "* CAPS"
108 s[18]<- Paste("CGA G A ", Cgpt, "p")
109 s[19]<- Paste("CGK G K ", Cgkt, "p")
110 s[20]<- Paste("CAK A K ", Cpkt, "p")
111 s[21]<- ".ENDS"
112 } else {
113 s[2] <- Paste("* Generic pentode model: ", mn)
114 s[6] <- Paste(".SUBCKT ", mn, " A G2 G1 K")
115 s[7] <- Paste(".param GG {(V(G1,K)+", p$Ego, ")}")
116 s[8] <- ".param EP {URAMP(V(A,K))}"
117 s[9] <- ".param EG {URAMP(V(G1,K))}"
118 s[10]<- ".param EG2 {URAMP(V(G2,K))}"
119 s[11]<- Paste(".param M1 {((", sig(c/2/p$muc), "*EG2)^", sig(b), ")}")
120 s[12]<- Paste(".param M2 {((", sig(1.5/a), "*URAMP(GG+EG2/", p$muc, "))^", sig(a), ")}")
121 s[13]<- Paste(".param P {(", sig(G.p), "*URAMP(GG+EG2/", sig(mum), ")^1.5)}")
122 s[14]<- Paste(".param IK {(U(GG)*P+(1-U(GG))*", p$G, "*M1*M2)}")
123 s[15]<- Paste(".param IG {(", sig(Ig.ratio*G.lim), "*EG^1.5*(EG/(EP+EG)*1.2+0.4))}")
124 s[16]<- ".param IK2 {((IK-IG)*(1-0.4*(EXP(-EP/(EG2+1e-10)*15)-EXP(-15))))}"
125 s[17]<- Paste(".param IG2T {(IK2*(", 1-p$g2.r, "*(1-EP/(EP+10))^1.5+", p$g2.r, "))}")
126 s[18]<- Paste(".param IK3 {(IK2*(EP+", -p$Ea, ")/(EG2+", -p$Ea, "))}")
127 s[19]<- Paste(".param IK4 {(IK3-URAMP(IK3-(", sig((1-Ig.ratio)*G.lim), "*(EP+URAMP(EG2-EP))^1.5)))}")
128 s[20]<- Paste(".param IP {URAMP(IK4-IG2T-URAMP(IK4-IG2T-(", sig((1-Ig.ratio)*G.lim), "*EP^1.5)))}")
129 s[21]<- "BIAK A K I=IP+1e-10*V(A,K)"
130 s[22]<- "BIG2 G2 K I=URAMP(IK4-IP)"
131 s[23]<- "BIGK G1 K I=IG"
132 s[24]<- "* CAPS"
133 s[25]<- Paste("CGA G1 A ", Cgp, "p")
134 s[26]<- Paste("CGK G1 K ", Cgk, "p")
135 s[27]<- Paste("C12 G1 G2 ", Cg1g2, "p")
136 s[28]<- Paste("CAK A K ", Cpk, "p")
137 s[29]<- ".ENDS"
138 }
139 filename <- paste(fn, ".mod", sep="")
140 cat("Writing", filename, "\n")
141 write(s, file=filename)
142 invisible()
143 }
通常のSPICE用のファイルは fn.inc という名前で, SIMetrix用のファイルは fn.mod という名前で作成されます. mode に "pentode" と指定すると,五極管のモデルが作成されます.
この関数を使ってR上のパラメータ t12AU7 をファイルに出力します. SPICEのサブ回路名は 12AU7 です. 引用符の使い方に注意してください.
> r2spice(t12AU7, "12AU7", "12AU7", Cgp=1.5e-12, Ci=1.6e-12, Co=0.4e-12)
> system("cat 12AU7.inc") # 内容を確認
# Windowsの場合は cat を type にする
*
* Generic triode model: 12AU7
* Copyright 2003--2006 by Ayumi Nakabayashi, All rights reserved.
* Version 3.01, Generated on Wed Mar 22 17:21:35 2006
.SUBCKT 12AU7 A G K
BGG GG 0 V=V(G,K)+0.89005722
BEP EP 0 V=URAMP(V(A,K))+1e-10
BEG EG 0 V=URAMP(V(G,K))+1e-10
BM1 M1 0 V=(0.028826571*(URAMP(V(EP)-1e-10)+1e-10))^-0.90897681
BM2 M2 0 V=(0.622671*(URAMP(V(GG)+V(EP)/13.089625)+1e-10))^2.4089768
BP P 0 V=0.00087237591*(URAMP(V(GG)+V(EP)/21.021735)+1e-10)^1.5
BIK IK 0 V=U(V(GG))*V(P)+(1-U(V(GG)))*0.00055330711*V(M1)*V(M2)
BIG IG 0 V=0.00043618795*V(EG)^1.5*(V(EG)/(V(EP)+V(EG))*1.2+0.4)
BIAK A K I=URAMP(V(IK,IG)-URAMP(V(IK,IG)-(0.00049917061*V(EP)^1.5)))+1e-10*V(A,K)
BIGK G K I=V(IG)
* CAPS
CGA G A 1.5p
CGK G K 1.6p
CAK A K 0.4p
.ENDS