信號/電源完整性之最佳化:系統性分析

在前一則貼文中, 我們提到若欲找到”一個“方案時, 線性的假設性分析是一個不錯的優化方式。然而當我們要把更多的設計變數放在一起通盤考量來對更大的解答空間裡求最佳化時, 則必需要有更系統性的、而非挑一兩個變數在固定其它變量於一常數值、的優化程序。

反應曲面模型( Response surface model,  RSM):

在下圖中, 系統輸出Y1, Y2等同時含有可控制變量X及不受控變量Z; 在其它如晶片設計或晶圓廠裡,諸如不可預測的宇宙射線等對載體的影響便可歸類於這些不受控變數;但在透過仿真來得到輸出結果的整合性分析裡, 過程與結果都是確定性(deterministic)的; 也就是說只要輸入情況一樣, 輸出結果每次也都會相同, 所以這些不受控變數Z便可忽略不計; 我們可以把這種輸入轉成輸出的關係看做是一個具有多維空間的反應曲面, 在這曲面上找頂點或最低點便是最佳化的過程。

doersm

這種輸出入間的對應一般稱為”反應曲面模型” (response surface model, or RSM), 透過在解答間裡的諸多取樣點並對其(透過仿真或場解)求輸出後構間出這樣的一個多維模型來優化便是一種系統性的優化流程; 而實驗設計法(design of experiments, or DOE)則是最常與RSM一起運作的建模程序。

實驗設計法 (Design of experiments, DOE):

當系統有許多變量且各含有一定範圍及可能值時, 要透過全面完整組合(full combinatorial, or full grid)來找最佳值是不大可能的; 我們只能透過極有限取樣點來得到反應以建構出RSM。

將上圖中輸出Y寫成是一個由變量x1, x2 ~ xn所形成的函數f(x), 則透過Taylor Theorem, 這些函式f(x)均可以級數的形式來近似:

當更高階級數(bigger alpha)被包含Taylor級數時, 這近似式與原f(x)就更接近了, 這就好比對時域方波做傅利葉轉換時, 若頻域上包含的諧波更高, 則再反轉回時域時就更近似原來的方波。

在現實世界裡, 大部份的現象主要來自於低階的項目的影響, 若我們只取到二階, 則上述的Taylor級數展開後可寫成如下的二次式:

quadraeq

當變數X1, X2的值不同時, 等式左邊的輸Yfit值也就不同, 而系數Beta則決定了各變量對輸出的影響程度: beta值愈小, 則變量就更為次要; 那要怎麼算出相關係數Beta呢? 如果我們有N個取樣點, 則上面這種型式的等式寫在一起時便可以如下的矩陣的樣式來表現:

quadramtx

當將二階拉高為至K階時, 則廣義的矩陣式便可寫成如下:

DOERSMMtx

最左邊的X矩陣大多不是方陣, 所以若要求出相關系數Beta的向量, 則需使用一般線性代數裡的操作技巧:擬反矩陣(pseudo inverse)及奇異值分解(singular value decomposition, or SVD), 而所得的係數是在以最小的平均誤差(mean square error)的情況下的解。

modelfit

欲使用DOE/RSM流程來進行優化, 則有幾項前置作業必需完成:

  • 決定有那些變量X及最高階為何: 如能先有洞見, 則取較具相關性的變量可使建構出的模型更近似;其次, X的數目及階數也影響了欲進行仿真的數目及最後矩陣的大小;
  • 決定取用那些輸出函數Y: 因為我們只用低階的X來置入Taylor級數, 故若是結果得再經過複雜的數學運算或後處理,則過程間的高階操作便可能打破了低階X和Y的關連性;
  • 決定那種取樣方式:在上面矩陣式中, 每一列都是一個系統仿真, 我們只要能在解答空間裡有足夠數目及涵蓋性的取樣點便可, 過多或過少都會影響建出模型的品質; 而這取樣點的方式在統計學上則有許有許多不同的理論可採用。

以實驗設計法優化的流程:

