1
0

tilelink2 RegisterRouter: support new TL2 interrupts

This commit is contained in:
Wesley W. Terpstra 2016-09-08 15:17:30 -07:00
parent 23e896ed5d
commit 66f58cf2d0
3 changed files with 30 additions and 11 deletions

View File

@ -16,14 +16,22 @@ trait GPIOModule extends HasRegMap
{ {
val params: GPIOParams val params: GPIOParams
val io: GPIOBundle val io: GPIOBundle
val interrupts: Vec[Bool]
val state = RegInit(UInt(0)) val state = RegInit(UInt(0))
io.gpio := state val pending = RegInit(UInt(0xf, width = 4))
regmap(0 -> Seq(RegField(params.num, state))) io.gpio := state
interrupts := pending.toBools
regmap(
0 -> Seq(
RegField(params.num, state)),
1 -> Seq(
RegField.w1ToClear(4, pending, state)))
} }
// Create a concrete TL2 version of the abstract GPIO slave // Create a concrete TL2 version of the abstract GPIO slave
class TLGPIO(p: GPIOParams) extends TLRegisterRouter(p.address)( class TLGPIO(p: GPIOParams) extends TLRegisterRouter(p.address, 4)(
new TLRegBundle(p, _) with GPIOBundle)( new TLRegBundle(p, _) with GPIOBundle)(
new TLRegModule(p, _, _) with GPIOModule) new TLRegModule(p, _, _) with GPIOModule)

View File

@ -86,6 +86,7 @@ object RegField
trait HasRegMap trait HasRegMap
{ {
def regmap(mapping: RegField.Map*): Unit def regmap(mapping: RegField.Map*): Unit
val interrupts: Vec[Bool]
} }
// See GPIO.scala for an example of how to use regmap // See GPIO.scala for an example of how to use regmap

View File

@ -75,29 +75,39 @@ object TLRegisterNode
// register mapped device from a totally abstract register mapped device. // register mapped device from a totally abstract register mapped device.
// See GPIO.scala in this directory for an example // See GPIO.scala in this directory for an example
abstract class TLRegisterRouterBase(address: AddressSet, concurrency: Option[Int], beatBytes: Int) extends LazyModule abstract class TLRegisterRouterBase(address: AddressSet, interrupts: Int, concurrency: Option[Int], beatBytes: Int) extends LazyModule
{ {
val node = TLRegisterNode(address, concurrency, beatBytes) val node = TLRegisterNode(address, concurrency, beatBytes)
val intnode = IntSourceNode(name + s" @ ${address.base}", interrupts)
} }
class TLRegBundle[P](val params: P, val in: Vec[TLBundle]) extends Bundle case class TLRegBundleArg(interrupts: Vec[Vec[Bool]], in: Vec[TLBundle])
class TLRegModule[P, B <: Bundle](val params: P, bundleBuilder: => B, router: TLRegisterRouterBase) class TLRegBundleBase(arg: TLRegBundleArg) extends Bundle
{
val interrupts = arg.interrupts
val in = arg.in
}
class TLRegBundle[P](val params: P, arg: TLRegBundleArg) extends TLRegBundleBase(arg)
class TLRegModule[P, B <: TLRegBundleBase](val params: P, bundleBuilder: => B, router: TLRegisterRouterBase)
extends LazyModuleImp(router) with HasRegMap extends LazyModuleImp(router) with HasRegMap
{ {
val io = bundleBuilder val io = bundleBuilder
val interrupts = if (io.interrupts.isEmpty) Vec(0, Bool()) else io.interrupts(0)
def regmap(mapping: RegField.Map*) = router.node.regmap(mapping:_*) def regmap(mapping: RegField.Map*) = router.node.regmap(mapping:_*)
} }
class TLRegisterRouter[B <: Bundle, M <: LazyModuleImp] class TLRegisterRouter[B <: TLRegBundleBase, M <: LazyModuleImp]
(base: BigInt, size: BigInt = 4096, concurrency: Option[Int] = None, beatBytes: Int = 4) (base: BigInt, interrupts: Int = 0, size: BigInt = 4096, concurrency: Option[Int] = None, beatBytes: Int = 4)
(bundleBuilder: Vec[TLBundle] => B) (bundleBuilder: TLRegBundleArg => B)
(moduleBuilder: (=> B, TLRegisterRouterBase) => M) (moduleBuilder: (=> B, TLRegisterRouterBase) => M)
extends TLRegisterRouterBase(AddressSet(base, size-1), concurrency, beatBytes) extends TLRegisterRouterBase(AddressSet(base, size-1), interrupts, 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))
require (size >= 4096) require (size >= 4096)
lazy val module = moduleBuilder(bundleBuilder(node.bundleIn), this) lazy val module = moduleBuilder(bundleBuilder(TLRegBundleArg(intnode.bundleOut, node.bundleIn)), this)
} }