3

我正在学习凿子和火箭芯片。火箭芯片在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 报告类型不匹配。

4

2 回答 2

3

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)

于 2019-11-14T02:14:04.663 回答
1

这一行声明了一个常量 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.Ux(6, 5) = 3.U(或“b11”.U)Cat(x(12), x(6,5)) == "b111".U == 7.U

返回的索引是 7,对应于最初声明的序列 Seq() 中的 3.U。

那么函数的值将是:

val funct = 3.U
于 2019-11-13T14:59:58.010 回答