Merge pull request #536 from ucb-bar/diplomacy-star-nodes
diplomacy: add :*= and :=* to support flexible # of edges
This commit is contained in:
		| @@ -11,17 +11,14 @@ import util._ | |||||||
|  |  | ||||||
| class DefaultCoreplex(implicit p: Parameters) extends BaseCoreplex | class DefaultCoreplex(implicit p: Parameters) extends BaseCoreplex | ||||||
|     with CoreplexRISCVPlatform |     with CoreplexRISCVPlatform | ||||||
|     with HasL2MasterPort |  | ||||||
|     with HasRocketTiles { |     with HasRocketTiles { | ||||||
|   override lazy val module = new DefaultCoreplexModule(this, () => new DefaultCoreplexBundle(this)) |   override lazy val module = new DefaultCoreplexModule(this, () => new DefaultCoreplexBundle(this)) | ||||||
| } | } | ||||||
|  |  | ||||||
| class DefaultCoreplexBundle[+L <: DefaultCoreplex](_outer: L) extends BaseCoreplexBundle(_outer) | class DefaultCoreplexBundle[+L <: DefaultCoreplex](_outer: L) extends BaseCoreplexBundle(_outer) | ||||||
|     with CoreplexRISCVPlatformBundle |     with CoreplexRISCVPlatformBundle | ||||||
|     with HasL2MasterPortBundle |  | ||||||
|     with HasRocketTilesBundle |     with HasRocketTilesBundle | ||||||
|  |  | ||||||
| class DefaultCoreplexModule[+L <: DefaultCoreplex, +B <: DefaultCoreplexBundle[L]](_outer: L, _io: () => B) extends BaseCoreplexModule(_outer, _io) | class DefaultCoreplexModule[+L <: DefaultCoreplex, +B <: DefaultCoreplexBundle[L]](_outer: L, _io: () => B) extends BaseCoreplexModule(_outer, _io) | ||||||
|     with CoreplexRISCVPlatformModule |     with CoreplexRISCVPlatformModule | ||||||
|     with HasL2MasterPortModule |  | ||||||
|     with HasRocketTilesModule |     with HasRocketTilesModule | ||||||
|   | |||||||
| @@ -24,9 +24,13 @@ trait CoreplexNetwork extends HasCoreplexParameters { | |||||||
|  |  | ||||||
|   val mmio = TLOutputNode() |   val mmio = TLOutputNode() | ||||||
|   val mmioInt = IntInputNode() |   val mmioInt = IntInputNode() | ||||||
|  |   val l2in = TLInputNode() | ||||||
|  |  | ||||||
|   intBar.intnode := mmioInt |   intBar.intnode := mmioInt | ||||||
|  |  | ||||||
|  |   // Allows a variable number of inputs from outside to the Xbar | ||||||
|  |   l1tol2.node :=* l2in | ||||||
|  |  | ||||||
|   cbus.node := |   cbus.node := | ||||||
|     TLBuffer()( |     TLBuffer()( | ||||||
|     TLAtomicAutomata(arithmetic = true)( // disable once TLB uses TL2 metadata |     TLAtomicAutomata(arithmetic = true)( // disable once TLB uses TL2 metadata | ||||||
| @@ -43,6 +47,7 @@ trait CoreplexNetworkBundle extends HasCoreplexParameters { | |||||||
|  |  | ||||||
|   val mmio = outer.mmio.bundleOut |   val mmio = outer.mmio.bundleOut | ||||||
|   val interrupts = outer.mmioInt.bundleIn |   val interrupts = outer.mmioInt.bundleIn | ||||||
|  |   val l2in = outer.l2in.bundleIn | ||||||
| } | } | ||||||
|  |  | ||||||
| trait CoreplexNetworkModule extends HasCoreplexParameters { | trait CoreplexNetworkModule extends HasCoreplexParameters { | ||||||
| @@ -93,21 +98,3 @@ trait BankedL2CoherenceManagersModule extends CoreplexNetworkModule { | |||||||
|   val outer: BankedL2CoherenceManagers |   val outer: BankedL2CoherenceManagers | ||||||
|   val io: BankedL2CoherenceManagersBundle |   val io: BankedL2CoherenceManagersBundle | ||||||
| } | } | ||||||
|  |  | ||||||
| ///// |  | ||||||
|  |  | ||||||
| trait HasL2MasterPort extends CoreplexNetwork { |  | ||||||
|   val module: HasL2MasterPortModule |  | ||||||
|   val l2in = TLInputNode() |  | ||||||
|   l1tol2.node := TLBuffer()(l2in) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| trait HasL2MasterPortBundle extends CoreplexNetworkBundle { |  | ||||||
|   val outer: HasL2MasterPort |  | ||||||
|   val l2in = outer.l2in.bundleIn |  | ||||||
| } |  | ||||||
|  |  | ||||||
| trait HasL2MasterPortModule extends CoreplexNetworkModule { |  | ||||||
|   val outer: HasL2MasterPort |  | ||||||
|   val io: HasL2MasterPortBundle |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -16,7 +16,9 @@ trait InwardNodeImp[DI, UI, EI, BI <: Data] | |||||||
|   def edgeI(pd: DI, pu: UI): EI |   def edgeI(pd: DI, pu: UI): EI | ||||||
|   def bundleI(ei: Seq[EI]): Vec[BI] |   def bundleI(ei: Seq[EI]): Vec[BI] | ||||||
|   def colour: String |   def colour: String | ||||||
|   def connect(bo: => BI, bi: => BI, e: => EI)(implicit p: Parameters, sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) |   def connect(bindings: () => Seq[(EI, BI, BI)])(implicit p: Parameters, sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = { | ||||||
|  |     (None, () => bindings().foreach { case (_, i, o) => i <> o }) | ||||||
|  |   } | ||||||
|  |  | ||||||
|   // optional methods to track node graph |   // optional methods to track node graph | ||||||
|   def mixI(pu: UI, node: InwardNode[DI, UI, BI]): UI = pu // insert node into parameters |   def mixI(pu: UI, node: InwardNode[DI, UI, BI]): UI = pu // insert node into parameters | ||||||
| @@ -71,8 +73,17 @@ trait InwardNodeHandle[DI, UI, BI <: Data] | |||||||
|   val inward: InwardNode[DI, UI, BI] |   val inward: InwardNode[DI, UI, BI] | ||||||
|   def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[LazyModule] = |   def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[LazyModule] = | ||||||
|     inward.:=(h)(p, sourceInfo) |     inward.:=(h)(p, sourceInfo) | ||||||
|  |   def :*= (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[LazyModule] = | ||||||
|  |     inward.:*=(h)(p, sourceInfo) | ||||||
|  |   def :=* (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[LazyModule] = | ||||||
|  |     inward.:=*(h)(p, sourceInfo) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | sealed trait NodeBinding | ||||||
|  | case object BIND_ONCE  extends NodeBinding | ||||||
|  | case object BIND_QUERY extends NodeBinding | ||||||
|  | case object BIND_STAR  extends NodeBinding | ||||||
|  |  | ||||||
| trait InwardNode[DI, UI, BI <: Data] extends BaseNode with InwardNodeHandle[DI, UI, BI] | trait InwardNode[DI, UI, BI <: Data] extends BaseNode with InwardNodeHandle[DI, UI, BI] | ||||||
| { | { | ||||||
|   val inward = this |   val inward = this | ||||||
| @@ -81,21 +92,22 @@ trait InwardNode[DI, UI, BI <: Data] extends BaseNode with InwardNodeHandle[DI, | |||||||
|   require (!numPI.isEmpty, s"No number of inputs would be acceptable to ${name}${lazyModule.line}") |   require (!numPI.isEmpty, s"No number of inputs would be acceptable to ${name}${lazyModule.line}") | ||||||
|   require (numPI.start >= 0, s"${name} accepts a negative number of inputs${lazyModule.line}") |   require (numPI.start >= 0, s"${name} accepts a negative number of inputs${lazyModule.line}") | ||||||
|  |  | ||||||
|   private val accPI = ListBuffer[(Int, OutwardNode[DI, UI, BI])]() |   private val accPI = ListBuffer[(Int, OutwardNode[DI, UI, BI], NodeBinding)]() | ||||||
|   private var iRealized = false |   private var iRealized = false | ||||||
|  |  | ||||||
|   protected[diplomacy] def iPushed = accPI.size |   protected[diplomacy] def iPushed = accPI.size | ||||||
|   protected[diplomacy] def iPush(index: Int, node: OutwardNode[DI, UI, BI])(implicit sourceInfo: SourceInfo) { |   protected[diplomacy] def iPush(index: Int, node: OutwardNode[DI, UI, BI], binding: NodeBinding)(implicit sourceInfo: SourceInfo) { | ||||||
|     val info = sourceLine(sourceInfo, " at ", "") |     val info = sourceLine(sourceInfo, " at ", "") | ||||||
|     val noIs = numPI.size == 1 && numPI.contains(0) |     val noIs = numPI.size == 1 && numPI.contains(0) | ||||||
|     require (!noIs, s"${name}${lazyModule.line} was incorrectly connected as a sink" + info) |     require (!noIs, s"${name}${lazyModule.line} was incorrectly connected as a sink" + info) | ||||||
|     require (!iRealized, s"${name}${lazyModule.line} was incorrectly connected as a sink after it's .module was used" + info) |     require (!iRealized, s"${name}${lazyModule.line} was incorrectly connected as a sink after it's .module was used" + info) | ||||||
|     accPI += ((index, node)) |     accPI += ((index, node, binding)) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private def reqI() = require(numPI.contains(accPI.size), s"${name} has ${accPI.size} inputs, expected ${numPI}${lazyModule.line}") |   protected[diplomacy] lazy val iBindings = { iRealized = true; accPI.result() } | ||||||
|   protected[diplomacy] lazy val iPorts = { iRealized = true; reqI(); accPI.result() } |  | ||||||
|  |  | ||||||
|  |   protected[diplomacy] val iStar: Int | ||||||
|  |   protected[diplomacy] val iPortMapping: Seq[(Int, Int)] | ||||||
|   protected[diplomacy] val iParams: Seq[UI] |   protected[diplomacy] val iParams: Seq[UI] | ||||||
|   val bundleIn: Vec[BI] |   val bundleIn: Vec[BI] | ||||||
| } | } | ||||||
| @@ -113,48 +125,84 @@ trait OutwardNode[DO, UO, BO <: Data] extends BaseNode with OutwardNodeHandle[DO | |||||||
|   require (!numPO.isEmpty, s"No number of outputs would be acceptable to ${name}${lazyModule.line}") |   require (!numPO.isEmpty, s"No number of outputs would be acceptable to ${name}${lazyModule.line}") | ||||||
|   require (numPO.start >= 0, s"${name} accepts a negative number of outputs${lazyModule.line}") |   require (numPO.start >= 0, s"${name} accepts a negative number of outputs${lazyModule.line}") | ||||||
|  |  | ||||||
|   private val accPO = ListBuffer[(Int, InwardNode [DO, UO, BO])]() |   private val accPO = ListBuffer[(Int, InwardNode [DO, UO, BO], NodeBinding)]() | ||||||
|   private var oRealized = false |   private var oRealized = false | ||||||
|  |  | ||||||
|   protected[diplomacy] def oPushed = accPO.size |   protected[diplomacy] def oPushed = accPO.size | ||||||
|   protected[diplomacy] def oPush(index: Int, node: InwardNode [DO, UO, BO])(implicit sourceInfo: SourceInfo) { |   protected[diplomacy] def oPush(index: Int, node: InwardNode [DO, UO, BO], binding: NodeBinding)(implicit sourceInfo: SourceInfo) { | ||||||
|     val info = sourceLine(sourceInfo, " at ", "") |     val info = sourceLine(sourceInfo, " at ", "") | ||||||
|     val noOs = numPO.size == 1 && numPO.contains(0) |     val noOs = numPO.size == 1 && numPO.contains(0) | ||||||
|     require (!noOs, s"${name}${lazyModule.line} was incorrectly connected as a source" + info) |     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 (!oRealized, s"${name}${lazyModule.line} was incorrectly connected as a source after it's .module was used" + info) | ||||||
|     accPO += ((index, node)) |     accPO += ((index, node, binding)) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private def reqO() = require(numPO.contains(accPO.size), s"${name} has ${accPO.size} outputs, expected ${numPO}${lazyModule.line}") |   protected[diplomacy] lazy val oBindings = { oRealized = true; accPO.result() } | ||||||
|   protected[diplomacy] lazy val oPorts = { oRealized = true; reqO(); accPO.result() } |  | ||||||
|  |  | ||||||
|  |   protected[diplomacy] val oStar: Int | ||||||
|  |   protected[diplomacy] val oPortMapping: Seq[(Int, Int)] | ||||||
|   protected[diplomacy] val oParams: Seq[DO] |   protected[diplomacy] val oParams: Seq[DO] | ||||||
|   val bundleOut: Vec[BO] |   val bundleOut: Vec[BO] | ||||||
| } | } | ||||||
|  |  | ||||||
| class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( | abstract class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( | ||||||
|   inner: InwardNodeImp [DI, UI, EI, BI], |   inner: InwardNodeImp [DI, UI, EI, BI], | ||||||
|   outer: OutwardNodeImp[DO, UO, EO, BO])( |   outer: OutwardNodeImp[DO, UO, EO, BO])( | ||||||
|   private val dFn: (Int, Seq[DI]) => Seq[DO], |  | ||||||
|   private val uFn: (Int, Seq[UO]) => Seq[UI], |  | ||||||
|   protected[diplomacy] val numPO: Range.Inclusive, |   protected[diplomacy] val numPO: Range.Inclusive, | ||||||
|   protected[diplomacy] val numPI: Range.Inclusive) |   protected[diplomacy] val numPI: Range.Inclusive) | ||||||
|   extends BaseNode with InwardNode[DI, UI, BI] with OutwardNode[DO, UO, BO] |   extends BaseNode with InwardNode[DI, UI, BI] with OutwardNode[DO, UO, BO] | ||||||
| { | { | ||||||
|   // meta-data for printing the node graph |   protected[diplomacy] def resolveStarO(i: Int, o: Int): Int | ||||||
|   protected[diplomacy] def colour  = inner.colour |   protected[diplomacy] def resolveStarI(i: Int, o: Int): Int | ||||||
|   protected[diplomacy] def outputs = oPorts.map(_._2) zip edgesOut.map(e => outer.labelO(e)) |   protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO] | ||||||
|   protected[diplomacy] def inputs  = iPorts.map(_._2) zip edgesIn .map(e => inner.labelI(e)) |   protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI] | ||||||
|  |  | ||||||
|  |   protected[diplomacy] lazy val (oPortMapping, iPortMapping, oStar, iStar) = { | ||||||
|  |     val oStars = oBindings.filter { case (_,_,b) => b == BIND_STAR }.size | ||||||
|  |     val iStars = iBindings.filter { case (_,_,b) => b == BIND_STAR }.size | ||||||
|  |     require (oStars + iStars <= 1, s"${name} appears beside a :*= ${iStars} times and a :=* ${oStars} times; at most once is allowed${lazyModule.line}") | ||||||
|  |     val oKnown = oBindings.map { case (_, n, b) => b match { | ||||||
|  |       case BIND_ONCE  => 1 | ||||||
|  |       case BIND_QUERY => n.iStar | ||||||
|  |       case BIND_STAR  => 0 }}.foldLeft(0)(_+_) | ||||||
|  |     val iKnown = iBindings.map { case (_, n, b) => b match { | ||||||
|  |       case BIND_ONCE  => 1 | ||||||
|  |       case BIND_QUERY => n.oStar | ||||||
|  |       case BIND_STAR  => 0 }}.foldLeft(0)(_+_) | ||||||
|  |     val oStar = if (oStars > 0) resolveStarO(iKnown, oKnown) else 0 | ||||||
|  |     val iStar = if (iStars > 0) resolveStarI(iKnown, oKnown) else 0 | ||||||
|  |     val oSum = oBindings.map { case (_, n, b) => b match { | ||||||
|  |       case BIND_ONCE  => 1 | ||||||
|  |       case BIND_QUERY => n.iStar | ||||||
|  |       case BIND_STAR  => oStar }}.scanLeft(0)(_+_) | ||||||
|  |     val iSum = iBindings.map { case (_, n, b) => b match { | ||||||
|  |       case BIND_ONCE  => 1 | ||||||
|  |       case BIND_QUERY => n.oStar | ||||||
|  |       case BIND_STAR  => iStar }}.scanLeft(0)(_+_) | ||||||
|  |     val oTotal = oSum.lastOption.getOrElse(0) | ||||||
|  |     val iTotal = iSum.lastOption.getOrElse(0) | ||||||
|  |     require(numPO.contains(oTotal), s"${name} has ${oTotal} outputs, expected ${numPO}${lazyModule.line}") | ||||||
|  |     require(numPI.contains(iTotal), s"${name} has ${iTotal} inputs, expected ${numPI}${lazyModule.line}") | ||||||
|  |     (oSum.init zip oSum.tail, iSum.init zip iSum.tail, oStar, iStar) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   lazy val oPorts = oBindings.flatMap { case (i, n, _) => | ||||||
|  |     val (start, end) = n.iPortMapping(i) | ||||||
|  |     (start until end) map { j => (j, n) } | ||||||
|  |   } | ||||||
|  |   lazy val iPorts = iBindings.flatMap { case (i, n, _) => | ||||||
|  |     val (start, end) = n.oPortMapping(i) | ||||||
|  |     (start until end) map { j => (j, n) } | ||||||
|  |   } | ||||||
|  |  | ||||||
|   private def reqE(o: Int, i: Int) = require(i == o, s"${name} has ${i} inputs and ${o} outputs; they must match${lazyModule.line}") |  | ||||||
|   protected[diplomacy] lazy val oParams: Seq[DO] = { |   protected[diplomacy] lazy val oParams: Seq[DO] = { | ||||||
|     val o = dFn(oPorts.size, iPorts.map { case (i, n) => n.oParams(i) }) |     val o = mapParamsD(oPorts.size, iPorts.map { case (i, n) => n.oParams(i) }) | ||||||
|     reqE(oPorts.size, o.size) |     require (o.size == oPorts.size, s"Bug in diplomacy; ${name} has ${o.size} != ${oPorts.size} down/up outer parameters${lazyModule.line}") | ||||||
|     o.map(outer.mixO(_, this)) |     o.map(outer.mixO(_, this)) | ||||||
|   } |   } | ||||||
|   protected[diplomacy] lazy val iParams: Seq[UI] = { |   protected[diplomacy] lazy val iParams: Seq[UI] = { | ||||||
|     val i = uFn(iPorts.size, oPorts.map { case (o, n) => n.iParams(o) }) |     val i = mapParamsU(iPorts.size, oPorts.map { case (o, n) => n.iParams(o) }) | ||||||
|     reqE(i.size, iPorts.size) |     require (i.size == iPorts.size, s"Bug in diplomacy; ${name} has ${i.size} != ${iPorts.size} up/down inner parameters${lazyModule.line}") | ||||||
|     i.map(inner.mixI(_, this)) |     i.map(inner.mixI(_, this)) | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -175,87 +223,174 @@ class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( | |||||||
|   lazy val bundleIn  = wireI(flipI(inner.bundleI(edgesIn))) |   lazy val bundleIn  = wireI(flipI(inner.bundleI(edgesIn))) | ||||||
|  |  | ||||||
|   // connects the outward part of a node with the inward part of this node |   // connects the outward part of a node with the inward part of this node | ||||||
|   override def := (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[LazyModule] = { |   private def bind(h: OutwardNodeHandle[DI, UI, BI], binding: NodeBinding)(implicit p: Parameters, sourceInfo: SourceInfo): Option[LazyModule] = { | ||||||
|     val x = this // x := y |     val x = this // x := y | ||||||
|     val y = h.outward |     val y = h.outward | ||||||
|     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) | ||||||
|     val i = x.iPushed |     val i = x.iPushed | ||||||
|     val o = y.oPushed |     val o = y.oPushed | ||||||
|     y.oPush(i, x) |     y.oPush(i, x, binding match { | ||||||
|     x.iPush(o, y) |       case BIND_ONCE  => BIND_ONCE | ||||||
|     val (out, binding) = inner.connect(y.bundleOut(o), x.bundleIn(i), x.edgesIn(i)) |       case BIND_STAR  => BIND_QUERY | ||||||
|     LazyModule.stack.head.bindings = binding :: LazyModule.stack.head.bindings |       case BIND_QUERY => BIND_STAR }) | ||||||
|  |     x.iPush(o, y, binding) | ||||||
|  |     def bindings() = { | ||||||
|  |       val (iStart, iEnd) = x.iPortMapping(i) | ||||||
|  |       val (oStart, oEnd) = y.oPortMapping(o) | ||||||
|  |       require (iEnd - iStart == oEnd - oStart, s"Bug in diplomacy; ${iEnd-iStart} != ${oEnd-oStart} means port resolution failed") | ||||||
|  |       Seq.tabulate(iEnd - iStart) { j => | ||||||
|  |         (x.edgesIn(iStart+j), x.bundleIn(iStart+j), y.bundleOut(oStart+j)) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     val (out, newbinding) = inner.connect(bindings _) | ||||||
|  |     LazyModule.stack.head.bindings = newbinding :: LazyModule.stack.head.bindings | ||||||
|     out |     out | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   override def :=  (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[LazyModule] = bind(h, BIND_ONCE) | ||||||
|  |   override def :*= (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[LazyModule] = bind(h, BIND_STAR) | ||||||
|  |   override def :=* (h: OutwardNodeHandle[DI, UI, BI])(implicit p: Parameters, sourceInfo: SourceInfo): Option[LazyModule] = bind(h, BIND_QUERY) | ||||||
|  |  | ||||||
|  |   // meta-data for printing the node graph | ||||||
|  |   protected[diplomacy] def colour  = inner.colour | ||||||
|  |   protected[diplomacy] def outputs = oPorts.map(_._2) zip edgesOut.map(e => outer.labelO(e)) | ||||||
|  |   protected[diplomacy] def inputs  = iPorts.map(_._2) zip edgesIn .map(e => inner.labelI(e)) | ||||||
| } | } | ||||||
|  |  | ||||||
| class SimpleNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])( | class MixedAdapterNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( | ||||||
|   oFn: (Int, Seq[D]) => Seq[D], |   inner: InwardNodeImp [DI, UI, EI, BI], | ||||||
|   iFn: (Int, Seq[U]) => Seq[U], |   outer: OutwardNodeImp[DO, UO, EO, BO])( | ||||||
|   numPO: Range.Inclusive, |   dFn: DI => DO, | ||||||
|   numPI: Range.Inclusive) |   uFn: UO => UI, | ||||||
|     extends MixedNode[D, U, EI, B, D, U, EO, B](imp, imp)(oFn, iFn, numPO, numPI) |   num: Range.Inclusive = 0 to 999) | ||||||
|  |   extends MixedNode(inner, outer)(num, num) | ||||||
|  | { | ||||||
|  |   protected[diplomacy] def resolveStarO(i: Int, o: Int): Int = { | ||||||
|  |     require (i >= o, s"${name} has ${o} outputs and ${i} inputs; cannot assign ${i-o} edges to resolve :=*${lazyModule.line}") | ||||||
|  |     i - o | ||||||
|  |   } | ||||||
|  |   protected[diplomacy] def resolveStarI(i: Int, o: Int): Int = { | ||||||
|  |     require (o >= i, s"${name} has ${o} outputs and ${i} inputs; cannot assign ${o-i} edges to resolve :*=${lazyModule.line}") | ||||||
|  |     o - i | ||||||
|  |   } | ||||||
|  |   protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO] = { | ||||||
|  |     require(n == p.size, s"${name} has ${p.size} inputs and ${n} outputs; they must match${lazyModule.line}") | ||||||
|  |     p.map(dFn) | ||||||
|  |   } | ||||||
|  |   protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI] = { | ||||||
|  |     require(n == p.size, s"${name} has ${n} inputs and ${p.size} outputs; they must match${lazyModule.line}") | ||||||
|  |     p.map(uFn) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| class IdentityNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B]) | class MixedNexusNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( | ||||||
|   extends SimpleNode(imp)({case (_, s) => s}, {case (_, s) => s}, 0 to 999, 0 to 999) |   inner: InwardNodeImp [DI, UI, EI, BI], | ||||||
|  |   outer: OutwardNodeImp[DO, UO, EO, BO])( | ||||||
|  |   dFn: Seq[DI] => DO, | ||||||
|  |   uFn: Seq[UO] => UI, | ||||||
|  |   numPO: Range.Inclusive = 1 to 999, | ||||||
|  |   numPI: Range.Inclusive = 1 to 999) | ||||||
|  |   extends MixedNode(inner, outer)(numPO, numPI) | ||||||
|  | { | ||||||
|  |   require (numPO.end >= 1, s"${name} does not accept outputs${lazyModule.line}") | ||||||
|  |   require (numPI.end >= 1, s"${name} does not accept inputs${lazyModule.line}") | ||||||
|  |   protected[diplomacy] def resolveStarO(i: Int, o: Int): Int = { | ||||||
|  |     require (false, "${name} cannot resolve :=*${lazyModule.line}") | ||||||
|  |     0 | ||||||
|  |   } | ||||||
|  |   protected[diplomacy] def resolveStarI(i: Int, o: Int): Int = { | ||||||
|  |     require (false, s"${name} cannot resolve :*=${lazyModule.line}") | ||||||
|  |     0 | ||||||
|  |   } | ||||||
|  |   protected[diplomacy] def mapParamsD(n: Int, p: Seq[DI]): Seq[DO] = Seq.fill(n) { dFn(p) } | ||||||
|  |   protected[diplomacy] def mapParamsU(n: Int, p: Seq[UO]): Seq[UI] = Seq.fill(n) { uFn(p) } | ||||||
|  | } | ||||||
|  |  | ||||||
| class OutputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B]) extends IdentityNode(imp) | class AdapterNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])( | ||||||
|  |   dFn: D => D, | ||||||
|  |   uFn: U => U, | ||||||
|  |   num: Range.Inclusive = 0 to 999) | ||||||
|  |     extends MixedAdapterNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn, num) | ||||||
|  |  | ||||||
|  | class NexusNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])( | ||||||
|  |   dFn: Seq[D] => D, | ||||||
|  |   uFn: Seq[U] => U, | ||||||
|  |   numPO: Range.Inclusive = 1 to 999, | ||||||
|  |   numPI: Range.Inclusive = 1 to 999) | ||||||
|  |     extends MixedNexusNode[D, U, EI, B, D, U, EO, B](imp, imp)(dFn, uFn, numPO, numPI) | ||||||
|  |  | ||||||
|  | class IdentityNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B]) | ||||||
|  |   extends AdapterNode(imp)({s => s}, {s => s}) | ||||||
|  |  | ||||||
|  | class OutputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B]) extends IdentityNode(imp) | ||||||
| { | { | ||||||
|   override lazy val bundleIn = bundleOut |   override lazy val bundleIn = bundleOut | ||||||
| } | } | ||||||
|  |  | ||||||
| class InputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B]) extends IdentityNode(imp) | class InputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B]) extends IdentityNode(imp) | ||||||
| { | { | ||||||
|   override lazy val bundleOut = bundleIn |   override lazy val bundleOut = bundleIn | ||||||
| } | } | ||||||
|  |  | ||||||
| class SourceNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(po: PO, num: Range.Inclusive = 1 to 1) | class SourceNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq[D]) | ||||||
|   extends SimpleNode(imp)({case (n, Seq()) => Seq.fill(n)(po)}, {case (0, _) => Seq()}, num, 0 to 0) |   extends MixedNode(imp, imp)(po.size to po.size, 0 to 0) | ||||||
| { | { | ||||||
|   require (num.end >= 1, s"${name} is a source which does not accept outputs${lazyModule.line}") |   protected[diplomacy] def resolveStarO(i: Int, o: Int): Int = { | ||||||
|  |     require (po.size >= o, s"${name} has ${o} outputs out of ${po.size}; cannot assign ${po.size - o} edges to resolve :=*${lazyModule.line}") | ||||||
|  |     po.size - o | ||||||
|  |   } | ||||||
|  |   protected[diplomacy] def resolveStarI(i: Int, o: Int): Int = { | ||||||
|  |     require (false, s"${name} cannot resolve :*=${lazyModule.line}") | ||||||
|  |     0 | ||||||
|  |   } | ||||||
|  |   protected[diplomacy] def mapParamsD(n: Int, p: Seq[D]): Seq[D] = po | ||||||
|  |   protected[diplomacy] def mapParamsU(n: Int, p: Seq[U]): Seq[U] = Seq() | ||||||
|  |  | ||||||
|   override lazy val bundleIn = { require(false, s"${name} has no bundleIn; try bundleOut?"); bundleOut } |   override lazy val bundleIn = { require(false, s"${name} has no bundleIn; try bundleOut?"); bundleOut } | ||||||
| } | } | ||||||
|  |  | ||||||
| class SinkNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(pi: PI, num: Range.Inclusive = 1 to 1) | class SinkNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U]) | ||||||
|   extends SimpleNode(imp)({case (0, _) => Seq()}, {case (n, Seq()) => Seq.fill(n)(pi)}, 0 to 0, num) |   extends MixedNode(imp, imp)(0 to 0, pi.size to pi.size) | ||||||
| { | { | ||||||
|   require (num.end >= 1, s"${name} is a sink which does not accept inputs${lazyModule.line}") |   protected[diplomacy] def resolveStarO(i: Int, o: Int): Int = { | ||||||
|  |     require (false, s"${name} cannot resolve :=*${lazyModule.line}") | ||||||
|  |     0 | ||||||
|  |   } | ||||||
|  |   protected[diplomacy] def resolveStarI(i: Int, o: Int): Int = { | ||||||
|  |     require (pi.size >= i, s"${name} has ${i} inputs out of ${pi.size}; cannot assign ${pi.size - i} edges to resolve :*=${lazyModule.line}") | ||||||
|  |     pi.size - i | ||||||
|  |   } | ||||||
|  |   protected[diplomacy] def mapParamsD(n: Int, p: Seq[D]): Seq[D] = Seq() | ||||||
|  |   protected[diplomacy] def mapParamsU(n: Int, p: Seq[U]): Seq[U] = pi | ||||||
|  |  | ||||||
|   override lazy val bundleOut = { require(false, s"${name} has no bundleOut; try bundleIn?"); bundleIn } |   override lazy val bundleOut = { require(false, s"${name} has no bundleOut; try bundleIn?"); bundleIn } | ||||||
| } | } | ||||||
|  |  | ||||||
| class BlindOutputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(pi: Seq[PI]) | class BlindOutputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U]) | ||||||
|   extends SimpleNode(imp)({case (0, _) => Seq()}, {case (_, Seq()) => pi}, 0 to 0, pi.size to pi.size) |   extends SinkNode(imp)(pi) | ||||||
| { | { | ||||||
|   override val flip = true |   override val flip = true | ||||||
|   override lazy val bundleOut = bundleIn |   override lazy val bundleOut = bundleIn | ||||||
| } | } | ||||||
|  |  | ||||||
| class BlindInputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(po: Seq[PO]) | class BlindInputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq[D]) | ||||||
|   extends SimpleNode(imp)({case (_, Seq()) => po}, {case (0, _) => Seq()}, po.size to po.size, 0 to 0) |   extends SourceNode(imp)(po) | ||||||
| { | { | ||||||
|   override val flip = true |   override val flip = true | ||||||
|   override lazy val bundleIn = bundleOut |   override lazy val bundleIn = bundleOut | ||||||
| } | } | ||||||
|  |  | ||||||
| class InternalOutputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(pi: Seq[PI]) | class InternalOutputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(pi: Seq[U]) | ||||||
|   extends SimpleNode(imp)({case (0, _) => Seq()}, {case (_, Seq()) => pi}, 0 to 0, pi.size to pi.size) |   extends SinkNode(imp)(pi) | ||||||
| { | { | ||||||
|   override val wire = true |   override val wire = true | ||||||
|   override lazy val bundleOut = bundleIn |   override lazy val bundleOut = bundleIn | ||||||
| } | } | ||||||
|  |  | ||||||
| class InternalInputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(po: Seq[PO]) | class InternalInputNode[D, U, EO, EI, B <: Data](imp: NodeImp[D, U, EO, EI, B])(po: Seq[D]) | ||||||
|   extends SimpleNode(imp)({case (_, Seq()) => po}, {case (0, _) => Seq()}, po.size to po.size, 0 to 0) |   extends SourceNode(imp)(po) | ||||||
| { | { | ||||||
|   override val wire = true |   override val wire = true | ||||||
|   override lazy val bundleIn = bundleOut |   override lazy val bundleIn = bundleOut | ||||||
| } | } | ||||||
|  |  | ||||||
| class InteriorNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B]) |  | ||||||
|   (oFn: Seq[PO] => PO, iFn: Seq[PI] => PI, numPO: Range.Inclusive, numPI: Range.Inclusive) |  | ||||||
|   extends SimpleNode(imp)({case (n,s) => Seq.fill(n)(oFn(s))}, {case (n,s) => Seq.fill(n)(iFn(s))}, numPO, numPI) |  | ||||||
| { |  | ||||||
|   require (numPO.end >= 1, s"${name} is an adapter which does not accept outputs${lazyModule.line}") |  | ||||||
|   require (numPI.end >= 1, s"${name} is an adapter which does not accept inputs${lazyModule.line}") |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ import uncore.util._ | |||||||
|  |  | ||||||
| class ScratchpadSlavePort(implicit p: Parameters) extends LazyModule { | class ScratchpadSlavePort(implicit p: Parameters) extends LazyModule { | ||||||
|   val coreDataBytes = p(XLen)/8 |   val coreDataBytes = p(XLen)/8 | ||||||
|   val node = TLManagerNode(TLManagerPortParameters( |   val node = TLManagerNode(Seq(TLManagerPortParameters( | ||||||
|     Seq(TLManagerParameters( |     Seq(TLManagerParameters( | ||||||
|       address            = List(AddressSet(0x80000000L, BigInt(p(DataScratchpadSize)-1))), |       address            = List(AddressSet(0x80000000L, BigInt(p(DataScratchpadSize)-1))), | ||||||
|       regionType         = RegionType.UNCACHED, |       regionType         = RegionType.UNCACHED, | ||||||
| @@ -25,7 +25,7 @@ class ScratchpadSlavePort(implicit p: Parameters) extends LazyModule { | |||||||
|       supportsGet        = TransferSizes(1, coreDataBytes), |       supportsGet        = TransferSizes(1, coreDataBytes), | ||||||
|       fifoId             = Some(0))), // requests handled in FIFO order |       fifoId             = Some(0))), // requests handled in FIFO order | ||||||
|     beatBytes = coreDataBytes, |     beatBytes = coreDataBytes, | ||||||
|     minLatency = 1)) |     minLatency = 1))) | ||||||
|  |  | ||||||
|   lazy val module = new LazyModuleImp(this) { |   lazy val module = new LazyModuleImp(this) { | ||||||
|     val io = new Bundle { |     val io = new Bundle { | ||||||
|   | |||||||
| @@ -34,6 +34,7 @@ trait TopNetwork extends HasPeripheryParameters { | |||||||
|   val socBus = LazyModule(new TLXbar) |   val socBus = LazyModule(new TLXbar) | ||||||
|   val peripheryBus = LazyModule(new TLXbar) |   val peripheryBus = LazyModule(new TLXbar) | ||||||
|   val intBus = LazyModule(new IntXbar) |   val intBus = LazyModule(new IntXbar) | ||||||
|  |   val l2 = LazyModule(new TLBuffer) | ||||||
|  |  | ||||||
|   peripheryBus.node := |   peripheryBus.node := | ||||||
|     TLBuffer()( |     TLBuffer()( | ||||||
| @@ -62,13 +63,3 @@ class BaseTopBundle[+L <: BaseTop](_outer: L) extends BareTopBundle(_outer) | |||||||
|  |  | ||||||
| class BaseTopModule[+L <: BaseTop, +B <: BaseTopBundle[L]](_outer: L, _io: () => B) extends BareTopModule(_outer, _io) | class BaseTopModule[+L <: BaseTop, +B <: BaseTopBundle[L]](_outer: L, _io: () => B) extends BareTopModule(_outer, _io) | ||||||
|     with TopNetworkModule |     with TopNetworkModule | ||||||
|  |  | ||||||
| trait L2Crossbar extends TopNetwork { |  | ||||||
|   val l2 = LazyModule(new TLXbar) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| trait L2CrossbarBundle extends TopNetworkBundle { |  | ||||||
| } |  | ||||||
|  |  | ||||||
| trait L2CrossbarModule extends TopNetworkModule { |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -165,7 +165,7 @@ trait PeripheryMasterAXI4MMIOModule { | |||||||
| ///// | ///// | ||||||
|  |  | ||||||
| // PeripherySlaveAXI4 is an example, make your own cake pattern like this one. | // PeripherySlaveAXI4 is an example, make your own cake pattern like this one. | ||||||
| trait PeripherySlaveAXI4 extends L2Crossbar { | trait PeripherySlaveAXI4 extends TopNetwork { | ||||||
|   private val config = p(ExtIn) |   private val config = p(ExtIn) | ||||||
|   val l2_axi4 = AXI4BlindInputNode(Seq(AXI4MasterPortParameters( |   val l2_axi4 = AXI4BlindInputNode(Seq(AXI4MasterPortParameters( | ||||||
|     masters = Seq(AXI4MasterParameters( |     masters = Seq(AXI4MasterParameters( | ||||||
| @@ -179,12 +179,12 @@ trait PeripherySlaveAXI4 extends L2Crossbar { | |||||||
|     l2_axi4)))) |     l2_axi4)))) | ||||||
| } | } | ||||||
|  |  | ||||||
| trait PeripherySlaveAXI4Bundle extends L2CrossbarBundle { | trait PeripherySlaveAXI4Bundle extends TopNetworkBundle { | ||||||
|   val outer: PeripherySlaveAXI4 |   val outer: PeripherySlaveAXI4 | ||||||
|   val l2_axi4 = outer.l2_axi4.bundleIn |   val l2_axi4 = outer.l2_axi4.bundleIn | ||||||
| } | } | ||||||
|  |  | ||||||
| trait PeripherySlaveAXI4Module extends L2CrossbarModule { | trait PeripherySlaveAXI4Module extends TopNetworkModule { | ||||||
|   val outer: PeripherySlaveAXI4 |   val outer: PeripherySlaveAXI4 | ||||||
|   val io: PeripherySlaveAXI4Bundle |   val io: PeripherySlaveAXI4Bundle | ||||||
|   // nothing to do |   // nothing to do | ||||||
| @@ -231,7 +231,7 @@ trait PeripheryMasterTLMMIOModule { | |||||||
| ///// | ///// | ||||||
|  |  | ||||||
| // NOTE: this port is NOT allowed to issue Acquires | // NOTE: this port is NOT allowed to issue Acquires | ||||||
| trait PeripherySlaveTL extends L2Crossbar { | trait PeripherySlaveTL extends TopNetwork { | ||||||
|   private val config = p(ExtIn) |   private val config = p(ExtIn) | ||||||
|   val l2_tl = TLBlindInputNode(Seq(TLClientPortParameters( |   val l2_tl = TLBlindInputNode(Seq(TLClientPortParameters( | ||||||
|     clients = Seq(TLClientParameters( |     clients = Seq(TLClientParameters( | ||||||
| @@ -243,12 +243,12 @@ trait PeripherySlaveTL extends L2Crossbar { | |||||||
|     l2_tl)) |     l2_tl)) | ||||||
| } | } | ||||||
|  |  | ||||||
| trait PeripherySlaveTLBundle extends L2CrossbarBundle { | trait PeripherySlaveTLBundle extends TopNetworkBundle { | ||||||
|   val outer: PeripherySlaveTL |   val outer: PeripherySlaveTL | ||||||
|   val l2_tl = outer.l2_tl.bundleIn |   val l2_tl = outer.l2_tl.bundleIn | ||||||
| } | } | ||||||
|  |  | ||||||
| trait PeripherySlaveTLModule extends L2CrossbarModule { | trait PeripherySlaveTLModule extends TopNetworkModule { | ||||||
|   val outer: PeripherySlaveTL |   val outer: PeripherySlaveTL | ||||||
|   val io: PeripherySlaveTLBundle |   val io: PeripherySlaveTLBundle | ||||||
|   // nothing to do |   // nothing to do | ||||||
|   | |||||||
| @@ -10,23 +10,23 @@ import uncore.devices._ | |||||||
| import util._ | import util._ | ||||||
| import coreplex._ | import coreplex._ | ||||||
|  |  | ||||||
| trait RocketPlexMaster extends L2Crossbar { | trait RocketPlexMaster extends TopNetwork { | ||||||
|   val module: RocketPlexMasterModule |   val module: RocketPlexMasterModule | ||||||
|   val mem: Seq[TLInwardNode] |   val mem: Seq[TLInwardNode] | ||||||
|  |  | ||||||
|   val coreplex = LazyModule(new DefaultCoreplex) |   val coreplex = LazyModule(new DefaultCoreplex) | ||||||
|  |  | ||||||
|   coreplex.l2in := l2.node |   coreplex.l2in :=* l2.node | ||||||
|   socBus.node := coreplex.mmio |   socBus.node := coreplex.mmio | ||||||
|   coreplex.mmioInt := intBus.intnode |   coreplex.mmioInt := intBus.intnode | ||||||
|   mem.foreach { _ := coreplex.mem } |   mem.foreach { _ := coreplex.mem } | ||||||
| } | } | ||||||
|  |  | ||||||
| trait RocketPlexMasterBundle extends L2CrossbarBundle { | trait RocketPlexMasterBundle extends TopNetworkBundle { | ||||||
|   val outer: RocketPlexMaster |   val outer: RocketPlexMaster | ||||||
| } | } | ||||||
|  |  | ||||||
| trait RocketPlexMasterModule extends L2CrossbarModule { | trait RocketPlexMasterModule extends TopNetworkModule { | ||||||
|   val outer: RocketPlexMaster |   val outer: RocketPlexMaster | ||||||
|   val io: RocketPlexMasterBundle |   val io: RocketPlexMasterBundle | ||||||
|   val clock: Clock |   val clock: Clock | ||||||
|   | |||||||
| @@ -19,10 +19,6 @@ object AHBImp extends NodeImp[AHBMasterPortParameters, AHBSlavePortParameters, A | |||||||
|   override def labelI(ei: AHBEdgeParameters) = (ei.slave.beatBytes * 8).toString |   override def labelI(ei: AHBEdgeParameters) = (ei.slave.beatBytes * 8).toString | ||||||
|   override def labelO(eo: AHBEdgeParameters) = (eo.slave.beatBytes * 8).toString |   override def labelO(eo: AHBEdgeParameters) = (eo.slave.beatBytes * 8).toString | ||||||
|  |  | ||||||
|   def connect(bo: => AHBBundle, bi: => AHBBundle, ei: => AHBEdgeParameters)(implicit p: Parameters, sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = { |  | ||||||
|     (None, () => { bi <> bo }) |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   override def mixO(pd: AHBMasterPortParameters, node: OutwardNode[AHBMasterPortParameters, AHBSlavePortParameters, AHBBundle]): AHBMasterPortParameters  = |   override def mixO(pd: AHBMasterPortParameters, node: OutwardNode[AHBMasterPortParameters, AHBSlavePortParameters, AHBBundle]): AHBMasterPortParameters  = | ||||||
|    pd.copy(masters = pd.masters.map  { c => c.copy (nodePath = node +: c.nodePath) }) |    pd.copy(masters = pd.masters.map  { c => c.copy (nodePath = node +: c.nodePath) }) | ||||||
|   override def mixI(pu: AHBSlavePortParameters, node: InwardNode[AHBMasterPortParameters, AHBSlavePortParameters, AHBBundle]): AHBSlavePortParameters = |   override def mixI(pu: AHBSlavePortParameters, node: InwardNode[AHBMasterPortParameters, AHBSlavePortParameters, AHBBundle]): AHBSlavePortParameters = | ||||||
| @@ -31,16 +27,14 @@ object AHBImp extends NodeImp[AHBMasterPortParameters, AHBSlavePortParameters, A | |||||||
|  |  | ||||||
| // Nodes implemented inside modules | // Nodes implemented inside modules | ||||||
| case class AHBIdentityNode() extends IdentityNode(AHBImp) | case class AHBIdentityNode() extends IdentityNode(AHBImp) | ||||||
| case class AHBMasterNode(portParams: AHBMasterPortParameters, numPorts: Range.Inclusive = 1 to 1) | case class AHBMasterNode(portParams: Seq[AHBMasterPortParameters]) extends SourceNode(AHBImp)(portParams) | ||||||
|   extends SourceNode(AHBImp)(portParams, numPorts) | case class AHBSlaveNode(portParams: Seq[AHBSlavePortParameters]) extends SinkNode(AHBImp)(portParams) | ||||||
| case class AHBSlaveNode(portParams: AHBSlavePortParameters, numPorts: Range.Inclusive = 1 to 1) | case class AHBNexusNode( | ||||||
|   extends SinkNode(AHBImp)(portParams, numPorts) |  | ||||||
| case class AHBAdapterNode( |  | ||||||
|   masterFn:       Seq[AHBMasterPortParameters] => AHBMasterPortParameters, |   masterFn:       Seq[AHBMasterPortParameters] => AHBMasterPortParameters, | ||||||
|   slaveFn:        Seq[AHBSlavePortParameters]  => AHBSlavePortParameters, |   slaveFn:        Seq[AHBSlavePortParameters]  => AHBSlavePortParameters, | ||||||
|   numMasterPorts: Range.Inclusive = 1 to 1, |   numMasterPorts: Range.Inclusive = 1 to 999, | ||||||
|   numSlavePorts:  Range.Inclusive = 1 to 1) |   numSlavePorts:  Range.Inclusive = 1 to 999) | ||||||
|   extends InteriorNode(AHBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts) |   extends NexusNode(AHBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts) | ||||||
|  |  | ||||||
| // Nodes passed from an inner module | // Nodes passed from an inner module | ||||||
| case class AHBOutputNode() extends OutputNode(AHBImp) | case class AHBOutputNode() extends OutputNode(AHBImp) | ||||||
|   | |||||||
| @@ -9,13 +9,13 @@ import regmapper._ | |||||||
| import scala.math.{min,max} | import scala.math.{min,max} | ||||||
|  |  | ||||||
| class AHBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) | class AHBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) | ||||||
|   extends AHBSlaveNode(AHBSlavePortParameters( |   extends AHBSlaveNode(Seq(AHBSlavePortParameters( | ||||||
|     Seq(AHBSlaveParameters( |     Seq(AHBSlaveParameters( | ||||||
|       address       = Seq(address), |       address       = Seq(address), | ||||||
|       executable    = executable, |       executable    = executable, | ||||||
|       supportsWrite = TransferSizes(1, min(address.alignment.toInt, beatBytes * AHBParameters.maxTransfer)), |       supportsWrite = TransferSizes(1, min(address.alignment.toInt, beatBytes * AHBParameters.maxTransfer)), | ||||||
|       supportsRead  = TransferSizes(1, min(address.alignment.toInt, beatBytes * AHBParameters.maxTransfer)))), |       supportsRead  = TransferSizes(1, min(address.alignment.toInt, beatBytes * AHBParameters.maxTransfer)))), | ||||||
|     beatBytes  = beatBytes)) |     beatBytes  = beatBytes))) | ||||||
| { | { | ||||||
|   require (address.contiguous) |   require (address.contiguous) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,14 +8,14 @@ import diplomacy._ | |||||||
|  |  | ||||||
| class AHBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule | class AHBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule | ||||||
| { | { | ||||||
|   val node = AHBSlaveNode(AHBSlavePortParameters( |   val node = AHBSlaveNode(Seq(AHBSlavePortParameters( | ||||||
|     Seq(AHBSlaveParameters( |     Seq(AHBSlaveParameters( | ||||||
|       address       = List(address), |       address       = List(address), | ||||||
|       regionType    = RegionType.UNCACHED, |       regionType    = RegionType.UNCACHED, | ||||||
|       executable    = executable, |       executable    = executable, | ||||||
|       supportsRead  = TransferSizes(1, beatBytes * AHBParameters.maxTransfer), |       supportsRead  = TransferSizes(1, beatBytes * AHBParameters.maxTransfer), | ||||||
|       supportsWrite = TransferSizes(1, beatBytes * AHBParameters.maxTransfer))), |       supportsWrite = TransferSizes(1, beatBytes * AHBParameters.maxTransfer))), | ||||||
|     beatBytes  = beatBytes)) |     beatBytes  = beatBytes))) | ||||||
|  |  | ||||||
|   // We require the address range to include an entire beat (for the write mask) |   // We require the address range to include an entire beat (for the write mask) | ||||||
|   require ((address.mask & (beatBytes-1)) == beatBytes-1) |   require ((address.mask & (beatBytes-1)) == beatBytes-1) | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ import regmapper._ | |||||||
| import scala.math.{min,max} | import scala.math.{min,max} | ||||||
|  |  | ||||||
| class AHBFanout()(implicit p: Parameters) extends LazyModule { | class AHBFanout()(implicit p: Parameters) extends LazyModule { | ||||||
|   val node = AHBAdapterNode( |   val node = AHBNexusNode( | ||||||
|     numSlavePorts  = 1 to 1, |     numSlavePorts  = 1 to 1, | ||||||
|     numMasterPorts = 1 to 32, |     numMasterPorts = 1 to 32, | ||||||
|     masterFn = { case Seq(m) => m }, |     masterFn = { case Seq(m) => m }, | ||||||
|   | |||||||
| @@ -19,10 +19,6 @@ object APBImp extends NodeImp[APBMasterPortParameters, APBSlavePortParameters, A | |||||||
|   override def labelI(ei: APBEdgeParameters) = (ei.slave.beatBytes * 8).toString |   override def labelI(ei: APBEdgeParameters) = (ei.slave.beatBytes * 8).toString | ||||||
|   override def labelO(eo: APBEdgeParameters) = (eo.slave.beatBytes * 8).toString |   override def labelO(eo: APBEdgeParameters) = (eo.slave.beatBytes * 8).toString | ||||||
|  |  | ||||||
|   def connect(bo: => APBBundle, bi: => APBBundle, ei: => APBEdgeParameters)(implicit p: Parameters, sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = { |  | ||||||
|     (None, () => { bi <> bo }) |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   override def mixO(pd: APBMasterPortParameters, node: OutwardNode[APBMasterPortParameters, APBSlavePortParameters, APBBundle]): APBMasterPortParameters  = |   override def mixO(pd: APBMasterPortParameters, node: OutwardNode[APBMasterPortParameters, APBSlavePortParameters, APBBundle]): APBMasterPortParameters  = | ||||||
|    pd.copy(masters = pd.masters.map  { c => c.copy (nodePath = node +: c.nodePath) }) |    pd.copy(masters = pd.masters.map  { c => c.copy (nodePath = node +: c.nodePath) }) | ||||||
|   override def mixI(pu: APBSlavePortParameters, node: InwardNode[APBMasterPortParameters, APBSlavePortParameters, APBBundle]): APBSlavePortParameters = |   override def mixI(pu: APBSlavePortParameters, node: InwardNode[APBMasterPortParameters, APBSlavePortParameters, APBBundle]): APBSlavePortParameters = | ||||||
| @@ -31,16 +27,14 @@ object APBImp extends NodeImp[APBMasterPortParameters, APBSlavePortParameters, A | |||||||
|  |  | ||||||
| // Nodes implemented inside modules | // Nodes implemented inside modules | ||||||
| case class APBIdentityNode() extends IdentityNode(APBImp) | case class APBIdentityNode() extends IdentityNode(APBImp) | ||||||
| case class APBMasterNode(portParams: APBMasterPortParameters, numPorts: Range.Inclusive = 1 to 1) | case class APBMasterNode(portParams: Seq[APBMasterPortParameters]) extends SourceNode(APBImp)(portParams) | ||||||
|   extends SourceNode(APBImp)(portParams, numPorts) | case class APBSlaveNode(portParams: Seq[APBSlavePortParameters]) extends SinkNode(APBImp)(portParams) | ||||||
| case class APBSlaveNode(portParams: APBSlavePortParameters, numPorts: Range.Inclusive = 1 to 1) | case class APBNexusNode( | ||||||
|   extends SinkNode(APBImp)(portParams, numPorts) |  | ||||||
| case class APBAdapterNode( |  | ||||||
|   masterFn:       Seq[APBMasterPortParameters] => APBMasterPortParameters, |   masterFn:       Seq[APBMasterPortParameters] => APBMasterPortParameters, | ||||||
|   slaveFn:        Seq[APBSlavePortParameters]  => APBSlavePortParameters, |   slaveFn:        Seq[APBSlavePortParameters]  => APBSlavePortParameters, | ||||||
|   numMasterPorts: Range.Inclusive = 1 to 1, |   numMasterPorts: Range.Inclusive = 1 to 1, | ||||||
|   numSlavePorts:  Range.Inclusive = 1 to 1) |   numSlavePorts:  Range.Inclusive = 1 to 1) | ||||||
|   extends InteriorNode(APBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts) |   extends NexusNode(APBImp)(masterFn, slaveFn, numMasterPorts, numSlavePorts) | ||||||
|  |  | ||||||
| // Nodes passed from an inner module | // Nodes passed from an inner module | ||||||
| case class APBOutputNode() extends OutputNode(APBImp) | case class APBOutputNode() extends OutputNode(APBImp) | ||||||
|   | |||||||
| @@ -9,13 +9,13 @@ import regmapper._ | |||||||
| import scala.math.{min,max} | import scala.math.{min,max} | ||||||
|  |  | ||||||
| class APBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) | class APBRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) | ||||||
|   extends APBSlaveNode(APBSlavePortParameters( |   extends APBSlaveNode(Seq(APBSlavePortParameters( | ||||||
|     Seq(APBSlaveParameters( |     Seq(APBSlaveParameters( | ||||||
|       address       = Seq(address), |       address       = Seq(address), | ||||||
|       executable    = executable, |       executable    = executable, | ||||||
|       supportsWrite = true, |       supportsWrite = true, | ||||||
|       supportsRead  = true)), |       supportsRead  = true)), | ||||||
|     beatBytes  = beatBytes)) |     beatBytes  = beatBytes))) | ||||||
| { | { | ||||||
|   require (address.contiguous) |   require (address.contiguous) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,14 +8,14 @@ import diplomacy._ | |||||||
|  |  | ||||||
| class APBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule | class APBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule | ||||||
| { | { | ||||||
|   val node = APBSlaveNode(APBSlavePortParameters( |   val node = APBSlaveNode(Seq(APBSlavePortParameters( | ||||||
|     Seq(APBSlaveParameters( |     Seq(APBSlaveParameters( | ||||||
|       address       = List(address), |       address       = List(address), | ||||||
|       regionType    = RegionType.UNCACHED, |       regionType    = RegionType.UNCACHED, | ||||||
|       executable    = executable, |       executable    = executable, | ||||||
|       supportsRead  = true, |       supportsRead  = true, | ||||||
|       supportsWrite = true)), |       supportsWrite = true)), | ||||||
|     beatBytes  = beatBytes)) |     beatBytes  = beatBytes))) | ||||||
|  |  | ||||||
|   // We require the address range to include an entire beat (for the write mask) |   // We require the address range to include an entire beat (for the write mask) | ||||||
|   require ((address.mask & (beatBytes-1)) == beatBytes-1) |   require ((address.mask & (beatBytes-1)) == beatBytes-1) | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ import regmapper._ | |||||||
| import scala.math.{min,max} | import scala.math.{min,max} | ||||||
|  |  | ||||||
| class APBFanout()(implicit p: Parameters) extends LazyModule { | class APBFanout()(implicit p: Parameters) extends LazyModule { | ||||||
|   val node = APBAdapterNode( |   val node = APBNexusNode( | ||||||
|     numSlavePorts  = 1 to 1, |     numSlavePorts  = 1 to 1, | ||||||
|     numMasterPorts = 1 to 32, |     numMasterPorts = 1 to 32, | ||||||
|     masterFn = { case Seq(m) => m }, |     masterFn = { case Seq(m) => m }, | ||||||
|   | |||||||
| @@ -18,8 +18,8 @@ class AXI4Buffer(aw: Int = 2, w: Int = 2, b: Int = 2, ar: Int = 2, r: Int = 2, p | |||||||
|   require (r  >= 0) |   require (r  >= 0) | ||||||
|  |  | ||||||
|   val node = AXI4AdapterNode( |   val node = AXI4AdapterNode( | ||||||
|     masterFn = { case Seq(p) => p }, |     masterFn = { p => p }, | ||||||
|     slaveFn  = { case Seq(p) => p.copy(minLatency = p.minLatency + min(1,min(aw,ar)) + min(1,min(r,b))) }) |     slaveFn  = { p => p.copy(minLatency = p.minLatency + min(1,min(aw,ar)) + min(1,min(r,b))) }) | ||||||
|  |  | ||||||
|   lazy val module = new LazyModuleImp(this) { |   lazy val module = new LazyModuleImp(this) { | ||||||
|     val io = new Bundle { |     val io = new Bundle { | ||||||
|   | |||||||
| @@ -23,8 +23,8 @@ class AXI4Fragmenter(lite: Boolean = false, maxInFlight: => Int = 32, combinatio | |||||||
|   def mapMaster(m: AXI4MasterParameters) = m.copy(aligned = true) |   def mapMaster(m: AXI4MasterParameters) = m.copy(aligned = true) | ||||||
|  |  | ||||||
|   val node = AXI4AdapterNode( |   val node = AXI4AdapterNode( | ||||||
|     masterFn = { case Seq(mp) => mp.copy(masters = mp.masters.map(m => mapMaster(m))) }, |     masterFn = { mp => mp.copy(masters = mp.masters.map(m => mapMaster(m))) }, | ||||||
|     slaveFn  = { case Seq(sp) => sp.copy(slaves  = sp.slaves .map(s => mapSlave(s, sp.beatBytes))) }) |     slaveFn  = { sp => sp.copy(slaves  = sp.slaves .map(s => mapSlave(s, sp.beatBytes))) }) | ||||||
|  |  | ||||||
|   lazy val module = new LazyModuleImp(this) { |   lazy val module = new LazyModuleImp(this) { | ||||||
|     val io = new Bundle { |     val io = new Bundle { | ||||||
| @@ -32,8 +32,7 @@ class AXI4Fragmenter(lite: Boolean = false, maxInFlight: => Int = 32, combinatio | |||||||
|       val out = node.bundleOut |       val out = node.bundleOut | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     val edgeOut   = node.edgesOut(0) |     ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => | ||||||
|     val edgeIn    = node.edgesIn(0) |  | ||||||
|       val slave     = edgeOut.slave |       val slave     = edgeOut.slave | ||||||
|       val slaves    = slave.slaves |       val slaves    = slave.slaves | ||||||
|       val beatBytes = slave.beatBytes |       val beatBytes = slave.beatBytes | ||||||
| @@ -136,9 +135,6 @@ class AXI4Fragmenter(lite: Boolean = false, maxInFlight: => Int = 32, combinatio | |||||||
|         (out, last, beats) |         (out, last, beats) | ||||||
|       } |       } | ||||||
|  |  | ||||||
|     val in = io.in(0) |  | ||||||
|     val out = io.out(0) |  | ||||||
|  |  | ||||||
|       // The size to which we will fragment the access |       // The size to which we will fragment the access | ||||||
|       val readSizes1  = slaves.map(s => s.supportsRead .max/beatBytes-1) |       val readSizes1  = slaves.map(s => s.supportsRead .max/beatBytes-1) | ||||||
|       val writeSizes1 = slaves.map(s => s.supportsWrite.max/beatBytes-1) |       val writeSizes1 = slaves.map(s => s.supportsWrite.max/beatBytes-1) | ||||||
| @@ -284,6 +280,7 @@ class AXI4FragmenterSideband(maxInFlight: Int, flow: Boolean = false) extends Mo | |||||||
|       is(WAIT) { when (last && io.deq.ready)                  { state := PASS } } |       is(WAIT) { when (last && io.deq.ready)                  { state := PASS } } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| object AXI4Fragmenter | object AXI4Fragmenter | ||||||
| { | { | ||||||
|   | |||||||
| @@ -19,10 +19,6 @@ object AXI4Imp extends NodeImp[AXI4MasterPortParameters, AXI4SlavePortParameters | |||||||
|   override def labelI(ei: AXI4EdgeParameters) = (ei.slave.beatBytes * 8).toString |   override def labelI(ei: AXI4EdgeParameters) = (ei.slave.beatBytes * 8).toString | ||||||
|   override def labelO(eo: AXI4EdgeParameters) = (eo.slave.beatBytes * 8).toString |   override def labelO(eo: AXI4EdgeParameters) = (eo.slave.beatBytes * 8).toString | ||||||
|  |  | ||||||
|   def connect(bo: => AXI4Bundle, bi: => AXI4Bundle, ei: => AXI4EdgeParameters)(implicit p: Parameters, sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = { |  | ||||||
|     (None, () => { bi <> bo }) |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   override def mixO(pd: AXI4MasterPortParameters, node: OutwardNode[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4Bundle]): AXI4MasterPortParameters  = |   override def mixO(pd: AXI4MasterPortParameters, node: OutwardNode[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4Bundle]): AXI4MasterPortParameters  = | ||||||
|    pd.copy(masters = pd.masters.map  { c => c.copy (nodePath = node +: c.nodePath) }) |    pd.copy(masters = pd.masters.map  { c => c.copy (nodePath = node +: c.nodePath) }) | ||||||
|   override def mixI(pu: AXI4SlavePortParameters, node: InwardNode[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4Bundle]): AXI4SlavePortParameters = |   override def mixI(pu: AXI4SlavePortParameters, node: InwardNode[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4Bundle]): AXI4SlavePortParameters = | ||||||
| @@ -31,16 +27,13 @@ object AXI4Imp extends NodeImp[AXI4MasterPortParameters, AXI4SlavePortParameters | |||||||
|  |  | ||||||
| // Nodes implemented inside modules | // Nodes implemented inside modules | ||||||
| case class AXI4IdentityNode() extends IdentityNode(AXI4Imp) | case class AXI4IdentityNode() extends IdentityNode(AXI4Imp) | ||||||
| case class AXI4MasterNode(portParams: AXI4MasterPortParameters, numPorts: Range.Inclusive = 1 to 1) | case class AXI4MasterNode(portParams: Seq[AXI4MasterPortParameters]) extends SourceNode(AXI4Imp)(portParams) | ||||||
|   extends SourceNode(AXI4Imp)(portParams, numPorts) | case class AXI4SlaveNode(portParams: Seq[AXI4SlavePortParameters]) extends SinkNode(AXI4Imp)(portParams) | ||||||
| case class AXI4SlaveNode(portParams: AXI4SlavePortParameters, numPorts: Range.Inclusive = 1 to 1) |  | ||||||
|   extends SinkNode(AXI4Imp)(portParams, numPorts) |  | ||||||
| case class AXI4AdapterNode( | case class AXI4AdapterNode( | ||||||
|   masterFn:       Seq[AXI4MasterPortParameters]  => AXI4MasterPortParameters, |   masterFn:  AXI4MasterPortParameters => AXI4MasterPortParameters, | ||||||
|   slaveFn:        Seq[AXI4SlavePortParameters] => AXI4SlavePortParameters, |   slaveFn:   AXI4SlavePortParameters  => AXI4SlavePortParameters, | ||||||
|   numMasterPorts: Range.Inclusive = 1 to 1, |   numPorts:  Range.Inclusive = 0 to 999) | ||||||
|   numSlavePorts:  Range.Inclusive = 1 to 1) |   extends AdapterNode(AXI4Imp)(masterFn, slaveFn, numPorts) | ||||||
|   extends InteriorNode(AXI4Imp)(masterFn, slaveFn, numMasterPorts, numSlavePorts) |  | ||||||
|  |  | ||||||
| // Nodes passed from an inner module | // Nodes passed from an inner module | ||||||
| case class AXI4OutputNode() extends OutputNode(AXI4Imp) | case class AXI4OutputNode() extends OutputNode(AXI4Imp) | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ import regmapper._ | |||||||
| import scala.math.{min,max} | import scala.math.{min,max} | ||||||
|  |  | ||||||
| class AXI4RegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) | class AXI4RegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) | ||||||
|   extends AXI4SlaveNode(AXI4SlavePortParameters( |   extends AXI4SlaveNode(Seq(AXI4SlavePortParameters( | ||||||
|     Seq(AXI4SlaveParameters( |     Seq(AXI4SlaveParameters( | ||||||
|       address       = Seq(address), |       address       = Seq(address), | ||||||
|       executable    = executable, |       executable    = executable, | ||||||
| @@ -17,7 +17,7 @@ class AXI4RegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int | |||||||
|       supportsRead  = TransferSizes(1, beatBytes), |       supportsRead  = TransferSizes(1, beatBytes), | ||||||
|       interleavedId = Some(0))), |       interleavedId = Some(0))), | ||||||
|     beatBytes  = beatBytes, |     beatBytes  = beatBytes, | ||||||
|     minLatency = min(concurrency, 1))) // the Queue adds at most one cycle |     minLatency = min(concurrency, 1)))) // the Queue adds at most one cycle | ||||||
| { | { | ||||||
|   require (address.contiguous) |   require (address.contiguous) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ import diplomacy._ | |||||||
|  |  | ||||||
| class AXI4RAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule | class AXI4RAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule | ||||||
| { | { | ||||||
|   val node = AXI4SlaveNode(AXI4SlavePortParameters( |   val node = AXI4SlaveNode(Seq(AXI4SlavePortParameters( | ||||||
|     Seq(AXI4SlaveParameters( |     Seq(AXI4SlaveParameters( | ||||||
|       address       = List(address), |       address       = List(address), | ||||||
|       regionType    = RegionType.UNCACHED, |       regionType    = RegionType.UNCACHED, | ||||||
| @@ -17,7 +17,7 @@ class AXI4RAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = | |||||||
|       supportsWrite = TransferSizes(1, beatBytes), |       supportsWrite = TransferSizes(1, beatBytes), | ||||||
|       interleavedId = Some(0))), |       interleavedId = Some(0))), | ||||||
|     beatBytes  = beatBytes, |     beatBytes  = beatBytes, | ||||||
|     minLatency = 0)) // B responds on same cycle |     minLatency = 0))) // B responds on same cycle | ||||||
|  |  | ||||||
|   // We require the address range to include an entire beat (for the write mask) |   // We require the address range to include an entire beat (for the write mask) | ||||||
|   require ((address.mask & (beatBytes-1)) == beatBytes-1) |   require ((address.mask & (beatBytes-1)) == beatBytes-1) | ||||||
|   | |||||||
| @@ -8,15 +8,15 @@ import config._ | |||||||
| import diplomacy._ | import diplomacy._ | ||||||
| import uncore.tilelink2._ | import uncore.tilelink2._ | ||||||
|  |  | ||||||
| case class AXI4ToTLNode() extends MixedNode(AXI4Imp, TLImp)( | case class AXI4ToTLNode() extends MixedAdapterNode(AXI4Imp, TLImp)( | ||||||
|   dFn = { case (1, Seq(AXI4MasterPortParameters(masters))) => |   dFn = { case AXI4MasterPortParameters(masters) => | ||||||
|     Seq(TLClientPortParameters(clients = masters.map { m => |     TLClientPortParameters(clients = masters.map { m => | ||||||
|       TLClientParameters( |       TLClientParameters( | ||||||
|         sourceId = IdRange(m.id.start << 1, m.id.end << 1), // R+W ids are distinct |         sourceId = IdRange(m.id.start << 1, m.id.end << 1), // R+W ids are distinct | ||||||
|         nodePath = m.nodePath) |         nodePath = m.nodePath) | ||||||
|     })) |     }) | ||||||
|   }, |   }, | ||||||
|   uFn = { case (1, Seq(mp)) => Seq(AXI4SlavePortParameters( |   uFn = { mp => AXI4SlavePortParameters( | ||||||
|     slaves = mp.managers.map { m => |     slaves = mp.managers.map { m => | ||||||
|       AXI4SlaveParameters( |       AXI4SlaveParameters( | ||||||
|         address       = m.address, |         address       = m.address, | ||||||
| @@ -27,10 +27,8 @@ case class AXI4ToTLNode() extends MixedNode(AXI4Imp, TLImp)( | |||||||
|         supportsRead  = m.supportsGet, |         supportsRead  = m.supportsGet, | ||||||
|         interleavedId = Some(0))}, // TL2 never interleaves D beats |         interleavedId = Some(0))}, // TL2 never interleaves D beats | ||||||
|     beatBytes = mp.beatBytes, |     beatBytes = mp.beatBytes, | ||||||
|     minLatency = mp.minLatency)) |     minLatency = mp.minLatency) | ||||||
|   }, |   }) | ||||||
|   numPO = 1 to 1, |  | ||||||
|   numPI = 1 to 1) |  | ||||||
|  |  | ||||||
| class AXI4ToTL()(implicit p: Parameters) extends LazyModule | class AXI4ToTL()(implicit p: Parameters) extends LazyModule | ||||||
| { | { | ||||||
| @@ -42,10 +40,7 @@ class AXI4ToTL()(implicit p: Parameters) extends LazyModule | |||||||
|       val out = node.bundleOut |       val out = node.bundleOut | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     val in = io.in(0) |     ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => | ||||||
|     val out = io.out(0) |  | ||||||
|     val edgeIn = node.edgesIn(0) |  | ||||||
|     val edgeOut = node.edgesOut(0) |  | ||||||
|       val numIds = edgeIn.master.endId |       val numIds = edgeIn.master.endId | ||||||
|       val beatBytes = edgeOut.manager.beatBytes |       val beatBytes = edgeOut.manager.beatBytes | ||||||
|       val countBits = AXI4Parameters.lenBits + (1 << AXI4Parameters.sizeBits) - 1 |       val countBits = AXI4Parameters.lenBits + (1 << AXI4Parameters.sizeBits) - 1 | ||||||
| @@ -169,6 +164,7 @@ class AXI4ToTL()(implicit p: Parameters) extends LazyModule | |||||||
|       out.e.valid := Bool(false) |       out.e.valid := Bool(false) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| class AXI4BundleRError(params: AXI4BundleParameters) extends AXI4BundleBase(params) | class AXI4BundleRError(params: AXI4BundleParameters) extends AXI4BundleBase(params) | ||||||
| { | { | ||||||
|   | |||||||
| @@ -62,7 +62,7 @@ class TLPLIC(supervisor: Boolean, maxPriorities: Int, address: BigInt = 0xC00000 | |||||||
|     beatBytes = p(rocket.XLen)/8, |     beatBytes = p(rocket.XLen)/8, | ||||||
|     undefZero = false) |     undefZero = false) | ||||||
|  |  | ||||||
|   val intnode = IntAdapterNode( |   val intnode = IntNexusNode( | ||||||
|     numSourcePorts = 0 to 1024, |     numSourcePorts = 0 to 1024, | ||||||
|     numSinkPorts   = 0 to 1024, |     numSinkPorts   = 0 to 1024, | ||||||
|     sourceFn       = { _ => IntSourcePortParameters(Seq(IntSourceParameters(contextsPerHart))) }, |     sourceFn       = { _ => IntSourcePortParameters(Seq(IntSourceParameters(contextsPerHart))) }, | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ import Chisel._ | |||||||
| import chisel3.internal.sourceinfo.SourceInfo | import chisel3.internal.sourceinfo.SourceInfo | ||||||
| import config._ | import config._ | ||||||
| import diplomacy._ | import diplomacy._ | ||||||
|  | import util.GenericParameterizedBundle | ||||||
| import scala.math.{min,max} | import scala.math.{min,max} | ||||||
|  |  | ||||||
| // Ensures that all downstream RW managers support Atomic operationss. | // Ensures that all downstream RW managers support Atomic operationss. | ||||||
| @@ -15,8 +16,8 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc | |||||||
|   require (concurrency >= 1) |   require (concurrency >= 1) | ||||||
|  |  | ||||||
|   val node = TLAdapterNode( |   val node = TLAdapterNode( | ||||||
|     clientFn  = { case Seq(cp) => require (!cp.unsafeAtomics); cp.copy(unsafeAtomics = true) }, |     clientFn  = { case cp => require (!cp.unsafeAtomics); cp.copy(unsafeAtomics = true) }, | ||||||
|     managerFn = { case Seq(mp) => mp.copy(managers = mp.managers.map { m => |     managerFn = { case mp => mp.copy(managers = mp.managers.map { m => | ||||||
|       val ourSupport = TransferSizes(1, mp.beatBytes) |       val ourSupport = TransferSizes(1, mp.beatBytes) | ||||||
|       def widen(x: TransferSizes) = if (passthrough && x.min <= 2*mp.beatBytes) TransferSizes(1, max(mp.beatBytes, x.max)) else ourSupport |       def widen(x: TransferSizes) = if (passthrough && x.min <= 2*mp.beatBytes) TransferSizes(1, max(mp.beatBytes, x.max)) else ourSupport | ||||||
|       val canDoit = m.supportsPutFull.contains(ourSupport) && m.supportsGet.contains(ourSupport) |       val canDoit = m.supportsPutFull.contains(ourSupport) && m.supportsGet.contains(ourSupport) | ||||||
| @@ -33,10 +34,7 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc | |||||||
|       val out = node.bundleOut |       val out = node.bundleOut | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     val in  = io.in(0) |     ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => | ||||||
|     val out = io.out(0) |  | ||||||
|     val edgeIn  = node.edgesIn(0) |  | ||||||
|     val edgeOut = node.edgesOut(0) |  | ||||||
|       val managers = edgeOut.manager.managers |       val managers = edgeOut.manager.managers | ||||||
|       val beatBytes = edgeOut.manager.beatBytes |       val beatBytes = edgeOut.manager.beatBytes | ||||||
|  |  | ||||||
| @@ -72,25 +70,14 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc | |||||||
|         if (x.map(_ == x(0)).reduce(_ && _)) x(0).containsLg(lgSize) else |         if (x.map(_ == x(0)).reduce(_ && _)) x(0).containsLg(lgSize) else | ||||||
|         Mux1H(select, x.map(_.containsLg(lgSize)))  |         Mux1H(select, x.map(_.containsLg(lgSize)))  | ||||||
|  |  | ||||||
|  |       val params = TLAtomicAutomata.CAMParams(out.a.bits.params, domainsNeedingHelp.size) | ||||||
|       // Do we need to do anything at all? |       // Do we need to do anything at all? | ||||||
|       if (camSize > 0) { |       if (camSize > 0) { | ||||||
|       class CAM_S extends Bundle { |         val initval = Wire(new TLAtomicAutomata.CAM_S(params)) | ||||||
|         val state = UInt(width = 2) |  | ||||||
|       } |  | ||||||
|       class CAM_A extends Bundle { |  | ||||||
|         val bits    = new TLBundleA(out.a.bits.params) |  | ||||||
|         val fifoId  = UInt(width = log2Up(domainsNeedingHelp.size)) |  | ||||||
|         val lut     = UInt(width = 4) |  | ||||||
|       } |  | ||||||
|       class CAM_D extends Bundle { |  | ||||||
|         val data = UInt(width = out.a.bits.params.dataBits) |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       val initval = Wire(new CAM_S) |  | ||||||
|         initval.state := FREE |         initval.state := FREE | ||||||
|         val cam_s = RegInit(Vec.fill(camSize)(initval)) |         val cam_s = RegInit(Vec.fill(camSize)(initval)) | ||||||
|       val cam_a = Reg(Vec(camSize, new CAM_A)) |         val cam_a = Reg(Vec(camSize, new TLAtomicAutomata.CAM_A(params))) | ||||||
|       val cam_d = Reg(Vec(camSize, new CAM_D)) |         val cam_d = Reg(Vec(camSize, new TLAtomicAutomata.CAM_D(params))) | ||||||
|  |  | ||||||
|         val cam_free   = cam_s.map(_.state === FREE) |         val cam_free   = cam_s.map(_.state === FREE) | ||||||
|         val cam_amo    = cam_s.map(_.state === AMO) |         val cam_amo    = cam_s.map(_.state === AMO) | ||||||
| @@ -275,6 +262,7 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| object TLAtomicAutomata | object TLAtomicAutomata | ||||||
| { | { | ||||||
| @@ -284,6 +272,20 @@ object TLAtomicAutomata | |||||||
|     atomics.node := x |     atomics.node := x | ||||||
|     atomics.node |     atomics.node | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   case class CAMParams(a: TLBundleParameters, domainsNeedingHelp: Int) | ||||||
|  |  | ||||||
|  |   class CAM_S(params: CAMParams) extends GenericParameterizedBundle(params) { | ||||||
|  |     val state = UInt(width = 2) | ||||||
|  |   } | ||||||
|  |   class CAM_A(params: CAMParams) extends GenericParameterizedBundle(params) { | ||||||
|  |     val bits    = new TLBundleA(params.a) | ||||||
|  |     val fifoId  = UInt(width = log2Up(params.domainsNeedingHelp)) | ||||||
|  |     val lut     = UInt(width = 4) | ||||||
|  |   } | ||||||
|  |   class CAM_D(params: CAMParams) extends GenericParameterizedBundle(params) { | ||||||
|  |     val data = UInt(width = params.a.dataBits) | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| /** Synthesizeable unit tests */ | /** Synthesizeable unit tests */ | ||||||
|   | |||||||
| @@ -13,11 +13,11 @@ class TLBroadcast(lineBytes: Int, numTrackers: Int = 4, bufferless: Boolean = fa | |||||||
|   require (numTrackers > 0) |   require (numTrackers > 0) | ||||||
|  |  | ||||||
|   val node = TLAdapterNode( |   val node = TLAdapterNode( | ||||||
|     clientFn  = { case Seq(cp) => |     clientFn  = { cp => | ||||||
|       cp.copy(clients = Seq(TLClientParameters( |       cp.copy(clients = Seq(TLClientParameters( | ||||||
|         sourceId = IdRange(0, 1 << log2Ceil(cp.endSourceId*4))))) |         sourceId = IdRange(0, 1 << log2Ceil(cp.endSourceId*4))))) | ||||||
|     }, |     }, | ||||||
|     managerFn = { case Seq(mp) => |     managerFn = { mp => | ||||||
|       mp.copy( |       mp.copy( | ||||||
|         endSinkId  = numTrackers, |         endSinkId  = numTrackers, | ||||||
|         managers   = mp.managers.map { m => |         managers   = mp.managers.map { m => | ||||||
| @@ -56,10 +56,7 @@ class TLBroadcast(lineBytes: Int, numTrackers: Int = 4, bufferless: Boolean = fa | |||||||
|       val out = node.bundleOut |       val out = node.bundleOut | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     val in = io.in(0) |     ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => | ||||||
|     val out = io.out(0) |  | ||||||
|     val edgeIn = node.edgesIn(0) |  | ||||||
|     val edgeOut = node.edgesOut(0) |  | ||||||
|       val clients = edgeIn.client.clients |       val clients = edgeIn.client.clients | ||||||
|       val managers = edgeOut.manager.managers |       val managers = edgeOut.manager.managers | ||||||
|       val lineShift = log2Ceil(lineBytes) |       val lineShift = log2Ceil(lineBytes) | ||||||
| @@ -206,6 +203,7 @@ class TLBroadcast(lineBytes: Int, numTrackers: Int = 4, bufferless: Boolean = fa | |||||||
|       out.e.valid := Bool(false) |       out.e.valid := Bool(false) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| class TLBroadcastTracker(id: Int, lineBytes: Int, probeCountBits: Int, bufferless: Boolean, edgeIn: TLEdgeIn, edgeOut: TLEdgeOut) extends Module | class TLBroadcastTracker(id: Int, lineBytes: Int, probeCountBits: Int, bufferless: Boolean, edgeIn: TLEdgeIn, edgeOut: TLEdgeOut) extends Module | ||||||
| { | { | ||||||
|   | |||||||
| @@ -18,8 +18,8 @@ class TLBuffer(a: Int = 2, b: Int = 2, c: Int = 2, d: Int = 2, e: Int = 2, pipe: | |||||||
|   require (e >= 0) |   require (e >= 0) | ||||||
|  |  | ||||||
|   val node = TLAdapterNode( |   val node = TLAdapterNode( | ||||||
|     clientFn  = { case Seq(p) => p.copy(minLatency = p.minLatency + min(1,b) + min(1,c)) }, |     clientFn  = { p => p.copy(minLatency = p.minLatency + min(1,b) + min(1,c)) }, | ||||||
|     managerFn = { case Seq(p) => p.copy(minLatency = p.minLatency + min(1,a) + min(1,d)) }) |     managerFn = { p => p.copy(minLatency = p.minLatency + min(1,a) + min(1,d)) }) | ||||||
|  |  | ||||||
|   lazy val module = new LazyModuleImp(this) { |   lazy val module = new LazyModuleImp(this) { | ||||||
|     val io = new Bundle { |     val io = new Bundle { | ||||||
|   | |||||||
| @@ -210,11 +210,11 @@ final class DecoupledSnoop[+T <: Data](gen: T) extends Bundle | |||||||
|  |  | ||||||
| object DecoupledSnoop | object DecoupledSnoop | ||||||
| { | { | ||||||
|   def apply[T <: Data](i: DecoupledIO[T]) = { |   def apply[T <: Data](source: DecoupledIO[T], sink: DecoupledIO[T]) = { | ||||||
|     val out = Wire(new DecoupledSnoop(i.bits)) |     val out = Wire(new DecoupledSnoop(sink.bits)) | ||||||
|     out.ready := i.ready |     out.ready := sink.ready | ||||||
|     out.valid := i.valid |     out.valid := source.valid | ||||||
|     out.bits  := i.bits |     out.bits  := source.bits | ||||||
|     out |     out | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @@ -230,13 +230,13 @@ class TLBundleSnoop(params: TLBundleParameters) extends TLBundleBase(params) | |||||||
|  |  | ||||||
| object TLBundleSnoop | object TLBundleSnoop | ||||||
| { | { | ||||||
|   def apply(x: TLBundle) = { |   def apply(source: TLBundle, sink: TLBundle) = { | ||||||
|     val out = Wire(new TLBundleSnoop(x.params)) |     val out = Wire(new TLBundleSnoop(sink.params)) | ||||||
|     out.a <> DecoupledSnoop(x.a) |     out.a := DecoupledSnoop(source.a, sink.a) | ||||||
|     out.b <> DecoupledSnoop(x.b) |     out.b := DecoupledSnoop(sink.b, source.b) | ||||||
|     out.c <> DecoupledSnoop(x.c) |     out.c := DecoupledSnoop(source.c, sink.c) | ||||||
|     out.d <> DecoupledSnoop(x.d) |     out.d := DecoupledSnoop(sink.d, source.d) | ||||||
|     out.e <> DecoupledSnoop(x.e) |     out.e := DecoupledSnoop(source.e, sink.e) | ||||||
|     out |     out | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -12,10 +12,10 @@ import TLMessages._ | |||||||
| class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyModule | class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyModule | ||||||
| { | { | ||||||
|   val node = TLAdapterNode( |   val node = TLAdapterNode( | ||||||
|     clientFn  = { case Seq(cp) => |     clientFn  = { case cp => | ||||||
|       cp.copy(clients = cp.clients.map { c => c.copy( |       cp.copy(clients = cp.clients.map { c => c.copy( | ||||||
|         sourceId = IdRange(c.sourceId.start*2, c.sourceId.end*2))})}, |         sourceId = IdRange(c.sourceId.start*2, c.sourceId.end*2))})}, | ||||||
|     managerFn = { case Seq(mp) => |     managerFn = { case mp => | ||||||
|       mp.copy(managers = mp.managers.map { m => m.copy( |       mp.copy(managers = mp.managers.map { m => m.copy( | ||||||
|         regionType         = if (m.regionType == RegionType.UNCACHED) RegionType.TRACKED else m.regionType, |         regionType         = if (m.regionType == RegionType.UNCACHED) RegionType.TRACKED else m.regionType, | ||||||
|         supportsAcquireB   = m.supportsGet, |         supportsAcquireB   = m.supportsGet, | ||||||
| @@ -27,18 +27,13 @@ class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyM | |||||||
|       val out = node.bundleOut |       val out = node.bundleOut | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     val edgeIn = node.edgesIn(0) |     ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => | ||||||
|     val edgeOut = node.edgesOut(0) |  | ||||||
|  |  | ||||||
|       require (edgeIn.client.clients.size == 1 || unsafe, "Only one client can safely use a TLCacheCork") |       require (edgeIn.client.clients.size == 1 || unsafe, "Only one client can safely use a TLCacheCork") | ||||||
|       require (edgeIn.client.clients.filter(_.supportsProbe).size == 1, "Only one caching client allowed") |       require (edgeIn.client.clients.filter(_.supportsProbe).size == 1, "Only one caching client allowed") | ||||||
|       edgeOut.manager.managers.foreach { case m => |       edgeOut.manager.managers.foreach { case m => | ||||||
|         require (!m.supportsAcquireB, "Cannot support caches beyond the Cork") |         require (!m.supportsAcquireB, "Cannot support caches beyond the Cork") | ||||||
|       } |       } | ||||||
|  |  | ||||||
|     val out = io.out(0) |  | ||||||
|     val in = io.in(0) |  | ||||||
|  |  | ||||||
|       // The Cork turns [Acquire=>Get] => [AccessAckData=>GrantData] |       // The Cork turns [Acquire=>Get] => [AccessAckData=>GrantData] | ||||||
|       //            and [ReleaseData=>PutFullData] => [AccessAck=>ReleaseAck] |       //            and [ReleaseData=>PutFullData] => [AccessAck=>ReleaseAck] | ||||||
|       // We need to encode information sufficient to reverse the transformation in output. |       // We need to encode information sufficient to reverse the transformation in output. | ||||||
| @@ -116,6 +111,7 @@ class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyM | |||||||
|       out.e.valid := Bool(false) |       out.e.valid := Bool(false) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| object TLCacheCork | object TLCacheCork | ||||||
| { | { | ||||||
|   | |||||||
| @@ -11,8 +11,8 @@ import scala.math.{min,max} | |||||||
| class TLFilter(select: AddressSet)(implicit p: Parameters) extends LazyModule | class TLFilter(select: AddressSet)(implicit p: Parameters) extends LazyModule | ||||||
| { | { | ||||||
|   val node = TLAdapterNode( |   val node = TLAdapterNode( | ||||||
|     clientFn  = { case Seq(cp) => cp }, |     clientFn  = { cp => cp }, | ||||||
|     managerFn = { case Seq(mp) => |     managerFn = { mp => | ||||||
|       mp.copy(managers = mp.managers.map { m => |       mp.copy(managers = mp.managers.map { m => | ||||||
|         val filtered = m.address.map(_.intersect(select)).flatten |         val filtered = m.address.map(_.intersect(select)).flatten | ||||||
|         val alignment = select.alignment /* alignment 0 means 'select' selected everything */ |         val alignment = select.alignment /* alignment 0 means 'select' selected everything */ | ||||||
|   | |||||||
| @@ -41,8 +41,8 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean = | |||||||
|     sourceId = IdRange(c.sourceId.start << fragmentBits, c.sourceId.end << fragmentBits)) |     sourceId = IdRange(c.sourceId.start << fragmentBits, c.sourceId.end << fragmentBits)) | ||||||
|  |  | ||||||
|   val node = TLAdapterNode( |   val node = TLAdapterNode( | ||||||
|     clientFn  = { case Seq(c) => c.copy(clients = c.clients.map(mapClient)) }, |     clientFn  = { c => c.copy(clients = c.clients.map(mapClient)) }, | ||||||
|     managerFn = { case Seq(m) => m.copy(managers = m.managers.map(mapManager)) }) |     managerFn = { m => m.copy(managers = m.managers.map(mapManager)) }) | ||||||
|  |  | ||||||
|   lazy val module = new LazyModuleImp(this) { |   lazy val module = new LazyModuleImp(this) { | ||||||
|     val io = new Bundle { |     val io = new Bundle { | ||||||
| @@ -50,9 +50,8 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean = | |||||||
|       val out = node.bundleOut |       val out = node.bundleOut | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => | ||||||
|       // All managers must share a common FIFO domain (responses might end up interleaved) |       // All managers must share a common FIFO domain (responses might end up interleaved) | ||||||
|     val edgeOut   = node.edgesOut(0) |  | ||||||
|     val edgeIn    = node.edgesIn(0) |  | ||||||
|       val manager   = edgeOut.manager |       val manager   = edgeOut.manager | ||||||
|       val managers  = manager.managers |       val managers  = manager.managers | ||||||
|       val beatBytes = manager.beatBytes |       val beatBytes = manager.beatBytes | ||||||
| @@ -129,9 +128,6 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean = | |||||||
|        * put1    put1   0       ack1    0      ack1      0     0 |        * put1    put1   0       ack1    0      ack1      0     0 | ||||||
|        */ |        */ | ||||||
|  |  | ||||||
|     val in = io.in(0) |  | ||||||
|     val out = io.out(0) |  | ||||||
|  |  | ||||||
|       val counterBits = log2Up(maxSize/beatBytes) |       val counterBits = log2Up(maxSize/beatBytes) | ||||||
|       val maxDownSize = if (alwaysMin) minSize else manager.maxTransfer |       val maxDownSize = if (alwaysMin) minSize else manager.maxTransfer | ||||||
|  |  | ||||||
| @@ -250,6 +246,7 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean = | |||||||
|       out.e.valid := Bool(false) |       out.e.valid := Bool(false) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| object TLFragmenter | object TLFragmenter | ||||||
| { | { | ||||||
|   | |||||||
| @@ -12,8 +12,8 @@ import diplomacy._ | |||||||
| class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = false, passthrough: Boolean = true)(implicit p: Parameters) extends LazyModule | class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = false, passthrough: Boolean = true)(implicit p: Parameters) extends LazyModule | ||||||
| { | { | ||||||
|   val node = TLAdapterNode( |   val node = TLAdapterNode( | ||||||
|     clientFn  = { case Seq(c) => if (!supportClients)  c else c.copy(minLatency = min(1, c.minLatency), clients  = c.clients .map(_.copy(supportsHint = TransferSizes(1, c.maxTransfer)))) }, |     clientFn  = { c => if (!supportClients)  c else c.copy(minLatency = min(1, c.minLatency), clients  = c.clients .map(_.copy(supportsHint = TransferSizes(1, c.maxTransfer)))) }, | ||||||
|     managerFn = { case Seq(m) => if (!supportManagers) m else m.copy(minLatency = min(1, m.minLatency), managers = m.managers.map(_.copy(supportsHint = TransferSizes(1, m.maxTransfer)))) }) |     managerFn = { m => if (!supportManagers) m else m.copy(minLatency = min(1, m.minLatency), managers = m.managers.map(_.copy(supportsHint = TransferSizes(1, m.maxTransfer)))) }) | ||||||
|  |  | ||||||
|   lazy val module = new LazyModuleImp(this) { |   lazy val module = new LazyModuleImp(this) { | ||||||
|     val io = new Bundle { |     val io = new Bundle { | ||||||
| @@ -21,11 +21,7 @@ class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = f | |||||||
|       val out = node.bundleOut |       val out = node.bundleOut | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     val in  = io.in(0) |     ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => | ||||||
|     val out = io.out(0) |  | ||||||
|     val edgeIn  = node.edgesIn(0) |  | ||||||
|     val edgeOut = node.edgesOut(0) |  | ||||||
|  |  | ||||||
|       // Don't add support for clients if there is no BCE channel |       // Don't add support for clients if there is no BCE channel | ||||||
|       val bce = edgeOut.manager.anySupportAcquireB && edgeIn.client.anySupportProbe |       val bce = edgeOut.manager.anySupportAcquireB && edgeIn.client.anySupportProbe | ||||||
|       require (!supportClients || bce) |       require (!supportClients || bce) | ||||||
| @@ -97,6 +93,7 @@ class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = f | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| object TLHintHandler | object TLHintHandler | ||||||
| { | { | ||||||
|   | |||||||
| @@ -81,16 +81,16 @@ object IntImp extends NodeImp[IntSourcePortParameters, IntSinkPortParameters, In | |||||||
|  |  | ||||||
| case class IntIdentityNode() extends IdentityNode(IntImp) | case class IntIdentityNode() extends IdentityNode(IntImp) | ||||||
| case class IntSourceNode(num: Int) extends SourceNode(IntImp)( | case class IntSourceNode(num: Int) extends SourceNode(IntImp)( | ||||||
|   IntSourcePortParameters(Seq(IntSourceParameters(num))), (if (num == 0) 0 else 1) to 1) |   if (num == 0) Seq() else Seq(IntSourcePortParameters(Seq(IntSourceParameters(num))))) | ||||||
| case class IntSinkNode() extends SinkNode(IntImp)( | case class IntSinkNode() extends SinkNode(IntImp)( | ||||||
|   IntSinkPortParameters(Seq(IntSinkParameters()))) |   Seq(IntSinkPortParameters(Seq(IntSinkParameters())))) | ||||||
|  |  | ||||||
| case class IntAdapterNode( | case class IntNexusNode( | ||||||
|   sourceFn:       Seq[IntSourcePortParameters] => IntSourcePortParameters, |   sourceFn:       Seq[IntSourcePortParameters] => IntSourcePortParameters, | ||||||
|   sinkFn:         Seq[IntSinkPortParameters]   => IntSinkPortParameters, |   sinkFn:         Seq[IntSinkPortParameters]   => IntSinkPortParameters, | ||||||
|   numSourcePorts: Range.Inclusive = 1 to 1, |   numSourcePorts: Range.Inclusive = 0 to 128, | ||||||
|   numSinkPorts:   Range.Inclusive = 1 to 1) |   numSinkPorts:   Range.Inclusive = 0 to 128) | ||||||
|   extends InteriorNode(IntImp)(sourceFn, sinkFn, numSourcePorts, numSinkPorts) |   extends NexusNode(IntImp)(sourceFn, sinkFn, numSourcePorts, numSinkPorts) | ||||||
|  |  | ||||||
| case class IntOutputNode() extends OutputNode(IntImp) | case class IntOutputNode() extends OutputNode(IntImp) | ||||||
| case class IntInputNode() extends InputNode(IntImp) | case class IntInputNode() extends InputNode(IntImp) | ||||||
| @@ -103,9 +103,7 @@ case class IntInternalInputNode(num: Int) extends InternalInputNode(IntImp)(Seq( | |||||||
|  |  | ||||||
| class IntXbar()(implicit p: Parameters) extends LazyModule | class IntXbar()(implicit p: Parameters) extends LazyModule | ||||||
| { | { | ||||||
|   val intnode = IntAdapterNode( |   val intnode = IntNexusNode( | ||||||
|     numSourcePorts = 0 to 128, |  | ||||||
|     numSinkPorts   = 0 to 128, |  | ||||||
|     sinkFn         = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) }, |     sinkFn         = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) }, | ||||||
|     sourceFn       = { seq => |     sourceFn       = { seq => | ||||||
|       IntSourcePortParameters((seq zip seq.map(_.num).scanLeft(0)(_+_).init).map { |       IntSourcePortParameters((seq zip seq.map(_.num).scanLeft(0)(_+_).init).map { | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ import chisel3.internal.sourceinfo.{SourceInfo, SourceLine} | |||||||
| import config._ | import config._ | ||||||
| import diplomacy._ | import diplomacy._ | ||||||
|  |  | ||||||
| case class TLMonitorArgs(gen: () => TLBundleSnoop, edge: () => TLEdge, sourceInfo: SourceInfo, p: Parameters) | case class TLMonitorArgs(edge: () => Seq[TLEdge], sourceInfo: SourceInfo, p: Parameters) | ||||||
|  |  | ||||||
| abstract class TLMonitorBase(args: TLMonitorArgs) extends LazyModule()(args.p) | abstract class TLMonitorBase(args: TLMonitorArgs) extends LazyModule()(args.p) | ||||||
| { | { | ||||||
| @@ -16,11 +16,12 @@ abstract class TLMonitorBase(args: TLMonitorArgs) extends LazyModule()(args.p) | |||||||
|   def legalize(bundle: TLBundleSnoop, edge: TLEdge, reset: Bool): Unit |   def legalize(bundle: TLBundleSnoop, edge: TLEdge, reset: Bool): Unit | ||||||
|  |  | ||||||
|   lazy val module = new LazyModuleImp(this) { |   lazy val module = new LazyModuleImp(this) { | ||||||
|  |     val edges = args.edge() | ||||||
|     val io = new Bundle { |     val io = new Bundle { | ||||||
|       val in = args.gen().asInput |       val in = Vec(edges.size, new TLBundleSnoop(TLBundleParameters.union(edges.map(_.bundle)))).flip | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     legalize(io.in, args.edge(), reset) |     (edges zip io.in).foreach { case (e, in) => legalize(in, e, reset) } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -24,11 +24,13 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL | |||||||
|   override def labelI(ei: TLEdgeIn)  = (ei.manager.beatBytes * 8).toString |   override def labelI(ei: TLEdgeIn)  = (ei.manager.beatBytes * 8).toString | ||||||
|   override def labelO(eo: TLEdgeOut) = (eo.manager.beatBytes * 8).toString |   override def labelO(eo: TLEdgeOut) = (eo.manager.beatBytes * 8).toString | ||||||
|  |  | ||||||
|   def connect(bo: => TLBundle, bi: => TLBundle, ei: => TLEdgeIn)(implicit p: Parameters, sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = { |   override def connect(bindings: () => Seq[(TLEdgeIn, TLBundle, TLBundle)])(implicit p: Parameters, sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = { | ||||||
|     val monitor = p(TLMonitorBuilder)(TLMonitorArgs(() => new TLBundleSnoop(bo.params), () => ei, sourceInfo, p)) |     val monitor = p(TLMonitorBuilder)(TLMonitorArgs(() => bindings().map(_._1), sourceInfo, p)) | ||||||
|     (monitor, () => { |     (monitor, () => { | ||||||
|  |       val eval = bindings () | ||||||
|  |       monitor.foreach { m => (eval zip m.module.io.in) foreach { case ((_,i,o), m) => m := TLBundleSnoop(o,i) } } | ||||||
|  |       eval.foreach { case (_, bi, bo) => | ||||||
|         bi <> bo |         bi <> bo | ||||||
|       monitor.foreach { _.module.io.in := TLBundleSnoop(bo) } |  | ||||||
|         if (p(TLCombinationalCheck)) { |         if (p(TLCombinationalCheck)) { | ||||||
|           // It is forbidden for valid to depend on ready in TL2 |           // It is forbidden for valid to depend on ready in TL2 | ||||||
|           // If someone did that, then this will create a detectable combinational loop |           // If someone did that, then this will create a detectable combinational loop | ||||||
| @@ -63,6 +65,7 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL | |||||||
|           when (!bo.d.valid) { bo.d.bits := bits_d } |           when (!bo.d.valid) { bo.d.bits := bits_d } | ||||||
|           when (!bi.e.valid) { bi.e.bits := bits_e } |           when (!bi.e.valid) { bi.e.bits := bits_e } | ||||||
|         } |         } | ||||||
|  |       } | ||||||
|     }) |     }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -86,29 +89,33 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL | |||||||
|  |  | ||||||
| // Nodes implemented inside modules | // Nodes implemented inside modules | ||||||
| case class TLIdentityNode() extends IdentityNode(TLImp) | case class TLIdentityNode() extends IdentityNode(TLImp) | ||||||
| case class TLClientNode(portParams: TLClientPortParameters, numPorts: Range.Inclusive = 1 to 1) | case class TLClientNode(portParams: Seq[TLClientPortParameters]) extends SourceNode(TLImp)(portParams) | ||||||
|   extends SourceNode(TLImp)(portParams, numPorts) | case class TLManagerNode(portParams: Seq[TLManagerPortParameters]) extends SinkNode(TLImp)(portParams) | ||||||
| case class TLManagerNode(portParams: TLManagerPortParameters, numPorts: Range.Inclusive = 1 to 1) |  | ||||||
|   extends SinkNode(TLImp)(portParams, numPorts) |  | ||||||
|  |  | ||||||
| object TLClientNode | object TLClientNode | ||||||
| { | { | ||||||
|   def apply(params: TLClientParameters) = |   def apply(params: TLClientParameters) = | ||||||
|     new TLClientNode(TLClientPortParameters(Seq(params)), 1 to 1) |     new TLClientNode(Seq(TLClientPortParameters(Seq(params)))) | ||||||
| } | } | ||||||
|  |  | ||||||
| object TLManagerNode | object TLManagerNode | ||||||
| { | { | ||||||
|   def apply(beatBytes: Int, params: TLManagerParameters) = |   def apply(beatBytes: Int, params: TLManagerParameters) = | ||||||
|     new TLManagerNode(TLManagerPortParameters(Seq(params), beatBytes, minLatency = 0), 1 to 1) |     new TLManagerNode(Seq(TLManagerPortParameters(Seq(params), beatBytes, minLatency = 0))) | ||||||
| } | } | ||||||
|  |  | ||||||
| case class TLAdapterNode( | case class TLAdapterNode( | ||||||
|  |   clientFn:  TLClientPortParameters  => TLClientPortParameters, | ||||||
|  |   managerFn: TLManagerPortParameters => TLManagerPortParameters, | ||||||
|  |   num:       Range.Inclusive = 0 to 999) | ||||||
|  |   extends AdapterNode(TLImp)(clientFn, managerFn, num) | ||||||
|  |  | ||||||
|  | case class TLNexusNode( | ||||||
|   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 999, | ||||||
|   numManagerPorts: Range.Inclusive = 1 to 1) |   numManagerPorts: Range.Inclusive = 1 to 999) | ||||||
|   extends InteriorNode(TLImp)(clientFn, managerFn, numClientPorts, numManagerPorts) |   extends NexusNode(TLImp)(clientFn, managerFn, numClientPorts, numManagerPorts) | ||||||
|  |  | ||||||
| // Nodes passed from an inner module | // Nodes passed from an inner module | ||||||
| case class TLOutputNode() extends OutputNode(TLImp) | case class TLOutputNode() extends OutputNode(TLImp) | ||||||
| @@ -155,10 +162,6 @@ object TLAsyncImp extends NodeImp[TLAsyncClientPortParameters, TLAsyncManagerPor | |||||||
|   override def labelI(ei: TLAsyncEdgeParameters) = ei.manager.depth.toString |   override def labelI(ei: TLAsyncEdgeParameters) = ei.manager.depth.toString | ||||||
|   override def labelO(eo: TLAsyncEdgeParameters) = eo.manager.depth.toString |   override def labelO(eo: TLAsyncEdgeParameters) = eo.manager.depth.toString | ||||||
|  |  | ||||||
|   def connect(bo: => TLAsyncBundle, bi: => TLAsyncBundle, ei: => TLAsyncEdgeParameters)(implicit p: Parameters, sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = { |  | ||||||
|     (None, () => { bi <> bo }) |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   override def mixO(pd: TLAsyncClientPortParameters, node: OutwardNode[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle]): TLAsyncClientPortParameters  = |   override def mixO(pd: TLAsyncClientPortParameters, node: OutwardNode[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle]): TLAsyncClientPortParameters  = | ||||||
|    pd.copy(base = pd.base.copy(clients  = pd.base.clients.map  { c => c.copy (nodePath = node +: c.nodePath) })) |    pd.copy(base = pd.base.copy(clients  = pd.base.clients.map  { c => c.copy (nodePath = node +: c.nodePath) })) | ||||||
|   override def mixI(pu: TLAsyncManagerPortParameters, node: InwardNode[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle]): TLAsyncManagerPortParameters = |   override def mixI(pu: TLAsyncManagerPortParameters, node: InwardNode[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle]): TLAsyncManagerPortParameters = | ||||||
| @@ -169,17 +172,15 @@ case class TLAsyncIdentityNode() extends IdentityNode(TLAsyncImp) | |||||||
| case class TLAsyncOutputNode() extends OutputNode(TLAsyncImp) | case class TLAsyncOutputNode() extends OutputNode(TLAsyncImp) | ||||||
| case class TLAsyncInputNode() extends InputNode(TLAsyncImp) | case class TLAsyncInputNode() extends InputNode(TLAsyncImp) | ||||||
|  |  | ||||||
| case class TLAsyncSourceNode(sync: Int) extends MixedNode(TLImp, TLAsyncImp)( | case class TLAsyncSourceNode(sync: Int) | ||||||
|   dFn = { case (1, Seq(p)) => Seq(TLAsyncClientPortParameters(p)) }, |   extends MixedAdapterNode(TLImp, TLAsyncImp)( | ||||||
|   uFn = { case (1, Seq(p)) => Seq(p.base.copy(minLatency = sync+1)) }, // discard cycles in other clock domain |     dFn = { p => TLAsyncClientPortParameters(p) }, | ||||||
|   numPO = 1 to 1, |     uFn = { p => p.base.copy(minLatency = sync+1) }) // discard cycles in other clock domain | ||||||
|   numPI = 1 to 1) |  | ||||||
|  |  | ||||||
| case class TLAsyncSinkNode(depth: Int, sync: Int) extends MixedNode(TLAsyncImp, TLImp)( | case class TLAsyncSinkNode(depth: Int, sync: Int) | ||||||
|   dFn = { case (1, Seq(p)) => Seq(p.base.copy(minLatency = sync+1)) }, |   extends MixedAdapterNode(TLAsyncImp, TLImp)( | ||||||
|   uFn = { case (1, Seq(p)) => Seq(TLAsyncManagerPortParameters(depth, p)) }, |     dFn = { p => p.base.copy(minLatency = sync+1) }, | ||||||
|   numPO = 1 to 1, |     uFn = { p => TLAsyncManagerPortParameters(depth, p) }) | ||||||
|   numPI = 1 to 1) |  | ||||||
|  |  | ||||||
| object TLRationalImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TLEdgeParameters, TLEdgeParameters, TLRationalBundle] | object TLRationalImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TLEdgeParameters, TLEdgeParameters, TLRationalBundle] | ||||||
| { | { | ||||||
| @@ -191,10 +192,6 @@ object TLRationalImp extends NodeImp[TLClientPortParameters, TLManagerPortParame | |||||||
|  |  | ||||||
|   def colour = "#00ff00" // green |   def colour = "#00ff00" // green | ||||||
|  |  | ||||||
|   def connect(bo: => TLRationalBundle, bi: => TLRationalBundle, ei: => TLEdgeParameters)(implicit p: Parameters, sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = { |  | ||||||
|     (None, () => { bi <> bo }) |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   override def mixO(pd: TLClientPortParameters, node: OutwardNode[TLClientPortParameters, TLManagerPortParameters, TLRationalBundle]): TLClientPortParameters  = |   override def mixO(pd: TLClientPortParameters, node: OutwardNode[TLClientPortParameters, TLManagerPortParameters, TLRationalBundle]): TLClientPortParameters  = | ||||||
|    pd.copy(clients  = pd.clients.map  { c => c.copy (nodePath = node +: c.nodePath) }) |    pd.copy(clients  = pd.clients.map  { c => c.copy (nodePath = node +: c.nodePath) }) | ||||||
|   override def mixI(pu: TLManagerPortParameters, node: InwardNode[TLClientPortParameters, TLManagerPortParameters, TLRationalBundle]): TLManagerPortParameters = |   override def mixI(pu: TLManagerPortParameters, node: InwardNode[TLClientPortParameters, TLManagerPortParameters, TLRationalBundle]): TLManagerPortParameters = | ||||||
| @@ -205,14 +202,12 @@ case class TLRationalIdentityNode() extends IdentityNode(TLRationalImp) | |||||||
| case class TLRationalOutputNode() extends OutputNode(TLRationalImp) | case class TLRationalOutputNode() extends OutputNode(TLRationalImp) | ||||||
| case class TLRationalInputNode() extends InputNode(TLRationalImp) | case class TLRationalInputNode() extends InputNode(TLRationalImp) | ||||||
|  |  | ||||||
| case class TLRationalSourceNode() extends MixedNode(TLImp, TLRationalImp)( | case class TLRationalSourceNode() | ||||||
|   dFn = { case (_, s) => s }, |   extends MixedAdapterNode(TLImp, TLRationalImp)( | ||||||
|   uFn = { case (_, s) => s.map(p => p.copy(minLatency = 1)) }, // discard cycles from other clock domain |     dFn = { p => p }, | ||||||
|   numPO = 0 to 999, |     uFn = { p => p.copy(minLatency = 1) }) // discard cycles from other clock domain | ||||||
|   numPI = 0 to 999) |  | ||||||
|  |  | ||||||
| case class TLRationalSinkNode() extends MixedNode(TLRationalImp, TLImp)( | case class TLRationalSinkNode() | ||||||
|   dFn = { case (_, s) => s.map(p => p.copy(minLatency = 1)) }, |   extends MixedAdapterNode(TLRationalImp, TLImp)( | ||||||
|   uFn = { case (_, s) => s }, |     dFn = { p => p.copy(minLatency = 1) }, | ||||||
|   numPO = 0 to 999, |     uFn = { p => p }) | ||||||
|   numPI = 0 to 999) |  | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ package uncore.tilelink2 | |||||||
| import Chisel._ | import Chisel._ | ||||||
| import config._ | import config._ | ||||||
| import diplomacy._ | import diplomacy._ | ||||||
|  | import util.GenericParameterizedBundle | ||||||
|  |  | ||||||
| // We detect concurrent puts that put memory into an undefined state. | // We detect concurrent puts that put memory into an undefined state. | ||||||
| // put0, put0Ack, put1, put1Ack => ok: defined | // put0, put0Ack, put1, put1Ack => ok: defined | ||||||
| @@ -31,13 +32,8 @@ class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule | |||||||
|       val out = node.bundleOut |       val out = node.bundleOut | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // !!! support multiple clients via clock division |     ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => | ||||||
|     require (io.out.size == 1) |       val edge         = edgeIn | ||||||
|  |  | ||||||
|     val in = io.in(0) |  | ||||||
|     val out = io.out(0) |  | ||||||
|  |  | ||||||
|     val edge         = node.edgesIn(0) |  | ||||||
|       val endAddress   = edge.manager.maxAddress + 1 |       val endAddress   = edge.manager.maxAddress + 1 | ||||||
|       val endSourceId  = edge.client.endSourceId |       val endSourceId  = edge.client.endSourceId | ||||||
|       val maxTransfer  = edge.manager.maxTransfer |       val maxTransfer  = edge.manager.maxTransfer | ||||||
| @@ -71,18 +67,10 @@ class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule | |||||||
|       in.c.ready := Bool(true) |       in.c.ready := Bool(true) | ||||||
|       in.e.ready := Bool(true) |       in.e.ready := Bool(true) | ||||||
|  |  | ||||||
|     class ByteMonitor extends Bundle { |       val params = TLRAMModel.MonitorParameters(addressBits, sizeBits) | ||||||
|       val valid = Bool() |  | ||||||
|       val value = UInt(width = 8) |  | ||||||
|     } |  | ||||||
|     class FlightMonitor extends Bundle { |  | ||||||
|       val base    = UInt(width = addressBits) |  | ||||||
|       val size    = UInt(width = sizeBits) |  | ||||||
|       val opcode  = UInt(width = 3) |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|       // Infer as simple dual port BRAM/M10k with write-first/new-data semantics (bypass needed) |       // Infer as simple dual port BRAM/M10k with write-first/new-data semantics (bypass needed) | ||||||
|     val shadow = Seq.fill(beatBytes) { Mem(endAddressHi, new ByteMonitor) } |       val shadow = Seq.fill(beatBytes) { Mem(endAddressHi, new TLRAMModel.ByteMonitor(params)) } | ||||||
|       val inc_bytes = Seq.fill(beatBytes) { Mem(endAddressHi, UInt(width = countBits)) } |       val inc_bytes = Seq.fill(beatBytes) { Mem(endAddressHi, UInt(width = countBits)) } | ||||||
|       val dec_bytes = Seq.fill(beatBytes) { Mem(endAddressHi, UInt(width = countBits)) } |       val dec_bytes = Seq.fill(beatBytes) { Mem(endAddressHi, UInt(width = countBits)) } | ||||||
|       val inc_trees = Seq.tabulate(decTrees) { i => Mem(endAddressHi >> (i+1), UInt(width = countBits)) } |       val inc_trees = Seq.tabulate(decTrees) { i => Mem(endAddressHi >> (i+1), UInt(width = countBits)) } | ||||||
| @@ -95,11 +83,11 @@ class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule | |||||||
|       val dec_trees_wen = Wire(init = Fill(decTrees, wipe)) |       val dec_trees_wen = Wire(init = Fill(decTrees, wipe)) | ||||||
|  |  | ||||||
|       // This must be registers b/c we build a CAM from it |       // This must be registers b/c we build a CAM from it | ||||||
|     val flight = Reg(Vec(endSourceId, new FlightMonitor)) |       val flight = Reg(Vec(endSourceId, new TLRAMModel.FlightMonitor(params))) | ||||||
|       val valid = Reg(Vec(endSourceId, Bool())) |       val valid = Reg(Vec(endSourceId, Bool())) | ||||||
|  |  | ||||||
|       // We want to cross flight data from A to D in the same cycle (for combinational TL2 devices) |       // We want to cross flight data from A to D in the same cycle (for combinational TL2 devices) | ||||||
|     val a_flight = Wire(new FlightMonitor) |       val a_flight = Wire(new TLRAMModel.FlightMonitor(params)) | ||||||
|       a_flight.base   := edge.address(in.a.bits) |       a_flight.base   := edge.address(in.a.bits) | ||||||
|       a_flight.size   := edge.size(in.a.bits) |       a_flight.size   := edge.size(in.a.bits) | ||||||
|       a_flight.opcode := in.a.bits.opcode |       a_flight.opcode := in.a.bits.opcode | ||||||
| @@ -169,7 +157,7 @@ class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule | |||||||
|  |  | ||||||
|       val a_waddr = Mux(wipe, wipeIndex, a_addr_hi) |       val a_waddr = Mux(wipe, wipeIndex, a_addr_hi) | ||||||
|       for (i <- 0 until beatBytes) { |       for (i <- 0 until beatBytes) { | ||||||
|       val data = Wire(new ByteMonitor) |         val data = Wire(new TLRAMModel.ByteMonitor(params)) | ||||||
|         val busy = a_inc(i) =/= a_dec(i) + (!a_first).asUInt |         val busy = a_inc(i) =/= a_dec(i) + (!a_first).asUInt | ||||||
|         val amo = a.opcode === TLMessages.ArithmeticData || a.opcode === TLMessages.LogicalData |         val amo = a.opcode === TLMessages.ArithmeticData || a.opcode === TLMessages.LogicalData | ||||||
|         data.valid := Mux(wipe, Bool(false), (!busy || a_fifo) && !amo) |         data.valid := Mux(wipe, Bool(false), (!busy || a_fifo) && !amo) | ||||||
| @@ -296,3 +284,19 @@ class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | object TLRAMModel | ||||||
|  | { | ||||||
|  |   case class MonitorParameters(addressBits: Int, sizeBits: Int) | ||||||
|  |  | ||||||
|  |   class ByteMonitor(params: MonitorParameters) extends GenericParameterizedBundle(params) { | ||||||
|  |     val valid = Bool() | ||||||
|  |     val value = UInt(width = 8) | ||||||
|  |   } | ||||||
|  |   class FlightMonitor(params: MonitorParameters) extends GenericParameterizedBundle(params) { | ||||||
|  |     val base    = UInt(width = params.addressBits) | ||||||
|  |     val size    = UInt(width = params.sizeBits) | ||||||
|  |     val opcode  = UInt(width = 3) | ||||||
|  |   } | ||||||
|  | } | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ import regmapper._ | |||||||
| import scala.math.{min,max} | import scala.math.{min,max} | ||||||
|  |  | ||||||
| class TLRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) | class TLRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) | ||||||
|   extends TLManagerNode(TLManagerPortParameters( |   extends TLManagerNode(Seq(TLManagerPortParameters( | ||||||
|     Seq(TLManagerParameters( |     Seq(TLManagerParameters( | ||||||
|       address            = Seq(address), |       address            = Seq(address), | ||||||
|       executable         = executable, |       executable         = executable, | ||||||
| @@ -18,7 +18,7 @@ class TLRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = | |||||||
|       supportsPutFull    = TransferSizes(1, beatBytes), |       supportsPutFull    = TransferSizes(1, beatBytes), | ||||||
|       fifoId             = Some(0))), // requests are handled in order |       fifoId             = Some(0))), // requests are handled in order | ||||||
|     beatBytes  = beatBytes, |     beatBytes  = beatBytes, | ||||||
|     minLatency = min(concurrency, 1))) // the Queue adds at most one cycle |     minLatency = min(concurrency, 1)))) // the Queue adds at most one cycle | ||||||
| { | { | ||||||
|   require (address.contiguous) |   require (address.contiguous) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ import diplomacy._ | |||||||
|  |  | ||||||
| class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule | class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule | ||||||
| { | { | ||||||
|   val node = TLManagerNode(TLManagerPortParameters( |   val node = TLManagerNode(Seq(TLManagerPortParameters( | ||||||
|     Seq(TLManagerParameters( |     Seq(TLManagerParameters( | ||||||
|       address            = List(address), |       address            = List(address), | ||||||
|       regionType         = RegionType.UNCACHED, |       regionType         = RegionType.UNCACHED, | ||||||
| @@ -18,7 +18,7 @@ class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4) | |||||||
|       supportsPutFull    = TransferSizes(1, beatBytes), |       supportsPutFull    = TransferSizes(1, beatBytes), | ||||||
|       fifoId             = Some(0))), // requests are handled in order |       fifoId             = Some(0))), // requests are handled in order | ||||||
|     beatBytes  = beatBytes, |     beatBytes  = beatBytes, | ||||||
|     minLatency = 1)) // no bypass needed for this device |     minLatency = 1))) // no bypass needed for this device | ||||||
|  |  | ||||||
|   // We require the address range to include an entire beat (for the write mask) |   // We require the address range to include an entire beat (for the write mask) | ||||||
|   require ((address.mask & (beatBytes-1)) == beatBytes-1) |   require ((address.mask & (beatBytes-1)) == beatBytes-1) | ||||||
|   | |||||||
| @@ -15,8 +15,8 @@ class TLSourceShrinker(maxInFlight: Int)(implicit p: Parameters) extends LazyMod | |||||||
|   private val client = TLClientParameters(sourceId = IdRange(0, maxInFlight)) |   private val client = TLClientParameters(sourceId = IdRange(0, maxInFlight)) | ||||||
|   val node = TLAdapterNode( |   val node = TLAdapterNode( | ||||||
|     // We erase all client information since we crush the source Ids |     // We erase all client information since we crush the source Ids | ||||||
|     clientFn  = { case _ => TLClientPortParameters(clients = Seq(client)) }, |     clientFn  = { _ => TLClientPortParameters(clients = Seq(client)) }, | ||||||
|     managerFn = { case Seq(mp) => mp }) |     managerFn = { mp => mp }) | ||||||
|  |  | ||||||
|   lazy val module = new LazyModuleImp(this) { |   lazy val module = new LazyModuleImp(this) { | ||||||
|     val io = new Bundle { |     val io = new Bundle { | ||||||
| @@ -24,11 +24,7 @@ class TLSourceShrinker(maxInFlight: Int)(implicit p: Parameters) extends LazyMod | |||||||
|       val out = node.bundleOut |       val out = node.bundleOut | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     val edgeIn = node.edgesIn(0) |     ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => | ||||||
|     val edgeOut = node.edgesOut(0) |  | ||||||
|     val in = io.in(0) |  | ||||||
|     val out = io.out(0) |  | ||||||
|  |  | ||||||
|       // Acquires cannot pass this adapter; it makes Probes impossible |       // Acquires cannot pass this adapter; it makes Probes impossible | ||||||
|       require (!edgeIn.client.anySupportProbe ||  |       require (!edgeIn.client.anySupportProbe ||  | ||||||
|                !edgeOut.manager.anySupportAcquireB) |                !edgeOut.manager.anySupportAcquireB) | ||||||
| @@ -75,6 +71,7 @@ class TLSourceShrinker(maxInFlight: Int)(implicit p: Parameters) extends LazyMod | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| object TLSourceShrinker | object TLSourceShrinker | ||||||
| { | { | ||||||
|   | |||||||
| @@ -10,12 +10,12 @@ import uncore.ahb._ | |||||||
| import scala.math.{min, max} | import scala.math.{min, max} | ||||||
| import AHBParameters._ | import AHBParameters._ | ||||||
|  |  | ||||||
| case class TLToAHBNode() extends MixedNode(TLImp, AHBImp)( | case class TLToAHBNode() extends MixedAdapterNode(TLImp, AHBImp)( | ||||||
|   dFn = { case (1, Seq(TLClientPortParameters(clients, unsafeAtomics, minLatency))) => |   dFn = { case TLClientPortParameters(clients, unsafeAtomics, minLatency) => | ||||||
|     val masters = clients.map { case c => AHBMasterParameters(nodePath = c.nodePath) } |     val masters = clients.map { case c => AHBMasterParameters(nodePath = c.nodePath) } | ||||||
|     Seq(AHBMasterPortParameters(masters)) |     AHBMasterPortParameters(masters) | ||||||
|   }, |   }, | ||||||
|   uFn = { case (1, Seq(AHBSlavePortParameters(slaves, beatBytes))) => |   uFn = { case AHBSlavePortParameters(slaves, beatBytes) => | ||||||
|     val managers = slaves.map { case s => |     val managers = slaves.map { case s => | ||||||
|       TLManagerParameters( |       TLManagerParameters( | ||||||
|         address            = s.address, |         address            = s.address, | ||||||
| @@ -26,10 +26,8 @@ case class TLToAHBNode() extends MixedNode(TLImp, AHBImp)( | |||||||
|         supportsPutFull    = s.supportsWrite, // but not PutPartial |         supportsPutFull    = s.supportsWrite, // but not PutPartial | ||||||
|         fifoId             = Some(0)) // a common FIFO domain |         fifoId             = Some(0)) // a common FIFO domain | ||||||
|     } |     } | ||||||
|     Seq(TLManagerPortParameters(managers, beatBytes, 1, 1)) |     TLManagerPortParameters(managers, beatBytes, 1, 1) | ||||||
|   }, |   }) | ||||||
|   numPO = 1 to 1, |  | ||||||
|   numPI = 1 to 1) |  | ||||||
|  |  | ||||||
| class TLToAHB(combinational: Boolean = true)(implicit p: Parameters) extends LazyModule | class TLToAHB(combinational: Boolean = true)(implicit p: Parameters) extends LazyModule | ||||||
| { | { | ||||||
| @@ -41,10 +39,7 @@ class TLToAHB(combinational: Boolean = true)(implicit p: Parameters) extends Laz | |||||||
|       val out = node.bundleOut |       val out = node.bundleOut | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     val in = io.in(0) |     ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => | ||||||
|     val out = io.out(0) |  | ||||||
|     val edgeIn  = node.edgesIn(0) |  | ||||||
|     val edgeOut = node.edgesOut(0) |  | ||||||
|       val beatBytes = edgeOut.slave.beatBytes |       val beatBytes = edgeOut.slave.beatBytes | ||||||
|       val maxTransfer = edgeOut.slave.maxTransfer |       val maxTransfer = edgeOut.slave.maxTransfer | ||||||
|       val lgMax = log2Ceil(maxTransfer) |       val lgMax = log2Ceil(maxTransfer) | ||||||
| @@ -128,6 +123,7 @@ class TLToAHB(combinational: Boolean = true)(implicit p: Parameters) extends Laz | |||||||
|       out.hwdata    := RegEnable(a.bits.data, a.fire()) |       out.hwdata    := RegEnable(a.bits.data, a.fire()) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| object TLToAHB | object TLToAHB | ||||||
| { | { | ||||||
|   | |||||||
| @@ -10,12 +10,12 @@ import uncore.apb._ | |||||||
| import scala.math.{min, max} | import scala.math.{min, max} | ||||||
| import APBParameters._ | import APBParameters._ | ||||||
|  |  | ||||||
| case class TLToAPBNode() extends MixedNode(TLImp, APBImp)( | case class TLToAPBNode() extends MixedAdapterNode(TLImp, APBImp)( | ||||||
|   dFn = { case (1, Seq(TLClientPortParameters(clients, unsafeAtomics, minLatency))) => |   dFn = { case TLClientPortParameters(clients, unsafeAtomics, minLatency) => | ||||||
|     val masters = clients.map { case c => APBMasterParameters(nodePath = c.nodePath) } |     val masters = clients.map { case c => APBMasterParameters(nodePath = c.nodePath) } | ||||||
|     Seq(APBMasterPortParameters(masters)) |     APBMasterPortParameters(masters) | ||||||
|   }, |   }, | ||||||
|   uFn = { case (1, Seq(APBSlavePortParameters(slaves, beatBytes))) => |   uFn = { case APBSlavePortParameters(slaves, beatBytes) => | ||||||
|     val managers = slaves.map { case s => |     val managers = slaves.map { case s => | ||||||
|       TLManagerParameters( |       TLManagerParameters( | ||||||
|         address            = s.address, |         address            = s.address, | ||||||
| @@ -27,10 +27,8 @@ case class TLToAPBNode() extends MixedNode(TLImp, APBImp)( | |||||||
|         supportsPutFull    = if (s.supportsWrite) TransferSizes(1, beatBytes) else TransferSizes.none, |         supportsPutFull    = if (s.supportsWrite) TransferSizes(1, beatBytes) else TransferSizes.none, | ||||||
|         fifoId             = Some(0)) // a common FIFO domain |         fifoId             = Some(0)) // a common FIFO domain | ||||||
|     } |     } | ||||||
|     Seq(TLManagerPortParameters(managers, beatBytes, 1, 0)) |     TLManagerPortParameters(managers, beatBytes, 1, 0) | ||||||
|   }, |   }) | ||||||
|   numPO = 1 to 1, |  | ||||||
|   numPI = 1 to 1) |  | ||||||
|  |  | ||||||
| class TLToAPB(combinational: Boolean = true)(implicit p: Parameters) extends LazyModule | class TLToAPB(combinational: Boolean = true)(implicit p: Parameters) extends LazyModule | ||||||
| { | { | ||||||
| @@ -42,10 +40,7 @@ class TLToAPB(combinational: Boolean = true)(implicit p: Parameters) extends Laz | |||||||
|       val out = node.bundleOut |       val out = node.bundleOut | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     val in = io.in(0) |     ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => | ||||||
|     val out = io.out(0) |  | ||||||
|     val edgeIn  = node.edgesIn(0) |  | ||||||
|     val edgeOut = node.edgesOut(0) |  | ||||||
|       val beatBytes = edgeOut.slave.beatBytes |       val beatBytes = edgeOut.slave.beatBytes | ||||||
|       val lgBytes = log2Ceil(beatBytes) |       val lgBytes = log2Ceil(beatBytes) | ||||||
|  |  | ||||||
| @@ -89,6 +84,7 @@ class TLToAPB(combinational: Boolean = true)(implicit p: Parameters) extends Laz | |||||||
|       d.bits.opcode := Mux(a_write, TLMessages.AccessAck, TLMessages.AccessAckData) |       d.bits.opcode := Mux(a_write, TLMessages.AccessAck, TLMessages.AccessAckData) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| object TLToAPB | object TLToAPB | ||||||
| { | { | ||||||
|   | |||||||
| @@ -10,16 +10,16 @@ import util.PositionalMultiQueue | |||||||
| import uncore.axi4._ | import uncore.axi4._ | ||||||
| import scala.math.{min, max} | import scala.math.{min, max} | ||||||
|  |  | ||||||
| case class TLToAXI4Node(idBits: Int) extends MixedNode(TLImp, AXI4Imp)( | case class TLToAXI4Node(idBits: Int) extends MixedAdapterNode(TLImp, AXI4Imp)( | ||||||
|   dFn = { case (1, _) => |   dFn = { _ => | ||||||
|     // We must erase all client information, because we crush their source Ids |     // We must erase all client information, because we crush their source Ids | ||||||
|     val masters = Seq( |     val masters = Seq( | ||||||
|       AXI4MasterParameters( |       AXI4MasterParameters( | ||||||
|         id      = IdRange(0, 1 << idBits), |         id      = IdRange(0, 1 << idBits), | ||||||
|         aligned = true)) |         aligned = true)) | ||||||
|     Seq(AXI4MasterPortParameters(masters)) |     AXI4MasterPortParameters(masters) | ||||||
|   }, |   }, | ||||||
|   uFn = { case (1, Seq(p)) => Seq(TLManagerPortParameters( |   uFn = { p => TLManagerPortParameters( | ||||||
|     managers = p.slaves.map { case s => |     managers = p.slaves.map { case s => | ||||||
|       TLManagerParameters( |       TLManagerParameters( | ||||||
|         address            = s.address, |         address            = s.address, | ||||||
| @@ -31,10 +31,8 @@ case class TLToAXI4Node(idBits: Int) extends MixedNode(TLImp, AXI4Imp)( | |||||||
|         supportsPutPartial = s.supportsWrite)}, |         supportsPutPartial = s.supportsWrite)}, | ||||||
|         // AXI4 is NEVER fifo in TL sense (R+W are independent) |         // AXI4 is NEVER fifo in TL sense (R+W are independent) | ||||||
|       beatBytes = p.beatBytes, |       beatBytes = p.beatBytes, | ||||||
|       minLatency = p.minLatency)) |       minLatency = p.minLatency) | ||||||
|   }, |   }) | ||||||
|   numPO = 1 to 1, |  | ||||||
|   numPI = 1 to 1) |  | ||||||
|  |  | ||||||
| class TLToAXI4(idBits: Int, combinational: Boolean = true)(implicit p: Parameters) extends LazyModule | class TLToAXI4(idBits: Int, combinational: Boolean = true)(implicit p: Parameters) extends LazyModule | ||||||
| { | { | ||||||
| @@ -46,11 +44,7 @@ class TLToAXI4(idBits: Int, combinational: Boolean = true)(implicit p: Parameter | |||||||
|       val out = node.bundleOut |       val out = node.bundleOut | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     val in = io.in(0) |     ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => | ||||||
|     val out = io.out(0) |  | ||||||
|  |  | ||||||
|     val edgeIn  = node.edgesIn(0) |  | ||||||
|     val edgeOut = node.edgesOut(0) |  | ||||||
|       val slaves  = edgeOut.slave.slaves |       val slaves  = edgeOut.slave.slaves | ||||||
|  |  | ||||||
|       // All pairs of slaves must promise that they will never interleave data |       // All pairs of slaves must promise that they will never interleave data | ||||||
| @@ -227,6 +221,7 @@ class TLToAXI4(idBits: Int, combinational: Boolean = true)(implicit p: Parameter | |||||||
|       in.e.ready := Bool(true) |       in.e.ready := Bool(true) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| object TLToAXI4 | object TLToAXI4 | ||||||
| { | { | ||||||
|   | |||||||
| @@ -12,8 +12,8 @@ import scala.math.{min,max} | |||||||
| class TLWidthWidget(innerBeatBytes: Int)(implicit p: Parameters) extends LazyModule | class TLWidthWidget(innerBeatBytes: Int)(implicit p: Parameters) extends LazyModule | ||||||
| { | { | ||||||
|   val node = TLAdapterNode( |   val node = TLAdapterNode( | ||||||
|     clientFn  = { case Seq(c) => c }, |     clientFn  = { case c => c }, | ||||||
|     managerFn = { case Seq(m) => m.copy(beatBytes = innerBeatBytes) }) |     managerFn = { case m => m.copy(beatBytes = innerBeatBytes) }) | ||||||
|  |  | ||||||
|   lazy val module = new LazyModuleImp(this) { |   lazy val module = new LazyModuleImp(this) { | ||||||
|     val io = new Bundle { |     val io = new Bundle { | ||||||
| @@ -139,11 +139,7 @@ class TLWidthWidget(innerBeatBytes: Int)(implicit p: Parameters) extends LazyMod | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     val edgeOut = node.edgesOut(0) |     ((io.in zip io.out) zip (node.edgesIn zip node.edgesOut)) foreach { case ((in, out), (edgeIn, edgeOut)) => | ||||||
|     val edgeIn = node.edgesIn(0) |  | ||||||
|     val in = io.in(0) |  | ||||||
|     val out = io.out(0) |  | ||||||
|  |  | ||||||
|       splice(edgeIn,  in.a,  edgeOut, out.a) |       splice(edgeIn,  in.a,  edgeOut, out.a) | ||||||
|       splice(edgeOut, out.d, edgeIn,  in.d) |       splice(edgeOut, out.d, edgeIn,  in.d) | ||||||
|  |  | ||||||
| @@ -163,6 +159,7 @@ class TLWidthWidget(innerBeatBytes: Int)(implicit p: Parameters) extends LazyMod | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| object TLWidthWidget | object TLWidthWidget | ||||||
| { | { | ||||||
|   | |||||||
| @@ -34,7 +34,7 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.lowestIndexFirst)(implicit p: | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   val node = TLAdapterNode( |   val node = TLNexusNode( | ||||||
|     numClientPorts  = 1 to 32, |     numClientPorts  = 1 to 32, | ||||||
|     numManagerPorts = 1 to 32, |     numManagerPorts = 1 to 32, | ||||||
|     clientFn  = { seq => |     clientFn  = { seq => | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user