1
0

tilelink2 Nodes: split connect into eager and lazy halves

This commit is contained in:
Wesley W. Terpstra 2016-09-21 12:08:05 -07:00
parent 684072023f
commit d1151e2f0f
4 changed files with 25 additions and 14 deletions

View File

@ -225,7 +225,7 @@ class TLFuzzRAM extends LazyModule
ram2.node := TLFragmenter(xbar2.node, 16, 256) ram2.node := TLFragmenter(xbar2.node, 16, 256)
xbar.node := TLWidthWidget(TLHintHandler(xbar2.node), 16) xbar.node := TLWidthWidget(TLHintHandler(xbar2.node), 16)
cross.node := TLFragmenter(TLBuffer(xbar.node), 4, 256) cross.node := TLFragmenter(TLBuffer(xbar.node), 4, 256)
ram.node := cross.node val monitor = (ram.node := cross.node)
gpio.node := TLFragmenter(TLBuffer(xbar.node), 4, 32) gpio.node := TLFragmenter(TLBuffer(xbar.node), 4, 32)
lazy val module = new LazyModuleImp(this) with HasUnitTestIO { lazy val module = new LazyModuleImp(this) with HasUnitTestIO {
@ -240,6 +240,12 @@ class TLFuzzRAM extends LazyModule
cross.module.io.in_reset := reset cross.module.io.in_reset := reset
cross.module.io.out_clock := clocks.io.clock_out cross.module.io.out_clock := clocks.io.clock_out
cross.module.io.out_reset := reset cross.module.io.out_reset := reset
// Push the Monitor into the right clock domain
monitor.foreach { m =>
m.module.clock := clocks.io.clock_out
m.module.reset := reset
}
} }
} }

View File

@ -60,10 +60,12 @@ object IntImp extends NodeImp[IntSourcePortParameters, IntSinkPortParameters, In
Vec(ei.size, Vec(ei.map(_.source.num).max, Bool())).flip Vec(ei.size, Vec(ei.map(_.source.num).max, Bool())).flip
} }
def connect(bo: Vec[Bool], eo: IntEdge, bi: Vec[Bool], ei: IntEdge)(implicit sourceInfo: SourceInfo): Unit = { def connect(bo: => Vec[Bool], eo: => IntEdge, bi: => Vec[Bool], ei: => IntEdge)(implicit sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = {
require (eo == ei) (None, () => {
// Cannot use bulk connect, because the widths could differ require (eo == ei)
(bo zip bi) foreach { case (o, i) => i := o } // Cannot use bulk connect, because the widths could differ
(bo zip bi) foreach { case (o, i) => i := o }
})
} }
override def mixO(po: IntSourcePortParameters, node: IntBaseNode): IntSourcePortParameters = override def mixO(po: IntSourcePortParameters, node: IntBaseNode): IntSourcePortParameters =

View File

@ -16,7 +16,7 @@ abstract class NodeImp[PO, PI, EO, EI, B <: Data]
def edgeI(po: PO, pi: PI): EI def edgeI(po: PO, pi: PI): EI
def bundleO(eo: Seq[EO]): Vec[B] def bundleO(eo: Seq[EO]): Vec[B]
def bundleI(ei: Seq[EI]): Vec[B] def bundleI(ei: Seq[EI]): Vec[B]
def connect(bo: B, eo: EO, bi: B, ei: EI)(implicit sourceInfo: SourceInfo): Unit def connect(bo: => B, eo: => EO, bi: => B, ei: => EI)(implicit sourceInfo: SourceInfo): (Option[LazyModule], () => Unit)
// If you want to track parameters as they flow through nodes, overload these: // If you want to track parameters as they flow through nodes, overload these:
def mixO(po: PO, node: BaseNode[PO, PI, EO, EI, B]): PO = po def mixO(po: PO, node: BaseNode[PO, PI, EO, EI, B]): PO = po
def mixI(pi: PI, node: BaseNode[PO, PI, EO, EI, B]): PI = pi def mixI(pi: PI, node: BaseNode[PO, PI, EO, EI, B]): PI = pi
@ -79,7 +79,7 @@ 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
def := (y: BaseNode[PO, PI, EO, EI, B])(implicit sourceInfo: SourceInfo) = { def := (y: BaseNode[PO, PI, EO, EI, B])(implicit sourceInfo: SourceInfo): Option[LazyModule] = {
val x = this // x := y val x = this // x := y
val info = sourceLine(sourceInfo, " at ", "") val info = sourceLine(sourceInfo, " at ", "")
require (!LazyModule.stack.isEmpty, s"${y.name} cannot be connected to ${x.name} outside of LazyModule scope" + info) require (!LazyModule.stack.isEmpty, s"${y.name} cannot be connected to ${x.name} outside of LazyModule scope" + info)
@ -91,9 +91,9 @@ class BaseNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(
val o = y.accPO.size val o = y.accPO.size
y.accPO += ((i, x)) y.accPO += ((i, x))
x.accPI += ((o, y)) x.accPI += ((o, y))
LazyModule.stack.head.bindings = (() => { val (out, binding) = imp.connect(y.connectOut(o), y.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 = binding :: LazyModule.stack.head.bindings
}) :: LazyModule.stack.head.bindings out
} }
} }

View File

@ -19,10 +19,13 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL
Vec(ei.size, TLBundle(ei.map(_.bundle).reduce(_.union(_)))).flip Vec(ei.size, TLBundle(ei.map(_.bundle).reduce(_.union(_)))).flip
} }
def connect(bo: TLBundle, eo: TLEdgeOut, bi: TLBundle, ei: TLEdgeIn)(implicit sourceInfo: SourceInfo): Unit = { def connect(bo: => TLBundle, eo: => TLEdgeOut, bi: => TLBundle, ei: => TLEdgeIn)(implicit sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = {
require (eo.asInstanceOf[TLEdgeParameters] == ei.asInstanceOf[TLEdgeParameters]) val monitor = LazyModule(new TLMonitor(() => new TLBundleSnoop(bo.params), () => eo, sourceInfo))
// TLMonitor.legalize(bo, eo) (Some(monitor), () => {
bi <> bo require (eo.asInstanceOf[TLEdgeParameters] == ei.asInstanceOf[TLEdgeParameters])
bi <> bo
monitor.module.io.in := TLBundleSnoop(bo)
})
} }
override def mixO(po: TLClientPortParameters, node: TLBaseNode): TLClientPortParameters = override def mixO(po: TLClientPortParameters, node: TLBaseNode): TLClientPortParameters =