coreplex: print memory map using DTS, also write a JSON for it
This commit is contained in:
		| @@ -115,22 +115,47 @@ trait CoreplexNetworkModule extends HasCoreplexParameters { | |||||||
|   val io: CoreplexNetworkBundle |   val io: CoreplexNetworkBundle | ||||||
|  |  | ||||||
|   println("Generated Address Map") |   println("Generated Address Map") | ||||||
|   val ranges = outer.topManagers.get.flatMap { manager => |   private val aw = (outer.p(rocket.PAddrBits)-1)/4 + 1 | ||||||
|     val prot = (if (manager.supportsGet)     "R" else "") + |   private val fmt = s"\t%${aw}x - %${aw}x %c%c%c%c %s" | ||||||
|                (if (manager.supportsPutFull) "W" else "") + |  | ||||||
|                (if (manager.executable)      "X" else "") + |   private def collect(path: List[String], value: ResourceValue): List[(String, ResourceAddress)] = { | ||||||
|                (if (manager.supportsAcquireB) " [C]" else "") |     value match { | ||||||
|     AddressRange.fromSets(manager.address).map { r => |       case r: ResourceAddress => List((path(1), r)) | ||||||
|       (manager.name, r.base, r.base+r.size, prot) |       case ResourceMap(value, _) => value.toList.flatMap { case (key, seq) => seq.flatMap(r => collect(key :: path, r)) } | ||||||
|  |       case _ => Nil | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   val aw = (outer.p(rocket.PAddrBits)-1)/4 + 1 |   private val ranges = collect(Nil, outer.bindingTree).groupBy(_._2).toList.flatMap { case (key, seq) => | ||||||
|   val nw = ranges.map(_._1.length).max |     AddressRange.fromSets(key.address).map { r => (r, key.r, key.w, key.x, key.c, seq.map(_._1)) } | ||||||
|   val fmt = s"\t%${nw}s %${aw}x - %${aw}x, %s" |   }.sortBy(_._1) | ||||||
|   ranges.sortWith(_._2 < _._2).foreach { case (name, start, end, prot) => |   private val json = ranges.map { case (range, r, w, x, c, names) => | ||||||
|     println(fmt.format(name, start, end, prot)) |     println(fmt.format( | ||||||
|  |       range.base, | ||||||
|  |       range.base+range.size, | ||||||
|  |       if (r) 'R' else ' ', | ||||||
|  |       if (w) 'W' else ' ', | ||||||
|  |       if (x) 'X' else ' ', | ||||||
|  |       if (c) 'C' else ' ', | ||||||
|  |       names.mkString(", "))) | ||||||
|  |     s"""{"base":[${range.base}],"size":[${range.size}],"r":[$r],"w":[$w],"x":[$x],"c":[$c],"names":[${names.map('"'+_+'"').mkString(",")}]}""" | ||||||
|   } |   } | ||||||
|   println("") |   println("") | ||||||
|  |   ElaborationArtefacts.add("memmap.json", s"""{"mapping":[${json.mkString(",")}]}""") | ||||||
|  |  | ||||||
|  |   // Confirm that all of memory was described by DTS | ||||||
|  |   private val dtsRanges = AddressRange.unify(ranges.map(_._1)) | ||||||
|  |   private val allRanges = AddressRange.unify(outer.topManagers.get.flatMap { m => AddressRange.fromSets(m.address) }) | ||||||
|  |  | ||||||
|  |   if (dtsRanges != allRanges) { | ||||||
|  |     println("Address map described by DTS differs from physical implementation:") | ||||||
|  |     AddressRange.subtract(allRanges, dtsRanges).foreach { case r => | ||||||
|  |       println(s"\texists, but undescribed by DTS: ${r}") | ||||||
|  |     } | ||||||
|  |     AddressRange.subtract(dtsRanges, allRanges).foreach { case r => | ||||||
|  |       println(s"\tdoes not exist, but described by DTS: ${r}") | ||||||
|  |     } | ||||||
|  |     println("") | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| ///// | ///// | ||||||
|   | |||||||
| @@ -3,7 +3,6 @@ | |||||||
| package diplomacy | package diplomacy | ||||||
|  |  | ||||||
| import Chisel._ | import Chisel._ | ||||||
| import scala.math.max |  | ||||||
|  |  | ||||||
| /** Options for memory regions */ | /** Options for memory regions */ | ||||||
| object RegionType { | object RegionType { | ||||||
| @@ -110,6 +109,14 @@ case class AddressRange(base: BigInt, size: BigInt) extends Ordered[AddressRange | |||||||
|       Some(AddressRange(obase, oend-obase)) |       Some(AddressRange(obase, oend-obase)) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   private def helper(base: BigInt, end: BigInt) = | ||||||
|  |     if (base < end) Seq(AddressRange(base, end-base)) else Nil | ||||||
|  |   def subtract(x: AddressRange) = | ||||||
|  |     helper(base, end min x.base) ++ helper(base max x.end, end) | ||||||
|  |  | ||||||
|  |   // We always want to see things in hex | ||||||
|  |   override def toString() = "AddressRange(0x%x, 0x%x)".format(base, size) | ||||||
| } | } | ||||||
|  |  | ||||||
| // AddressSets specify the address space managed by the manager | // AddressSets specify the address space managed by the manager | ||||||
| @@ -197,6 +204,9 @@ object AddressRange | |||||||
|       } |       } | ||||||
|     }.reverse |     }.reverse | ||||||
|   } |   } | ||||||
|  |   // Set subtraction... O(n*n) b/c I am lazy | ||||||
|  |   def subtract(from: Seq[AddressRange], take: Seq[AddressRange]): Seq[AddressRange] = | ||||||
|  |     take.foldLeft(from) { case (left, r) => left.flatMap { _.subtract(r) } } | ||||||
| } | } | ||||||
|  |  | ||||||
| object AddressSet | object AddressSet | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user