tilelink2: create optimized hasData method on edges (statically evaluates if known)
This commit is contained in:
parent
5db7ae262b
commit
11b0272d91
@ -106,12 +106,24 @@ object Bogus
|
||||
def apply() = new Bogus
|
||||
}
|
||||
|
||||
object ChannelType {
|
||||
sealed trait T
|
||||
case object A extends T
|
||||
case object B extends T
|
||||
case object C extends T
|
||||
case object D extends T
|
||||
case object E extends T
|
||||
val cases = Seq(A, B, C, D, E)
|
||||
}
|
||||
|
||||
trait HasTLOpcode
|
||||
{
|
||||
// The data field in this message has value
|
||||
def hasData(x: Bogus = Bogus()): Bool
|
||||
// This message requires a response
|
||||
def hasFollowUp(x: Bogus = Bogus()): Bool
|
||||
// What channel type is this?
|
||||
def channelType(x: Bogus = Bogus()): ChannelType.T
|
||||
// The size field of the opcode
|
||||
def size(x: Bogus = Bogus()): UInt
|
||||
}
|
||||
@ -142,6 +154,7 @@ class TLBundleA(params: TLBundleParameters)
|
||||
// opcode === TLMessages.ArithmeticData ||
|
||||
// opcode === TLMessages.LogicalData
|
||||
def hasFollowUp(x: Bogus = Bogus()) = Bool(true)
|
||||
def channelType(x: Bogus = Bogus()) = ChannelType.A
|
||||
def size(x: Bogus = Bogus()) = size
|
||||
def data(x: Bogus = Bogus()) = data
|
||||
def mask(x: Bogus = Bogus()) = mask
|
||||
@ -163,6 +176,7 @@ class TLBundleB(params: TLBundleParameters)
|
||||
|
||||
def hasData(x: Bogus = Bogus()) = !opcode(2)
|
||||
def hasFollowUp(x: Bogus = Bogus()) = Bool(true)
|
||||
def channelType(x: Bogus = Bogus()) = ChannelType.B
|
||||
def size(x: Bogus = Bogus()) = size
|
||||
def data(x: Bogus = Bogus()) = data
|
||||
def mask(x: Bogus = Bogus()) = mask
|
||||
@ -189,6 +203,7 @@ class TLBundleC(params: TLBundleParameters)
|
||||
def hasFollowUp(x: Bogus = Bogus()) = opcode(2) && opcode(1)
|
||||
// opcode === TLMessages.Release ||
|
||||
// opcode === TLMessages.ReleaseData
|
||||
def channelType(x: Bogus = Bogus()) = ChannelType.C
|
||||
def size(x: Bogus = Bogus()) = size
|
||||
def data(x: Bogus = Bogus()) = data
|
||||
def mask(x: Bogus = Bogus()) = SInt(-1, width = params.dataBits/8).asUInt
|
||||
@ -214,6 +229,7 @@ class TLBundleD(params: TLBundleParameters)
|
||||
def hasFollowUp(x: Bogus = Bogus()) = opcode(2) && !opcode(1)
|
||||
// opcode === TLMessages.Grant ||
|
||||
// opcode === TLMessages.GrantData
|
||||
def channelType(x: Bogus = Bogus()) = ChannelType.D
|
||||
def size(x: Bogus = Bogus()) = size
|
||||
def data(x: Bogus = Bogus()) = data
|
||||
def mask(x: Bogus = Bogus()) = SInt(-1, width = params.dataBits/8).asUInt
|
||||
@ -227,6 +243,7 @@ class TLBundleE(params: TLBundleParameters)
|
||||
|
||||
def hasData(x: Bogus = Bogus()) = Bool(false)
|
||||
def hasFollowUp(x: Bogus = Bogus()) = Bool(false)
|
||||
def channelType(x: Bogus = Bogus()) = ChannelType.E
|
||||
def size(x: Bogus = Bogus()) = UInt(log2Up(params.dataBits/8))
|
||||
}
|
||||
|
||||
|
@ -39,8 +39,47 @@ class TLEdge(
|
||||
Cat(helper(lgBytes).map(_._1).reverse)
|
||||
}
|
||||
|
||||
def staticHasData(bundle: HasTLOpcode): Option[Boolean] = {
|
||||
bundle.channelType() match {
|
||||
case ChannelType.A => {
|
||||
// Do there exist A messages with Data?
|
||||
val aDataYes = manager.anySupportArithmetic || manager.anySupportLogical || manager.anySupportPutFull || manager.anySupportPutPartial
|
||||
// Do there exist A messages without Data?
|
||||
val aDataNo = manager.anySupportAcquire || manager.anySupportGet || manager.anySupportHint
|
||||
// Statically optimize the case where hasData is a constant
|
||||
if (!aDataYes) Some(false) else if (!aDataNo) Some(true) else None
|
||||
}
|
||||
case ChannelType.B => {
|
||||
// Do there exist B messages with Data?
|
||||
val bDataYes = client.anySupportArithmetic || client.anySupportLogical || client.anySupportPutFull || client.anySupportPutPartial
|
||||
// Do there exist B messages without Data?
|
||||
val bDataNo = client.anySupportProbe || client.anySupportGet || client.anySupportHint
|
||||
// Statically optimize the case where hasData is a constant
|
||||
if (!bDataYes) Some(false) else if (!bDataNo) Some(true) else None
|
||||
}
|
||||
case ChannelType.C => {
|
||||
// Do there eixst C messages with Data?
|
||||
val cDataYes = client.anySupportGet || client.anySupportArithmetic || client.anySupportLogical || client.anySupportProbe
|
||||
// Do there exist C messages without Data?
|
||||
val cDataNo = client.anySupportPutFull || client.anySupportPutPartial || client.anySupportHint || client.anySupportProbe
|
||||
if (!cDataYes) Some(false) else if (!cDataNo) Some(true) else None
|
||||
}
|
||||
case ChannelType.D => {
|
||||
// Do there eixst D messages with Data?
|
||||
val dDataYes = manager.anySupportGet || manager.anySupportArithmetic || manager.anySupportLogical || manager.anySupportAcquire
|
||||
// Do there exist D messages without Data?
|
||||
val dDataNo = manager.anySupportPutFull || manager.anySupportPutPartial || manager.anySupportHint || manager.anySupportAcquire
|
||||
if (!dDataYes) Some(false) else if (!dDataNo) Some(true) else None
|
||||
}
|
||||
case ChannelType.E => Some(false)
|
||||
}
|
||||
}
|
||||
|
||||
def hasData(bundle: HasTLOpcode): Bool =
|
||||
staticHasData(bundle).map(Bool(_)).getOrElse(bundle.hasData())
|
||||
|
||||
def numBeats(bundle: HasTLOpcode) = {
|
||||
val hasData = bundle.hasData()
|
||||
val hasData = this.hasData(bundle)
|
||||
val size = bundle.size()
|
||||
val cutoff = log2Ceil(manager.beatBytes)
|
||||
val small = size <= UInt(cutoff)
|
||||
|
Loading…
Reference in New Issue
Block a user