欲利用實驗設計法在對信號或電源完整性上優化; 一般來說有下列步驟:

  • 定義變數: 儘量只將主要變量列如分析的範圍則模型才有意義且建模才有效率; 而主要變量則可透過:線性掃描(linear sweep), 假設性分析, 之前產品設計的分析及經驗等等來決定; 再者實驗設計法通常不會只進行一次, 在每次結果出來後對相關係數的檢視都可為下次再進行分析做參考。
  • 定義取樣點: 取樣方式及數目取決於變量多少及範圍; 在信號/電源完整性的應用上, 一般若變量數目在10左右, 則central composite design 是一個不錯的選擇, 如此選出的取樣點在一千到數千個之間; 若是有更多的變量(<=30),  則使用D-Optimal較佳, 取樣法亦和建模方式有關, 當欲建模型不是透過RSM, 而是由神經網路的方式時, 則二次式的需求便未必需要, 故而可用如space filling等取樣法來進行;所述這些都是統計學上的應用, 故許多統計軟體都可拿來設計相關實驗;在我們的建模模組MPro裡, 則有許多常用的有關的內建:

    Design

  • 產生測試案例: 所定變量一般可分為連續性變量(如電阻值)及非連續性(如各corner等),雖然在變量可能值範圍內有不同的階度可選, 但在上一步驟的取樣點裡, 每一個變數一般只用-1, 0, +1來表示其最小,中間及最大值以用於其案例; 故接下來竹的步驟就是把這取樣點的設定轉為實際的案例以便進行仿真或場解。若是佈線前的分析, 則案例多是Spice的網表(netlist), 故案例的產生可運用如樣板網表(template netlist)進行字串替換來輕易達成; 對於和幾何相關的案例(後佈線或2D傳輸線或3D結構以場解進行), 則得需要更複雜的程序才能將取樣點轉成測試案例。不論那種程序,最後的結果是每一個測試點表示矩陣裡的一個行而必需要有相對應的案例產出。

    Collect

  • 對案例仿真、場解並後處理: 再來就是對產出的測試案例仿真、場解及後處理以得到輸出了; 因為可能有維數上千或上萬的案例需進行, 故一般是透過多執行緒或甚至是利用多台電腦來平行處理,最後再將每個案例的算出結果組合以便和原始輸入形成對應關係; 而在這一步驟中所著重的便是如何迅速有效的管理這些平行處理的案例分析。

    SimMgr

  • 為輸入至輸出建模: 有了輸入及輸出後, 接下來的就是實際的建模了, 若是反應曲面模型, 則可用前述的奇異值分解(SVD)來解相關係數; 其它的建模方式也包括了類神經網路等等;而模型的優劣則可透過其對現有結果的預測及殘值大小來查驗; 殘值(及實際值及預測值間差)愈小則模型愈好; 一般上可用R^2, 即因模型所造成的變異數, 來計模型好壞, R^2 >= 0.95表示是可接受的預測模型。

    modeling

    Prediction

  • 優化: 優化是在一定的變量範圍及條件(如不以是負值)等的前題下進行; 而後對單一輸出Y或是以比重組合出的複合Y (or cost function)來求極大極小化; 取決於所取變量的階度, 也有以下幾種演算法可運用:
    • 線性規劃: 若變數皆為一階且無cross terms, 則可用線性規化方式得到絕對解; 一般而言, 很多和幾何相關的計算(如layer stackup對阻抗的反應)等都只需要用到一階就可有很好的近似;
    • 非線性方法:常有高階項時, 可試著用如Nelder algorithm來求優化值;
    • 基因演算法: 這是需經過許多迴圈但可適用於近乎所有模型(含類神經網路)的優化方式。

      Optimize

  • 審視相關係數及殘值,重覆進行: 最後一步驟則是審視模型中各變量的相關係數, 剔除非主要的變量後再在下一迴圈裡做更進一步的操作; 也可能是對高殘值之案例更進一步檢查看是否是仿值或後處理的過程產生問題以造成離群值。

由上可見, 相較前一則貼文裡所提到的假設性分析, 欲以DOE/RSM的方式來為系統做優化是需要進行更多步驟的及計算資源的; 在另一方面, 一旦所建模型可具預測性(即殘值小), 則此一模型可做為假設性分析的基礎而取代很多不必要的仿真; 下圖中所示:我們的TPro模組先已透過對十數萬案例進行二維場解及建模而能將結果拿來建置成一快速的假設性分析功能使讀者可很快地透過拉BAR來得到相關的性能資訊。

