1
0

tilelink2: create optimized hasData method on edges (statically evaluates if known)

This commit is contained in:
Wesley W. Terpstra 2016-09-02 19:55:08 -07:00
parent 5db7ae262b
commit 11b0272d91
2 changed files with 57 additions and 1 deletions

View File

@ -106,12 +106,24 @@ object Bogus
def apply() = new 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 trait HasTLOpcode
{ {
// The data field in this message has value // The data field in this message has value
def hasData(x: Bogus = Bogus()): Bool def hasData(x: Bogus = Bogus()): Bool
// This message requires a response // This message requires a response
def hasFollowUp(x: Bogus = Bogus()): Bool def hasFollowUp(x: Bogus = Bogus()): Bool
// What channel type is this?
def channelType(x: Bogus = Bogus()): ChannelType.T
// The size field of the opcode // The size field of the opcode
def size(x: Bogus = Bogus()): UInt def size(x: Bogus = Bogus()): UInt
} }
@ -142,6 +154,7 @@ class TLBundleA(params: TLBundleParameters)
// opcode === TLMessages.ArithmeticData || // opcode === TLMessages.ArithmeticData ||
// opcode === TLMessages.LogicalData // opcode === TLMessages.LogicalData
def hasFollowUp(x: Bogus = Bogus()) = Bool(true) def hasFollowUp(x: Bogus = Bogus()) = Bool(true)
def channelType(x: Bogus = Bogus()) = ChannelType.A
def size(x: Bogus = Bogus()) = size def size(x: Bogus = Bogus()) = size
def data(x: Bogus = Bogus()) = data def data(x: Bogus = Bogus()) = data
def mask(x: Bogus = Bogus()) = mask def mask(x: Bogus = Bogus()) = mask
@ -163,6 +176,7 @@ class TLBundleB(params: TLBundleParameters)
def hasData(x: Bogus = Bogus()) = !opcode(2) def hasData(x: Bogus = Bogus()) = !opcode(2)
def hasFollowUp(x: Bogus = Bogus()) = Bool(true) def hasFollowUp(x: Bogus = Bogus()) = Bool(true)
def channelType(x: Bogus = Bogus()) = ChannelType.B
def size(x: Bogus = Bogus()) = size def size(x: Bogus = Bogus()) = size
def data(x: Bogus = Bogus()) = data def data(x: Bogus = Bogus()) = data
def mask(x: Bogus = Bogus()) = mask def mask(x: Bogus = Bogus()) = mask
@ -189,6 +203,7 @@ class TLBundleC(params: TLBundleParameters)
def hasFollowUp(x: Bogus = Bogus()) = opcode(2) && opcode(1) def hasFollowUp(x: Bogus = Bogus()) = opcode(2) && opcode(1)
// opcode === TLMessages.Release || // opcode === TLMessages.Release ||
// opcode === TLMessages.ReleaseData // opcode === TLMessages.ReleaseData
def channelType(x: Bogus = Bogus()) = ChannelType.C
def size(x: Bogus = Bogus()) = size def size(x: Bogus = Bogus()) = size
def data(x: Bogus = Bogus()) = data def data(x: Bogus = Bogus()) = data
def mask(x: Bogus = Bogus()) = SInt(-1, width = params.dataBits/8).asUInt 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) def hasFollowUp(x: Bogus = Bogus()) = opcode(2) && !opcode(1)
// opcode === TLMessages.Grant || // opcode === TLMessages.Grant ||
// opcode === TLMessages.GrantData // opcode === TLMessages.GrantData
def channelType(x: Bogus = Bogus()) = ChannelType.D
def size(x: Bogus = Bogus()) = size def size(x: Bogus = Bogus()) = size
def data(x: Bogus = Bogus()) = data def data(x: Bogus = Bogus()) = data
def mask(x: Bogus = Bogus()) = SInt(-1, width = params.dataBits/8).asUInt 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 hasData(x: Bogus = Bogus()) = Bool(false)
def hasFollowUp(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)) def size(x: Bogus = Bogus()) = UInt(log2Up(params.dataBits/8))
} }

View File

@ -39,8 +39,47 @@ class TLEdge(
Cat(helper(lgBytes).map(_._1).reverse) 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) = { def numBeats(bundle: HasTLOpcode) = {
val hasData = bundle.hasData() val hasData = this.hasData(bundle)
val size = bundle.size() val size = bundle.size()
val cutoff = log2Ceil(manager.beatBytes) val cutoff = log2Ceil(manager.beatBytes)
val small = size <= UInt(cutoff) val small = size <= UInt(cutoff)