Use HomogenousBag to handle lists of peripherals
[sifive-blocks.git] / src / main / scala / devices / pwm / PWMPeriphery.scala
1 // See LICENSE for license details.
2 package sifive.blocks.devices.pwm
3
4 import Chisel._
5 import config._
6 import diplomacy.LazyModule
7 import rocketchip.{TopNetwork,TopNetworkModule}
8 import uncore.tilelink2.TLFragmenter
9 import util.HeterogeneousBag
10
11 import sifive.blocks.devices.gpio._
12
13 class PWMPortIO(c: PWMConfig)(implicit p: Parameters) extends Bundle {
14 val port = Vec(c.ncmp, Bool()).asOutput
15 override def cloneType: this.type = new PWMPortIO(c).asInstanceOf[this.type]
16 }
17
18 class PWMPinsIO(c: PWMConfig)(implicit p: Parameters) extends Bundle {
19 val pwm = Vec(c.ncmp, new GPIOPin)
20 }
21
22 class PWMGPIOPort(c: PWMConfig)(implicit p: Parameters) extends Module {
23 val io = new Bundle {
24 val pwm = new PWMPortIO(c).flip()
25 val pins = new PWMPinsIO(c)
26 }
27
28 GPIOOutputPinCtrl(io.pins.pwm, io.pwm.port.asUInt)
29 }
30
31 trait PeripheryPWM {
32 this: TopNetwork { val pwmConfigs: Seq[PWMConfig] } =>
33
34 val pwm = (pwmConfigs.zipWithIndex) map { case (c, i) =>
35 val pwm = LazyModule(new TLPWM(c))
36 pwm.node := TLFragmenter(peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node)
37 intBus.intnode := pwm.intnode
38 pwm
39 }
40 }
41
42 trait PeripheryPWMBundle {
43 this: {
44 val p: Parameters
45 val pwmConfigs: Seq[PWMConfig]
46 } =>
47 val pwms = HeterogeneousBag(pwmConfigs.map(new PWMPortIO(_)(p)))
48 }
49
50 trait PeripheryPWMModule {
51 this: TopNetworkModule {
52 val outer: PeripheryPWM
53 val io: PeripheryPWMBundle
54 } =>
55 (io.pwms.zipWithIndex zip outer.pwm) foreach { case ((io, i), device) =>
56 io.port := device.module.io.gpio
57 }
58 }