A stackup what-if based on model built via DOE/RSM flow

 

仿真器之研發:建模 (IBIS及傳輸線元件)

元件在仿真器內運作的順序大致上是:先將網表上所給的原始設定轉為仿真過程中內部所需的資料結構(Parse)、在DC未開始之前將物理模形轉成(Model)諾頓等效電路之形式,而後在每一時步或每一時步的牛頓迴圈中更新(Solve)等效電路參數值並將其填入(Stamp)系統矩陣中,最後在每時步或仿真結束前將其資料傳給上層以便記錄後處理或直接寫成波形檔(Query)。這其間的“Model”與”Solve”的設計便是仿真器設計中需對元件物理要有的理解才能順利完成的。

在這兩篇貼文中,我們將大致談談系統元件中IBIS、傳輸線及S-參數等是怎麼被建模(Model)及求解(Solve)的。

B-Element… IBIS:

我們之前已對IBIS寫過幾篇貼文,同時也由下面的IBIS結構中便可對如何建模猜得一二:

這幾組IV曲線: pull-up, pull-down, power clamp and ground clamp基本上就是非線性電阻,亦即其電阻值隨著兩端點的瞬態電壓而改變;故在牛頓迴圈裡,程式只要利用其電壓差來在之前Parse得的曲線做線性內插即可。實務上因為這種內插要進行很多次。。若每次都從第一點開始掃描點落在的區間則效率不佳,故可先建成線性方程以增進查值速度。

上述IV曲線之外,瞬態波形轉出的切換係數switching coefficient及合成電流composite current 兩者都是與時間點有關的,其作用可視為是一個乘數來對靜態算出的電流再加以限制。切換係數的目的是要確認IBIS在連到表定的負載時,在端點會有如waveform table一樣的響應。而這係數是在仿真過程中只要事先計算一次即可的,故可在Model步驟中完成。最後至於C_Comp,若可能的話可直接加入仿真器已有的電容器串列中而不需要自行管理有關error prediction及積分等的事宜。

大致上來說,為IBIS元件編程較複雜之處多是因為不同的模型參數可能有不同的skew,而其間可能的不同組合(比如說fast 和slow就會由不同參數中typ, min, max組合而成)便得對簿計先事先規劃;其次,因為在同一元件裡,除主IBIS外也可能會有submodel, driver schedule等的附加IBIS模型以達成pre-emphasis等的等化功能,故在軟體的設計上可能也得考慮如composite pattern以便能以一模版來遞迴地加入主要及附加IBIS模形部份。最終而言,IBIS元件的建模是相對容易的。。尤其是如果跟即將要提的傳輸線相比的話。

W-Element… 傳輸線

每本電磁學教科數裡都會列出如下傳輸線單位長度dx上的RLGC基本模型:

在含HSpice的許多仿真器裡,上述的模型多以U-element建成,即(Uniform distributed model);由於使用者得事先決定要以多少單位長度(dx)來建模,再加上仿真效率上的考量,這種U元件多已不被使用了。話雖如此,傳輸線的基本模型資料(frequency dependent tabular model, or tab model)仍是以這種形式儲存的:

這種tab model一般是由二維場解器依PCB疊層、走線寬度、疊層間界質之物理特性(如導電度,介電常數等等)甚至是粗糙度後處理(surface roughness treatment)等照Maxwell的邊界值條件在不同頻率上解出而來;一般上也都必需要有低頻(近DC)、高頻(50G或100G)及其間不同的頻率點的值才算完整。那要如何將這原始資料轉成可仿真的線性模型呢?一般可從電報者等式 Telegrapher’s equations 開始著手:藉由解出單位長度下RLGC的KCL/KVL,我們可得到一階導數式:

而這兩列微分方程的解,即如上述wiki連結裡所示,為一含有傳播函數Gamma T的波方程 :

當把這系統模型之解寫成有如線性式時,便有如下的諾頓等效電路:

