掃描為了解決的「記憶深埋」難題
想像一座巨大的倉庫裡有一百萬個電燈開關,但你能親手碰到的,只有靠近大門那幾百個。其他每一個開關的狀態,都取決於它前面的開關,而那些又取決於*再前面*的,一路回溯到累積了好幾個小時的歷史。現在我要你:證明第 814,562 號開關還能正常運作。從大門出發,唯一的辦法是用恰好正確的順序去撥前面那些開關,等效應一路漣漪傳到後方,再想辦法讀回一個還得一路漣漪傳回前方的結果。這就是測試晶片內部正反器時,每天面對的真實處境。
上一階為這個困難取了名字:深埋在循序電路裡的位元,可控性與可觀察性都極差。要把一個正反器逼到某個指定值,你可能需要數十甚至數百個時脈週期的精確序列;而要*看見*它捕捉到了什麼,又需要同樣長的序列把值一路推回某根針腳。把這乘上一百萬個正反器,所需的測試週期數就會爆炸,遠超任何測試程式所能執行。難的不是中間那些邏輯——難的純粹是你*碰不到*那些狀態。
掃描正反器:多一顆多工器,全盤改觀
這份魔法小得幾乎令人難為情。一個掃描正反器,就是一顆普通正反器,在它的資料輸入端栓上一顆二選一的多工器。多工器的一個輸入是功能資料 D——電路平常想存進去的值;另一個是掃描輸入(scan-in,SI),由鏈中*前一個*掃描正反器餵進來。一條全域的控制線——掃描致能(scan-enable,SE)——決定誰勝出。當 SE 為低時,這顆元件的行為和設計者畫的那顆正反器一模一樣;當 SE 為高時,它無視自己的功能邏輯,只聽鄰居的話。
functional data scan-in (from prev FF)
| |
v v
+---+ +-------------------+
D--| 0 | | |
|mux|---| D' FF Q |----> Q (to logic AND
SI--| 1 | | (rising edge) | to next FF's SI)
+---+ +---------^---------+
^ |
| CLK
scan-enable (SE)
SE = 0 -> D' = D (FUNCTIONAL / CAPTURE mode)
SE = 1 -> D' = SI (SHIFT mode: the chain acts as a shift register)現在把每個掃描正反器的 Q 輸出,接到下一個的 SI 輸入,就像把珠子串在線上。讓 SE 維持為高,每顆元件都從它上游的那顆取資料,於是整串集合就像一條長長的移位暫存器:時脈跳動一次,整個圖樣就剛好滑移一個位元。第一顆元件的 SI 來自一根專屬的晶片針腳,叫 scan-in;最後一顆的 Q 則送到一根叫 scan-out 的針腳。這串縫合起來的正反器,就是掃描鏈。
移位—捕捉—移位的舞步
鏈一旦就位,測試機就以三拍舞步跑完一個圖樣。第一拍——移入:把掃描致能拉高,對鏈打 N 次時脈(N 是鏈長)。一個位元接一個位元,你從 scan-in 把選定的圖樣推進去,直到每個正反器都握著你要的值。你剛剛*以單一、機械式的操作,把電路放進了任意狀態*——完全不需要費神去找什麼巧妙序列。第二拍——捕捉:把掃描致能拉低,剛好一個時脈脈衝。此刻每個正反器都回到功能模式,於是各自取樣它真實的組合邏輯,從你載入的狀態加上輸入針腳上的值所算出的結果。電路的回應,現在凍結在正反器裡。第三拍——移出:再把掃描致能拉高,多打 N 次時脈,把捕捉到的回應從 scan-out 一路推出來,測試機在那裡將它逐位元比對預期的「良品機」答案。
SE ___________ ___________________________
| | |
__| |_____________________|
<-- shift-in N --><-- capture --><-- shift-out N -->
CLK _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
| | | | | | | | | | | | | | | | | |
___| |_| |_| |_| |____| |____________| |_| |_| |_| |___
load pattern ONE pulse unload response
(SE=0): FFs grab (and load the
real logic output) NEXT pattern in
the SAME shifts!)第三拍裡藏著一個漂亮的效率:當你把*當前*回應移出時,你同時也在把*下一個*圖樣移入。這兩趟 N 週期的旅程共用同一組時脈。所以一個測試圖樣的成本,大約就是 N 個移位週期加一個捕捉週期,而對整顆晶片的完整測試,不過是這一連串動作的長長串流——載入、捕捉、卸出、重複——由工具自動產生,再在測試機上全速重播。
為什麼這把循序測試壓縮成組合測試
這裡藏著最深的回報,值得停下來細想。測試產生器的工作,是找出能暴露製造缺陷的輸入圖樣。對一個循序電路而言,這難得殘酷:工具必須對*時間*進行推理,搜尋一段橫跨許多週期的輸入序列,先把機器驅動到一個能「敏化」缺陷的狀態,再把缺陷的效應傳播出來——這個搜尋空間會隨週期深度指數成長。它是這個領域裡,真正難以處理的問題之一。
掃描讓正反器從那個問題裡消失了。因為你能直接*寫入*每個正反器(透過移入)、直接*讀出*每個正反器(透過移出),產生器不再需要去尋找抵達某狀態的序列——它直接點名那個狀態,移位暫存器就把它送上。留在正反器之間的,是純粹的組合邏輯:掃描正反器的輸出此刻就像額外的可控輸入,掃描正反器的輸入則像額外的可觀察輸出。工具只需要解那個靜態、無關時間的問題:『哪個輸入向量能暴露這條卡住的線?』這個組合問題,正是自動測試圖樣產生真正攻擊的對象——而它好處理得多。
掃描插入:流程後段的一道 EDA 步驟
設計者幾乎從不手繪掃描正反器。掃描是由工具自動加入的,發生在流程中一個定義明確的時點——這道步驟叫掃描插入。設計者在 RTL 裡寫的是普通的暫存器,只專心想功能;測試結構是事後接上去的,所以它從不擾亂設計意圖。
- 照常合成。邏輯合成把 RTL 對映到標準元件,選用普通正反器。就功能而言,這份網表已經完整且正確。
- 換成掃描元件。DFT 工具把每個符合條件的正反器,替換成程式庫裡的掃描對等元件——功能相同,外加 SI/SE 多工器。這是一對一的替換,不會改變電路計算的內容。
- 縫合成鏈。工具決定掃描元件的排序,把每個 Q 接到下一個 SI,再把鏈頭接到 scan-in 針腳、鏈尾接到 scan-out 針腳。它常會重用既有的功能針腳當作 scan-in/out 埠,以免耗掉珍貴的封裝針腳。
- 檢查並重新收斂時序。新的多工器與鏈的繞線增加了延遲,所以設計要對時序重新檢查;鏈本身只需在慢速的移位模式下滿足時序,這很容易。
- 交棒給 ATPG。結構就位、鏈的模型也寫出來後,測試產生工具就能生出圖樣——這正是下一階的主題。
一條一百萬位元的鏈,光載入就要打一百萬以上的時脈——太慢了。所以工具把正反器切分到許多條平行的鏈上,每條由自己的 scan-in 針腳餵入、由自己的 scan-out 針腳讀出。二十條各五萬位元的鏈,五萬個時脈就載完,而不是一百萬;大型設計上有幾百條鏈是常事。鏈平衡(chain balancing)就是維持所有鏈長度相近的家務活,因為測試機是把每條鏈一起打時脈,最慢(最長)那條決定了測試時間。長短不一的鏈,會浪費週期空等那個拖油瓶。
掃描回頭向你索取什麼
掃描不是免費的,好的設計者清楚它的帳單。每個正反器上的多工器,替功能路徑加了一點延遲,再加上百分之幾的面積。掃描致能訊號成了晶片上扇出最重的網路之一——它碰到每一個掃描正反器——必須像第二條時脈一樣被繞線與平衡。而且要讓鏈表現得像一條乾淨的移位暫存器,設計得遵守若干正確性規則:測試時時脈必須能從針腳控制、被閘控的時脈需要旁路、組合迴授或不受控的閂鎖會破壞移位。工具會把這些標記為 DFT 規則違規,而修正它們是「為測試而設計」的一部分,不是事後補救。
退一步看,這筆交易明顯划算。用幾個百分點的矽片,加上一套有紀律的設計規則,你就把一顆內部狀態實質上無法觸及的晶片,變成一顆每個位元都是門、能任意寫入與讀出的晶片。這正是為什麼掃描——誕生於 1970 年代的 IBM——至今仍是數位測試的基石;也是為什麼下一階的自動測試圖樣產生,根本有一個可處理的組合電路可以下手。