document PWM example better
This commit is contained in:
@@ -14,9 +14,14 @@ class PWM(implicit p: Parameters) extends Module {
|
|||||||
val tl = (new ClientUncachedTileLinkIO).flip
|
val tl = (new ClientUncachedTileLinkIO).flip
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// How many clock cycles in a PWM cycle?
|
||||||
val period = Reg(UInt(width = 64))
|
val period = Reg(UInt(width = 64))
|
||||||
|
// For how many cycles should the clock be high?
|
||||||
val duty = Reg(UInt(width = 64))
|
val duty = Reg(UInt(width = 64))
|
||||||
|
// Is the PWM even running at all?
|
||||||
val enable = Reg(init = Bool(false))
|
val enable = Reg(init = Bool(false))
|
||||||
|
|
||||||
|
// The counter should count up until period is reached
|
||||||
val counter = Reg(UInt(width = 64))
|
val counter = Reg(UInt(width = 64))
|
||||||
|
|
||||||
when (counter >= period) {
|
when (counter >= period) {
|
||||||
@@ -25,11 +30,28 @@ class PWM(implicit p: Parameters) extends Module {
|
|||||||
counter := counter + UInt(1)
|
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)
|
io.pwmout := enable && (counter < duty)
|
||||||
|
|
||||||
|
// One entry queue to hold the acquire message
|
||||||
val acq = Queue(io.tl.acquire, 1)
|
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
|
io.tl.grant.valid := acq.valid
|
||||||
acq.ready := io.tl.grant.ready
|
acq.ready := io.tl.grant.ready
|
||||||
io.tl.grant.bits := Grant(
|
io.tl.grant.bits := Grant(
|
||||||
@@ -38,20 +60,20 @@ class PWM(implicit p: Parameters) extends Module {
|
|||||||
client_xact_id = acq.bits.client_xact_id,
|
client_xact_id = acq.bits.client_xact_id,
|
||||||
manager_xact_id = UInt(0),
|
manager_xact_id = UInt(0),
|
||||||
addr_beat = acq.bits.addr_beat,
|
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(0) -> period,
|
||||||
UInt(1) -> duty,
|
UInt(1) -> duty,
|
||||||
UInt(2) -> enable)))
|
UInt(2) -> enable)))
|
||||||
|
|
||||||
|
// If this is a put, update the registers according to the index
|
||||||
when (acq.fire() && acq.bits.hasData()) {
|
when (acq.fire() && acq.bits.hasData()) {
|
||||||
switch (addr) {
|
switch (index) {
|
||||||
is (UInt(0)) { period := acq.bits.data }
|
is (UInt(0)) { period := acq.bits.data }
|
||||||
is (UInt(1)) { duty := acq.bits.data }
|
is (UInt(1)) { duty := acq.bits.data }
|
||||||
is (UInt(2)) { enable := acq.bits.data(0) }
|
is (UInt(2)) { enable := acq.bits.data(0) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
require(io.tl.tlDataBits == 64)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trait PeripheryPWM extends LazyModule {
|
trait PeripheryPWM extends LazyModule {
|
||||||
|
|||||||
Reference in New Issue
Block a user