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:
parent
aae4230627
commit
d2421654c4
@ -100,118 +100,55 @@ object TLAtomics
|
||||
def isLogical(x: UInt) = x <= SWAP
|
||||
}
|
||||
|
||||
class Bogus
|
||||
object Bogus
|
||||
{
|
||||
def apply() = new Bogus
|
||||
}
|
||||
sealed trait TLChannel
|
||||
sealed trait TLDataChannel extends TLChannel
|
||||
sealed trait TLAddrChannel extends TLDataChannel
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
trait HasTLData extends HasTLOpcode
|
||||
{
|
||||
def data(x: Bogus = Bogus()): UInt
|
||||
def mask(x: Bogus = Bogus()): UInt
|
||||
}
|
||||
|
||||
class TLBundleA(params: TLBundleParameters)
|
||||
extends TLBundleBase(params)
|
||||
with HasTLData
|
||||
final class TLBundleA(params: TLBundleParameters)
|
||||
extends TLBundleBase(params) with TLAddrChannel
|
||||
{
|
||||
// fixed fields during multibeat:
|
||||
val opcode = UInt(width = 3)
|
||||
val param = UInt(width = 3) // amo_opcode || perms || hint
|
||||
val size = UInt(width = params.sizeBits)
|
||||
val source = UInt(width = params.sourceBits) // from
|
||||
val address = UInt(width = params.addressBits) // to
|
||||
val addr_hi = UInt(width = params.addrHiBits) // to
|
||||
// variable fields during multibeat:
|
||||
val mask = UInt(width = params.dataBits/8)
|
||||
val data = UInt(width = params.dataBits)
|
||||
|
||||
def hasData(x: Bogus = Bogus()) = !opcode(2)
|
||||
// opcode === TLMessages.PutFullData ||
|
||||
// opcode === TLMessages.PutPartialData ||
|
||||
// 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
|
||||
}
|
||||
|
||||
class TLBundleB(params: TLBundleParameters)
|
||||
extends TLBundleBase(params)
|
||||
with HasTLData
|
||||
final class TLBundleB(params: TLBundleParameters)
|
||||
extends TLBundleBase(params) with TLAddrChannel
|
||||
{
|
||||
// fixed fields during multibeat:
|
||||
val opcode = UInt(width = 3)
|
||||
val param = UInt(width = 3)
|
||||
val size = UInt(width = params.sizeBits)
|
||||
val source = UInt(width = params.sourceBits) // to
|
||||
val address = UInt(width = params.addressBits) // from
|
||||
val addr_hi = UInt(width = params.addrHiBits) // from
|
||||
// variable fields during multibeat:
|
||||
val mask = UInt(width = params.dataBits/8)
|
||||
val data = UInt(width = params.dataBits)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
class TLBundleC(params: TLBundleParameters)
|
||||
extends TLBundleBase(params)
|
||||
with HasTLData
|
||||
final class TLBundleC(params: TLBundleParameters)
|
||||
extends TLBundleBase(params) with TLAddrChannel
|
||||
{
|
||||
// fixed fields during multibeat:
|
||||
val opcode = UInt(width = 3)
|
||||
val param = UInt(width = 3)
|
||||
val size = UInt(width = params.sizeBits)
|
||||
val source = UInt(width = params.sourceBits) // from
|
||||
val address = UInt(width = params.addressBits) // to
|
||||
val addr_hi = UInt(width = params.addrHiBits) // to
|
||||
val addr_lo = UInt(width = params.addrLoBits) // instead of mask
|
||||
// variable fields during multibeat:
|
||||
val data = UInt(width = params.dataBits)
|
||||
val error = Bool() // AccessAck[Data]
|
||||
|
||||
def hasData(x: Bogus = Bogus()) = opcode(0)
|
||||
// opcode === TLMessages.AccessAckData ||
|
||||
// opcode === TLMessages.ProbeAckData ||
|
||||
// opcode === TLMessages.ReleaseData
|
||||
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
|
||||
}
|
||||
|
||||
class TLBundleD(params: TLBundleParameters)
|
||||
extends TLBundleBase(params)
|
||||
with HasTLData
|
||||
final class TLBundleD(params: TLBundleParameters)
|
||||
extends TLBundleBase(params) with TLDataChannel
|
||||
{
|
||||
// fixed fields during multibeat:
|
||||
val opcode = UInt(width = 3)
|
||||
@ -219,32 +156,16 @@ class TLBundleD(params: TLBundleParameters)
|
||||
val size = UInt(width = params.sizeBits)
|
||||
val source = UInt(width = params.sourceBits) // to
|
||||
val sink = UInt(width = params.sinkBits) // from
|
||||
val addr_lo = UInt(width = params.addrLoBits) // instead of mask
|
||||
// variable fields during multibeat:
|
||||
val data = UInt(width = params.dataBits)
|
||||
val error = Bool() // AccessAck[Data], Grant[Data]
|
||||
|
||||
def hasData(x: Bogus = Bogus()) = opcode(0)
|
||||
// opcode === TLMessages.AccessAckData ||
|
||||
// opcode === TLMessages.GrantData
|
||||
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
|
||||
}
|
||||
|
||||
class TLBundleE(params: TLBundleParameters)
|
||||
extends TLBundleBase(params)
|
||||
with HasTLOpcode
|
||||
final class TLBundleE(params: TLBundleParameters)
|
||||
extends TLBundleBase(params) with TLChannel
|
||||
{
|
||||
val sink = UInt(width = params.sourceBits) // to
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
class TLBundle(params: TLBundleParameters) extends TLBundleBase(params)
|
||||
|
@ -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,35 +82,120 @@ 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) = {
|
||||
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 = bundle.size()
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TLEdgeOut(
|
||||
@ -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,45 +426,48 @@ 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.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.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.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,45 +552,53 @@ 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.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.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.sink := fromSink
|
||||
d.addr_lo := fromAddress
|
||||
d.data := UInt(0)
|
||||
d.error := Bool(false)
|
||||
d
|
||||
|
@ -57,7 +57,9 @@ class TLFragmenter(minSize: Int, maxSize: Int, alwaysMin: Boolean = false) exten
|
||||
}
|
||||
|
||||
// All managers must share a common FIFO domain (responses might end up interleaved)
|
||||
val manager = node.edgesOut(0).manager
|
||||
val edgeOut = node.edgesOut(0)
|
||||
val edgeIn = node.edgesIn(0)
|
||||
val manager = edgeOut.manager
|
||||
val managers = manager.managers
|
||||
val beatBytes = manager.beatBytes
|
||||
val fifoId = managers(0).fifoId
|
||||
@ -137,9 +139,6 @@ class TLFragmenter(minSize: Int, maxSize: Int, alwaysMin: Boolean = false) exten
|
||||
val counterBits = log2Up(maxSize/beatBytes)
|
||||
val maxDownSize = if (alwaysMin) minSize else manager.maxTransfer
|
||||
|
||||
def OH1ToUInt(x: UInt) = OHToUInt((x << 1 | UInt(1)) ^ x)
|
||||
def UIntToOH1(x: UInt, width: Int) = ~(SInt(-1, width=width).asUInt << x)(width-1, 0)
|
||||
|
||||
// First, handle the return path
|
||||
val acknum = RegInit(UInt(0, width = counterBits))
|
||||
val dOrig = Reg(UInt())
|
||||
@ -147,7 +146,7 @@ class TLFragmenter(minSize: Int, maxSize: Int, alwaysMin: Boolean = false) exten
|
||||
val dFirst = acknum === UInt(0)
|
||||
val dsizeOH = UIntToOH (out.d.bits.size, log2Ceil(maxDownSize)+1)
|
||||
val dsizeOH1 = UIntToOH1(out.d.bits.size, log2Ceil(maxDownSize))
|
||||
val dHasData = node.edgesOut(0).hasData(out.d.bits)
|
||||
val dHasData = edgeOut.hasData(out.d.bits)
|
||||
|
||||
// calculate new acknum
|
||||
val acknum_fragment = dFragnum << log2Ceil(minSize/beatBytes)
|
||||
@ -189,7 +188,7 @@ class TLFragmenter(minSize: Int, maxSize: Int, alwaysMin: Boolean = false) exten
|
||||
val maxLgHints = maxHints .map(m => if (m == 0) lgMinSize else UInt(log2Ceil(m)))
|
||||
|
||||
// If this is infront of a single manager, these become constants
|
||||
val find = manager.find(in.a.bits.address)
|
||||
val find = manager.find(edgeIn.address(in.a.bits))
|
||||
val maxLgArithmetic = Mux1H(find, maxLgArithmetics)
|
||||
val maxLgLogical = Mux1H(find, maxLgLogicals)
|
||||
val maxLgGet = Mux1H(find, maxLgGets)
|
||||
@ -225,7 +224,7 @@ class TLFragmenter(minSize: Int, maxSize: Int, alwaysMin: Boolean = false) exten
|
||||
out.a.valid := in.a.valid
|
||||
in.a.ready := out.a.ready && !delay
|
||||
out.a.bits := in.a.bits
|
||||
out.a.bits.address := in.a.bits.address | (~aFragnum << log2Ceil(minSize) & aOrigOH1)
|
||||
out.a.bits.addr_hi := in.a.bits.addr_hi | (~aFragnum << log2Ceil(minSize/beatBytes) & aOrigOH1 >> log2Ceil(beatBytes))
|
||||
out.a.bits.source := Cat(in.a.bits.source, aFragnum)
|
||||
out.a.bits.size := aFrag
|
||||
|
||||
|
@ -28,13 +28,13 @@ class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = f
|
||||
require (!supportClients || bce)
|
||||
|
||||
if (supportManagers) {
|
||||
val handleA = if (passthrough) !edgeOut.manager.supportsHint(in.a.bits.address) else Bool(true)
|
||||
val handleA = if (passthrough) !edgeOut.manager.supportsHint(edgeIn.address(in.a.bits)) else Bool(true)
|
||||
val bypassD = handleA && in.a.bits.opcode === TLMessages.Hint
|
||||
|
||||
// Prioritize existing D traffic over HintAck
|
||||
in.d.valid := out.d.valid || (bypassD && in.a.valid)
|
||||
out.d.ready := in.d.ready
|
||||
in.d.bits := Mux(out.d.valid, out.d.bits, edgeIn.HintAck(in.a.bits.source, in.a.bits.size))
|
||||
in.d.bits := Mux(out.d.valid, out.d.bits, edgeIn.HintAck(in.a.bits))
|
||||
|
||||
in.a.ready := Mux(bypassD, in.d.ready && !out.d.valid, out.a.ready)
|
||||
out.a.valid := in.a.valid && !bypassD
|
||||
@ -56,7 +56,7 @@ class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = f
|
||||
// Prioritize existing C traffic over HintAck
|
||||
out.c.valid := in.c.valid || (bypassC && in.b.valid)
|
||||
in.c.ready := out.c.ready
|
||||
out.c.bits := Mux(in.c.valid, in.c.bits, edgeOut.HintAck(out.b.bits.address, out.b.bits.size))
|
||||
out.c.bits := Mux(in.c.valid, in.c.bits, edgeOut.HintAck(out.b.bits))
|
||||
|
||||
out.b.ready := Mux(bypassC, out.c.ready && !in.c.valid, in.b.ready)
|
||||
in.b.valid := out.b.valid && !bypassC
|
||||
|
@ -50,7 +50,7 @@ object LazyModule
|
||||
}
|
||||
}
|
||||
|
||||
abstract class LazyModuleImp(val outer: LazyModule) extends Module
|
||||
abstract class LazyModuleImp(outer: LazyModule) extends Module
|
||||
{
|
||||
// .module had better not be accessed while LazyModules are still being built!
|
||||
require (LazyModule.stack.isEmpty)
|
||||
|
@ -104,14 +104,14 @@ class TLLegacy(implicit val p: Parameters) extends LazyModule with HasTileLinkPa
|
||||
// Get rid of some unneeded muxes
|
||||
out.a.bits.source := source
|
||||
out.a.bits.data := data
|
||||
out.a.bits.address := ~(~address | addressMask)
|
||||
out.a.bits.addr_hi := ~(~address | addressMask) >> log2Ceil(tlDataBytes)
|
||||
|
||||
// TL legacy does not support bus errors
|
||||
assert (!out.d.bits.error)
|
||||
|
||||
// Recreate the beat address counter
|
||||
val beatCounter = RegInit(UInt(0, width = tlBeatAddrBits))
|
||||
when (out.d.fire() && out.d.bits.hasData() && out.d.bits.size === block) {
|
||||
when (out.d.fire() && edge.hasData(out.d.bits) && out.d.bits.size === block) {
|
||||
beatCounter := beatCounter + UInt(1)
|
||||
}
|
||||
|
||||
|
@ -19,20 +19,20 @@ object TLMonitor
|
||||
|
||||
// Reuse these subexpressions to save some firrtl lines
|
||||
val source_ok = edge.client.contains(bundle.source)
|
||||
val is_aligned = edge.isAligned(bundle.address, bundle.size)
|
||||
val mask = edge.fullMask(bundle.address | edge.lowAddress(bundle.mask), bundle.size)
|
||||
val is_aligned = edge.isHiAligned(bundle.addr_hi, bundle.size)
|
||||
val mask = edge.mask(edge.addr_lo(bundle.mask), bundle.size)
|
||||
|
||||
when (bundle.opcode === TLMessages.Acquire) {
|
||||
assert (edge.manager.supportsAcquire(bundle.address, bundle.size), "'A' channel carries Acquire type unsupported by manager" + extra)
|
||||
assert (edge.manager.supportsAcquire(edge.address(bundle), bundle.size), "'A' channel carries Acquire type unsupported by manager" + extra)
|
||||
assert (source_ok, "'A' channel Acquire carries invalid source ID" + extra)
|
||||
assert (bundle.size >= UInt(log2Ceil(edge.manager.beatBytes)), "'A' channel Acquire smaller than a beat" + extra)
|
||||
assert (is_aligned, "'A' channel Acquire address not aligned to size" + extra)
|
||||
assert (TLPermissions.isGrow(bundle.param), "'A' channel Acquire carries invalid grow param" + extra)
|
||||
assert (bundle.mask === SInt(-1).asUInt, "'A' channel Acquire contains invalid mask" + extra)
|
||||
assert (~bundle.mask === UInt(0), "'A' channel Acquire contains invalid mask" + extra)
|
||||
}
|
||||
|
||||
when (bundle.opcode === TLMessages.Get) {
|
||||
assert (edge.manager.supportsGet(bundle.address, bundle.size), "'A' channel carries Get type unsupported by manager" + extra)
|
||||
assert (edge.manager.supportsGet(edge.address(bundle), bundle.size), "'A' channel carries Get type unsupported by manager" + extra)
|
||||
assert (source_ok, "'A' channel Get carries invalid source ID" + extra)
|
||||
assert (is_aligned, "'A' channel Get address not aligned to size" + extra)
|
||||
assert (bundle.param === UInt(0), "'A' channel Get carries invalid param" + extra)
|
||||
@ -40,7 +40,7 @@ object TLMonitor
|
||||
}
|
||||
|
||||
when (bundle.opcode === TLMessages.PutFullData) {
|
||||
assert (edge.manager.supportsPutFull(bundle.address, bundle.size), "'A' channel carries PutFull type unsupported by manager" + extra)
|
||||
assert (edge.manager.supportsPutFull(edge.address(bundle), bundle.size), "'A' channel carries PutFull type unsupported by manager" + extra)
|
||||
assert (source_ok, "'A' channel PutFull carries invalid source ID" + extra)
|
||||
assert (is_aligned, "'A' channel PutFull address not aligned to size" + extra)
|
||||
assert (bundle.param === UInt(0), "'A' channel PutFull carries invalid param" + extra)
|
||||
@ -48,7 +48,7 @@ object TLMonitor
|
||||
}
|
||||
|
||||
when (bundle.opcode === TLMessages.PutPartialData) {
|
||||
assert (edge.manager.supportsPutPartial(bundle.address, bundle.size), "'A' channel carries PutPartial type unsupported by manager" + extra)
|
||||
assert (edge.manager.supportsPutPartial(edge.address(bundle), bundle.size), "'A' channel carries PutPartial type unsupported by manager" + extra)
|
||||
assert (source_ok, "'A' channel PutPartial carries invalid source ID" + extra)
|
||||
assert (is_aligned, "'A' channel PutPartial address not aligned to size" + extra)
|
||||
assert (bundle.param === UInt(0), "'A' channel PutPartial carries invalid param" + extra)
|
||||
@ -57,7 +57,7 @@ object TLMonitor
|
||||
}
|
||||
|
||||
when (bundle.opcode === TLMessages.ArithmeticData) {
|
||||
assert (edge.manager.supportsArithmetic(bundle.address, bundle.size), "'A' channel carries Arithmetic type unsupported by manager" + extra)
|
||||
assert (edge.manager.supportsArithmetic(edge.address(bundle), bundle.size), "'A' channel carries Arithmetic type unsupported by manager" + extra)
|
||||
assert (source_ok, "'A' channel Arithmetic carries invalid source ID" + extra)
|
||||
assert (is_aligned, "'A' channel Arithmetic address not aligned to size" + extra)
|
||||
assert (TLAtomics.isArithmetic(bundle.param), "'A' channel Arithmetic carries invalid opcode param" + extra)
|
||||
@ -65,7 +65,7 @@ object TLMonitor
|
||||
}
|
||||
|
||||
when (bundle.opcode === TLMessages.LogicalData) {
|
||||
assert (edge.manager.supportsLogical(bundle.address, bundle.size), "'A' channel carries Logical type unsupported by manager" + extra)
|
||||
assert (edge.manager.supportsLogical(edge.address(bundle), bundle.size), "'A' channel carries Logical type unsupported by manager" + extra)
|
||||
assert (source_ok, "'A' channel Logical carries invalid source ID" + extra)
|
||||
assert (is_aligned, "'A' channel Logical address not aligned to size" + extra)
|
||||
assert (TLAtomics.isLogical(bundle.param), "'A' channel Logical carries invalid opcode param" + extra)
|
||||
@ -73,7 +73,7 @@ object TLMonitor
|
||||
}
|
||||
|
||||
when (bundle.opcode === TLMessages.Hint) {
|
||||
assert (edge.manager.supportsHint(bundle.address), "'A' channel carries Hint type unsupported by manager" + extra)
|
||||
assert (edge.manager.supportsHint(edge.address(bundle)), "'A' channel carries Hint type unsupported by manager" + extra)
|
||||
assert (source_ok, "'A' channel Hint carries invalid source ID" + extra)
|
||||
assert (is_aligned, "'A' channel Hint address not aligned to size" + extra)
|
||||
assert (bundle.mask === mask, "'A' channel Hint contains invalid mask" + extra)
|
||||
@ -85,8 +85,8 @@ object TLMonitor
|
||||
|
||||
// Reuse these subexpressions to save some firrtl lines
|
||||
val address_ok = edge.manager.contains(bundle.source)
|
||||
val is_aligned = edge.isAligned(bundle.address, bundle.size)
|
||||
val mask = edge.fullMask(bundle.address | edge.lowAddress(bundle.mask), bundle.size)
|
||||
val is_aligned = edge.isHiAligned(bundle.addr_hi, bundle.size)
|
||||
val mask = edge.mask(edge.addr_lo(bundle.mask), bundle.size)
|
||||
|
||||
when (bundle.opcode === TLMessages.Probe) {
|
||||
assert (edge.client.supportsProbe(bundle.source, bundle.size), "'B' channel carries Probe type unsupported by client" + extra)
|
||||
@ -94,7 +94,7 @@ object TLMonitor
|
||||
assert (bundle.size >= UInt(log2Ceil(edge.manager.beatBytes)), "'B' channel Probe smaller than a beat" + extra)
|
||||
assert (is_aligned, "'B' channel Probe address not aligned to size" + extra)
|
||||
assert (TLPermissions.isCap(bundle.param), "'B' channel Probe carries invalid cap param" + extra)
|
||||
assert (bundle.mask === SInt(-1).asUInt, "'B' channel Probe contains invalid mask" + extra)
|
||||
assert (~bundle.mask === UInt(0).asUInt, "'B' channel Probe contains invalid mask" + extra)
|
||||
}
|
||||
|
||||
when (bundle.opcode === TLMessages.Get) {
|
||||
@ -150,12 +150,12 @@ object TLMonitor
|
||||
assert (TLMessages.isC(bundle.opcode), "'C' channel has invalid opcode" + extra)
|
||||
|
||||
val source_ok = edge.client.contains(bundle.source)
|
||||
val is_aligned = edge.isAligned(bundle.address, bundle.size)
|
||||
val is_aligned = edge.isHiAligned(bundle.addr_hi, bundle.size) && edge.isLoAligned(bundle.addr_lo, bundle.size)
|
||||
val address_ok = edge.manager.contains(bundle.source)
|
||||
|
||||
when (bundle.opcode === TLMessages.ProbeAck) {
|
||||
assert (address_ok, "'C' channel ProbeAck carries unmanaged address" + extra)
|
||||
// source is ignored
|
||||
assert (source_ok, "'C' channel ProbeAck carries invalid source ID" + extra)
|
||||
assert (bundle.size >= UInt(log2Ceil(edge.manager.beatBytes)), "'C' channel ProbeAck smaller than a beat" + extra)
|
||||
assert (is_aligned, "'C' channel ProbeAck address not aligned to size" + extra)
|
||||
assert (TLPermissions.isReport(bundle.param), "'C' channel ProbeAck carries invalid report param" + extra)
|
||||
@ -164,7 +164,7 @@ object TLMonitor
|
||||
|
||||
when (bundle.opcode === TLMessages.ProbeAckData) {
|
||||
assert (address_ok, "'C' channel ProbeAckData carries unmanaged address" + extra)
|
||||
// source is ignored
|
||||
assert (source_ok, "'C' channel ProbeAckData carries invalid source ID" + extra)
|
||||
assert (bundle.size >= UInt(log2Ceil(edge.manager.beatBytes)), "'C' channel ProbeAckData smaller than a beat" + extra)
|
||||
assert (is_aligned, "'C' channel ProbeAckData address not aligned to size" + extra)
|
||||
assert (TLPermissions.isReport(bundle.param), "'C' channel ProbeAckData carries invalid report param" + extra)
|
||||
@ -172,7 +172,7 @@ object TLMonitor
|
||||
}
|
||||
|
||||
when (bundle.opcode === TLMessages.Release) {
|
||||
assert (edge.manager.supportsAcquire(bundle.address, bundle.size), "'C' channel carries Release type unsupported by manager" + extra)
|
||||
assert (edge.manager.supportsAcquire(edge.address(bundle), bundle.size), "'C' channel carries Release type unsupported by manager" + extra)
|
||||
assert (source_ok, "'C' channel Release carries invalid source ID" + extra)
|
||||
assert (bundle.size >= UInt(log2Ceil(edge.manager.beatBytes)), "'C' channel Release smaller than a beat" + extra)
|
||||
assert (is_aligned, "'C' channel Release address not aligned to size" + extra)
|
||||
@ -181,7 +181,7 @@ object TLMonitor
|
||||
}
|
||||
|
||||
when (bundle.opcode === TLMessages.ReleaseData) {
|
||||
assert (edge.manager.supportsAcquire(bundle.address, bundle.size), "'C' channel carries ReleaseData type unsupported by manager" + extra)
|
||||
assert (edge.manager.supportsAcquire(edge.address(bundle), bundle.size), "'C' channel carries ReleaseData type unsupported by manager" + extra)
|
||||
assert (source_ok, "'C' channel ReleaseData carries invalid source ID" + extra)
|
||||
assert (bundle.size >= UInt(log2Ceil(edge.manager.beatBytes)), "'C' channel ReleaseData smaller than a beat" + extra)
|
||||
assert (is_aligned, "'C' channel ReleaseData address not aligned to size" + extra)
|
||||
@ -191,21 +191,21 @@ object TLMonitor
|
||||
|
||||
when (bundle.opcode === TLMessages.AccessAck) {
|
||||
assert (address_ok, "'C' channel AccessAck carries unmanaged address" + extra)
|
||||
// source is ignored
|
||||
assert (source_ok, "'C' channel AccessAck carries invalid source ID" + extra)
|
||||
assert (is_aligned, "'C' channel AccessAck address not aligned to size" + extra)
|
||||
assert (bundle.param === UInt(0), "'C' channel AccessAck carries invalid param" + extra)
|
||||
}
|
||||
|
||||
when (bundle.opcode === TLMessages.AccessAckData) {
|
||||
assert (address_ok, "'C' channel AccessAckData carries unmanaged address" + extra)
|
||||
// source is ignored
|
||||
assert (source_ok, "'C' channel AccessAckData carries invalid source ID" + extra)
|
||||
assert (is_aligned, "'C' channel AccessAckData address not aligned to size" + extra)
|
||||
assert (bundle.param === UInt(0), "'C' channel AccessAckData carries invalid param" + extra)
|
||||
}
|
||||
|
||||
when (bundle.opcode === TLMessages.HintAck) {
|
||||
assert (address_ok, "'C' channel HintAck carries unmanaged address" + extra)
|
||||
// source is ignored
|
||||
assert (source_ok, "'C' channel HintAck carries invalid source ID" + extra)
|
||||
assert (is_aligned, "'C' channel HintAck address not aligned to size" + extra)
|
||||
assert (bundle.param === UInt(0), "'C' channel HintAck carries invalid param" + extra)
|
||||
assert (!bundle.error, "'C' channel HintAck carries an error" + extra)
|
||||
@ -216,11 +216,13 @@ object TLMonitor
|
||||
assert (TLMessages.isD(bundle.opcode), "'D' channel has invalid opcode" + extra)
|
||||
|
||||
val source_ok = edge.client.contains(bundle.source)
|
||||
val is_aligned = edge.isLoAligned(bundle.addr_lo, bundle.size)
|
||||
val sink_ok = edge.manager.containsById(bundle.sink)
|
||||
|
||||
when (bundle.opcode === TLMessages.ReleaseAck) {
|
||||
assert (source_ok, "'D' channel ReleaseAck carries invalid source ID" + extra)
|
||||
// sink is ignored
|
||||
assert (is_aligned, "'D' channel ReleaseAck address not aligned to size" + extra)
|
||||
assert (sink_ok, "'D' channel ReleaseAck carries invalid sink ID" + extra)
|
||||
assert (bundle.size >= UInt(log2Ceil(edge.manager.beatBytes)), "'D' channel ReleaseAck smaller than a beat" + extra)
|
||||
assert (bundle.param === UInt(0), "'D' channel ReleaseeAck carries invalid param" + extra)
|
||||
assert (!bundle.error, "'D' channel ReleaseAck carries an error" + extra)
|
||||
@ -228,6 +230,7 @@ object TLMonitor
|
||||
|
||||
when (bundle.opcode === TLMessages.Grant) {
|
||||
assert (source_ok, "'D' channel Grant carries invalid source ID" + extra)
|
||||
assert (is_aligned, "'D' channel Grant address not aligned to size" + extra)
|
||||
assert (sink_ok, "'D' channel Grant carries invalid sink ID" + extra)
|
||||
assert (bundle.size >= UInt(log2Ceil(edge.manager.beatBytes)), "'D' channel Grant smaller than a beat" + extra)
|
||||
assert (TLPermissions.isCap(bundle.param), "'D' channel Grant carries invalid cap param" + extra)
|
||||
@ -235,6 +238,7 @@ object TLMonitor
|
||||
|
||||
when (bundle.opcode === TLMessages.GrantData) {
|
||||
assert (source_ok, "'D' channel GrantData carries invalid source ID" + extra)
|
||||
assert (is_aligned, "'D' channel GrantData address not aligned to size" + extra)
|
||||
assert (sink_ok, "'D' channel GrantData carries invalid sink ID" + extra)
|
||||
assert (bundle.size >= UInt(log2Ceil(edge.manager.beatBytes)), "'D' channel GrantData smaller than a beat" + extra)
|
||||
assert (TLPermissions.isCap(bundle.param), "'D' channel GrantData carries invalid cap param" + extra)
|
||||
@ -242,21 +246,24 @@ object TLMonitor
|
||||
|
||||
when (bundle.opcode === TLMessages.AccessAck) {
|
||||
assert (source_ok, "'D' channel AccessAck carries invalid source ID" + extra)
|
||||
// sink is ignored
|
||||
assert (is_aligned, "'D' channel AccessAck address not aligned to size" + extra)
|
||||
assert (sink_ok, "'D' channel AccessAck carries invalid sink ID" + extra)
|
||||
// size is ignored
|
||||
assert (bundle.param === UInt(0), "'D' channel AccessAck carries invalid param" + extra)
|
||||
}
|
||||
|
||||
when (bundle.opcode === TLMessages.AccessAckData) {
|
||||
assert (source_ok, "'D' channel AccessAckData carries invalid source ID" + extra)
|
||||
// sink is ignored
|
||||
assert (is_aligned, "'D' channel AccessAckData address not aligned to size" + extra)
|
||||
assert (sink_ok, "'D' channel AccessAckData carries invalid sink ID" + extra)
|
||||
// size is ignored
|
||||
assert (bundle.param === UInt(0), "'D' channel AccessAckData carries invalid param" + extra)
|
||||
}
|
||||
|
||||
when (bundle.opcode === TLMessages.HintAck) {
|
||||
assert (source_ok, "'D' channel HintAck carries invalid source ID" + extra)
|
||||
// sink is ignored
|
||||
assert (is_aligned, "'D' channel HintAck address not aligned to size" + extra)
|
||||
assert (sink_ok, "'D' channel HintAck carries invalid sink ID" + extra)
|
||||
// size is ignored
|
||||
assert (bundle.param === UInt(0), "'D' channel HintAck carries invalid param" + extra)
|
||||
assert (!bundle.error, "'D' channel HintAck carries an error" + extra)
|
||||
@ -281,13 +288,13 @@ object TLMonitor
|
||||
val param = Reg(UInt())
|
||||
val size = Reg(UInt())
|
||||
val source = Reg(UInt())
|
||||
val address = Reg(UInt())
|
||||
val addr_hi = Reg(UInt())
|
||||
when (a.valid && counter =/= UInt(0)) {
|
||||
assert (a.bits.opcode === opcode, "'A' channel opcode changed within multibeat operation" + extra)
|
||||
assert (a.bits.param === param, "'A' channel param changed within multibeat operation" + extra)
|
||||
assert (a.bits.size === size, "'A' channel size changed within multibeat operation" + extra)
|
||||
assert (a.bits.source === source, "'A' channel source changed within multibeat operation" + extra)
|
||||
assert (a.bits.address=== address,"'A' channel address changed with multibeat operation" + extra)
|
||||
assert (a.bits.addr_hi=== addr_hi,"'A' channel addr_hi changed with multibeat operation" + extra)
|
||||
}
|
||||
when (a.fire()) {
|
||||
counter := counter - UInt(1)
|
||||
@ -297,7 +304,7 @@ object TLMonitor
|
||||
param := a.bits.param
|
||||
size := a.bits.size
|
||||
source := a.bits.source
|
||||
address := a.bits.address
|
||||
addr_hi := a.bits.addr_hi
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -308,13 +315,13 @@ object TLMonitor
|
||||
val param = Reg(UInt())
|
||||
val size = Reg(UInt())
|
||||
val source = Reg(UInt())
|
||||
val address = Reg(UInt())
|
||||
val addr_hi = Reg(UInt())
|
||||
when (b.valid && counter =/= UInt(0)) {
|
||||
assert (b.bits.opcode === opcode, "'B' channel opcode changed within multibeat operation" + extra)
|
||||
assert (b.bits.param === param, "'B' channel param changed within multibeat operation" + extra)
|
||||
assert (b.bits.size === size, "'B' channel size changed within multibeat operation" + extra)
|
||||
assert (b.bits.source === source, "'B' channel source changed within multibeat operation" + extra)
|
||||
assert (b.bits.address=== address,"'B' channel address changed with multibeat operation" + extra)
|
||||
assert (b.bits.addr_hi=== addr_hi,"'B' channel addr_hi changed with multibeat operation" + extra)
|
||||
}
|
||||
when (b.fire()) {
|
||||
counter := counter - UInt(1)
|
||||
@ -324,7 +331,7 @@ object TLMonitor
|
||||
param := b.bits.param
|
||||
size := b.bits.size
|
||||
source := b.bits.source
|
||||
address := b.bits.address
|
||||
addr_hi := b.bits.addr_hi
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -335,13 +342,15 @@ object TLMonitor
|
||||
val param = Reg(UInt())
|
||||
val size = Reg(UInt())
|
||||
val source = Reg(UInt())
|
||||
val address = Reg(UInt())
|
||||
val addr_hi = Reg(UInt())
|
||||
val addr_lo = Reg(UInt())
|
||||
when (c.valid && counter =/= UInt(0)) {
|
||||
assert (c.bits.opcode === opcode, "'C' channel opcode changed within multibeat operation" + extra)
|
||||
assert (c.bits.param === param, "'C' channel param changed within multibeat operation" + extra)
|
||||
assert (c.bits.size === size, "'C' channel size changed within multibeat operation" + extra)
|
||||
assert (c.bits.source === source, "'C' channel source changed within multibeat operation" + extra)
|
||||
assert (c.bits.address=== address,"'C' channel address changed with multibeat operation" + extra)
|
||||
assert (c.bits.addr_hi=== addr_hi,"'C' channel addr_hi changed with multibeat operation" + extra)
|
||||
assert (c.bits.addr_lo=== addr_lo,"'C' channel addr_lo changed with multibeat operation" + extra)
|
||||
}
|
||||
when (c.fire()) {
|
||||
counter := counter - UInt(1)
|
||||
@ -351,7 +360,8 @@ object TLMonitor
|
||||
param := c.bits.param
|
||||
size := c.bits.size
|
||||
source := c.bits.source
|
||||
address := c.bits.address
|
||||
addr_hi := c.bits.addr_hi
|
||||
addr_lo := c.bits.addr_lo
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -363,12 +373,14 @@ object TLMonitor
|
||||
val size = Reg(UInt())
|
||||
val source = Reg(UInt())
|
||||
val sink = Reg(UInt())
|
||||
val addr_lo = Reg(UInt())
|
||||
when (d.valid && counter =/= UInt(0)) {
|
||||
assert (d.bits.opcode === opcode, "'D' channel opcode changed within multibeat operation" + extra)
|
||||
assert (d.bits.param === param, "'D' channel param changed within multibeat operation" + extra)
|
||||
assert (d.bits.size === size, "'D' channel size changed within multibeat operation" + extra)
|
||||
assert (d.bits.source === source, "'D' channel source changed within multibeat operation" + extra)
|
||||
assert (d.bits.sink === sink, "'D' channel sink changed with multibeat operation" + extra)
|
||||
assert (d.bits.addr_lo=== addr_lo,"'C' channel addr_lo changed with multibeat operation" + extra)
|
||||
}
|
||||
when (d.fire()) {
|
||||
counter := counter - UInt(1)
|
||||
@ -379,6 +391,7 @@ object TLMonitor
|
||||
size := d.bits.size
|
||||
source := d.bits.source
|
||||
sink := d.bits.sink
|
||||
addr_lo := d.bits.addr_lo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,25 +19,25 @@ class TLNarrower(innerBeatBytes: Int) extends LazyModule
|
||||
val out = node.bundleOut
|
||||
}
|
||||
|
||||
val edge = node.edgesOut(0)
|
||||
val outerBeatBytes = edge.manager.beatBytes
|
||||
val edgeOut = node.edgesOut(0)
|
||||
val edgeIn = node.edgesIn(0)
|
||||
val outerBeatBytes = edgeOut.manager.beatBytes
|
||||
require (outerBeatBytes < innerBeatBytes)
|
||||
|
||||
val ratio = innerBeatBytes / outerBeatBytes
|
||||
val bce = edge.manager.anySupportAcquire && edge.client.anySupportProbe
|
||||
val bce = edgeOut.manager.anySupportAcquire && edgeIn.client.anySupportProbe
|
||||
|
||||
def UIntToOH1(x: UInt, width: Int) = ~(SInt(-1, width=width).asUInt << x)(width-1, 0)
|
||||
def trailingZeros(x: Int) = if (x > 0) Some(log2Ceil(x & -x)) else None
|
||||
|
||||
def split(in: HasTLData, fire: Bool): (Bool, UInt, UInt) = {
|
||||
val dataSlices = Vec.tabulate (ratio) { i => in.data()((i+1)*outerBeatBytes*8-1, i*outerBeatBytes*8) }
|
||||
val maskSlices = Vec.tabulate (ratio) { i => in.mask()((i+1)*outerBeatBytes -1, i*outerBeatBytes) }
|
||||
def split(edge: TLEdge, in: TLDataChannel, fire: Bool): (Bool, UInt, UInt) = {
|
||||
val dataSlices = Vec.tabulate (ratio) { i => edge.data(in)((i+1)*outerBeatBytes*8-1, i*outerBeatBytes*8) }
|
||||
val maskSlices = Vec.tabulate (ratio) { i => edge.mask(in)((i+1)*outerBeatBytes -1, i*outerBeatBytes) }
|
||||
val filter = Reg(UInt(width = ratio), init = SInt(-1, width = ratio).asUInt)
|
||||
val mask = maskSlices.map(_.orR)
|
||||
val hasData = edge.hasData(in)
|
||||
|
||||
// decoded_size = 1111 (for smallest), 0101, 0001 (for largest)
|
||||
val sizeOH1 = UIntToOH1(in.size(), log2Ceil(innerBeatBytes)) >> log2Ceil(outerBeatBytes)
|
||||
val sizeOH1 = UIntToOH1(edge.size(in), log2Ceil(innerBeatBytes)) >> log2Ceil(outerBeatBytes)
|
||||
val decoded_size = Seq.tabulate(ratio) { i => trailingZeros(i).map(!sizeOH1(_)).getOrElse(Bool(true)) }
|
||||
|
||||
val first = filter(ratio-1)
|
||||
@ -56,12 +56,12 @@ class TLNarrower(innerBeatBytes: Int) extends LazyModule
|
||||
}
|
||||
}
|
||||
|
||||
def merge(in: HasTLData, fire: Bool): (Bool, UInt) = {
|
||||
def merge(edge: TLEdge, in: TLDataChannel, fire: Bool): (Bool, UInt) = {
|
||||
val count = RegInit(UInt(0, width = log2Ceil(ratio)))
|
||||
val rdata = Reg(UInt(width = (ratio-1)*outerBeatBytes*8))
|
||||
val data = Cat(in.data(), rdata)
|
||||
val data = Cat(edge.data(in), rdata)
|
||||
val first = count === UInt(0)
|
||||
val limit = UIntToOH1(in.size(), log2Ceil(innerBeatBytes)) >> log2Ceil(outerBeatBytes)
|
||||
val limit = UIntToOH1(edge.size(in), log2Ceil(innerBeatBytes)) >> log2Ceil(outerBeatBytes)
|
||||
val last = count === limit || !edge.hasData(in)
|
||||
|
||||
when (fire) {
|
||||
@ -82,21 +82,22 @@ class TLNarrower(innerBeatBytes: Int) extends LazyModule
|
||||
if (edge.staticHasData(in) == Some(false)) {
|
||||
(Bool(true), UInt(0))
|
||||
} else {
|
||||
(last, mux(in.size()))
|
||||
(last, mux(edge.size(in)))
|
||||
}
|
||||
}
|
||||
|
||||
val in = io.in(0)
|
||||
val out = io.out(0)
|
||||
|
||||
val (alast, adata, amask) = split(in.a.bits, out.a.fire())
|
||||
val (alast, adata, amask) = split(edgeIn, in.a.bits, out.a.fire())
|
||||
in.a.ready := out.a.ready && alast
|
||||
out.a.valid := in.a.valid
|
||||
out.a.bits := in.a.bits
|
||||
out.a.bits.addr_hi := Cat(in.a.bits.addr_hi, edgeIn.addr_lo(in.a.bits) >> log2Ceil(outerBeatBytes))
|
||||
out.a.bits.data := adata
|
||||
out.a.bits.mask := amask
|
||||
|
||||
val (dlast, ddata) = merge(out.d.bits, out.d.fire())
|
||||
val (dlast, ddata) = merge(edgeOut, out.d.bits, out.d.fire())
|
||||
out.d.ready := in.d.ready || !dlast
|
||||
in.d.valid := out.d.valid && dlast
|
||||
in.d.bits := out.d.bits
|
||||
|
@ -286,23 +286,25 @@ case class TLClientPortParameters(clients: Seq[TLClientParameters]) {
|
||||
}
|
||||
|
||||
case class TLBundleParameters(
|
||||
addressBits: Int,
|
||||
addrHiBits: Int,
|
||||
dataBits: Int,
|
||||
sourceBits: Int,
|
||||
sinkBits: Int,
|
||||
sizeBits: Int)
|
||||
{
|
||||
// Chisel has issues with 0-width wires
|
||||
require (addressBits >= 1)
|
||||
require (dataBits >= 1)
|
||||
require (addrHiBits >= 1)
|
||||
require (dataBits >= 8)
|
||||
require (sourceBits >= 1)
|
||||
require (sinkBits >= 1)
|
||||
require (sizeBits >= 1)
|
||||
require (isPow2(dataBits))
|
||||
|
||||
val addrLoBits = log2Up(dataBits/8)
|
||||
|
||||
def union(x: TLBundleParameters) =
|
||||
TLBundleParameters(
|
||||
max(addressBits, x.addressBits),
|
||||
max(addrHiBits, x.addrHiBits),
|
||||
max(dataBits, x.dataBits),
|
||||
max(sourceBits, x.sourceBits),
|
||||
max(sinkBits, x.sinkBits),
|
||||
@ -320,7 +322,7 @@ case class TLEdgeParameters(
|
||||
require (maxTransfer >= manager.beatBytes)
|
||||
|
||||
val bundle = TLBundleParameters(
|
||||
addressBits = log2Up(manager.maxAddress + 1),
|
||||
addrHiBits = log2Up(manager.maxAddress + 1) - log2Up(manager.beatBytes),
|
||||
dataBits = manager.beatBytes * 8,
|
||||
sourceBits = log2Up(client.endSourceId),
|
||||
sinkBits = log2Up(manager.endSinkId),
|
||||
|
@ -21,13 +21,19 @@ class TLRegisterNode(address: AddressSet, concurrency: Option[Int] = None, beatB
|
||||
val d = bundleIn(0).d
|
||||
val edge = edgesIn(0)
|
||||
|
||||
val params = RegMapperParams(log2Up(address.mask+1), beatBytes, edge.bundle.sourceBits + edge.bundle.sizeBits)
|
||||
// Please forgive me ...
|
||||
val baseEnd = 0
|
||||
val (sizeEnd, sizeOff) = (edge.bundle.sizeBits + baseEnd, baseEnd)
|
||||
val (sourceEnd, sourceOff) = (edge.bundle.sourceBits + sizeEnd, sizeEnd)
|
||||
val (addrLoEnd, addrLoOff) = (log2Ceil(beatBytes) + sourceEnd, sourceEnd)
|
||||
|
||||
val params = RegMapperParams(log2Up(address.mask+1), beatBytes, addrLoEnd)
|
||||
val in = Wire(Decoupled(new RegMapperInput(params)))
|
||||
in.bits.read := a.bits.opcode === TLMessages.Get
|
||||
in.bits.index := a.bits.address >> log2Ceil(beatBytes)
|
||||
in.bits.index := a.bits.addr_hi
|
||||
in.bits.data := a.bits.data
|
||||
in.bits.mask := a.bits.mask
|
||||
in.bits.extra := Cat(a.bits.source, a.bits.size)
|
||||
in.bits.extra := Cat(edge.addr_lo(a.bits), a.bits.source, a.bits.size)
|
||||
|
||||
// Invoke the register map builder
|
||||
val (endIndex, out) = RegMapper(beatBytes, concurrency, in, mapping:_*)
|
||||
@ -41,8 +47,13 @@ class TLRegisterNode(address: AddressSet, concurrency: Option[Int] = None, beatB
|
||||
d.valid := out.valid
|
||||
out.ready := d.ready
|
||||
|
||||
val sizeBits = edge.bundle.sizeBits
|
||||
d.bits := edge.AccessAck(out.bits.extra >> sizeBits, out.bits.extra(sizeBits-1, 0))
|
||||
// We must restore the size and addr_lo to enable width adapters to work
|
||||
d.bits := edge.AccessAck(
|
||||
fromAddress = out.bits.extra(addrLoEnd-1, addrLoOff),
|
||||
fromSink = UInt(0), // our unique sink id
|
||||
toSource = out.bits.extra(sourceEnd-1, sourceOff),
|
||||
lgSize = out.bits.extra(sizeEnd-1, sizeOff))
|
||||
|
||||
// avoid a Mux on the data bus by manually overriding two fields
|
||||
d.bits.data := out.bits.data
|
||||
d.bits.opcode := Mux(out.bits.read, TLMessages.AccessAckData, TLMessages.AccessAck)
|
||||
|
@ -24,10 +24,10 @@ class TLRAM(address: AddressSet, beatBytes: Int = 4) extends LazyModule
|
||||
|
||||
def bigBits(x: BigInt, tail: List[Boolean] = List.empty[Boolean]): List[Boolean] =
|
||||
if (x == 0) tail.reverse else bigBits(x >> 1, ((x & 1) == 1) :: tail)
|
||||
val mask = bigBits(address.mask - (beatBytes-1))
|
||||
val mask = bigBits(address.mask >> log2Ceil(beatBytes))
|
||||
|
||||
val in = io.in(0)
|
||||
val addrBits = (mask zip in.a.bits.address.toBools).filter(_._1).map(_._2)
|
||||
val addrBits = (mask zip in.a.bits.addr_hi.toBools).filter(_._1).map(_._2)
|
||||
val memAddress = Cat(addrBits.reverse)
|
||||
val mem = SeqMem(1 << addrBits.size, Vec(beatBytes, Bits(width = 8)))
|
||||
|
||||
@ -35,6 +35,7 @@ class TLRAM(address: AddressSet, beatBytes: Int = 4) extends LazyModule
|
||||
val d_read = Reg(Bool())
|
||||
val d_size = Reg(UInt())
|
||||
val d_source = Reg(UInt())
|
||||
val d_addr = Reg(UInt())
|
||||
val d_data = Wire(UInt())
|
||||
|
||||
// Flow control
|
||||
@ -43,7 +44,8 @@ class TLRAM(address: AddressSet, beatBytes: Int = 4) extends LazyModule
|
||||
in.d.valid := d_full
|
||||
in.a.ready := in.d.ready || !d_full
|
||||
|
||||
in.d.bits := node.edgesIn(0).AccessAck(d_source, d_size)
|
||||
val edge = node.edgesIn(0)
|
||||
in.d.bits := edge.AccessAck(d_addr, UInt(0), d_source, d_size)
|
||||
// avoid data-bus Mux
|
||||
in.d.bits.data := d_data
|
||||
in.d.bits.opcode := Mux(d_read, TLMessages.AccessAckData, TLMessages.AccessAck)
|
||||
@ -56,6 +58,7 @@ class TLRAM(address: AddressSet, beatBytes: Int = 4) extends LazyModule
|
||||
d_read := read
|
||||
d_size := in.a.bits.size
|
||||
d_source := in.a.bits.source
|
||||
d_addr := edge.addr_lo(in.a.bits)
|
||||
when (read) {
|
||||
rdata := mem.read(memAddress)
|
||||
} .otherwise {
|
||||
|
@ -23,10 +23,6 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL
|
||||
require (eo.asInstanceOf[TLEdgeParameters] == ei.asInstanceOf[TLEdgeParameters])
|
||||
TLMonitor.legalize(bo, eo, bi, ei)
|
||||
bi <> bo
|
||||
val mask = UInt(ei.manager.beatBytes - 1)
|
||||
bi.a.bits.address := ~(mask | ~bo.a.bits.address)
|
||||
bo.b.bits.address := ~(mask | ~bi.b.bits.address)
|
||||
bi.c.bits.address := ~(mask | ~bo.c.bits.address)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,9 +145,9 @@ class TLXbar(policy: (Vec[Bool], Bool) => Seq[Bool] = TLXbar.lowestIndex) extend
|
||||
in(i).e.ready := Mux1C(grantedEIO(i), out.map(_.e.ready))
|
||||
}
|
||||
|
||||
val requestAIO = Vec(in.map { i => Vec(node.edgesOut.map { o => i.a.valid && o.manager.contains(i.a.bits.address) }) })
|
||||
val requestAIO = Vec(in.map { i => Vec(node.edgesOut.map { o => i.a.valid && o.manager.contains(o.address(i.a.bits)) }) })
|
||||
val requestBOI = Vec(out.map { o => Vec(inputIdRanges.map { i => o.b.valid && i .contains(o.b.bits.source) }) })
|
||||
val requestCIO = Vec(in.map { i => Vec(node.edgesOut.map { o => i.c.valid && o.manager.contains(i.c.bits.address) }) })
|
||||
val requestCIO = Vec(in.map { i => Vec(node.edgesOut.map { o => i.c.valid && o.manager.contains(o.address(i.c.bits)) }) })
|
||||
val requestDOI = Vec(out.map { o => Vec(inputIdRanges.map { i => o.d.valid && i .contains(o.d.bits.source) }) })
|
||||
val requestEIO = Vec(in.map { i => Vec(outputIdRanges.map { o => i.e.valid && o .contains(i.e.bits.sink) }) })
|
||||
|
||||
|
@ -5,4 +5,6 @@ import Chisel._
|
||||
package object tilelink2
|
||||
{
|
||||
type TLBaseNode = BaseNode[TLClientPortParameters, TLManagerPortParameters, TLEdgeOut, TLEdgeIn, TLBundle]
|
||||
def OH1ToUInt(x: UInt) = OHToUInt((x << 1 | UInt(1)) ^ x)
|
||||
def UIntToOH1(x: UInt, width: Int) = ~(SInt(-1, width=width).asUInt << x)(width-1, 0)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user