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:
		| @@ -100,151 +100,72 @@ object TLAtomics | |||||||
|   def isLogical(x: UInt) = x <= SWAP |   def isLogical(x: UInt) = x <= SWAP | ||||||
| } | } | ||||||
|  |  | ||||||
| class Bogus | sealed trait TLChannel | ||||||
| object Bogus | sealed trait TLDataChannel extends TLChannel | ||||||
| { | sealed trait TLAddrChannel extends TLDataChannel | ||||||
|   def apply() = new Bogus |  | ||||||
| } |  | ||||||
|  |  | ||||||
| object ChannelType { | final class TLBundleA(params: TLBundleParameters) | ||||||
|   sealed trait T |   extends TLBundleBase(params) with TLAddrChannel | ||||||
|   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 |  | ||||||
| { | { | ||||||
|   // fixed fields during multibeat: |   // fixed fields during multibeat: | ||||||
|   val opcode  = UInt(width = 3) |   val opcode  = UInt(width = 3) | ||||||
|   val param   = UInt(width = 3) // amo_opcode || perms || hint |   val param   = UInt(width = 3) // amo_opcode || perms || hint | ||||||
|   val size    = UInt(width = params.sizeBits) |   val size    = UInt(width = params.sizeBits) | ||||||
|   val source  = UInt(width = params.sourceBits)  // from |   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: |   // variable fields during multibeat: | ||||||
|   val mask    = UInt(width = params.dataBits/8) |   val mask    = UInt(width = params.dataBits/8) | ||||||
|   val data    = UInt(width = params.dataBits) |   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) | final class TLBundleB(params: TLBundleParameters) | ||||||
|   extends TLBundleBase(params) |   extends TLBundleBase(params) with TLAddrChannel | ||||||
|   with HasTLData |  | ||||||
| { | { | ||||||
|   // fixed fields during multibeat: |   // fixed fields during multibeat: | ||||||
|   val opcode  = UInt(width = 3) |   val opcode  = UInt(width = 3) | ||||||
|   val param   = UInt(width = 3) |   val param   = UInt(width = 3) | ||||||
|   val size    = UInt(width = params.sizeBits) |   val size    = UInt(width = params.sizeBits) | ||||||
|   val source  = UInt(width = params.sourceBits)  // to |   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: |   // variable fields during multibeat: | ||||||
|   val mask    = UInt(width = params.dataBits/8) |   val mask    = UInt(width = params.dataBits/8) | ||||||
|   val data    = UInt(width = params.dataBits) |   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) | final class TLBundleC(params: TLBundleParameters) | ||||||
|   extends TLBundleBase(params) |   extends TLBundleBase(params) with TLAddrChannel | ||||||
|   with HasTLData |  | ||||||
| { | { | ||||||
|   // fixed fields during multibeat: |   // fixed fields during multibeat: | ||||||
|   val opcode  = UInt(width = 3) |   val opcode  = UInt(width = 3) | ||||||
|   val param   = UInt(width = 3) |   val param   = UInt(width = 3) | ||||||
|   val size    = UInt(width = params.sizeBits) |   val size    = UInt(width = params.sizeBits) | ||||||
|   val source  = UInt(width = params.sourceBits)  // from |   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: |   // variable fields during multibeat: | ||||||
|   val data    = UInt(width = params.dataBits) |   val data    = UInt(width = params.dataBits) | ||||||
|   val error   = Bool() // AccessAck[Data] |   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) | final class TLBundleD(params: TLBundleParameters) | ||||||
|   extends TLBundleBase(params) |   extends TLBundleBase(params) with TLDataChannel | ||||||
|   with HasTLData |  | ||||||
| { | { | ||||||
|   // fixed fields during multibeat: |   // fixed fields during multibeat: | ||||||
|   val opcode = UInt(width = 3) |   val opcode  = UInt(width = 3) | ||||||
|   val param  = UInt(width = 2) |   val param   = UInt(width = 2) | ||||||
|   val size   = UInt(width = params.sizeBits) |   val size    = UInt(width = params.sizeBits) | ||||||
|   val source = UInt(width = params.sourceBits) // to |   val source  = UInt(width = params.sourceBits) // to | ||||||
|   val sink   = UInt(width = params.sinkBits)   // from |   val sink    = UInt(width = params.sinkBits)   // from | ||||||
|  |   val addr_lo = UInt(width = params.addrLoBits) // instead of mask | ||||||
|   // variable fields during multibeat: |   // variable fields during multibeat: | ||||||
|   val data   = UInt(width = params.dataBits) |   val data    = UInt(width = params.dataBits) | ||||||
|   val error  = Bool() // AccessAck[Data], Grant[Data] |   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) | final class TLBundleE(params: TLBundleParameters) | ||||||
|   extends TLBundleBase(params) |   extends TLBundleBase(params) with TLChannel | ||||||
|   with HasTLOpcode |  | ||||||
| { | { | ||||||
|   val sink = UInt(width = params.sourceBits) // to |   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) | class TLBundle(params: TLBundleParameters) extends TLBundleBase(params) | ||||||
|   | |||||||
| @@ -10,14 +10,22 @@ class TLEdge( | |||||||
|   manager: TLManagerPortParameters) |   manager: TLManagerPortParameters) | ||||||
|   extends TLEdgeParameters(client, manager) |   extends TLEdgeParameters(client, manager) | ||||||
| { | { | ||||||
|   def isAligned(address: UInt, lgSize: UInt) = |   def isHiAligned(addr_hi: UInt, lgSize: UInt): Bool = { | ||||||
|     if (maxLgSize == 0) Bool(true) else { |     if (maxLgSize == 0) Bool(true) else { | ||||||
|       val mask = ~(SInt(-1, width=maxLgSize).asUInt << lgSize)(maxLgSize-1, 0) |       val mask = UIntToOH1(lgSize, maxLgSize) >> log2Ceil(manager.beatBytes) | ||||||
|       (address & mask) === UInt(0) |       (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 ... |   // 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 lgBytes = log2Ceil(manager.beatBytes) | ||||||
|     val sizeOH = UIntToOH(lgSize, lgBytes) |     val sizeOH = UIntToOH(lgSize, lgBytes) | ||||||
|     def helper(i: Int): Seq[(Bool, Bool)] = { |     def helper(i: Int): Seq[(Bool, Bool)] = { | ||||||
| @@ -26,7 +34,7 @@ class TLEdge( | |||||||
|       } else { |       } else { | ||||||
|         val sub = helper(i-1) |         val sub = helper(i-1) | ||||||
|         val size = sizeOH(lgBytes - i) |         val size = sizeOH(lgBytes - i) | ||||||
|         val bit = address(lgBytes - i) |         val bit = addr_lo(lgBytes - i) | ||||||
|         val nbit = !bit |         val nbit = !bit | ||||||
|         Seq.tabulate (1 << i) { j => |         Seq.tabulate (1 << i) { j => | ||||||
|           val (sub_acc, sub_eq) = sub(j/2) |           val (sub_acc, sub_eq) = sub(j/2) | ||||||
| @@ -39,8 +47,8 @@ class TLEdge( | |||||||
|     Cat(helper(lgBytes).map(_._1).reverse) |     Cat(helper(lgBytes).map(_._1).reverse) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   def lowAddress(mask: UInt) = { |   def addr_lo(mask: UInt): UInt = { | ||||||
|     // Almost OHToUInt, but any bit in low => use low address |     // Almost OHToUInt, but bits set => bits not set | ||||||
|     def helper(mask: UInt, width: Int): UInt = { |     def helper(mask: UInt, width: Int): UInt = { | ||||||
|       if (width <= 1) { |       if (width <= 1) { | ||||||
|         UInt(0) |         UInt(0) | ||||||
| @@ -56,9 +64,9 @@ class TLEdge( | |||||||
|     helper(mask, bundle.dataBits/8) |     helper(mask, bundle.dataBits/8) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   def staticHasData(bundle: HasTLOpcode): Option[Boolean] = { |   def staticHasData(bundle: TLChannel): Option[Boolean] = { | ||||||
|     bundle.channelType() match { |     bundle match { | ||||||
|       case ChannelType.A => { |       case _:TLBundleA => { | ||||||
|         // Do there exist A messages with Data? |         // Do there exist A messages with Data? | ||||||
|         val aDataYes = manager.anySupportArithmetic || manager.anySupportLogical || manager.anySupportPutFull || manager.anySupportPutPartial |         val aDataYes = manager.anySupportArithmetic || manager.anySupportLogical || manager.anySupportPutFull || manager.anySupportPutPartial | ||||||
|         // Do there exist A messages without Data? |         // Do there exist A messages without Data? | ||||||
| @@ -66,7 +74,7 @@ class TLEdge( | |||||||
|         // Statically optimize the case where hasData is a constant |         // Statically optimize the case where hasData is a constant | ||||||
|         if (!aDataYes) Some(false) else if (!aDataNo) Some(true) else None |         if (!aDataYes) Some(false) else if (!aDataNo) Some(true) else None | ||||||
|       } |       } | ||||||
|       case ChannelType.B => { |       case _:TLBundleB => { | ||||||
|         // Do there exist B messages with Data? |         // Do there exist B messages with Data? | ||||||
|         val bDataYes = client.anySupportArithmetic || client.anySupportLogical || client.anySupportPutFull || client.anySupportPutPartial |         val bDataYes = client.anySupportArithmetic || client.anySupportLogical || client.anySupportPutFull || client.anySupportPutPartial | ||||||
|         // Do there exist B messages without Data? |         // Do there exist B messages without Data? | ||||||
| @@ -74,34 +82,119 @@ class TLEdge( | |||||||
|         // Statically optimize the case where hasData is a constant |         // Statically optimize the case where hasData is a constant | ||||||
|         if (!bDataYes) Some(false) else if (!bDataNo) Some(true) else None |         if (!bDataYes) Some(false) else if (!bDataNo) Some(true) else None | ||||||
|       } |       } | ||||||
|       case ChannelType.C => { |       case _:TLBundleC => { | ||||||
|         // Do there eixst C messages with Data? |         // Do there eixst C messages with Data? | ||||||
|         val cDataYes = client.anySupportGet || client.anySupportArithmetic || client.anySupportLogical || client.anySupportProbe |         val cDataYes = client.anySupportGet || client.anySupportArithmetic || client.anySupportLogical || client.anySupportProbe | ||||||
|         // Do there exist C messages without Data? |         // Do there exist C messages without Data? | ||||||
|         val cDataNo  = client.anySupportPutFull || client.anySupportPutPartial || client.anySupportHint || client.anySupportProbe |         val cDataNo  = client.anySupportPutFull || client.anySupportPutPartial || client.anySupportHint || client.anySupportProbe | ||||||
|         if (!cDataYes) Some(false) else if (!cDataNo) Some(true) else None |         if (!cDataYes) Some(false) else if (!cDataNo) Some(true) else None | ||||||
|       } |       } | ||||||
|       case ChannelType.D => { |       case _:TLBundleD => { | ||||||
|         // Do there eixst D messages with Data? |         // Do there eixst D messages with Data? | ||||||
|         val dDataYes = manager.anySupportGet || manager.anySupportArithmetic || manager.anySupportLogical || manager.anySupportAcquire |         val dDataYes = manager.anySupportGet || manager.anySupportArithmetic || manager.anySupportLogical || manager.anySupportAcquire | ||||||
|         // Do there exist D messages without Data? |         // Do there exist D messages without Data? | ||||||
|         val dDataNo  = manager.anySupportPutFull || manager.anySupportPutPartial || manager.anySupportHint || manager.anySupportAcquire |         val dDataNo  = manager.anySupportPutFull || manager.anySupportPutPartial || manager.anySupportHint || manager.anySupportAcquire | ||||||
|         if (!dDataYes) Some(false) else if (!dDataNo) Some(true) else None |         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 = |   def hasFollowUp(x: TLChannel): Bool = { | ||||||
|     staticHasData(bundle).map(Bool(_)).getOrElse(bundle.hasData()) |     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 hasData = this.hasData(bundle) |     val opdata = x match { | ||||||
|     val size = bundle.size() |       case a: TLBundleA => !a.opcode(2) | ||||||
|     val cutoff = log2Ceil(manager.beatBytes) |         //    opcode === TLMessages.PutFullData    || | ||||||
|     val small = if (manager.maxTransfer <= manager.beatBytes) Bool(true) else size <= UInt(cutoff) |         //    opcode === TLMessages.PutPartialData || | ||||||
|     val decode = UIntToOH(size, maxLgSize+1) >> cutoff |         //    opcode === TLMessages.ArithmeticData || | ||||||
|     Mux(!hasData || small, UInt(1), decode) |         //    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.param   := growPermissions | ||||||
|     a.size    := lgSize |     a.size    := lgSize | ||||||
|     a.source  := fromSource |     a.source  := fromSource | ||||||
|     a.address := toAddress |     a.addr_hi := toAddress >> log2Ceil(manager.beatBytes) | ||||||
|     a.mask    := SInt(-1).asUInt |     a.mask    := SInt(-1).asUInt | ||||||
|     a.data    := UInt(0) |     a.data    := UInt(0) | ||||||
|     (legal, a) |     (legal, a) | ||||||
| @@ -133,7 +226,8 @@ class TLEdgeOut( | |||||||
|     c.param   := shrinkPermissions |     c.param   := shrinkPermissions | ||||||
|     c.size    := lgSize |     c.size    := lgSize | ||||||
|     c.source  := fromSource |     c.source  := fromSource | ||||||
|     c.address := toAddress |     c.addr_hi := toAddress >> log2Ceil(manager.beatBytes) | ||||||
|  |     c.addr_lo := toAddress | ||||||
|     c.data    := UInt(0) |     c.data    := UInt(0) | ||||||
|     c.error   := Bool(false) |     c.error   := Bool(false) | ||||||
|     (legal, c) |     (legal, c) | ||||||
| @@ -147,31 +241,34 @@ class TLEdgeOut( | |||||||
|     c.param   := shrinkPermissions |     c.param   := shrinkPermissions | ||||||
|     c.size    := lgSize |     c.size    := lgSize | ||||||
|     c.source  := fromSource |     c.source  := fromSource | ||||||
|     c.address := toAddress |     c.addr_hi := toAddress >> log2Ceil(manager.beatBytes) | ||||||
|  |     c.addr_lo := toAddress | ||||||
|     c.data    := data |     c.data    := data | ||||||
|     c.error   := Bool(false) |     c.error   := Bool(false) | ||||||
|     (legal, c) |     (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)) |     val c = Wire(new TLBundleC(bundle)) | ||||||
|     c.opcode  := TLMessages.ProbeAck |     c.opcode  := TLMessages.ProbeAck | ||||||
|     c.param   := reportPermissions |     c.param   := reportPermissions | ||||||
|     c.size    := lgSize |     c.size    := lgSize | ||||||
|     c.source  := UInt(0) |     c.source  := fromSource | ||||||
|     c.address := toAddress |     c.addr_hi := toAddress >> log2Ceil(manager.beatBytes) | ||||||
|  |     c.addr_lo := toAddress | ||||||
|     c.data    := UInt(0) |     c.data    := UInt(0) | ||||||
|     c.error   := Bool(false) |     c.error   := Bool(false) | ||||||
|     c |     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)) |     val c = Wire(new TLBundleC(bundle)) | ||||||
|     c.opcode  := TLMessages.ProbeAckData |     c.opcode  := TLMessages.ProbeAckData | ||||||
|     c.param   := reportPermissions |     c.param   := reportPermissions | ||||||
|     c.size    := lgSize |     c.size    := lgSize | ||||||
|     c.source  := UInt(0) |     c.source  := fromSource | ||||||
|     c.address := toAddress |     c.addr_hi := toAddress >> log2Ceil(manager.beatBytes) | ||||||
|  |     c.addr_lo := toAddress | ||||||
|     c.data    := data |     c.data    := data | ||||||
|     c.error   := Bool(false) |     c.error   := Bool(false) | ||||||
|     c |     c | ||||||
| @@ -192,8 +289,8 @@ class TLEdgeOut( | |||||||
|     a.param   := UInt(0) |     a.param   := UInt(0) | ||||||
|     a.size    := lgSize |     a.size    := lgSize | ||||||
|     a.source  := fromSource |     a.source  := fromSource | ||||||
|     a.address := toAddress |     a.addr_hi := toAddress >> log2Ceil(manager.beatBytes) | ||||||
|     a.mask    := fullMask(toAddress, lgSize) |     a.mask    := mask(toAddress, lgSize) | ||||||
|     a.data    := UInt(0) |     a.data    := UInt(0) | ||||||
|     (legal, a) |     (legal, a) | ||||||
|   } |   } | ||||||
| @@ -206,8 +303,8 @@ class TLEdgeOut( | |||||||
|     a.param   := UInt(0) |     a.param   := UInt(0) | ||||||
|     a.size    := lgSize |     a.size    := lgSize | ||||||
|     a.source  := fromSource |     a.source  := fromSource | ||||||
|     a.address := toAddress |     a.addr_hi := toAddress >> log2Ceil(manager.beatBytes) | ||||||
|     a.mask    := fullMask(toAddress, lgSize) |     a.mask    := mask(toAddress, lgSize) | ||||||
|     a.data    := data |     a.data    := data | ||||||
|     (legal, a) |     (legal, a) | ||||||
|   } |   } | ||||||
| @@ -220,7 +317,7 @@ class TLEdgeOut( | |||||||
|     a.param   := UInt(0) |     a.param   := UInt(0) | ||||||
|     a.size    := lgSize |     a.size    := lgSize | ||||||
|     a.source  := fromSource |     a.source  := fromSource | ||||||
|     a.address := toAddress |     a.addr_hi := toAddress >> log2Ceil(manager.beatBytes) | ||||||
|     a.mask    := mask |     a.mask    := mask | ||||||
|     a.data    := data |     a.data    := data | ||||||
|     (legal, a) |     (legal, a) | ||||||
| @@ -234,8 +331,8 @@ class TLEdgeOut( | |||||||
|     a.param   := atomic |     a.param   := atomic | ||||||
|     a.size    := lgSize |     a.size    := lgSize | ||||||
|     a.source  := fromSource |     a.source  := fromSource | ||||||
|     a.address := toAddress |     a.addr_hi := toAddress >> log2Ceil(manager.beatBytes) | ||||||
|     a.mask    := fullMask(toAddress, lgSize) |     a.mask    := mask(toAddress, lgSize) | ||||||
|     a.data    := data |     a.data    := data | ||||||
|     (legal, a) |     (legal, a) | ||||||
|   } |   } | ||||||
| @@ -248,8 +345,8 @@ class TLEdgeOut( | |||||||
|     a.param   := atomic |     a.param   := atomic | ||||||
|     a.size    := lgSize |     a.size    := lgSize | ||||||
|     a.source  := fromSource |     a.source  := fromSource | ||||||
|     a.address := toAddress |     a.addr_hi := toAddress >> log2Ceil(manager.beatBytes) | ||||||
|     a.mask    := fullMask(toAddress, lgSize) |     a.mask    := mask(toAddress, lgSize) | ||||||
|     a.data    := data |     a.data    := data | ||||||
|     (legal, a) |     (legal, a) | ||||||
|   } |   } | ||||||
| @@ -262,45 +359,53 @@ class TLEdgeOut( | |||||||
|     a.param   := param |     a.param   := param | ||||||
|     a.size    := lgSize |     a.size    := lgSize | ||||||
|     a.source  := fromSource |     a.source  := fromSource | ||||||
|     a.address := toAddress |     a.addr_hi := toAddress >> log2Ceil(manager.beatBytes) | ||||||
|     a.mask    := fullMask(toAddress, lgSize) |     a.mask    := mask(toAddress, lgSize) | ||||||
|     a.data    := UInt(0) |     a.data    := UInt(0) | ||||||
|     (legal, a) |     (legal, a) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   def AccessAck(toAddress: UInt, lgSize: UInt): TLBundleC = AccessAck(toAddress, lgSize, Bool(false)) |   def AccessAck(b: TLBundleB): TLBundleC = AccessAck(b.source, address(b), b.size) | ||||||
|   def AccessAck(toAddress: UInt, lgSize: UInt, error: Bool) = { |   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)) |     val c = Wire(new TLBundleC(bundle)) | ||||||
|     c.opcode  := TLMessages.AccessAck |     c.opcode  := TLMessages.AccessAck | ||||||
|     c.param   := UInt(0) |     c.param   := UInt(0) | ||||||
|     c.size    := lgSize |     c.size    := lgSize | ||||||
|     c.source  := UInt(0) |     c.source  := fromSource | ||||||
|     c.address := toAddress |     c.addr_hi := toAddress >> log2Ceil(manager.beatBytes) | ||||||
|  |     c.addr_lo := toAddress | ||||||
|     c.data    := UInt(0) |     c.data    := UInt(0) | ||||||
|     c.error   := error |     c.error   := error | ||||||
|     c |     c | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   def AccessAck(toAddress: UInt, lgSize: UInt, data: UInt): TLBundleC = AccessAck(toAddress, lgSize, data, Bool(false)) |   def AccessAck(b: TLBundleB, data: UInt): TLBundleC = AccessAck(b.source, address(b), b.size, data) | ||||||
|   def AccessAck(toAddress: UInt, lgSize: UInt, data: UInt, error: Bool) = { |   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)) |     val c = Wire(new TLBundleC(bundle)) | ||||||
|     c.opcode  := TLMessages.AccessAckData |     c.opcode  := TLMessages.AccessAckData | ||||||
|     c.param   := UInt(0) |     c.param   := UInt(0) | ||||||
|     c.size    := lgSize |     c.size    := lgSize | ||||||
|     c.source  := UInt(0) |     c.source  := fromSource | ||||||
|     c.address := toAddress |     c.addr_hi := toAddress >> log2Ceil(manager.beatBytes) | ||||||
|  |     c.addr_lo := toAddress | ||||||
|     c.data    := data |     c.data    := data | ||||||
|     c.error   := error |     c.error   := error | ||||||
|     c |     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)) |     val c = Wire(new TLBundleC(bundle)) | ||||||
|     c.opcode  := TLMessages.HintAck |     c.opcode  := TLMessages.HintAck | ||||||
|     c.param   := UInt(0) |     c.param   := UInt(0) | ||||||
|     c.size    := lgSize |     c.size    := lgSize | ||||||
|     c.source  := UInt(0) |     c.source  := fromSource | ||||||
|     c.address := toAddress |     c.addr_hi := toAddress >> log2Ceil(manager.beatBytes) | ||||||
|  |     c.addr_lo := toAddress | ||||||
|     c.data    := UInt(0) |     c.data    := UInt(0) | ||||||
|     c.error   := Bool(false) |     c.error   := Bool(false) | ||||||
|     c |     c | ||||||
| @@ -321,47 +426,50 @@ class TLEdgeIn( | |||||||
|     b.param   := capPermissions |     b.param   := capPermissions | ||||||
|     b.size    := lgSize |     b.size    := lgSize | ||||||
|     b.source  := toSource |     b.source  := toSource | ||||||
|     b.address := fromAddress |     b.addr_hi := fromAddress >> log2Ceil(manager.beatBytes) | ||||||
|     b.mask    := SInt(-1).asUInt |     b.mask    := SInt(-1).asUInt | ||||||
|     b.data    := UInt(0) |     b.data    := UInt(0) | ||||||
|     (legal, b) |     (legal, b) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   def Grant(fromSink: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt): TLBundleD = Grant(fromSink, toSource, lgSize, capPermissions, Bool(false)) |   def Grant(fromAddress: UInt, fromSink: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt): TLBundleD = Grant(fromAddress, 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, error: Bool) = { | ||||||
|     val d = Wire(new TLBundleD(bundle)) |     val d = Wire(new TLBundleD(bundle)) | ||||||
|     d.opcode := TLMessages.Grant |     d.opcode  := TLMessages.Grant | ||||||
|     d.param  := capPermissions |     d.param   := capPermissions | ||||||
|     d.size   := lgSize |     d.size    := lgSize | ||||||
|     d.source := toSource |     d.source  := toSource | ||||||
|     d.sink   := fromSink |     d.sink    := fromSink | ||||||
|     d.data   := UInt(0) |     d.addr_lo := fromAddress | ||||||
|     d.error  := error |     d.data    := UInt(0) | ||||||
|  |     d.error   := error | ||||||
|     d |     d | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   def Grant(fromSink: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt, data: UInt): TLBundleD = Grant(fromSink, toSource, lgSize, capPermissions, data, Bool(false)) |   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(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, error: Bool) = { | ||||||
|     val d = Wire(new TLBundleD(bundle)) |     val d = Wire(new TLBundleD(bundle)) | ||||||
|     d.opcode := TLMessages.GrantData |     d.opcode  := TLMessages.GrantData | ||||||
|     d.param  := capPermissions |     d.param   := capPermissions | ||||||
|     d.size   := lgSize |     d.size    := lgSize | ||||||
|     d.source := toSource |     d.source  := toSource | ||||||
|     d.sink   := fromSink |     d.sink    := fromSink | ||||||
|     d.data   := data |     d.addr_lo := fromAddress | ||||||
|     d.error  := error |     d.data    := data | ||||||
|  |     d.error   := error | ||||||
|     d |     d | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   def ReleaseAck(toSource: UInt, lgSize: UInt) = { |   def ReleaseAck(fromAddress: UInt, fromSink: UInt, toSource: UInt, lgSize: UInt) = { | ||||||
|     val d = Wire(new TLBundleD(bundle)) |     val d = Wire(new TLBundleD(bundle)) | ||||||
|     d.opcode := TLMessages.ReleaseAck |     d.opcode  := TLMessages.ReleaseAck | ||||||
|     d.param  := UInt(0) |     d.param   := UInt(0) | ||||||
|     d.size   := lgSize |     d.size    := lgSize | ||||||
|     d.source := toSource |     d.source  := toSource | ||||||
|     d.sink   := UInt(0) |     d.sink    := fromSink | ||||||
|     d.data   := UInt(0) |     d.addr_lo := fromAddress | ||||||
|     d.error  := Bool(false) |     d.data    := UInt(0) | ||||||
|  |     d.error   := Bool(false) | ||||||
|     d |     d | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -374,8 +482,8 @@ class TLEdgeIn( | |||||||
|     b.param   := UInt(0) |     b.param   := UInt(0) | ||||||
|     b.size    := lgSize |     b.size    := lgSize | ||||||
|     b.source  := toSource |     b.source  := toSource | ||||||
|     b.address := fromAddress |     b.addr_hi := fromAddress >> log2Ceil(manager.beatBytes) | ||||||
|     b.mask    := fullMask(fromAddress, lgSize) |     b.mask    := mask(fromAddress, lgSize) | ||||||
|     b.data    := UInt(0) |     b.data    := UInt(0) | ||||||
|     (legal, b) |     (legal, b) | ||||||
|   } |   } | ||||||
| @@ -388,8 +496,8 @@ class TLEdgeIn( | |||||||
|     b.param   := UInt(0) |     b.param   := UInt(0) | ||||||
|     b.size    := lgSize |     b.size    := lgSize | ||||||
|     b.source  := toSource |     b.source  := toSource | ||||||
|     b.address := fromAddress |     b.addr_hi := fromAddress >> log2Ceil(manager.beatBytes) | ||||||
|     b.mask    := fullMask(fromAddress, lgSize) |     b.mask    := mask(fromAddress, lgSize) | ||||||
|     b.data    := data |     b.data    := data | ||||||
|     (legal, b) |     (legal, b) | ||||||
|   } |   } | ||||||
| @@ -402,7 +510,7 @@ class TLEdgeIn( | |||||||
|     b.param   := UInt(0) |     b.param   := UInt(0) | ||||||
|     b.size    := lgSize |     b.size    := lgSize | ||||||
|     b.source  := toSource |     b.source  := toSource | ||||||
|     b.address := fromAddress |     b.addr_hi := fromAddress >> log2Ceil(manager.beatBytes) | ||||||
|     b.mask    := mask |     b.mask    := mask | ||||||
|     b.data    := data |     b.data    := data | ||||||
|     (legal, b) |     (legal, b) | ||||||
| @@ -416,8 +524,8 @@ class TLEdgeIn( | |||||||
|     b.param   := atomic |     b.param   := atomic | ||||||
|     b.size    := lgSize |     b.size    := lgSize | ||||||
|     b.source  := toSource |     b.source  := toSource | ||||||
|     b.address := fromAddress |     b.addr_hi := fromAddress >> log2Ceil(manager.beatBytes) | ||||||
|     b.mask    := fullMask(fromAddress, lgSize) |     b.mask    := mask(fromAddress, lgSize) | ||||||
|     b.data    := data |     b.data    := data | ||||||
|     (legal, b) |     (legal, b) | ||||||
|   } |   } | ||||||
| @@ -430,8 +538,8 @@ class TLEdgeIn( | |||||||
|     b.param   := atomic |     b.param   := atomic | ||||||
|     b.size    := lgSize |     b.size    := lgSize | ||||||
|     b.source  := toSource |     b.source  := toSource | ||||||
|     b.address := fromAddress |     b.addr_hi := fromAddress >> log2Ceil(manager.beatBytes) | ||||||
|     b.mask    := fullMask(fromAddress, lgSize) |     b.mask    := mask(fromAddress, lgSize) | ||||||
|     b.data    := data |     b.data    := data | ||||||
|     (legal, b) |     (legal, b) | ||||||
|   } |   } | ||||||
| @@ -444,47 +552,55 @@ class TLEdgeIn( | |||||||
|     b.param   := param |     b.param   := param | ||||||
|     b.size    := lgSize |     b.size    := lgSize | ||||||
|     b.source  := toSource |     b.source  := toSource | ||||||
|     b.address := fromAddress |     b.addr_hi := fromAddress >> log2Ceil(manager.beatBytes) | ||||||
|     b.mask    := fullMask(fromAddress, lgSize) |     b.mask    := mask(fromAddress, lgSize) | ||||||
|     b.data    := UInt(0) |     b.data    := UInt(0) | ||||||
|     (legal, b) |     (legal, b) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   def AccessAck(toSource: UInt, lgSize: UInt): TLBundleD = AccessAck(toSource, lgSize, Bool(false)) |   def AccessAck(a: TLBundleA, fromSink: UInt): TLBundleD = AccessAck(address(a), fromSink, a.source, a.size) | ||||||
|   def AccessAck(toSource: UInt, lgSize: UInt, error: Bool) = { |   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)) |     val d = Wire(new TLBundleD(bundle)) | ||||||
|     d.opcode := TLMessages.AccessAck |     d.opcode  := TLMessages.AccessAck | ||||||
|     d.param  := UInt(0) |     d.param   := UInt(0) | ||||||
|     d.size   := lgSize |     d.size    := lgSize | ||||||
|     d.source := toSource |     d.source  := toSource | ||||||
|     d.sink   := UInt(0) |     d.sink    := fromSink | ||||||
|     d.data   := UInt(0) |     d.addr_lo := fromAddress | ||||||
|     d.error  := error |     d.data    := UInt(0) | ||||||
|  |     d.error   := error | ||||||
|     d |     d | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   def AccessAck(toSource: UInt, lgSize: UInt, data: UInt): TLBundleD = AccessAck(toSource, lgSize, data, Bool(false)) |   def AccessAck(a: TLBundleA, fromSink: UInt, data: UInt): TLBundleD = AccessAck(address(a), fromSink, a.source, a.size, data) | ||||||
|   def AccessAck(toSource: UInt, lgSize: UInt, data: UInt, error: Bool) = { |   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)) |     val d = Wire(new TLBundleD(bundle)) | ||||||
|     d.opcode := TLMessages.AccessAckData |     d.opcode  := TLMessages.AccessAckData | ||||||
|     d.param  := UInt(0) |     d.param   := UInt(0) | ||||||
|     d.size   := lgSize |     d.size    := lgSize | ||||||
|     d.source := toSource |     d.source  := toSource | ||||||
|     d.sink   := UInt(0) |     d.sink    := fromSink | ||||||
|     d.data   := data |     d.addr_lo := fromAddress | ||||||
|     d.error  := error |     d.data    := data | ||||||
|  |     d.error   := error | ||||||
|     d |     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)) |     val d = Wire(new TLBundleD(bundle)) | ||||||
|     d.opcode := TLMessages.HintAck |     d.opcode  := TLMessages.HintAck | ||||||
|     d.param  := UInt(0) |     d.param   := UInt(0) | ||||||
|     d.size   := lgSize |     d.size    := lgSize | ||||||
|     d.source := toSource |     d.source  := toSource | ||||||
|     d.sink   := UInt(0) |     d.sink    := fromSink | ||||||
|     d.data   := UInt(0) |     d.addr_lo := fromAddress | ||||||
|     d.error  := Bool(false) |     d.data    := UInt(0) | ||||||
|  |     d.error   := Bool(false) | ||||||
|     d |     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) |     // 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 managers  = manager.managers | ||||||
|     val beatBytes = manager.beatBytes |     val beatBytes = manager.beatBytes | ||||||
|     val fifoId = managers(0).fifoId |     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 counterBits = log2Up(maxSize/beatBytes) | ||||||
|     val maxDownSize = if (alwaysMin) minSize else manager.maxTransfer |     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 |     // First, handle the return path | ||||||
|     val acknum = RegInit(UInt(0, width = counterBits)) |     val acknum = RegInit(UInt(0, width = counterBits)) | ||||||
|     val dOrig = Reg(UInt()) |     val dOrig = Reg(UInt()) | ||||||
| @@ -147,7 +146,7 @@ class TLFragmenter(minSize: Int, maxSize: Int, alwaysMin: Boolean = false) exten | |||||||
|     val dFirst = acknum === UInt(0) |     val dFirst = acknum === UInt(0) | ||||||
|     val dsizeOH  = UIntToOH (out.d.bits.size, log2Ceil(maxDownSize)+1) |     val dsizeOH  = UIntToOH (out.d.bits.size, log2Ceil(maxDownSize)+1) | ||||||
|     val dsizeOH1 = UIntToOH1(out.d.bits.size, log2Ceil(maxDownSize)) |     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 |     // calculate new acknum | ||||||
|     val acknum_fragment = dFragnum << log2Ceil(minSize/beatBytes) |     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))) |     val maxLgHints       = maxHints      .map(m => if (m == 0) lgMinSize else UInt(log2Ceil(m))) | ||||||
|  |  | ||||||
|     // If this is infront of a single manager, these become constants |     // 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 maxLgArithmetic  = Mux1H(find, maxLgArithmetics) | ||||||
|     val maxLgLogical     = Mux1H(find, maxLgLogicals) |     val maxLgLogical     = Mux1H(find, maxLgLogicals) | ||||||
|     val maxLgGet         = Mux1H(find, maxLgGets) |     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 |     out.a.valid := in.a.valid | ||||||
|     in.a.ready := out.a.ready && !delay |     in.a.ready := out.a.ready && !delay | ||||||
|     out.a.bits := in.a.bits |     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.source := Cat(in.a.bits.source, aFragnum) | ||||||
|     out.a.bits.size := aFrag |     out.a.bits.size := aFrag | ||||||
|  |  | ||||||
|   | |||||||
| @@ -28,13 +28,13 @@ class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = f | |||||||
|     require (!supportClients || bce) |     require (!supportClients || bce) | ||||||
|  |  | ||||||
|     if (supportManagers) { |     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 |       val bypassD = handleA && in.a.bits.opcode === TLMessages.Hint | ||||||
|  |  | ||||||
|       // Prioritize existing D traffic over HintAck |       // Prioritize existing D traffic over HintAck | ||||||
|       in.d.valid  := out.d.valid || (bypassD && in.a.valid) |       in.d.valid  := out.d.valid || (bypassD && in.a.valid) | ||||||
|       out.d.ready := in.d.ready |       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) |       in.a.ready  := Mux(bypassD, in.d.ready && !out.d.valid, out.a.ready) | ||||||
|       out.a.valid := in.a.valid && !bypassD |       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 |       // Prioritize existing C traffic over HintAck | ||||||
|       out.c.valid := in.c.valid || (bypassC && in.b.valid) |       out.c.valid := in.c.valid || (bypassC && in.b.valid) | ||||||
|       in.c.ready  := out.c.ready |       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) |       out.b.ready := Mux(bypassC, out.c.ready && !in.c.valid, in.b.ready) | ||||||
|       in.b.valid  := out.b.valid && !bypassC |       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! |   // .module had better not be accessed while LazyModules are still being built! | ||||||
|   require (LazyModule.stack.isEmpty) |   require (LazyModule.stack.isEmpty) | ||||||
|   | |||||||
| @@ -104,14 +104,14 @@ class TLLegacy(implicit val p: Parameters) extends LazyModule with HasTileLinkPa | |||||||
|     // Get rid of some unneeded muxes |     // Get rid of some unneeded muxes | ||||||
|     out.a.bits.source  := source |     out.a.bits.source  := source | ||||||
|     out.a.bits.data    := data |     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 |     // TL legacy does not support bus errors | ||||||
|     assert (!out.d.bits.error) |     assert (!out.d.bits.error) | ||||||
|  |  | ||||||
|     // Recreate the beat address counter |     // Recreate the beat address counter | ||||||
|     val beatCounter = RegInit(UInt(0, width = tlBeatAddrBits)) |     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) |       beatCounter := beatCounter + UInt(1) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -19,20 +19,20 @@ object TLMonitor | |||||||
|  |  | ||||||
|     // Reuse these subexpressions to save some firrtl lines |     // Reuse these subexpressions to save some firrtl lines | ||||||
|     val source_ok = edge.client.contains(bundle.source) |     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) | ||||||
|     val mask = edge.fullMask(bundle.address | edge.lowAddress(bundle.mask), bundle.size) |     val mask = edge.mask(edge.addr_lo(bundle.mask), bundle.size) | ||||||
|  |  | ||||||
|     when (bundle.opcode === TLMessages.Acquire) { |     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 (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 (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 (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 (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) { |     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 (source_ok, "'A' channel Get carries invalid source ID" + extra) | ||||||
|       assert (is_aligned, "'A' channel Get address not aligned to size" + 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) |       assert (bundle.param === UInt(0), "'A' channel Get carries invalid param" + extra) | ||||||
| @@ -40,7 +40,7 @@ object TLMonitor | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     when (bundle.opcode === TLMessages.PutFullData) { |     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 (source_ok, "'A' channel PutFull carries invalid source ID" + extra) | ||||||
|       assert (is_aligned, "'A' channel PutFull address not aligned to size" + 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) |       assert (bundle.param === UInt(0), "'A' channel PutFull carries invalid param" + extra) | ||||||
| @@ -48,7 +48,7 @@ object TLMonitor | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     when (bundle.opcode === TLMessages.PutPartialData) { |     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 (source_ok, "'A' channel PutPartial carries invalid source ID" + extra) | ||||||
|       assert (is_aligned, "'A' channel PutPartial address not aligned to size" + 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) |       assert (bundle.param === UInt(0), "'A' channel PutPartial carries invalid param" + extra) | ||||||
| @@ -57,7 +57,7 @@ object TLMonitor | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     when (bundle.opcode === TLMessages.ArithmeticData) { |     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 (source_ok, "'A' channel Arithmetic carries invalid source ID" + extra) | ||||||
|       assert (is_aligned, "'A' channel Arithmetic address not aligned to size" + 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) |       assert (TLAtomics.isArithmetic(bundle.param), "'A' channel Arithmetic carries invalid opcode param" + extra) | ||||||
| @@ -65,7 +65,7 @@ object TLMonitor | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     when (bundle.opcode === TLMessages.LogicalData) { |     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 (source_ok, "'A' channel Logical carries invalid source ID" + extra) | ||||||
|       assert (is_aligned, "'A' channel Logical address not aligned to size" + 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) |       assert (TLAtomics.isLogical(bundle.param), "'A' channel Logical carries invalid opcode param" + extra) | ||||||
| @@ -73,7 +73,7 @@ object TLMonitor | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     when (bundle.opcode === TLMessages.Hint) { |     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 (source_ok, "'A' channel Hint carries invalid source ID" + extra) | ||||||
|       assert (is_aligned, "'A' channel Hint address not aligned to size" + extra) |       assert (is_aligned, "'A' channel Hint address not aligned to size" + extra) | ||||||
|       assert (bundle.mask === mask, "'A' channel Hint contains invalid mask" + 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 |     // Reuse these subexpressions to save some firrtl lines | ||||||
|     val address_ok = edge.manager.contains(bundle.source) |     val address_ok = edge.manager.contains(bundle.source) | ||||||
|     val is_aligned = edge.isAligned(bundle.address, bundle.size) |     val is_aligned = edge.isHiAligned(bundle.addr_hi, bundle.size) | ||||||
|     val mask = edge.fullMask(bundle.address | edge.lowAddress(bundle.mask), bundle.size) |     val mask = edge.mask(edge.addr_lo(bundle.mask), bundle.size) | ||||||
|  |  | ||||||
|     when (bundle.opcode === TLMessages.Probe) { |     when (bundle.opcode === TLMessages.Probe) { | ||||||
|       assert (edge.client.supportsProbe(bundle.source, bundle.size), "'B' channel carries Probe type unsupported by client" + extra) |       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 (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 (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 (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) { |     when (bundle.opcode === TLMessages.Get) { | ||||||
| @@ -150,12 +150,12 @@ object TLMonitor | |||||||
|     assert (TLMessages.isC(bundle.opcode), "'C' channel has invalid opcode" + extra) |     assert (TLMessages.isC(bundle.opcode), "'C' channel has invalid opcode" + extra) | ||||||
|  |  | ||||||
|     val source_ok = edge.client.contains(bundle.source) |     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) |     val address_ok = edge.manager.contains(bundle.source) | ||||||
|  |  | ||||||
|     when (bundle.opcode === TLMessages.ProbeAck) { |     when (bundle.opcode === TLMessages.ProbeAck) { | ||||||
|       assert (address_ok, "'C' channel ProbeAck carries unmanaged address" + extra) |       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 (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 (is_aligned, "'C' channel ProbeAck address not aligned to size" + extra) | ||||||
|       assert (TLPermissions.isReport(bundle.param), "'C' channel ProbeAck carries invalid report param" + 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) { |     when (bundle.opcode === TLMessages.ProbeAckData) { | ||||||
|       assert (address_ok, "'C' channel ProbeAckData carries unmanaged address" + extra) |       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 (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 (is_aligned, "'C' channel ProbeAckData address not aligned to size" + extra) | ||||||
|       assert (TLPermissions.isReport(bundle.param), "'C' channel ProbeAckData carries invalid report param" + 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) { |     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 (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 (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) |       assert (is_aligned, "'C' channel Release address not aligned to size" + extra) | ||||||
| @@ -181,7 +181,7 @@ object TLMonitor | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     when (bundle.opcode === TLMessages.ReleaseData) { |     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 (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 (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) |       assert (is_aligned, "'C' channel ReleaseData address not aligned to size" + extra) | ||||||
| @@ -191,21 +191,21 @@ object TLMonitor | |||||||
|  |  | ||||||
|     when (bundle.opcode === TLMessages.AccessAck) { |     when (bundle.opcode === TLMessages.AccessAck) { | ||||||
|       assert (address_ok, "'C' channel AccessAck carries unmanaged address" + extra) |       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 (is_aligned, "'C' channel AccessAck address not aligned to size" + extra) | ||||||
|       assert (bundle.param === UInt(0), "'C' channel AccessAck carries invalid param" + extra) |       assert (bundle.param === UInt(0), "'C' channel AccessAck carries invalid param" + extra) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     when (bundle.opcode === TLMessages.AccessAckData) { |     when (bundle.opcode === TLMessages.AccessAckData) { | ||||||
|       assert (address_ok, "'C' channel AccessAckData carries unmanaged address" + extra) |       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 (is_aligned, "'C' channel AccessAckData address not aligned to size" + extra) | ||||||
|       assert (bundle.param === UInt(0), "'C' channel AccessAckData carries invalid param" + extra) |       assert (bundle.param === UInt(0), "'C' channel AccessAckData carries invalid param" + extra) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     when (bundle.opcode === TLMessages.HintAck) { |     when (bundle.opcode === TLMessages.HintAck) { | ||||||
|       assert (address_ok, "'C' channel HintAck carries unmanaged address" + extra) |       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 (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.param === UInt(0), "'C' channel HintAck carries invalid param" + extra) | ||||||
|       assert (!bundle.error, "'C' channel HintAck carries an error" + 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) |     assert (TLMessages.isD(bundle.opcode), "'D' channel has invalid opcode" + extra) | ||||||
|  |  | ||||||
|     val source_ok = edge.client.contains(bundle.source) |     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) |     val sink_ok = edge.manager.containsById(bundle.sink) | ||||||
|  |  | ||||||
|     when (bundle.opcode === TLMessages.ReleaseAck) { |     when (bundle.opcode === TLMessages.ReleaseAck) { | ||||||
|       assert (source_ok, "'D' channel ReleaseAck carries invalid source ID" + extra) |       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.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.param === UInt(0), "'D' channel ReleaseeAck carries invalid param" + extra) | ||||||
|       assert (!bundle.error, "'D' channel ReleaseAck carries an error" + extra) |       assert (!bundle.error, "'D' channel ReleaseAck carries an error" + extra) | ||||||
| @@ -228,6 +230,7 @@ object TLMonitor | |||||||
|  |  | ||||||
|     when (bundle.opcode === TLMessages.Grant) { |     when (bundle.opcode === TLMessages.Grant) { | ||||||
|       assert (source_ok, "'D' channel Grant carries invalid source ID" + extra) |       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 (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 (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) |       assert (TLPermissions.isCap(bundle.param), "'D' channel Grant carries invalid cap param" + extra) | ||||||
| @@ -235,6 +238,7 @@ object TLMonitor | |||||||
|  |  | ||||||
|     when (bundle.opcode === TLMessages.GrantData) { |     when (bundle.opcode === TLMessages.GrantData) { | ||||||
|       assert (source_ok, "'D' channel GrantData carries invalid source ID" + extra) |       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 (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 (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) |       assert (TLPermissions.isCap(bundle.param), "'D' channel GrantData carries invalid cap param" + extra) | ||||||
| @@ -242,21 +246,24 @@ object TLMonitor | |||||||
|  |  | ||||||
|     when (bundle.opcode === TLMessages.AccessAck) { |     when (bundle.opcode === TLMessages.AccessAck) { | ||||||
|       assert (source_ok, "'D' channel AccessAck carries invalid source ID" + extra) |       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 |       // size is ignored | ||||||
|       assert (bundle.param === UInt(0), "'D' channel AccessAck carries invalid param" + extra) |       assert (bundle.param === UInt(0), "'D' channel AccessAck carries invalid param" + extra) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     when (bundle.opcode === TLMessages.AccessAckData) { |     when (bundle.opcode === TLMessages.AccessAckData) { | ||||||
|       assert (source_ok, "'D' channel AccessAckData carries invalid source ID" + extra) |       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 |       // size is ignored | ||||||
|       assert (bundle.param === UInt(0), "'D' channel AccessAckData carries invalid param" + extra) |       assert (bundle.param === UInt(0), "'D' channel AccessAckData carries invalid param" + extra) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     when (bundle.opcode === TLMessages.HintAck) { |     when (bundle.opcode === TLMessages.HintAck) { | ||||||
|       assert (source_ok, "'D' channel HintAck carries invalid source ID" + extra) |       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 |       // size is ignored | ||||||
|       assert (bundle.param === UInt(0), "'D' channel HintAck carries invalid param" + extra) |       assert (bundle.param === UInt(0), "'D' channel HintAck carries invalid param" + extra) | ||||||
|       assert (!bundle.error, "'D' channel HintAck carries an error" + extra) |       assert (!bundle.error, "'D' channel HintAck carries an error" + extra) | ||||||
| @@ -281,13 +288,13 @@ object TLMonitor | |||||||
|     val param   = Reg(UInt()) |     val param   = Reg(UInt()) | ||||||
|     val size    = Reg(UInt()) |     val size    = Reg(UInt()) | ||||||
|     val source  = Reg(UInt()) |     val source  = Reg(UInt()) | ||||||
|     val address = Reg(UInt()) |     val addr_hi = Reg(UInt()) | ||||||
|     when (a.valid && counter =/= UInt(0)) { |     when (a.valid && counter =/= UInt(0)) { | ||||||
|       assert (a.bits.opcode === opcode, "'A' channel opcode changed within multibeat operation" + extra) |       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.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.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.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()) { |     when (a.fire()) { | ||||||
|       counter := counter - UInt(1) |       counter := counter - UInt(1) | ||||||
| @@ -297,7 +304,7 @@ object TLMonitor | |||||||
|         param   := a.bits.param |         param   := a.bits.param | ||||||
|         size    := a.bits.size |         size    := a.bits.size | ||||||
|         source  := a.bits.source |         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 param   = Reg(UInt()) | ||||||
|     val size    = Reg(UInt()) |     val size    = Reg(UInt()) | ||||||
|     val source  = Reg(UInt()) |     val source  = Reg(UInt()) | ||||||
|     val address = Reg(UInt()) |     val addr_hi = Reg(UInt()) | ||||||
|     when (b.valid && counter =/= UInt(0)) { |     when (b.valid && counter =/= UInt(0)) { | ||||||
|       assert (b.bits.opcode === opcode, "'B' channel opcode changed within multibeat operation" + extra) |       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.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.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.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()) { |     when (b.fire()) { | ||||||
|       counter := counter - UInt(1) |       counter := counter - UInt(1) | ||||||
| @@ -324,7 +331,7 @@ object TLMonitor | |||||||
|         param   := b.bits.param |         param   := b.bits.param | ||||||
|         size    := b.bits.size |         size    := b.bits.size | ||||||
|         source  := b.bits.source |         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 param   = Reg(UInt()) | ||||||
|     val size    = Reg(UInt()) |     val size    = Reg(UInt()) | ||||||
|     val source  = 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)) { |     when (c.valid && counter =/= UInt(0)) { | ||||||
|       assert (c.bits.opcode === opcode, "'C' channel opcode changed within multibeat operation" + extra) |       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.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.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.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()) { |     when (c.fire()) { | ||||||
|       counter := counter - UInt(1) |       counter := counter - UInt(1) | ||||||
| @@ -351,7 +360,8 @@ object TLMonitor | |||||||
|         param   := c.bits.param |         param   := c.bits.param | ||||||
|         size    := c.bits.size |         size    := c.bits.size | ||||||
|         source  := c.bits.source |         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 size    = Reg(UInt()) | ||||||
|     val source  = Reg(UInt()) |     val source  = Reg(UInt()) | ||||||
|     val sink    = Reg(UInt()) |     val sink    = Reg(UInt()) | ||||||
|  |     val addr_lo = Reg(UInt()) | ||||||
|     when (d.valid && counter =/= UInt(0)) { |     when (d.valid && counter =/= UInt(0)) { | ||||||
|       assert (d.bits.opcode === opcode, "'D' channel opcode changed within multibeat operation" + extra) |       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.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.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.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.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()) { |     when (d.fire()) { | ||||||
|       counter := counter - UInt(1) |       counter := counter - UInt(1) | ||||||
| @@ -379,6 +391,7 @@ object TLMonitor | |||||||
|         size    := d.bits.size |         size    := d.bits.size | ||||||
|         source  := d.bits.source |         source  := d.bits.source | ||||||
|         sink    := d.bits.sink |         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 out = node.bundleOut | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     val edge = node.edgesOut(0) |     val edgeOut = node.edgesOut(0) | ||||||
|     val outerBeatBytes = edge.manager.beatBytes |     val edgeIn  = node.edgesIn(0) | ||||||
|  |     val outerBeatBytes = edgeOut.manager.beatBytes | ||||||
|     require (outerBeatBytes < innerBeatBytes) |     require (outerBeatBytes < innerBeatBytes) | ||||||
|  |  | ||||||
|     val ratio = innerBeatBytes / outerBeatBytes |     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 trailingZeros(x: Int) = if (x > 0) Some(log2Ceil(x & -x)) else None | ||||||
|  |  | ||||||
|     def split(in: HasTLData, fire: Bool): (Bool, UInt, UInt) = { |     def split(edge: TLEdge, in: TLDataChannel, fire: Bool): (Bool, UInt, UInt) = { | ||||||
|       val dataSlices = Vec.tabulate (ratio) { i => in.data()((i+1)*outerBeatBytes*8-1, i*outerBeatBytes*8) } |       val dataSlices = Vec.tabulate (ratio) { i => edge.data(in)((i+1)*outerBeatBytes*8-1, i*outerBeatBytes*8) } | ||||||
|       val maskSlices = Vec.tabulate (ratio) { i => in.mask()((i+1)*outerBeatBytes  -1, i*outerBeatBytes)   } |       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 filter = Reg(UInt(width = ratio), init = SInt(-1, width = ratio).asUInt) | ||||||
|       val mask = maskSlices.map(_.orR) |       val mask = maskSlices.map(_.orR) | ||||||
|       val hasData = edge.hasData(in) |       val hasData = edge.hasData(in) | ||||||
|  |  | ||||||
|       // decoded_size = 1111 (for smallest), 0101, 0001 (for largest) |       // 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 decoded_size = Seq.tabulate(ratio) { i => trailingZeros(i).map(!sizeOH1(_)).getOrElse(Bool(true)) } | ||||||
|  |  | ||||||
|       val first = filter(ratio-1) |       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 count = RegInit(UInt(0, width = log2Ceil(ratio))) | ||||||
|       val rdata = Reg(UInt(width = (ratio-1)*outerBeatBytes*8)) |       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 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) |       val last = count === limit || !edge.hasData(in) | ||||||
|  |  | ||||||
|       when (fire) { |       when (fire) { | ||||||
| @@ -82,21 +82,22 @@ class TLNarrower(innerBeatBytes: Int) extends LazyModule | |||||||
|       if (edge.staticHasData(in) == Some(false)) { |       if (edge.staticHasData(in) == Some(false)) { | ||||||
|         (Bool(true), UInt(0)) |         (Bool(true), UInt(0)) | ||||||
|       } else { |       } else { | ||||||
|         (last, mux(in.size())) |         (last, mux(edge.size(in))) | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     val in = io.in(0) |     val in = io.in(0) | ||||||
|     val out = io.out(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 |     in.a.ready := out.a.ready && alast | ||||||
|     out.a.valid := in.a.valid |     out.a.valid := in.a.valid | ||||||
|     out.a.bits := in.a.bits |     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.data := adata | ||||||
|     out.a.bits.mask := amask |     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 |     out.d.ready := in.d.ready || !dlast | ||||||
|     in.d.valid := out.d.valid && dlast |     in.d.valid := out.d.valid && dlast | ||||||
|     in.d.bits := out.d.bits |     in.d.bits := out.d.bits | ||||||
|   | |||||||
| @@ -286,23 +286,25 @@ case class TLClientPortParameters(clients: Seq[TLClientParameters]) { | |||||||
| } | } | ||||||
|  |  | ||||||
| case class TLBundleParameters( | case class TLBundleParameters( | ||||||
|   addressBits: Int, |   addrHiBits: Int, | ||||||
|   dataBits:    Int, |   dataBits:   Int, | ||||||
|   sourceBits:  Int, |   sourceBits: Int, | ||||||
|   sinkBits:    Int, |   sinkBits:   Int, | ||||||
|   sizeBits:    Int) |   sizeBits:   Int) | ||||||
| { | { | ||||||
|   // Chisel has issues with 0-width wires |   // Chisel has issues with 0-width wires | ||||||
|   require (addressBits >= 1) |   require (addrHiBits  >= 1) | ||||||
|   require (dataBits    >= 1) |   require (dataBits    >= 8) | ||||||
|   require (sourceBits  >= 1) |   require (sourceBits  >= 1) | ||||||
|   require (sinkBits    >= 1) |   require (sinkBits    >= 1) | ||||||
|   require (sizeBits    >= 1) |   require (sizeBits    >= 1) | ||||||
|   require (isPow2(dataBits)) |   require (isPow2(dataBits)) | ||||||
|    |  | ||||||
|  |   val addrLoBits = log2Up(dataBits/8) | ||||||
|  |  | ||||||
|   def union(x: TLBundleParameters) = |   def union(x: TLBundleParameters) = | ||||||
|     TLBundleParameters( |     TLBundleParameters( | ||||||
|       max(addressBits, x.addressBits), |       max(addrHiBits,  x.addrHiBits), | ||||||
|       max(dataBits,    x.dataBits), |       max(dataBits,    x.dataBits), | ||||||
|       max(sourceBits,  x.sourceBits), |       max(sourceBits,  x.sourceBits), | ||||||
|       max(sinkBits,    x.sinkBits), |       max(sinkBits,    x.sinkBits), | ||||||
| @@ -320,7 +322,7 @@ case class TLEdgeParameters( | |||||||
|   require (maxTransfer >= manager.beatBytes) |   require (maxTransfer >= manager.beatBytes) | ||||||
|  |  | ||||||
|   val bundle = TLBundleParameters( |   val bundle = TLBundleParameters( | ||||||
|     addressBits = log2Up(manager.maxAddress + 1), |     addrHiBits  = log2Up(manager.maxAddress + 1) - log2Up(manager.beatBytes), | ||||||
|     dataBits    = manager.beatBytes * 8, |     dataBits    = manager.beatBytes * 8, | ||||||
|     sourceBits  = log2Up(client.endSourceId), |     sourceBits  = log2Up(client.endSourceId), | ||||||
|     sinkBits    = log2Up(manager.endSinkId), |     sinkBits    = log2Up(manager.endSinkId), | ||||||
|   | |||||||
| @@ -20,14 +20,20 @@ class TLRegisterNode(address: AddressSet, concurrency: Option[Int] = None, beatB | |||||||
|     val a = bundleIn(0).a |     val a = bundleIn(0).a | ||||||
|     val d = bundleIn(0).d |     val d = bundleIn(0).d | ||||||
|     val edge = edgesIn(0) |     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))) |     val in = Wire(Decoupled(new RegMapperInput(params))) | ||||||
|     in.bits.read  := a.bits.opcode === TLMessages.Get |     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.data  := a.bits.data | ||||||
|     in.bits.mask  := a.bits.mask |     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 |     // Invoke the register map builder | ||||||
|     val (endIndex, out) = RegMapper(beatBytes, concurrency, in, mapping:_*) |     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 |     d.valid   := out.valid | ||||||
|     out.ready := d.ready |     out.ready := d.ready | ||||||
|  |  | ||||||
|     val sizeBits = edge.bundle.sizeBits |     // We must restore the size and addr_lo to enable width adapters to work | ||||||
|     d.bits := edge.AccessAck(out.bits.extra >> sizeBits, out.bits.extra(sizeBits-1, 0)) |     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 |     // avoid a Mux on the data bus by manually overriding two fields | ||||||
|     d.bits.data := out.bits.data |     d.bits.data := out.bits.data | ||||||
|     d.bits.opcode := Mux(out.bits.read, TLMessages.AccessAckData, TLMessages.AccessAck) |     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] = |     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) |       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 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 memAddress = Cat(addrBits.reverse) | ||||||
|     val mem = SeqMem(1 << addrBits.size, Vec(beatBytes, Bits(width = 8))) |     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_read = Reg(Bool()) | ||||||
|     val d_size = Reg(UInt()) |     val d_size = Reg(UInt()) | ||||||
|     val d_source = Reg(UInt()) |     val d_source = Reg(UInt()) | ||||||
|  |     val d_addr = Reg(UInt()) | ||||||
|     val d_data = Wire(UInt()) |     val d_data = Wire(UInt()) | ||||||
|  |  | ||||||
|     // Flow control |     // Flow control | ||||||
| @@ -43,7 +44,8 @@ class TLRAM(address: AddressSet, beatBytes: Int = 4) extends LazyModule | |||||||
|     in.d.valid := d_full |     in.d.valid := d_full | ||||||
|     in.a.ready := in.d.ready || !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 |     // avoid data-bus Mux | ||||||
|     in.d.bits.data := d_data |     in.d.bits.data := d_data | ||||||
|     in.d.bits.opcode := Mux(d_read, TLMessages.AccessAckData, TLMessages.AccessAck) |     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_read   := read | ||||||
|       d_size   := in.a.bits.size |       d_size   := in.a.bits.size | ||||||
|       d_source := in.a.bits.source |       d_source := in.a.bits.source | ||||||
|  |       d_addr   := edge.addr_lo(in.a.bits) | ||||||
|       when (read) { |       when (read) { | ||||||
|         rdata := mem.read(memAddress) |         rdata := mem.read(memAddress) | ||||||
|       } .otherwise { |       } .otherwise { | ||||||
|   | |||||||
| @@ -23,10 +23,6 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL | |||||||
|     require (eo.asInstanceOf[TLEdgeParameters] == ei.asInstanceOf[TLEdgeParameters]) |     require (eo.asInstanceOf[TLEdgeParameters] == ei.asInstanceOf[TLEdgeParameters]) | ||||||
|     TLMonitor.legalize(bo, eo, bi, ei) |     TLMonitor.legalize(bo, eo, bi, ei) | ||||||
|     bi <> bo |     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,11 +145,11 @@ class TLXbar(policy: (Vec[Bool], Bool) => Seq[Bool] = TLXbar.lowestIndex) extend | |||||||
|       in(i).e.ready := Mux1C(grantedEIO(i), out.map(_.e.ready)) |       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 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 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)    }) }) |     val requestEIO = Vec(in.map  { i => Vec(outputIdRanges.map { o => i.e.valid && o        .contains(i.e.bits.sink)       }) }) | ||||||
|  |  | ||||||
|     val beatsA = Vec((in  zip node.edgesIn)  map { case (i, e) => e.numBeats(i.a.bits) }) |     val beatsA = Vec((in  zip node.edgesIn)  map { case (i, e) => e.numBeats(i.a.bits) }) | ||||||
|     val beatsB = Vec((out zip node.edgesOut) map { case (o, e) => e.numBeats(o.b.bits) }) |     val beatsB = Vec((out zip node.edgesOut) map { case (o, e) => e.numBeats(o.b.bits) }) | ||||||
|   | |||||||
| @@ -5,4 +5,6 @@ import Chisel._ | |||||||
| package object tilelink2 | package object tilelink2 | ||||||
| { | { | ||||||
|   type TLBaseNode = BaseNode[TLClientPortParameters, TLManagerPortParameters, TLEdgeOut, TLEdgeIn, TLBundle] |   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) | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user