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