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
|
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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user