From 3e47ed6b335bc84d6469cf4c84eb1ccf5a0353cc Mon Sep 17 00:00:00 2001 From: Megan Wachs Date: Mon, 2 Oct 2017 11:13:33 -0700 Subject: [PATCH] PWM: Add the ability to invert the output directly in PWM (without GPIO pinmux) --- src/main/scala/devices/pwm/PWM.scala | 6 +++++- src/main/scala/util/Timer.scala | 6 ++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/scala/devices/pwm/PWM.scala b/src/main/scala/devices/pwm/PWM.scala index 6381004..7e7b30d 100644 --- a/src/main/scala/devices/pwm/PWM.scala +++ b/src/main/scala/devices/pwm/PWM.scala @@ -18,6 +18,7 @@ class PWM(val ncmp: Int = 4, val cmpWidth: Int = 16) extends GenericTimer { protected lazy val feed = count.carryOut(scale + UInt(cmpWidth)) protected lazy val countEn = Wire(Bool()) override protected lazy val oneShot = RegEnable(io.regs.cfg.write.bits(13) && !countReset, Bool(false), (io.regs.cfg.write.valid && unlocked) || countReset) + override protected lazy val extra = RegEnable(io.regs.cfg.write.bits(20 + ncmp - 1, 20), init = 0.U, enable = io.regs.cfg.write.valid && unlocked) override protected lazy val center = RegEnable(io.regs.cfg.write.bits(16 + ncmp - 1, 16), io.regs.cfg.write.valid && unlocked) override protected lazy val gang = RegEnable(io.regs.cfg.write.bits(24 + ncmp - 1, 24), io.regs.cfg.write.valid && unlocked) override protected lazy val deglitch = RegEnable(io.regs.cfg.write.bits(10), io.regs.cfg.write.valid && unlocked)(0) @@ -33,7 +34,10 @@ class PWM(val ncmp: Int = 4, val cmpWidth: Int = 16) extends GenericTimer { lazy val io = new GenericTimerIO { val gpio = Vec(ncmp, Bool()).asOutput } - io.gpio := io.gpio.fromBits(ip & ~(gang & Cat(ip(0), ip >> 1))) + + val invert = extra + + io.gpio := io.gpio.fromBits((ip & ~(gang & Cat(ip(0), ip >> 1))) ^ invert) countEn := countAlways || oneShot } diff --git a/src/main/scala/util/Timer.scala b/src/main/scala/util/Timer.scala index 52bbab2..c46d2be 100644 --- a/src/main/scala/util/Timer.scala +++ b/src/main/scala/util/Timer.scala @@ -38,6 +38,7 @@ abstract class GenericTimer extends Module { protected def sticky: Bool = Bool(false) protected def oneShot: Bool = Bool(false) protected def center: UInt = UInt(0) + protected def extra: UInt = UInt(0) protected def gang: UInt = UInt(0) protected val scaleWidth = 4 protected val regWidth = 32 @@ -76,8 +77,9 @@ abstract class GenericTimer extends Module { protected val countReset = feed || (zerocmp && elapsed(0)) when (countReset) { count := 0 } - io.regs.cfg.read := Cat(ip, gang | UInt(0, maxcmp), UInt(0, maxcmp), center | UInt(0, maxcmp), - UInt(0, 2), countAwake || oneShot, countAlways, UInt(0, 1), deglitch, zerocmp, rsten || sticky, UInt(0, 8-scaleWidth), scale) + io.regs.cfg.read := Cat(ip, gang | UInt(0, maxcmp), extra | UInt(0, maxcmp), center | UInt(0, maxcmp), + UInt(0, 2), countAwake || oneShot, countAlways, UInt(0, 1), deglitch, zerocmp, rsten || sticky, + UInt(0, 8-scaleWidth), scale) io.regs.countLo.read := count io.regs.countHi.read := count >> regWidth io.regs.s.read := s