從一份規格說明開始
在任何人畫下第一根線之前,設計是從一張願望清單開始的。這塊晶片到底要做什麼?也許是解碼影片,也許是當一部手機的大腦,也許是測量心跳。把這張願望清單精確地寫下來,就叫做規格說明(spec,是 specification 的簡稱)。把它想成建築師在房子還不存在時手裡那份任務書:要幾個房間、蓋多高、能花多少錢。
一份真正的規格說明,核心其實是三個讓人吵個沒完的數字:跑多快、耗多少電,以及佔多大晶片面積(也就是多少錢)。這三者彼此較勁,像一場三方拔河——讓它更快,通常就會更熱、更大。整個晶片設計的功夫,就是在這三者之間找到一個甜蜜點。
從規格說明出發,工程師先勾勒出架構——有哪些大模組、它們怎麼連,就像一張平面圖寫著「廚房在這、臥室在那」。然後他們再放大到微架構:每個模組究竟一步一步怎麼幹活。這一切都是在紙上和文件裡定下來的,遠早於任何佈局的出現。在這一步把方案想錯了,後面再聰明的佈線也救不回來。
用 RTL 描述行為
方案定下來後,設計師並不去畫電晶體——他們寫程式碼。用 Verilog 或 VHDL 這樣的硬體描述語言,在所謂的暫存器傳輸級(register-transfer level,簡稱 RTL)上描述這塊晶片該做什麼。這名字聽著唬人,意思卻很親切:你描述的是資料在時脈每跳一下時,怎麼從一個小儲存格(暫存器)搬到下一個,以及途中算了些什麼。
這裡有個最容易把新手絆倒的地方:它看起來像軟體,但它不是一份一步接一步執行的菜譜。你寫的每一行都會變成真實的硬體,全部同時存在、並行執行。寫 RTL 與其說像列一張待辦清單,不如說像在描述一整支同時演奏的管弦樂隊,所有聲部都跟著指揮棒——也就是時脈——的每一拍一起響。
// an 8-bit register: on each rising clock edge,
// load new data, unless reset is held
always @(posedge clk) begin
if (reset)
count <= 8'd0; // clear to zero
else
count <= count + 1; // otherwise count up
end把上面那段慢慢讀一遍,你幾乎能聽見它的節奏:時脈每往上跳一次,計數器要麼清零,要麼往上挪一格。一整塊晶片,就是成千上萬段這樣的小描述拼接而成的。RTL 一旦寫好,人來做的部分基本就告一段落了——從這裡起,方向盤交給軟體。
綜合 → 邏輯閘
你的 RTL 說清了應該發生什麼,但還沒說清要用哪些真實零件去做。一個叫綜合器(synthesizer)的工具來完成這步翻譯。把你的程式碼餵給它,它就把那些行為描述編譯成一張網表(netlist)——一份精確的清單,列出實際用到的邏輯閘(及閘、或閘、反閘這一家子)以及它們到底怎麼連在一起,才能產生你描述的那個行為。
拿普通程式設計來類比會更好懂:寫 RTL 就像用一門高階語言寫程式,而綜合就是那個把它翻譯成硬體世界真能造出來的東西的「編譯器」。只不過它產出的不是機器指令,而是一張由邏輯閘組成的接線圖——而且每個閘都是從一本現成的「積木目錄」裡挑出來的,這本目錄我們下一節就會見到。
標準單元、佈局與繞線
網表裡的那些閘,並不是每次都從頭設計的。晶圓廠會給你一個現成小積木的庫,叫做標準單元(standard cells)——畫好的及閘、畫好的正反器等等,每一個都是同樣高度的整齊小方塊,像專門做來一排排卡在一起的樂高積木。你的網表現在就成了一張巨大的物料清單:成千上萬乃至上百萬塊這樣的積木。
接下來是實體設計,工具的活兒變得無比具體、可見。它先給晶粒(die)做佈局規劃(floorplan)——決定哪些大區域擺在這塊矽矩形的什麼位置。然後它把每個單元擺放(place)到一個真實的位置上。再然後它繞線(route),把連接它們的金屬線一條條接好,並在很多層之間堆疊走線,像一座擁擠城市裡的馬路、立交橋和隧道。這整套「裝箱加接線」的活兒,就叫做佈局繞線。
而且它不能隨便亂塞。工具會一刻不停地檢查自己有沒有守住面積預算(晶片不能長得太大)和功耗預算(不能抽走太多電流),同時還要讓導線足夠短,好讓訊號準時到達。這是一道城市那麼大的裝箱難題,卻要在幾個小時內解開。
驗證與時序
在走完上面這一切的過程中,尤其是在拍板量產之前,設計必須被證明是正確的——因為晶片一旦出貨,你沒法再打補丁。驗證就是那張安全網,它有好幾種花樣。模擬(simulation)給設計餵進假裝的輸入、再核對輸出,就像真飛之前先上飛行模擬器。形式化檢查(formal checks)走得更遠,用數學去證明某條性質對每一種可能的輸入都成立,而不只是你碰巧試到的那幾種。
最難守住的承諾是時序(timing)。還記得那個打節拍的時脈嗎?每一個離開暫存器的訊號,都得穿過沿途的邏輯閘,並在下一個時脈跳動之前抵達下一個暫存器。哪怕只有一條路徑太慢,那一拍就會在半路上把訊號截住,於是晶片算出一堆垃圾。讓每一條路徑都按時安頓好,叫做時序收斂(timing closure)——在一塊大晶片上,要檢查的路徑可能多達上百萬條。
下線(Tape-out)
當驗證通過、每條路徑都完成時序收斂,設計就迎來它的高光時刻:簽核(sign-off)。團隊跑完最後一整套檢查,所有該批准的人都批准了,然後這份完工的設計被送往工廠——也就是晶圓廠(foundry)——送過去的是一套光罩(masks),那是工廠用來把晶片印到矽片上的「模板」。這次交付,就叫做下線。
這個有點好笑的老名字,來自從前——那時完工的設計真的會被寫到一卷磁帶上,再帶出門送去晶圓廠(fab)。磁帶早就沒了,但這一刻的分量沒變:一旦下線,你就收不回來了。光罩會被做出來,晶圓會被印出來,幾週之後,第一批真正的晶片就回到自家手裡接受測試。
EDA 工具在做什麼
退後一步看整段旅程,有一個事實會跳出來:思考是人做的,但搭建是軟體做的。綜合器、佈局器、繞線器、時序檢查器、各種驗證引擎——它們全都屬於一個大類,叫做 EDA,是 Electronic Design Automation(電子設計自動化)的簡稱。你剛剛讀到的每一個環節,都跑在 EDA 軟體上。
而它非這樣不可,原因其實很簡單。一塊現代晶片可以裝下幾百億個電晶體。要是你一秒擺一個、純手工、還從不睡覺,你也得擺上好幾個世紀。沒有任何一個人、也沒有任何一支人類團隊,能用手工設計出那麼大的晶片——這個規模根本超出了我們的能力。是 EDA,把不可能變成了日常。
- 規格:定下晶片要做什麼,以及它的速度、功耗、面積預算。
- RTL:用 Verilog 或 VHDL 一個暫存器一個暫存器、一拍時脈一拍時脈地描述行為。
- 綜合:把 RTL 編譯成一張由邏輯閘和標準單元組成的網表。
- 佈局繞線:給晶粒做佈局規劃、擺放每個單元、繞好金屬線,並守住預算。
- 驗證並收斂時序:模擬、證明,並確保每條路徑都跑贏時脈。
- 下線:簽核,把光罩送去晶圓廠——這是不可回頭的一步。
所以下次你拿起一部手機,記得它內部那個奇妙的小奇蹟:一個寫成規格的願望,變成了程式碼,編譯成了邏輯閘,由軟體裝箱接線,一拍一拍地核對過,最後印到一小片比你指甲還小的矽片上。這就是 IC 設計流程——而現在,你已經把整條路走完了一遍。