diff --git a/src/main/scala/coreplex/RISCVPlatform.scala b/src/main/scala/coreplex/RISCVPlatform.scala index 79a306e2..4744ea85 100644 --- a/src/main/scala/coreplex/RISCVPlatform.scala +++ b/src/main/scala/coreplex/RISCVPlatform.scala @@ -25,6 +25,7 @@ trait CoreplexRISCVPlatform extends CoreplexNetwork { plic.intnode := intBar.intnode lazy val dts = DTS(bindingTree) + lazy val json = JSON(bindingTree) } trait CoreplexRISCVPlatformBundle extends CoreplexNetworkBundle { @@ -49,4 +50,5 @@ trait CoreplexRISCVPlatformModule extends CoreplexNetworkModule { println(outer.dts) ElaborationArtefacts.add("dts", outer.dts) + ElaborationArtefacts.add("json", outer.json) } diff --git a/src/main/scala/diplomacy/JSON.scala b/src/main/scala/diplomacy/JSON.scala new file mode 100644 index 00000000..ff6b28e3 --- /dev/null +++ b/src/main/scala/diplomacy/JSON.scala @@ -0,0 +1,45 @@ +// See LICENSE.SiFive for license details. + +package diplomacy + +import scala.collection.immutable.SortedMap + +object JSON +{ + def apply(res: ResourceValue): String = { + val root = res match { + case ResourceMap(value, _) => value.toList match { + case Seq(("/", Seq(subtree))) => subtree + case _ => res + } + case _ => res + } + helper(root)(SortedMap(map(root):_*)).mkString + } + + private def map(res: ResourceValue, path: String = ""): Seq[(String, String)] = res match { + case ResourceMap(value, labels) => { + labels.map(_ -> path) ++ + value.flatMap { case (key, seq) => seq.flatMap(map(_, path + "/" + key)) } + } + case _ => Nil + } + + private def helper(res: ResourceValue)(implicit path: Map[String, String]): Seq[String] = res match { + case ResourceAddress(address, r, w, x) => + AddressRange.fromSets(address).map { case AddressRange(base, size) => + s"""{"base":${base},"size":${size},"r":${r},"w":${w},"x":${x}}"""} + case ResourceMapping(address, offset) => + AddressRange.fromSets(address).map { case AddressRange(base, size) => + s"""{"base":${base},"size":${size},"offset":${offset}}"""} + case ResourceInt(value) => Seq(value.toString) + case ResourceString(value) => Seq("\"" + value + "\"") + case ResourceReference(value) => Seq("\"&" + path(value) + "\"") + case ResourceMap(value, _) => { + Seq(value.map { + case (key, Seq(v: ResourceMap)) => s""""${key}":${helper(v).mkString}""" + case (key, seq) => s""""${key}":[${seq.flatMap(helper).mkString(",")}]""" + }.mkString("{", ",", "}")) + } + } +} diff --git a/src/main/scala/diplomacy/Resources.scala b/src/main/scala/diplomacy/Resources.scala index 04a454df..cfcaa23b 100644 --- a/src/main/scala/diplomacy/Resources.scala +++ b/src/main/scala/diplomacy/Resources.scala @@ -126,9 +126,9 @@ trait BindingScope protected[diplomacy] var resourceBindings: Seq[(Resource, Option[Device], ResourceValue)] = Nil private case class ExpandedValue(path: Seq[String], labels: Seq[String], value: Seq[ResourceValue]) - private def eval() { + private lazy val eval: Unit = { require (LazyModule.stack.isEmpty, "May not evaluate binding while still constructing LazyModules") - parentScope.foreach { _.eval() } + parentScope.foreach { _.eval } resourceBindings = parentScope.map(_.resourceBindings).getOrElse(Nil) BindingScope.active = Some(this) resourceBindingFns.reverse.foreach { _() } @@ -142,7 +142,6 @@ trait BindingScope val labels = values_p.flatMap(_.labels) val keys = keys_p.groupBy(_.path.head).toList.map { case (key, seq) => (key -> makeTree(seq.map { x => x.copy(path = x.path.tail) })) - // case ExpandedValue(keys, values) => ExpandedValue(keys.tail, values) })) } if (keys.isEmpty) values else ResourceMap(SortedMap(keys:_*), labels) +: values } @@ -158,7 +157,7 @@ trait BindingScope } def bindingTree: ResourceMap = { - eval() + eval val map: Map[Device, ResourceBindings] = resourceBindings.reverse.groupBy(_._1.owner).mapValues(seq => ResourceBindings( seq.groupBy(_._1.key).mapValues(_.map(z => Binding(z._2, z._3))))) diff --git a/src/main/scala/rocket/ScratchpadSlavePort.scala b/src/main/scala/rocket/ScratchpadSlavePort.scala index 7bcc7a7f..3c5a9794 100644 --- a/src/main/scala/rocket/ScratchpadSlavePort.scala +++ b/src/main/scala/rocket/ScratchpadSlavePort.scala @@ -15,9 +15,11 @@ import util._ class ScratchpadSlavePort(sizeBytes: Int)(implicit p: Parameters) extends LazyModule with HasCoreParameters { + val device = new MemoryDevice val node = TLManagerNode(Seq(TLManagerPortParameters( Seq(TLManagerParameters( address = List(AddressSet(0x80000000L, BigInt(sizeBytes-1))), + resources = device.reg, regionType = RegionType.UNCACHED, executable = true, supportsArithmetic = if (usingAtomics) TransferSizes(1, coreDataBytes) else TransferSizes.none, diff --git a/src/main/scala/rocket/Tile.scala b/src/main/scala/rocket/Tile.scala index 04462028..90de7e63 100644 --- a/src/main/scala/rocket/Tile.scala +++ b/src/main/scala/rocket/Tile.scala @@ -43,19 +43,31 @@ class RocketTile(val rocketParams: RocketTileParams, val hartid: Int)(implicit p val isa = s"rv${p(XLen)}i$m$a$f$d$c$s" val dcache = rocketParams.dcache.map(d => Map( - "d-tlb-size" -> ofInt(d.nTLBEntries), - "d-tlb-sets" -> ofInt(1), "d-cache-block-size" -> ofInt(block), "d-cache-sets" -> ofInt(d.nSets), "d-cache-size" -> ofInt(d.nSets * d.nWays * block))).getOrElse(Map()) val icache = rocketParams.icache.map(i => Map( - "i-tlb-size" -> ofInt(i.nTLBEntries), - "i-tlb-sets" -> ofInt(1), "i-cache-block-size" -> ofInt(block), "i-cache-sets" -> ofInt(i.nSets), "i-cache-size" -> ofInt(i.nSets * i.nWays * block))).getOrElse(Map()) + val dtlb = rocketParams.dcache.filter(_ => rocketParams.core.useVM).map(d => Map( + "d-tlb-size" -> ofInt(d.nTLBEntries), + "d-tlb-sets" -> ofInt(1))).getOrElse(Map()) + + val itlb = rocketParams.icache.filter(_ => rocketParams.core.useVM).map(i => Map( + "i-tlb-size" -> ofInt(i.nTLBEntries), + "i-tlb-sets" -> ofInt(1))).getOrElse(Map()) + + val mmu = if (!rocketParams.core.useVM) Map() else Map( + "tlb-split" -> Nil, + "mmu-type" -> ofStr(p(PgLevels) match { + case 2 => "riscv,sv32" + case 3 => "riscv,sv39" + case 4 => "riscv,sv48" + })) + // Find all the caches val outer = masterNode.edgesOut .flatMap(_.manager.managers) @@ -74,14 +86,9 @@ class RocketTile(val rocketParams: RocketTileParams, val hartid: Int)(implicit p "status" -> ofStr("okay"), "clock-frequency" -> Seq(ResourceInt(rocketParams.core.bootFreqHz)), "riscv,isa" -> ofStr(isa), - "mmu-type" -> ofStr(p(PgLevels) match { - case 2 => "riscv,sv32" - case 3 => "riscv,sv39" - case 4 => "riscv,sv48" }), - "tlb-split" -> Nil, "interrupt-controller" -> Nil, "#interrupt-cells" -> ofInt(1)) - ++ dcache ++ icache ++ nextlevel) + ++ dcache ++ icache ++ nextlevel ++ mmu ++ itlb ++ dtlb) } } diff --git a/src/main/scala/rocketchip/Configs.scala b/src/main/scala/rocketchip/Configs.scala index f69f0d9b..1c975c98 100644 --- a/src/main/scala/rocketchip/Configs.scala +++ b/src/main/scala/rocketchip/Configs.scala @@ -148,6 +148,10 @@ class WithDTS(model: String, compat: Seq[String]) extends Config((site, here, up case DTSCompat => compat }) +class WithTimebase(hertz: BigInt) extends Config((site, here, up) => { + case DTSTimebase => hertz +}) + class WithScratchpad extends Config(new WithNMemoryChannels(0) ++ new WithDataScratchpad(16384)) class DefaultFPGASmallConfig extends Config(new WithNSmallCores(1) ++ new DefaultFPGAConfig) diff --git a/src/main/scala/rocketchip/Periphery.scala b/src/main/scala/rocketchip/Periphery.scala index 3fdc8a41..65b59033 100644 --- a/src/main/scala/rocketchip/Periphery.scala +++ b/src/main/scala/rocketchip/Periphery.scala @@ -59,10 +59,12 @@ trait PeripheryExtInterrupts { val nExtInterrupts = p(NExtTopInterrupts) val extInterrupts = IntInternalInputNode(IntSourcePortSimple(num = nExtInterrupts, resources = device.int)) - val extInterruptXing = LazyModule(new IntXing) - intBus.intnode := extInterruptXing.intnode - extInterruptXing.intnode := extInterrupts + if (nExtInterrupts > 0) { + val extInterruptXing = LazyModule(new IntXing) + intBus.intnode := extInterruptXing.intnode + extInterruptXing.intnode := extInterrupts + } } trait PeripheryExtInterruptsBundle { @@ -77,7 +79,7 @@ trait PeripheryExtInterruptsModule { val outer: PeripheryExtInterrupts val io: PeripheryExtInterruptsBundle } => - outer.extInterrupts.bundleIn(0).zipWithIndex.foreach { case(o, i) => o := io.interrupts(i) } + outer.extInterrupts.bundleIn.flatten.zipWithIndex.foreach { case(o, i) => o := io.interrupts(i) } } /////