仿真器之研發:建模 (S-參數及Port元件)

系統上的channel及很多個別元件都是以S-參數來表示,其可能是用三維場解器依實體結構(導孔或連結器等)算出、也有可能是利用我們SPro的工具一級一級串結計算(cascade)而成。再加上LTI (Linear, time invariat即線性非時變)的假設,很多工具便可依channel單一脈衝(pulse)的波形來模擬數以百萬計位元的相疊加而得到如眼圖或BER圖形等的資料;無疑地,不論是單一脈衝波行的計算(在含IBIS情況下,未必都能用IFFT的方式來達成)、抑或是針對一些特定位元樣式(bit pattern)時域響應,一仿真器都應有能支援的能力。除此之外,在很多情況下我們所得到的spice電路是由頻域轉換而來、但其原始頻域資料又已不可得;故也常會有要能重現其原來S-參數資料的需要。這篇貼文裡,我們將簡單談談S-參數及相關的port 元件在SPISim使必信 SSolver裡是如何建模的。

S-Element… S-參數

近十數年的研討會或學術論文裡,多有許多對S-參數時域建模仿真的研究;在最基本的概念上,S-參數是在不同頻域點的輸出入相關資料,其可被視為一頻域的轉換函式(transfer function)或是濾波器;故可套用數位信號處理的基本應用:在頻域上和輸入做相乘等於是在時域上做捲積(convolution):

一旦轉成時域(如上圖的最底部方程右邊)則等號右邊則可進一步改寫分成兩項:一個是由元件過去的歷史值算出、亦即由-infinity積分至前一步t=n-1的項目;以及在現今時步t=n和當下輸入有關的項目。前者因是歷史值已發生,故可被視為是一常數而在牛頓迴圈裡不再更動;後者則因和當下輸入有關,故需在Solve及Stamp的熱迴圈裡不斷更新。總的來說,這兩者寫在一起便有了諾頓等效電路I = Y * V + J的形式。其中的Y和輸入V是連在一起的而J則可被視為常數不變。這兩者的值算出後便可自系統矩陣內更新來求解。

有興趣的讀者可參考HP多年前所出版的文件,其中對以這種捲積方式求S-參數解的過程及數學有更詳細的解釋:

Integration of Transient S-Parameter Simulation into HSpice

其中的第「18」及「19」式即為上述有關等效電路的部份。

因為捲積的基本理論是在每一時步之末,常數的值都需更新為-infinity to t=n以便為下一時步t=n+1所用,再者捲積是一種IFFT的樣式而在時域上的時步是固定的,這種要求限制了仿真器運行的速度,也就是為何近來有許多研究論文建議以不同方式來進行S-參數時域仿真。

其中的一種可能是利用之前所提、用在傳輸線建模上的的vector fitting技巧:先利用如Pade approximation 般將S-參數頻域資料透過不同極零點的選取而轉成有理式(rational function),而後利用同一種basis function在不同極點頻率對時域的轉換而得到相對應的形式;這過程的一個附加效果是若原有的S-參數資料有non-causal的情況,便可在有理化的過程中得到修正;與為傳輸線建模同樣地:極零點數目的多寡和是否與原始頻域資料相近似、以及轉成時域後的仿真速率都有相關;再加上原始S-參數資料在某些點可能是ill-behaved,故在實務上常得用如pseudo-inverse的方式以minimum-square-error sense的方式來求得近似有理方程式。

P-Element… 埠(port)元件

系統上許多元件、諸如晶片封裝package, 導孔via,連結器connector等等設計過程都是先有立體設計;而後用三維場解轉出S-參數,最後再用如broadband spice等的工具轉成相對應的spice 基本元件以便能在時域上仿真。對系統完整性分析人員而言,也在很多情況下所得到的元件模型多是這種已透過轉換得到的spice形式而其原始頻域資料並不可得;與其就直接把元件置入channel中來進行分析,較好的做法是先看看其頻域響應為何、頻寬是否足夠及是否有連結性上的問題等等。透過仿真的方式將spice subckt轉出S-參數在此便用應用的空間;而由於S-參數之轉出是植基於小信號頻域分析的,故一旦系統元件的AC模型建構完成,則轉出其S-參數也就近乎水到渠成了。

在此我們談的S-參數轉出是小信號部份,也就是在DC操作點附近的頻域分析,故而步驟上是先在輸入埠元件定義的地方先而對DC求解、加上AC信號後對其它埠測量,而後再進行下一個埠以至所有埠都掃過為止。

一般而言,埠元件(port element)都有幾個參數:DC偏壓、參考負載(reference impedance)、埠序(port order)及埠名(port name)等等;在輸入埠有DC偏壓時,其它的輸出埠都是連到參考負載的;在不同的頻率上求解後,輸入輸出埠間功率的關係可透過對埠的電壓及輸出入電流的量測而算得,而後依S-參數的測量公式:

S-parameter measurements

便可得到輸入埠i對其它埠j的Sij值;重覆這程序掃過所有的i後(不同的輸入埠可能有不同的偏壓)不同頻域點的Sij就都有值了,最後再依之前定義的埠序把資料寫出(至touch-stone format)且在表頭註記埠名則S-參數轉出的程序即算完成了。若是有進一步的需要要將S-參數轉成其它如Y, 或Z參數的形式,則可透過公式(雖是只有雙埠,但若假設S-參數是廣義的2-n port 也可適用)或是如本司SPro的工具達成。

 

回到仿真器的部分:

除了至今所提的各個元件物理模型的建模外,回到仿真器的階層則又有如下列的相關的課題:

  • 記憶區(memory pool)之管理:分配,擴張及清除
  • 多執行緒
  • 模組化外掛架構以支援新元件
  • 其它種種。。

不難想見這清單可很長地列下去,而之中的編程的工作也未必簡單;即便如此,對於系統分析的方法及流程而言,仿真器的完成及支援實有其不可取代的價值:對很多日後的分析,我們都不用(很多情況下也不可能)再得事先導出所有的算式了,我們大可透過直接形成網表後呼叫仿真器後再後處理資料的方式達成。這不僅有助於軟體的模組化,在穩定性(仿真可在另一執行緒或透過simulation farm完成)甚或是可測試性上都很有幫助, 對於一以研發系統EDA的公司如我者而言,是一項值得的投資。

仿真器之研發:建模 (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在我看來是個很完整、至少頗具教育性的仿真器架構。教科書方面我則推薦以下兩本經典供參考: