在計算機歷史的浩瀚星空中,PDP-11 系列無疑是其中最璀璨的星座之一。這款 DEC 於 1970 年推出的 16 位元迷你電腦,不僅定義了現代指令集架構的雛形,更深刻影響了 Unix 作業系統的誕生與發展。時至今日,愛好者與歷史學家們仍在透過模擬器重溫這段歷史,然而模擬的精度邊界始終是個值得探討的議題。當絕大多數 PDP-11 模擬器滿足於指令級別的精確性時,ll-34 專案選擇了一條更為激進的道路:在晶體管層面完整重建 PDP-11/34A 的硬體行為。

從原理圖到可執行代碼:逆向工程的艱辛之旅

ll-34 的核心創新在於其「電路級模擬」(circuit-level emulation)的定位。專案作者 Damien Boureille 從 Bitsavers 獲取的 DEC 原始原理圖出發,將整個 KD11-EA CPU 翻譯為 C 語言程式碼。這種做法不同於傳統的閘極級模擬(gate-level),後者通常使用 Verilog 或 VHDL 描述硬體行為;相反,ll-34 採用了 ROM 查找表結合組合邏輯的混合方式。

這種設計選擇蘊含著精心的工程考量。作者在專案文件中明確指出,選擇電路級而非閘極級的原因是:電路級模擬足夠底層以重現硬體層面的臭蟲,同時又足夠高效以執行實際程式。換言之,這是精確度與效能之間的精妙平衡點。若要完全模擬每一個 74 系列邏輯閘的傳播延遲,效能將嚴重下降到無法實際使用的程度;而僅模擬指令執行則會喪失諸多硬體特有的時序特性。

在具體實現層面,ll-34 的虛擬 CPU 由多個關鍵模組構成。微碼 ROM(ucode_rom.h)存儲了 512 個 48 位元的微指令,這些雙極性 PROM 直接控制著 ALU、暫存器匯流排與分支邏輯。組合邏輯 ROM(combo_roms.h)則涵蓋了指令解碼、ALU 函數選擇、陷阱優先權處理與條件碼邏輯,全部根據原理圖與邏輯擷取重新建構。資料路徑引擎(kd11ea.c)使用基礎的 C 邏輯運算子(!、&&、>> 等)模擬 74xx 系列閘,而 4 個 74S181 位元切片 ALU 被完整模型化,構成 16 位元的運算核心。

時序建模的挑戰:時脈產生器與匯流排協議

晶體管級模擬最為困難的環節莫過於時序建模。PDP-11/34 的時脈系統包含一個 E106 延遲線元件,產生 TAP 30、TAP 90 與 TAP 120 三組回授信號,並透過 TRAN INH 匯流排實現等待狀態。ll-34 的 clockgen.c 精確模型化了這一過程:短週期為 180 奈秒,長週期為 240 奈秒,而匯流排傳輸會自動延長直到從設備返回 SSYN 確認信號。

UNIBUS 匯流排的時序同樣至關重要。ll-34 的 unibus.c 模組實現了完整的匯流排仲裁、位址解碼與傳輸協定,包括 BR4 至 BR7 的中斷優先權佇列與 daisy-chain 授權順序的近似模擬。這種程度的時序精確性使得模擬器能夠重現真實硬體中罕見的時序競合問題,例如多個周邊裝置同時競爭匯流排時的訊號衝突。

微架構級精確實現:傳統軟體模擬器的設計取捨

與 ll-34 的電路級方法形成鮮明對比的是傳統的軟體模擬器。以 SimH 為代表的經典模擬器採取了「指令級精確」(instruction-accurate)的設計方針:模擬器只需要確保每條指令的最終結果正確,至於指令內部各階段的時序則以近似方式處理。這種方法的優勢顯而易見:效能極高,可以在現代硬體上以數十倍於原始機器的速度執行;開發與維護相對簡單;對於執行標準軟體(如 Unix V6、RT-11)而言已經足夠。

然而,指令級模擬的局限同樣明顯。當研究目標涉及硬體 - 軟體共同設計、時序關鍵的周邊裝置互動,或需要重現原始硬體中的特殊行為時,這種抽象層級就显得力不從心。例如,某些 PDP-11 程式的運算結果會受到條件碼更新時序的影響,而條件碼的精確時序取決於微架構的具體實現細節。指令級模擬器通常只能根據公開的指令時序規格進行估算,這與實際硬體的訊號層級行為可能存在微妙差異。

另一種折中方案是「微架構級模擬」。這種方法在指令級與電路級之間取得平衡:模擬器建模 CPU 的執行單元、暫存器檔案與微碼,但跳過閘極層級的延遲計算。這種做法可以捕捉到指令執行過程中的資源競合(如多個暫存器同時存取匯流排),同時保持可接受的執行效能。ll-34 的設計實際上可以被視為微架構級的一種極端實現 —— 它几乎觸及了硬體的訊號層面,但透過 ROM 查表而非個別閘極的方式維持了效能。

調試工具的演進:邏輯分析儀的內建化

ll-34 專案中最具啟發性的設計或許是其內建的邏輯分析儀功能。由於模擬器的行為與真實硬體如此接近,開發過程中遇到的問題也與調試真實硬體別無二致。為此,作者在模擬器中直接實現了一個邏輯分析儀,能夠追蹤 102 個主要 CPU 訊號點,這些訊號點採用與 DEC 原理圖一致的 KD1:Exx:pin 命名法。

這個內建分析儀的取樣速率為真實 CPU 時脈(5,555,556 Hz),解析度可達 180 奈秒,並提供可配置的觸發條件與環形緩衝區(最高 64K 樣本)。這一設計揭示了一個深刻的洞見:當模擬器的抽象層級足夠接近硬體時,硬體調試的許多方法論可以直接移植到軟體領域。這種「軟體定義的硬體」不僅是對歷史的致敬,更是一種獨特的研究與教育工具。

工程實踐參數:何時採用何種模擬精度

對於希望在 PDP-11 平台上進行開發或研究的工程師而言,選擇何種模擬精度需要權衡多個因素。若目標是功能驗證並確保軟體執行的正確性,一個經過良好調校的指令級模擬器通常足夠,且能提供數十倍於原始硬體的執行速度。若需要研究作業系統的核心行為、驅動程式的時序依賴,或探索硬體 - 軟體介面的詳細實現,則微架構級模擬能提供更豐富的資訊。

至於電路級模擬,如 ll-34 所展示的,則適用於以下場景:需要精確重現原始硬體的特定行為(如硬體層級的臭蟲或特殊邊緣案例);對 PDP-11 的內部實現進行深入的歷史與工程研究;或將模擬器作為調試工具,輔助維修真實的 PDP-11 硬體。當然,電路級模擬的代價是開發複雜度顯著提升,且執行效能可能降低到接近原始硬體甚至更慢的水準。

小結

ll-34 專案為我們示範了一種超越傳統模擬邊界的方法。透過在 C 語言中重建 DEC 原始原理圖的邏輯結構,這個專案實現了前所未有的硬體忠實度,同時保持了足夠的執行效率以運行完整的作業系統與應用程式。對於計算機歷史研究者、系統軟體開發者與懷舊愛好者而言,這種電路級模擬提供了一個獨特的視角,讓我們得以窺見那個由邏輯閘與微碼構成的時代中,硬體與軟體之間最原始也最純粹的互動方式。


資料來源: ll-34 專案 GitHub 倉庫(https://github.com/dbrll/ll-34);Bitsavers PDP-11/34 原理圖檔案。