我正在学习凿子和火箭芯片。 火箭芯片在RVC.scala中具有使用Seq和Cat的代码。
val funct = Seq(0.U,4.U,6.U,7.U,0.U,2.U,3.U)(Cat(x(12),x(6,5)))
但是当我如上所述编写代码时,出现错误。 凿报告类型不匹配。
Scala提供了一个非常强大的功能,称为Implicit Conversions。我将在StackOverflow上进行许多解释,而Google可以找到它们来解释细节和动机,但让我解释一下如何在Chisel和Rocket Chip中使用它们。
Scala中的 Ints
(如3
)等效于原始Java ints
。如果检查API docs,将找不到任何功能def U
,但是在Chisel中,我们可以将UInt
的文字构造为3.U
。这是通过称为fromIntToLiteral
的隐式转换完成的,该转换实际上使我们可以定义def U
,就像在Scala Int
类本身上定义它一样。借助import chisel3._
,您正在导入fromIntToLiteral
并告诉Scala编译器实际上Int
确实有一个名为U
的方法!>
Rocket Chip具有自己的一些隐式转换,作者认为这将很有用。在这种情况下,freechips.rocketchip.util
包含定义def apply(idx: UInt): T
的{{3}},此函数在此处*。本质上,Scala编译器发现没有apply
方法期望在UInt
上定义了Seq
,因此它注意到SeqToAugmentedSeq
被导入到作用域中并提供了这种方法。它进行了以下转换:
val funct = Seq(0.U,4.U,6.U,7.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,3.U))).apply(Cat(x(12),5)))
我希望这会有所帮助!
*对象上的括号正在调用SeqToAugmentedSeq
。 myUInt(3)
等同于myUInt.apply(3)
。
此行声明一个常量Seq:
//idx:0 1 2 3 4 5 6 7
Seq(0.U,3.U)
然后返回由索引Cat(x(12),5))
给出的项目(UInt)。
x
应该在之前和UInt
之前声明。如果我们这样声明:
val x = "b0001000011000001".U(16.W)
我们将有x(12) = 1.U
和x(6,5) = 3.U
(或“ b11” .U),然后是Cat(x(12),5)) == "b111".U == 7.U
返回的索引为7,对应于最初声明的序列Seq()中的3.U。
那么funct的值将是:
val funct = 3.U