From d765a980211f0fe830f2d97cf6fa59692d60d6c6 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 13 Mar 2020 18:37:35 -0700 Subject: [PATCH 1/9] tilelink: retain userFields when copying diplomatic parameters This got messed up when the original branch was merged with the TileLink parameters refactor. --- src/main/scala/tilelink/Parameters.scala | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/scala/tilelink/Parameters.scala b/src/main/scala/tilelink/Parameters.scala index 27bdf585e8..606128748b 100644 --- a/src/main/scala/tilelink/Parameters.scala +++ b/src/main/scala/tilelink/Parameters.scala @@ -582,8 +582,8 @@ class TLSlavePortParameters private( beatBytes: Int = -1, endSinkId: Int = endSinkId, minLatency: Int = minLatency, - responseFields: Seq[BundleFieldBase] = Nil, - requestKeys: Seq[BundleKeyBase] = Nil) = + responseFields: Seq[BundleFieldBase] = responseFields, + requestKeys: Seq[BundleKeyBase] = requestKeys) = { new TLSlavePortParameters( slaves = managers, @@ -599,8 +599,8 @@ class TLSlavePortParameters private( beatBytes: Int = -1, endSinkId: Int = endSinkId, minLatency: Int = minLatency, - responseFields: Seq[BundleFieldBase] = Nil, - requestKeys: Seq[BundleKeyBase] = Nil) = + responseFields: Seq[BundleFieldBase] = responseFields, + requestKeys: Seq[BundleKeyBase] = requestKeys) = { v1copy( managers, @@ -944,9 +944,9 @@ class TLMasterPortParameters private( def v1copy( clients: Seq[TLClientParameters] = masters, minLatency: Int = minLatency, - echoFields: Seq[BundleFieldBase] = Nil, - requestFields: Seq[BundleFieldBase] = Nil, - responseKeys: Seq[BundleKeyBase] = Nil) = + echoFields: Seq[BundleFieldBase] = echoFields, + requestFields: Seq[BundleFieldBase] = requestFields, + responseKeys: Seq[BundleKeyBase] = responseKeys) = { new TLMasterPortParameters( masters = clients, @@ -961,9 +961,9 @@ class TLMasterPortParameters private( def copy( clients: Seq[TLClientParameters] = masters, minLatency: Int = minLatency, - echoFields: Seq[BundleFieldBase] = Nil, - requestFields: Seq[BundleFieldBase] = Nil, - responseKeys: Seq[BundleKeyBase] = Nil) = + echoFields: Seq[BundleFieldBase] = echoFields, + requestFields: Seq[BundleFieldBase] = requestFields, + responseKeys: Seq[BundleKeyBase] = responseKeys) = { v1copy( clients, From acc0a80abd0edb4503e9e966247b1a6c99295f31 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 13 Mar 2020 18:38:47 -0700 Subject: [PATCH 2/9] TLToAHB: correctly drive prot bits --- src/main/scala/tilelink/ToAHB.scala | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/scala/tilelink/ToAHB.scala b/src/main/scala/tilelink/ToAHB.scala index ad52f2d84a..93255a2690 100644 --- a/src/main/scala/tilelink/ToAHB.scala +++ b/src/main/scala/tilelink/ToAHB.scala @@ -188,10 +188,12 @@ class TLToAHB(val aFlow: Boolean = false, val supportHints: Boolean = true, val // Set prot bits if we have extra meta-data send.hauser.lift(AMBAProt).foreach { x => - out.hprot(0) := !x.fetch - out.hprot(1) := x.privileged - out.hprot(2) := x.bufferable - out.hprot(3) := x.cacheable + val hprot = Wire(Vec(4, Bool())) + hprot(0) := !x.fetch + hprot(1) := x.privileged + hprot(2) := x.bufferable + hprot(3) := x.cacheable + out.hprot := Cat(hprot.reverse) } // We need a skidpad to capture D output: From 441f980dffc11d2265fea4915a1de6e5502a1472 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 13 Mar 2020 18:39:04 -0700 Subject: [PATCH 3/9] TLToAPB: correctly drive prot bits --- src/main/scala/tilelink/ToAPB.scala | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/scala/tilelink/ToAPB.scala b/src/main/scala/tilelink/ToAPB.scala index c423dc9e22..dbe5c4e4db 100644 --- a/src/main/scala/tilelink/ToAPB.scala +++ b/src/main/scala/tilelink/ToAPB.scala @@ -90,9 +90,11 @@ class TLToAPB(val aFlow: Boolean = true)(implicit p: Parameters) extends LazyMod out.pstrb := Mux(a_write, a.bits.mask, UInt(0)) out.pauser :<= a.bits.user a.bits.user.lift(AMBAProt).foreach { x => - out.pprot(0) := x.privileged - out.pprot(1) := !x.secure - out.pprot(2) := x.fetch + val pprot = Wire(Vec(3, Bool())) + pprot(0) := x.privileged + pprot(1) := !x.secure + pprot(2) := x.fetch + out.pprot := Cat(pprot.reverse) } a.ready := a_enable && out.pready From 14f3a545324a845f48c32c1607b92bfd43a38e2e Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 13 Mar 2020 18:39:12 -0700 Subject: [PATCH 4/9] TLToAXI4: correctly drive prot+cache bits --- src/main/scala/tilelink/ToAXI4.scala | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/scala/tilelink/ToAXI4.scala b/src/main/scala/tilelink/ToAXI4.scala index 41a21a1b39..dd9ba97e08 100644 --- a/src/main/scala/tilelink/ToAXI4.scala +++ b/src/main/scala/tilelink/ToAXI4.scala @@ -182,13 +182,17 @@ class TLToAXI4(val combinational: Boolean = true, val adapterName: Option[String a_extra.size := a_size in.a.bits.user.lift(AMBAProt).foreach { x => - arw.prot(0) := x.privileged - arw.prot(1) := !x.secure - arw.prot(2) := x.fetch - arw.cache(0) := x.bufferable - arw.cache(1) := x.modifiable - arw.cache(2) := x.cacheable - arw.cache(3) := x.cacheable + val prot = Wire(Vec(3, Bool())) + val cache = Wire(Vec(4, Bool())) + prot(0) := x.privileged + prot(1) := !x.secure + prot(2) := x.fetch + cache(0) := x.bufferable + cache(1) := x.modifiable + cache(2) := x.cacheable + cache(3) := x.cacheable + arw.prot := Cat(prot.reverse) + arw.cache := Cat(cache.reverse) } val stall = sourceStall(in.a.bits.source) && a_first From e56ad0e20893cd6e880d5444697061b084905838 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 13 Mar 2020 18:33:45 -0700 Subject: [PATCH 5/9] BundleMap: enhance with field subset and partial assignment --- src/main/scala/util/BundleMap.scala | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/main/scala/util/BundleMap.scala b/src/main/scala/util/BundleMap.scala index 79ea54892a..0e07805b50 100644 --- a/src/main/scala/util/BundleMap.scala +++ b/src/main/scala/util/BundleMap.scala @@ -119,12 +119,22 @@ class BundleMap(val fields: Seq[BundleFieldBase]) extends Record with CustomBulk } } + // A BundleMap is best viewed as a map from BundleKey to Data + def keydata: Seq[(BundleKeyBase, Data)] = (fields zip elements) map { case (field, (_, data)) => (field.key, data) } + def apply[T <: Data](key: BundleKey[T]): T = elements(key.name).asInstanceOf[T] def lift [T <: Data](key: BundleKey[T]): Option[T] = elements.lift(key.name).map(_.asInstanceOf[T]) def apply(key: BundleKeyBase): Data = elements(key.name) def lift (key: BundleKeyBase): Option[Data] = elements.lift(key.name) + // Create a new BundleMap with only the selected Keys retained + def subset(fn: BundleKeyBase => Boolean): BundleMap = { + val out = Wire(BundleMap(fields.filter(x => fn(x.key)))) + out :<= this + out + } + // Assign all outputs of this from either: // outputs of that (if they exist) // or the default value for the BundleField @@ -166,6 +176,22 @@ class BundleMap(val fields: Seq[BundleFieldBase]) extends Record with CustomBulk } // it's ok to have excess elements in 'hx' } + + // Assign only those outputs of this which exist as outputs in that + def partialAssignL(that: BundleMap): Unit = { + val h = HashMap(that.keydata:_*) + keydata foreach { case (key, vx) => + h.lift(key).foreach { vy => FixChisel3.descendL(vx, vy) } + } + } + + // Assign only those inputs of that which exist as inputs in this + def partialAssignR(that: BundleMap): Unit = { + val h = HashMap(keydata:_*) + that.keydata foreach { case (key, vy) => + h.lift(key).foreach { vx => FixChisel3.descendL(vx, vy) } + } + } } object BundleMap { From 3a86e4dccd6e5474b218c7e6dc164aab42a996dd Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 13 Mar 2020 18:34:45 -0700 Subject: [PATCH 6/9] echoFields: only control fields are legal --- src/main/scala/amba/axi4/Parameters.scala | 1 + src/main/scala/tilelink/Parameters.scala | 1 + 2 files changed, 2 insertions(+) diff --git a/src/main/scala/amba/axi4/Parameters.scala b/src/main/scala/amba/axi4/Parameters.scala index 0b78dd2e1f..d288d8b4fd 100644 --- a/src/main/scala/amba/axi4/Parameters.scala +++ b/src/main/scala/amba/axi4/Parameters.scala @@ -107,6 +107,7 @@ case class AXI4BundleParameters( require (addrBits >= 1, s"AXI4 addr bits must be >= 1 (got $addrBits)") require (idBits >= 1, s"AXI4 id bits must be >= 1 (got $idBits)") require (isPow2(dataBits), s"AXI4 data bits must be pow2 (got $dataBits)") + echoFields.foreach { f => require (f.key.isControl, s"${f} is not a legal echo field") } // Bring the globals into scope val lenBits = AXI4Parameters.lenBits diff --git a/src/main/scala/tilelink/Parameters.scala b/src/main/scala/tilelink/Parameters.scala index 606128748b..24129881fc 100644 --- a/src/main/scala/tilelink/Parameters.scala +++ b/src/main/scala/tilelink/Parameters.scala @@ -1028,6 +1028,7 @@ case class TLBundleParameters( require (sinkBits >= 1) require (sizeBits >= 1) require (isPow2(dataBits)) + echoFields.foreach { f => require (f.key.isControl, s"${f} is not a legal echo field") } val addrLoBits = log2Up(dataBits/8) From 1cb87ecc25064a372881122ecde389682eeda19c Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 13 Mar 2020 18:35:30 -0700 Subject: [PATCH 7/9] Fragmenter: save some flops --- src/main/scala/tilelink/Fragmenter.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/scala/tilelink/Fragmenter.scala b/src/main/scala/tilelink/Fragmenter.scala index 0aacc6b376..f2677db631 100644 --- a/src/main/scala/tilelink/Fragmenter.scala +++ b/src/main/scala/tilelink/Fragmenter.scala @@ -302,6 +302,7 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean = val fullMask = UInt((BigInt(1) << beatBytes) - 1) assert (!repeater.io.full || in_a.bits.mask === fullMask) out.a.bits.mask := Mux(repeater.io.full, fullMask, in.a.bits.mask) + out.a.bits.user.partialAssignL(in.a.bits.user.subset(_.isData)) // Tie off unused channels in.b.valid := Bool(false) From 33e9ad431047a23e2e13eb099a12cfa30f11715f Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 13 Mar 2020 18:36:04 -0700 Subject: [PATCH 8/9] HintHandler: connect user/echo bits --- src/main/scala/tilelink/HintHandler.scala | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/scala/tilelink/HintHandler.scala b/src/main/scala/tilelink/HintHandler.scala index a0839defce..b036a79908 100644 --- a/src/main/scala/tilelink/HintHandler.scala +++ b/src/main/scala/tilelink/HintHandler.scala @@ -6,7 +6,7 @@ import chisel3._ import chisel3.util._ import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ -import freechips.rocketchip.util.Repeater +import freechips.rocketchip.util._ import freechips.rocketchip.devices.tilelink.TLROM import scala.math.min @@ -56,11 +56,8 @@ class TLHintHandler(passthrough: Boolean = true)(implicit p: Parameters) extends val mux = Wire(chiselTypeOf(in.a)) repeater.io.repeat := mapPP && !edgeIn.last(out.a) - repeater.io.enq <> in.a - // Work-around broken chisel3 <> - out.a.bits := mux.bits - out.a.valid := mux.valid - mux.ready := out.a.ready + repeater.io.enq :<> in.a + out.a :<> mux // Only some signals need to be repeated mux.bits.opcode := in.a.bits.opcode // ignored when full @@ -72,6 +69,11 @@ class TLHintHandler(passthrough: Boolean = true)(implicit p: Parameters) extends mux.bits.mask := in.a.bits.mask // ignored when full mux.bits.corrupt := in.a.bits.corrupt // irrelevant when full (mask = 0) + // Hints have no data fields; use defaults for those + mux.bits.user :<= in.a.bits.user + mux.bits.user.partialAssignL(repeater.io.deq.bits.user.subset(_.isControl)) + mux.bits.echo :<= repeater.io.deq.bits.echo // control only + mux.valid := repeater.io.deq.valid repeater.io.deq.ready := mux.ready From b684c1f185ecc2c85bb19d8c39018477776422e1 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 13 Mar 2020 21:09:31 -0700 Subject: [PATCH 9/9] AXI4ToTL: fix echo bits parameterization --- src/main/scala/amba/axi4/ToTL.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/amba/axi4/ToTL.scala b/src/main/scala/amba/axi4/ToTL.scala index ea40259088..ed714854a0 100644 --- a/src/main/scala/amba/axi4/ToTL.scala +++ b/src/main/scala/amba/axi4/ToTL.scala @@ -22,7 +22,7 @@ case class AXI4ToTLNode(wcorrupt: Boolean)(implicit valName: ValName) extends Mi nodePath = m.nodePath, requestFifo = true) }, - echoFields = mp.requestFields, + echoFields = mp.echoFields, requestFields = AMBAProtField() +: mp.requestFields, responseKeys = mp.responseKeys) },