為什么我們需要開源的系統芯片?
現代的小型電子產品往往基于某個高度集成的芯片構建,這種芯片稱為“系統芯片”(System on aChip,縮寫:SoC)。最早的家用計算機主板大約包含一百多個芯片,然而當80286 PC/AT兼容機成為主流后,在摩爾定律的推動下,主板上的芯片減少到了寥寥幾個,而且這個行業永遠不會走回頭路。現在,典型的SoC可以集成一個CPU核心組件,以及數十個外圍設備,包括模擬、RF和電源等功能。我們甚至還有“系統級封裝”解決方案,可將SoC、RAM,有時甚至將FLASH芯片封裝到一個塑封中。
現代SoC極其復雜。現代SoC完整的“用戶手冊”往往長達幾千頁,而bug列表也有幾百頁。我在“用戶手冊”上加了引號,因為即使是最開放、文檔最齊全的SoC(例如NXP的i.MX系列),也必須簽署嚴格的保密協議,才能閱讀各種第三方知識產權功能模塊對應的數千頁文檔,例如視頻解碼、圖形加速以及安全等。除了需要保密協議的文檔之外,通常還有數千頁未發布的、針對那些不再使用的芯片區域的文檔,例如原本設計中包含但最終未能成功的外圍設備,內部調試工具以及預引導工具等。許多不再使用的功能,甚至連設計芯片的團隊都不知道。

不再使用的芯片區域是一件大事,因為構建芯片可不像搭樂高積木那般簡單,它更像是雕刻家刻在大理石快上的雕塑,因此添加電路的難度遠遠高于關閉電路。增加一條電路僅制作新的掩膜就大約需要花費100萬美元,同時還會導致項目延遲70天(大約10萬人時的額外工作)。而在正確計劃的情況下,關閉一條電路非常簡單,只需要修改代碼,或者針對某個掩模層進行輕微改動,只需要花費大約1萬美元以及幾天的延遲(假設晶圓尚處于中期階段,很容易進行這樣的改動)。
因此,剛開始的時候,系統芯片的掩模組常常擁有很多額外的功能、備用邏輯和調試功能,然后逐步剔除(棄用)部分功能,直到最后系統芯片成型。正如米開朗基羅曾經說:“每一塊大理石中都隱藏著一個雕像,而雕塑家的任務就是發現它。”
而我們可以說:“每個系統芯片的掩模組中都隱藏著一個數據手冊,而驗證團隊的任務就是發現它。”有時,最后的修補發生在啟動時刻,利用一些在CPU執行任何指令之前就執行的代碼來關閉錯誤的功能或者打補丁。這樣做的結果就是,即使是文檔最完善的系統芯片中,被標記為不再使用的晶體管數量也不可忽視,盡管理論上這些晶體管不會被用戶看到。
從安全角度來看,系統芯片中的這種“暗物質”的存在令人擔憂。不必擔心ROM的啟動或CPU微代碼的問題,內建自測試(Built in Self Test,即BIST)基礎設施具有執行代碼注入所需的一切,你只需將它設置為正確的模式。此外,系統芯片集成商都會從寥寥幾個IP供應商那里購買DDR、PCI和USB等功能塊。這意味著,成千上萬的設備都加載了相同的棄用邏輯單元,甚至不同品牌和競爭產品之間也一樣。所以,系統芯片中存在無法修補,甚至可能破壞生態系統的危險。
為了規避這種風險,Precursor使用FPGA來實現系統芯片。FPGA允許使用者重新編程,從而極大地降低了設計錯誤帶來的成本。我們不必再像大理石雕刻那樣做減法,而是可以像樂高積木那樣來搭建。當然,這種靈活性需要付出一定的代價:FPGA的價格比同等功能的系統芯片高50倍,而絕對頻率則慢5-10倍。
但是,這樣能保證Precursor中沒有暗物質,因為描述系統芯片的每一行代碼都可以查看。這也意味著,如果Precursor的系統芯片中發現邏輯錯誤,則可以通過更新對其進行修補。這大大降低了迭代系統芯片的成本,從經濟的角度來看它也可以向開源靠攏。理想情況下,Precursor的系統芯片設計將在未來幾年內成熟并接受徹底的審查,以低風險的方式朝著打造固定芯片的方向發展,從而降低生產成本并提高性能,同時保持高標準的透明度。
LiteX:Precursor系統芯片背后的框架
Precursor的系統芯片使用LiteX構建。LiteX是由Florent Kermarrec創建的框架,使用Migen/MiSoC FHDL定義系統芯片,該框架本身是用Python 3.6+編寫的。LiteX的核心是一組“處理程序”,它們能夠自動根據總線標準和寬度進行適配。這樣,設計人員可以很容易地在Wishbone、AXI和CSR等總線互聯標準下混合使用不同的控制器和外設。只需幾行代碼就可以將一個額外的USB調試控制器連接到一個復雜的系統芯片中,而且整個總線仲裁和適配器的架構能夠自行做出響應。
Precursor系統芯片簡介

