tilelink2 Xbar: merge the AddressSets of fractured managers
This commit is contained in:
		| @@ -144,5 +144,24 @@ object AddressSet | ||||
|       misaligned(base+step, size-step, AddressSet(base, step-1) +: tail) | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
|   def unify(seq: Seq[AddressSet]): Seq[AddressSet] = { | ||||
|     val n = seq.size | ||||
|     val array = Array(seq:_*) | ||||
|     var filter = Array.fill(n) { false } | ||||
|     for (i <- 0 until n-1) { if (!filter(i)) { | ||||
|       for (j <- i+1 until n) { if (!filter(j)) { | ||||
|         val a = array(i) | ||||
|         val b = array(j) | ||||
|         if (a.mask == b.mask && isPow2(a.base ^ b.base)) { | ||||
|           val c_base = a.base & ~(a.base ^ b.base) | ||||
|           val c_mask = a.mask | (a.base ^ b.base) | ||||
|           filter.update(j, true) | ||||
|           array.update(i, AddressSet(c_base, c_mask)) | ||||
|         } | ||||
|       }} | ||||
|     }} | ||||
|     val out = (array zip filter) flatMap { case (a, f) => if (f) None else Some(a) } | ||||
|     if (out.size != n) unify(out) else out.toList | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -287,3 +287,45 @@ case class TLAsyncEdgeParameters(client: TLAsyncClientPortParameters, manager: T | ||||
| { | ||||
|   val bundle = TLAsyncBundleParameters(manager.depth, TLBundleParameters(client.base, manager.base)) | ||||
| } | ||||
|  | ||||
| object ManagerUnification | ||||
| { | ||||
|   def apply(managers: Seq[TLManagerParameters]) = { | ||||
|     // To be unified, devices must agree on all of these terms | ||||
|     case class TLManagerKey( | ||||
|       regionType:         RegionType.T, | ||||
|       executable:         Boolean, | ||||
|       lastNode:           BaseNode, | ||||
|       supportsAcquire:    TransferSizes, | ||||
|       supportsArithmetic: TransferSizes, | ||||
|       supportsLogical:    TransferSizes, | ||||
|       supportsGet:        TransferSizes, | ||||
|       supportsPutFull:    TransferSizes, | ||||
|       supportsPutPartial: TransferSizes, | ||||
|       supportsHint:       TransferSizes) | ||||
|     def key(x: TLManagerParameters) = TLManagerKey( | ||||
|       regionType         = x.regionType, | ||||
|       executable         = x.executable, | ||||
|       lastNode           = x.nodePath.last, | ||||
|       supportsAcquire    = x.supportsAcquire, | ||||
|       supportsArithmetic = x.supportsArithmetic, | ||||
|       supportsLogical    = x.supportsLogical, | ||||
|       supportsGet        = x.supportsGet, | ||||
|       supportsPutFull    = x.supportsPutFull, | ||||
|       supportsPutPartial = x.supportsPutPartial, | ||||
|       supportsHint       = x.supportsHint) | ||||
|     val map = scala.collection.mutable.HashMap[TLManagerKey, TLManagerParameters]() | ||||
|     managers.foreach { m => | ||||
|       val k = key(m) | ||||
|       map.get(k) match { | ||||
|         case None => map.update(k, m) | ||||
|         case Some(n) => { | ||||
|           map.update(k, m.copy( | ||||
|             address = m.address ++ n.address, | ||||
|             fifoId  = None)) // Merging means it's not FIFO anymore! | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     map.values.map(m => m.copy(address = AddressSet.unify(m.address))).toList | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -54,13 +54,13 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.lowestIndexFirst) extends Lazy | ||||
|       seq(0).copy( | ||||
|         minLatency = seq.map(_.minLatency).min, | ||||
|         endSinkId = outputIdRanges.map(_.end).max, | ||||
|         managers = (outputIdRanges zip seq) flatMap { case (range, port) => | ||||
|         managers = ManagerUnification(seq.flatMap { port => | ||||
|           require (port.beatBytes == seq(0).beatBytes) | ||||
|           val fifoIdMapper = fifoIdFactory() | ||||
|           port.managers map { manager => manager.copy( | ||||
|             fifoId = manager.fifoId.map(fifoIdMapper(_)) | ||||
|           )} | ||||
|         } | ||||
|         }) | ||||
|       ) | ||||
|     }) | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user