PWM: Add the ability to invert the output directly in PWM (without GPIO pinmux) pwm_invert
authorMegan Wachs <megan@sifive.com>
Mon, 2 Oct 2017 18:13:33 +0000 (11:13 -0700)
committerMegan Wachs <megan@sifive.com>
Mon, 2 Oct 2017 22:08:06 +0000 (15:08 -0700)
src/main/scala/devices/pwm/PWM.scala
src/main/scala/util/Timer.scala

index 638100496dabfb564b597a335d05e57c68aef041..7e7b30d98f45984f2158a7cd16101686a57af403 100644 (file)
@@ -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
 }
 
index 52bbab2de251e20a1248372eebbf3e6efced2e41..c46d2bef07ff68f6c677175be6f2b2b94ff07a5e 100644 (file)
@@ -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