我正在学习凿子和火箭芯片。火箭芯片在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)))
但是当我像上面那样编写代码时,我得到了一个错误。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)))
但是当我像上面那样编写代码时,我得到了一个错误。chisel 报告类型不匹配。
Scala 提供了一个非常强大的功能,称为隐式转换。我将把它留给 StackOverflow 上的许多解释,谷歌可以找到其他解释来解释细节和动机,但让我解释一下它们是如何在 Chisel 和 Rocket Chip 中使用的。
Ints
在 Scala 中(如3
)等价于原始 Java ints
。如果您查看API 文档,您将找不到任何函数def U
,但在 Chisel 中,我们能够将UInt
文字构造为3.U
. 这是通过调用的隐式转换fromIntToLiteral
来完成的,它本质上允许我们定义def U
它,就好像它是在 ScalaInt
类本身上定义的一样。凭借import chisel3._
,您正在导入fromIntToLiteral
并告诉 Scala 编译器实际上Int
确实有一个名为U
!
Rocket Chip 有一些作者认为有用的隐式转换。在这种情况下,freechips.rocketchip.util
包含SeqToAugmentedSeq
定义def apply(idx: UInt): T
,在此处调用的函数*。本质上,Scala 编译器发现没有apply
方法需要UInt
定义 on Seq
,因此它会注意到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
方法。myUInt(3)
相当于myUInt.apply(3)
。
这一行声明了一个常量 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)
然后返回由 index 给出的项目(UInt)Cat(x(12), x(6,5))
。
x
应声明为和UInt
之前。如果我们声明为它:
val x = "b0001000011000001".U(16.W)
然后我们将有x(12) = 1.U
和x(6, 5) = 3.U
(或“b11”.U)Cat(x(12), x(6,5)) == "b111".U == 7.U
返回的索引是 7,对应于最初声明的序列 Seq() 中的 3.U。
那么函数的值将是:
val funct = 3.U