上圖是于2020年10月發表的Precursor芯片系統的示意圖。請隨時關注圖中的日期,因為基于FPGA的系統芯片會不斷發生變化。一般,我們都不用太在意這般漂亮的手繪示意圖,因為通常這些圖片在完成的那一天就已經過時了。而我們的CI系統會在每次代碼推送時,動態生成“程序員手冊”。對于Rust程序員,我們的svd2utra工具可將LiteX生成的SVD文件自動轉換為Rust API的crate。使用基于FPGA的開源系統芯片,自動化CI不僅是最佳實踐,而且是至關重要的部分,因為有時子模塊依賴項中一個很小但很重要的補丁會不斷影響你的設計。
核心區域
“核心區域”(Core Complex)目前由一個RISC-V核心構成,它由Charles Papon的VexRiscV實現。我們將其配置為支持“RV32IMAC”指令子集,給它添加了一個MMU,還強化了緩存。VexRiscV將緩存大小限制為4kB,但可以通過增大緩存關聯來提高有效容量。通過給核心添加一個雙向I-cache和一個四向D-cache,我們將性能提升了大約10%。我們還準備了一個32kB的啟動ROM,目前包含三條指令,但以后可以擴展,可以對從外部內存加載的代碼進行簽名檢查。還有一個128kB的板載SRAM,用于緊密耦合或高安全性的操作。CPU核心被適配到一個由LiteX實現的Wishbone總線多用控制器上,以后可以進一步利用獨立的CSR橋適配到CSR總線上,只需要將CSR橋配置為自動在4kB頁面邊界上進行空間并行,從而與MMU單獨建立映射。還有一個IRQ控制器負責管理來自芯片周圍外設的中斷。

核心區域還包含一組負責執行下面功能的CSR,大部分為樣板代碼:
“Reboot”可以為重置向量指定一個新位置
“Ctrl”可以發送軟重置
“Timer 0”是LiteX提供的默認定時器。這是一個高解析度的32位定時器,時鐘頻率與CPU核心頻率相同。
“CRG”是負責控制FPGA時鐘生成器的接口。目前我們還沒有考慮太多,但最終它將在電源管理和延長電池壽命方面發揮重要作用。
“Git Info”是一個靜態寄存器,提供用于構建Precursor芯片的git代碼庫的信息。
“BtSeed”是一個64位數,經過隨機初始化后可以為布局布線過程提供一個熵。如果最終用戶要求為其設備設計獨有的FPGA網表,那么通過BtSeed,無需改動代碼就可以實現(否則所有構建都是完全相同的)。
“Litex ID”是一個可供人閱讀的文本字符串,用于標識系統芯片設計。
“TickTimer”是一個低分辨率的64位定時器,時鐘增量為1毫秒。它作為Xous OS的時鐘源使用。
調試塊
核心區域旁邊是一個調試塊。調試塊擁有一個全速的USB MAC/PHY,負責為Wishbone包打開隧道,從CPU的角度來看,它是另一個Wishbone控制器。我們使用給它來驅動CPU上的調試接口。這樣即使CPU停機,也可以通過USB用GDB連接到Precursor上。甚至可以構建一個不帶RISC-V CPU的Precursor,然后通過USB來為Wishbone包打開隧道,進行調試和驅動開發。調試塊還包含一個名為“Messible”的小型CSR外設,這是一個包含64個元素的8位寬FIFO,可以在調試時作為郵箱或草稿使用。