在傳輸線近端及遠端的電路裡,都有兩個部份:其一是在瞬態當下的電抗Z(s),其二是由彼端入射或反射、經傳播遲延而傳來的電流源。這兩者在上圖都仍是頻域值,故在時域仿真時,均需再進一步地轉化成可積分的形式才能在不同時步中stamp入矩陣。綜上而言,傳輸線元件的仿真步驟為:

  • 讀取並儲存原始的tabular model;
  • 利用上者最高頻率值(或利用外插)來算出此線之傳播遲延及特性阻抗,這兩值將使用在後面的時域仿真中;
  • 在頻域中建模出上面系統模形裡的阻抗響應Z(s)及傳播響應r(s),因傳輸線可能是有多條線藕合在一起的,故這些響應式多是多維的矩陣;
  • 利用Vector fitting 的技巧以數個極零點來模擬上述Z(s)及r(s)的曲線,在大多數的情形下(尤其是當原始模型資料不足或ill-behaved時)要很完美的能去map這些曲線可說是不太可能的,則需採minimum-square-error等的方式如來求近似曲線的極零值;
  • 一旦有極零點,便可將每個term都轉成相對應的時域函數,而這所有的term在時域上的組成即是其在時域上的響應。例如Pade’s approximation就是同樣的原理;
  • 在時域仿真時,每一時步中都對彼端在傳播遲延時間前的歷使值利用內插的方式來得現值r(t),這現值再和當下的Z(t)一起組成等效電路填值於矩陣中;
  • 在頻域仿真則簡單得多:可跳過vector fitting及轉成時域積分式的步驟而可直接內插出當下頻率的Z(s), r(s)來使用。

對於前三個步驟,我簡單地寫了兩個Matlab scripts 來模擬兩條藕合線的情形:

阻抗函數:

傳播函數:

輸出:

以matlab編程的話則上面的程式看起來簡單得多;實務上多數的仿真器(含SPISim的SSolver)為了仿真速度上的考量都是以原生碼(C/C++)編程而成,故在matlab裡簡單呼叫即可的矩陣操作如inverse, eigen value, LU decomposition等等都會因在原生碼語言中所用函式庫不同而多顯得冗長複雜許多。

最後,很少剛為元件建模完成即可直接運作無誤的,很多情況後面除錯所花的時間精力會較前面開發的期間更多;對傳輸線而言,因其多為多條線藕合、且由極零方程轉到時域的方程又有很多項、再加上有些信號得等上傳播遲延後才會由另一端傳來,故在除錯上是極具挑戰性的。一般上我們是用divide and concour的方式先把問題簡化到最少再一項一項來修正:比如說先除錯單線,阻抗完全匹配(故無反射),且特性阻抗為已知(故可查入射的振幅)再從DC位準來的除錯等等,這樣便會顯得有頭緒許多:

SPISim SSolver傳輸線建模的根據論文和HSpice所本的是同一篇,有興趣的讀者可依下查閱:

“Optimal Transient Simulation of Transmission Lines” by Dmitri Borisovich Kuznetsov, Jose E. Schutt-Aine, IEEE Trans. on Circuit and Systems, I Feb. 1996

教科書方面個人則以為Dan Oh:“High-speed Signaling”, 也就是我們相關書籍選列中的第S6 於第五章部份解釋得較詳細;這也可能是因為原著者也在相近時期與上述論文第一作者自同一學校畢業之故;最後也值得一提的是上述傳輸線的建模方法也常可應用到其它不同的元件,比如說是同是均質被動、以S-參數表示的system channel。在將頻域資料利用vector fitting轉成有理化式的過程中,一些原有的S-參數問題(causality)即可透過這個程序來修正。

仿真器之研發:界面

在前則貼文中,我們提到電路仿真器的核心部份是有由線性代數方法, 來對由節點電流及網目電壓方程所形成的矩陣做求解;我們也提到靜態及瞬態的運算中,元件部份被呼叫最多次的函式是”Solve”及”Stamp”兩式,也就是元件先依在那一時步的那牛頓迴圈中的端點電壓電流情況針對元件本身的物理方程求解,而後再將解出值填入矩陣式中的步驟。由於在熱迴圈(hot loop)內而被呼叫次數眾多,元件裡的這兩個函式便需務求精簡迅速必要以使仿真器整體運作能穩定、易維護且具延展性。

在前文底所列的經典電路分析教科書中 “Computer Methods for Circuit Analysis and Design” :第170頁列有元件值是如何被填入矩陣裡的:

