如何在 Chisel 中将 Seq 与 Cat 一起使用?

How to use Seq with Cat in Chisel?

我正在学习凿子和火箭芯片。 火箭芯片在 RVC.scala.

中有使用 Seq 和 Cat 的代码
    val funct = Seq(0.U, 4.U, 6.U, 7.U, 0.U, 0.U, 2.U, 3.U)(Cat(x(12), x(6,5)))

但是当我按照上面的方式编写代码时,出现了错误。 凿子报告类型不匹配。

这一行声明了一个常量 Seq :

//idx:0    1    2    3    4    5    6    7
Seq(0.U, 4.U, 6.U, 7.U, 0.U, 0.U, 2.U, 3.U)

然后 return 由索引 Cat(x(12), x(6,5)) 给出的项目 (UInt)。

x 应该声明为 and UInt 之前。如果我们这样声明:

val x = "b0001000011000001".U(16.W)

我们将有 x(12) = 1.Ux(6, 5) = 3.U(或 "b11".U)然后 Cat(x(12), x(6,5)) == "b111".U == 7.U

索引 returned 为 7,对应于初始声明序列 Seq() 中的 3.U。

那么 funct 的值将是:

val funct = 3.U

Scala 提供了一个非常强大的功能,称为 Implicit Conversions。我将把它留给 Whosebug 上的许多解释,否则可以通过 Google 找到来解释细节和动机,但让我解释一下它们是如何在 Chisel 和 Rocket Chip 中使用的。

Ints 在 Scala 中(如 3)等同于原始 Java ints。如果你检查 API docs, you won't find any function def U, yet in Chisel we are able to construct UInt literals as 3.U. This is accomplished with an implicit conversion called fromIntToLiteral 本质上允许我们定义 def U 就好像它是在 Scala Int class 本身上定义的一样。由于 import chisel3._,您正在导入 fromIntToLiteral 并告诉 Scala 编译器实际上,Int 有一个名为 U 的方法!

Rocket Chip 有一些作者认为很有用的隐式转换。在这种情况下,freechips.rocketchip.util 包含定义 def apply(idx: UInt): TSeqToAugmentedSeq,此处调用的函数*。本质上,Scala 编译器发现没有 apply 方法需要 Seq 上定义的 UInt,因此它注意到 SeqToAugmentedSeq 被导入范围并提供这样的方法.它进行以下转换:

val funct = Seq(0.U, 4.U, 6.U, 7.U, 0.U, 0.U, 2.U, 3.U)(Cat(x(12), x(6,5)))
// The compiler turns this into:
val funct = (new SeqToAugmentedSeq(Seq(0.U, 4.U, 6.U, 7.U, 0.U, 0.U, 2.U, 3.U))).apply(Cat(x(12), x(6,5)))

希望对您有所帮助!

*对象上的圆括号调用 apply methodmyUInt(3) 等同于 myUInt.apply(3).