tilelink2: decouple BaseNode from TileLink bus (so it can be reused)
This commit is contained in:
parent
c785375276
commit
69b3de92a8
@ -11,9 +11,9 @@ abstract class LazyModule
|
|||||||
private val bindings = ListBuffer[() => Unit]()
|
private val bindings = ListBuffer[() => Unit]()
|
||||||
|
|
||||||
// Use as: connect(source -> sink, source2 -> sink2, ...)
|
// Use as: connect(source -> sink, source2 -> sink2, ...)
|
||||||
def connect(edges: (TLBaseNode, TLBaseNode)*)(implicit sourceInfo: SourceInfo) = {
|
def connect[PO, PI, EO, EI, B <: Bundle](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) =>
|
||||||
bindings += sink.edge(source)
|
bindings += (source edge sink)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,9 +6,22 @@ import Chisel._
|
|||||||
import scala.collection.mutable.ListBuffer
|
import scala.collection.mutable.ListBuffer
|
||||||
import chisel3.internal.sourceinfo.SourceInfo
|
import chisel3.internal.sourceinfo.SourceInfo
|
||||||
|
|
||||||
class TLBaseNode(
|
// PI = PortInputParameters
|
||||||
private val clientFn: Option[Seq[TLClientPortParameters] => TLClientPortParameters],
|
// PO = PortOutputParameters
|
||||||
private val managerFn: Option[Seq[TLManagerPortParameters] => TLManagerPortParameters],
|
// EI = EdgeInput
|
||||||
|
// EO = EdgeOutput
|
||||||
|
abstract class NodeImp[PO, PI, EO, EI, B <: Bundle]
|
||||||
|
{
|
||||||
|
def edgeO(po: PO, pi: PI): EO
|
||||||
|
def edgeI(po: PO, pi: PI): EI
|
||||||
|
def bundleO(eo: Seq[EO]): Vec[B]
|
||||||
|
def bundleI(ei: Seq[EI]): Vec[B]
|
||||||
|
def connect(bo: B, eo: EO, bi: B, ei: EI)(implicit sourceInfo: SourceInfo): Unit
|
||||||
|
}
|
||||||
|
|
||||||
|
class BaseNode[PO, PI, EO, EI, B <: Bundle](imp: NodeImp[PO, PI, EO, EI, B])(
|
||||||
|
private val clientFn: Option[Seq[PO] => PO],
|
||||||
|
private val managerFn: Option[Seq[PI] => PI],
|
||||||
private val numClientPorts: Range.Inclusive,
|
private val numClientPorts: Range.Inclusive,
|
||||||
private val numManagerPorts: Range.Inclusive)
|
private val numManagerPorts: Range.Inclusive)
|
||||||
{
|
{
|
||||||
@ -24,50 +37,44 @@ class TLBaseNode(
|
|||||||
require (noClients || clientFn.isDefined)
|
require (noClients || clientFn.isDefined)
|
||||||
require (noManagers || managerFn.isDefined)
|
require (noManagers || managerFn.isDefined)
|
||||||
|
|
||||||
private val accClientPorts = ListBuffer[TLBaseNode]()
|
private val accClientPorts = ListBuffer[BaseNode[PO, PI, EO, EI, B]]()
|
||||||
private val accManagerPorts = ListBuffer[TLBaseNode]()
|
private val accManagerPorts = ListBuffer[BaseNode[PO, PI, EO, EI, B]]()
|
||||||
private var clientRealized = false
|
private var clientRealized = false
|
||||||
private var managerRealized = false
|
private var managerRealized = false
|
||||||
|
|
||||||
private lazy val clientPorts = { clientRealized = true; require (numClientPorts.contains(accClientPorts.size)); accClientPorts.result() }
|
private lazy val clientPorts = { clientRealized = true; require (numClientPorts.contains(accClientPorts.size)); accClientPorts.result() }
|
||||||
private lazy val managerPorts = { managerRealized = true; require (numManagerPorts.contains(accManagerPorts.size)); accManagerPorts.result() }
|
private lazy val managerPorts = { managerRealized = true; require (numManagerPorts.contains(accManagerPorts.size)); accManagerPorts.result() }
|
||||||
private lazy val clientParams : Option[TLClientPortParameters] = clientFn.map(_(managerPorts.map(_.clientParams.get)))
|
private lazy val clientParams : Option[PO] = clientFn.map(_(managerPorts.map(_.clientParams.get)))
|
||||||
private lazy val managerParams : Option[TLManagerPortParameters] = managerFn.map(_(clientPorts.map(_.managerParams.get)))
|
private lazy val managerParams : Option[PI] = managerFn.map(_(clientPorts.map(_.managerParams.get)))
|
||||||
|
|
||||||
lazy val edgesOut = clientPorts.map { n => new TLEdgeOut(clientParams.get, n.managerParams.get) }
|
lazy val edgesOut = clientPorts.map { n => imp.edgeO(clientParams.get, n.managerParams.get) }
|
||||||
lazy val edgesIn = managerPorts.map { n => new TLEdgeIn (n.clientParams.get, managerParams.get) }
|
lazy val edgesIn = managerPorts.map { n => imp.edgeI(n.clientParams.get, managerParams.get) }
|
||||||
|
|
||||||
lazy val bundleOut = { require (!edgesOut.isEmpty); Vec(edgesOut.size, TLBundle(edgesOut.map(_.bundle).reduce(_.union(_)))) }
|
lazy val bundleOut = imp.bundleO(edgesOut)
|
||||||
lazy val bundleIn = { require (!edgesIn .isEmpty); Vec(edgesIn .size, TLBundle(edgesIn .map(_.bundle).reduce(_.union(_)))).flip }
|
lazy val bundleIn = imp.bundleI(edgesIn)
|
||||||
|
|
||||||
def connectOut = bundleOut
|
def connectOut = bundleOut
|
||||||
def connectIn = bundleIn
|
def connectIn = bundleIn
|
||||||
|
|
||||||
protected[tilelink2] def edge(x: TLBaseNode)(implicit sourceInfo: SourceInfo) = {
|
// source.edge(sink)
|
||||||
require (!noManagers)
|
protected[tilelink2] def edge(x: BaseNode[PO, PI, EO, EI, B])(implicit sourceInfo: SourceInfo) = {
|
||||||
require (!managerRealized)
|
require (!noClients)
|
||||||
require (!x.noClients)
|
require (!clientRealized)
|
||||||
require (!x.clientRealized)
|
require (!x.noManagers)
|
||||||
val i = accManagerPorts.size
|
require (!x.managerRealized)
|
||||||
val j = x.accClientPorts.size
|
val i = x.accManagerPorts.size
|
||||||
accManagerPorts += x
|
val o = accClientPorts.size
|
||||||
x.accClientPorts += this
|
accClientPorts += x
|
||||||
|
x.accManagerPorts += this
|
||||||
() => {
|
() => {
|
||||||
val in = connectIn(i)
|
imp.connect(connectOut(o), edgesOut(o), x.connectIn(i), x.edgesIn(i))
|
||||||
val out = x.connectOut(j)
|
|
||||||
TLMonitor.legalize(out, x.edgesOut(j), in, edgesIn(i), sourceInfo)
|
|
||||||
in <> out
|
|
||||||
val mask = ~UInt(edgesIn(i).manager.beatBytes - 1)
|
|
||||||
in .a.bits.address := (mask & out.a.bits.address)
|
|
||||||
out.b.bits.address := (mask & in .b.bits.address)
|
|
||||||
in .c.bits.address := (mask & out.c.bits.address)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TLClientNode(
|
class TLClientNode(
|
||||||
params: TLClientParameters,
|
params: TLClientParameters,
|
||||||
numPorts: Range.Inclusive = 1 to 1) extends TLBaseNode(
|
numPorts: Range.Inclusive = 1 to 1) extends BaseNode(TLImp)(
|
||||||
clientFn = Some {case Seq() => TLClientPortParameters(Seq(params))},
|
clientFn = Some {case Seq() => TLClientPortParameters(Seq(params))},
|
||||||
managerFn = None,
|
managerFn = None,
|
||||||
numClientPorts = numPorts,
|
numClientPorts = numPorts,
|
||||||
@ -86,7 +93,7 @@ object TLClientNode
|
|||||||
class TLManagerNode(
|
class TLManagerNode(
|
||||||
beatBytes: Int,
|
beatBytes: Int,
|
||||||
params: TLManagerParameters,
|
params: TLManagerParameters,
|
||||||
numPorts: Range.Inclusive = 1 to 1) extends TLBaseNode(
|
numPorts: Range.Inclusive = 1 to 1) extends BaseNode(TLImp)(
|
||||||
clientFn = None,
|
clientFn = None,
|
||||||
managerFn = Some {case Seq() => TLManagerPortParameters(Seq(params), beatBytes)},
|
managerFn = Some {case Seq() => TLManagerPortParameters(Seq(params), beatBytes)},
|
||||||
numClientPorts = 0 to 0,
|
numClientPorts = 0 to 0,
|
||||||
@ -107,7 +114,7 @@ class TLAdapterNode(
|
|||||||
clientFn: Seq[TLClientPortParameters] => TLClientPortParameters,
|
clientFn: Seq[TLClientPortParameters] => TLClientPortParameters,
|
||||||
managerFn: Seq[TLManagerPortParameters] => TLManagerPortParameters,
|
managerFn: Seq[TLManagerPortParameters] => TLManagerPortParameters,
|
||||||
numClientPorts: Range.Inclusive = 1 to 1,
|
numClientPorts: Range.Inclusive = 1 to 1,
|
||||||
numManagerPorts: Range.Inclusive = 1 to 1) extends TLBaseNode(
|
numManagerPorts: Range.Inclusive = 1 to 1) extends BaseNode(TLImp)(
|
||||||
clientFn = Some(clientFn),
|
clientFn = Some(clientFn),
|
||||||
managerFn = Some(managerFn),
|
managerFn = Some(managerFn),
|
||||||
numClientPorts = numClientPorts,
|
numClientPorts = numClientPorts,
|
||||||
@ -122,7 +129,7 @@ object TLAdapterNode
|
|||||||
numManagerPorts: Range.Inclusive = 1 to 1) = new TLAdapterNode(clientFn, managerFn, numClientPorts, numManagerPorts)
|
numManagerPorts: Range.Inclusive = 1 to 1) = new TLAdapterNode(clientFn, managerFn, numClientPorts, numManagerPorts)
|
||||||
}
|
}
|
||||||
|
|
||||||
class TLOutputNode extends TLBaseNode(
|
class TLOutputNode extends BaseNode(TLImp)(
|
||||||
clientFn = Some({case Seq(x) => x}),
|
clientFn = Some({case Seq(x) => x}),
|
||||||
managerFn = Some({case Seq(x) => x}),
|
managerFn = Some({case Seq(x) => x}),
|
||||||
numClientPorts = 1 to 1,
|
numClientPorts = 1 to 1,
|
||||||
@ -137,7 +144,7 @@ object TLOutputNode
|
|||||||
def apply() = new TLOutputNode()
|
def apply() = new TLOutputNode()
|
||||||
}
|
}
|
||||||
|
|
||||||
class TLInputNode extends TLBaseNode(
|
class TLInputNode extends BaseNode(TLImp)(
|
||||||
clientFn = Some({case Seq(x) => x}),
|
clientFn = Some({case Seq(x) => x}),
|
||||||
managerFn = Some({case Seq(x) => x}),
|
managerFn = Some({case Seq(x) => x}),
|
||||||
numClientPorts = 1 to 1,
|
numClientPorts = 1 to 1,
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
package uncore.tilelink2
|
package uncore.tilelink2
|
||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
|
import chisel3.internal.sourceinfo.SourceInfo
|
||||||
|
|
||||||
class TLEdge(
|
class TLEdge(
|
||||||
client: TLClientPortParameters,
|
client: TLClientPortParameters,
|
||||||
@ -430,3 +431,26 @@ class TLEdgeIn(
|
|||||||
d
|
d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TLEdgeOut, TLEdgeIn, TLBundle]
|
||||||
|
{
|
||||||
|
def edgeO(po: TLClientPortParameters, pi: TLManagerPortParameters): TLEdgeOut = new TLEdgeOut(po, pi)
|
||||||
|
def edgeI(po: TLClientPortParameters, pi: TLManagerPortParameters): TLEdgeIn = new TLEdgeIn(po, pi)
|
||||||
|
def bundleO(eo: Seq[TLEdgeOut]): Vec[TLBundle] = {
|
||||||
|
require (!eo.isEmpty)
|
||||||
|
Vec(eo.size, TLBundle(eo.map(_.bundle).reduce(_.union(_))))
|
||||||
|
}
|
||||||
|
def bundleI(ei: Seq[TLEdgeIn]): Vec[TLBundle] = {
|
||||||
|
require (!ei.isEmpty)
|
||||||
|
Vec(ei.size, TLBundle(ei.map(_.bundle).reduce(_.union(_)))).flip
|
||||||
|
}
|
||||||
|
|
||||||
|
def connect(bo: TLBundle, eo: TLEdgeOut, bi: TLBundle, ei: TLEdgeIn)(implicit sourceInfo: SourceInfo): Unit = {
|
||||||
|
TLMonitor.legalize(bo, eo, bi, ei, sourceInfo)
|
||||||
|
bi <> bo
|
||||||
|
val mask = ~UInt(ei.manager.beatBytes - 1)
|
||||||
|
bi.a.bits.address := (mask & bo.a.bits.address)
|
||||||
|
bo.b.bits.address := (mask & bi.b.bits.address)
|
||||||
|
bi.c.bits.address := (mask & bo.c.bits.address)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user