從上表可見,在第一層的界面定義中(也就是元件的Solve函式裡)最主要的工作是不論單獨元件物理特性為何,均能由當下端點偏壓或所流經電流值而轉應成相對應的基本元件(如電流I、電壓V、電應G及電抗A)形式再依上表填入系統矩陣中。除此之外,由於牛頓法裡也要求要能提供一階導數以便在下一迴圈裡能更新自變數,故元件也要有能依端點情況提供一階導數(i.e. partial derivative)的能力;否則,仿真器將被迫以數值方式來對系統矩陣求導數,也就是在某一點情況下固定一自變數但依續變動其它自變數的方式來求數值上的導數(dV/dI 或 dI/dV),如此以來,將導致仿真速度明顯變慢且更不穩定(易不收歛)。

在理論上,不論一元件(即便如場效體或傳輸線等複雜元件)是否為非線性,其都可以藉由固定維持大多數自變數為常數的方式而得其線性化模型;比如說在某一時步(故t在此為常數不變)的某一牛頓迴圈(故端點情況為固定不變)的情況下,便可利用諾頓(Norton circuit)戴維寧電路(Thevenin circuit)來達到簡化模型的目的:

上圖中,簡化後的模型已可用上述的基本元件(I, V, G, A)來表示而可依表填值;在我認為:這簡化的過程就是元件物理和仿真器相交集之處。

舉例來說,簡單的元件如R, V, I等等,程式只要依表填入到系統矩陣相對應之處即可;被控元件如E, F, G, H等也可被視為受控電阻或電感來依樣填值。較複雜的元件如之前提及的場效體、傳輸線或S-參數等當然就要事先導出數學式來表示其物理意義。專piecewise-linear電路或元件而應用的Katzenelson algorithm或可在此派上用場,即便是諸如電容或電感等的元件也得規畫一番才能填值;這兩者一般是用數值積分/微分器及Predictor來達成此一目的的:

從上述式裡可見:電容及電感沒有直接的電應或電感值可用, 而是得利用如數值微分的方式來進行;比如說簡單的Backward Eular dV/dt = (V0-V1)/(t0-t1)就可使電容C的電流變成有諾頓電路般I=Y*V+J的形式,而這J的部份則是由此電容過去的歷史值演算來而來。在固定時步的仿真器裡,這種簿計(book keeping)尚稱容易,但對非固定時步的仿真器而言dt的取捨則影響了仿真的精確度。而某些元件如傳輸線等,其線長也決定了信號傳輸的遲延故而也就限制了dt的值,否則若時步差過大,則由另一端入射或反射而傳來的信號變會被跳過了。綜上所述,可見一仿真器的研發真的必需由許多面向來考慮。

下面所示的截圖即為仿真器裡電容元件在熱迴圈裡的函式,讀者可由黃色文字的加註看到前述不同的處理:

仿真器設計裡第二層的界面設計是有關於延伸性的考量。在前則貼文裡可見:以英文字首為始的二十六個元件大多已被使用,比如說R,L,C,I,G,E,F,G,H等字首都已約定俗成地表示電阻乃至於各類的受控元件;但除此之外若吾人要為特殊元件如天線、濾波器、特殊集成電路或甚至是將來尚未開發的元件來建模呢?一般而言仿真器都會有外掛的架構並以動態函式庫(dynamic link library .dll or shared object .so)用預定界面API的方式來達成此目的。拿Berkeley spice的仿真器來看,其定義的API如下:

可以看到能使用的類別較本文之初的表列更少了,更有甚者,藉由定義這些埠(port)及取用函式,仿真器可進一步限制了延伸元件對系統矩陣的存取而維護其穩定性。於是,設計元件以便能外掛於現有仿真器的工程師就得更進一步地把原有不論複雜與否的元件物理簡化成上述簡單API形式的工作了。

當這些簡化物理模型的方式導出之後,剩下的就仿真器研發部份便是逐一地把各個元件的模型利用數值及程設技巧先在DC或TR開始之初加以建模,而後在每一時步的每一牛頓迴圈裡依端點值計算更新模形參數而(透過API)提供給系統,再在每時步末為下一時步的所能取的dt加以設限且更新歷史記綠等等。

