下面的 chisel 语句是如何解码的?

How is the following chisel statement decoded?

我正在学习 SonicBoom。下面这句要根据解码table来分配对应的解码信号

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 decoder map {case(s,d) => s := d}
      rocc := false.B
      this
  }
}

但是我想知道这一步是如何实现的。 sigs zip decoder map {case(s,d) => s := d}这个代码是什么意思?

Zip 和 map 似乎是 Vec 中的函数。我试着查看了它的官方手册。

https://www.chisel-lang.org/api/latest/chisel3/index.html?search=zip这本手册是我见过最难的手册

他只给出了如下解释:

defzip[A1 >: T, B, That](that: GenIterable[B])(implicit bf: CanBuildFrom[IndexedSeq[T], (A1, B), That]): That
Definition Classes
IterableLike → GenIterableLike

defmap[B, That](f: (T) ⇒ B)(implicit bf: CanBuildFrom[IndexedSeq[T], B, That]): That
Definition Classes
TraversableLike → GenTraversableLike → FilterMonadic

我完全看不懂说明书在说什么?我再次检查了 Chisel 的书。这两个功能目前还没有介绍。有人可以介绍一下吗?非常感谢!

zip 是一个 standard Scala method。它以 2 元组(值对)的序列将两个序列连接在一起。想想夹克拉链。

map也是一个standard scala method。它对序列的每个成员应用一个函数。

这里给map的函数是case(s,d) => s := d这个函数使用模式匹配得到两个元组成员sd。 该函数返回的值是ds的赋值(连接):s := d.

为了更好地理解Chisel,我认为我们必须先了解一点Scala。

我没有尝试编译它,老实说,我对 Chisel 的作用只有很模糊的理解,所以这只是一个有根据的猜测:

  • sigs是上面那行定义的序列Seq(legal, fp_val, ..., csr_cmd)
  • decoder 也是一些实体的序列,可以出现在 :=.
  • 的右侧
  • zipsigsdecoder 序列元素,即 [s1, s2, s3, ..., sN][d1, d2, d3, ..., dN] 被压缩成一个序列对 [(s1, d1), (s2, d2), ..., (sN, dN)] .
  • map 遍历序列,并对每一对做一些事情。由于结果未使用,我认为它实际上应该是 foreach.
  • case 将对解构为第一和第二部分 sd
  • s := d 以某种方式将 sd 连接在一起(如果您正在使用 Chisel,您可能比我更了解 := 的含义)

它可以用for-yield重写:

for ((s, d) <- sigs.zip(decoder))
yield s := d

但由于结果未被使用,它可能被写成

sigs.zip(decoder).foreach { case (s, d) => s := d }

或使用相应的 for-语法:

for ((s, d) <- sigs.zip(decoder)) {
  s := d
}

关于手动输入:这是一个非常典型的 Scala 集合库签名。泛型参数堆是一种类型级别的规范,可确保 returned 集合的类型“尽可能精确”。这样做的好处是可以为一大堆集合编写泛型方法,而不必 return 千篇一律 - List 无处不在。不幸的是,这也使得新手无法破译签名。

这是签名:

def zip[A1 >: T, B, That](that: GenIterable[B])(implicit bf: CanBuildFrom[IndexedSeq[T], (A1, B), That]): That 

以下是您阅读这些签名的方式:

  • 找出所有只出现在implicit参数中的类型变量。在这种情况下,这些将是 A1That.
  • 识别出现在return类型中的所有类型变量。在本例中,它是 That.

现在:

  • 如果类型变量只出现在implicit参数的类型中,而不出现在return类型中,那么只需忽略它们:this只是一种为最合适的隐式参数指定搜索 space 的方法。您可以忽略它们,除非您是试图将您的馆藏插入标准馆藏库的图书馆作者。认为这是不相关的图书馆作者到图书馆作者的闲聊。
  • 如果某些类型变量 X 同时出现在 implicit 参数的类型和 return 类型中,那么你可以假设它是“最好的 X你能想到的。

应用于此签名:

  • T是你原始向量的元素类型
  • B 是第一个参数的元素类型(您正在压缩的集合)
  • A1只出现在隐式参数的类型中:忽略它。
  • That 出现在隐式参数和 return 类型中:假设它是“最佳可能的集合类型”。

总而言之,它给你:

  • 您从一个元素类型为 T
  • 的向量开始
  • 您正在使用 B
  • 类型的元素序列对其进行压缩
  • 您可以假设 That 将是最精确类型的集合,类似于 Vec[(T, B)] 或至少 IndexedSeq[(T, B)]。它是什么并不重要,因为无论如何你都在调用 foreach

更一般地说,这个想法是您可以简单地依赖类型推断,并假设它会在任何地方找出最合适的结果类型。