From 1cd85ff0507f06743f12019447105611dbaad566 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 23 Aug 2016 16:23:35 -0700 Subject: [PATCH] tilelink2: add some bundle introspection to scaffold the xbar --- uncore/src/main/scala/tilelink2/Bundles.scala | 112 +++++++++++++++--- .../src/main/scala/tilelink2/Operations.scala | 47 +++++++- .../src/main/scala/tilelink2/Parameters.scala | 39 ++---- 3 files changed, 147 insertions(+), 51 deletions(-) diff --git a/uncore/src/main/scala/tilelink2/Bundles.scala b/uncore/src/main/scala/tilelink2/Bundles.scala index 503a685b..9cc724e1 100644 --- a/uncore/src/main/scala/tilelink2/Bundles.scala +++ b/uncore/src/main/scala/tilelink2/Bundles.scala @@ -19,28 +19,32 @@ abstract class TLBundleBase(val params: TLBundleParameters) extends Bundle } } +// common combos in lazy policy: +// Put + Acquire +// Release + AccessAck + object TLMessages { // A B C D E - val Get = UInt(0) // . . - val PutFullData = UInt(1) // . . - val PutPartialData = UInt(2) // . . - val ArithmeticData = UInt(3) // . . - val LogicalData = UInt(4) // . . + val PutFullData = UInt(0) // . . + val PutPartialData = UInt(1) // . . + val ArithmeticData = UInt(2) // . . + val LogicalData = UInt(3) // . . + val Get = UInt(4) // . . val Hint = UInt(5) // . . val AccessAck = UInt(0) // . . val AccessAckData = UInt(1) // . . - val AccessAckError = UInt(2) // . . + val AccessAckError = UInt(6) // . . val Acquire = UInt(6) // . val Probe = UInt(6) // . - val ProbeAck = UInt(3) // . - val ProbeAckData = UInt(4) // . - val Release = UInt(5) // . - val ReleaseData = UInt(6) // . -//val PutThroughData = UInt(7) // . // future extension - val ReleaseAck = UInt(3) // . - val Grant = UInt(4) // . - val GrantData = UInt(5) // . + val ProbeAck = UInt(2) // . + val ProbeAckData = UInt(3) // . + val Release = UInt(4) // . + val ReleaseData = UInt(5) // . +//val PutThroughData = UInt(7) // . // future extension ? + val Grant = UInt(2) // . + val GrantData = UInt(3) // . + val ReleaseAck = UInt(4) // . val GrantAck = UInt(0) // . def isA(x: UInt) = x <= Acquire @@ -85,7 +89,28 @@ object TLAtomics def isLogical(x: UInt) = Bool(true) } -class TLBundleA(params: TLBundleParameters) extends TLBundleBase(params) +trait HasTLOpcode +{ + // The data field in this message has value + def hasData(x: Int=0): Bool + // This message requires a response + def hasFollowUp(x: Int=0): Bool + // The size field of the opcode + def size(x: Int=0): UInt +} + +trait HasTLData extends HasTLOpcode +{ + def data(x: Int=0): UInt + def wmask(x: Int=0): UInt +} + +// !!! trait HasTLSource|Sink|Address +// !!! trait param: from and to perms + +class TLBundleA(params: TLBundleParameters) + extends TLBundleBase(params) + with HasTLData { val opcode = UInt(width = 3) val param = UInt(width = 3) // amo_opcode || perms || hint @@ -94,9 +119,21 @@ class TLBundleA(params: TLBundleParameters) extends TLBundleBase(params) val address = UInt(width = params.addressBits) // to val wmask = UInt(width = params.dataBits/8) val data = UInt(width = params.dataBits) + + def hasData(x: Int=0) = !opcode(2) +// opcode === TLMessages.PutFullData || +// opcode === TLMessages.PutPartialData || +// opcode === TLMessages.ArithmeticData || +// opcode === TLMessages.LogicalData + def hasFollowUp(x: Int=0) = Bool(true) + def size(x: Int=0) = size + def data(x: Int=0) = data + def wmask(x: Int=0) = wmask } -class TLBundleB(params: TLBundleParameters) extends TLBundleBase(params) +class TLBundleB(params: TLBundleParameters) + extends TLBundleBase(params) + with HasTLData { val opcode = UInt(width = 3) val param = UInt(width = 3) @@ -105,9 +142,17 @@ class TLBundleB(params: TLBundleParameters) extends TLBundleBase(params) val address = UInt(width = params.addressBits) // from val wmask = UInt(width = params.dataBits/8) val data = UInt(width = params.dataBits) + + def hasData(x: Int=0) = !opcode(2) + def hasFollowUp(x: Int=0) = Bool(true) + def size(x: Int=0) = size + def data(x: Int=0) = data + def wmask(x: Int=0) = wmask } -class TLBundleC(params: TLBundleParameters) extends TLBundleBase(params) +class TLBundleC(params: TLBundleParameters) + extends TLBundleBase(params) + with HasTLData { val opcode = UInt(width = 3) val param = UInt(width = 3) @@ -115,9 +160,22 @@ class TLBundleC(params: TLBundleParameters) extends TLBundleBase(params) val source = UInt(width = params.sourceBits) // from val address = UInt(width = params.addressBits) // to val data = UInt(width = params.dataBits) + + def hasData(x: Int=0) = opcode(0) +// opcode === TLMessages.AccessAckData || +// opcode === TLMessages.ProbeAckData || +// opcode === TLMessages.ReleaseData + def hasFollowUp(x: Int=0) = opcode(2) && !opcode(1) +// opcode === TLMessages.Release || +// opcode === TLMessages.ReleaseData + def size(x: Int=0) = size + def data(x: Int=0) = data + def wmask(x: Int=0) = SInt(-1, width = params.dataBits/8).asUInt } -class TLBundleD(params: TLBundleParameters) extends TLBundleBase(params) +class TLBundleD(params: TLBundleParameters) + extends TLBundleBase(params) + with HasTLData { val opcode = UInt(width = 3) val param = UInt(width = 2) @@ -125,11 +183,27 @@ class TLBundleD(params: TLBundleParameters) extends TLBundleBase(params) val source = UInt(width = params.sourceBits) // to val sink = UInt(width = params.sinkBits) // from val data = UInt(width = params.dataBits) + + def hasData(x: Int=0) = opcode(0) +// opcode === TLMessages.AccessAckData || +// opcode === TLMessages.GrantData + def hasFollowUp(x: Int=0) = !opcode(2) && opcode(1) +// opcode === TLMessages.Grant || +// opcode === TLMessages.GrantData + def size(x: Int=0) = size + def data(x: Int=0) = data + def wmask(x: Int=0) = SInt(-1, width = params.dataBits/8).asUInt } -class TLBundleE(params: TLBundleParameters) extends TLBundleBase(params) +class TLBundleE(params: TLBundleParameters) + extends TLBundleBase(params) + with HasTLOpcode { val sink = UInt(width = params.sourceBits) // to + + def hasData(x: Int=0) = Bool(false) + def hasFollowUp(x: Int=0) = Bool(false) + def size(x: Int=0) = UInt(log2Up(params.dataBits/8)) } class TLBundle(params: TLBundleParameters) extends TLBundleBase(params) diff --git a/uncore/src/main/scala/tilelink2/Operations.scala b/uncore/src/main/scala/tilelink2/Operations.scala index 476421a1..af956178 100644 --- a/uncore/src/main/scala/tilelink2/Operations.scala +++ b/uncore/src/main/scala/tilelink2/Operations.scala @@ -4,10 +4,53 @@ package uncore.tilelink2 import Chisel._ -class TLEdgeOut( +class TLEdge( client: TLClientPortParameters, manager: TLManagerPortParameters) extends TLEdgeParameters(client, manager) +{ + def isAligned(address: UInt, lgSize: UInt) = + if (maxLgSize == 0) Bool(true) else { + val mask = Vec.tabulate(maxLgSize) { UInt(_) < lgSize } + (address & mask.toBits.asUInt) === UInt(0) + } + + // This gets used everywhere, so make the smallest circuit possible ... + def fullMask(address: UInt, lgSize: UInt) = { + val lgBytes = log2Ceil(manager.beatBytes) + def helper(i: Int): Seq[(Bool, Bool)] = { + if (i == 0) { + Seq((lgSize >= UInt(lgBytes), Bool(true))) + } else { + val sub = helper(i-1) + val size = lgSize === UInt(lgBytes - i) + val bit = address(lgBytes - i) + val nbit = !bit + Seq.tabulate (1 << i) { j => + val (sub_acc, sub_eq) = sub(j/2) + val eq = sub_eq && (if (j % 2 == 1) bit else nbit) + val acc = sub_acc || (size && eq) + (acc, eq) + } + } + } + Vec(helper(lgBytes).map(_._1)).toBits.asUInt + } + + def numBeats(bundle: HasTLOpcode) = { + val hasData = bundle.hasData() + val size = bundle.size() + val cutoff = log2Ceil(manager.beatBytes) + val small = size <= UInt(cutoff) + val decode = Vec.tabulate (1+maxLgSize-cutoff) { i => UInt(i + cutoff) === size } + Mux(!hasData || small, UInt(1), decode) + } +} + +class TLEdgeOut( + client: TLClientPortParameters, + manager: TLManagerPortParameters) + extends TLEdge(client, manager) { // Transfers def Acquire(fromSource: UInt, toAddress: UInt, lgSize: UInt, growPermissions: UInt) = { @@ -200,7 +243,7 @@ class TLEdgeOut( class TLEdgeIn( client: TLClientPortParameters, manager: TLManagerPortParameters) - extends TLEdgeParameters(client, manager) + extends TLEdge(client, manager) { // Transfers def Probe(fromAddress: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt) = { diff --git a/uncore/src/main/scala/tilelink2/Parameters.scala b/uncore/src/main/scala/tilelink2/Parameters.scala index addc2991..cef5190a 100644 --- a/uncore/src/main/scala/tilelink2/Parameters.scala +++ b/uncore/src/main/scala/tilelink2/Parameters.scala @@ -31,7 +31,11 @@ case class IdRange(start: Int, end: Int) // contains => overlaps (because empty is forbidden) def contains(x: Int) = start <= x && x < end - def contains(x: UInt) = UInt(start) <= x && x < UInt(end) // !!! special-case = + def contains(x: UInt) = + if (start+1 == end) { UInt(start) === x } + else if (((end-1) & ~start) == end-start-1) + { ((UInt(start) ^ x) & ~UInt(end-start-1)) === UInt(0) } + else { UInt(start) <= x && x < UInt(end) } def shift(x: Int) = IdRange(start+x, end+x) } @@ -49,7 +53,10 @@ case class TransferSizes(min: Int, max: Int) def none = min == 0 def contains(x: Int) = isPow2(x) && min <= x && x <= max def containsLg(x: Int) = contains(1 << x) - def containsLg(x: UInt) = if (none) Bool(false) else { UInt(log2Ceil(min)) <= x && x <= UInt(log2Ceil(max)) } // !!! special-case = + def containsLg(x: UInt) = + if (none) Bool(false) + else if (min == max) { UInt(log2Ceil(min)) === x } + else { UInt(log2Ceil(min)) <= x && x <= UInt(log2Ceil(max)) } def contains(x: TransferSizes) = x.none || (min <= x.min && x.max <= max) @@ -299,32 +306,4 @@ case class TLEdgeParameters( sourceBits = log2Up(client.endSourceId), sinkBits = log2Up(manager.endSinkId), sizeBits = log2Up(maxLgSize+1)) - - def isAligned(address: UInt, lgSize: UInt) = - if (maxLgSize == 0) Bool(true) else { - val mask = Vec.tabulate(maxLgSize) { UInt(_) < lgSize } - (address & mask.toBits.asUInt) === UInt(0) - } - - // This gets used everywhere, so make the smallest circuit possible ... - def fullMask(address: UInt, lgSize: UInt) = { - val lgBytes = log2Ceil(manager.beatBytes) - def helper(i: Int): Seq[(Bool, Bool)] = { - if (i == 0) { - Seq((lgSize >= UInt(lgBytes), Bool(true))) - } else { - val sub = helper(i-1) - val size = lgSize === UInt(lgBytes - i) - val bit = address(lgBytes - i) - val nbit = !bit - Seq.tabulate (1 << i) { j => - val (sub_acc, sub_eq) = sub(j/2) - val eq = sub_eq && (if (j % 2 == 1) bit else nbit) - val acc = sub_acc || (size && eq) - (acc, eq) - } - } - } - Vec(helper(lgBytes).map(_._1)).toBits.asUInt - } }