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.
This commit is contained in:
parent
ae2bc4da21
commit
9cd2991fb3
@ -4,7 +4,7 @@ package uncore.tilelink2
|
|||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
|
|
||||||
case class GPIOParams(num: Int, address: Option[BigInt] = None)
|
case class GPIOParams(num: Int, address: BigInt)
|
||||||
|
|
||||||
trait GPIOBundle
|
trait GPIOBundle
|
||||||
{
|
{
|
||||||
|
@ -75,30 +75,28 @@ object TransferSizes {
|
|||||||
implicit def asBool(x: TransferSizes) = !x.none
|
implicit def asBool(x: TransferSizes) = !x.none
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddressSets specify the mask of bits consumed by the manager
|
// AddressSets specify the address space managed by the manager
|
||||||
// The base address used by the crossbar for routing
|
// Base is the base address, and mask are the bits consumed by the manager
|
||||||
case class AddressSet(mask: BigInt, base: Option[BigInt] = None)
|
// 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)
|
// 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: BigInt) = ((x ^ base) & ~mask) == 0
|
||||||
def contains(x: UInt) = ((x ^ UInt(base.get)) & ~UInt(mask)) === UInt(0)
|
def contains(x: UInt) = ((x ^ UInt(base)) & ~UInt(mask)) === UInt(0)
|
||||||
|
|
||||||
// overlap iff bitwise: both care (~mask0 & ~mask1) => both equal (base0=base1)
|
// 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) = (~(mask | x.mask) & (base ^ x.base)) == 0
|
||||||
def overlaps(x: AddressSet) = (base, x.base) match {
|
|
||||||
case (Some(tbase), Some(xbase)) => (~(mask | x.mask) & (tbase ^ xbase)) == 0
|
|
||||||
case _ => false
|
|
||||||
}
|
|
||||||
|
|
||||||
// contains iff bitwise: x.mask => mask && contains(x.base)
|
// 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
|
// 1 less than the number of bytes to which the manager should be aligned
|
||||||
def alignment1 = ((mask + 1) & ~mask) - 1
|
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
|
def strided = alignment1 != mask
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,10 +74,10 @@ class TLRegModule[P, B <: Bundle](val params: P, bundleBuilder: => B, router: TL
|
|||||||
}
|
}
|
||||||
|
|
||||||
class TLRegisterRouter[B <: Bundle, M <: LazyModuleImp]
|
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)
|
(bundleBuilder: Vec[TLBundle] => B)
|
||||||
(moduleBuilder: (=> B, TLRegisterRouterBase) => M)
|
(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 (size % 4096 == 0) // devices should be 4K aligned
|
||||||
require (isPow2(size))
|
require (isPow2(size))
|
||||||
|
Loading…
Reference in New Issue
Block a user