From bd045a3b95979b3c5dec7fc663671bc7c5b1f23b Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Thu, 5 Oct 2017 12:49:49 -0700 Subject: [PATCH] tilelink: split Acquire into Acquire{Block,Perm} (#1030) We had planned for a while to add an 'Overwrite' message which obtains permissions without requiring retrieval of data. This is useful whenever a master knows it will completely replace the contents of a cache block. Instead of calling it Overwrite, we decided to split the Acquire type. If you AcquirePerm, you MUST Release and ProbeAck with Data. --- src/main/scala/rocket/DCache.scala | 2 +- src/main/scala/rocket/NBDcache.scala | 2 +- src/main/scala/tilelink/Atomics.scala | 4 ++-- src/main/scala/tilelink/Broadcast.scala | 15 ++++++++------ src/main/scala/tilelink/Bundles.scala | 5 +++-- src/main/scala/tilelink/CacheCork.scala | 5 +++-- src/main/scala/tilelink/Edges.scala | 18 +++++++++++++++-- src/main/scala/tilelink/Monitor.scala | 27 +++++++++++++++++-------- src/main/scala/tilelink/RAMModel.scala | 2 +- 9 files changed, 55 insertions(+), 25 deletions(-) diff --git a/src/main/scala/rocket/DCache.scala b/src/main/scala/rocket/DCache.scala index 7f3b3b63..e3daa973 100644 --- a/src/main/scala/rocket/DCache.scala +++ b/src/main/scala/rocket/DCache.scala @@ -384,7 +384,7 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) { val a_size = mtSize(s2_req.typ) val a_data = Fill(beatWords, pstore1_data) val acquire = if (edge.manager.anySupportAcquireB) { - edge.Acquire(UInt(0), acquire_address, lgCacheBlockBytes, s2_grow_param)._2 // Cacheability checked by tlb + edge.AcquireBlock(UInt(0), acquire_address, lgCacheBlockBytes, s2_grow_param)._2 // Cacheability checked by tlb } else { Wire(new TLBundleA(edge.bundle)) } diff --git a/src/main/scala/rocket/NBDcache.scala b/src/main/scala/rocket/NBDcache.scala index 8d9899d4..cf0fa9bb 100644 --- a/src/main/scala/rocket/NBDcache.scala +++ b/src/main/scala/rocket/NBDcache.scala @@ -276,7 +276,7 @@ class MSHR(id: Int)(implicit edge: TLEdgeOut, p: Parameters) extends L1HellaCach io.wb_req.bits.voluntary := Bool(true) io.mem_acquire.valid := state === s_refill_req && grantackq.io.enq.ready - io.mem_acquire.bits := edge.Acquire( + io.mem_acquire.bits := edge.AcquireBlock( fromSource = UInt(id), toAddress = Cat(io.tag, req_idx) << blockOffBits, lgSize = lgCacheBlockBytes, diff --git a/src/main/scala/tilelink/Atomics.scala b/src/main/scala/tilelink/Atomics.scala index 5f412cc6..370817a3 100644 --- a/src/main/scala/tilelink/Atomics.scala +++ b/src/main/scala/tilelink/Atomics.scala @@ -51,8 +51,8 @@ class Atomics(params: TLBundleParameters) extends Module UInt(3), // LogicalData UInt(0), // Get UInt(0), // Hint - UInt(0), // Acquire - UInt(0)))( // Overwrite + UInt(0), // AcquireBlock + UInt(0)))( // AcquirePerm io.a.opcode)) // Only the masked bytes can be modified diff --git a/src/main/scala/tilelink/Broadcast.scala b/src/main/scala/tilelink/Broadcast.scala index 3e203a13..4681b8f3 100644 --- a/src/main/scala/tilelink/Broadcast.scala +++ b/src/main/scala/tilelink/Broadcast.scala @@ -176,6 +176,11 @@ class TLBroadcast(lineBytes: Int, numTrackers: Int = 4, bufferless: Boolean = fa t.probe := (if (caches.size == 0) UInt(0) else Mux(a_cache.orR(), UInt(caches.size-1), UInt(caches.size))) } + val acq_perms = MuxLookup(in.a.bits.param, Wire(UInt(width = 2)), Array( + TLPermissions.NtoB -> TLPermissions.toB, + TLPermissions.NtoT -> TLPermissions.toN, + TLPermissions.BtoT -> TLPermissions.toN)) + when (in.a.fire() && a_first) { probe_todo := ~a_cache // probe all but the cache who poked us probe_line := in.a.bits.address >> lineShift @@ -188,10 +193,8 @@ class TLBroadcast(lineBytes: Int, numTrackers: Int = 4, bufferless: Boolean = fa TLMessages.Hint -> MuxLookup(in.a.bits.param, Wire(UInt(width = 2)), Array( TLHints.PREFETCH_READ -> TLPermissions.toB, TLHints.PREFETCH_WRITE -> TLPermissions.toN)), - TLMessages.Acquire -> MuxLookup(in.a.bits.param, Wire(UInt(width = 2)), Array( - TLPermissions.NtoB -> TLPermissions.toB, - TLPermissions.NtoT -> TLPermissions.toN, - TLPermissions.BtoT -> TLPermissions.toN)))) + TLMessages.AcquireBlock -> acq_perms, + TLMessages.AcquirePerm -> acq_perms)) } // The outer TL connections may not be cached @@ -236,7 +239,7 @@ class TLBroadcastTracker(id: Int, lineBytes: Int, probeCountBits: Int, bufferles when (io.in_a.fire() && io.in_a_first) { assert (idle) sent_d := Bool(false) - got_e := io.in_a.bits.opcode =/= TLMessages.Acquire + got_e := io.in_a.bits.opcode =/= TLMessages.AcquireBlock && io.in_a.bits.opcode =/= TLMessages.AcquirePerm opcode := io.in_a.bits.opcode param := io.in_a.bits.param size := io.in_a.bits.size @@ -271,7 +274,7 @@ class TLBroadcastTracker(id: Int, lineBytes: Int, probeCountBits: Int, bufferles i_data.bits.data := io.in_a.bits.data val probe_done = count === UInt(0) - val acquire = opcode === TLMessages.Acquire + val acquire = opcode === TLMessages.AcquireBlock || opcode === TLMessages.AcquirePerm val transform = MuxLookup(param, Wire(UInt(width = 2)), Array( TLPermissions.NtoB -> TRANSFORM_B, diff --git a/src/main/scala/tilelink/Bundles.scala b/src/main/scala/tilelink/Bundles.scala index d58bc907..118b01e5 100644 --- a/src/main/scala/tilelink/Bundles.scala +++ b/src/main/scala/tilelink/Bundles.scala @@ -22,7 +22,8 @@ object TLMessages def LogicalData = UInt(3) // . . => AccessAckData def Get = UInt(4) // . . => AccessAckData def Hint = UInt(5) // . . => HintAck - def Acquire = UInt(6) // . => Grant[Data] + def AcquireBlock = UInt(6) // . => Grant[Data] + def AcquirePerm = UInt(7) // . => Grant[Data] def Probe = UInt(6) // . => ProbeAck[Data] def AccessAck = UInt(0) // . . def AccessAckData = UInt(1) // . . @@ -36,7 +37,7 @@ object TLMessages def ReleaseAck = UInt(6) // . def GrantAck = UInt(0) // . - def isA(x: UInt) = x <= Acquire + def isA(x: UInt) = x <= AcquirePerm def isB(x: UInt) = x <= Probe def isC(x: UInt) = x <= ReleaseData def isD(x: UInt) = x <= ReleaseAck diff --git a/src/main/scala/tilelink/CacheCork.scala b/src/main/scala/tilelink/CacheCork.scala index de52286f..063c58a4 100644 --- a/src/main/scala/tilelink/CacheCork.scala +++ b/src/main/scala/tilelink/CacheCork.scala @@ -47,7 +47,8 @@ class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyM val a_a = Wire(out.a) val a_d = Wire(in.d) val isPut = in.a.bits.opcode === PutFullData || in.a.bits.opcode === PutPartialData - val toD = in.a.bits.opcode === Acquire && in.a.bits.param === TLPermissions.BtoT + val toD = (in.a.bits.opcode === AcquireBlock && in.a.bits.param === TLPermissions.BtoT) || + (in.a.bits.opcode === AcquirePerm) in.a.ready := Mux(toD, a_d.ready, a_a.ready) a_a.valid := in.a.valid && !toD @@ -55,7 +56,7 @@ class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyM a_a.bits.source := in.a.bits.source << 1 | Mux(isPut, UInt(1), UInt(0)) // Transform Acquire into Get - when (in.a.bits.opcode === Acquire) { + when (in.a.bits.opcode === AcquireBlock || in.a.bits.opcode === AcquirePerm) { a_a.bits.opcode := Get a_a.bits.param := UInt(0) a_a.bits.source := in.a.bits.source << 1 | UInt(1) diff --git a/src/main/scala/tilelink/Edges.scala b/src/main/scala/tilelink/Edges.scala index 55c21711..4f59c9a3 100644 --- a/src/main/scala/tilelink/Edges.scala +++ b/src/main/scala/tilelink/Edges.scala @@ -271,11 +271,25 @@ class TLEdgeOut( extends TLEdge(client, manager, params, sourceInfo) { // Transfers - def Acquire(fromSource: UInt, toAddress: UInt, lgSize: UInt, growPermissions: UInt) = { + def AcquireBlock(fromSource: UInt, toAddress: UInt, lgSize: UInt, growPermissions: UInt) = { require (manager.anySupportAcquireB) val legal = manager.supportsAcquireBFast(toAddress, lgSize) val a = Wire(new TLBundleA(bundle)) - a.opcode := TLMessages.Acquire + a.opcode := TLMessages.AcquireBlock + a.param := growPermissions + a.size := lgSize + a.source := fromSource + a.address := toAddress + a.mask := mask(toAddress, lgSize) + a.data := UInt(0) + (legal, a) + } + + def AcquirePerm(fromSource: UInt, toAddress: UInt, lgSize: UInt, growPermissions: UInt) = { + require (manager.anySupportAcquireB) + val legal = manager.supportsAcquireBFast(toAddress, lgSize) + val a = Wire(new TLBundleA(bundle)) + a.opcode := TLMessages.AcquirePerm a.param := growPermissions a.size := lgSize a.source := fromSource diff --git a/src/main/scala/tilelink/Monitor.scala b/src/main/scala/tilelink/Monitor.scala index 11ddd0ec..9b258684 100644 --- a/src/main/scala/tilelink/Monitor.scala +++ b/src/main/scala/tilelink/Monitor.scala @@ -37,14 +37,25 @@ class TLMonitor(args: TLMonitorArgs) extends TLMonitorBase(args) val is_aligned = edge.isAligned(bundle.address, bundle.size) val mask = edge.full_mask(bundle) - when (bundle.opcode === TLMessages.Acquire) { - assert (edge.manager.supportsAcquireBSafe(edge.address(bundle), bundle.size), "'A' channel carries Acquire type unsupported by manager" + extra) - assert (edge.client.supportsProbe(edge.source(bundle), bundle.size), "'A' channel carries Acquire from a client which does not support Probe" + extra) - assert (source_ok, "'A' channel Acquire carries invalid source ID" + extra) - assert (bundle.size >= UInt(log2Ceil(edge.manager.beatBytes)), "'A' channel Acquire smaller than a beat" + extra) - assert (is_aligned, "'A' channel Acquire address not aligned to size" + extra) - assert (TLPermissions.isGrow(bundle.param), "'A' channel Acquire carries invalid grow param" + extra) - assert (~bundle.mask === UInt(0), "'A' channel Acquire contains invalid mask" + extra) + when (bundle.opcode === TLMessages.AcquireBlock) { + assert (edge.manager.supportsAcquireBSafe(edge.address(bundle), bundle.size), "'A' channel carries AcquireBlock type unsupported by manager" + extra) + assert (edge.client.supportsProbe(edge.source(bundle), bundle.size), "'A' channel carries AcquireBlock from a client which does not support Probe" + extra) + assert (source_ok, "'A' channel AcquireBlock carries invalid source ID" + extra) + assert (bundle.size >= UInt(log2Ceil(edge.manager.beatBytes)), "'A' channel AcquireBlock smaller than a beat" + extra) + assert (is_aligned, "'A' channel AcquireBlock address not aligned to size" + extra) + assert (TLPermissions.isGrow(bundle.param), "'A' channel AcquireBlock carries invalid grow param" + extra) + assert (~bundle.mask === UInt(0), "'A' channel AcquireBlock contains invalid mask" + extra) + } + + when (bundle.opcode === TLMessages.AcquirePerm) { + assert (edge.manager.supportsAcquireBSafe(edge.address(bundle), bundle.size), "'A' channel carries AcquirePerm type unsupported by manager" + extra) + assert (edge.client.supportsProbe(edge.source(bundle), bundle.size), "'A' channel carries AcquirePerm from a client which does not support Probe" + extra) + assert (source_ok, "'A' channel AcquirePerm carries invalid source ID" + extra) + assert (bundle.size >= UInt(log2Ceil(edge.manager.beatBytes)), "'A' channel AcquirePerm smaller than a beat" + extra) + assert (is_aligned, "'A' channel AcquirePerm address not aligned to size" + extra) + assert (TLPermissions.isGrow(bundle.param), "'A' channel AcquirePerm carries invalid grow param" + extra) + assert (bundle.param =/= TLPermissions.NtoB, "'A' channel AcquirePerm requests NtoB" + extra) + assert (~bundle.mask === UInt(0), "'A' channel AcquirePerm contains invalid mask" + extra) } when (bundle.opcode === TLMessages.Get) { diff --git a/src/main/scala/tilelink/RAMModel.scala b/src/main/scala/tilelink/RAMModel.scala index c121c002..21c5cf14 100644 --- a/src/main/scala/tilelink/RAMModel.scala +++ b/src/main/scala/tilelink/RAMModel.scala @@ -116,7 +116,7 @@ class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule when (a_fire) { // Record the request so we can handle it's response - assert (a.opcode =/= TLMessages.Acquire) + assert (a.opcode =/= TLMessages.AcquireBlock && a.opcode =/= TLMessages.AcquirePerm) // Mark the operation as valid valid(a.source) := Bool(true)