1 // See LICENSE for license details.
2 package sifive.blocks.devices.pwm
5 import Chisel.ImplicitConversions._
8 import rocketchip.PeripheryBusConfig
9 import uncore.tilelink2._
12 import sifive.blocks.util.GenericTimer
14 // Core PWM Functionality & Register Interface
16 class PWM(val ncmp: Int = 4, val cmpWidth: Int = 16)(implicit p: Parameters) extends GenericTimer {
17 protected def countWidth = ((1 << scaleWidth) - 1) + cmpWidth
18 protected lazy val countAlways = RegEnable(io.regs.cfg.write.bits(12), Bool(false), io.regs.cfg.write.valid && unlocked)
19 protected lazy val feed = count.carryOut(scale + UInt(cmpWidth))
20 protected lazy val countEn = Wire(Bool())
21 override protected lazy val oneShot = RegEnable(io.regs.cfg.write.bits(13) && !countReset, Bool(false), (io.regs.cfg.write.valid && unlocked) || countReset)
22 override protected lazy val center = RegEnable(io.regs.cfg.write.bits(16 + ncmp - 1, 16), io.regs.cfg.write.valid && unlocked)
23 override protected lazy val gang = RegEnable(io.regs.cfg.write.bits(24 + ncmp - 1, 24), io.regs.cfg.write.valid && unlocked)
24 override protected lazy val deglitch = RegEnable(io.regs.cfg.write.bits(10), io.regs.cfg.write.valid && unlocked)(0)
25 override protected lazy val sticky = RegEnable(io.regs.cfg.write.bits(8), io.regs.cfg.write.valid && unlocked)(0)
26 override protected lazy val ip = {
27 val doSticky = Reg(next = (deglitch && !countReset) || sticky)
28 val sel = ((0 until ncmp).map(i => s(cmpWidth-1) && center(i))).asUInt
29 val reg = Reg(UInt(width = ncmp))
30 reg := (sel & elapsed.asUInt) | (~sel & (elapsed.asUInt | (Fill(ncmp, doSticky) & reg)))
31 when (io.regs.cfg.write.valid && unlocked) { reg := io.regs.cfg.write.bits(28 + ncmp - 1, 28) }
34 lazy val io = new GenericTimerIO {
35 val gpio = Vec(ncmp, Bool()).asOutput
37 io.gpio := io.gpio.fromBits(ip & ~(gang & Cat(ip(0), ip >> 1)))
38 countEn := countAlways || oneShot
48 trait HasPWMParameters {
49 implicit val p: Parameters
54 trait PWMBundle extends Bundle with HasPWMParameters {
55 val gpio = Vec(c.ncmp, Bool()).asOutput
58 trait PWMModule extends Module with HasRegMap with HasPWMParameters {
61 val pwm = Module(new PWM(c.ncmp, c.cmpWidth))
63 interrupts := pwm.io.ip
64 io.gpio := pwm.io.gpio
66 regmap((GenericTimer.timerRegMap(pwm, 0, c.regBytes)):_*)
69 class TLPWM(c: PWMConfig)(implicit p: Parameters)
70 extends TLRegisterRouter(c.address, interrupts = c.ncmp, size = c.size, beatBytes = p(PeripheryBusConfig).beatBytes)(
71 new TLRegBundle(c, _) with PWMBundle)(
72 new TLRegModule(c, _, _) with PWMModule)