tilelink2: decouple BaseNode from TileLink bus (so it can be reused)
This commit is contained in:
		@@ -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)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user