xref: /XiangShan/src/main/scala/device/TLTimer.scala (revision 1865a66fb06dc0d7bdecc30c42ad77e8f09a8f7f)
1618fb109Slinjiaweipackage device
2618fb109Slinjiawei
3618fb109Slinjiaweiimport chisel3._
4618fb109Slinjiaweiimport chisel3.util._
5618fb109Slinjiaweiimport freechips.rocketchip.tilelink._
6618fb109Slinjiaweiimport chipsalliance.rocketchip.config._
7618fb109Slinjiaweiimport chisel3.util.experimental.BoringUtils
8618fb109Slinjiaweiimport freechips.rocketchip.diplomacy._
9*1865a66fSlinjiaweiimport freechips.rocketchip.regmapper.RegField
10*1865a66fSlinjiaweiimport utils.{HasTLDump, XSDebug}
11*1865a66fSlinjiaweiimport xiangshan.HasXSLog
12618fb109Slinjiawei
13618fb109Slinjiaweiclass TLTimer(address: Seq[AddressSet], sim: Boolean)(implicit p: Parameters) extends LazyModule {
14618fb109Slinjiawei
15618fb109Slinjiawei  val device = new SimpleDevice("clint", Seq("XiangShan", "clint"))
16618fb109Slinjiawei  val node = TLRegisterNode(address, device, beatBytes = 8)
17618fb109Slinjiawei
18*1865a66fSlinjiawei  lazy val module = new LazyModuleImp(this) with HasXSLog with HasTLDump{
19618fb109Slinjiawei    val mtip = IO(Output(Bool()))
20618fb109Slinjiawei
21618fb109Slinjiawei    val mtime = RegInit(0.U(64.W))  // unit: us
22618fb109Slinjiawei    val mtimecmp = RegInit(0.U(64.W))
23618fb109Slinjiawei
24618fb109Slinjiawei    val clk = (if (!sim) 40 /* 40MHz / 1000000 */ else 100)
25618fb109Slinjiawei    val freq = RegInit(clk.U(16.W))
26618fb109Slinjiawei    val inc = RegInit(1000.U(16.W))
27618fb109Slinjiawei
28618fb109Slinjiawei    val cnt = RegInit(0.U(16.W))
29618fb109Slinjiawei    val nextCnt = cnt + 1.U
30618fb109Slinjiawei    cnt := Mux(nextCnt < freq, nextCnt, 0.U)
31618fb109Slinjiawei    val tick = (nextCnt === freq)
32618fb109Slinjiawei    when (tick) { mtime := mtime + inc }
33618fb109Slinjiawei
34618fb109Slinjiawei    if (sim) {
35618fb109Slinjiawei      val isWFI = WireInit(false.B)
36618fb109Slinjiawei      BoringUtils.addSink(isWFI, "isWFI")
37618fb109Slinjiawei      when (isWFI) { mtime := mtime + 100000.U }
38618fb109Slinjiawei    }
39618fb109Slinjiawei
40618fb109Slinjiawei    node.regmap( mapping =
41618fb109Slinjiawei      0x4000 -> RegField.bytes(mtimecmp),
42618fb109Slinjiawei      0x8000 -> RegField.bytes(freq),
43618fb109Slinjiawei      0x8008 -> RegField.bytes(inc),
44618fb109Slinjiawei      0xbff8 -> RegField.bytes(mtime)
45618fb109Slinjiawei    )
46618fb109Slinjiawei
47*1865a66fSlinjiawei    val in = node.in.head._1
48*1865a66fSlinjiawei    when(in.a.valid){
49*1865a66fSlinjiawei      XSDebug("[A] channel valid ready=%d ", in.a.ready)
50*1865a66fSlinjiawei      in.a.bits.dump
51*1865a66fSlinjiawei    }
52*1865a66fSlinjiawei
53e2801f97Slinjiawei//    val gtime = GTimer()
54e2801f97Slinjiawei//    printf(p"[$gtime][Timer] mtime=$mtime cnt=$cnt freq=$freq\n")
55618fb109Slinjiawei
56618fb109Slinjiawei    mtip := RegNext(mtime >= mtimecmp)
57618fb109Slinjiawei  }
58618fb109Slinjiawei}
59