tilelink2: get rid of fragile implicit lazyModule pattern, and support :=
We can more reliably find the current LazyModule from the LazyModule.stack
This commit is contained in:
		| @@ -39,10 +39,10 @@ class TLBuffer(entries: Int = 2, pipe: Boolean = false) extends LazyModule | ||||
|  | ||||
| object TLBuffer | ||||
| { | ||||
|   // applied to the TL source node; connect (TLBuffer(x.node) -> y.node) | ||||
|   def apply(x: TLBaseNode, entries: Int = 2, pipe: Boolean = false)(implicit lazyModule: LazyModule, sourceInfo: SourceInfo): TLBaseNode = { | ||||
|   // applied to the TL source node; y.node := TLBuffer(x.node) | ||||
|   def apply(x: TLBaseNode, entries: Int = 2, pipe: Boolean = false)(implicit sourceInfo: SourceInfo): TLBaseNode = { | ||||
|     val buffer = LazyModule(new TLBuffer(entries, pipe)) | ||||
|     lazyModule.connect(x -> buffer.node) | ||||
|     buffer.node := x | ||||
|     buffer.node | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -240,10 +240,10 @@ class TLFragmenter(minSize: Int, maxSize: Int, alwaysMin: Boolean = false) exten | ||||
|  | ||||
| object TLFragmenter | ||||
| { | ||||
|   // applied to the TL source node; connect (TLFragmenter(x.node, 256, 4) -> y.node) | ||||
|   def apply(x: TLBaseNode, minSize: Int, maxSize: Int, alwaysMin: Boolean = false)(implicit lazyModule: LazyModule, sourceInfo: SourceInfo): TLBaseNode = { | ||||
|   // applied to the TL source node; y.node := TLFragmenter(x.node, 256, 4) | ||||
|   def apply(x: TLBaseNode, minSize: Int, maxSize: Int, alwaysMin: Boolean = false)(implicit sourceInfo: SourceInfo): TLBaseNode = { | ||||
|     val fragmenter = LazyModule(new TLFragmenter(minSize, maxSize, alwaysMin)) | ||||
|     lazyModule.connect(x -> fragmenter.node) | ||||
|     fragmenter.node := x | ||||
|     fragmenter.node | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -90,10 +90,10 @@ class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = f | ||||
|  | ||||
| object TLHintHandler | ||||
| { | ||||
|   // applied to the TL source node; connect (TLHintHandler(x.node) -> y.node) | ||||
|   def apply(x: TLBaseNode, supportManagers: Boolean = true, supportClients: Boolean = false, passthrough: Boolean = true)(implicit lazyModule: LazyModule, sourceInfo: SourceInfo): TLBaseNode = { | ||||
|   // applied to the TL source node; y.node := TLHintHandler(x.node) | ||||
|   def apply(x: TLBaseNode, supportManagers: Boolean = true, supportClients: Boolean = false, passthrough: Boolean = true)(implicit sourceInfo: SourceInfo): TLBaseNode = { | ||||
|     val hints = LazyModule(new TLHintHandler(supportManagers, supportClients, passthrough)) | ||||
|     lazyModule.connect(x -> hints.node) | ||||
|     hints.node := x | ||||
|     hints.node | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -18,16 +18,13 @@ abstract class LazyModule | ||||
|  | ||||
|   // 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 | ||||
|     } | ||||
|     edges.foreach { case (source, sink) => sink := source } | ||||
|   } | ||||
|  | ||||
|   def name = getClass.getName.split('.').last | ||||
|   def line = sourceLine(info) | ||||
|  | ||||
|   def module: LazyModuleImp | ||||
|   implicit val lazyModule = this | ||||
|  | ||||
|   protected[tilelink2] def instantiate() = { | ||||
|     children.reverse.foreach { c =>  | ||||
|   | ||||
| @@ -76,20 +76,21 @@ class BaseNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])( | ||||
|   def connectOut = bundleOut | ||||
|   def connectIn = bundleIn | ||||
|  | ||||
|   // source.edge(sink) | ||||
|   protected[tilelink2] def edge(x: BaseNode[PO, PI, EO, EI, B])(implicit sourceInfo: SourceInfo) = { | ||||
|   protected[tilelink2] def := (y: BaseNode[PO, PI, EO, EI, B])(implicit sourceInfo: SourceInfo) = { | ||||
|     val x = this // x := y | ||||
|     val info = sourceLine(sourceInfo, " at ", "") | ||||
|     require (!noOs, s"${name}${lazyModule.line} was incorrectly connected as a source" + info) | ||||
|     require (!oRealized, s"${name}${lazyModule.line} was incorrectly connected as a source after it's .module was used" + info) | ||||
|     require (!LazyModule.stack.isEmpty, s"${y.name} cannot be connected to ${x.name} outside of LazyModule scope" + info) | ||||
|     require (!y.noOs, s"${y.name}${y.lazyModule.line} was incorrectly connected as a source" + info) | ||||
|     require (!y.oRealized, s"${y.name}${y.lazyModule.line} was incorrectly connected as a source after it's .module was used" + info) | ||||
|     require (!x.noIs, s"${x.name}${x.lazyModule.line} was incorrectly connected as a sink" + info) | ||||
|     require (!x.iRealized, s"${x.name}${x.lazyModule.line} was incorrectly connected as a sink after it's .module was used" + info) | ||||
|     val i = x.accPI.size | ||||
|     val o = accPO.size | ||||
|     accPO += ((i, x)) | ||||
|     x.accPI += ((o, this)) | ||||
|     () => { | ||||
|       imp.connect(connectOut(o), edgesOut(o), x.connectIn(i), x.edgesIn(i)) | ||||
|     } | ||||
|     val o = y.accPO.size | ||||
|     y.accPO += ((i, x)) | ||||
|     x.accPI += ((o, y)) | ||||
|     LazyModule.stack.head.bindings = (() => { | ||||
|       imp.connect(y.connectOut(o), y.edgesOut(o), x.connectIn(i), x.edgesIn(i)) | ||||
|     }) :: LazyModule.stack.head.bindings | ||||
|   } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -171,10 +171,10 @@ class TLWidthWidget(innerBeatBytes: Int) extends LazyModule | ||||
|  | ||||
| object TLWidthWidget | ||||
| { | ||||
|   // applied to the TL source node; connect (WidthWidget(x.node, 16) -> y.node) | ||||
|   def apply(x: TLBaseNode, innerBeatBytes: Int)(implicit lazyModule: LazyModule, sourceInfo: SourceInfo): TLBaseNode = { | ||||
|   // applied to the TL source node; y.node := WidthWidget(x.node, 16) | ||||
|   def apply(x: TLBaseNode, innerBeatBytes: Int)(implicit sourceInfo: SourceInfo): TLBaseNode = { | ||||
|     val widget = LazyModule(new TLWidthWidget(innerBeatBytes)) | ||||
|     lazyModule.connect(x -> widget.node) | ||||
|     widget.node := x | ||||
|     widget.node | ||||
|   } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user