Merge pull request #827 from freechipsproject/dts-improvements
Dts improvements
This commit is contained in:
		@@ -118,14 +118,15 @@ trait CoreplexNetworkModule extends HasCoreplexParameters {
 | 
				
			|||||||
  private def collect(path: List[String], value: ResourceValue): List[(String, ResourceAddress)] = {
 | 
					  private def collect(path: List[String], value: ResourceValue): List[(String, ResourceAddress)] = {
 | 
				
			||||||
    value match {
 | 
					    value match {
 | 
				
			||||||
      case r: ResourceAddress => List((path(1), r))
 | 
					      case r: ResourceAddress => List((path(1), r))
 | 
				
			||||||
 | 
					      case b: ResourceMapping => List((path(1), ResourceAddress(b.address, b.permissions)))
 | 
				
			||||||
      case ResourceMap(value, _) => value.toList.flatMap { case (key, seq) => seq.flatMap(r => collect(key :: path, r)) }
 | 
					      case ResourceMap(value, _) => value.toList.flatMap { case (key, seq) => seq.flatMap(r => collect(key :: path, r)) }
 | 
				
			||||||
      case _ => Nil
 | 
					      case _ => Nil
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  private val ranges = collect(Nil, outer.bindingTree).groupBy(_._2).toList.flatMap { case (key, seq) =>
 | 
					  private val ranges = collect(Nil, outer.bindingTree).groupBy(_._2).toList.flatMap { case (key, seq) =>
 | 
				
			||||||
    AddressRange.fromSets(key.address).map { r => (r, key.r, key.w, key.x, key.c, seq.map(_._1)) }
 | 
					    AddressRange.fromSets(key.address).map { r => (r, key.permissions, seq.map(_._1)) }
 | 
				
			||||||
  }.sortBy(_._1)
 | 
					  }.sortBy(_._1)
 | 
				
			||||||
  private val json = ranges.map { case (range, r, w, x, c, names) =>
 | 
					  private val json = ranges.map { case (range, ResourcePermissions(r, w, x, c), names) =>
 | 
				
			||||||
    println(fmt.format(
 | 
					    println(fmt.format(
 | 
				
			||||||
      range.base,
 | 
					      range.base,
 | 
				
			||||||
      range.base+range.size,
 | 
					      range.base+range.size,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,12 +26,12 @@ object JSON
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private def helper(res: ResourceValue)(implicit path: Map[String, String]): Seq[String] = res match {
 | 
					  private def helper(res: ResourceValue)(implicit path: Map[String, String]): Seq[String] = res match {
 | 
				
			||||||
    case ResourceAddress(address, r, w, x, c) =>
 | 
					    case ResourceAddress(address, ResourcePermissions(r, w, x, c)) =>
 | 
				
			||||||
      AddressRange.fromSets(address).map { case AddressRange(base, size) =>
 | 
					      AddressRange.fromSets(address).map { case AddressRange(base, size) =>
 | 
				
			||||||
        s"""{"base":${base},"size":${size},"r":${r},"w":${w},"x":${x},"c":${c}}"""}
 | 
					        s"""{"base":${base},"size":${size},"r":${r},"w":${w},"x":${x},"c":${c}}"""}
 | 
				
			||||||
    case ResourceMapping(address, offset) =>
 | 
					    case ResourceMapping(address, offset, ResourcePermissions(r, w, x, c)) =>
 | 
				
			||||||
      AddressRange.fromSets(address).map { case AddressRange(base, size) =>
 | 
					      AddressRange.fromSets(address).map { case AddressRange(base, size) =>
 | 
				
			||||||
        s"""{"base":${base},"size":${size},"offset":${offset}}"""}
 | 
					        s"""{"base":${base},"size":${size},"offset":${offset},"r":${r},"w":${w},"x":${x},"c":${c}}"""}
 | 
				
			||||||
    case ResourceInt(value) => Seq(value.toString)
 | 
					    case ResourceInt(value) => Seq(value.toString)
 | 
				
			||||||
    case ResourceString(value) => Seq("\"" + value + "\"")
 | 
					    case ResourceString(value) => Seq("\"" + value + "\"")
 | 
				
			||||||
    case ResourceReference(value) => Seq("\"&" + path(value) + "\"")
 | 
					    case ResourceReference(value) => Seq("\"&" + path(value) + "\"")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,8 +7,9 @@ import config._
 | 
				
			|||||||
import scala.collection.immutable.{ListMap,SortedMap}
 | 
					import scala.collection.immutable.{ListMap,SortedMap}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sealed trait ResourceValue
 | 
					sealed trait ResourceValue
 | 
				
			||||||
final case class ResourceAddress(address: Seq[AddressSet], r: Boolean, w: Boolean, x: Boolean, c: Boolean) extends ResourceValue
 | 
					case class ResourcePermissions(r: Boolean, w: Boolean, x: Boolean, c: Boolean) // Not part of DTS
 | 
				
			||||||
final case class ResourceMapping(address: Seq[AddressSet], offset: BigInt) extends ResourceValue
 | 
					final case class ResourceAddress(address: Seq[AddressSet], permissions: ResourcePermissions) extends ResourceValue
 | 
				
			||||||
 | 
					final case class ResourceMapping(address: Seq[AddressSet], offset: BigInt, permissions: ResourcePermissions) extends ResourceValue
 | 
				
			||||||
final case class ResourceInt(value: BigInt) extends ResourceValue
 | 
					final case class ResourceInt(value: BigInt) extends ResourceValue
 | 
				
			||||||
final case class ResourceString(value: String) extends ResourceValue
 | 
					final case class ResourceString(value: String) extends ResourceValue
 | 
				
			||||||
final case class ResourceReference(value: String) extends ResourceValue
 | 
					final case class ResourceReference(value: String) extends ResourceValue
 | 
				
			||||||
@@ -69,15 +70,29 @@ trait DeviceRegName
 | 
				
			|||||||
  this: Device =>
 | 
					  this: Device =>
 | 
				
			||||||
  val prefix = "soc/" // nearly everything on-chip belongs here
 | 
					  val prefix = "soc/" // nearly everything on-chip belongs here
 | 
				
			||||||
  def describeName(devname: String, resources: ResourceBindings): String = {
 | 
					  def describeName(devname: String, resources: ResourceBindings): String = {
 | 
				
			||||||
    val reg = resources("reg")
 | 
					    val reg = resources.map.filterKeys(regFilter)
 | 
				
			||||||
    require (!reg.isEmpty, "Device is missing the 'reg' property")
 | 
					    if (reg.isEmpty) {
 | 
				
			||||||
    reg.head.value match {
 | 
					      devname
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      val (named, bulk) = reg.partition { case (k, v) => regName(k).isDefined }
 | 
				
			||||||
 | 
					      val mainreg = reg.find(x => regName(x._1) == "control").getOrElse(reg.head)._2
 | 
				
			||||||
 | 
					      require (!mainreg.isEmpty, s"reg binding for $devname is empty!")
 | 
				
			||||||
 | 
					      mainreg.head.value match {
 | 
				
			||||||
        case x: ResourceAddress => s"${prefix}${devname}@${x.address.head.base.toString(16)}"
 | 
					        case x: ResourceAddress => s"${prefix}${devname}@${x.address.head.base.toString(16)}"
 | 
				
			||||||
        case _ => require(false, "Device has the wrong type of 'reg' property (${reg.head})"); ""
 | 
					        case _ => require(false, "Device has the wrong type of 'reg' property (${reg.head})"); ""
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def reg = Seq(Resource(this, "reg"))
 | 
					  def reg(name: String): Seq[Resource] = Seq(Resource(this, "reg/" + name))
 | 
				
			||||||
 | 
					  def reg: Seq[Resource] = Seq(Resource(this, "reg"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def regFilter(name: String): Boolean = name == "reg" || name.take(4) == "reg/"
 | 
				
			||||||
 | 
					  def regName(name: String): Option[String] = {
 | 
				
			||||||
 | 
					    val keys = name.split("/")
 | 
				
			||||||
 | 
					    require (keys.size >= 1 && keys.size <= 2 && keys(0) == "reg", s"Invalid reg name '${name}'")
 | 
				
			||||||
 | 
					    if (keys.size == 1) None else Some(keys(1))
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SimpleDevice(devname: String, devcompat: Seq[String]) extends Device with DeviceInterrupts with DeviceRegName
 | 
					class SimpleDevice(devname: String, devcompat: Seq[String]) extends Device with DeviceInterrupts with DeviceRegName
 | 
				
			||||||
@@ -85,14 +100,52 @@ class SimpleDevice(devname: String, devcompat: Seq[String]) extends Device with
 | 
				
			|||||||
  def describe(resources: ResourceBindings): Description = {
 | 
					  def describe(resources: ResourceBindings): Description = {
 | 
				
			||||||
    val name = describeName(devname, resources)
 | 
					    val name = describeName(devname, resources)
 | 
				
			||||||
    val int = describeInterrupts(resources)
 | 
					    val int = describeInterrupts(resources)
 | 
				
			||||||
    val compat =
 | 
					 | 
				
			||||||
      if (devcompat.isEmpty) None else
 | 
					 | 
				
			||||||
      Some("compatible" -> devcompat.map(ResourceString(_)))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Description(name,
 | 
					    def optDef(x: String, seq: Seq[ResourceValue]) = if (seq.isEmpty) None else Some(x -> seq)
 | 
				
			||||||
      ListMap("reg" -> resources("reg").map(_.value))
 | 
					    val compat = optDef("compatible", devcompat.map(ResourceString(_)))
 | 
				
			||||||
      ++ compat ++ int)
 | 
					
 | 
				
			||||||
 | 
					    val reg = resources.map.filterKeys(regFilter)
 | 
				
			||||||
 | 
					    val (named, bulk) = reg.partition { case (k, v) => regName(k).isDefined }
 | 
				
			||||||
 | 
					    // We need to be sure that each named reg has exactly one AddressRange associated to it
 | 
				
			||||||
 | 
					    named.foreach {
 | 
				
			||||||
 | 
					      case (k, Seq(Binding(_, value: ResourceAddress))) =>
 | 
				
			||||||
 | 
					        val ranges = AddressRange.fromSets(value.address)
 | 
				
			||||||
 | 
					        require (ranges.size == 1, s"DTS device $name has $k = $ranges, must be a single range!")
 | 
				
			||||||
 | 
					      case (k, seq) =>
 | 
				
			||||||
 | 
					        require (false, s"DTS device $name has $k = $seq, must be a single ResourceAddress!")
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    val names = optDef("reg-names", named.map(x => ResourceString(regName(x._1).get)).toList)
 | 
				
			||||||
 | 
					    val regs = optDef("reg", (named ++ bulk).flatMap(_._2.map(_.value)).toList)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Description(name, ListMap() ++ compat ++ int ++ names ++ regs)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SimpleBus(devname: String, devcompat: Seq[String], offset: BigInt = 0) extends SimpleDevice(devname, devcompat ++ Seq("simple-bus"))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  override def describe(resources: ResourceBindings): Description = {
 | 
				
			||||||
 | 
					    val ranges = resources("ranges").map {
 | 
				
			||||||
 | 
					      case Binding(_, a: ResourceAddress) => ResourceMapping(a.address, offset, a.permissions)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    require (!ranges.isEmpty, s"SimpleBus $devname must set ranges")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    val map = AddressRange.fromSets(ranges.flatMap(_.address))
 | 
				
			||||||
 | 
					    val minBase = map.map(_.base).min
 | 
				
			||||||
 | 
					    val maxBase = map.map(_.end).max
 | 
				
			||||||
 | 
					    val maxSize = map.map(_.size).max
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def ofInt(x: Int) = Seq(ResourceInt(BigInt(x)))
 | 
				
			||||||
 | 
					    val extra = Map(
 | 
				
			||||||
 | 
					      "#address-cells"   -> ofInt((log2Ceil(maxBase) + 31) / 32),
 | 
				
			||||||
 | 
					      "#size-cells"      -> ofInt((log2Ceil(maxSize) + 31) / 32),
 | 
				
			||||||
 | 
					      "ranges"           -> ranges)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    val Description(_, mapping) = super.describe(resources)
 | 
				
			||||||
 | 
					    Description(s"${prefix}${devname}@${minBase.toString(16)}", mapping ++ extra)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def ranges = Seq(Resource(this, "ranges"))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MemoryDevice extends Device with DeviceRegName
 | 
					class MemoryDevice extends Device with DeviceRegName
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -83,7 +83,8 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  val q_depth = if (rational) (2 min maxUncachedInFlight-1) else 0
 | 
					  val q_depth = if (rational) (2 min maxUncachedInFlight-1) else 0
 | 
				
			||||||
  val tl_out_a = if (q_depth == 0) tl_out.a else Queue(tl_out.a, q_depth, flow = true, pipe = true)
 | 
					  val tl_out_a = Wire(tl_out.a)
 | 
				
			||||||
 | 
					  tl_out.a <> (if (q_depth == 0) tl_out_a else Queue(tl_out_a, q_depth, flow = true, pipe = true))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  val s1_valid = Reg(next=io.cpu.req.fire(), init=Bool(false))
 | 
					  val s1_valid = Reg(next=io.cpu.req.fire(), init=Bool(false))
 | 
				
			||||||
  val s1_probe = Reg(next=tl_out.b.fire(), init=Bool(false))
 | 
					  val s1_probe = Reg(next=tl_out.b.fire(), init=Bool(false))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -53,9 +53,9 @@ class FrontendIO(implicit p: Parameters) extends CoreBundle()(p) {
 | 
				
			|||||||
  val perf = new FrontendPerfEvents().asInput
 | 
					  val perf = new FrontendPerfEvents().asInput
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Frontend(val icacheParams: ICacheParams, hartid: Int)(implicit p: Parameters) extends LazyModule {
 | 
					class Frontend(val icacheParams: ICacheParams, hartid: Int, owner: => Option[Device] = None)(implicit p: Parameters) extends LazyModule {
 | 
				
			||||||
  lazy val module = new FrontendModule(this)
 | 
					  lazy val module = new FrontendModule(this)
 | 
				
			||||||
  val icache = LazyModule(new ICache(icacheParams, hartid))
 | 
					  val icache = LazyModule(new ICache(icacheParams, hartid, owner))
 | 
				
			||||||
  val masterNode = TLOutputNode()
 | 
					  val masterNode = TLOutputNode()
 | 
				
			||||||
  val slaveNode = TLInputNode()
 | 
					  val slaveNode = TLInputNode()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -184,7 +184,8 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer)
 | 
				
			|||||||
/** Mix-ins for constructing tiles that have an ICache-based pipeline frontend */
 | 
					/** Mix-ins for constructing tiles that have an ICache-based pipeline frontend */
 | 
				
			||||||
trait HasICacheFrontend extends CanHavePTW with HasTileLinkMasterPort {
 | 
					trait HasICacheFrontend extends CanHavePTW with HasTileLinkMasterPort {
 | 
				
			||||||
  val module: HasICacheFrontendModule
 | 
					  val module: HasICacheFrontendModule
 | 
				
			||||||
  val frontend = LazyModule(new Frontend(tileParams.icache.get, hartid: Int))
 | 
					  def itimOwner : Option[Device] = None
 | 
				
			||||||
 | 
					  val frontend = LazyModule(new Frontend(tileParams.icache.get, hartid: Int, itimOwner))
 | 
				
			||||||
  val hartid: Int
 | 
					  val hartid: Int
 | 
				
			||||||
  tileBus.node := frontend.masterNode
 | 
					  tileBus.node := frontend.masterNode
 | 
				
			||||||
  nPTWPorts += 1
 | 
					  nPTWPorts += 1
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,18 +35,25 @@ class ICacheReq(implicit p: Parameters) extends CoreBundle()(p) with HasL1ICache
 | 
				
			|||||||
  val addr = UInt(width = vaddrBits)
 | 
					  val addr = UInt(width = vaddrBits)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ICache(val icacheParams: ICacheParams, val hartid: Int)(implicit p: Parameters) extends LazyModule {
 | 
					class ICache(val icacheParams: ICacheParams, val hartid: Int, owner: => Option[Device] = None)(implicit p: Parameters) extends LazyModule {
 | 
				
			||||||
  lazy val module = new ICacheModule(this)
 | 
					  lazy val module = new ICacheModule(this)
 | 
				
			||||||
  val masterNode = TLClientNode(TLClientParameters(name = s"Core ${hartid} ICache"))
 | 
					  val masterNode = TLClientNode(TLClientParameters(name = s"Core ${hartid} ICache"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  val device = new SimpleDevice("itim", Seq("sifive,itim0")) {
 | 
				
			||||||
 | 
					      override def describe(resources: ResourceBindings): Description = {
 | 
				
			||||||
 | 
					      val extra = owner.map(x => ("sifive,cpu" -> Seq(ResourceReference(x.label))))
 | 
				
			||||||
 | 
					      val Description(name, mapping) = super.describe(resources)
 | 
				
			||||||
 | 
					      Description(name, mapping ++ extra)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  val size = icacheParams.nSets * icacheParams.nWays * icacheParams.blockBytes
 | 
					  val size = icacheParams.nSets * icacheParams.nWays * icacheParams.blockBytes
 | 
				
			||||||
  val device = new SimpleDevice("itim", Nil)
 | 
					 | 
				
			||||||
  val slaveNode = icacheParams.itimAddr.map { itimAddr =>
 | 
					  val slaveNode = icacheParams.itimAddr.map { itimAddr =>
 | 
				
			||||||
    val wordBytes = icacheParams.fetchBytes
 | 
					    val wordBytes = icacheParams.fetchBytes
 | 
				
			||||||
    TLManagerNode(Seq(TLManagerPortParameters(
 | 
					    TLManagerNode(Seq(TLManagerPortParameters(
 | 
				
			||||||
      Seq(TLManagerParameters(
 | 
					      Seq(TLManagerParameters(
 | 
				
			||||||
        address         = Seq(AddressSet(itimAddr, size-1)),
 | 
					        address         = Seq(AddressSet(itimAddr, size-1)),
 | 
				
			||||||
        resources       = device.reg,
 | 
					        resources       = device.reg("mem"),
 | 
				
			||||||
        regionType      = RegionType.UNCACHED,
 | 
					        regionType      = RegionType.UNCACHED,
 | 
				
			||||||
        executable      = true,
 | 
					        executable      = true,
 | 
				
			||||||
        supportsPutFull = TransferSizes(1, wordBytes),
 | 
					        supportsPutFull = TransferSizes(1, wordBytes),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,7 +42,7 @@ class RocketTile(val rocketParams: RocketTileParams, val hartid: Int)(implicit p
 | 
				
			|||||||
      val c = if (rocketParams.core.useCompressed) "c" else ""
 | 
					      val c = if (rocketParams.core.useCompressed) "c" else ""
 | 
				
			||||||
      val isa = s"rv${p(XLen)}i$m$a$f$d$c"
 | 
					      val isa = s"rv${p(XLen)}i$m$a$f$d$c"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      val dcache = rocketParams.dcache.map(d => Map(
 | 
					      val dcache = rocketParams.dcache.filter(!_.scratch.isDefined).map(d => Map(
 | 
				
			||||||
        "d-cache-block-size"   -> ofInt(block),
 | 
					        "d-cache-block-size"   -> ofInt(block),
 | 
				
			||||||
        "d-cache-sets"         -> ofInt(d.nSets),
 | 
					        "d-cache-sets"         -> ofInt(d.nSets),
 | 
				
			||||||
        "d-cache-size"         -> ofInt(d.nSets * d.nWays * block))).getOrElse(Map())
 | 
					        "d-cache-size"         -> ofInt(d.nSets * d.nWays * block))).getOrElse(Map())
 | 
				
			||||||
@@ -89,6 +89,10 @@ class RocketTile(val rocketParams: RocketTileParams, val hartid: Int)(implicit p
 | 
				
			|||||||
        ++ dcache ++ icache ++ nextlevel ++ mmu ++ itlb ++ dtlb)
 | 
					        ++ dcache ++ icache ++ nextlevel ++ mmu ++ itlb ++ dtlb)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  override def dtimOwner = Some(cpuDevice)
 | 
				
			||||||
 | 
					  override def itimOwner = Some(cpuDevice)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  val intcDevice = new Device {
 | 
					  val intcDevice = new Device {
 | 
				
			||||||
    def describe(resources: ResourceBindings): Description = {
 | 
					    def describe(resources: ResourceBindings): Description = {
 | 
				
			||||||
      Description(s"cpus/cpu@${hartid}/interrupt-controller", Map(
 | 
					      Description(s"cpus/cpu@${hartid}/interrupt-controller", Map(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,13 +13,20 @@ import uncore.tilelink2._
 | 
				
			|||||||
import uncore.util._
 | 
					import uncore.util._
 | 
				
			||||||
import util._
 | 
					import util._
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ScratchpadSlavePort(address: AddressSet)(implicit p: Parameters) extends LazyModule
 | 
					class ScratchpadSlavePort(address: AddressSet, owner: => Option[Device] = None)(implicit p: Parameters) extends LazyModule
 | 
				
			||||||
    with HasCoreParameters {
 | 
					    with HasCoreParameters {
 | 
				
			||||||
  val device = new SimpleDevice("dtim", Nil)
 | 
					  val device = new SimpleDevice("dtim", Seq("sifive,dtim0")) {
 | 
				
			||||||
 | 
					    override def describe(resources: ResourceBindings): Description = {
 | 
				
			||||||
 | 
					      val extra = owner.map(x => ("sifive,cpu" -> Seq(ResourceReference(x.label))))
 | 
				
			||||||
 | 
					      val Description(name, mapping) = super.describe(resources)
 | 
				
			||||||
 | 
					      Description(name, mapping ++ extra)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  val node = TLManagerNode(Seq(TLManagerPortParameters(
 | 
					  val node = TLManagerNode(Seq(TLManagerPortParameters(
 | 
				
			||||||
    Seq(TLManagerParameters(
 | 
					    Seq(TLManagerParameters(
 | 
				
			||||||
      address            = List(address),
 | 
					      address            = List(address),
 | 
				
			||||||
      resources          = device.reg,
 | 
					      resources          = device.reg("mem"),
 | 
				
			||||||
      regionType         = RegionType.UNCACHED,
 | 
					      regionType         = RegionType.UNCACHED,
 | 
				
			||||||
      executable         = true,
 | 
					      executable         = true,
 | 
				
			||||||
      supportsArithmetic = if (usingAtomics) TransferSizes(4, coreDataBytes) else TransferSizes.none,
 | 
					      supportsArithmetic = if (usingAtomics) TransferSizes(4, coreDataBytes) else TransferSizes.none,
 | 
				
			||||||
@@ -102,6 +109,7 @@ trait CanHaveScratchpad extends HasHellaCache with HasICacheFrontend with HasCor
 | 
				
			|||||||
  val module: CanHaveScratchpadModule
 | 
					  val module: CanHaveScratchpadModule
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  val slaveNode = TLInputNode() // Up to two uses for this input node:
 | 
					  val slaveNode = TLInputNode() // Up to two uses for this input node:
 | 
				
			||||||
 | 
					  def dtimOwner: Option[Device] = None // who owns the Scratchpad?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // 1) Frontend always exists, but may or may not have a scratchpad node
 | 
					  // 1) Frontend always exists, but may or may not have a scratchpad node
 | 
				
			||||||
  val fg = LazyModule(new TLFragmenter(fetchWidth*coreInstBytes, p(CacheBlockBytes), earlyAck=true))
 | 
					  val fg = LazyModule(new TLFragmenter(fetchWidth*coreInstBytes, p(CacheBlockBytes), earlyAck=true))
 | 
				
			||||||
@@ -112,7 +120,7 @@ trait CanHaveScratchpad extends HasHellaCache with HasICacheFrontend with HasCor
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  // 2) ScratchpadSlavePort always has a node, but only exists when the HellaCache has a scratchpad
 | 
					  // 2) ScratchpadSlavePort always has a node, but only exists when the HellaCache has a scratchpad
 | 
				
			||||||
  val scratch = tileParams.dcache.flatMap(d => d.scratch.map(s =>
 | 
					  val scratch = tileParams.dcache.flatMap(d => d.scratch.map(s =>
 | 
				
			||||||
    LazyModule(new ScratchpadSlavePort(AddressSet(s, d.dataScratchpadBytes-1)))))
 | 
					    LazyModule(new ScratchpadSlavePort(AddressSet(s, d.dataScratchpadBytes-1), dtimOwner))))
 | 
				
			||||||
  scratch foreach { lm => lm.node := TLFragmenter(xLen/8, p(CacheBlockBytes), earlyAck=true)(slaveNode) }
 | 
					  scratch foreach { lm => lm.node := TLFragmenter(xLen/8, p(CacheBlockBytes), earlyAck=true)(slaveNode) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def findScratchpadFromICache: Option[AddressSet] = scratch.map { s =>
 | 
					  def findScratchpadFromICache: Option[AddressSet] = scratch.map { s =>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -177,11 +177,11 @@ trait HasPeripheryMasterAXI4MemPortModuleImp extends LazyMultiIOModuleImp with H
 | 
				
			|||||||
/** Adds a AXI4 port to the system intended to master an MMIO device bus */
 | 
					/** Adds a AXI4 port to the system intended to master an MMIO device bus */
 | 
				
			||||||
trait HasPeripheryMasterAXI4MMIOPort extends HasSystemNetworks {
 | 
					trait HasPeripheryMasterAXI4MMIOPort extends HasSystemNetworks {
 | 
				
			||||||
  private val config = p(ExtBus)
 | 
					  private val config = p(ExtBus)
 | 
				
			||||||
  private val device = new SimpleDevice("mmio", Nil)
 | 
					  private val device = new SimpleBus("mmio", Nil)
 | 
				
			||||||
  val mmio_axi4 = AXI4BlindOutputNode(Seq(AXI4SlavePortParameters(
 | 
					  val mmio_axi4 = AXI4BlindOutputNode(Seq(AXI4SlavePortParameters(
 | 
				
			||||||
    slaves = Seq(AXI4SlaveParameters(
 | 
					    slaves = Seq(AXI4SlaveParameters(
 | 
				
			||||||
      address       = List(AddressSet(BigInt(config.base), config.size-1)),
 | 
					      address       = List(AddressSet(BigInt(config.base), config.size-1)),
 | 
				
			||||||
      resources     = device.reg,
 | 
					      resources     = device.ranges,
 | 
				
			||||||
      executable    = true,                  // Can we run programs on this memory?
 | 
					      executable    = true,                  // Can we run programs on this memory?
 | 
				
			||||||
      supportsWrite = TransferSizes(1, 256), // The slave supports 1-256 byte transfers
 | 
					      supportsWrite = TransferSizes(1, 256), // The slave supports 1-256 byte transfers
 | 
				
			||||||
      supportsRead  = TransferSizes(1, 256))),
 | 
					      supportsRead  = TransferSizes(1, 256))),
 | 
				
			||||||
@@ -252,11 +252,11 @@ trait HasPeripherySlaveAXI4PortModuleImp extends LazyMultiIOModuleImp with HasPe
 | 
				
			|||||||
/** Adds a TileLink port to the system intended to master an MMIO device bus */
 | 
					/** Adds a TileLink port to the system intended to master an MMIO device bus */
 | 
				
			||||||
trait HasPeripheryMasterTLMMIOPort extends HasSystemNetworks {
 | 
					trait HasPeripheryMasterTLMMIOPort extends HasSystemNetworks {
 | 
				
			||||||
  private val config = p(ExtBus)
 | 
					  private val config = p(ExtBus)
 | 
				
			||||||
  private val device = new SimpleDevice("mmio", Nil)
 | 
					  private val device = new SimpleBus("mmio", Nil)
 | 
				
			||||||
  val mmio_tl = TLBlindOutputNode(Seq(TLManagerPortParameters(
 | 
					  val mmio_tl = TLBlindOutputNode(Seq(TLManagerPortParameters(
 | 
				
			||||||
    managers = Seq(TLManagerParameters(
 | 
					    managers = Seq(TLManagerParameters(
 | 
				
			||||||
      address            = List(AddressSet(BigInt(config.base), config.size-1)),
 | 
					      address            = List(AddressSet(BigInt(config.base), config.size-1)),
 | 
				
			||||||
      resources          = device.reg,
 | 
					      resources          = device.ranges,
 | 
				
			||||||
      executable         = true,
 | 
					      executable         = true,
 | 
				
			||||||
      supportsGet        = TransferSizes(1, cacheBlockBytes),
 | 
					      supportsGet        = TransferSizes(1, cacheBlockBytes),
 | 
				
			||||||
      supportsPutFull    = TransferSizes(1, cacheBlockBytes),
 | 
					      supportsPutFull    = TransferSizes(1, cacheBlockBytes),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -70,8 +70,7 @@ class TLPLIC(params: PLICParams)(implicit p: Parameters) extends LazyModule
 | 
				
			|||||||
      val extra = Map(
 | 
					      val extra = Map(
 | 
				
			||||||
        "interrupt-controller" -> Nil,
 | 
					        "interrupt-controller" -> Nil,
 | 
				
			||||||
        "riscv,ndev" -> Seq(ResourceInt(nDevices)),
 | 
					        "riscv,ndev" -> Seq(ResourceInt(nDevices)),
 | 
				
			||||||
        "#interrupt-cells" -> Seq(ResourceInt(1)),
 | 
					        "#interrupt-cells" -> Seq(ResourceInt(1)))
 | 
				
			||||||
        "#address-cells" -> Seq(ResourceInt(0)))
 | 
					 | 
				
			||||||
      Description(name, mapping ++ extra)
 | 
					      Description(name, mapping ++ extra)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,7 @@ import uncore.util._
 | 
				
			|||||||
import config._
 | 
					import config._
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TLROM(val base: BigInt, val size: Int, contentsDelayed: => Seq[Byte], executable: Boolean = true, beatBytes: Int = 4,
 | 
					class TLROM(val base: BigInt, val size: Int, contentsDelayed: => Seq[Byte], executable: Boolean = true, beatBytes: Int = 4,
 | 
				
			||||||
  resources: Seq[Resource] = new SimpleDevice("rom", Nil).reg)(implicit p: Parameters) extends LazyModule
 | 
					  resources: Seq[Resource] = new SimpleDevice("rom", Seq("sifive,rom0")).reg("mem"))(implicit p: Parameters) extends LazyModule
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  val node = TLManagerNode(beatBytes, TLManagerParameters (
 | 
					  val node = TLManagerNode(beatBytes, TLManagerParameters (
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -283,7 +283,6 @@ class TLDebugModuleOuter(device: Device)(implicit p: Parameters) extends LazyMod
 | 
				
			|||||||
  val dmiNode = TLRegisterNode (
 | 
					  val dmiNode = TLRegisterNode (
 | 
				
			||||||
    address = AddressSet.misaligned(DMI_DMCONTROL << 2, 4),
 | 
					    address = AddressSet.misaligned(DMI_DMCONTROL << 2, 4),
 | 
				
			||||||
    device = device,
 | 
					    device = device,
 | 
				
			||||||
    deviceKey = "reg",
 | 
					 | 
				
			||||||
    beatBytes = 4,
 | 
					    beatBytes = 4,
 | 
				
			||||||
    executable = false
 | 
					    executable = false
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
@@ -430,7 +429,6 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
 | 
				
			|||||||
    address = AddressSet.misaligned(0, DMI_RegAddrs.DMI_DMCONTROL << 2) ++
 | 
					    address = AddressSet.misaligned(0, DMI_RegAddrs.DMI_DMCONTROL << 2) ++
 | 
				
			||||||
              AddressSet.misaligned((DMI_RegAddrs.DMI_DMCONTROL + 1) << 2, (0x200 - ((DMI_RegAddrs.DMI_DMCONTROL + 1) << 2))),
 | 
					              AddressSet.misaligned((DMI_RegAddrs.DMI_DMCONTROL + 1) << 2, (0x200 - ((DMI_RegAddrs.DMI_DMCONTROL + 1) << 2))),
 | 
				
			||||||
    device = device,
 | 
					    device = device,
 | 
				
			||||||
    deviceKey = "reg",
 | 
					 | 
				
			||||||
    beatBytes = 4,
 | 
					    beatBytes = 4,
 | 
				
			||||||
    executable = false
 | 
					    executable = false
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
@@ -438,7 +436,6 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
 | 
				
			|||||||
  val tlNode = TLRegisterNode(
 | 
					  val tlNode = TLRegisterNode(
 | 
				
			||||||
    address=Seq(AddressSet(0, 0xFFF)), // This is required for correct functionality, it's not configurable.
 | 
					    address=Seq(AddressSet(0, 0xFFF)), // This is required for correct functionality, it's not configurable.
 | 
				
			||||||
    device=device,
 | 
					    device=device,
 | 
				
			||||||
    deviceKey="reg",
 | 
					 | 
				
			||||||
    beatBytes=p(XLen)/8,
 | 
					    beatBytes=p(XLen)/8,
 | 
				
			||||||
    executable=true
 | 
					    executable=true
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ class TLError(address: Seq[AddressSet], beatBytes: Int = 4)(implicit p: Paramete
 | 
				
			|||||||
  val node = TLManagerNode(Seq(TLManagerPortParameters(
 | 
					  val node = TLManagerNode(Seq(TLManagerPortParameters(
 | 
				
			||||||
    Seq(TLManagerParameters(
 | 
					    Seq(TLManagerParameters(
 | 
				
			||||||
      address            = address,
 | 
					      address            = address,
 | 
				
			||||||
      resources          = device.reg,
 | 
					      resources          = device.reg("mem"),
 | 
				
			||||||
      supportsGet        = TransferSizes(1, beatBytes),
 | 
					      supportsGet        = TransferSizes(1, beatBytes),
 | 
				
			||||||
      supportsPutPartial = TransferSizes(1, beatBytes),
 | 
					      supportsPutPartial = TransferSizes(1, beatBytes),
 | 
				
			||||||
      supportsPutFull    = TransferSizes(1, beatBytes),
 | 
					      supportsPutFull    = TransferSizes(1, beatBytes),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -57,11 +57,11 @@ case class TLManagerParameters(
 | 
				
			|||||||
  require (minAlignment >= maxTransfer, s"minAlignment ($minAlignment) must be >= maxTransfer ($maxTransfer)")
 | 
					  require (minAlignment >= maxTransfer, s"minAlignment ($minAlignment) must be >= maxTransfer ($maxTransfer)")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def toResource: ResourceAddress = {
 | 
					  def toResource: ResourceAddress = {
 | 
				
			||||||
    ResourceAddress(address,
 | 
					    ResourceAddress(address, ResourcePermissions(
 | 
				
			||||||
      r = supportsAcquireB || supportsGet,
 | 
					      r = supportsAcquireB || supportsGet,
 | 
				
			||||||
      w = supportsAcquireT || supportsPutFull,
 | 
					      w = supportsAcquireT || supportsPutFull,
 | 
				
			||||||
      x = executable,
 | 
					      x = executable,
 | 
				
			||||||
      c = supportsAcquireB)
 | 
					      c = supportsAcquireB))
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,7 @@ import scala.math.{min,max}
 | 
				
			|||||||
class TLRegisterNode(
 | 
					class TLRegisterNode(
 | 
				
			||||||
    address:     Seq[AddressSet],
 | 
					    address:     Seq[AddressSet],
 | 
				
			||||||
    device:      Device,
 | 
					    device:      Device,
 | 
				
			||||||
    deviceKey:   String  = "reg",
 | 
					    deviceKey:   String  = "reg/control",
 | 
				
			||||||
    concurrency: Int     = 0,
 | 
					    concurrency: Int     = 0,
 | 
				
			||||||
    beatBytes:   Int     = 4,
 | 
					    beatBytes:   Int     = 4,
 | 
				
			||||||
    undefZero:   Boolean = true,
 | 
					    undefZero:   Boolean = true,
 | 
				
			||||||
@@ -88,7 +88,7 @@ object TLRegisterNode
 | 
				
			|||||||
  def apply(
 | 
					  def apply(
 | 
				
			||||||
      address:     Seq[AddressSet],
 | 
					      address:     Seq[AddressSet],
 | 
				
			||||||
      device:      Device,
 | 
					      device:      Device,
 | 
				
			||||||
      deviceKey:   String  = "reg",
 | 
					      deviceKey:   String  = "reg/control",
 | 
				
			||||||
      concurrency: Int     = 0,
 | 
					      concurrency: Int     = 0,
 | 
				
			||||||
      beatBytes:   Int     = 4,
 | 
					      beatBytes:   Int     = 4,
 | 
				
			||||||
      undefZero:   Boolean = true,
 | 
					      undefZero:   Boolean = true,
 | 
				
			||||||
@@ -103,7 +103,7 @@ object TLRegisterNode
 | 
				
			|||||||
abstract class TLRegisterRouterBase(devname: String, devcompat: Seq[String], val address: AddressSet, interrupts: Int, concurrency: Int, beatBytes: Int, undefZero: Boolean, executable: Boolean)(implicit p: Parameters) extends LazyModule
 | 
					abstract class TLRegisterRouterBase(devname: String, devcompat: Seq[String], val address: AddressSet, interrupts: Int, concurrency: Int, beatBytes: Int, undefZero: Boolean, executable: Boolean)(implicit p: Parameters) extends LazyModule
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  val device = new SimpleDevice(devname, devcompat)
 | 
					  val device = new SimpleDevice(devname, devcompat)
 | 
				
			||||||
  val node = TLRegisterNode(Seq(address), device, "reg", concurrency, beatBytes, undefZero, executable)
 | 
					  val node = TLRegisterNode(Seq(address), device, "reg/control", concurrency, beatBytes, undefZero, executable)
 | 
				
			||||||
  val intnode = IntSourceNode(IntSourcePortSimple(num = interrupts, resources = Seq(Resource(device, "int"))))
 | 
					  val intnode = IntSourceNode(IntSourcePortSimple(num = interrupts, resources = Seq(Resource(device, "int"))))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,11 +10,11 @@ import util._
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4, name: Option[String] = None)(implicit p: Parameters) extends LazyModule
 | 
					class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4, name: Option[String] = None)(implicit p: Parameters) extends LazyModule
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  val device = name.map(new SimpleDevice(_, Nil)).getOrElse(new MemoryDevice)
 | 
					  val device = name.map(new SimpleDevice(_, Seq("sifive,sram0"))).getOrElse(new MemoryDevice)
 | 
				
			||||||
  val node = TLManagerNode(Seq(TLManagerPortParameters(
 | 
					  val node = TLManagerNode(Seq(TLManagerPortParameters(
 | 
				
			||||||
    Seq(TLManagerParameters(
 | 
					    Seq(TLManagerParameters(
 | 
				
			||||||
      address            = List(address),
 | 
					      address            = List(address),
 | 
				
			||||||
      resources          = device.reg,
 | 
					      resources          = device.reg("mem"),
 | 
				
			||||||
      regionType         = RegionType.UNCACHED,
 | 
					      regionType         = RegionType.UNCACHED,
 | 
				
			||||||
      executable         = executable,
 | 
					      executable         = executable,
 | 
				
			||||||
      supportsGet        = TransferSizes(1, beatBytes),
 | 
					      supportsGet        = TransferSizes(1, beatBytes),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@ class TLTestRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int
 | 
				
			|||||||
  val node = TLManagerNode(Seq(TLManagerPortParameters(
 | 
					  val node = TLManagerNode(Seq(TLManagerPortParameters(
 | 
				
			||||||
    Seq(TLManagerParameters(
 | 
					    Seq(TLManagerParameters(
 | 
				
			||||||
      address            = List(address),
 | 
					      address            = List(address),
 | 
				
			||||||
      resources          = device.reg,
 | 
					      resources          = device.reg("mem"),
 | 
				
			||||||
      regionType         = RegionType.UNCACHED,
 | 
					      regionType         = RegionType.UNCACHED,
 | 
				
			||||||
      executable         = executable,
 | 
					      executable         = executable,
 | 
				
			||||||
      supportsGet        = TransferSizes(1, beatBytes),
 | 
					      supportsGet        = TransferSizes(1, beatBytes),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,12 +8,12 @@ import diplomacy._
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class TLZero(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule
 | 
					class TLZero(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  val device = new SimpleDevice("rom", Seq("ucbbar,cacheable-zero"))
 | 
					  val device = new SimpleDevice("rom", Seq("ucbbar,cacheable-zero0"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  val node = TLManagerNode(Seq(TLManagerPortParameters(
 | 
					  val node = TLManagerNode(Seq(TLManagerPortParameters(
 | 
				
			||||||
    Seq(TLManagerParameters(
 | 
					    Seq(TLManagerParameters(
 | 
				
			||||||
      address            = List(address),
 | 
					      address            = List(address),
 | 
				
			||||||
      resources          = device.reg,
 | 
					      resources          = device.reg("mem"),
 | 
				
			||||||
      regionType         = RegionType.UNCACHED,
 | 
					      regionType         = RegionType.UNCACHED,
 | 
				
			||||||
      executable         = executable,
 | 
					      executable         = executable,
 | 
				
			||||||
      supportsGet        = TransferSizes(1, beatBytes),
 | 
					      supportsGet        = TransferSizes(1, beatBytes),
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user