use RegisterRouter to simplify PWM
This commit is contained in:
@@ -7,9 +7,12 @@ import uncore.tilelink._
|
|||||||
import uncore.tilelink2._
|
import uncore.tilelink2._
|
||||||
import junctions._
|
import junctions._
|
||||||
import diplomacy._
|
import diplomacy._
|
||||||
|
import regmapper.{HasRegMap, RegField}
|
||||||
import rocketchip._
|
import rocketchip._
|
||||||
import _root_.util.UIntIsOneOf
|
import _root_.util.UIntIsOneOf
|
||||||
|
|
||||||
|
case class PWMParams(address: BigInt, beatBytes: Int)
|
||||||
|
|
||||||
class PWMBase(w: Int) extends Module {
|
class PWMBase(w: Int) extends Module {
|
||||||
val io = IO(new Bundle {
|
val io = IO(new Bundle {
|
||||||
val pwmout = Output(Bool())
|
val pwmout = Output(Bool())
|
||||||
@@ -32,28 +35,18 @@ class PWMBase(w: Int) extends Module {
|
|||||||
io.pwmout := io.enable && (counter < io.duty)
|
io.pwmout := io.enable && (counter < io.duty)
|
||||||
}
|
}
|
||||||
|
|
||||||
class PWMTL(address: AddressSet, beatBytes: Int)(implicit p: Parameters) extends LazyModule {
|
trait PWMTLBundle extends Bundle {
|
||||||
val node = TLManagerNode(Seq(TLManagerPortParameters(
|
val pwmout = Output(Bool())
|
||||||
Seq(TLManagerParameters(
|
|
||||||
address = List(address),
|
|
||||||
regionType = RegionType.PUT_EFFECTS,
|
|
||||||
executable = false,
|
|
||||||
supportsGet = TransferSizes(1, beatBytes),
|
|
||||||
supportsPutFull = TransferSizes(1, beatBytes),
|
|
||||||
fifoId = Some(0))), // requests are handled in order
|
|
||||||
beatBytes = beatBytes,
|
|
||||||
minLatency = 1)))
|
|
||||||
|
|
||||||
lazy val module = new PWMTLModule(this, beatBytes)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class PWMTLModule(outer: PWMTL, beatBytes: Int) extends LazyModuleImp(outer) {
|
trait PWMTLModule extends Module with HasRegMap {
|
||||||
val io = IO(new Bundle {
|
val io: PWMTLBundle
|
||||||
val pwmout = Output(Bool())
|
implicit val p: Parameters
|
||||||
val tl = outer.node.bundleIn
|
def params: PWMParams
|
||||||
})
|
|
||||||
|
val w = params.beatBytes * 8
|
||||||
|
require(w <= 32)
|
||||||
|
|
||||||
val w = beatBytes * 8
|
|
||||||
// How many clock cycles in a PWM cycle?
|
// How many clock cycles in a PWM cycle?
|
||||||
val period = Reg(UInt(w.W))
|
val period = Reg(UInt(w.W))
|
||||||
// For how many cycles should the clock be high?
|
// For how many cycles should the clock be high?
|
||||||
@@ -67,49 +60,31 @@ class PWMTLModule(outer: PWMTL, beatBytes: Int) extends LazyModuleImp(outer) {
|
|||||||
base.io.duty := duty
|
base.io.duty := duty
|
||||||
base.io.enable := enable
|
base.io.enable := enable
|
||||||
|
|
||||||
val tl = io.tl.head
|
regmap(
|
||||||
|
0x00 -> Seq(
|
||||||
tl.b.valid := false.B
|
RegField(w, period)),
|
||||||
tl.c.ready := false.B
|
0x04 -> Seq(
|
||||||
tl.e.ready := false.B
|
RegField(w, duty)),
|
||||||
|
0x08 -> Seq(
|
||||||
// One entry queue to hold the acquire message
|
RegField(1, enable)))
|
||||||
val acq = Queue(tl.a, 1)
|
|
||||||
|
|
||||||
// We have 3 32-bit registers
|
|
||||||
val index = acq.bits.address(3, 2)
|
|
||||||
|
|
||||||
val edge = outer.node.edgesIn(0)
|
|
||||||
val hasData = edge.hasData(acq.bits)
|
|
||||||
|
|
||||||
// Base the grant on the stored acquire
|
|
||||||
tl.d.valid := acq.valid
|
|
||||||
acq.ready := tl.d.ready
|
|
||||||
tl.d.bits := edge.AccessAck(acq.bits, 0.U)
|
|
||||||
tl.d.bits.opcode := Mux(hasData, TLMessages.AccessAck, TLMessages.AccessAckData)
|
|
||||||
tl.d.bits.data := MuxLookup(index, 0.U,
|
|
||||||
Seq(
|
|
||||||
0.U -> period,
|
|
||||||
1.U -> duty,
|
|
||||||
2.U -> enable))
|
|
||||||
tl.d.bits.error := index > 2.U
|
|
||||||
|
|
||||||
// If this is a put, update the registers according to the index
|
|
||||||
when (acq.fire() && acq.bits.opcode === TLMessages.PutFullData) {
|
|
||||||
switch (index) {
|
|
||||||
is (0.U) { period := acq.bits.data }
|
|
||||||
is (1.U) { duty := acq.bits.data }
|
|
||||||
is (2.U) { enable := acq.bits.data(0) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PWMTL(c: PWMParams)(implicit p: Parameters)
|
||||||
|
extends TLRegisterRouter(
|
||||||
|
c.address, "pwm", Seq("ucbbar,pwm"),
|
||||||
|
beatBytes = c.beatBytes)(
|
||||||
|
new TLRegBundle(c, _) with PWMTLBundle)(
|
||||||
|
new TLRegModule(c, _, _) with PWMTLModule)
|
||||||
|
|
||||||
trait PeripheryPWM extends LazyModule with HasPeripheryParameters {
|
trait PeripheryPWM extends LazyModule with HasPeripheryParameters {
|
||||||
implicit val p: Parameters
|
implicit val p: Parameters
|
||||||
val peripheryBus: TLXbar
|
val peripheryBus: TLXbar
|
||||||
|
|
||||||
private val address = AddressSet(0x2000, 0xfff)
|
private val address = 0x2000
|
||||||
val pwm = LazyModule(new PWMTL(address, peripheryBusConfig.beatBytes)(p))
|
|
||||||
|
val pwm = LazyModule(new PWMTL(
|
||||||
|
PWMParams(address, peripheryBusConfig.beatBytes))(p))
|
||||||
|
|
||||||
pwm.node := TLFragmenter(
|
pwm.node := TLFragmenter(
|
||||||
peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node)
|
peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user