Scala предоставляет очень мощную функцию под названием неявные преобразования. Я оставлю это множеству объяснений на StackOverflow и других способах поиска Google, чтобы объяснить детали и мотивацию, но позвольте мне объяснить, как они используются в Chisel и Rocket Chip.
Ints
в Scala (например, 3
) эквивалентны примитивной Java ints
. Если вы посмотрите документацию по API, вы выиграете ' не найти какую-либо функцию def U
, но в Chisel мы можем создавать UInt
литералы как 3.U
. Это достигается с помощью неявного преобразования под названием fromIntToLiteral
, что позволяет нам определять def U
так, как если бы он был определен в самом классе Scala Int
. На основании import chisel3._
вы импортируете fromIntToLiteral
и сообщаете компилятору Scala, что на самом деле Int
имеет метод с именем U
!
В Rocket Chip есть несколько собственных неявных преобразований, которые, по мнению авторов, были бы полезны. В этом случае freechips.rocketchip.util
содержит SeqToAugmentedSeq
, который определяет def apply(idx: UInt): T
, вызываемую здесь функцию *. По сути, компилятор Scala видит, что не существует apply
метода, ожидающего UInt
, определенного в 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
a >. myUInt(3)
эквивалентно myUInt.apply(3)
.
person
Jack Koenig
schedule
14.11.2019