国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

開源處理器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ā)展概述
广东省| 通辽市| 襄樊市| 潮安县| 成都市| 东乡县| 晴隆县| 滦南县| 长汀县| 固原市| 土默特右旗| 龙陵县| 伊宁市| 兰州市| 宝坻区| 宁武县| 元氏县| 华亭县| 东辽县| 额济纳旗| 离岛区| 塔城市| 刚察县| 拉萨市| 河池市| 乐安县| 葵青区| 嵊泗县| 鹿泉市| 嘉鱼县| 澎湖县| 神农架林区| 集贤县| 汕头市| 哈巴河县| 西峡县| 马尔康县| 两当县| 江川县| 松滋市| 崇仁县|