1package device 2 3import chisel3._ 4import chisel3.util._ 5import freechips.rocketchip.tilelink._ 6import chipsalliance.rocketchip.config._ 7import freechips.rocketchip.diplomacy._ 8import freechips.rocketchip.regmapper.RegField 9import utils.{HasTLDump, XSDebug} 10 11class TLTimer(address: Seq[AddressSet], sim: Boolean, numCores: Int)(implicit p: Parameters) extends LazyModule { 12 13 val device = new SimpleDevice("clint", Seq("XiangShan", "clint")) 14 val node = TLRegisterNode(address, device, beatBytes = 8) 15 16 lazy val module = new LazyModuleImp(this) with HasTLDump { 17 val io = IO(new Bundle() { 18 val mtip = Output(Vec(numCores, Bool())) 19 val msip = Output(Vec(numCores, Bool())) 20 }) 21 22 val mtime = RegInit(0.U(64.W)) // unit: us 23 val mtimecmp = Seq.fill(numCores)(RegInit(0.U(64.W))) 24 val msip = Seq.fill(numCores)(RegInit(0.U(32.W))) 25 26 val clk = (if (!sim) 1000000 /* 40MHz / 1000000 */ else 100) 27 val freq = RegInit(clk.U(64.W)) 28 val inc = RegInit(1.U(64.W)) 29 30 val cnt = RegInit(0.U(64.W)) 31 val nextCnt = cnt + 1.U 32 cnt := Mux(nextCnt < freq, nextCnt, 0.U) 33 val tick = (nextCnt === freq) 34 when (tick) { mtime := mtime + inc } 35 36 var clintMapping = Seq( 37 0x8000 -> RegField.bytes(freq), 38 0x8008 -> RegField.bytes(inc), 39 0xbff8 -> RegField.bytes(mtime)) 40 41 for (i <- 0 until numCores) { 42 clintMapping = clintMapping ++ Seq( 43 0x0000 + i*4 -> RegField.bytes(msip(i)), 44 0x4000 + i*8 -> RegField.bytes(mtimecmp(i)) 45 ) 46 } 47 48 node.regmap( mapping = clintMapping:_* ) 49 50 val in = node.in.head._1 51 when(in.a.valid){ 52 XSDebug("[A] channel valid ready=%d ", in.a.ready) 53 in.a.bits.dump 54 } 55 56 for (i <- 0 until numCores) { 57 io.mtip(i) := RegNext(mtime >= mtimecmp(i)) 58 io.msip(i) := RegNext(msip(i) =/= 0.U) 59 } 60 } 61} 62