From 66f58cf2d0f646576069ad5e380029937a0447d4 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Thu, 8 Sep 2016 15:17:30 -0700 Subject: [PATCH] tilelink2 RegisterRouter: support new TL2 interrupts --- src/main/scala/uncore/tilelink2/GPIO.scala | 14 +++++++--- .../scala/uncore/tilelink2/RegField.scala | 1 + .../uncore/tilelink2/RegisterRouter.scala | 26 +++++++++++++------ 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/main/scala/uncore/tilelink2/GPIO.scala b/src/main/scala/uncore/tilelink2/GPIO.scala index a9050882..6b4e1e4b 100644 --- a/src/main/scala/uncore/tilelink2/GPIO.scala +++ b/src/main/scala/uncore/tilelink2/GPIO.scala @@ -16,14 +16,22 @@ trait GPIOModule extends HasRegMap { val params: GPIOParams val io: GPIOBundle + val interrupts: Vec[Bool] 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 -class TLGPIO(p: GPIOParams) extends TLRegisterRouter(p.address)( +class TLGPIO(p: GPIOParams) extends TLRegisterRouter(p.address, 4)( new TLRegBundle(p, _) with GPIOBundle)( new TLRegModule(p, _, _) with GPIOModule) diff --git a/src/main/scala/uncore/tilelink2/RegField.scala b/src/main/scala/uncore/tilelink2/RegField.scala index 32a65c0d..9c324534 100644 --- a/src/main/scala/uncore/tilelink2/RegField.scala +++ b/src/main/scala/uncore/tilelink2/RegField.scala @@ -86,6 +86,7 @@ object RegField trait HasRegMap { def regmap(mapping: RegField.Map*): Unit + val interrupts: Vec[Bool] } // See GPIO.scala for an example of how to use regmap diff --git a/src/main/scala/uncore/tilelink2/RegisterRouter.scala b/src/main/scala/uncore/tilelink2/RegisterRouter.scala index e455efda..a3b61da7 100644 --- a/src/main/scala/uncore/tilelink2/RegisterRouter.scala +++ b/src/main/scala/uncore/tilelink2/RegisterRouter.scala @@ -75,29 +75,39 @@ object TLRegisterNode // register mapped device from a totally abstract register mapped device. // 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 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 { 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:_*) } -class TLRegisterRouter[B <: Bundle, M <: LazyModuleImp] - (base: BigInt, size: BigInt = 4096, concurrency: Option[Int] = None, beatBytes: Int = 4) - (bundleBuilder: Vec[TLBundle] => B) +class TLRegisterRouter[B <: TLRegBundleBase, M <: LazyModuleImp] + (base: BigInt, interrupts: Int = 0, size: BigInt = 4096, concurrency: Option[Int] = None, beatBytes: Int = 4) + (bundleBuilder: TLRegBundleArg => B) (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 (isPow2(size)) require (size >= 4096) - lazy val module = moduleBuilder(bundleBuilder(node.bundleIn), this) + lazy val module = moduleBuilder(bundleBuilder(TLRegBundleArg(intnode.bundleOut, node.bundleIn)), this) }