AXI4: add an optional user bundle field
This commit is contained in:
parent
d6e69066a5
commit
396ecacda4
@ -19,6 +19,7 @@ abstract class AXI4BundleA(params: AXI4BundleParameters) extends AXI4BundleBase(
|
|||||||
val cache = UInt(width = params.cacheBits)
|
val cache = UInt(width = params.cacheBits)
|
||||||
val prot = UInt(width = params.protBits)
|
val prot = UInt(width = params.protBits)
|
||||||
val qos = UInt(width = params.qosBits) // 0=no QoS, bigger = higher priority
|
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
|
// val region = UInt(width = 4) // optional
|
||||||
|
|
||||||
// Number of bytes-1 in this operation
|
// 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 id = UInt(width = params.idBits)
|
||||||
val data = UInt(width = params.dataBits)
|
val data = UInt(width = params.dataBits)
|
||||||
val resp = UInt(width = params.respBits)
|
val resp = UInt(width = params.respBits)
|
||||||
|
val user = if (params.userBits > 0) Some(UInt(width = params.userBits)) else None
|
||||||
val last = Bool()
|
val last = Bool()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,6 +60,7 @@ class AXI4BundleB(params: AXI4BundleParameters) extends AXI4BundleBase(params)
|
|||||||
{
|
{
|
||||||
val id = UInt(width = params.idBits)
|
val id = UInt(width = params.idBits)
|
||||||
val resp = UInt(width = params.respBits)
|
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)
|
class AXI4Bundle(params: AXI4BundleParameters) extends AXI4BundleBase(params)
|
||||||
|
@ -70,9 +70,13 @@ case class AXI4MasterParameters(
|
|||||||
}
|
}
|
||||||
|
|
||||||
case class AXI4MasterPortParameters(
|
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
|
val endId = masters.map(_.id.end).max
|
||||||
|
require (userBits >= 0)
|
||||||
|
require (maxFlight >= 0)
|
||||||
|
|
||||||
// Require disjoint ranges for ids
|
// Require disjoint ranges for ids
|
||||||
masters.combinations(2).foreach { case Seq(x,y) => require (!x.id.overlaps(y.id), s"$x and $y overlap") }
|
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(
|
case class AXI4BundleParameters(
|
||||||
addrBits: Int,
|
addrBits: Int,
|
||||||
dataBits: Int,
|
dataBits: Int,
|
||||||
idBits: Int)
|
idBits: Int,
|
||||||
|
userBits: Int)
|
||||||
{
|
{
|
||||||
require (dataBits >= 8, s"AXI4 data bits must be >= 8 (got $dataBits)")
|
require (dataBits >= 8, s"AXI4 data bits must be >= 8 (got $dataBits)")
|
||||||
require (addrBits >= 1, s"AXI4 addr bits must be >= 1 (got $addrBits)")
|
require (addrBits >= 1, s"AXI4 addr bits must be >= 1 (got $addrBits)")
|
||||||
@ -102,19 +107,21 @@ case class AXI4BundleParameters(
|
|||||||
AXI4BundleParameters(
|
AXI4BundleParameters(
|
||||||
max(addrBits, x.addrBits),
|
max(addrBits, x.addrBits),
|
||||||
max(dataBits, x.dataBits),
|
max(dataBits, x.dataBits),
|
||||||
max(idBits, x.idBits))
|
max(idBits, x.idBits),
|
||||||
|
max(userBits, x.userBits))
|
||||||
}
|
}
|
||||||
|
|
||||||
object AXI4BundleParameters
|
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 union(x: Seq[AXI4BundleParameters]) = x.foldLeft(emptyBundleParams)((x,y) => x.union(y))
|
||||||
|
|
||||||
def apply(master: AXI4MasterPortParameters, slave: AXI4SlavePortParameters) =
|
def apply(master: AXI4MasterPortParameters, slave: AXI4SlavePortParameters) =
|
||||||
new AXI4BundleParameters(
|
new AXI4BundleParameters(
|
||||||
addrBits = log2Up(slave.maxAddress+1),
|
addrBits = log2Up(slave.maxAddress+1),
|
||||||
dataBits = slave.beatBytes * 8,
|
dataBits = slave.beatBytes * 8,
|
||||||
idBits = log2Up(master.endId))
|
idBits = log2Up(master.endId),
|
||||||
|
userBits = master.userBits)
|
||||||
}
|
}
|
||||||
|
|
||||||
case class AXI4EdgeParameters(
|
case class AXI4EdgeParameters(
|
||||||
|
@ -9,10 +9,12 @@ import diplomacy._
|
|||||||
import uncore.tilelink2._
|
import uncore.tilelink2._
|
||||||
|
|
||||||
case class AXI4ToTLNode() extends MixedAdapterNode(AXI4Imp, TLImp)(
|
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 =>
|
TLClientPortParameters(clients = masters.map { m =>
|
||||||
TLClientParameters(
|
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)
|
nodePath = m.nodePath)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user