From 56d941db5f9a2c756ebcd47addfbb923cf8aeb6e Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Thu, 21 May 2020 11:13:49 -0700 Subject: [PATCH 1/3] diplomacy: standardize IdMapEntry interface --- src/main/scala/amba/axi4/Parameters.scala | 18 +++++++++++++++++ src/main/scala/amba/axi4/ToTL.scala | 9 +++++++++ src/main/scala/diplomacy/Parameters.scala | 20 +++++++++++++++++++ src/main/scala/tilelink/Parameters.scala | 20 ++++++++----------- src/main/scala/tilelink/ToAXI4.scala | 24 ++++++++++------------- 5 files changed, 65 insertions(+), 26 deletions(-) diff --git a/src/main/scala/amba/axi4/Parameters.scala b/src/main/scala/amba/axi4/Parameters.scala index d288d8b4fd2..6cf2e22b1a5 100644 --- a/src/main/scala/amba/axi4/Parameters.scala +++ b/src/main/scala/amba/axi4/Parameters.scala @@ -173,3 +173,21 @@ case class AXI4BufferParams( def copyOut(x: BufferParams) = this.copy(aw = x, ar = x, w = x) def copyInOut(x: BufferParams) = this.copyIn(x).copyOut(x) } + +/** Pretty printing of AXI4 source id maps */ +class AXI4IdMap(axi4: AXI4MasterPortParameters) extends IdMap[AXI4IdMapEntry] { + private val axi4Digits = String.valueOf(axi4.endId-1).length() + protected val fmt = s"\t[%${axi4Digits}d, %${axi4Digits}d) %s%s%s" + private val sorted = axi4.masters.sortBy(_.id) + + val mapping: Seq[AXI4IdMapEntry] = sorted.map { case c => + AXI4IdMapEntry(c.id, c.name) + } +} + +case class AXI4IdMapEntry(axi4Id: IdRange, name: String) extends IdMapEntry { + val from = axi4Id + val to = axi4Id + val isCache = false + val requestFifo = false +} diff --git a/src/main/scala/amba/axi4/ToTL.scala b/src/main/scala/amba/axi4/ToTL.scala index 219cbeea9c6..95aad81ed66 100644 --- a/src/main/scala/amba/axi4/ToTL.scala +++ b/src/main/scala/amba/axi4/ToTL.scala @@ -9,6 +9,15 @@ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.util._ +case class AXI4ToTLIdMapEntry(tlId: IdRange, axi4Id: IdRange, name: String) + extends IdMapEntry +{ + val from = axi4Id + val to = tlId + val isCache = false + val requestFifo = false +} + case class AXI4ToTLNode(wcorrupt: Boolean)(implicit valName: ValName) extends MixedAdapterNode(AXI4Imp, TLImp)( dFn = { case mp => mp.masters.foreach { m => require (m.maxFlight.isDefined, "AXI4 must include a transaction maximum per ID to convert to TL") } diff --git a/src/main/scala/diplomacy/Parameters.scala b/src/main/scala/diplomacy/Parameters.scala index a8fdc1e2d37..97c6785fc91 100644 --- a/src/main/scala/diplomacy/Parameters.scala +++ b/src/main/scala/diplomacy/Parameters.scala @@ -322,3 +322,23 @@ trait DirectedBuffers[T] { def copyOut(x: BufferParams): T def copyInOut(x: BufferParams): T } + +trait IdMapEntry { + val name: String + val from: IdRange + val to: IdRange + val isCache: Boolean + val requestFifo: Boolean + def pretty(fmt: String) = + if (from ne to) { + fmt.format(to.start, to.end, from.start, from.end, s""""$name"""", if (isCache) " [CACHE]" else "", if (requestFifo) " [FIFO]" else "") + } else { + fmt.format(from.start, from.end, s""""$name"""", if (isCache) " [CACHE]" else "", if (requestFifo) " [FIFO]" else "") + } +} + +abstract class IdMap[T <: IdMapEntry] { + protected val fmt: String + val mapping: Seq[T] + def pretty: String = mapping.map(_.pretty(fmt)).mkString(",\n") +} diff --git a/src/main/scala/tilelink/Parameters.scala b/src/main/scala/tilelink/Parameters.scala index 276e0352303..00c41f721f1 100644 --- a/src/main/scala/tilelink/Parameters.scala +++ b/src/main/scala/tilelink/Parameters.scala @@ -1168,23 +1168,19 @@ case class TLBufferParams( } /** Pretty printing of TL source id maps */ -class TLSourceIdMap(tl: TLClientPortParameters) { +class TLSourceIdMap(tl: TLMasterPortParameters) extends IdMap[TLSourceIdMapEntry] { private val tlDigits = String.valueOf(tl.endSourceId-1).length() - private val fmt = s"\t[%${tlDigits}d, %${tlDigits}d) %s%s%s" - private val sorted = tl.clients.sortWith(TLToAXI4.sortByType) + protected val fmt = s"\t[%${tlDigits}d, %${tlDigits}d) %s%s%s" + private val sorted = tl.clients.sortBy(_.sourceId) val mapping: Seq[TLSourceIdMapEntry] = sorted.map { case c => TLSourceIdMapEntry(c.sourceId, c.name, c.supportsProbe, c.requestFifo) } - - def pretty: String = mapping.map(_.pretty(fmt)).mkString(",\n") } -case class TLSourceIdMapEntry(tlId: IdRange, name: String, isCache: Boolean, requestFifo: Boolean) { - def pretty(fmt: String): String = fmt.format( - tlId.start, - tlId.end, - s""""$name"""", - if (isCache) " [CACHE]" else "", - if (requestFifo) " [FIFO]" else "") +case class TLSourceIdMapEntry(tlId: IdRange, name: String, isCache: Boolean, requestFifo: Boolean) + extends IdMapEntry +{ + val from = tlId + val to = tlId } diff --git a/src/main/scala/tilelink/ToAXI4.scala b/src/main/scala/tilelink/ToAXI4.scala index 131e95c46bc..3948003191d 100644 --- a/src/main/scala/tilelink/ToAXI4.scala +++ b/src/main/scala/tilelink/ToAXI4.scala @@ -24,28 +24,24 @@ case class AXI4TLStateField(sourceBits: Int) extends BundleField(AXI4TLState) { } } -class TLtoAXI4IdMap(tl: TLMasterPortParameters, axi4: AXI4MasterPortParameters) { +class TLtoAXI4IdMap(tl: TLMasterPortParameters, axi4: AXI4MasterPortParameters) + extends IdMap[TLToAXI4IdMapEntry] +{ private val axiDigits = String.valueOf(axi4.endId-1).length() private val tlDigits = String.valueOf(tl.endSourceId-1).length() - private val fmt = s"\t[%${axiDigits}d, %${axiDigits}d) <= [%${tlDigits}d, %${tlDigits}d) %s%s%s" - private val sorted = tl.clients.sortWith(TLToAXI4.sortByType) + protected val fmt = s"\t[%${axiDigits}d, %${axiDigits}d) <= [%${tlDigits}d, %${tlDigits}d) %s%s%s" + private val sorted = tl.clients.sortBy(_.sourceId).sortWith(TLToAXI4.sortByType) val mapping: Seq[TLToAXI4IdMapEntry] = (sorted zip axi4.masters) map { case (c, m) => TLToAXI4IdMapEntry(m.id, c.sourceId, c.name, c.supportsProbe, c.requestFifo) } - - def pretty: String = mapping.map(_.pretty(fmt)).mkString(",\n") } -case class TLToAXI4IdMapEntry(axi4Id: IdRange, tlId: IdRange, name: String, isCache: Boolean, requestFifo: Boolean) { - def pretty(fmt: String) = fmt.format( - axi4Id.start, - axi4Id.end, - tlId.start, - tlId.end, - s"$name", - if (isCache) " [CACHE]" else "", - if (requestFifo) " [FIFO]" else "") +case class TLToAXI4IdMapEntry(axi4Id: IdRange, tlId: IdRange, name: String, isCache: Boolean, requestFifo: Boolean) + extends IdMapEntry +{ + val from = tlId + val to = axi4Id } case class TLToAXI4Node(stripBits: Int = 0, wcorrupt: Boolean = true)(implicit valName: ValName) extends MixedAdapterNode(TLImp, AXI4Imp)( From b445a736ab22149afb0c861e3a3704ba8fed9589 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Thu, 21 May 2020 12:56:01 -0700 Subject: [PATCH 2/3] axi4.IdIndexer: note unused ids rather than leaving their name blank --- src/main/scala/amba/axi4/IdIndexer.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/scala/amba/axi4/IdIndexer.scala b/src/main/scala/amba/axi4/IdIndexer.scala index d08a794d76d..e775ef5f1a6 100644 --- a/src/main/scala/amba/axi4/IdIndexer.scala +++ b/src/main/scala/amba/axi4/IdIndexer.scala @@ -37,6 +37,7 @@ class AXI4IdIndexer(idBits: Int)(implicit p: Parameters) extends LazyModule maxFlight = old.maxFlight.flatMap { o => m.maxFlight.map { n => o+n } }) } } + names.foreach { n => if (n.isEmpty) n += "" } val bits = log2Ceil(mp.endId) - idBits val field = if (bits > 0) Seq(AXI4ExtraIdField(bits)) else Nil mp.copy( From 8f4e969f5a21d46e67f99207606c1995093453c4 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Thu, 21 May 2020 14:35:09 -0700 Subject: [PATCH 3/3] IdMapEntry: address reviewer comments --- src/main/scala/diplomacy/Parameters.scala | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/scala/diplomacy/Parameters.scala b/src/main/scala/diplomacy/Parameters.scala index 97c6785fc91..95d9da21ad5 100644 --- a/src/main/scala/diplomacy/Parameters.scala +++ b/src/main/scala/diplomacy/Parameters.scala @@ -324,13 +324,13 @@ trait DirectedBuffers[T] { } trait IdMapEntry { - val name: String - val from: IdRange - val to: IdRange - val isCache: Boolean - val requestFifo: Boolean + def name: String + def from: IdRange + def to: IdRange + def isCache: Boolean + def requestFifo: Boolean def pretty(fmt: String) = - if (from ne to) { + if (from ne to) { // if the subclass uses the same reference for both from and to, assume its format string has an arity of 5 fmt.format(to.start, to.end, from.start, from.end, s""""$name"""", if (isCache) " [CACHE]" else "", if (requestFifo) " [FIFO]" else "") } else { fmt.format(from.start, from.end, s""""$name"""", if (isCache) " [CACHE]" else "", if (requestFifo) " [FIFO]" else "")