xref: /XiangShan/src/main/scala/device/TLTimer.scala (revision 298aa395a6ec116ee255d90b2c1188c32a53ef35)
1618fb109Slinjiaweipackage device
2618fb109Slinjiawei
3618fb109Slinjiaweiimport chisel3._
4618fb109Slinjiaweiimport chisel3.util._
5618fb109Slinjiaweiimport freechips.rocketchip.tilelink._
6618fb109Slinjiaweiimport chipsalliance.rocketchip.config._
7618fb109Slinjiaweiimport freechips.rocketchip.diplomacy._
81865a66fSlinjiaweiimport freechips.rocketchip.regmapper.RegField
91865a66fSlinjiaweiimport utils.{HasTLDump, XSDebug}
101865a66fSlinjiaweiimport xiangshan.HasXSLog
11618fb109Slinjiawei
12618fb109Slinjiaweiclass TLTimer(address: Seq[AddressSet], sim: Boolean)(implicit p: Parameters) extends LazyModule {
13618fb109Slinjiawei
14618fb109Slinjiawei  val device = new SimpleDevice("clint", Seq("XiangShan", "clint"))
15618fb109Slinjiawei  val node = TLRegisterNode(address, device, beatBytes = 8)
160668d426Swangkaifan  val NumCores = top.Parameters.get.socParameters.NumCores
17618fb109Slinjiawei
181865a66fSlinjiawei  lazy val module = new LazyModuleImp(this) with HasXSLog with HasTLDump{
19799b61e0SLinJiawei    val io = IO(new Bundle() {
200668d426Swangkaifan      val mtip = Output(Vec(NumCores, Bool()))
210668d426Swangkaifan      val msip = Output(Vec(NumCores, Bool()))
22799b61e0SLinJiawei    })
23618fb109Slinjiawei
24618fb109Slinjiawei    val mtime = RegInit(0.U(64.W))  // unit: us
250668d426Swangkaifan    val mtimecmp = Seq.fill(NumCores)(RegInit(0.U(64.W)))
260668d426Swangkaifan    val msip = Seq.fill(NumCores)(RegInit(0.U(32.W)))
27618fb109Slinjiawei
28*298aa395SYinan Xu    val clk = (if (!sim) 40 /* 40MHz / 1000000 */ else 1000000)
29*298aa395SYinan Xu    val freq = RegInit(clk.U(64.W))
30*298aa395SYinan Xu    val inc = RegInit(1.U(64.W))
31618fb109Slinjiawei
32*298aa395SYinan Xu    val cnt = RegInit(0.U(64.W))
33618fb109Slinjiawei    val nextCnt = cnt + 1.U
34618fb109Slinjiawei    cnt := Mux(nextCnt < freq, nextCnt, 0.U)
35618fb109Slinjiawei    val tick = (nextCnt === freq)
36618fb109Slinjiawei    when (tick) { mtime := mtime + inc }
37618fb109Slinjiawei
380668d426Swangkaifan    var clintMapping = Seq(
39618fb109Slinjiawei      0x8000 -> RegField.bytes(freq),
40618fb109Slinjiawei      0x8008 -> RegField.bytes(inc),
410668d426Swangkaifan      0xbff8 -> RegField.bytes(mtime))
420668d426Swangkaifan
430668d426Swangkaifan    for (i <- 0 until NumCores) {
440668d426Swangkaifan      clintMapping = clintMapping ++ Seq(
450668d426Swangkaifan        0x0000 + i*4 -> RegField.bytes(msip(i)),
460668d426Swangkaifan        0x4000 + i*8 -> RegField.bytes(mtimecmp(i))
47618fb109Slinjiawei      )
480668d426Swangkaifan    }
490668d426Swangkaifan
500668d426Swangkaifan    node.regmap( mapping = clintMapping:_* )
51618fb109Slinjiawei
521865a66fSlinjiawei    val in = node.in.head._1
531865a66fSlinjiawei    when(in.a.valid){
541865a66fSlinjiawei      XSDebug("[A] channel valid ready=%d ", in.a.ready)
551865a66fSlinjiawei      in.a.bits.dump
561865a66fSlinjiawei    }
571865a66fSlinjiawei
580668d426Swangkaifan    for (i <- 0 until NumCores) {
590668d426Swangkaifan      io.mtip(i) := RegNext(mtime >= mtimecmp(i))
600668d426Swangkaifan      io.msip(i) := RegNext(msip(i) =/= 0.U)
610668d426Swangkaifan    }
62618fb109Slinjiawei  }
63618fb109Slinjiawei}
64