內存映射和CSR I/O
RISC-VCPU的內存空間通過Wishbone總線映射到多種外設和內存塊上。在傳統的系統芯片設計師看來,Wishbone有點像AXI,只不過是開源的。Wishbone支持許多很棒的特性,如多master、流水線和塊傳輸等。Wishbone總線空間的一部分還映射到了一個名為“配置和狀態寄存器”(Configurationand Status Register,CSR)的總線上。
雖然Wishbone是高性能總線,但它需要更多的接口邏輯,而且只在外設帶寬匹配總線帶寬時才能發揮最佳性能。CSR有區域效應,從硬件和軟件API兩方面都可以適應任意寄存器位寬,但性能較低。因此,CSR最適合用作低速到中速的輸入輸出任務(例如命名配置和狀態寄存器),這些任務中Wishbone非常適合映射到內存上的I/O,這樣可以提高帶寬并改善延遲,足以補償區域效應帶來的額外開銷。

在設計過程中,絕大多數外設的第一步都是映射到CSR空間,然后升級成內存映射實現,從而達到性能要求。因此,Precursor上的絕大部分外設都是僅支持CSR的設備,這并非偶然。下面是每個CSR外設的簡單介紹。需要提醒一點,你可以查看我們的參考手冊以獲取更詳細的信息。
“COM SPI”是連接到嵌入控制器(EmbeddedController,EC)系統芯片上 的SPI總線。這是一個20MHz的SPI外設,傳輸帶寬為固定的16位。該塊的目標為升級成內存映射I/O塊。
“I2C”是一個I2C總線控制器。目前,只有實時時鐘(RTC)芯片和一個音頻編碼解碼芯片連接到了這個I2C總線上。
“BtEvents”是一個負責各種外部實時終端的catch-all類型的塊。目前它負責處理來自EC和RTC芯片的中斷。
“KeyScan”是鍵盤控制器。它負責掃描9x10的鍵盤矩陣來發現擊鍵,使用一個慢速的32kHz外部時鐘源。將鍵盤掃描器與系統核心時鐘解耦合,系統就可以在等待鍵盤輸入時進入更低功耗狀態,從而將Precursor在兩次充電之間的使用時間延長數天。
“BtPower”是一組GPIO,專用于電源管理。它可以將音頻和離散的TRNG打開或關閉,覆蓋EC的電源控制指令,為USB type C端口激活boost模式(以支持DFP“宿主”操作),還可以采用自毀機制。
“JTAG”是一組GPIO,連接到FPGA的JTAG引腳。這些與我們的eFuseAPI驅動結合使用,可以在7 Series FPGA上自行提供AES比特流加密。
“XADC”是7 SeriesXADC塊的接口。它是一個12位的多通道ADC。主要用于自我監測系統電壓。在最終的產品版本中,至少有一個通道的ADC可以用于GPIO內部頭的配置項,這樣用戶可以很容易地將模擬傳感器集成到Precursor中。
“UART”是一個簡單的115200、8合一串口,連接到控制臺I/O的調試頭。
“BtGpio”是一個數字I/O塊,用于在GPIO內部頭上驅動引腳。注意由于FPGA的實現限制,在不更新比特流的情況下無法在數字GPIO和模擬GPIO功能之間切換。

除了CSR的I/O之外,還有一些I/O設備也映射到了內存,以實現高性能:
“External SRAM”是一個32位寬的一部接口,映射了16MB的外部SRAM。這些SRAM由電池供電,所以在系統芯片斷電時也可以保持狀態。這樣做的目的是通過減少睡眠和喚醒的額外開銷來優化電力消耗。但是,這也意味著自毀過程必須先清除SRAM中的敏感數據,才能啟動清除系統芯片的過程,因為自毀電路也是由SRAM的備用電源負責供電的。外部SRAM塊還有一個CSR接口,負責從SRAM中讀取配置模式。
“Audio”是一個連接到外部音頻編碼解碼的I2S接口。它包含一個用于配置I2S接口的CSR塊,還包含一對256x16的、映射到內存的采樣FIFO。
“SPI OPI”是一個類似于SPI的高速接口,連接到外部閃存存儲,并映射了12個8MB的非易失性存儲器上。OPI中的“O”代表八位,這是一個8位總線,頻率為DDR的100MHz。它還包含一個與讀取器,可以存儲相當于數個緩存線的代碼,可以優化順序代碼執行的情況。該總線的高性能非常重要,因為它主要被CPU用來運行代碼。它還包含一個CSR接口,用于控制諸如塊擦除、頁面編程等操作。
“MemLCD”是LCD的幀緩沖。Sharp Memory LCD包含自己的內部內存,因此即使宿主斷電,也能夠維持圖像。因此,MemLCD幀緩沖就是LCD自身的緩沖。它負責管理LCD中的哪些線需要重畫,在CSR上有請求發生時,它只會刷新那些需要重畫的線。這樣可以提高LCD的感知刷新率。如果重畫整個屏幕,那么刷新率只有10Hz;但屏幕上的靜態內容越多,刷新率也就越高。
加密區域
前面描述的所有功能僅占用了FPGA大約20%的邏輯,而Precursor的FPGA的主要邏輯位于加密區域。

