xref: /XiangShan/src/main/scala/device/TLTimer.scala (revision da10912fea5617e445e104859d417e2c09cf8658)
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}
10import xiangshan.HasXSLog
11
12class TLTimer(address: Seq[AddressSet], sim: Boolean)(implicit p: Parameters) extends LazyModule {
13
14  val device = new SimpleDevice("clint", Seq("XiangShan", "clint"))
15  val node = TLRegisterNode(address, device, beatBytes = 8)
16
17  lazy val module = new LazyModuleImp(this) with HasXSLog with HasTLDump{
18    val io = IO(new Bundle() {
19      val mtip = Output(Bool())
20      val msip = Output(Bool())
21    })
22
23    val mtime = RegInit(0.U(64.W))  // unit: us
24    val mtimecmp = RegInit(0.U(64.W))
25    val msip = RegInit(0.U(64.W))
26
27    val clk = (if (!sim) 40 /* 40MHz / 1000000 */ else 100)
28    val freq = RegInit(clk.U(16.W))
29    val inc = RegInit(1.U(16.W))
30
31    val cnt = RegInit(0.U(16.W))
32    val nextCnt = cnt + 1.U
33    cnt := Mux(nextCnt < freq, nextCnt, 0.U)
34    val tick = (nextCnt === freq)
35    when (tick) { mtime := mtime + inc }
36
37    node.regmap( mapping =
38      0x0000 -> RegField.bytes(msip),
39      0x4000 -> RegField.bytes(mtimecmp),
40      0x8000 -> RegField.bytes(freq),
41      0x8008 -> RegField.bytes(inc),
42      0xbff8 -> RegField.bytes(mtime)
43    )
44
45    val in = node.in.head._1
46    when(in.a.valid){
47      XSDebug("[A] channel valid ready=%d ", in.a.ready)
48      in.a.bits.dump
49    }
50
51//    val gtime = GTimer()
52//    printf(p"[$gtime][Timer] mtime=$mtime cnt=$cnt freq=$freq\n")
53
54    io.mtip := RegNext(mtime >= mtimecmp)
55    io.msip := RegNext(msip =/= 0.U)
56  }
57}
58