xref: /XiangShan/src/main/scala/device/TLTimer.scala (revision 618fb109099cc1d271e72520857cee13429b073c)
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