上圖展示了在Precursor系統芯片設計中各個功能的相對尺寸。一些塊(如半冗余SHA-512和SHA-2加速器)的存在,僅僅是因為FPGA中能夠容納這些功能,而不是因為有需求。幸運的是,刪除SHA-2塊很簡單,只需要注釋掉4行代碼,能節約大約2800個SLICE LUT,相當于大約9%的設備資源。LiteX和svd2rust腳本會負責其余的一切!

下面是加密區域中各個塊的簡要說明:
“Engine25519”是算術加速器,用于加速2^255-19質數域中的操作。它是一個微指令的256位算術引擎,計算帶有正規化的256位乘法僅需要大約1微秒,比在RISC-V CPU上運行同等操作大約快30倍。它需要消耗大量的資源,但依然非常重要,因為Betrusted安全通信應用程序建立在Double-Ratchet算法上,該算法非常依賴這種運算。要理解Engine25519,最好從CI文檔開始閱讀。該塊非常大,稍后我們會單獨寫一篇文章來解釋它的功能。
“SHA-512”和“SHA-2”是硬件加速的SHA散列塊。它們來自Google的OpenTitanSystemVerilog源代碼。SHA-2塊直接來自OpenTitan,幾乎包括了OpenTitan的所有代碼,因為它非常容易集成。SHA-512塊是我們自己對SHA-2塊的改進。由于歷史原因,目前的Precursor中同時包含了兩個快,盡管絕大部分應用程序僅需要其中一種。
“AES”是一個AES加速器,也直接來自Google的OpenTitan項目。它可以支持AES 128、192和256,還支持ECB、CBC和CTR模式下的加密和解密。
“KeyROM”是一個256x32的ROM,使用FPGA中的固定位置LUT實現。由于ROM的位置是固定的,我們可以使用PrjXray來確定FPGA比特流中KeyROM比特的位置。這樣就可以在FPGA比特流中直接編輯KeyROM,從而將信任從低層的eFuse AES key傳遞到Precursor系統芯片中的高層功能中。我們會在其他文章中進一步討論一些最近發現的FGPA eFuse AES key的重要脆弱性。
“TRNG”是芯片內的、基于環形振蕩器的真隨機數生成器。它使用多個小環來收集足夠多的熵,然后合并成一個大環,用于最終的測量。Precursor TRNG的構建和驗證也會另文介紹。
“ICAPE2”是在FPGA構造(fabric)中對未使用的內部調試端口的顯式綁定(tie-down)。ICAPE2是Xilinx采用的方法,FPGA可以通過它進行內省,并訪問內部配置狀態。我們顯式地將其綁定,這樣其他功能就無法使用它。此外,由于ICAP2位于比特流中眾所周知的位置,實際上可以寫一個工具,在編譯后對比特流進行檢查,以驗證ICAP2塊確實被禁用了。
分塊的思路
以上就是對Precursor系統芯片的介紹!我們按照功能和安全性分塊,希望開發社區能夠添加更多內容。只需要注釋掉一些代碼,就可以去掉不需要的塊,為你自己的創作騰出空間。Precursor的代碼完全開源,沒有任何隱藏的測試邏輯,也沒有微代碼塊,你如果想追蹤從電源鍵按下到第一條指令執行之間發生了什么事情,也不需要簽署保密協議。此外,Precursor系統芯片還有一個值得你信賴的原因:沒有“暗物質”,設計完全透明。
原文:https://www.bunniestudios.com/blog/?p=5971
*博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。
透射電鏡相關文章:透射電鏡原理










