// See LICENSE.SiFive for license details. package uncore.apb import Chisel._ import config._ import diplomacy._ import scala.math.max case class APBSlaveParameters( address: Seq[AddressSet], resources: Seq[Resource] = Nil, regionType: RegionType.T = RegionType.GET_EFFECTS, executable: Boolean = false, // processor can execute from this memory nodePath: Seq[BaseNode] = Seq(), supportsWrite: Boolean = true, supportsRead: Boolean = true) { address.foreach { a => require (a.finite) } address.combinations(2).foreach { case Seq(x,y) => require (!x.overlaps(y)) } val name = nodePath.lastOption.map(_.lazyModule.name).getOrElse("disconnected") val maxAddress = address.map(_.max).max val minAlignment = address.map(_.alignment).min } case class APBSlavePortParameters( slaves: Seq[APBSlaveParameters], beatBytes: Int) { require (!slaves.isEmpty) require (isPow2(beatBytes)) val maxAddress = slaves.map(_.maxAddress).max lazy val routingMask = AddressDecoder(slaves.map(_.address)) def findSafe(address: UInt) = Vec(slaves.map(_.address.map(_.contains(address)).reduce(_ || _))) def findFast(address: UInt) = Vec(slaves.map(_.address.map(_.widen(~routingMask)).distinct.map(_.contains(address)).reduce(_ || _))) // Require disjoint ranges for addresses slaves.combinations(2).foreach { case Seq(x,y) => x.address.foreach { a => y.address.foreach { b => require (!a.overlaps(b)) } } } } case class APBMasterParameters( nodePath: Seq[BaseNode] = Seq()) { val name = nodePath.lastOption.map(_.lazyModule.name).getOrElse("disconnected") } case class APBMasterPortParameters( masters: Seq[APBMasterParameters]) case class APBBundleParameters( addrBits: Int, dataBits: Int) { require (dataBits >= 8) require (addrBits >= 1) require (isPow2(dataBits)) // Bring the globals into scope val protBits = APBParameters.protBits def union(x: APBBundleParameters) = APBBundleParameters( max(addrBits, x.addrBits), max(dataBits, x.dataBits)) } object APBBundleParameters { val emptyBundleParams = APBBundleParameters(addrBits = 1, dataBits = 8) def union(x: Seq[APBBundleParameters]) = x.foldLeft(emptyBundleParams)((x,y) => x.union(y)) def apply(master: APBMasterPortParameters, slave: APBSlavePortParameters) = new APBBundleParameters( addrBits = log2Up(slave.maxAddress+1), dataBits = slave.beatBytes * 8) } case class APBEdgeParameters( master: APBMasterPortParameters, slave: APBSlavePortParameters) { val bundle = APBBundleParameters(master, slave) }