1package device 2 3import chisel3._ 4import chisel3.util._ 5import freechips.rocketchip.tilelink._ 6import chipsalliance.rocketchip.config 7import chipsalliance.rocketchip.config._ 8import chisel3.util.experimental.BoringUtils 9import freechips.rocketchip.diplomacy._ 10import freechips.rocketchip.regmapper.{RegField, RegWriteFn} 11import utils.{GTimer, HoldUnless, MaskExpand, RegMap} 12 13class TLTimer(address: Seq[AddressSet], sim: Boolean)(implicit p: Parameters) extends LazyModule { 14 15 val device = new SimpleDevice("clint", Seq("XiangShan", "clint")) 16 val node = TLRegisterNode(address, device, beatBytes = 8) 17 18 lazy val module = new LazyModuleImp(this){ 19 val mtip = IO(Output(Bool())) 20 21 val mtime = RegInit(0.U(64.W)) // unit: us 22 val mtimecmp = RegInit(0.U(64.W)) 23 24 val clk = (if (!sim) 40 /* 40MHz / 1000000 */ else 100) 25 val freq = RegInit(clk.U(16.W)) 26 val inc = RegInit(1000.U(16.W)) 27 28 val cnt = RegInit(0.U(16.W)) 29 val nextCnt = cnt + 1.U 30 cnt := Mux(nextCnt < freq, nextCnt, 0.U) 31 val tick = (nextCnt === freq) 32 when (tick) { mtime := mtime + inc } 33 34 if (sim) { 35 val isWFI = WireInit(false.B) 36 BoringUtils.addSink(isWFI, "isWFI") 37 when (isWFI) { mtime := mtime + 100000.U } 38 } 39 40 node.regmap( mapping = 41 0x4000 -> RegField.bytes(mtimecmp), 42 0x8000 -> RegField.bytes(freq), 43 0x8008 -> RegField.bytes(inc), 44 0xbff8 -> RegField.bytes(mtime) 45 ) 46 47// val gtime = GTimer() 48// printf(p"[$gtime][Timer] mtime=$mtime cnt=$cnt freq=$freq\n") 49 50 mtip := RegNext(mtime >= mtimecmp) 51 } 52} 53