tilelink2: add some bundle introspection to scaffold the xbar
This commit is contained in:
parent
9c62f5d9c1
commit
1cd85ff050
@ -19,28 +19,32 @@ abstract class TLBundleBase(val params: TLBundleParameters) extends Bundle
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// common combos in lazy policy:
|
||||||
|
// Put + Acquire
|
||||||
|
// Release + AccessAck
|
||||||
|
|
||||||
object TLMessages
|
object TLMessages
|
||||||
{
|
{
|
||||||
// A B C D E
|
// A B C D E
|
||||||
val Get = UInt(0) // . .
|
val PutFullData = UInt(0) // . .
|
||||||
val PutFullData = UInt(1) // . .
|
val PutPartialData = UInt(1) // . .
|
||||||
val PutPartialData = UInt(2) // . .
|
val ArithmeticData = UInt(2) // . .
|
||||||
val ArithmeticData = UInt(3) // . .
|
val LogicalData = UInt(3) // . .
|
||||||
val LogicalData = UInt(4) // . .
|
val Get = UInt(4) // . .
|
||||||
val Hint = UInt(5) // . .
|
val Hint = UInt(5) // . .
|
||||||
val AccessAck = UInt(0) // . .
|
val AccessAck = UInt(0) // . .
|
||||||
val AccessAckData = UInt(1) // . .
|
val AccessAckData = UInt(1) // . .
|
||||||
val AccessAckError = UInt(2) // . .
|
val AccessAckError = UInt(6) // . .
|
||||||
val Acquire = UInt(6) // .
|
val Acquire = UInt(6) // .
|
||||||
val Probe = UInt(6) // .
|
val Probe = UInt(6) // .
|
||||||
val ProbeAck = UInt(3) // .
|
val ProbeAck = UInt(2) // .
|
||||||
val ProbeAckData = UInt(4) // .
|
val ProbeAckData = UInt(3) // .
|
||||||
val Release = UInt(5) // .
|
val Release = UInt(4) // .
|
||||||
val ReleaseData = UInt(6) // .
|
val ReleaseData = UInt(5) // .
|
||||||
//val PutThroughData = UInt(7) // . // future extension
|
//val PutThroughData = UInt(7) // . // future extension ?
|
||||||
val ReleaseAck = UInt(3) // .
|
val Grant = UInt(2) // .
|
||||||
val Grant = UInt(4) // .
|
val GrantData = UInt(3) // .
|
||||||
val GrantData = UInt(5) // .
|
val ReleaseAck = UInt(4) // .
|
||||||
val GrantAck = UInt(0) // .
|
val GrantAck = UInt(0) // .
|
||||||
|
|
||||||
def isA(x: UInt) = x <= Acquire
|
def isA(x: UInt) = x <= Acquire
|
||||||
@ -85,7 +89,28 @@ object TLAtomics
|
|||||||
def isLogical(x: UInt) = Bool(true)
|
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 opcode = UInt(width = 3)
|
||||||
val param = UInt(width = 3) // amo_opcode || perms || hint
|
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 address = UInt(width = params.addressBits) // to
|
||||||
val wmask = UInt(width = params.dataBits/8)
|
val wmask = UInt(width = params.dataBits/8)
|
||||||
val data = UInt(width = params.dataBits)
|
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 opcode = UInt(width = 3)
|
||||||
val param = 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 address = UInt(width = params.addressBits) // from
|
||||||
val wmask = UInt(width = params.dataBits/8)
|
val wmask = UInt(width = params.dataBits/8)
|
||||||
val data = UInt(width = params.dataBits)
|
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 opcode = UInt(width = 3)
|
||||||
val param = 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 source = UInt(width = params.sourceBits) // from
|
||||||
val address = UInt(width = params.addressBits) // to
|
val address = UInt(width = params.addressBits) // to
|
||||||
val data = UInt(width = params.dataBits)
|
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 opcode = UInt(width = 3)
|
||||||
val param = UInt(width = 2)
|
val param = UInt(width = 2)
|
||||||
@ -125,11 +183,27 @@ class TLBundleD(params: TLBundleParameters) extends TLBundleBase(params)
|
|||||||
val source = UInt(width = params.sourceBits) // to
|
val source = UInt(width = params.sourceBits) // to
|
||||||
val sink = UInt(width = params.sinkBits) // from
|
val sink = UInt(width = params.sinkBits) // from
|
||||||
val data = UInt(width = params.dataBits)
|
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
|
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)
|
class TLBundle(params: TLBundleParameters) extends TLBundleBase(params)
|
||||||
|
@ -4,10 +4,53 @@ package uncore.tilelink2
|
|||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
|
|
||||||
class TLEdgeOut(
|
class TLEdge(
|
||||||
client: TLClientPortParameters,
|
client: TLClientPortParameters,
|
||||||
manager: TLManagerPortParameters)
|
manager: TLManagerPortParameters)
|
||||||
extends TLEdgeParameters(client, manager)
|
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
|
// Transfers
|
||||||
def Acquire(fromSource: UInt, toAddress: UInt, lgSize: UInt, growPermissions: UInt) = {
|
def Acquire(fromSource: UInt, toAddress: UInt, lgSize: UInt, growPermissions: UInt) = {
|
||||||
@ -200,7 +243,7 @@ class TLEdgeOut(
|
|||||||
class TLEdgeIn(
|
class TLEdgeIn(
|
||||||
client: TLClientPortParameters,
|
client: TLClientPortParameters,
|
||||||
manager: TLManagerPortParameters)
|
manager: TLManagerPortParameters)
|
||||||
extends TLEdgeParameters(client, manager)
|
extends TLEdge(client, manager)
|
||||||
{
|
{
|
||||||
// Transfers
|
// Transfers
|
||||||
def Probe(fromAddress: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt) = {
|
def Probe(fromAddress: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt) = {
|
||||||
|
@ -31,7 +31,11 @@ case class IdRange(start: Int, end: Int)
|
|||||||
// contains => overlaps (because empty is forbidden)
|
// contains => overlaps (because empty is forbidden)
|
||||||
|
|
||||||
def contains(x: Int) = start <= x && x < end
|
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)
|
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 none = min == 0
|
||||||
def contains(x: Int) = isPow2(x) && min <= x && x <= max
|
def contains(x: Int) = isPow2(x) && min <= x && x <= max
|
||||||
def containsLg(x: Int) = contains(1 << x)
|
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)
|
def contains(x: TransferSizes) = x.none || (min <= x.min && x.max <= max)
|
||||||
|
|
||||||
@ -299,32 +306,4 @@ case class TLEdgeParameters(
|
|||||||
sourceBits = log2Up(client.endSourceId),
|
sourceBits = log2Up(client.endSourceId),
|
||||||
sinkBits = log2Up(manager.endSinkId),
|
sinkBits = log2Up(manager.endSinkId),
|
||||||
sizeBits = log2Up(maxLgSize+1))
|
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user