Hello!
写这篇博客的目的是记录写Cadence Virtuoso IC617仿真所用工艺库参数计算程序时遇到的问题。
所用语言:Matlab
原理介绍
链接: 用Cadence Virtuoso IC617仿真工艺库参数
程序结构
程序核心为解三元二次方程组,带沟道调制系数的饱和区电流公式如下:
- 定义变量:要求的未知数有:Kn、laman、Vtn。已知的变量有:W、L、Vgs1、Vgs2、Vds1、Vds2以及其对应的Ids
- 定义方程组:将不同的变量带入方程,得到方程组
- 解方程
踩的坑
1、变量定义:
变量定义:将变量以矩阵的形式定义,方便以后的调用
%定义变量
W = 220e-6;
L = 180e-7;
Valueids = [0 0.8 1.0;1 28.62 53.72;1.5 30.35 56.21];
Vgs = [Valueids(1,2),Valueids(1,3)];
Vds = [Valueids(2,1), Valueids(3,1)];
Ids = [Valueids(2,2) Valueids(2,3);Valueids(3,2) Valueids(3,3)];
2、定义方程组
定义方程组:将变量赋值到方程中,以得到四个不同的方程,**但是在之前一定要把空矩阵中的某个元素赋值为字符类型,否则无法将方程赋值为矩阵的元素!!**你一定能感受到我的痛苦。
%定义方程组
eq = zeros(2,2);
eq = [laman 0;0 0];
for i = 1:2
for o = 1:2
eq(o,i) = [Ids(o,i)*10e-7 == (1/2)*Kn*(W/L)*(Vgs(i)-Vtn)^2*(1+laman*Vds(o))];
end
end
eq1 = eq(1,1);
eq2 = eq(1,2);
eq3 = eq(2,1);
eq4 = eq(2,2);
3、解方程
解方程:这里注意!**slove函数解出来的变量是一个字符矩阵,数据长度及其离谱,无法直接输出,**需要用double函数转化为小数,才能进行接下来的舍解操作。
Knmax = double(max(Kn));
Knmin = double(min(Kn));
lamanmax = double(max(laman));
lamanmin = double(min(laman));
Vtnmax = double(max(Vtn));
Vtnmin = double(min(Vtn));
Kn = [Knmax Knmin];
laman = [lamanmax lamanmin];
Vtn = [Vtnmax Vtnmin];
这里的逻辑不严谨,欢迎大佬指正
舍解:将每个解代入第四个方程,误差最小的那组解为答案。
counter = 0;%对遍历次数进行计数,若为最大次数或者1次则结果可能不可靠
for i = 1:2
for o = 1:1
for p = 1:2
Knfinal = Kn(1,i)
lamanfinal = laman(1,1)
Vtnfinal = Vtn(1,p)
counter = counter + 1;
t = Ids(2,2)*10e-7 - (1/2)*Knfinal*(W/L)*(Vgs(2)-Vtnfinal)^2*(1+lamanfinal*Vds(2))
if (abs(Ids(2,2)*10e-7 - (1/2)*Knfinal*(W/L)*(Vgs(2)-Vtnfinal)^2*(1+lamanfinal*Vds(2))) < 0.0000001)
flag = 1;
break;
end
end
if flag == 1
break
end
end
if flag == 1
break
end
end
最后输出答案
counter
Knfinal
lamanfinal
Vtnfinal
整体代码如下:
clear,clc
syms Kn laman Vtn;
W = 220e-6;
L = 180e-7;
eq = zeros(2,2);
Valueids = [0 0.8 1.0;1 28.62 53.72;1.5 30.35 56.21];
Vgs = [Valueids(1,2),Valueids(1,3)];
Vds = [Valueids(2,1), Valueids(3,1)];
Ids = [Valueids(2,2) Valueids(2,3);Valueids(3,2) Valueids(3,3)];
eq = [laman 0;0 0];
for i = 1:2
for o = 1:2
eq(o,i) = [Ids(o,i)*10e-7 == (1/2)*Kn*(W/L)*(Vgs(i)-Vtn)^2*(1+laman*Vds(o))];
end
end
eq1 = eq(1,1);
eq2 = eq(1,2);
eq3 = eq(2,1);
eq4 = eq(2,2);
[Kn,laman,Vtn] = solve(eq1,eq2,eq3,Kn,laman,Vtn);
Knmax = double(max(Kn));
Knmin = double(min(Kn));
lamanmax = double(max(laman));
lamanmin = double(min(laman));
Vtnmax = double(max(Vtn));
Vtnmin = double(min(Vtn));
Kn = [Knmax Knmin];
laman = [lamanmax lamanmin];
Vtn = [Vtnmax Vtnmin];
counter = 0;
for i = 1:2
for o = 1:1
for p = 1:2
Knfinal = Kn(1,i)
lamanfinal = laman(1,1)
Vtnfinal = Vtn(1,p)
counter = counter + 1;
t = Ids(2,2)*10e-7 - (1/2)*Knfinal*(W/L)*(Vgs(2)-Vtnfinal)^2*(1+lamanfinal*Vds(2))
if (abs(Ids(2,2)*10e-7 - (1/2)*Knfinal*(W/L)*(Vgs(2)-Vtnfinal)^2*(1+lamanfinal*Vds(2))) < 0.0000001)
flag = 1;
break;
end
end
if flag == 1
break
end
end
if flag == 1
break
end
end
counter
Knfinal
lamanfinal
Vtnfinal