在我們SPISim使必信的SSolver仿真器裡,我們所參考的正是Berkeley Spice的架構且深為其設計理念及樣式所影響;在其原始版本及許多演化至今的其它開源版本裡,都沒有系統整合性仿真所必需支援的元件如: IBIS, 有損藕合傳輸線, S-參數及可定義如PRBS等的有源電壓等等;即便是S-參數的轉出,其它版本多也只支援雙埠電路(two port network)。由於過去的業界相關經驗,我們能夠相對輕易地了解其原本架構、流程而在較短的時間內加上這些元件的支持而達到應用的目的,但在閱讀相關文件及研發過程中,對這款在數十年前便已開發完成的仿真器,我們仍不禁且不時地為其設計之週到及流程之順感到敬佩,也建議有興趣的讀者能以其為本來深入地研究。

 

仿真器之研發:架構

在系統電氣性分析上,有效的方法及流程都必需建構在一定堅實的基礎之上,這“基礎科技”大致上包括了二維或三維場解器、仿真器及能依統計方法來演算出眼圖或BER的模組。針對仿真器而言,新思科技的HSpice可說是業界公認的標準,它功能強大又涵蓋了系統完整性分析上的各個面向;在北美及世界上的有些地區,我們可假設每個工程師都有HSpice可使用;但在許多其它地區。。比如說亞洲、或是當部門預算受限的情況之下,這假設就不成立了。為了能使我們使必信客戶在這種情形下也能享用我們所建構的分析流程,自去年下半年始我們開始了仿真器SSolver的研發。其初版本剛於日前釋出;為了分享一些背後的研發構想及基本仿真概念,我們將以以此篇為首的幾篇貼文饗有興趣的讀者。要說明的是我們的前提是以電氣信號為主之MNA仿真器,故不包含其它有關機械或熱能等的部份。

電路仿真器可說是一門電腦科學、數學及物理等知識相結合的一門術!

每個大二電機系學生都學過:兩個電路分析的基本形式是節點電流網目電壓、分別以科希賀夫電流及電壓定律表之;而由這兩種形式都列出的方程式可以用矩陣的方式來表示。

 

 

 

 

 

當然,並非所有的電路元件均可以電壓或電流的形式表之, 比如說電流源的電壓準位即沒有定值。為了能將對每個節點電壓或分枝電流都能求解,將KCL/KVL合寫的MNA (Modified Nodal Analysis)便有其必要,其是以節點電壓法為主是因為就一電路而言,其節點電壓數目較網路來得少,故當以矩陣式來求解時,矩陣大小就小得多而能更快地求解。而暨然談到矩陣,則許多有關線性代數的技巧、諸如稀疏矩陣、conditioning、pivoting等等也都會被使用,而這也就是數學在仿真過程中所扮演不可或缺的角色;否則一旦矩陣循迴幾次求解不成,仿真便不能收歛了。對仿真器研發而言,常也是在這時候必需思考到若有矩陣元素造成不收歛,將如何連結至原始元件或是提供相對應的資訊給用戶以便能對網表(NetList)進行除錯。

實務上,要解一個矩陣一次很簡單。。幾行Matlab碼就可以了,但若要能以最有效率的方式在仿真電路過程中解幾千幾萬次,則又得多費思量了。所以即使是尚未談到元件物理特性的此時,沒有資訊科學上的考量也是行不通的。

電路分析有很多種形式:時域瞬態(TR)、時域靜態(DC)、頻域小信號(AC)、極零(Pole-Zero)等等。系統分析上,最常用的是時域瞬態分析,而其最基本的分析步驟是牛頓法求解,也就是利用矩陣在某個點的一階導數來對下一迴圈可能值來進行預測及再求解,直至矩陣的值解出為止。這個過程又分做兩個步驟:靜態解(DC)及之後每個時間點的瞬間解(t > 0);在解靜態值時,所有的元件已達靜態值:故電容器是開路而電感是閉路,且也沒有任何時變信號。而在瞬態求解的每一個牛頓迴圈裡,時間點是固定的而且端點電壓、支路電流也是固定的。。就好像解靜態值一樣,若求解不成功,則仿真器就在同一時間點內,依矩陣的一階導數來調整端點電壓值等以在下一個牛頓迴圈裡再進行求解。如此一時步一時步地完成時域仿真。在某些情況下DC求解不成功,則仿真器可更進一步地利用Ramp或Charge-up的流程,先假設所有的電壓電流源都是0且元件無初值(則每點電壓就當然也是0),而後漸漸地將有源元件”Ramp”至應有的最終值,通常經此一步驟,DC求解多能成功。

