1
0

tilelink2: refactor address into addr_hi on ABC and addr_lo on CD

We need addr_lo in order to properly convert widths.
As part of the refactoring, move all methods out of the Bundles
This commit is contained in:
Wesley W. Terpstra
2016-09-06 23:46:44 -07:00
parent aae4230627
commit d2421654c4
14 changed files with 378 additions and 314 deletions

View File

@ -10,14 +10,22 @@ class TLEdge(
manager: TLManagerPortParameters)
extends TLEdgeParameters(client, manager)
{
def isAligned(address: UInt, lgSize: UInt) =
def isHiAligned(addr_hi: UInt, lgSize: UInt): Bool = {
if (maxLgSize == 0) Bool(true) else {
val mask = ~(SInt(-1, width=maxLgSize).asUInt << lgSize)(maxLgSize-1, 0)
(address & mask) === UInt(0)
val mask = UIntToOH1(lgSize, maxLgSize) >> log2Ceil(manager.beatBytes)
(addr_hi & mask) === UInt(0)
}
}
def isLoAligned(addr_lo: UInt, lgSize: UInt): Bool = {
if (maxLgSize == 0) Bool(true) else {
val mask = UIntToOH1(lgSize, maxLgSize)
(addr_lo & mask) === UInt(0)
}
}
// This gets used everywhere, so make the smallest circuit possible ...
def fullMask(address: UInt, lgSize: UInt) = {
def mask(addr_lo: UInt, lgSize: UInt): UInt = {
val lgBytes = log2Ceil(manager.beatBytes)
val sizeOH = UIntToOH(lgSize, lgBytes)
def helper(i: Int): Seq[(Bool, Bool)] = {
@ -26,7 +34,7 @@ class TLEdge(
} else {
val sub = helper(i-1)
val size = sizeOH(lgBytes - i)
val bit = address(lgBytes - i)
val bit = addr_lo(lgBytes - i)
val nbit = !bit
Seq.tabulate (1 << i) { j =>
val (sub_acc, sub_eq) = sub(j/2)
@ -39,8 +47,8 @@ class TLEdge(
Cat(helper(lgBytes).map(_._1).reverse)
}
def lowAddress(mask: UInt) = {
// Almost OHToUInt, but any bit in low => use low address
def addr_lo(mask: UInt): UInt = {
// Almost OHToUInt, but bits set => bits not set
def helper(mask: UInt, width: Int): UInt = {
if (width <= 1) {
UInt(0)
@ -56,9 +64,9 @@ class TLEdge(
helper(mask, bundle.dataBits/8)
}
def staticHasData(bundle: HasTLOpcode): Option[Boolean] = {
bundle.channelType() match {
case ChannelType.A => {
def staticHasData(bundle: TLChannel): Option[Boolean] = {
bundle match {
case _:TLBundleA => {
// Do there exist A messages with Data?
val aDataYes = manager.anySupportArithmetic || manager.anySupportLogical || manager.anySupportPutFull || manager.anySupportPutPartial
// Do there exist A messages without Data?
@ -66,7 +74,7 @@ class TLEdge(
// Statically optimize the case where hasData is a constant
if (!aDataYes) Some(false) else if (!aDataNo) Some(true) else None
}
case ChannelType.B => {
case _:TLBundleB => {
// Do there exist B messages with Data?
val bDataYes = client.anySupportArithmetic || client.anySupportLogical || client.anySupportPutFull || client.anySupportPutPartial
// Do there exist B messages without Data?
@ -74,34 +82,119 @@ class TLEdge(
// Statically optimize the case where hasData is a constant
if (!bDataYes) Some(false) else if (!bDataNo) Some(true) else None
}
case ChannelType.C => {
case _:TLBundleC => {
// 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 => {
case _:TLBundleD => {
// 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)
case _:TLBundleE => Some(false)
}
}
def hasData(bundle: HasTLOpcode): Bool =
staticHasData(bundle).map(Bool(_)).getOrElse(bundle.hasData())
def hasFollowUp(x: TLChannel): Bool = {
x match {
case a: TLBundleA => Bool(true)
case b: TLBundleB => Bool(true)
case c: TLBundleC => c.opcode(2) && c.opcode(1)
// opcode === TLMessages.Release ||
// opcode === TLMessages.ReleaseData
case d: TLBundleD => d.opcode(2) && !d.opcode(1)
// opcode === TLMessages.Grant ||
// opcode === TLMessages.GrantData
case e: TLBundleE => Bool(false)
}
}
def numBeats(bundle: HasTLOpcode) = {
val hasData = this.hasData(bundle)
val size = bundle.size()
val cutoff = log2Ceil(manager.beatBytes)
val small = if (manager.maxTransfer <= manager.beatBytes) Bool(true) else size <= UInt(cutoff)
val decode = UIntToOH(size, maxLgSize+1) >> cutoff
Mux(!hasData || small, UInt(1), decode)
def hasData(x: TLChannel): Bool = {
val opdata = x match {
case a: TLBundleA => !a.opcode(2)
// opcode === TLMessages.PutFullData ||
// opcode === TLMessages.PutPartialData ||
// opcode === TLMessages.ArithmeticData ||
// opcode === TLMessages.LogicalData
case b: TLBundleB => !b.opcode(2)
// opcode === TLMessages.PutFullData ||
// opcode === TLMessages.PutPartialData ||
// opcode === TLMessages.ArithmeticData ||
// opcode === TLMessages.LogicalData
case c: TLBundleC => c.opcode(0)
// opcode === TLMessages.AccessAckData ||
// opcode === TLMessages.ProbeAckData ||
// opcode === TLMessages.ReleaseData
case d: TLBundleD => d.opcode(0)
// opcode === TLMessages.AccessAckData ||
// opcode === TLMessages.GrantData
case e: TLBundleE => Bool(false)
}
staticHasData(x).map(Bool(_)).getOrElse(opdata)
}
def size(x: TLDataChannel): UInt = {
x match {
case a: TLBundleA => a.size
case b: TLBundleB => b.size
case c: TLBundleC => c.size
case d: TLBundleD => d.size
}
}
def data(x: TLDataChannel): UInt = {
x match {
case a: TLBundleA => a.data
case b: TLBundleB => b.data
case c: TLBundleC => c.data
case d: TLBundleD => d.data
}
}
def mask(x: TLDataChannel): UInt = {
x match {
case a: TLBundleA => a.mask
case b: TLBundleB => b.mask
case c: TLBundleC => mask(c.addr_lo, c.size)
case d: TLBundleD => mask(d.addr_lo, d.size)
}
}
def addr_lo(x: TLDataChannel): UInt = {
x match {
case a: TLBundleA => addr_lo(a.mask)
case b: TLBundleB => addr_lo(b.mask)
case c: TLBundleC => c.addr_lo
case d: TLBundleD => d.addr_lo
}
}
def address(x: TLAddrChannel): UInt = {
val hi = x match {
case a: TLBundleA => a.addr_hi
case b: TLBundleB => b.addr_hi
case c: TLBundleC => c.addr_hi
}
if (manager.beatBytes == 1) hi else Cat(hi, addr_lo(x))
}
def numBeats(x: TLChannel): UInt = {
x match {
case _: TLBundleE => UInt(1)
case bundle: TLDataChannel => {
val hasData = this.hasData(bundle)
val size = this.size(bundle)
val cutoff = log2Ceil(manager.beatBytes)
val small = if (manager.maxTransfer <= manager.beatBytes) Bool(true) else size <= UInt(cutoff)
val decode = UIntToOH(size, maxLgSize+1) >> cutoff
Mux(!hasData || small, UInt(1), decode)
}
}
}
}
@ -119,7 +212,7 @@ class TLEdgeOut(
a.param := growPermissions
a.size := lgSize
a.source := fromSource
a.address := toAddress
a.addr_hi := toAddress >> log2Ceil(manager.beatBytes)
a.mask := SInt(-1).asUInt
a.data := UInt(0)
(legal, a)
@ -133,7 +226,8 @@ class TLEdgeOut(
c.param := shrinkPermissions
c.size := lgSize
c.source := fromSource
c.address := toAddress
c.addr_hi := toAddress >> log2Ceil(manager.beatBytes)
c.addr_lo := toAddress
c.data := UInt(0)
c.error := Bool(false)
(legal, c)
@ -147,31 +241,34 @@ class TLEdgeOut(
c.param := shrinkPermissions
c.size := lgSize
c.source := fromSource
c.address := toAddress
c.addr_hi := toAddress >> log2Ceil(manager.beatBytes)
c.addr_lo := toAddress
c.data := data
c.error := Bool(false)
(legal, c)
}
def ProbeAck(toAddress: UInt, lgSize: UInt, reportPermissions: UInt) = {
def ProbeAck(fromSource: UInt, toAddress: UInt, lgSize: UInt, reportPermissions: UInt) = {
val c = Wire(new TLBundleC(bundle))
c.opcode := TLMessages.ProbeAck
c.param := reportPermissions
c.size := lgSize
c.source := UInt(0)
c.address := toAddress
c.source := fromSource
c.addr_hi := toAddress >> log2Ceil(manager.beatBytes)
c.addr_lo := toAddress
c.data := UInt(0)
c.error := Bool(false)
c
}
def ProbeAck(toAddress: UInt, lgSize: UInt, reportPermissions: UInt, data: UInt) = {
def ProbeAck(fromSource: UInt, toAddress: UInt, lgSize: UInt, reportPermissions: UInt, data: UInt) = {
val c = Wire(new TLBundleC(bundle))
c.opcode := TLMessages.ProbeAckData
c.param := reportPermissions
c.size := lgSize
c.source := UInt(0)
c.address := toAddress
c.source := fromSource
c.addr_hi := toAddress >> log2Ceil(manager.beatBytes)
c.addr_lo := toAddress
c.data := data
c.error := Bool(false)
c
@ -192,8 +289,8 @@ class TLEdgeOut(
a.param := UInt(0)
a.size := lgSize
a.source := fromSource
a.address := toAddress
a.mask := fullMask(toAddress, lgSize)
a.addr_hi := toAddress >> log2Ceil(manager.beatBytes)
a.mask := mask(toAddress, lgSize)
a.data := UInt(0)
(legal, a)
}
@ -206,8 +303,8 @@ class TLEdgeOut(
a.param := UInt(0)
a.size := lgSize
a.source := fromSource
a.address := toAddress
a.mask := fullMask(toAddress, lgSize)
a.addr_hi := toAddress >> log2Ceil(manager.beatBytes)
a.mask := mask(toAddress, lgSize)
a.data := data
(legal, a)
}
@ -220,7 +317,7 @@ class TLEdgeOut(
a.param := UInt(0)
a.size := lgSize
a.source := fromSource
a.address := toAddress
a.addr_hi := toAddress >> log2Ceil(manager.beatBytes)
a.mask := mask
a.data := data
(legal, a)
@ -234,8 +331,8 @@ class TLEdgeOut(
a.param := atomic
a.size := lgSize
a.source := fromSource
a.address := toAddress
a.mask := fullMask(toAddress, lgSize)
a.addr_hi := toAddress >> log2Ceil(manager.beatBytes)
a.mask := mask(toAddress, lgSize)
a.data := data
(legal, a)
}
@ -248,8 +345,8 @@ class TLEdgeOut(
a.param := atomic
a.size := lgSize
a.source := fromSource
a.address := toAddress
a.mask := fullMask(toAddress, lgSize)
a.addr_hi := toAddress >> log2Ceil(manager.beatBytes)
a.mask := mask(toAddress, lgSize)
a.data := data
(legal, a)
}
@ -262,45 +359,53 @@ class TLEdgeOut(
a.param := param
a.size := lgSize
a.source := fromSource
a.address := toAddress
a.mask := fullMask(toAddress, lgSize)
a.addr_hi := toAddress >> log2Ceil(manager.beatBytes)
a.mask := mask(toAddress, lgSize)
a.data := UInt(0)
(legal, a)
}
def AccessAck(toAddress: UInt, lgSize: UInt): TLBundleC = AccessAck(toAddress, lgSize, Bool(false))
def AccessAck(toAddress: UInt, lgSize: UInt, error: Bool) = {
def AccessAck(b: TLBundleB): TLBundleC = AccessAck(b.source, address(b), b.size)
def AccessAck(b: TLBundleB, error: Bool): TLBundleC = AccessAck(b.source, address(b), b.size, error)
def AccessAck(fromSource: UInt, toAddress: UInt, lgSize: UInt): TLBundleC = AccessAck(fromSource, toAddress, lgSize, Bool(false))
def AccessAck(fromSource: UInt, toAddress: UInt, lgSize: UInt, error: Bool) = {
val c = Wire(new TLBundleC(bundle))
c.opcode := TLMessages.AccessAck
c.param := UInt(0)
c.size := lgSize
c.source := UInt(0)
c.address := toAddress
c.source := fromSource
c.addr_hi := toAddress >> log2Ceil(manager.beatBytes)
c.addr_lo := toAddress
c.data := UInt(0)
c.error := error
c
}
def AccessAck(toAddress: UInt, lgSize: UInt, data: UInt): TLBundleC = AccessAck(toAddress, lgSize, data, Bool(false))
def AccessAck(toAddress: UInt, lgSize: UInt, data: UInt, error: Bool) = {
def AccessAck(b: TLBundleB, data: UInt): TLBundleC = AccessAck(b.source, address(b), b.size, data)
def AccessAck(b: TLBundleB, data: UInt, error: Bool): TLBundleC = AccessAck(b.source, address(b), b.size, data, error)
def AccessAck(fromSource: UInt, toAddress: UInt, lgSize: UInt, data: UInt): TLBundleC = AccessAck(fromSource, toAddress, lgSize, data, Bool(false))
def AccessAck(fromSource: UInt, toAddress: UInt, lgSize: UInt, data: UInt, error: Bool) = {
val c = Wire(new TLBundleC(bundle))
c.opcode := TLMessages.AccessAckData
c.param := UInt(0)
c.size := lgSize
c.source := UInt(0)
c.address := toAddress
c.source := fromSource
c.addr_hi := toAddress >> log2Ceil(manager.beatBytes)
c.addr_lo := toAddress
c.data := data
c.error := error
c
}
def HintAck(toAddress: UInt, lgSize: UInt) = {
def HintAck(b: TLBundleB): TLBundleC = HintAck(b.source, address(b), b.size)
def HintAck(fromSource: UInt, toAddress: UInt, lgSize: UInt) = {
val c = Wire(new TLBundleC(bundle))
c.opcode := TLMessages.HintAck
c.param := UInt(0)
c.size := lgSize
c.source := UInt(0)
c.address := toAddress
c.source := fromSource
c.addr_hi := toAddress >> log2Ceil(manager.beatBytes)
c.addr_lo := toAddress
c.data := UInt(0)
c.error := Bool(false)
c
@ -321,47 +426,50 @@ class TLEdgeIn(
b.param := capPermissions
b.size := lgSize
b.source := toSource
b.address := fromAddress
b.addr_hi := fromAddress >> log2Ceil(manager.beatBytes)
b.mask := SInt(-1).asUInt
b.data := UInt(0)
(legal, b)
}
def Grant(fromSink: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt): TLBundleD = Grant(fromSink, toSource, lgSize, capPermissions, Bool(false))
def Grant(fromSink: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt, error: Bool) = {
def Grant(fromAddress: UInt, fromSink: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt): TLBundleD = Grant(fromAddress, fromSink, toSource, lgSize, capPermissions, Bool(false))
def Grant(fromAddress: UInt, fromSink: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt, error: Bool) = {
val d = Wire(new TLBundleD(bundle))
d.opcode := TLMessages.Grant
d.param := capPermissions
d.size := lgSize
d.source := toSource
d.sink := fromSink
d.data := UInt(0)
d.error := error
d.opcode := TLMessages.Grant
d.param := capPermissions
d.size := lgSize
d.source := toSource
d.sink := fromSink
d.addr_lo := fromAddress
d.data := UInt(0)
d.error := error
d
}
def Grant(fromSink: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt, data: UInt): TLBundleD = Grant(fromSink, toSource, lgSize, capPermissions, data, Bool(false))
def Grant(fromSink: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt, data: UInt, error: Bool) = {
def Grant(fromAddress: UInt, fromSink: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt, data: UInt): TLBundleD = Grant(fromAddress, fromSink, toSource, lgSize, capPermissions, data, Bool(false))
def Grant(fromAddress: UInt, fromSink: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt, data: UInt, error: Bool) = {
val d = Wire(new TLBundleD(bundle))
d.opcode := TLMessages.GrantData
d.param := capPermissions
d.size := lgSize
d.source := toSource
d.sink := fromSink
d.data := data
d.error := error
d.opcode := TLMessages.GrantData
d.param := capPermissions
d.size := lgSize
d.source := toSource
d.sink := fromSink
d.addr_lo := fromAddress
d.data := data
d.error := error
d
}
def ReleaseAck(toSource: UInt, lgSize: UInt) = {
def ReleaseAck(fromAddress: UInt, fromSink: UInt, toSource: UInt, lgSize: UInt) = {
val d = Wire(new TLBundleD(bundle))
d.opcode := TLMessages.ReleaseAck
d.param := UInt(0)
d.size := lgSize
d.source := toSource
d.sink := UInt(0)
d.data := UInt(0)
d.error := Bool(false)
d.opcode := TLMessages.ReleaseAck
d.param := UInt(0)
d.size := lgSize
d.source := toSource
d.sink := fromSink
d.addr_lo := fromAddress
d.data := UInt(0)
d.error := Bool(false)
d
}
@ -374,8 +482,8 @@ class TLEdgeIn(
b.param := UInt(0)
b.size := lgSize
b.source := toSource
b.address := fromAddress
b.mask := fullMask(fromAddress, lgSize)
b.addr_hi := fromAddress >> log2Ceil(manager.beatBytes)
b.mask := mask(fromAddress, lgSize)
b.data := UInt(0)
(legal, b)
}
@ -388,8 +496,8 @@ class TLEdgeIn(
b.param := UInt(0)
b.size := lgSize
b.source := toSource
b.address := fromAddress
b.mask := fullMask(fromAddress, lgSize)
b.addr_hi := fromAddress >> log2Ceil(manager.beatBytes)
b.mask := mask(fromAddress, lgSize)
b.data := data
(legal, b)
}
@ -402,7 +510,7 @@ class TLEdgeIn(
b.param := UInt(0)
b.size := lgSize
b.source := toSource
b.address := fromAddress
b.addr_hi := fromAddress >> log2Ceil(manager.beatBytes)
b.mask := mask
b.data := data
(legal, b)
@ -416,8 +524,8 @@ class TLEdgeIn(
b.param := atomic
b.size := lgSize
b.source := toSource
b.address := fromAddress
b.mask := fullMask(fromAddress, lgSize)
b.addr_hi := fromAddress >> log2Ceil(manager.beatBytes)
b.mask := mask(fromAddress, lgSize)
b.data := data
(legal, b)
}
@ -430,8 +538,8 @@ class TLEdgeIn(
b.param := atomic
b.size := lgSize
b.source := toSource
b.address := fromAddress
b.mask := fullMask(fromAddress, lgSize)
b.addr_hi := fromAddress >> log2Ceil(manager.beatBytes)
b.mask := mask(fromAddress, lgSize)
b.data := data
(legal, b)
}
@ -444,47 +552,55 @@ class TLEdgeIn(
b.param := param
b.size := lgSize
b.source := toSource
b.address := fromAddress
b.mask := fullMask(fromAddress, lgSize)
b.addr_hi := fromAddress >> log2Ceil(manager.beatBytes)
b.mask := mask(fromAddress, lgSize)
b.data := UInt(0)
(legal, b)
}
def AccessAck(toSource: UInt, lgSize: UInt): TLBundleD = AccessAck(toSource, lgSize, Bool(false))
def AccessAck(toSource: UInt, lgSize: UInt, error: Bool) = {
def AccessAck(a: TLBundleA, fromSink: UInt): TLBundleD = AccessAck(address(a), fromSink, a.source, a.size)
def AccessAck(a: TLBundleA, fromSink: UInt, error: Bool): TLBundleD = AccessAck(address(a), fromSink, a.source, a.size, error)
def AccessAck(fromAddress: UInt, fromSink: UInt, toSource: UInt, lgSize: UInt): TLBundleD = AccessAck(fromAddress, fromSink, toSource, lgSize, Bool(false))
def AccessAck(fromAddress: UInt, fromSink: UInt, toSource: UInt, lgSize: UInt, error: Bool) = {
val d = Wire(new TLBundleD(bundle))
d.opcode := TLMessages.AccessAck
d.param := UInt(0)
d.size := lgSize
d.source := toSource
d.sink := UInt(0)
d.data := UInt(0)
d.error := error
d.opcode := TLMessages.AccessAck
d.param := UInt(0)
d.size := lgSize
d.source := toSource
d.sink := fromSink
d.addr_lo := fromAddress
d.data := UInt(0)
d.error := error
d
}
def AccessAck(toSource: UInt, lgSize: UInt, data: UInt): TLBundleD = AccessAck(toSource, lgSize, data, Bool(false))
def AccessAck(toSource: UInt, lgSize: UInt, data: UInt, error: Bool) = {
def AccessAck(a: TLBundleA, fromSink: UInt, data: UInt): TLBundleD = AccessAck(address(a), fromSink, a.source, a.size, data)
def AccessAck(a: TLBundleA, fromSink: UInt, data: UInt, error: Bool): TLBundleD = AccessAck(address(a), fromSink, a.source, a.size, data, error)
def AccessAck(fromAddress: UInt, fromSink: UInt, toSource: UInt, lgSize: UInt, data: UInt): TLBundleD = AccessAck(fromAddress, fromSink, toSource, lgSize, data, Bool(false))
def AccessAck(fromAddress: UInt, fromSink: UInt, toSource: UInt, lgSize: UInt, data: UInt, error: Bool) = {
val d = Wire(new TLBundleD(bundle))
d.opcode := TLMessages.AccessAckData
d.param := UInt(0)
d.size := lgSize
d.source := toSource
d.sink := UInt(0)
d.data := data
d.error := error
d.opcode := TLMessages.AccessAckData
d.param := UInt(0)
d.size := lgSize
d.source := toSource
d.sink := fromSink
d.addr_lo := fromAddress
d.data := data
d.error := error
d
}
def HintAck(toSource: UInt, lgSize: UInt) = {
def HintAck(a: TLBundleA, sink: UInt = UInt(0)): TLBundleD = HintAck(address(a), sink, a.source, a.size)
def HintAck(fromAddress: UInt, fromSink: UInt, toSource: UInt, lgSize: UInt) = {
val d = Wire(new TLBundleD(bundle))
d.opcode := TLMessages.HintAck
d.param := UInt(0)
d.size := lgSize
d.source := toSource
d.sink := UInt(0)
d.data := UInt(0)
d.error := Bool(false)
d.opcode := TLMessages.HintAck
d.param := UInt(0)
d.size := lgSize
d.source := toSource
d.sink := fromSink
d.addr_lo := fromAddress
d.data := UInt(0)
d.error := Bool(false)
d
}
}