我正在學習SonicBoom。下面這句話應該是根據解碼表來分配相應的解碼信號。
class CtrlSigs extends Bundle
{
val legal = Bool()
val fp_val = Bool()
val fp_single = Bool()
val uopc = UInt(UOPC_SZ.W)
val iq_type = UInt(IQT_SZ.W)
val fu_code = UInt(FUC_SZ.W)
val dst_type = UInt(2.W)
val rs1_type = UInt(2.W)
val rs2_type = UInt(2.W)
val frs3_en = Bool()
val imm_sel = UInt(IS_X.getWidth.W)
val uses_ldq = Bool()
val uses_stq = Bool()
val is_amo = Bool()
val is_fence = Bool()
val is_fencei = Bool()
val mem_cmd = UInt(freechips.rocketchip.rocket.M_SZ.W)
val wakeup_delay = UInt(2.W)
val bypassable = Bool()
val is_br = Bool()
val is_sys_pc2epc = Bool()
val inst_unique = Bool()
val flush_on_commit = Bool()
val csr_cmd = UInt(freechips.rocketchip.rocket.CSR.SZ.W)
val rocc = Bool()
def decode(inst: UInt, table: Iterable[(BitPat, List[BitPat])] = {
val decoder = freechips.rocketchip.rocket.DecodeLogic(inst, XDecode.decode_default, table)
val sigs =
Seq(legal, fp_val, fp_single, uopc, iq_type, fu_code, dst_type, rs1_type,
rs2_type, frs3_en, imm_sel, uses_ldq, uses_stq, is_amo,
is_fence, is_fencei, mem_cmd, wakeup_delay, bypassable,
is_br, is_sys_pc2epc, inst_unique, flush_on_commit, csr_cmd)
sigs zip解碼器地圖 {case(s,d) => s := d}
rocc := false.B。
this。
}
但是我想知道這個步驟是如何實作的。 sigs zip decoder map {case(s,d) => s := d}這段代碼是什么意思?
Zip和map似乎是Vec中的函式。 我試著查了一下它的官方手冊。
Zip和map似乎是Vec中的函式。
https://www.chisel-lang.org/api/latest/chisel3/index.html?search=zip這個手冊是我見過的最難的手冊。
他只給出了以下解釋:
他只給出了以下解釋:
defzip[A1 > 。T, B, That](那。GenIterable[B])(implicit bf: CanBuildFrom[IndexedSeq[T] 。(A1, B), That])。) That]: That
Definition ClassesIterableLike →GenIterableLike
defmap[B, That](f: (T) ? B)(implicit bf: CanBuildFrom[IndexedSeq[T], B, That] )。) That]: That
Definition ClassesTraversableLike→GenTraversableLike→FilterMonadic
我完全不能理解手冊上說的是什么?我又查了一下Chisel的書。仍然沒有對這兩個函式的介紹。誰能介紹一下?非常感謝!
uj5u.com熱心網友回復:
zip是一個標準的Scala方法。它將兩個序列連接在一起,形成一個2-Tuples的序列(數值的對偶)。想一想外套拉鏈。
map也是一個標準的Scala方法。它對序列中的每個成員應用一個函式。
這里給map的函式是case(s,d) => s := d這個函式使用模式匹配來獲取兩個元組成員s和d。
這個函式回傳的值是d對s的賦值(連接)。s := d.
為了更好地理解Chisel,我認為我們必須在之前了解一些Scala的知識。
uj5u.com熱心網友回復:
我沒有嘗試過編譯它,而且說實話,我對Chisel的作用根本就只有一個不同的模糊認識,所以這只是一個有根據的猜測:
sigs是上面一行中定義的序列Seq(legal, fp_val, ..., csr_cmd)。
decoder也是一些物體的序列,可以出現在:=的右手邊。zip對sigs和decoder-序列進行元素化,即[s1, s2, s3, ... , sN]和[d1, d2, d3, ..., dN]被壓縮成一個對的序列[(s1, d1), (s2, d2), ..., (sN, dN)]。
map瀏覽這個序列,并對每一對做一些處理。由于結果是未使用的,我認為它實際上應該是一個foreach.case將這些對解構為第一和第二部分 s 和 ds := d以某種方式將s和d連接起來(如果你正在使用Chisel,你可能比我更清楚:=的意思)它可以用for-yield來重寫:
for ((s, d) <- sigs.zip(decoder) )
yield s := d
但是由于結果是未使用的,它可能被寫成
sigs.zip(decoder).forach { case (s, d) => s := d }
或者用相應的for-語法:
for ((s, d) <- sigs.zip(decoder) ) {
s := d
}
<解釋一下
關于手動條目:這是一個簽名,對于Scala集合庫來說是很典型的。泛型引數的堆積是一種型別級別的規范,可以確保回傳集合的型別 "盡可能精確"。這樣做的好處是,我們可以為一大堆集合撰寫通用方法,而不必到處回傳一個尺寸的Lists。不幸的是,這也使得新手們無法解讀其簽名。
這就是簽名:
def zip[A1 > 。T, B, That] (that: GenIterable[B])(implicit bf: CanBuildFrom[IndexedSeq[T] 。(A1, B), That])。) That
下面是你如何閱讀這些簽名的:
implicit引數中的型別變數。在本例中,這些將是A1和That。
That.現在:
- 如果一個型別變數只出現在
implicit引數的型別中,而沒有出現在回傳型別中,那么只需忽略它們:這只是一種指定搜索空間的方式,以尋找最合適的隱含引數。你可以忽略它們,除非你是一個試圖將你的集合插入標準集合庫中的庫作者。把它看作是無關緊要的庫-作者之間的喋喋不休。 。
- 如果一些型別變數
X同時出現在implicit引數的型別和回傳型別中,那么你可以認為它是 "你能想到的最好的X"。
應用于此簽名:
T是你原始向量的元素型別 。
B是第一個引數的元素型別(你正在使用的集合) 。
A1只出現在隱含引數的型別中:忽略它吧。That出現在隱含引數和回傳型別中:假設它是 "最好的集合型別"。
全部加起來,它給你:
- 你從一個元素型別為
T的向量開始。
- 你正在用一個型別為
B的元素序列對它進行壓縮。
- 你可以假設
That將是一個最精確型別的集合,類似于Vec[(T, B)]或者至少是IndexedSeq[(T, B)]。它是什么,其實并不重要,因為無論如何你都要在它上面呼叫foreach。
更普遍的想法是,你可以簡單地依賴型別推理,并假設它將在任何地方找出最合適的結果型別。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/326144.html
標籤:
上一篇:斯帕克。找到前N個值的高性能方法
下一篇:實施核心資料的問題
