Search code examples
scalachiselrocket-chip

How to use Seq with Cat in Chisel?


I am learning chisel and rocket-chip. The rocket-chip has a code using Seq and Cat in RVC.scala.

    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)))

But when I write my code as above, I got an Error. chisel reports type mismatch.


Solution

  • Scala provides a very powerful feature called Implicit Conversions. I'll leave it to the many explanations on StackOverflow and otherwise findable by Google to explain the details and motivation, but let me explain how they are used in Chisel and Rocket Chip.

    Ints in Scala (like 3) are equivalent to primitive Java ints. If you check the 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 that essentially allows us to define def U as if it were defined on the Scala Int class itself. By virtue of import chisel3._, you are importing fromIntToLiteral and telling the Scala compiler that actually, Int does have a method called U!

    Rocket Chip has some of its own implicit conversions that the authors thought would be useful. In this case, freechips.rocketchip.util contains SeqToAugmentedSeq that defines def apply(idx: UInt): T, the function being called here*. Essentially, the Scala compiler is seeing that there's no apply method expecting a UInt defined on Seq, so it notices that SeqToAugmentedSeq is imported into the scope and provides such a method. It makes the following transformation:

    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)))
    

    I hope this helps!

    *Parentheses on an object is calling the apply method. myUInt(3) is equivalent to myUInt.apply(3).