-
Notifications
You must be signed in to change notification settings - Fork 21
LazyModule
A LazyModule was created to decouple the point in the code where a circuit element is instantiated, from the point in the code where the constructor is called and that instance is actually built. The reason for the delay is that it gives a chance for other calculations to happen, which fill in the parameters that are passed to the constructor.
LazyModule is built on top of Scala's Lazy val mechanism:
If you put lazy
in front of a val
definition, the initializing expression on the right-hand side will only be evaluated at the time the val
is used (which can be long after the system was initialized and after other computation has completed, such as computation that figured out how you want to initialize the value).
To show the difference, start with example of normal initialization:
object Demo {
val x = { println("initializing x"); "done" }
}
Now, first refer to Demo
, then to Demo.x
:
>Demo
initializing x
res3: Demo.type = Demo$@2129a843
Chapter 20 · Abstract Members
>Demo.x
res4: String = done
The "initializing x" shows that as soon as you create Demo
, all it's internal val
s are also created. The x
field was initialed at the same point as Demo was initialized.
Now, see how it's different if x
is lazy:
object Demo {
lazy val x = { println("initializing x"); "done" }
}
defined object Demo
> Demo
res5: Demo.type = Demo$@5b1769c
> Demo.x
initializing x
res6: String = done
Aha, when Demo is initialized, nothing happens with x
! Only when you try to get the value of x
, does x
actually get created. Note that a lazy val
is never evaluated more than once. After the first evaluation of a lazy val
the result of the evaluation is stored, to be reused when the same val
is used subsequently.
More detailed explanations of lazy val
usage in Scala, and examples, may be found here.
LazyModule leverages the Lazy val concept, extending it to Chisel Modules. The reason is that the parameterization system needs to do computation before it figures out the interface to a particular module. For example the interface to RocketTile changes dramatically based on what parameter choices are made, and those parameters are not fully known at the point a RockeTile instance is created via "val rTile = RocketTile()". needs to run for a bit before initializing RocketTile.. but.. the scala language needs a place holder, that is created when the language initializes! Hence, LazyModule splits things into two pieces. Once piece is the placeholder class, that initializes when the program starts.. and the second piece is an internal module that initializes after Diplomacy has figured out its interface.
LazyModule
is an abstract class of rocket-chip
whose complete code is contained in LazyModule.scala
found here
LazyModule
represents the base for diplomacy
and cake pattern, as this abstract class is a module generator that allows postponed (lazy) module elaboration [3].
Classes children of LazyModule
are classes that are instantiated only when they are accessed for the first time.
Here are examples found in RocketTile.scala
:
val rocket = LazyModule(new RocketTile(rtp, hartid)) // @L158
~
val xing = LazyModule(new IntXing(3)) // @L173
~
val intXbar = LazyModule(new IntXbar) // @L176
~
lazy val module = new LazyModuleImp(this) { // @L183
The point of making modules "lazy" (read: "not instantiated until accessed for the first time") is to allow the Diplomacy and TileLink to negotiate during the elaboration phase about creating interfaces between those modules. The modules are written in a generic way. Separately, a user will choose parameters, such as which features to include. Then during the elaboration phase, Diplomacy and TileLink "calculate" exactly what is needed for communication between those modules, given the configuration chosen, and instantiate the modules with the appropriate interface.
RocketTile is a LazyModule, the actual implementation is instantiated here
RocketTile uses Diplomacy
- M. Odersky, Programming in Scala
- K. Bhimani, Updates to Sodor
- W. Song, Notes for Rocket-Chip