Rocket Core : Decode

Decode

本文分析Rocket Core中的譯碼邏輯已脓。

以RV32I為例厕宗,指令集手冊中RISC-V指令編碼主要有下圖六種類型


常見編碼格式

譯碼模塊需要根據(jù)opcode與func3/func7字段對指令譯碼曲聂,基于指令類型生成相應的控制信號送往對應模塊朋腋。

相關代碼

  • Instructions.cala
  • IDecode.scala
  • Decode.scala

Instructions.scala

該文件基于RISC-V指令集架構手冊中定義的RISC-V指令集編碼,使用腳本自動生成旭咽。

Instuctions.scala 文件主要包含三個部分:

1. 指令集編碼

rocket-core中指令編碼如下圖所示

object Instructions {
  def BEQ   = BitPat("b?????????????????000?????1100011")
  def BNE   = BitPat("b?????????????????001?????1100011")
  def BLT   = BitPat("b?????????????????100?????1100011")
  def BGE   = BitPat("b?????????????????101?????1100011")
  def BLTU  = BitPat("b?????????????????110?????1100011")
  def BGEU  = BitPat("b?????????????????111?????1100011")
  
  ...
}

為了提取opcode以及func字段,Chisel中定義了BitPat類來描述不同指令編碼的pattern:

指令編碼Pattern

width即為二進制長度,RV32I中指令的BitPat寬度均為32

BitPat中利用parse函數(shù)來從指令Pattern中解析 value 和 mask。

// BitPat中parse函數(shù)的關鍵代碼
  for (d <- x.tail) {
    if (d != '_') {
      require("01?".contains(d), "Literal: " + x + " contains illegal character: " + d)
      mask = (mask << 1) + (if (d == '?') 0 else 1)
      bits = (bits << 1) + (if (d == '1') 1 else 0)
    }
  }
  • mask將"?"的位置標記無效混稽,“0”和“1”有效
  • value只記錄“1”的位置

以指令BEQ為例

def BEQ  = BitPat("b?????????????????000?????1100011")
  1. value : "b00000000000000000000000001100011"
  2. mask : "b00000000000000000111000001111111"

2. Causes

定義了異常/中斷原因的編碼,具體參考RISC-V指令集手冊: 特權級架構

object Causes {
  val misaligned_fetch    = 0x0 
  val fetch_access        = 0x1
  val illegal_instruction = 0x2
  val breakpoint          = 0x3
  val misaligned_load     = 0x4
  val load_access         = 0x5
  val misaligned_store    = 0x6
  val store_access        = 0x7
  val user_ecall          = 0x8
  val supervisor_ecall    = 0x9
  val hypervisor_ecall    = 0xa
  val machine_ecall       = 0xb
  val fetch_page_fault    = 0xc
  val load_page_fault     = 0xd
  val store_page_fault    = 0xf

3. CSRs

定義了CSR寄存器地址編碼,具體參考RISC-V指令集手冊: 特權級架構

object CSRs {
  val ustatus = 0x0
  val uie = 0x4
  val utvec = 0x5
  val vstart = 0x8
  val vxsat = 0x9
  val vxrm = 0xa
  val uscratch = 0x40
  val uepc = 0x41
...
}

IDecode.scala

IDecode : Instruction Decode, 主要包含兩部分:

  1. 譯碼生成的控制信號
  2. 指令集譯碼表

1. IntCtrlSigs: 譯碼得到的控制信號

class IntCtrlSigs extends Bundle {
    // 1. 譯碼生成的控制信號
    val legal = Bool()  // 是否非法指令
    val fp = Bool()     // 是否浮點指令
    val rocc = Bool()   // 是否協(xié)處理器相關指令
    val branch = Bool()
    val jal = Bool()
    val jalr = Bool()

    // 讀使能信號(xs猜測是excute stage)
    val rxs2 = Bool()
    val rxs1 = Bool()
    val scie = Bool()

    // ALU 控制信號
    val sel_alu2 = Bits(width = A2_X.getWidth)
    val sel_alu1 = Bits(width = A1_X.getWidth)
    val sel_imm = Bits(width = IMM_X.getWidth)
    val alu_dw = Bool()                       // double word 是否是64位
    val alu_fn = Bits(width = FN_X.getWidth)  // ALU function

    val mem = Bool()
    val mem_cmd = Bits(width = M_SZ)

    // 下面三個信號目前沒找到連線洽洁,還不清楚
    val rfs1 = Bool()
    val rfs2 = Bool()
    val rfs3 = Bool()

    val wfd = Bool()
    val mul = Bool()
    val div = Bool()
    val wxd = Bool()
    val csr = Bits(width = CSR.SZ)
    val fence_i = Bool()
    val fence = Bool()
    val amo = Bool() // 原子指令
    val dp = Bool()  // 雙精度浮點指令
    
    // 2. default:譯碼表缺失饿自,說明是非法指令
    //    譯碼結果第一項legal信號為N昭雌,表明非法
    def default: List[BitPat] = List(N, ... X, X, X)
    