上面的圖是Berkeley Spice以元件字首的表列;之前談到仿真器難的地方在於要以最快的速度求解,則我們就不能不對所要支援的元件進行更進一步的分類,以便在仿真過程中減少函式呼叫(function call)的次數。比如說,我們可將上面所列的元件分為下面幾類:

  • 不具時變性:如dc電壓或電流源,電阻等等,它們的值在仿真一開始之前就決定了而不會再有變化。
  • 具時變性:
    • 線性: 比如說PWL源,其值雖時變,但在同一時步的每個牛頓迴圈裡並不會再改變,所以同一時步只要求解一次即可;
    • 非線性:如場效體或傳輸線等等,他們的值必需在每個時步的每個牛頓迴圈裡更新才能求得正解。
  • 頻變或非頻變:

一旦分類完成,我們便可再進一步定出仿真器需支援的元件界面,以便能以最有效率的方式在每個牛頓迴圈裡由各個元件將先求元件內的解(Solve)再將那一瞬間的元件值填(Stamp,如蓋印章)到矩陣內以求解;這兩步驟(Solve & Stamp)可說是仿真過程裡被呼叫朂多次的程序(hot loop);一般來說,我們可為元件定出下面的界面:

  • 讀網表資料:仿真之初,將網表資料讀入且做語法偵錯;
  • 元件初始化:DC開始前將讀入的資料轉成仿真時會用的資料;
  • 建物理模型:DC開始前(或也含TR開始前)初始化物理模型;
  • 填入矩陣值:依每個牛頓迴圈內的解將元件資料填入矩陣裡;
  • 解元件瞬值:在每個牛頓迴圈內依端點值求元件瞬間解;
  • 輸出測量值:每個時步完成後輸出所量的元件值;
  • 清內部資料:仿真完成後清除資料。

若是以物件導向性語言如C++等來設計,則上述的界面程序應是以虛擬函式來實作,若是以程序語言如C,則大概是以struct 的形式定出functional pointer而由實作的元件依在struct裡出現的順序來覆寫;在仿真器的上層,也應有一些串列來將網表內的所有元件來串連起來;故在仿真過程中,所有的電容器等都位在同一串列中而由仿真器引擎依序呼叫;如此一來,若是遇到非時變性元件的元件串列,則在那時步之初便可直接跳過;而時變性線性元件也只要在同一時步的第一個牛頓迴圈裡呼叫一次即可。

另外也要考慮到的是物理模型的儲存。舉例來說:一個晶片可能有數以千萬計的場效體,但之間有不同元件尺寸的可能不會太多,所以可以以數個不同物理模型供這些場效體來使用而不用每個元件有一個local copy;而每個元件對不同模型的取用也可能得用雜湊函數(hash map)來進行而非連結串列(linked-list), 以避免N^2迴圈情況的發生。

其它的考量至少也包括了時步進行的程序及再初始化:就前者而言,現今的仿真器很少是固定時步的,通常仿真器內會有Predictor來預測下一時步可以跳多遠解值也不會差太多,但一旦“跳太遠”時便必需倒車以較小時步來進行;所以在系統矩陣上簿計的程序也要具備才不會重覆求解;對再初始化而言,仿真器多有”.alter”類的語法以便只要稍改部份元件值便能再進行仿真;故在元件內部的設計上,不僅不需要的程序不用每次仿真(.alter)前都重做,就連算過的解也要能清楚乾淨而不要“污染”到下一次仿真的進行。

諸如以上種種,不難想見設計一仿真器所得先有的設計及想法,否則設計出來的軟體不是臭蟲多、不易除錯或維護、就是延伸性不強而不能輕易地加入新的元件。在另一方面,也正是因為這些必需要有的深刻思考而能讓工程師如我者能欣賞領略各個領域知識相互契合運作無誤而能有助我解決工程設計難題之美。

網上已有許多開源仿真器可供讀者參考,它們多是衍伸自Berkeley Spice而來,Berkeley Spice在我看來是個很完整、至少頗具教育性的仿真器架構。教科書方面我則推薦以下兩本經典供參考: