From 9a09850dd24a4a6ec57bfa6e266ccc02caff3023 Mon Sep 17 00:00:00 2001 From: Howard Mao Date: Tue, 25 Oct 2016 11:36:11 -0700 Subject: [PATCH] document PWM example better --- src/main/scala/pwm/PWM.scala | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/main/scala/pwm/PWM.scala b/src/main/scala/pwm/PWM.scala index 6f8ee9c9..e151f35f 100644 --- a/src/main/scala/pwm/PWM.scala +++ b/src/main/scala/pwm/PWM.scala @@ -14,9 +14,14 @@ class PWM(implicit p: Parameters) extends Module { val tl = (new ClientUncachedTileLinkIO).flip } + // How many clock cycles in a PWM cycle? val period = Reg(UInt(width = 64)) + // For how many cycles should the clock be high? val duty = Reg(UInt(width = 64)) + // Is the PWM even running at all? val enable = Reg(init = Bool(false)) + + // The counter should count up until period is reached val counter = Reg(UInt(width = 64)) when (counter >= period) { @@ -25,11 +30,28 @@ class PWM(implicit p: Parameters) extends Module { counter := counter + UInt(1) } + // If PWM is enabled, pwmout is high when counter < duty + // If PWM is not enabled, it will always be low io.pwmout := enable && (counter < duty) + // One entry queue to hold the acquire message val acq = Queue(io.tl.acquire, 1) - val addr = Cat(acq.bits.addr_block, acq.bits.addr_beat) + // We assume that the TileLink interface is 64 bits wide + require(io.tl.tlDataBits == 64) + + // Then addr_block and addr_beat together form the word address + val full_addr = Cat(acq.bits.addr_block, acq.bits.addr_beat) + // Since we have 3 registers, we only need the lower two bits to distinguish them + val index = full_addr(1, 0) + + // Make sure the acquires we get are only the types we expect + assert(!acq.valid || + acq.bits.isBuiltInType(Acquire.getType) || + acq.bits.isBuiltInType(Acquire.putType), + "PWM: unexpected acquire type") + + // Base the grant on the stored acquire io.tl.grant.valid := acq.valid acq.ready := io.tl.grant.ready io.tl.grant.bits := Grant( @@ -38,20 +60,20 @@ class PWM(implicit p: Parameters) extends Module { client_xact_id = acq.bits.client_xact_id, manager_xact_id = UInt(0), addr_beat = acq.bits.addr_beat, - data = MuxLookup(addr, UInt(0), Seq( + // For gets, map the index to the three registers + data = MuxLookup(index, UInt(0), Seq( UInt(0) -> period, UInt(1) -> duty, UInt(2) -> enable))) + // If this is a put, update the registers according to the index when (acq.fire() && acq.bits.hasData()) { - switch (addr) { + switch (index) { is (UInt(0)) { period := acq.bits.data } is (UInt(1)) { duty := acq.bits.data } is (UInt(2)) { enable := acq.bits.data(0) } } } - - require(io.tl.tlDataBits == 64) } trait PeripheryPWM extends LazyModule {