From 396ecacda4105b77b57fb222b1f0611bcff87ccf Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 17 Mar 2017 17:06:04 -0700 Subject: [PATCH] AXI4: add an optional user bundle field --- src/main/scala/uncore/axi4/Bundles.scala | 3 +++ src/main/scala/uncore/axi4/Parameters.scala | 17 ++++++++++++----- src/main/scala/uncore/axi4/ToTL.scala | 6 ++++-- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/main/scala/uncore/axi4/Bundles.scala b/src/main/scala/uncore/axi4/Bundles.scala index f8c9ddc6..75f43c66 100644 --- a/src/main/scala/uncore/axi4/Bundles.scala +++ b/src/main/scala/uncore/axi4/Bundles.scala @@ -19,6 +19,7 @@ abstract class AXI4BundleA(params: AXI4BundleParameters) extends AXI4BundleBase( val cache = UInt(width = params.cacheBits) val prot = UInt(width = params.protBits) val qos = UInt(width = params.qosBits) // 0=no QoS, bigger = higher priority + val user = if (params.userBits > 0) Some(UInt(width = params.userBits)) else None // val region = UInt(width = 4) // optional // Number of bytes-1 in this operation @@ -51,6 +52,7 @@ class AXI4BundleR(params: AXI4BundleParameters) extends AXI4BundleBase(params) val id = UInt(width = params.idBits) val data = UInt(width = params.dataBits) val resp = UInt(width = params.respBits) + val user = if (params.userBits > 0) Some(UInt(width = params.userBits)) else None val last = Bool() } @@ -58,6 +60,7 @@ class AXI4BundleB(params: AXI4BundleParameters) extends AXI4BundleBase(params) { val id = UInt(width = params.idBits) val resp = UInt(width = params.respBits) + val user = if (params.userBits > 0) Some(UInt(width = params.userBits)) else None } class AXI4Bundle(params: AXI4BundleParameters) extends AXI4BundleBase(params) diff --git a/src/main/scala/uncore/axi4/Parameters.scala b/src/main/scala/uncore/axi4/Parameters.scala index 017bc001..a3a8f472 100644 --- a/src/main/scala/uncore/axi4/Parameters.scala +++ b/src/main/scala/uncore/axi4/Parameters.scala @@ -70,9 +70,13 @@ case class AXI4MasterParameters( } case class AXI4MasterPortParameters( - masters: Seq[AXI4MasterParameters]) + masters: Seq[AXI4MasterParameters], + userBits: Int = 0, + maxFlight: Int = 0) // at most X transactions per ID (0 = unlimited) { val endId = masters.map(_.id.end).max + require (userBits >= 0) + require (maxFlight >= 0) // Require disjoint ranges for ids masters.combinations(2).foreach { case Seq(x,y) => require (!x.id.overlaps(y.id), s"$x and $y overlap") } @@ -81,7 +85,8 @@ case class AXI4MasterPortParameters( case class AXI4BundleParameters( addrBits: Int, dataBits: Int, - idBits: Int) + idBits: Int, + userBits: Int) { require (dataBits >= 8, s"AXI4 data bits must be >= 8 (got $dataBits)") require (addrBits >= 1, s"AXI4 addr bits must be >= 1 (got $addrBits)") @@ -102,19 +107,21 @@ case class AXI4BundleParameters( AXI4BundleParameters( max(addrBits, x.addrBits), max(dataBits, x.dataBits), - max(idBits, x.idBits)) + max(idBits, x.idBits), + max(userBits, x.userBits)) } object AXI4BundleParameters { - val emptyBundleParams = AXI4BundleParameters(addrBits=1, dataBits=8, idBits=1) + val emptyBundleParams = AXI4BundleParameters(addrBits=1, dataBits=8, idBits=1, userBits=0) def union(x: Seq[AXI4BundleParameters]) = x.foldLeft(emptyBundleParams)((x,y) => x.union(y)) def apply(master: AXI4MasterPortParameters, slave: AXI4SlavePortParameters) = new AXI4BundleParameters( addrBits = log2Up(slave.maxAddress+1), dataBits = slave.beatBytes * 8, - idBits = log2Up(master.endId)) + idBits = log2Up(master.endId), + userBits = master.userBits) } case class AXI4EdgeParameters( diff --git a/src/main/scala/uncore/axi4/ToTL.scala b/src/main/scala/uncore/axi4/ToTL.scala index a7612b36..16542763 100644 --- a/src/main/scala/uncore/axi4/ToTL.scala +++ b/src/main/scala/uncore/axi4/ToTL.scala @@ -9,10 +9,12 @@ import diplomacy._ import uncore.tilelink2._ case class AXI4ToTLNode() extends MixedAdapterNode(AXI4Imp, TLImp)( - dFn = { case AXI4MasterPortParameters(masters) => + dFn = { case AXI4MasterPortParameters(masters, userBits, maxFlight) => + require (userBits == 0, "AXI4 user bits cannot be transported by TL") + require (maxFlight > 0, "AXI4 must include a maximum transactions per ID to convert to TL") TLClientPortParameters(clients = masters.map { m => TLClientParameters( - sourceId = IdRange(m.id.start << 1, m.id.end << 1), // R+W ids are distinct + sourceId = IdRange((maxFlight * m.id.start) << 1, (maxFlight * m.id.end) << 1), // R+W ids are distinct nodePath = m.nodePath) }) },