diff --git a/src/main/scala/uncore/tilelink2/Edges.scala b/src/main/scala/uncore/tilelink2/Edges.scala index 0d178560..6c156ab6 100644 --- a/src/main/scala/uncore/tilelink2/Edges.scala +++ b/src/main/scala/uncore/tilelink2/Edges.scala @@ -20,12 +20,13 @@ class TLEdge( // This gets used everywhere, so make the smallest circuit possible ... def fullMask(address: UInt, lgSize: UInt) = { val lgBytes = log2Ceil(manager.beatBytes) + val sizeOH = UIntToOH(lgSize, lgBytes) def helper(i: Int): Seq[(Bool, Bool)] = { if (i == 0) { Seq((lgSize >= UInt(lgBytes), Bool(true))) } else { val sub = helper(i-1) - val size = lgSize === UInt(lgBytes - i) + val size = sizeOH(lgBytes - i) val bit = address(lgBytes - i) val nbit = !bit Seq.tabulate (1 << i) { j => @@ -39,6 +40,23 @@ class TLEdge( Cat(helper(lgBytes).map(_._1).reverse) } + def lowAddress(mask: UInt) = { + // Almost OHToUInt, but any bit in low => use low address + def helper(mask: UInt, width: Int): UInt = { + if (width <= 1) { + UInt(0) + } else if (width == 2) { + ~mask(0, 0) + } else { + val mid = 1 << (log2Up(width)-1) + val hi = mask(width-1, mid) + val lo = mask(mid-1, 0) + Cat(!lo.orR, helper(hi | lo, mid)) + } + } + helper(mask, bundle.dataBits/8) + } + def staticHasData(bundle: HasTLOpcode): Option[Boolean] = { bundle.channelType() match { case ChannelType.A => { diff --git a/src/main/scala/uncore/tilelink2/Monitor.scala b/src/main/scala/uncore/tilelink2/Monitor.scala index 97132d97..8f974a8a 100644 --- a/src/main/scala/uncore/tilelink2/Monitor.scala +++ b/src/main/scala/uncore/tilelink2/Monitor.scala @@ -20,7 +20,7 @@ object TLMonitor // Reuse these subexpressions to save some firrtl lines val source_ok = edge.client.contains(bundle.source) val is_aligned = edge.isAligned(bundle.address, bundle.size) - val mask = edge.fullMask(bundle.address, bundle.size) + val mask = edge.fullMask(bundle.address | edge.lowAddress(bundle.mask), bundle.size) when (bundle.opcode === TLMessages.Acquire) { assert (edge.manager.supportsAcquire(bundle.address, bundle.size), "'A' channel carries Acquire type unsupported by manager" + extra) @@ -86,7 +86,7 @@ object TLMonitor // Reuse these subexpressions to save some firrtl lines val address_ok = edge.manager.contains(bundle.source) val is_aligned = edge.isAligned(bundle.address, bundle.size) - val mask = edge.fullMask(bundle.address, bundle.size) + val mask = edge.fullMask(bundle.address | edge.lowAddress(bundle.mask), bundle.size) when (bundle.opcode === TLMessages.Probe) { assert (edge.client.supportsProbe(bundle.source, bundle.size), "'B' channel carries Probe type unsupported by client" + extra)