[轉] RISC-V架構介紹

1. RISC-V和其餘開放架構有何不一樣

若是僅從「免費」或「開放」這兩點來評判,RISC-V架構並非第一個作到免費或開放的處理器架構。算法

在開始以前,咱們先經過論述幾個具備表明性的開放架構,來分析RISC-V架構的不一樣之處以及爲何其餘開放架構沒能取得足夠的成功。安全

平民英雄——OpenRISC

OpenRISC是OpenCores組織提供的基於GPL協議的開放源代碼RISC處理器。服務器

OpenRISC具備如下特色:網絡

  • 採用免費開放的32/64位 RISC架構。
  • 用Verilog HDL(硬件描述語言)實現了基於該架構的處理器源代碼。
  • 具備完整的工具鏈。
  • OpenRISC被應用到不少公司的項目之中。能夠說,OpenRISC是應用很是普遍的一種開源處理器實現。架構

    OpenRISC的不足之處在於其側重於實現一種開源的CPU Core,而非立足於定義一種開放的指令集架構,所以其架構的發展不夠完整,指令集的定義也不具有上節中提到的RISC-V架構的優勢,更加沒有上升到成立專門的基金會組織的高度。OpenRISC更多的時候被認爲是一個開源的Core,而非一種優美的指令集架構。此外,OpenRISC的許可證爲GPL,這意味着全部的指令集改動都必須開源(而RISC-V則無此約束)。ide

    豪門顯貴——SPARC

    SPARC架構做爲經典的RISC微處理器架構之一,SPARC最先於1985年由Sun電腦所設計。SPARC也是SPARC國際公司的註冊商標之一,這家公司於1989年成立,目的是向外界推廣SPARC架構以及爲該架構進行兼容性測試。該公司爲了推廣SPARC的生態系統,SPARC國際公司將標準開放,並受權予多家生產商採用,包括德州儀器、Cypress半導體和富士通等。因爲SPARC架構也對外徹底開放,所以,也出現了徹底開放源碼的LEON處理器。不只如此,Sun公司還於1994年推進SPARC v8架構成爲IEEE標準(IEEE Standard 1754-1994)。模塊化

    因爲SPARC架構的初衷是面向服務器領域而設計,其最大的特色是擁有一個大型的寄存器窗口,符合SPARC架構的處理器須要實現從72到640個之多的通用寄存器,每一個寄存器寬度爲64bits,組成一系列的寄存器組,稱之爲寄存器窗口。函數

    這種寄存器窗口的架構,因爲能夠切換不一樣的寄存器組快速地響應函數調用與返回,所以,可以產生很是高的性能,可是這種架構因爲功耗面積代價太大,而並不適用於PC與嵌入式領域處理器。而SPARC架構也不具有模塊化的特色,使得用戶沒法裁剪和選擇。很難做爲一種通用的處理器架構對商用的x86和ARM架構造成替代。工具

    設計這種超大服務器CPU芯片又非普通公司與我的所能涉足,而有能力設計這種大型CPU的公司也沒有必要投入巨大的成原本挑戰x86的統治地位。隨着Sun公司的衰弱,SPARC架構如今基本上退出了人們的視野。感興趣的讀者請在網絡上自行搜索文章《再見SPARC處理器,再見Sun》oop

    名校優生——RISC-V

    關於RISC-V在伯克利大學誕生的經歷,本節在此不作重複贅述。

    由於多年來在CPU領域已經出現過多個免費或開放的架構,不少高校也在科研項目中推出過多種指令集架構。所以,當筆者第一次據說RISC-V之時,覺得又是一個玩具,或純粹學術性質的科研項目而不覺得意。

    直到筆者親自通讀了一遍RISC-V的架構文檔,不由爲其先進的設計理念所折服。同時,RISC-V架構的各類優勢也獲得了衆多專業人士的青睞好評和衆多商業公司的相繼加盟。而且2016年RISC-V基金會的正式啓動在業界引發了不小的影響。如此種種,使得RISC-V成爲至今爲止最具有革命性意義的開放處理器架構。

    2. 簡單就是美——RISC-V架構的設計哲學

    RISC-V架構做爲一種指令集架構,在介紹細節以前,讓咱們先了解設計的哲學。所謂設計的「哲學」即是其推崇的一種策略,譬如說咱們熟知的日本車的設計哲學是經濟省油,美國車的設計哲學是霸氣外漏等。RISC-V架構的設計哲學是什麼呢?是「大道至簡」。

    筆者最爲推崇的一種設計原則即是:簡單就是美,簡單便意味着可靠。無數的實際案例已經佐證了「簡單即意味着可靠的」真理,反之越複雜的機器越則越容易出錯。

    所謂大道至簡,在IC設計的實際工做中,筆者曾見過最簡潔的設計實現安全可靠,也曾見過最繁複的設計長時間沒法穩定收斂。最簡潔的設計每每是最可靠的,在大多數的項目實踐中一次次的獲得檢驗。

    IC設計的工做性質很是特殊,其最終的產出是芯片,而一款芯片的設計和製造週期均很長,沒法像軟件代碼那樣輕易的升級和打補丁,每一次芯片的改版到交付都須要幾個月的週期。不只如此,芯片的一次制形成本費用高昂,從幾十萬美金到百千萬美金不等。這些特性都決定了IC設計的試錯成本極爲高昂,所以可以有效的下降錯誤的發生就顯得很是的重要。

    現代的芯片設計規模愈來愈大,複雜度愈來愈高,並非說要求設計者一味的逃避使用複雜的技術,而是應該將好鋼用在刀刃上,將最複雜的設計用在最爲關鍵的場景,在大多數有選擇的狀況下,儘可能選擇簡潔的實現方案。

    筆者在第一次閱讀了RISC-V架構文檔之時,不由擊節讚歎,拍案驚奇,由於RISC-V架構在其文檔中不斷地明確強調,其設計哲學是「大道至簡」,力圖經過架構的定義使得硬件的實現足夠簡單。其簡單就是美的哲學,能夠從幾個方面容易看出,後續小節將一一加以論述。

    無病一身輕——架構的篇幅

    在處理器領域,目前主流的架構爲x86與ARM架構,筆者曾經參與設計ARM架構的應用處理器,所以須要閱讀ARM的架構文檔,若是對其熟悉的讀者應該瞭解其篇幅。通過幾十年的發展,現代的x86與ARM架構的架構文檔長達幾百數千頁。打印出來能有半個桌子高,可真是「著做等身」。

    之因此現代x86與ARM架構的文檔長達數千頁,且版本衆多,一個主要的緣由是由於其架構的發展的過程也伴隨了現代處理器架構技術的不斷髮展成熟。

    而且做爲商用的架構,爲了可以保持架構的向後兼容性,其不得不保留許多過期的定義,或者在定義新的架構部分時爲了可以將就已經存在的技術部分而顯得很是的彆扭。長此以往就變得極爲冗長。

    那麼現代成熟的架構是否可以選擇從新開始,從新定義一個簡潔的架構呢,能夠說是幾乎不可能。其中一個重要的緣由即是其沒法向前兼容,從而沒法獲得用戶的接受。試想一下若是咱們買了一款新的搭配新的處理器的電腦或者手機回家,以前全部的軟件都沒法運行而變磚,那確定是沒法讓人接受的。

    而如今才推出的RISC-V架構,則具有了後發優點,因爲計算機體系結構通過多年的發展已經成爲比較成熟的技術,多年來在不斷成熟的過程當中暴露的問題都已經被研究透徹,所以新的RISC-V架構可以加以規避,而且沒有揹負向後兼容的歷史包袱,能夠說是無病一身輕。

    目前的「RISC-V架構文檔」分爲「指令集文檔」(riscv-spec-v2.2.pdf)和「特權架構文檔」(riscv-privileged-v1.10.pdf)。「指令集文檔」的篇幅爲145頁,而「特權架構文檔」的篇幅也僅爲91頁。熟悉體系結構的工程師僅需一至兩天即可將其通讀,雖然「RISC-V的架構文檔」還在不斷地豐富,可是相比「x86的架構文檔」與「ARM的架構文檔」,RISC-V的篇幅能夠說是極其短小精悍。

    感興趣的讀者能夠在RISC-V基金會的網站上(https://riscv.org/specifications/)無需註冊即可免費下載其文檔,如圖1所示。

    圖1 RISC-V基金會網站上的架構文檔

    能屈能伸——模塊化的指令集

    RISC-V架構相比其餘成熟的商業架構的最大一個不一樣還在於它是一個模塊化的架構。所以,RISC-V架構不只短小精悍,並且其不一樣的部分還能以模塊化的方式組織在一塊兒,從而試圖經過一套統一的架構知足各類不一樣的應用。

    這種模塊化是x86與ARM架構所不具有的。以ARM的架構爲例,ARM的架構分爲A、R和M三個系列,分別針對於Application(應用操做系統)、Real-Time(實時)和Embedded(嵌入式)三個領域,彼此之間並不兼容。

    可是模塊化的RISC-V架構可以使得用戶可以靈活選擇不一樣的模塊組合,以知足不一樣的應用場景,能夠說是「老小咸宜」。譬如針對於小面積低功耗嵌入式場景,用戶能夠選擇RV32IC組合的指令集,僅使用Machine Mode(機器模式);而高性能應用操做系統場景則能夠選擇譬如RV32IMFDC的指令集,使用Machine Mode(機器模式)與User Mode(用戶模式)兩種模式。而他們共同的部分則能夠相互兼容。

    濃縮的都是精華——指令的數量

    短小精悍的架構以及模塊化的哲學,使得RISC-V架構的指令數目很是的簡潔。基本的RISC-V指令數目僅有40多條,加上其餘的模塊化擴展指令總共幾十條指令。

    3. RISC-V指令集架構簡介

    本章將對RISC-V的指令集架構多方面的特性進行簡要介紹。

    模塊化的指令子集

    RISC-V的指令集使用模塊化的方式進行組織,每個模塊使用一個英文字母來表示。RISC-V最基本也是惟一強制要求實現的指令集部分是由I字母表示的基本整數指令子集,使用該整數指令子集,便可以實現完整的軟件編譯器。其餘的指令子集部分均爲可選的模塊,具備表明性的模塊包括M/A/F/D/C,如表1所示。

    表1 RISC-V的模塊化指令集

    爲了提升代碼密度,RISC-V架構也提供可選的「壓縮」指令子集,由英文字母C表示。壓縮指令的指令編碼長度爲16比特,而普通的非壓縮指令的長度爲32比特。以上這些模塊的一個特定組合「IMAFD」,也被稱爲「通用」組合,由英文字母G表示。所以RV32G表示RV32IMAFD,同理RV64G表示RV64IMAFD。

    爲了進一步減小面積,RISC-V架構還提供一種「嵌入式」架構,由英文字母E表示。該架構主要用於追求極低面積與功耗的深嵌入式場景。該架構僅須要支持16個通用整數寄存器,而非嵌入式的普通架構則須要支持32個通用整數寄存器。

    經過以上的模塊化指令集,可以選擇不一樣的組合來知足不一樣的應用。譬如,追求小面積低功耗的嵌入式場景能夠選擇使用RV32EC架構;而大型的64位架構則能夠選擇RV64G。

    除了上述的模塊,還有若干的模塊包括L、B、P、V和T等。這些擴展目前大多數還在不斷完善和定義中,還沒有最終肯定,所以本文在此不作詳細論述。

    可配置的通用寄存器組

    RISC-V架構支持32位或者64位的架構,32位架構由RV32表示,其每一個通用寄存器的寬度爲32比特;64位架構由RV64表示,其每一個通用寄存器的寬度爲64比特。

    RISC-V架構的整數通用寄存器組,包含32個(I架構)或者16個(E架構)通用整數寄存器,其中整數寄存器0被預留爲常數0,其餘的31個(I架構)或者15個(E架構)爲普通的通用整數寄存器。

    若是使用了浮點模塊(F或者D),則須要另一個獨立的浮點寄存器組,包含32個通用浮點寄存器。若是僅使用F模塊的浮點指令子集,則每一個通用浮點寄存器的寬度爲32比特;若是使用了D模塊的浮點指令子集,則每一個通用浮點寄存器的寬度爲64比特。

    規整的指令編碼

    在流水線中可以儘早儘快的讀取通用寄存器組,每每是處理器流水線設計的指望之一,這樣能夠提升處理器性能和優化時序。這個看似簡單的道理在不少現存的商用RISC架構中都難以實現,由於通過多年反覆修改不斷添加新指令後,其指令編碼中的寄存器索引位置變得很是的凌亂,給譯碼器形成了負擔。

    得益於後發優點和總結了多年來處理器發展的教訓,RISC-V的指令集編碼很是的規整,指令所需的通用寄存器的索引(Index)都被放在固定的位置,如圖2所示。所以指令譯碼器(Instruction Decoder)能夠很是便捷的譯碼出寄存器索引而後讀取通用寄存器組(Register File,Regfile)。

    圖2 RV32I規整的指令編碼格式

    簡潔的存儲器訪問指令

    與全部的RISC處理器架構同樣,RISC-V架構使用專用的存儲器讀(Load)指令和存儲器寫(Store)指令訪問存儲器(Memory),其餘的普通指令沒法訪問存儲器,這種架構是RISC架構的經常使用的一個基本策略,這種策略使得處理器核的硬件設計變得簡單。

    存儲器訪問的基本單位是字節(Byte)。RISC-V的存儲器讀和存儲器寫指令支持一個字節(8位),半字(16位),單字(32位)爲單位的存儲器讀寫操做,若是是64位架構還能夠支持一個雙字(64位)爲單位的存儲器讀寫操做。

    RISC-V架構的存儲器訪問指令還有以下顯著特色:

    爲了提升存儲器讀寫的性能,RISC-V架構推薦使用地址對齊的存儲器讀寫操做,可是地址非對齊的存儲器操做RISC-V架構也支持,處理器能夠選擇用硬件來支持,也能夠選擇用軟件來支持。

    因爲如今的主流應用是小端格式(Little-Endian),RISC-V架構僅支持小端格式。有關小端格式和大端格式的定義和區別,本文在此不作過多介紹,若對此不甚瞭解的初學者能夠自行查閱學習。

    不少的RISC處理器都支持地址自增或者自減模式,這種自增或者自減的模式雖然可以提升處理器訪問連續存儲器地址區間的性能,可是也增長了設計處理器的難度。RISC-V架構的存儲器讀和存儲器寫指令不支持地址自增自減的模式。

    RISC-V架構採用鬆散存儲器模型(Relaxed Memory Model),鬆散存儲器模型對於訪問不一樣地址的存儲器讀寫指令的執行順序不做要求,除非使用明確的存儲器屏障(Fence)指令加以屏蔽。

    這些選擇都清楚地反映了RISC-V架構力圖簡化基本指令集,從而簡化硬件設計的哲學。RISC-V架構如此定義很是合理,可以達到能屈能伸的效果。譬如:對於低功耗的簡單CPU,可使用很是簡單的硬件電路便可完成設計;而對於追求高性能的超標量處理器則能夠經過複雜設計的動態硬件調度能力來提升性能。

    高效的分支跳轉指令

    RISC-V架構有兩條無條件跳轉指令(Unconditional Jump),jal與jalr指令。跳轉連接(Jump and Link)指令jal可用於進行子程序調用,同時將子程序返回地址存在連接寄存器(Link Register:由某一個通用整數寄存器擔任)中。跳轉連接寄存器(Jump and Link-Register)指令jalr指令可以用於子程序返回指令,經過將jal指令(跳轉進入子程序)保存的連接寄存器用於jalr指令的基地址寄存器,則能夠從子程序返回。

    RISC-V架構有6條帶條件跳轉指令(Conditional Branch),這種帶條件的跳轉指令跟普通的運算指令同樣直接使用2個整數操做數,而後對其進行比較,若是比較的條件知足時,則進行跳轉。所以,此類指令將比較與跳轉兩個操做放到了一條指令裏完成。

    做爲比較,不少的其餘RISC架構的處理器須要使用兩條獨立的指令。第一條指令先使用比較指令,比較的結果被保存到狀態寄存器之中;第二條指令使用跳轉指令,判斷前一條指令保存在狀態寄存器當中的比較結果爲真時則進行跳轉。相比而言RISC-V的這種帶條件跳轉指令不只減小了指令的條數,同時硬件設計上更加簡單。

    對於沒有配備硬件分支預測器的低端CPU,爲了保證其性能,RISC-V的架構明確要求其採用默認的靜態分支預測機制,即:若是是向後跳轉的條件跳轉指令,則預測爲「跳」;若是是向前跳轉的條件跳轉指令,則預測爲「不跳」,而且RISC-V架構要求編譯器也按照這種默認的靜態分支預測機制來編譯生成彙編代碼,從而讓低端的CPU也能獲得不錯的性能。

    爲了使硬件設計儘可能簡單,RISC-V架構特意定義了全部的帶條件跳轉指令跳轉目標的偏移量(相對於當前指令的地址)都是有符號數,而且其符號位被編碼在固定的位置。所以,這種靜態預測機制在硬件上很是容易實現,硬件譯碼器能夠輕鬆的找到這個固定的位置,並判斷其是0仍是1來判斷其是正數仍是負數,若是是負數則表示跳轉的目標地址爲當前地址減去偏移量,也就是向後跳轉,則預測爲「跳」。固然對於配備有硬件分支預測器的高端CPU,則能夠採用高級的動態分支預測機制來保證性能。

    簡潔的子程序調用

    爲了理解此節,需先對通常RISC架構中程序調用子函數的過程予以介紹,其過程以下:

    • 進入子函數以後須要用存儲器寫(Store)指令來將當前的上下文(通用寄存器等的值)保存到系統存儲器的堆棧區內,這個過程一般稱爲「保存現場」。
    • 在退出子程序之時,須要用存儲器讀(Load)指令來將以前保存的上下文(通用寄存器等的值)從系統存儲器的堆棧區讀出來,這個過程一般稱爲「恢復現場」。

    「保存現場」和「恢復現場」的過程一般由編譯器編譯生成的指令來完成,使用高層語言(譬如C或者C++)開發的開發者對此能夠不用太關心。高層語言的程序中直接寫上一個子函數調用便可,可是這個底層發生的「保存現場」和「恢復現場」的過程倒是實實在在地發生着(能夠從編譯出的彙編語言裏面看到那些「保存現場」和「恢復現場」的彙編指令),而且還須要消耗若干的CPU執行時間。

    爲了加速這個「保存現場」和「恢復現場」的過程,有的RISC架構發明了一次寫多個寄存器到存儲器中(Store Multiple),或者一次從存儲器中讀多個寄存器出來(Load Multiple)的指令,此類指令的好處是一條指令就能夠完成不少事情,從而減小彙編指令的代碼量,節省代碼的空間大小。可是此種「Load Multiple」和「Store Multiple」的弊端是會讓CPU的硬件設計變得複雜,增長硬件的開銷,也可能損傷時序使得CPU的主頻沒法提升,筆者在曾經設計此類處理器時便深受其苦。

    RISC-V架構則放棄使用這種「Load Multiple」和「Store Multiple」指令。並解釋,若是有的場合比較介意這種「保存現場」和「恢復現場」的指令條數,那麼可使用公用的程序庫(專門用於保存和恢復現場)來進行,這樣就能夠省掉在每一個子函數調用的過程當中都放置數目不等的「保存現場」和「恢復現場」的指令。

    此選擇再次印證了RISC-V追求硬件簡單的哲學,由於放棄「Load Multiple」和「Store Multiple」指令能夠大幅簡化CPU的硬件設計,對於低功耗小面積的CPU能夠選擇很是簡單的電路進行實現,而高性能超標量處理器因爲硬件動態調度能力很強,能夠有強大的分支預測電路保證CPU可以快速的跳轉執行,從而能夠選擇使用公用的程序庫(專門用於保存和恢復現場)的方式減小代碼量,可是同時達到高性能。

    無條件碼執行

    不少早期的RISC架構發明了帶條件碼的指令,譬如在指令編碼的頭幾位表示的是條件碼(Conditional Code),只有該條件碼對應的條件爲真時,該指令才被真正執行。

    這種將條件碼編碼到指令中的形式可使得編譯器將短小的循環編譯成帶條件碼的指令,而不用編譯成分支跳轉指令。這樣便減小了分支跳轉的出現,一方面減小了指令的數目;另外一方面也避免了分支跳轉帶來的性能損失。然而,這種「條件碼」指令的弊端一樣會使得CPU的硬件設計變得複雜,增長硬件的開銷,也可能損傷時序使得CPU的主頻沒法提升,筆者在曾經設計此類處理器時便深受其苦。

    RISC-V架構則放棄使用這種帶「條件碼」指令的方式,對於任何的條件判斷都使用普通的帶條件分支跳轉指令。此選擇再次印證了RISC-V追求硬件簡單的哲學,由於放棄帶「條件碼」指令的方式能夠大幅簡化CPU的硬件設計,對於低功耗小面積的CPU能夠選擇很是簡單的電路進行實現,而高性能超標量處理器因爲硬件動態調度能力很強,能夠有強大的分支預測電路保證CPU可以快速的跳轉執行達到高性能。

    無分支延遲槽

    不少早期的RISC架構均使用了「分支延遲槽(Delay Slot)」,最具備表明性的即是MIPS架構,在不少經典的計算機體系結構教材中,均使用MIPS對分支延遲槽進行過介紹。分支延遲槽就是指在每一條分支指令後面緊跟的一條或者若干條指令不受分支跳轉的影響,無論分支是否跳轉,這後面的幾條指令都必定會被執行。

    早期的RISC架構不少採用了分支延遲槽誕生的緣由主要是由於當時的處理器流水線比較簡單,沒有使用高級的硬件動態分支預測器,因此使用分支延遲槽可以取得可觀的性能效果。然而,這種分支延遲槽使得CPU的硬件設計變得極爲的彆扭,CPU設計人員對此每每苦不堪言。

    RISC-V架構則放棄了分支延遲槽,再次印證了RISC-V力圖簡化硬件的哲學,由於現代的高性能處理器的分支預測算法精度已經很是高,能夠有強大的分支預測電路保證CPU可以準確的預測跳轉執行達到高性能。而對於低功耗小面積的CPU,因爲無需支持分支延遲槽,硬件獲得極大簡化,也能進一步減小功耗和提升時序。

    無零開銷硬件循環

    不少RISC架構還支持零開銷硬件循環(Zero Overhead Hardware Loop)指令,其思想是經過硬件的直接參與,經過設置某些循環次數寄存器(Loop Count),而後可讓程序自動地進行循環,每一次循環則Loop Count自動減1,這樣持續循環直到Loop Count的值變成0,則退出循環。

    之因此提出發明這種硬件協助的零開銷循環是由於在軟件代碼中的for 循環(for i=0; i<="" p=""></N;>

    然有得必有失,此類零開銷硬件循環指令大幅地增長了硬件設計的複雜度。所以,零開銷循環指令與RISC-V架構簡化硬件的哲學是徹底相反的,在RISC-V架構中天然沒有使用此類零開銷硬件循環指令。

    簡潔的運算指令

    在本章第2.1節中曾經提到RISC-V架構使用模塊化的方式組織不一樣的指令子集,最基本的整數指令子集(I字母表示)支持的運算包括加法、減法、移位、按位邏輯操做和比較操做。這些基本的運算操做可以經過組合或者函數庫的方式完成更多的複雜操做(譬如乘除法和浮點操做),從而可以完成大多數的軟件操做。

    整數乘除法指令子集(M字母表示)支持的運算包括,有符號或者無符號的乘法和除法操做。乘法操做可以支持兩個32位的整數相乘獲得一個64位的結果;除法操做可以支持兩個32位的整數相除獲得一個32位的商與32位的餘數。

    單精度浮點指令子集(F字母表示)與雙精度浮點指令子集(D字母表示)支持的運算包括浮點加減法,乘除法,乘累加,開平方根和比較等操做,同時提供整數與浮點,單精度與雙精度浮點彼此之間的格式轉換操做。

    不少RISC架構的處理器在運算指令產生錯誤之時,譬如上溢(Overflow)、下溢(Underflow)、非規格化浮點數(Subnormal)和除零(Divide by Zero),都會產生軟件異常。RISC-V架構的一個特殊之處是對任何的運算指令錯誤(包括整數與浮點指令)均不產生異常,而是產生某個特殊的默認值,同時,設置某些狀態寄存器的狀態位。RISC-V架構推薦軟件經過其餘方法來找到這些錯誤。再次清楚地反映了RISC-V架構力圖簡化基本的指令集,從而簡化硬件設計的哲學。

    優雅的壓縮指令子集

    基本的RISC-V基本整數指令子集(字母I表示 )規定的指令長度均爲等長的32位,這種等長指令定義使得僅支持整數指令子集的基本RISC-V CPU很是容易設計。可是等長的32位編碼指令也會形成代碼體積(Code Size)相對較大的問題。

    爲了知足某些對於代碼體積要求較高的場景(譬如嵌入式領域),RISC-V定義了一種可選的壓縮(Compressed)指令子集,由字母C表示,也能夠由RVC表示。RISC-V具備後發優點,從一開始便規劃了壓縮指令,預留了足夠的編碼空間,16位長指令與普通的32位長指令能夠無縫自由地交織在一塊兒,處理器也沒有定義額外的狀態。

    RISC-V壓縮指令的另一個特別之處是,16位指令的壓縮策略是將一部分普通最經常使用的的32位指令中的信息進行壓縮重排獲得(譬如假設一條指令使用了兩個一樣的操做數索引,則能夠省去其中一個索引的編碼空間),所以每一條16位長的指令都能一一找到其對應的原始32位指令。所以,程序編譯成爲壓縮指令僅在彙編器階段就能夠完成,極大的簡化了編譯器工具鏈的負擔。

    RISC-V架構的研究者進行了詳細的代碼體積分析,如圖3所示,經過分析結果能夠看出,RV32C的代碼體積相比RV32的代碼體積減小了百分之四十,而且與ARM,MIPS和x86等架構相比都有不錯的表現。

    圖3 各指令集架構的代碼密度比較(數據越小越好)

    特權模式

    RISC-V架構定義了三種工做模式,又稱特權模式(Privileged Mode):

    • Machine Mode:機器模式,簡稱M Mode。
    • Supervisor Mode:監督模式,簡稱S Mode。
    • User Mode:用戶模式,簡稱U Mode。

    RISC-V架構定義M Mode爲必選模式,另外兩種爲可選模式。經過不一樣的模式組合能夠實現不一樣的系統。

    RISC-V架構也支持幾種不一樣的存儲器地址管理機制,包括對於物理地址和虛擬地址的管理機制,使得RISC-V架構可以支持從簡單的嵌入式系統(直接操做物理地址)到複雜的操做系統(直接操做虛擬地址)的各類系統。

    CSR寄存器

    RISC-V架構定義了一些控制和狀態寄存器(Control and Status Register,CSR),用於配置或記錄一些運行的狀態。CSR寄存器是處理器核內部的寄存器,使用其本身的地址編碼空間和存儲器尋址的地址區間徹底無關係。

    CSR寄存器的訪問採用專用的CSR指令,包括CSRRW、CSRRS、CSRRC、CSRRWI、CSRRSI以及CSRRCI指令。

    中斷和異常

    中斷和異常機制每每是處理器指令集架構中最爲複雜而關鍵的部分。RISC-V架構定義了一套相對簡單基本的中斷和異常機制,可是也容許用戶對其進行定製和擴展。

    矢量指令子集

    RISC-V架構目前雖然尚未定型矢量(Vector)指令子集,可是從目前的草案中已經能夠看出,RISC-V矢量指令子集的設計理念很是的先進,因爲後發優點及藉助矢量架構多年發展成熟的結論,RISC-V架構將使用可變長度的矢量,而不是矢量定長的SIMD指令集(譬如ARM的NEON和Intel的MMX),從而可以靈活的支持不一樣的實現。追求低功耗小面積的CPU能夠選擇使用長度較短的硬件矢量進行實現,而高性能的CPU則能夠選擇較長的硬件矢量進行實現,而且一樣的軟件代碼可以彼此兼容。

    自定製指令擴展

    除了上述闡述的模塊化指令子集的可擴展、可選擇,RISC-V架構還有一個很是重要的特性,那就是支持第三方的擴展。用戶能夠擴展本身的指令子集,RISC-V預留了大量的指令編碼空間用於用戶的自定義擴展,同時,還定義了四條Custom指令可供用戶直接使用,每條Custom指令都有幾個比特位的子編碼空間預留,所以,用戶能夠直接使用四條Custom指令擴展出幾十條自定義的指令。

    總結與比較

    處理器設計技術通過幾十年的衍進,隨着大規模集成電路設計技術的發展直至今天,呈現出以下特色:

    • 因爲高性能處理器的硬件調度能力已經很是強勁且主頻很高,所以,硬件設計但願指令集儘量的規整、簡單,從而,使得處理器能夠設計出更高的主頻與更低的面積。
    • 以IoT應用爲主的極低功耗處理器更加苛求低功耗與低面積。
    • 存儲器的資源也比早期的RISC處理器更加豐富。

    如上種種這些因素,使得不少早期的RISC架構設計理念(依據當時技術背景而誕生),時至今日不只不能幫助現代處理器設計,反而成了負擔桎梏。某些早期RISC架構定義的特性,一方面使得高性能處理器的硬件設計束手束腳;另外一方面又使得極低功耗的處理器硬件設計揹負沒必要要的複雜度。

    得益於後發優點,全新的RISC-V架構可以規避全部這些已知的負擔,同時,利用其先進的設計哲學,設計出一套「現代」的指令集。本節再次將其特色總結如表2所示。

    表2 RISC-V指令集架構特色總結

    相關文章
    相關標籤/搜索