RISC-V基金會(RISC-V Fundation)由於同時擁有開源自由與標準化的優勢,正吸引著廣泛的業界關注。RISC-V核心標準穩定進展且即將被批准,其軟核心、硬核心CPU以及晶片、開發板和工具都已實現商用,許多主要的公司開始採用RISC-V來取代其客製架構。該架構的一個關鍵特性是CPU開發人員可以根據需求調整RISC-V功能,而無需犧牲為基本標準所創建的適用工具與庫。這種適應性的關鍵在於必須瞭解RISC-V模組化指令集架構。

RISC-V最初是美國加州大學柏克萊分校(UC Berkeley)精簡指令集運算(RISC)設計工作的第五次反覆運算,但它很快地就從學術研究演變為一場尋求重新定義電子產業處理硬體設計方法的運動。目前的情況是,系統開發人員必須選擇通常為特定應用領域最佳化的專有CPU架構,或設計自己的CPU架構。然而,要追求自己的設計,開發人員就必須放棄現有CPU所形成的廣泛支援生態系統。一個折衷辦法是:在保留大部份支援生態系統的同時,調整專有CPU架構以實現客製。遺憾的是,由於專有架構涉及高額的授權費用,這種折衷方法對於許多設計團隊來說並不切實際。

RISC-V計畫是在保留標準化優勢的同時,為設計人員提供可客製、創新的替代方案。為此,RISC-V基金會一直在推動模組化、開源RISC-V處理器指令集架構(ISA)的社群發展,以滿足從嵌入式系統到伺服器的各種應用需求。該架構的規範提供免費下載,開發人員可以自由實現基於ISA的設計而無需支付授權費。如同其他開源計畫一樣,開發人員並沒有義務向其他人開放其設計。它是開源ISA,但如果開發人員希望的話,個人設計、硬體架構以及客製化都可以保持專有。

該計畫目前發展態勢強勁,已經有RISC-V晶片以及核心的商用和開源了。SiFive、GreenWaves Technologies和Microsemi等公司都已開發了基於RISC-V架構的開發板。開發工具、軟體庫和作業系統埠(包括Linux)都是當前RISC-V支援生態系統的組成部份。但是,要全部利用這項支援以實現客製設計,首先需要認真研究RISC-V ISA的架構。

基本規格

RISC-V ISA的定義包含兩個關鍵檔案:基本用戶級(User-level) ISA規範和特權(Privileged) ISA規範。其中包括對於基本要求和豐富的標準化、模組化擴展加以定義。標準擴展是模組化的,在CPU設計中實現任何給定的標準擴展都不會干擾任何其他標準擴展的實現。但是,某些擴展可能基於其他擴展,需要將基本擴展作為所需擴展的一部份來實現。

RISC-V的整體設計基於暫存器,所有的操作以及對一般記憶體空間的載入和儲存存取都是透過調用31個通用暫存器進行。指令集對於32位元、64位元和128位元的位址空間進行了定義,並另行定義一個精簡暫存器數的32位元指令集,專門針對嵌入式系統設計的較少閘數實現。除了存在附加指令以處理較長字長,以及暫存器大小與位址空間匹配以外,這些變化版本的指令編碼也都相同。

圖1示意圖顯示了核心規範與標準擴展的對話模式。RISC-V基金會現已凍結許多規範,從而確保基於這些規範的建置在ISA演進的過程中始終有效。這樣能夠確保今天編寫的軟體可以永遠在類似RISC-V核心上運行。某些擴展指令集仍處於草案模式中,因此將來可能發生變化。還有一些被保留了,即留下了一些預留位置以待未來的發展。例如,32位元和64位元基本整數ISA已經凍結,而128位元和嵌入式變數仍處於草案中。

基本整數指令集(I)是建構其他所有指令的基礎,必須包含於任何建置中。除了基本整數ISA以外,所有的標準RISC-V建置必須至少包含特權ISA的機器級部份;監管者(supervisor)級(S)和監管程式(hypervisor)部份則屬於標準擴展。然而,特權級ISA被定義為:如果開發人員願意,他們可以實現客製形式的特權程式碼執行,而不會影響基本整數ISA。

20190808_RISC-V_NT31P1

圖1:RISC-V ISA構成了一個模組化的指令組合,可建置於CPU設計中,而彼此之間互不干擾。

使用標準擴展以增強基本功能

