使用python指令碼玩轉古早TCAD軟體(待更新)

滇南鼠鼠發表於2024-06-17

前言

TCAD(Technology Computer Aided Design),雖然原名中沒有與半導體器件有關的詞彙,但這種軟體便是半導體工藝模擬及器件模擬的工具,可以說是EDA軟體的一種。TCAD軟體同其他EDA軟體一樣,底層需要複雜的數學模型和數物模型支撐,能大幅減少半導體制造的研發成本,為新型半導體器件提供初步驗證,是半導體研究中不可或缺的軟體。

這種軟體大多使用自己開發的指令碼語言進行程式設計模擬,少有圖形化的操作介面,地球上幾乎沒有系統講解TCAD軟體的使用教程,即便市面上有一些教程,也只是粗略介紹了軟體的基本使用,唯一的學習資源就是軟體附帶的文件,筆者在今年5月份有幸接觸到人生中的第一款TCAD軟體—Medici,使用該軟體的目的是改變一種器件的某些引數後獲取器件的擊穿電壓Bv,在使用過程中發現medici軟體不僅模擬速度較慢而且需要頻繁修改原始檔去獲取不同情況下的引數,大幅度延長了引數驗證的時間,拖累科研程序,所以必須利用一些歪門邪道改變這一現狀。

本文提供了一種利用python指令碼讓Medici根據使用者所設引數自動獲取結果的思路,筆者非計算機相關專業出生,指令碼程式也只是筆者東平西湊的產物,但指令碼確是提高了工作效率,本文也只注重講解設計指令碼的思路,不涉及器件源程式的相關知識。

實現原理

在設計python指令碼的時候,將medici軟體視為一個黑盒,這個黑盒是一個擁有一個輸入和兩個輸出的盒子,當輸入一個電壓,這個盒子可以輸出兩個值,透過比對輸出的兩個值是否都在1附近來判斷輸入的電壓是否正確。如下圖所示:
image

由於判斷輸入的電壓是否是正確的是在模擬結束後才能進行判斷,因此需要進行多次修改原始檔的電壓進行模擬,存在著一定的試錯成本,而且試錯是一個不可避免的環節,所以我第一次設計的指令碼也是一個暴力試錯型的,下面是程式碼實現的流程圖。

程式流程圖1

在上述所示的程式流程中,我最先輸入了一個保守值進行模擬,為什麼要輸入這個保守值?由於筆者並沒有深究Medici軟體的數學模型,即便文件有提到也難以進行驗證,在Medici軟體提取電離值的時候,輸出的結果是不固定的,這裡的不固定說的是輸出的內容不固定而不是指輸出的數值不固定,當輸入的電壓小於一定值時,提取電離值語法會輸出一些難以預料的內容,讀者可以自行嘗試,而即便是輸出了自己想要的內容也離預期值過遠,大大增加了試錯的成本,所以這裡我輸入的保守值其實是一個“便於後續處理的數值”,如果不從一個“便於後續處理的數值”開始模擬,從0開始模擬的話是非常浪費時間的。因此,需要先根據一定的經驗先輸入一個保守值進行模擬,以便後續流程的處理。

指令碼以這種執行方式執行往往需要多次修改電壓輸入後再執行多次模擬後才能得到結果,並且模擬次數與預期電壓和我們輸入的保守值有關,也就是說我們輸入的保守值越接近預期電壓其模擬所需要的次數也就越少,這樣做的缺點是很明顯的,在不同條件下器件的擊穿電壓應該是不一樣的,也就是說需要試錯的次數也不一樣,不推薦這種做法。

在使用上述的方法編寫指令碼後我發現了一些規律,如下圖所示

結果圖1

可以看出,我是在保守值得基礎上增加1伏電壓或是減少一伏電壓讓保守值去逼近目標值,而上圖資料所示我輸入的保守值是小於預期值的,因此只需每次加1伏電壓否判斷是否符合預期結果後輸出就行(這裡我為了方便演示選擇了每次模擬結束後都輸出結果),如上圖所示,為得到預期結果我的指令碼一共模擬了27次,這是特別花費時間的,是否還有跟簡單的模擬方式?

圖中的結果已經給出了答案,在圖中可以看出,我每增加1伏電壓對電離值所產生的增量是比較相近的,如果我先用保守值進行一次模擬然後再在保守值的基礎上增加1伏後進行模擬後,得到這兩次的電離值的差值也就得到了這1伏電壓增量對結果引起的電離值的增量,隨後我計算目前的電離值距離預期電離值還有多少個這樣的增量,再增加這些量後進行模擬是不是就能快速達到預期結果了?改進後的程式設計流程如下所示:

程式流程圖2

這樣便能快速逼近預期值,省了不少時間,以下是改進後的指令碼輸出的結果圖

結果圖2

可以看到模擬的次數大大減少了,下面講解具體的程式碼實現

程式碼實現

引言

雖然流程圖裡的步驟並不複雜,但我們需要組成流程圖裡的組分

由於筆者不是計算機專業出生的,但也略懂些程式設計的思路,這裡我採用“自下而上”的程式設計思路,簡單來說也就是先實現一些小功能,再將這些功能組合成邏輯執行。

在手動模擬的過程中,我發現經常需要執行以下幾個步驟:

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)

這裡需要注意兩個地方

  1. 由於指令碼是在windows環境下編寫的,任何檔案都需要有一個字尾名,而Linux環境下檔案可以沒有字尾名,程式的原始檔一般為純文字型別,這裡在windows環境下選擇了“.txt”字尾。
  2. 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"的函式成功返回看關鍵字所在行。至此,在原始檔中找到找到自己想要的資訊講解結束。

三、在原始檔中刪除我需要更改的資訊

程式碼

四、在原始檔中添改我想要的資訊

五、執行模擬

六、輸出我想要的資訊

相關文章