1
0
rocket-chip/src/main/scala/uncore/tilelink2/LazyModule.scala

61 lines
1.8 KiB
Scala
Raw Normal View History

// See LICENSE for license details.
package uncore.tilelink2
import Chisel._
import chisel3.internal.sourceinfo._
abstract class LazyModule
{
protected[tilelink2] var bindings = List[() => Unit]()
protected[tilelink2] var children = List[LazyModule]()
protected[tilelink2] var info: SourceInfo = UnlocatableSourceInfo
protected[tilelink2] val parent = LazyModule.stack.headOption
LazyModule.stack = this :: LazyModule.stack
parent.foreach(p => p.children = this :: p.children)
// Use as: connect(source -> sink, source2 -> sink2, ...)
def connect[PO, PI, EO, EI, B <: Data](edges: (BaseNode[PO, PI, EO, EI, B], BaseNode[PO, PI, EO, EI, B])*)(implicit sourceInfo: SourceInfo) = {
edges.foreach { case (source, sink) =>
bindings = (source edge sink) :: bindings
}
}
def module: LazyModuleImp
implicit val lazyModule = this
protected[tilelink2] def instantiate() = {
children.reverse.foreach { c =>
// !!! fix chisel3 so we can pass the desired sourceInfo
// implicit val sourceInfo = c.module.outer.info
Module(c.module)
}
bindings.reverse.foreach { f => f () }
}
}
object LazyModule
{
protected[tilelink2] var stack = List[LazyModule]()
def apply[T <: LazyModule](bc: T)(implicit sourceInfo: SourceInfo): T = {
// Make sure the user put LazyModule around modules in the correct order
// If this require fails, probably some grandchild was missing a LazyModule
// ... or you applied LazyModule twice
require (!stack.isEmpty && (stack.head eq bc))
stack = stack.tail
bc.info = sourceInfo
bc
}
}
abstract class LazyModuleImp(outer: LazyModule) extends Module
{
// .module had better not be accessed while LazyModules are still being built!
require (LazyModule.stack.isEmpty)
override def desiredName = outer.getClass.getName.split('.').last
outer.instantiate()
}