基本整數ISA (I)和機器級特權ISA提供了基本通用CPU所需的所有功能。但是開發人員也可以透過向ISA添加擴展來增強這些基本功能。開發人員可以自訂擴展,但是已經有很多標準擴展,RISC-V基金會技術任務組對其進行管理,從而確保它們對設計社群具有廣泛的吸引力,而且其指令並不會與其他標準擴展衝突。因此,開發人員可以自由地在其設計中包含他們需要的任何標準擴展,而無需擔心指令編碼中會有衝突。這些標準擴展包括:

  • M – 對兩個整數暫存器中保存的值進行乘法和除法的指令(凍結)
  • A – 對記憶體進行原子讀、改、寫操作的指令,以支援同步(凍結)
  • F、D和Q – 符合IEEE 754-2008算數標準的(F)單精確度、(D)雙精度和(Q)四精度浮點運算的指令。每種精度的擴展取決於當前的較低精度擴展。(凍結)
  • G – 由於包含基本整數規範(I)以及M、A、F和D標準擴展的建置非常受歡迎,基金會將這個組合定義為G,並將G配置為開發中的編譯器工具鏈目標。(凍結)
  • V – 向浮點擴展添加向量指令的指令(草案)
  • L – 十進位浮點計算指令(保留)
  • B – 位元級操作指令(保留)
  • N – 處理用戶級中斷的指令(草案)
  • P – 支援封包單指令、多資料指令的擴展(保留)
  • T – 支援事務記憶體操作的指令(保留)
  • J – 支援動態翻譯語言的擴展(保留)
  • C – 支援壓縮指令執行。基本整數(I)規範要求指令字長32位元,並在記憶體中的32位元邊界上對齊。建置C標準擴展提供了16位元常用操作的編碼,使CPU設計可在自由混合的32位元和16位元邊界上對齊,從而使程式碼長度縮減25%至30%。它可以以任何基本整數位元寬度和用任何其他標準擴展實現。(凍結)
  • S – 特權ISA的supervisor級擴展(草案)

與用戶級ISA一樣,特權ISA使設計人員可以決定所包含的複雜度。該規範定義了兩組ISA:機器級和supervisor級,以及為了支援虛擬化hypervisor功能而為相應指令保留的預留位置。這些指令集又使開發人員能夠支援程式碼可操作的最多三個特權級(圖2)。單個特權級別(機器級)意味著所有運行的程式碼都可以完全存取系統資源,例如在簡單嵌入式系統中運行的單個應用程式。具有兩個特權級(需要機器和supervisor ISA指令),可以支援部份系統資源與圖1應用程式碼隔離,以增強軟體安全性,並使作業系統支援多個同步應用。三個特權級則可支援類Unix作業系統和hypervisor等。

20190808_RISC-V_NT31P2

圖2:兩個特權ISA級可以支援多種軟體配置,包括簡單的應用執行環境(AEE)、在採用supervisor執行環境(SEE)的單個作業系統上執行的多個應用程式,以及具有hypervisor的多種作業系統。
(來源:RISC-V基金會)

憑藉標準擴展和特權級的所有可能組合,‘RISC-V’的簡單命名還不足以表徵ISA的某個實際硬體建置。為了闡明程式人員在採用特定硬體建置時能夠存取哪些指令,基金會設計了一個核心命名法。如圖3所示,該命名包含三個部份:所使用的基本規範(如RV32I、RV64I等)、增加的標準擴展(如M、F、A等),以及每個元素的版本編號(如版本1.2標為1p2等)。為了簡單起見,在許多情況下可以省略版本編號(如RV32IC、RV64G等)。

20190808_RISC-V_NT31P3

圖3:RISC-V的命名完整地描述了其所支援的指令集。

該命名慣例也可以用於辨識客製擴展。基本整數ISA的擴展使用開發人員選擇的名稱並採用Xname的形式,再加上適當的版本編號。如果擴展涉及到特權ISA的supervisor級,則形式為SXname。

超越標準擴展

即使模組化標準擴展提供了設計靈活性,RISC-V標準並未提供許多開發人員可能希望的指令增強功能。例如,某個應用程式需要頻繁地對兩個16位元整數(例如兩個ADC的測量值)進行向下取整求平均值運算,即(r1+r2)/2。若使用基本整數ISA,計算所需的平均值將會需要執行兩條指令:整數加法和算術右移(後者實際上執行整數除以2,並向下取整)。但如果採用一條可用一步執行兩個操作的自訂指令,就可以加快應用程式的軟體執行速度。如果採用ISA的標準指令格式,RISC-V ISA可以輕鬆添加這樣的指令。

RV32I基本指令集遵循四種基本格式,如圖4所示。R類指令從兩個來源暫存器(rs1和rs2)取值,並以某種方式(add、XOR等)對它們進行組合,形成一個值並將其儲存到第三個暫存器,即目標暫存器(rd)中。I類指令獲取一個來源值(rs1)和一個以指令本身編碼的12位元值(imm),將其組合並儲存到目標暫存器(rd)中。載入指令使用I類格式,結合來源值和立即數以確定記憶體位址,並將其內容傳送到目標暫存器。S類指令從一個來源暫存器取值,將其儲存到第二個暫存器的內容和立即數組合所指向的記憶體位址。S類指令的B類變體格式相同,但使用兩個值來計算條件分支指令位址。U類指令可使用大於12位元的立即數,而J類變體使用該立即數以執行無條件跳轉。

