verilog-A语法
1. 一篇verilog-A论文的翻译
1.1 一个二极管的例子
HOW TO (AND HOW NOT TO) WRITE A COMPACT MODEL IN VERILOG-A
该文章通过一个diode
的案例讲解verilog-A的文件框架和语法
‘include "disciplines.vams"
‘include "constants.vams"
module diode(a,c);
inout a,c;
electrical a,c,int;
branch (a,int) res;
branch (int,c) dio;
parameter real is = 10p from (0:inf);
parameter real rs = 0.0 from [0:inf);
parameter real cjo = 0.0 from [0:inf);
parameter real vj = 1.0 from (0:inf);
‘ifdef VAMS COMPACT MODELING
aliasparam phi = vj;
(*desc="jct. voltage"*) real vd;
(*desc="current"*) real id;
(*desc="depl. charge"*) real qd;
(*desc="depl. cap."*) real cd;
(*desc="conductance"*) real gd;
‘define GMIN ($simparam("gmin"))
‘else
real vd, id, qd;
‘define GMIN (1.0e-12)
‘endif
analog begin
V(res) <+ I(res) * rs;
vd = V(dio);
id = is * (limexp(vd/$vt) - 1.0);
if (vd < vj) begin
qd = cjo * vj * (1.0 - 2.0 * sqrt(1.0 - vd/vj));
end else begin
qd = cjo * vd * (1.0 + vd / (4.0 * vj) );
end
‘ifdef VAMS COMPACT MODELING
gd = ddx(id, V(int));
cd = ddx(qd, V(int));
‘endif
I(dio) <+ id + ‘GMIN * vd;
I(dio) <+ ddt(qd);
I(dio) <+ white noise(2 * ‘P Q * id,"shot");
V(res) <+ white noise(4 * ‘P K *
$temperature * rs,"thermal");
end
endmodule
-
"a"和"b"是器件的端口,在模块名称后面的括号内
-
"inout"表示数据的流向
-
"electrical"是节点,其来自
disciplines.vams
。里面包含了很多disciplines,其本质是用户定义的数据类型,包括through (I) and across(V) variables,单位,容差。 -
"branch"是分支,res和dio是分支助记符。
-
"parameter"需要在端口和分支声明之后,必须包含默认值(这个值可以是参数),指定范围,[]包括端点,()不包括端点。
-
"aliasparam"允许给参数起别名。这是属于扩展的功能, 需要用
‘ifdef __VAMS_COMPACT_MODELING__
导入。 -
"real"变量在模块上方声明。
-
"begin"和"end"表示模块的开始和结束。
-
"<+"表示对支路(res,dio)电压或者电流的贡献。可以使用基本的数学函数,包括:
+ - * / sqrt pow ln exp abs
。使用limexp
代替exp
可以提高收敛性,使用电容电流是通过电荷的时间导数ddt
计算的。紧凑建模扩展提供了偏导数ddx
。 -
仿真温度要求为
$temperature
,热电压要求为$vt
。紧凑的建模扩展提供了一种从模拟器请求其他重要值的方法,例如最小电导$simparam(“gmin”)
。$
表示系统功能。 -
可以使用
if...else...
实现条件语句,逻辑表达式有&& || !
,关系运算符有> >= < <= == !=
。当然,也可以使用case 和 for
,但这两个不常用。 -
此外还可以添加噪声。
1.2 其他有用的功能
1. 参数技巧
// 可以引用其他参数
parameter real r = rho * length / width;
// 设置取值范围
parameter integer mobmod = 1 from [1:3];
// 三目运算符
parameter real uc = (mobmod==3) ? -46.5e-3 : -46.5e-12;
// 范围中设置参数,使得p2>0,p3>0,1-p2-p3>0
parameter real p2 = 0 from [0:1);
parameter real p3 = 0 from [0:1-p2);
2. N型和P型器件
// 可以声明一个整形参数区分N和P型器件
parameter integer type = 1 from [-1:1] exclude 0;
// 或者可以利用字符串是区分更加清晰,注意符号只能改变电压和电流
parameter string type = "NMOS" from f"NMOS", "PMOS"g;
localparam integer sign=(type=="NMOS")?1:-1;
3. Debug
// 打印系统变量,%m打印模块名称
gm = ddx(id chan, V(g));
$debug("%m : gm = ", gm);
4. 常量
// 建议使用"constants.vams"中的物理常量,而不是自定义
$simparam("tnom") returns a value in Celsius
$temperature is in Kelvin.
spice网表语法
1. 程序结构
- 标题
- 控制语句
.option
- 信号源
- 电路元件 [定义参数
.PARAM
] - 导入模型和子电路文件
- 分析语句
.DC .AC .TRAN
- 输出叙述
.plot .print
- 结束符号
.END
2. 标题
程序识别第1行为标题,即使没有标题,第一行也应该留空白
.title IDVG
3. 控制语句
OPTION
目前还不太清楚,暂时统一写成
.OPTIONS LIST NODE POST
*或者
.OPTIONS POST=2
ALTER
.alter
暂时理解为改变部分条件,并重新执行之前的所有程序
.title CMOS inverter-ch3_1
.option post
.param wn=5u wp=16u l=1u vdd=5v
vdd vcc 0 dc vdd
M1 n2 n1 vcc vcc pch W=wp L=l
M2 n2 n1 0 0 nch W=wn L=l
vs n1 0
.model pch pmos level=2
.model nch nmos level=2
.dc vs 0 5 0.01
.print dc v(n2) I(n2)
.alter
.param wp=4u
.alter
.param wp=6u
.alter
.param wp=8u
.alter
.param wp=10u
.alter
.param wp=12u
.end
TEMP & DTEMP
.title CMOS inverter-ch3_1
.option post
.temp 25
m1 2 1 0 0 mn w=10u l=0.35u
m2 4 1 0 0 mn w=10u l=0.35u dtemp=20
.model mn NMOS
v2 3 0 dc 5v
v4_45c 3 4 dc 0v
v3_25c 3 2 dc 0v
v1 1 0 dc 3v
.dc v2 0 5 0.1 v1 1 5 1
.print dc i(v4_45c) i(v3_25c)
.end
4. 信号源
4.1 片段波
使用描点法绘制PWL/PL (t1 v1 t2 v2 ... tn vn)
PWL (0ms 3 0.4ms 5 1ms 4 1.6ms -1)
4.2 脉冲波
PULSE V1 V2 <td tr tf pw per>
其中:低压V1,高压V2,延迟时间td,上升时间tr,下降时间td,脉冲宽度pw,周期per
4.3 正弦波
SIN V1 V2 <freq td df phase>
其中:参考电压V1,幅值的一半V2,频率freq,延迟时间td,阻尼因子df,相位phase
4.4 指数波
EXP V1 V2 td1 τ1 td2 τ2...
V1 1 0 EXP 1 0 0.1ms 1m 3ms 1m
5. 电路元件
值的后缀:f p n u m [1] k meg g t
5.1 基本元件
*电压源 节点1 节点2 DC(用于DC扫描) 初始值(用于静态工作点分析)
Vbb 1 0 DC 0.87
*电压源 节点1 节点2 AC(用于AC响应) 输入幅值(一般设置为1,方便计算增益)
Vs 2 1 AC 1
* 三极管 C B E ModelName
Q1 4 3 0 Q2N2222
.MODEL Q2N2222 NPN(IS=5e-15 BF=100 BR=100 VAF=50)
* 受控源 E F G H
* 格式 E N+ N- NC+ NC- gain_value
* MOS管 D G S B 模型名称 其他参数
M1 n2 n1 vcc vcc pch W=wp L=l
5.2 导入模型
.MODEL RMOD RES(R=1)
.model pch pmos level=2
.model nch nmos level=2
5.3 子电路
语法:
开始.SUBCKT <Definition name> <node 1> <node2>...
结束.ENDS
.title lff_test
.OPTIONS POST=2
* 参数
.param Calter=2u
* 子电路开始
.subckt amp 1 2 6 4
Ri 1 2 2e6
Gb 4 3 1 2 1
R1 3 4 10k
C1 3 4 Calter
Ea 4 5 3 4 1k
Ro 5 6 75
.ends
* 子电路结束
* 主电路开始
R1 2 0 1g
Vs 1 0 ac 1
Xa1 1 0 2 0 amp
.ac dec 5 1m 100g
.plot ac v(2)
.end
5.4 Verilog-A
VA模型的导入与调用
* 导入 文件路径 模块名称
.hdl "D:\Users\LFF\Desktop\veriloga-test\capacitor_lff.va" cap_lff
* 调用 Xn node... 模块名 参数
X1 1 0 cap_lff c=10n
6. 模型和子电路
7. 分析语句
7.1 直流分析
DC直流扫描
语法:.DC VX/IX start stop incrm
解释:扫描信号源VX/IX,初始值start,结束值stop,步长incrm
.title DC+SWEEP+Param
.OPTIONS LIST NODE POST
Vin 1 0 10
R1 1 2 1k
R2 2 3 RMOD
R3 3 0 1k
.PARAM RMOD=100
.DC Vin 0 10 1 SWEEP RMOD 100 1000 200
.end
OP静态工作点
只考虑直流(time=0)时刻时,打印所有Source、Resistors、三极管等器件的所有状态,包括:电压、电流、功耗等
TF小信号转移函数
语法:.TF output_variable input_source
输出的信息:整个DC扫描范围的(1)out/in (2)输入阻抗 (3)输出阻抗
.title lff_test
.OPTIONS POST=2
* DC Bias
Vbb 1 0 DC 0.87
Vcc 5 0 DC 10
* AC Source
Vs 2 1 AC 1
* Resistance
Rb 2 3 10k
Rc 5 4 2k
* Bipolar C B E ModelName
Q1 4 3 0 Q2N2222
.MODEL Q2N2222 NPN(IS=5e-15 BF=100 BR=100 VAF=50)
.OP
.DC Vbb 0 2 0.01
.TF V(4) Vs
.PRINT DC V(1) I(Q1) IE(Q1) IB(Q1)
.end
7.2 瞬态分析
Tran
语法:.tran step stop
IC设置暂态初始值
语法:.IC V(node)=value
7.3 交流分析
AC
语法:.AC DEC/OCT/LIN pts start stop
解释:点数pts,每十进制DEC、八进制OCT、线性LIN
8. 输出语句
8.1 print
.print DC/AC/Tran V(node) I(node) Vdb(node) Vp(node)
解释:V电压,Vdb电压dB,Vp电压相位
.print DC V(1) I(Q1) IE(Q1) IB(Q1)
解释:三极管的C、E、B的电流,方向按照工作状态算
.title lff_test
.OPTIONS LIST NODE POST
vs 1 0 ac 1
r1 1 2 1k
r2 2 3 1k
c1 2 0 1u
c2 3 0 1u
.ac dec 10 1Hz 1megHz
.print ac vdb(3) vp(3)
.end
8.2 plot
与print相同,但是在lis文件中以二位网格的形式打印