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