20190808_RISC-V_NT31P4

圖4:RISC-V指令的四種基本格式。
(來源:RISC-V基金會)

這些指令格式的定義方法讓開發人員可以輕鬆地在混合指令集中添加自訂指令。所有的指令都在低位元包含一個7位元操作碼(opcode),除了U類格式外的所有指令在12至14位元都有一個功能碼(funct3)。R類指令在第25至31位元有一個第二功能碼(funct7)。當涉及目標暫存器位址時,它始終位於第7至第11位元,第一個來源暫存器位址始終位於第15至19位元,另一個來源暫存器則位於第20至24位元。這種程式碼和暫存器指標安排的一致性意味著,如果使用者可以將其新指令映射為這些基本格式之一,並且可以以某個相容的RISC-V設計開始,那麼建置該指令的硬體設計幾乎已經完成。大多數的新操作(例如指令解碼和暫存器資料存取)都存在於現有設計中,用戶可以充份進行利用。

以添加求均值指令為例來說明,可參考圖5中的流程圖。現有的整數類RV32I ADD和SUB指令遵循R類格式,並且opcode (0110011)和funct3 (000)程式碼值完全相同,僅funct7程式碼不同(0000000 vs. 0100000)。沒有其他RV32I指令使用該opcode和funct3組合,剩下120多種可能的funct7值都可用於編寫新指令,而不會觸碰任何標準指令。如圖所示,這些標準指令的一種可能建置是,將兩個來源暫存器的值送往算術單元進行加法或減法運算(取決於位元指令30),並將結果傳送到目標暫存器。

20190808_RISC-V_NT31P5

圖5:修改標準RISC-V建置,以添加兩條新指令。

添加新的求均值指令只需要對這個硬體進行微幅更改。例如,可以從指令解碼邏輯中提取指令位元25,用它來對算術單元之後插入的一組新的多工器發送命令來完成。這一位元可以使多工器在將修改前的標準ADD或SUB結果傳送到目標暫存器之前,先將其右移一位元。該設計現在僅用於少量的附加邏輯閘數,就可以實現ADD和SUB以及兩條新的指令:求平均值[(rs1+rs2)/2]和求差值二分[(rs1-rs2)/2]。這種圍繞現有指令編碼的自訂擴展被稱為棕地擴展(brownfield extension)。

指令擴展機會比比皆是

RISC-V為棕地擴展提供了許多機會。RV32I基本ISA由於利用3位funct3和7位funct7值來定義大指令類型上的微小變化,因此僅使用128個(7位元)主要操作碼中的11個,就定義了其47個不同的指令。大多數標準擴展和較長的基本整數變體(RV64I、RV128I)只需要幾個額外的主要操作碼。這就留下了充足的空間,可用於對新的棕地擴展指令進行編碼。只有壓縮指令(C)標準擴展添加了大量獨特的指令程式碼來解釋其在指令長度上的多種變體。即使這樣,它也是以最小化操作碼命令的方式實現的。

圖6給出了具有G標準擴展的32位元、64位元和128位元寬基本整數建置中可用的未定義主要操作碼,預計將成為開發人員所採用的最常見配置。RISC-V基金會將避免在未來的任何標準擴展中使用這些,以確保開發人員的設計與這些標準擴展相容。其他則保留用於未來的標準擴展以及預期的128位元基本整數標準,但若開發人員並不擔心未來可能出現不相容性,當然也能加以使用。

20190808_RISC-V_NT31P6

圖6:可用RISC-V主要操作碼的映射。

對於希望為基本整數(I)規範創建客製化擴展而不考慮所有標準擴展的開發人員來說,機會更加豐富。例如,RISC-V ISA定義了其所有基本整數(I)和大多數標準擴展指令,其編碼的兩個最低有效位元(LSB)都設置為x11。只有壓縮(C)標準擴展所定義的指令將這些位元設置為x00、x01或x10。因此,開發人員如果不需要C標準擴展,則可以隨心所欲地定義指令的這些LSB位元模式。這為他們提供了三個30位元指令編碼空間,可以在不影響基本整數ISA或任何其他標準擴展的情況下自由發揮。

RISC-V計畫的一個主要目標是促進創新和客製化,但又不至於導致成長中的生態系統零碎化。為了實現這一目標,需要所有開發人員在擴展基礎架構時均遵守ISA準則和要求。

(參考原文:Creating a custom processor with RISC-V,by Richard Quinnell)

本文同步刊登於電子技術設計雜誌2019年8月號