xref: /XiangShan/src/main/scala/device/TLTimer.scala (revision 9c14492e06b8bd9d352aade663a198358c1a5295)
1package device
2
3import chisel3._
4import chisel3.util._
5import freechips.rocketchip.tilelink._
6import chipsalliance.rocketchip.config._
7import chisel3.util.experimental.BoringUtils
8import freechips.rocketchip.diplomacy._
9import freechips.rocketchip.regmapper.RegField
10import utils.{HasTLDump, XSDebug}
11import xiangshan.HasXSLog
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) with HasXSLog with HasTLDump{
19    val io = IO(new Bundle() {
20      val mtip = Output(Bool())
21      val msip = Output(Bool())
22    })
23
24    val mtime = RegInit(0.U(64.W))  // unit: us
25    val mtimecmp = RegInit(0.U(64.W))
26    val msip = RegInit(0.U(64.W))
27
28    val clk = (if (!sim) 40 /* 40MHz / 1000000 */ else 100)
29    val freq = RegInit(clk.U(16.W))
30    val inc = RegInit(1.U(16.W))
31
32    val cnt = RegInit(0.U(16.W))
33    val nextCnt = cnt + 1.U
34    cnt := Mux(nextCnt < freq, nextCnt, 0.U)
35    val tick = (nextCnt === freq)
36    when (tick) { mtime := mtime + inc }
37
38    if (sim) {
39      val isWFI = WireInit(false.B)
40      BoringUtils.addSink(isWFI, "isWFI")
41      when (isWFI) { mtime := mtime + 100000.U }
42    }
43
44    node.regmap( mapping =
45      0x0000 -> RegField.bytes(msip),
46      0x4000 -> RegField.bytes(mtimecmp),
47      0x8000 -> RegField.bytes(freq),
48      0x8008 -> RegField.bytes(inc),
49      0xbff8 -> RegField.bytes(mtime)
50    )
51
52    val in = node.in.head._1
53    when(in.a.valid){
54      XSDebug("[A] channel valid ready=%d ", in.a.ready)
55      in.a.bits.dump
56    }
57
58//    val gtime = GTimer()
59//    printf(p"[$gtime][Timer] mtime=$mtime cnt=$cnt freq=$freq\n")
60
61    io.mtip := RegNext(mtime >= mtimecmp)
62    io.msip := RegNext(msip =/= 0.U)
63  }
64}
65