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)に, 912行目は式(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