    // 3. 譯碼邏輯主體部分,基于指令和譯碼表,譯碼得到結果唱星,返回該Bundle
    def decode(inst: UInt, table: Iterable[(BitPat, List[BitPat])]) = {
      
          // 調(diào)用DecodeLogic方法间聊,譯碼結果存在decoder中
          val decoder = DecodeLogic(inst, default, table)
          

          // 利用scala高階特性: zip + map將decoder譯碼結果賦值給本Bundle中
          // 展開來相當于
          //      legal   := decoder.legal
          //      fp      := decoder.fp
          //      rocc    := decoder.rocc
          //      ... 省略十幾行orz
          val sigs = Seq(legal, fp, rocc, branch, jal, jalr, rxs2, rxs1, scie, sel_alu2,
                         sel_alu1, sel_imm, alu_dw, alu_fn, mem, mem_cmd,
                         rfs1, rfs2, rfs3, wfd, mul, div, wxd, csr, fence_i, fence, amo, dp)
          sigs zip decoder map {case(s,d) => s := d}
          
          // 最后返回this, 即返回賦值完成后的IntCtrlSigs
          this
      }
    
}

可以看到型豁,譯碼邏輯相關的方法定義在控制信號中迎变。

備注:
IntCtrlSigs命名中的Int即整數(shù)Int衣形,與之相對應的就是浮點數(shù)的FPCtrlSigs
FPCtrlSigs的譯碼邏輯與IntCtrlSigs相類似,參考FPU即可

指令集譯碼表

譯碼表類視圖
  1. DecodeConstants定義為abstract trait,類似于C++中的虛基類,其中只定義了一個譯碼表(table)腻菇,
  2. 剩下的所有xxxDecode均繼承自DecodeConstants筹吐,內(nèi)部定義了各個指令擴展的譯碼表(table)丘薛。

RISC-V模塊化的設計使得Rocket Core可以通過config配置需要的指令擴展周拐,并將選擇的指令譯碼表整合妥粟。

舉個例子勾给,例如我們需要實現(xiàn)RV32IM,配置config后,Rocket Generator會將IDecode.table與MDecode.table合并成一張譯碼表(decode_table)售睹,合并相關的邏輯如下所示(只截取部分代碼說明,完整代碼見RocketCore.scala)

  val decode_table = {
  
    // usingMulDiv來自rocket-core的配置
    (if (usingMulDiv) new MDecode(pipelinedMul) ++:
    
    // RV32I是文檔中要求必須實現(xiàn)的部分
    Seq(new IDecode)
    
  } flatMap(_.table) // 合并成一張譯碼表

合并邏輯在Chisel代碼編譯過程中自動生成所需要的譯碼邏輯,無關的指令集擴展會被直接無視飞崖,并不會產(chǎn)生冗余的譯碼邏輯電路固歪。

Decode.scala

上面IntCtrlSigs的decode函數(shù)中調(diào)用了DecodeLogic函數(shù)來譯碼,該函數(shù)就定義在Decode.scala中贰健,這里實現(xiàn)了Quine-McCluskey算法伶椿,以簡化指令Pattern的譯碼邏輯。

網(wǎng)絡上資料講解得比較清楚(但我沒弄清楚偎痛,有點復雜orz)踩麦,這里只羅列一些重要的參考資料谓谦。

重要名詞解釋

文章(來源于公眾號:故事v歷史)

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末幅垮,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子匕争,更是在濱河造成了極大的恐慌甘桑,老刑警劉巖跑杭,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件萨螺,死亡現(xiàn)場離奇詭異,居然都是意外死亡慰技,警方通過查閱死者的電腦和手機椭盏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吻商,“玉大人掏颊,你說我怎么就攤上這事“剩” “怎么了?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵柒爸,是天一觀的道長准浴。 經(jīng)常有香客問我,道長揍鸟,這世上最難降的妖魔是什么兄裂? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮阳藻,結果婚禮上晰奖,老公的妹妹穿的比我還像新娘。我一直安慰自己腥泥,他們只是感情好匾南,可當我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蛔外,像睡著了一般蛆楞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上夹厌,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天豹爹,我揣著相機與錄音,去河邊找鬼矛纹。 笑死臂聋,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的或南。 我是一名探鬼主播孩等,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼采够!你這毒婦竟也來了肄方?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蹬癌,失蹤者是張志新(化名)和其女友劉穎权她,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體逝薪,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡伴奥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了翼闽。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拾徙。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖感局,靈堂內(nèi)的尸體忽然破棺而出尼啡,到底是詐尸還是另有隱情,我是刑警寧澤询微,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布崖瞭,位于F島的核電站,受9級特大地震影響撑毛,放射性物質發(fā)生泄漏书聚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望雌续。 院中可真熱鬧斩个,春花似錦、人聲如沸驯杜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鸽心。三九已至滚局,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間顽频,已是汗流浹背藤肢。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留糯景,地道東北人谤草。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像莺奸,于是被迫代替她去往敵國和親丑孩。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,044評論 2 355