diff --git a/src/main/scala/pwm/PWM.scala b/src/main/scala/pwm/PWM.scala index 463e2d96..b1a7748f 100644 --- a/src/main/scala/pwm/PWM.scala +++ b/src/main/scala/pwm/PWM.scala @@ -7,9 +7,12 @@ import uncore.tilelink._ import uncore.tilelink2._ import junctions._ import diplomacy._ +import regmapper.{HasRegMap, RegField} import rocketchip._ import _root_.util.UIntIsOneOf +case class PWMParams(address: BigInt, beatBytes: Int) + class PWMBase(w: Int) extends Module { val io = IO(new Bundle { val pwmout = Output(Bool()) @@ -32,28 +35,18 @@ class PWMBase(w: Int) extends Module { io.pwmout := io.enable && (counter < io.duty) } -class PWMTL(address: AddressSet, beatBytes: Int)(implicit p: Parameters) extends LazyModule { - val node = TLManagerNode(Seq(TLManagerPortParameters( - 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) +trait PWMTLBundle extends Bundle { + val pwmout = Output(Bool()) } -class PWMTLModule(outer: PWMTL, beatBytes: Int) extends LazyModuleImp(outer) { - val io = IO(new Bundle { - val pwmout = Output(Bool()) - val tl = outer.node.bundleIn - }) +trait PWMTLModule extends Module with HasRegMap { + val io: PWMTLBundle + implicit val p: Parameters + def params: PWMParams + + val w = params.beatBytes * 8 + require(w <= 32) - val w = beatBytes * 8 // How many clock cycles in a PWM cycle? val period = Reg(UInt(w.W)) // 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.enable := enable - val tl = io.tl.head - - tl.b.valid := false.B - tl.c.ready := false.B - tl.e.ready := false.B - - // One entry queue to hold the acquire message - 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) } - } - } + regmap( + 0x00 -> Seq( + RegField(w, period)), + 0x04 -> Seq( + RegField(w, duty)), + 0x08 -> Seq( + RegField(1, enable))) } +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 { implicit val p: Parameters val peripheryBus: TLXbar - private val address = AddressSet(0x2000, 0xfff) - val pwm = LazyModule(new PWMTL(address, peripheryBusConfig.beatBytes)(p)) + private val address = 0x2000 + + val pwm = LazyModule(new PWMTL( + PWMParams(address, peripheryBusConfig.beatBytes))(p)) + pwm.node := TLFragmenter( peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node) }