999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

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

2017-05-13 01:09:12雷思磊
單片機與嵌入式系統應用 2017年5期
關鍵詞:指令信息

雷思磊

(酒泉衛星發射中心,酒泉 735000)

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

雷思磊

(酒泉衛星發射中心,酒泉 735000)

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

Rocket;RoCC;RISC-V

引 言

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

1 Rocket處理器簡介

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

① 支持MMU,支持分頁虛擬內存,所以可以移植Linux操作系統;

② 具有兼容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的優勢,將面向對象(object orientation)、函數式編程(functional programming)、類型參數化(parameterized types)、類型推斷(type inference)等概念引入硬件編程語言,從而提供更加強大的硬件開發能力。Chisel除了開源之外,還有一個優勢就是使用Chisel編寫的硬件電路可以通過編譯得到對應的Verilog設計,還可以得到對應的C++模擬器。Rocket使用Chisel編寫,就可以很容易得到對應的軟件模擬器[2]。

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

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

customX rd, rs1, rs2, funct

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

圖1 customX指令的二進制格式

3 RoCC模塊

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

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

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

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

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

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

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

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

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

③ Float Point Unit:RoCC可以使用該接口向FPU收發數據,圖2中以FPU開始的信息就是Float Point Unit接口的內容。

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

上述7組接口中,最基本的就是Register Mode接口,處理器發送指令給RoCC以及RoCC返回響應信息都是通過該接口實現的,該接口包括兩個部分:Rocket Core發送給RoCC的指令信息(即Core Cmd)、RoCC返回給Rocket Core的結果信息(即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發送給RoCC的指令,其中包括源寄存器rs1、rs2的值,以及對應的指令信息,后者通過RoCCInstruction類實現,其內容與圖1中的結構是一一對應的。Core Resp的定義如下:

class RoCCResponse(implicit p: Parameters) extends

CoreBundle()(p) {

val rd = Bits(width = 5)

val data = Bits(width = xLen)

}

其中包括要寫入的目的寄存器地址、要寫入的數據。

4 默認的RoCC功能分析

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

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

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

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

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

圖3 RoccCommandRouter類進行RoCC指令與處理結果的分發

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

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

custom0 rd, rs1, rs2, 0

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

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

custom0 rd, rs1, rs2, 1

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

③ 從L1 DCache加載數據到RoCC內部寄存器。指令格式如下:

custom0 rd, rs1, rs2, 2

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

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

custom0 rd, rs1, rs2, 3

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

5 RoCC測試

本節通過Rocket自帶的程序測試RoCC的功能是否正確,試驗環境為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域,該域的值只有為非零的時候,才可以執行自定義指令,否則會出現無效指令異常。默認情況下該域的值為零,需要通過程序修改該值。

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

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

ms = INSERT_FIELD(ms, MSTATUS_XS, 3);

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

5.3 測試程序

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

#include

#include

#include

int main() {

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

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

//加載x的值到RoCC的內部寄存器2

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

//讀取RoCC內部寄存器2的值,保存到變量z

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

//驗證z是否等于x

assert(z == x);

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

//將變量y的值與RoCC內部寄存器2的值相加,結果存儲 //到RoCC內部寄存器2

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

//讀出RoCC內部寄存器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的數據,保存到RoCC內 //部寄存器2

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

//將變量y的值與RoCC內部寄存器2的值相加,結果存儲 //到RoCC內部寄存器2

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

//讀出RoCC內部寄存器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,表示測試成功。

結 語

[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.

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

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)

猜你喜歡
指令信息
聽我指令:大催眠術
ARINC661顯控指令快速驗證方法
測控技術(2018年5期)2018-12-09 09:04:26
LED照明產品歐盟ErP指令要求解讀
電子測試(2018年18期)2018-11-14 02:30:34
訂閱信息
中華手工(2017年2期)2017-06-06 23:00:31
殺毒軟件中指令虛擬機的脆弱性分析
電信科學(2016年10期)2016-11-23 05:11:56
展會信息
中外會展(2014年4期)2014-11-27 07:46:46
一種基于滑窗的余度指令判別算法
坐標系旋轉指令數控編程應用
機電信息(2014年27期)2014-02-27 15:53:56
信息
建筑創作(2001年3期)2001-08-22 18:48:14
健康信息
祝您健康(1987年3期)1987-12-30 09:52:32
主站蜘蛛池模板: 日韩欧美综合在线制服| 91精品人妻互换| 日韩天堂网| 亚洲高清资源| 国产永久无码观看在线| AV网站中文| 超碰aⅴ人人做人人爽欧美| 欧美狠狠干| 99精品免费欧美成人小视频| 秋霞一区二区三区| 欧美精品三级在线| 国产一区二区免费播放| 中文字幕久久波多野结衣 | 视频二区中文无码| 日韩福利在线视频| 国产亚洲欧美日韩在线观看一区二区 | 九九线精品视频在线观看| 黄色网址免费在线| 国产91线观看| 国内精品手机在线观看视频| 国产香蕉一区二区在线网站| 色欲色欲久久综合网| 欧美色综合网站| 亚洲国产成人综合精品2020 | 国产浮力第一页永久地址| 亚洲欧洲日韩综合| 日本亚洲国产一区二区三区| 91麻豆精品国产高清在线| 性色一区| 亚洲天堂.com| 精品视频第一页| 亚洲Va中文字幕久久一区 | 一本久道久久综合多人| 中文字幕66页| 91青青视频| 亚洲欧洲免费视频| 国产成人精品在线| 精品人妻系列无码专区久久| 手机在线免费不卡一区二| 中文字幕在线欧美| 少妇被粗大的猛烈进出免费视频| 国产第八页| 国产高颜值露脸在线观看| 国产黄色爱视频| 在线观看无码av免费不卡网站| 亚洲熟女中文字幕男人总站| 国产日韩欧美中文| 欧美成人亚洲综合精品欧美激情| 91色在线视频| 丝袜高跟美脚国产1区| 伊人网址在线| 国产欧美网站| 99国产精品一区二区| 国产欧美另类| 亚洲AⅤ无码国产精品| 欧美劲爆第一页| 久久综合色视频| 综合亚洲网| 波多野衣结在线精品二区| 精品三级网站| 日韩成人高清无码| 色综合网址| 国产微拍一区| 日韩国产欧美精品在线| 黄色三级网站免费| 欧美日本激情| 国产区免费精品视频| 国产成人一区二区| 欧美一级高清视频在线播放| 992tv国产人成在线观看| 国产迷奸在线看| 国产视频入口| 日本黄色不卡视频| 狠狠色成人综合首页| 在线综合亚洲欧美网站| 无码啪啪精品天堂浪潮av| 日韩在线中文| www精品久久| 91破解版在线亚洲| 国产真实乱人视频| 日韩a级毛片| 97青青青国产在线播放|