• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看

      ?

      開源處理器Rocket的自定義指令研究與測試

      2017-05-13 01:09:12雷思磊
      關鍵詞:測試程序模擬器寄存器

      雷思磊

      (酒泉衛(wèi)星發(fā)射中心,酒泉 735000)

      開源處理器Rocket的自定義指令研究與測試

      雷思磊

      (酒泉衛(wèi)星發(fā)射中心,酒泉 735000)

      Rocket是基于RISC-V指令集架構(gòu)的開源處理器,其實現(xiàn)了RISC-V的三條自定義指令custom0、custom1、custom2,在分析Rocket中自定義指令的處理過程后,編寫測試程序,驗證了自定義指令的實現(xiàn)。

      Rocket;RoCC;RISC-V

      引 言

      RISC-V是加州大學伯克利分校(University of California at Berkeley,以下簡稱UCB)設計并發(fā)布的一種開源精簡指令集架構(gòu),其目標是成為指令集架構(gòu)領域的Linux,應用覆蓋IoT(Internet of Things)設備、桌面計算機、高性能計算機等領域[1]。RISC-V自2014年正式發(fā)布以來,得到了包括谷歌、IBM、Oracle等在內(nèi)的眾多企業(yè),以及包括劍橋大學、蘇黎世聯(lián)邦理工大學、印度理工學院、中國科學院在內(nèi)的眾多知名學府與研究機構(gòu)的關注和參與,圍繞RISC-V的生態(tài)環(huán)境逐漸完善,并涌現(xiàn)了眾多開源處理器及SoC采用RISC-V架構(gòu)。Rocket就是采用RISC-V指令集的開源處理器,本文研究分析了Rocket處理器對于RISC-V中自定義指令的實現(xiàn)原理,并進行了測試。

      1 Rocket處理器簡介

      Rocket是UCB設計的一款基于RISC-V指令集、5級流水線、單發(fā)射順序執(zhí)行的64位處理器,主要特點有:

      ① 支持MMU,支持分頁虛擬內(nèi)存,所以可以移植Linux操作系統(tǒng);

      ② 具有兼容IEEE 754-2008標準的FPU;具有分支預測功能,具有BPB(Branch Prediction Buff)、BHT(Branch History Table)、RAS(Return Address Stack)。

      ③ Rocket是采用Chisel(Constructing Hardware in an Scala Embedded Language)編寫的,這也是UCB設計的一種開源硬件編程語言,是Scala語言的領域特定應用,可以充分利用Scala的優(yōu)勢,將面向?qū)ο?object orientation)、函數(shù)式編程(functional programming)、類型參數(shù)化(parameterized types)、類型推斷(type inference)等概念引入硬件編程語言,從而提供更加強大的硬件開發(fā)能力。Chisel除了開源之外,還有一個優(yōu)勢就是使用Chisel編寫的硬件電路可以通過編譯得到對應的Verilog設計,還可以得到對應的C++模擬器。Rocket使用Chisel編寫,就可以很容易得到對應的軟件模擬器[2]。

      2 RISCV指令集中的自定義指令

      RISC-V指令集架構(gòu)是一個靈活可擴展的架構(gòu),其中定義了4個自定義指令:custom0、custom1、custom2、custom3。其使用方法如下:

      customX rd, rs1, rs2, funct

      其中rs1、rs2是源操作數(shù)寄存器編碼,rd是目的寄存器編碼,funct是具體的操作類型編碼。其二進制指令格式如圖1所示。通過opcode的編碼來區(qū)分custom0、custom1、custom2、custom3。xd、xs1、xs2分別表示rd、rs1、rs2對應的通用寄存器是否需要訪問(讀或者寫)。在Rocket處理器中,默認實現(xiàn)了custom0、custom1、custom2指令,其通過RoCC(Rocket Custom Coprocessor)模塊執(zhí)行這三條自定義指令。

      圖1 customX指令的二進制格式

      3 RoCC模塊

      RoCC是在Rocket處理器中設計的協(xié)處理器,用來執(zhí)行自定義指令,從而有助于實現(xiàn)特定運算的加速執(zhí)行。RoCC與其他模塊的連接關系如圖2所示[3],在實際應用中可以有多個RoCC模塊,分別執(zhí)行不同的自定義指令。

      圖2 RoCC與Rocket中其余模塊的連接關系

      從圖2中可以發(fā)現(xiàn),RoCC與Core、L1 DCache、FPU、PageTable Walker、L2 Bus都有接口連接,其中與Core、L1 DCache之間的接口是基本接口,可分為如下3組:

      ① Core Control:用來在RoCC與Rocket Core之間傳遞狀態(tài)信息,比如RoCC正在執(zhí)行指令,處于busy狀態(tài),就會通過CC_Busy傳遞給Rocket Core。圖2中以CC開始的信息就是Core Control接口的內(nèi)容。

      ② Register Mode:用來在RoCC與Rocket Core之間傳遞指令信息,比如源寄存器的值、指令內(nèi)容等。圖2中以Core開始的信息就是Register Mode接口的內(nèi)容。

      ③ Memory Mode:用來在RoCC與L1 DCache之間傳遞數(shù)據(jù),圖2中以MEM開始的信息就是Memory Mode接口的內(nèi)容。

      其余的接口都是可選的擴展接口,可分為如下4組:

      ① Control Status Register:用來使得運行在Rocket Core上的Linux可以獲取RoCC的狀態(tài)信息,圖2中以CSR開始的信息就是Control Status Register接口的內(nèi)容。

      ② PageTable Walker:RoCC可以使用該接口進行虛擬地址到物理地址的轉(zhuǎn)換,圖2中以PTW開始的信息就是PageTable Walker接口的內(nèi)容。

      ③ Float Point Unit:RoCC可以使用該接口向FPU收發(fā)數(shù)據(jù),圖2中以FPU開始的信息就是Float Point Unit接口的內(nèi)容。

      ④ Uncached TileLink:RoCC可以使用該接口訪問L2 Cache,圖2中以UTL開始的信息就是Uncached TileLink接口的內(nèi)容。

      上述7組接口中,最基本的就是Register Mode接口,處理器發(fā)送指令給RoCC以及RoCC返回響應信息都是通過該接口實現(xiàn)的,該接口包括兩個部分:Rocket Core發(fā)送給RoCC的指令信息(即Core Cmd)、RoCC返回給Rocket Core的結(jié)果信息(即Core Resp)。其中Core Cmd的定義如下:

      //指令域的定義,共32bit

      class RoCCInstruction extends Bundle{

      val funct = Bits(width = 7)

      val rs2 = Bits(width = 5)

      val rs1 = Bits(width = 5)

      val xd = Bool()

      val xs1 = Bool()

      val xs2 = Bool()

      val rd = Bits(width = 5)

      val opcode = Bits(width = 7)

      }

      class RoCCCommand(implicit p: Parameters) extends CoreBundle()(p) {

      val inst = new RoCCInstruction

      //在上面定義了RoCCInstruction類

      val rs1 = Bits(width = xLen)

      val rs2 = Bits(width = xLen)

      val status = new MStatus

      }

      上文定義的類RoCCCommand就是Core Cmd,是Rocket Core發(fā)送給RoCC的指令,其中包括源寄存器rs1、rs2的值,以及對應的指令信息,后者通過RoCCInstruction類實現(xiàn),其內(nèi)容與圖1中的結(jié)構(gòu)是一一對應的。Core Resp的定義如下:

      class RoCCResponse(implicit p: Parameters) extends

      CoreBundle()(p) {

      val rd = Bits(width = 5)

      val data = Bits(width = xLen)

      }

      其中包括要寫入的目的寄存器地址、要寫入的數(shù)據(jù)。

      4 默認的RoCC功能分析

      Rocket處理器默認實現(xiàn)了3個RoCC,分別是AccumulatorExample、TranslatorExample、CharacterCountExample,均在rocc.scala中定義,其作用分別如下:

      ① AccumulatorExample:是一個累加器的例子,驗證了RoCC與Rocket Core、L1 DCache的接口是否正常,用來處理指令custom0。

      ② TranslatorExample:通過計算一個虛擬地址對應的物理地址,驗證了RoCC與PageTable Walker的接口是否正常,用來處理指令custom1。

      ③ CharacterCountExample:通過計算一個數(shù)據(jù)塊中的特定字符的數(shù)量,驗證RoCC的Uncache TileLink接口是否正常,用來處理指令custom2。

      Rocket Core在譯碼的時候需要判斷是否是自定義指令,如果是,那么會通過Core Cmd送出自定義指令,由RoccCommandRouter這個類分析判斷是哪一條自定義指令,從而送入對應的RoCC進行處理并將結(jié)果返回給Rocket Core,如圖3所示。

      圖3 RoccCommandRouter類進行RoCC指令與處理結(jié)果的分發(fā)

      限于篇幅,本文重點對AccumulatorExample的實現(xiàn)加以分析和測試。當Rocket Core處理器在譯碼的時候發(fā)現(xiàn)是指令custom0,那么就會將相應的參數(shù)通過Core Cmd發(fā)送給AccumulatorExample這個RoCC,AccumulatorExample依據(jù)發(fā)送過的參數(shù)中funct的值進行具體處理,funct代表了具體的操作類型, AccumulatorExample支持的操作類型有:

      ① 將通用寄存器的值寫入RoCC。AccumulatorExample在RoCC中定義了4個內(nèi)部寄存器,可以將Rocket Core中某個通用寄存器的值寫到這4個內(nèi)部寄存器中。指令格式如下:

      custom0 rd, rs1, rs2, 0

      rd沒有使用,可以任意;rs1為要讀取的通用寄存器的編號;rs2的值等于0~3,表示RoCC內(nèi)部寄存器的編號;最后的funct為0。

      ② 將RoCC內(nèi)部寄存器的值寫入通用寄存器。指令格式如下:

      custom0 rd, rs1, rs2, 1

      rd為要寫入的通用寄存器編號;rs1沒有使用,可以任意;rs2的值等于0~3,表示RoCC內(nèi)部寄存器的編號;最后的funct為1。

      ③ 從L1 DCache加載數(shù)據(jù)到RoCC內(nèi)部寄存器。指令格式如下:

      custom0 rd, rs1, rs2, 2

      rd沒有使用,可以任意;rs1為通用寄存器的編號,該通用寄存器中存儲的是數(shù)據(jù)的物理地址;rs2的值等于0~3,表示要加載到的RoCC內(nèi)部寄存器的編號;最后的funct為2。

      ④ 將通用寄存器的值與RoCC內(nèi)部寄存器的值相加,結(jié)果保存到RoCC內(nèi)部寄存器。指令格式如下:

      custom0 rd, rs1, rs2, 3

      rd沒有使用,可以任意;rs1為通用寄存器的編號;rs2的值等于0~3,表示要執(zhí)行累加操作的RoCC內(nèi)部寄存器的編號;最后的funct為3。

      5 RoCC測試

      本節(jié)通過Rocket自帶的程序測試RoCC的功能是否正確,試驗環(huán)境為Ubuntu14.04。

      5.1 編譯得到對應的模擬器

      使用如下指令從Github上下載Rocket對應的代碼,并編譯得到相應的GCC編譯器等工具。

      $ git clone https://github.com/ucb-bar/rocket-chip.git

      $ cd rocket-chip

      $ git submodule update - -init

      $ cd riscv-tools

      $ git submodule update - -init - -recursive

      $ export RISCV=/opt/riscv

      $ ./build.sh

      然后進入emulator目錄,編譯得到帶RoCC功能的C++模擬器,如下:

      $ cd emulator

      $ make CONFIG=RoCCExampleConfig

      在emulator目錄下得到C++模擬器emulator-rocketchip-RoccExampleConfig。

      5.2 修改Proxy Kernel

      在Rocket處理器中有一個寄存器mstatus,其中有一個XS域,該域的值只有為非零的時候,才可以執(zhí)行自定義指令,否則會出現(xiàn)無效指令異常。默認情況下該域的值為零,需要通過程序修改該值。

      Proxy Kernel(簡稱pk)是一個輕量級的應用程序執(zhí)行環(huán)境,能夠在其上執(zhí)行ELF程序[4]。對于使用C編寫的應用程序,可以在pk中執(zhí)行,此時處理器首先執(zhí)行pk,準備好硬件環(huán)境,然后pk加載應用程序。

      本文的測試程序為C代碼,使用pk作為其執(zhí)行環(huán)境,從而可以直接修改pk的代碼,使得pk在準備硬件環(huán)境的時候就設置mstatus寄存器的XS域為一個非零值。具體過程就是修改pk目錄下minit.c中的mstatus_init函數(shù),在其中添加如下語句:

      ms = INSERT_FIELD(ms, MSTATUS_XS, 3);

      然后重新編譯得到新的pk。

      5.3 測試程序

      使用C語言編寫測試程序如下,該程序是在Rocket-chip提供的測試程序之上修改的,原測試程序經(jīng)過測試有一定問題,第三個測試沒有通過。

      #include

      #include

      #include

      int main() {

      uint64_t x = 123, y = 456, z = 0;

      //************** 測試一**************

      //加載x的值到RoCC的內(nèi)部寄存器2

      asm volatile ("custom0 x0, %0, 2, 0" : : "r"(x));

      //讀取RoCC內(nèi)部寄存器2的值,保存到變量z

      asm volatile ("custom0 %0, x0, 2, 1" : "=r"(z));

      //驗證z是否等于x

      assert(z == x);

      //************** 測試二**************

      //將變量y的值與RoCC內(nèi)部寄存器2的值相加,結(jié)果存儲 //到RoCC內(nèi)部寄存器2

      asm volatile ("custom0 x0, %0, 2, 3" : : "r"(y));

      //讀出RoCC內(nèi)部寄存器2的值,保存到變量z

      asm volatile ("custom0 %0, x0, 2, 1" : "=r"(z));

      //驗證z是否等于x+y

      assert(z == x+y);

      //************** 測試三**************

      //測試三與測試二的過程是一致的,但是在測試三中是從 //L1 DCache中獲取變量x的值

      //使用custom1指令,獲取變量x的物理地址,保存到通用 //寄存器x0

      asm volatile ("custom1 x0, %0, 2, 0" : : "r"(&x));

      //從L1 DCache中加載地址為x0的數(shù)據(jù),保存到RoCC內(nèi) //部寄存器2

      asm volatile ("custom0 x0, x0, 2, 2");

      //將變量y的值與RoCC內(nèi)部寄存器2的值相加,結(jié)果存儲 //到RoCC內(nèi)部寄存器2

      asm volatile ("custom0 x0, %0, 2, 3" : : "r"(y));

      //讀出RoCC內(nèi)部寄存器2的值,保存到變量z

      asm volatile ("custom0 %0, x0, 2, 1" : "=r"(z));

      //驗證z是否等于x+y

      assert(z == x+y);

      printf("success! ");

      }

      上述測試程序可以分為三個部分,測試了AccumulatorExample、TranslatorExample兩個RoCC,custom0、custom1兩條自定義指令。使用gcc編譯得到對應的ELF程序,使用前文得到的C++模擬器進行仿真測試,如下:

      ./emulator-rocketchip-RoccExampleConfig +max-cycles=10000000 +dramsim pk ../../test/rocctest/a.out

      最后輸出success,表示測試成功。

      結(jié) 語

      [1] Waterman A.The RISC-V Instruction Set Manual,Volume I:User-Level ISA,Version 2.1,2016.

      [2] Chisel 2.2 Tutorial[EB/OL].[2016-12].https://chisel.eecs.berkeley.edu/2.2.0/chisel-tutorial.

      [3] Anuj Rao.The RoCC Doc V2:An Introduction to the Rocket Custom Coprocessor Interface[EB/OL].[2016-12].https://docs.google.com/document/d/1CH2ep4YcL_ojsa3BVHEW-uwcKh1FlFTjH_kg5v8bxVw/edit.

      [4] RISC-V Proxy Kernel[EB/OL].[2016-12].https://github.com/riscv/riscv-pk/tree/f892b43a2bb1c2405b9941aaefdb25 e3b4efe1f1.

      雷思磊(工程師),主要研究方向為處理器架構(gòu)、嵌入式處理器應用等。

      Custom Instruction Research and Verification of Open Source Processor Rocket

      Lei Silei

      (Jiuquan Satellite Launch Center,Jiuquan 735000,China)

      The Rocket is an open source processor based on RISC-V instruction set architecture,which implements the RISC-V three custom instructions including custom0,custom1 and custom2.After analyzing the principle of Rocket,the program is written to verify the implementation of the custom instructions.

      Rocket;RoCC;RISC-V

      TP368.1

      A

      士然

      2016-12-12)

      猜你喜歡
      測試程序模擬器寄存器
      了不起的安檢模擬器
      盲盒模擬器
      劃船模擬器
      Lite寄存器模型的設計與實現(xiàn)
      計算機應用(2020年5期)2020-06-07 07:06:44
      基于Castle型機械手的三溫量產(chǎn)測試平臺實現(xiàn)
      分簇結(jié)構(gòu)向量寄存器分配策略研究*
      手機APP交互界面人因適合性測試程序的設計與實現(xiàn)
      中心主導制訂的《VHF/UHF頻率范圍內(nèi)測向系統(tǒng)測向靈敏度的測試程序》等兩項國際標準在ITU官網(wǎng)正式發(fā)布
      電氣自動化控制設備可靠性測試探討
      動態(tài)飛行模擬器及其發(fā)展概述
      深州市| 武功县| 阿克苏市| 乌鲁木齐市| 汕头市| 托里县| 云南省| 永昌县| 合水县| 大同县| 文山县| 龙门县| 普宁市| 如皋市| 驻马店市| 隆回县| 康马县| 宝兴县| 高州市| 闽清县| 湄潭县| 罗江县| 霍林郭勒市| 米林县| 若尔盖县| 金寨县| 太康县| 馆陶县| 洪泽县| 陵川县| 白银市| 庆元县| 浮山县| 齐河县| 昭通市| 武平县| 聂荣县| 大名县| 怀安县| 上饶县| 乡城县|