From 9cd2991fb3e0c5f55cd194605b125ccbaf67598b Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Wed, 31 Aug 2016 14:49:18 -0700 Subject: [PATCH] tilelink2: AddressSet always has an assigned base address The consensus seems to be that TileLink should not be assigning addresses dynamically. The reasons: 1. We can come up with another scheme for assigning addresses that is independent of TileLink. This decoupling is good, because it would allow us to use the same mechanism for different buses in the SoC. 2. The informational flow of addresses is more likely to naturally follow the module hierarchy than the TileLike bus topology. Thus, it seems better to pass address parameterization using Module constructors. 3. Addresses are still checked by TileLink, so using a Module-centric flow for addresses will not pose a correctness concern. 4. An address need only be provided to a slave on its construction and TileLink parameterization spreads this globally. Thus, the burden to manually assign an address is low. --- uncore/src/main/scala/tilelink2/GPIO.scala | 2 +- .../src/main/scala/tilelink2/Parameters.scala | 26 +++++++++---------- .../main/scala/tilelink2/RegisterRouter.scala | 4 +-- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/uncore/src/main/scala/tilelink2/GPIO.scala b/uncore/src/main/scala/tilelink2/GPIO.scala index e4b8572f..a9050882 100644 --- a/uncore/src/main/scala/tilelink2/GPIO.scala +++ b/uncore/src/main/scala/tilelink2/GPIO.scala @@ -4,7 +4,7 @@ package uncore.tilelink2 import Chisel._ -case class GPIOParams(num: Int, address: Option[BigInt] = None) +case class GPIOParams(num: Int, address: BigInt) trait GPIOBundle { diff --git a/uncore/src/main/scala/tilelink2/Parameters.scala b/uncore/src/main/scala/tilelink2/Parameters.scala index 6a8170c9..7482a32c 100644 --- a/uncore/src/main/scala/tilelink2/Parameters.scala +++ b/uncore/src/main/scala/tilelink2/Parameters.scala @@ -75,30 +75,28 @@ object TransferSizes { implicit def asBool(x: TransferSizes) = !x.none } -// AddressSets specify the mask of bits consumed by the manager -// The base address used by the crossbar for routing -case class AddressSet(mask: BigInt, base: Option[BigInt] = None) +// AddressSets specify the address space managed by the manager +// Base is the base address, and mask are the bits consumed by the manager +// e.g: base=0x200, mask=0xff describes a device managing 0x200-0x2ff +// e.g: base=0x1000, mask=0xf0f decribes a device managing 0x1000-0x100f, 0x1100-0x110f, ... +case class AddressSet(base: BigInt, mask: BigInt) { // Forbid misaligned base address (and empty sets) - require (base == None || (base.get & mask) == 0) + require ((base & mask) == 0) - def contains(x: BigInt) = ((x ^ base.get) & ~mask) == 0 - def contains(x: UInt) = ((x ^ UInt(base.get)) & ~UInt(mask)) === UInt(0) + def contains(x: BigInt) = ((x ^ base) & ~mask) == 0 + def contains(x: UInt) = ((x ^ UInt(base)) & ~UInt(mask)) === UInt(0) // overlap iff bitwise: both care (~mask0 & ~mask1) => both equal (base0=base1) - // if base = None, it will be auto-assigned and thus not overlap anything - def overlaps(x: AddressSet) = (base, x.base) match { - case (Some(tbase), Some(xbase)) => (~(mask | x.mask) & (tbase ^ xbase)) == 0 - case _ => false - } + def overlaps(x: AddressSet) = (~(mask | x.mask) & (base ^ x.base)) == 0 // contains iff bitwise: x.mask => mask && contains(x.base) - def contains(x: AddressSet) = ((x.mask | (base.get ^ x.base.get)) & ~mask) == 0 + def contains(x: AddressSet) = ((x.mask | (base ^ x.base)) & ~mask) == 0 // 1 less than the number of bytes to which the manager should be aligned def alignment1 = ((mask + 1) & ~mask) - 1 - def max = base.get | mask + def max = base | mask - // A strided slave has serves discontiguous ranges + // A strided slave serves discontiguous ranges def strided = alignment1 != mask } diff --git a/uncore/src/main/scala/tilelink2/RegisterRouter.scala b/uncore/src/main/scala/tilelink2/RegisterRouter.scala index 70923787..a9d33695 100644 --- a/uncore/src/main/scala/tilelink2/RegisterRouter.scala +++ b/uncore/src/main/scala/tilelink2/RegisterRouter.scala @@ -74,10 +74,10 @@ class TLRegModule[P, B <: Bundle](val params: P, bundleBuilder: => B, router: TL } class TLRegisterRouter[B <: Bundle, M <: LazyModuleImp] - (address: Option[BigInt] = None, size: BigInt = 4096, concurrency: Option[Int] = None, beatBytes: Int = 4) + (base: BigInt, size: BigInt = 4096, concurrency: Option[Int] = None, beatBytes: Int = 4) (bundleBuilder: Vec[TLBundle] => B) (moduleBuilder: (=> B, TLRegisterRouterBase) => M) - extends TLRegisterRouterBase(AddressSet(size-1, address), concurrency, beatBytes) + extends TLRegisterRouterBase(AddressSet(base, size-1), concurrency, beatBytes) { require (size % 4096 == 0) // devices should be 4K aligned require (isPow2(size))