前言
TCAD(Technology Computer Aided Design),虽然原名中没有与半导体器件有关的词汇,但这种软件便是半导体工艺模拟及器件模拟的工具,可以说是EDA软件的一种。TCAD软件同其他EDA软件一样,底层需要复杂的数学模型和数物模型支撑,能大幅减少半导体制造的研发成本,为新型半导体器件提供初步验证,是半导体研究中不可或缺的软件。
这种软件大多使用自己开发的脚本语言进行编程仿真,少有图形化的操作界面,地球上几乎没有系统讲解TCAD软件的使用教程,即便市面上有一些教程,也只是粗略介绍了软件的基本使用,唯一的学习资源就是软件附带的文档,笔者在今年5月份有幸接触到人生中的第一款TCAD软件—Medici,使用该软件的目的是改变一种器件的某些参数后获取器件的击穿电压Bv,在使用过程中发现medici软件不仅仿真速度较慢而且需要频繁修改源文件去获取不同情况下的参数,大幅度延长了参数验证的时间,拖累科研进程,所以必须利用一些歪门邪道改变这一现状。
本文提供了一种利用python脚本让Medici根据用户所设参数自动获取结果的思路,笔者非计算机相关专业出生,脚本程序也只是笔者东平西凑的产物,但脚本确是提高了工作效率,本文也只注重讲解设计脚本的思路,不涉及器件源程序的相关知识。
实现原理
在设计python脚本的时候,将medici软件视为一个黑盒,这个黑盒是一个拥有一个输入和两个输出的盒子,当输入一个电压,这个盒子可以输出两个值,通过比对输出的两个值是否都在1附近来判断输入的电压是否正确。如下图所示:
由于判断输入的电压是否是正确的是在仿真结束后才能进行判断,因此需要进行多次修改源文件的电压进行仿真,存在着一定的试错成本,而且试错是一个不可避免的环节,所以我第一次设计的脚本也是一个暴力试错型的,下面是代码实现的流程图。
在上述所示的程序流程中,我最先输入了一个保守值进行仿真,为什么要输入这个保守值?由于笔者并没有深究Medici软件的数学模型,即便文档有提到也难以进行验证,在Medici软件提取电离值的时候,输出的结果是不固定的,这里的不固定说的是输出的内容不固定而不是指输出的数值不固定,当输入的电压小于一定值时,提取电离值语法会输出一些难以预料的内容,读者可以自行尝试,而即便是输出了自己想要的内容也离预期值过远,大大增加了试错的成本,所以这里我输入的保守值其实是一个“便于后续处理的数值”,如果不从一个“便于后续处理的数值”开始仿真,从0开始仿真的话是非常浪费时间的。因此,需要先根据一定的经验先输入一个保守值进行仿真,以便后续流程的处理。
脚本以这种运行方式运行往往需要多次修改电压输入后再运行多次仿真后才能得到结果,并且仿真次数与预期电压和我们输入的保守值有关,也就是说我们输入的保守值越接近预期电压其仿真所需要的次数也就越少,这样做的缺点是很明显的,在不同条件下器件的击穿电压应该是不一样的,也就是说需要试错的次数也不一样,不推荐这种做法。
在使用上述的方法编写脚本后我发现了一些规律,如下图所示
可以看出,我是在保守值得基础上增加1伏电压或是减少一伏电压让保守值去逼近目标值,而上图数据所示我输入的保守值是小于预期值的,因此只需每次加1伏电压否判断是否符合预期结果后输出就行(这里我为了方便演示选择了每次仿真结束后都输出结果),如上图所示,为得到预期结果我的脚本一共仿真了27次,这是特别花费时间的,是否还有跟简单的仿真方式?
图中的结果已经给出了答案,在图中可以看出,我每增加1伏电压对电离值所产生的增量是比较相近的,如果我先用保守值进行一次仿真然后再在保守值的基础上增加1伏后进行仿真后,得到这两次的电离值的差值也就得到了这1伏电压增量对结果引起的电离值的增量,随后我计算目前的电离值距离预期电离值还有多少个这样的增量,再增加这些量后进行仿真是不是就能快速达到预期结果了?改进后的程序设计流程如下所示:
这样便能快速逼近预期值,省了不少时间,以下是改进后的脚本输出的结果图
可以看到仿真的次数大大减少了,下面讲解具体的代码实现
代码实现
引言
虽然流程图里的步骤并不复杂,但我们需要组成流程图里的组分
由于笔者不是计算机专业出生的,但也略懂些编程的思路,这里我采用“自下而上”的编程思路,简单来说也就是先实现一些小功能,再将这些功能组合成逻辑运行。
在手动仿真的过程中,我发现经常需要执行以下几个步骤:
1. 打开源文件,填入电压,关闭源文件
2. 在源文件的路径中让shell执行“medici 源文件名”的命令
3. 查看文件后缀是".out"的输出文件,判断结果是否符合预期
也就是说我的脚本需要以下功能:
1. 获得源文件路径
2. 在源文件中找到找到自己想要的信息
3. 在源文件中删除我需要更改的信息
4. 在源文件中添改我想要的信息
5. 执行仿真
6. 输出我想要的信息
下面逐一讲解代码实现,再三声明,笔者非计算机专业出生,脚本代码只是笔者东平西凑的产物,这个份产物对于专业人士而言就是所谓的”屎山“,但脚本确实提高了笔者的工作效率,不喜勿喷。
一、获得源文件路径
代码
windows环境
import os
fileDir = os.path.abspath('.') # 获取文件目录路径
FileName_Source = 'soi.txt' # 源文件名(带拓展名)
FilePath_Source = fileDir + "\\" + FileName_Source # 获取源文件路径
print(FilePath_Source)
Linux环境
import os
fileDir = os.path.abspath('.') # 获取文件目录路径
FileName_Source = 'soi.txt' # 源文件名(带拓展名)
FilePath_Source = fileDir + "/" + FileName_Source # 获取源文件路径
print(FilePath_Source)
这里需要注意两个地方
- 由于脚本是在windows环境下编写的,任何文件都需要有一个后缀名,而Linux环境下文件可以没有后缀名,程序的源文件一般为纯文本类型,这里在windows环境下选择了“.txt”后缀。
- Linux环境下文件的路径中的斜杠的方向与windows中的是相反的,如果需要在linux环境下运行则需要将"\"改成"/"
测试结果:
windows环境
C:\Users\73812\Desktop\半导体器件脚本\soi.txt
Process finished with exit code 0
Linux环境
代码
总结
可以看出文件路径中的斜杆是相反的,该代码能成功获取源文件路径。至此,获得源文件路径功能的讲解结束
二、在源文件中找到找到自己想要的信息
代码
import os
fileDir = os.path.abspath('.') # 获取文件目录路径
FileName_Source = 'soi.txt' # 源文件名(带拓展名)
FilePath_Source = fileDir + "\\" + FileName_Source # 获取源文件路径
KeyWord_Nd = '$Nd' # 查找目标关键字
def seek_target_line(FilePath, KeyWord):
'''
这个函数的功能是寻找目标关键字所在的行
:param FilePath:文件路径
:param KeyWord:文件中的关键词
:return:target_line:返回查找的目标所在的行数
'''
with open(FilePath, encoding="utf8") as file:
lines = file.readlines()
count_line = 0
target_line = 0
for line in lines:
count_line += 1
if KeyWord in line:
target_line = count_line
del lines[:]
return target_line
print(FilePath_Source)
print(seek_target_line(FilePath_Source, KeyWord_Nd))
部分源文件图
![](C:\Users\73812\Desktop\自动化脚本图片\屏幕截图 2024-06-10 173607.png)
测试结果
C:\Users\73812\Desktop\半导体器件脚本\soi.txt
3
Process finished with exit code 0
总结
我的目的是为了修改第源文件中第4行后进行仿真,所以我在上一行也就是第3行增加了一个注释便于我去定位第四行,通过运行结果可以看出名为"seek_target_line"的函数成功返回看关键字所在行。至此,在源文件中找到找到自己想要的信息讲解结束。