xref: /XiangShan/src/main/scala/device/TLTimer.scala (revision 8b33cd30e0034914b58520e0dc3c0c4b1aad6a03)
1/***************************************************************************************
2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3* Copyright (c) 2020-2021 Peng Cheng Laboratory
4*
5* XiangShan is licensed under Mulan PSL v2.
6* You can use this software according to the terms and conditions of the Mulan PSL v2.
7* You may obtain a copy of Mulan PSL v2 at:
8*          http://license.coscl.org.cn/MulanPSL2
9*
10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13*
14* See the Mulan PSL v2 for more details.
15***************************************************************************************/
16
17package device
18
19import chisel3._
20import chisel3.util._
21import freechips.rocketchip.tilelink._
22import org.chipsalliance.cde.config._
23import freechips.rocketchip.diplomacy._
24import freechips.rocketchip.regmapper.RegField
25import utils.HasTLDump
26import utility.XSDebug
27
28class TLTimer(address: Seq[AddressSet], sim: Boolean, numCores: Int)(implicit p: Parameters) extends LazyModule {
29
30  val device = new SimpleDevice("clint", Seq("XiangShan", "clint"))
31  val node = TLRegisterNode(address, device, beatBytes = 8)
32
33  lazy val module = new LazyModuleImp(this) with HasTLDump {
34    val io = IO(new Bundle() {
35      val mtip = Output(Vec(numCores, Bool()))
36      val msip = Output(Vec(numCores, Bool()))
37    })
38
39    val mtime = RegInit(0.U(64.W))  // unit: us
40    val mtimecmp = Seq.fill(numCores)(RegInit(0.U(64.W)))
41    val msip = Seq.fill(numCores)(RegInit(0.U(32.W)))
42
43    val clk = (if (!sim) 1000000 /* 40MHz / 1000000 */ else 100)
44    val freq = RegInit(clk.U(64.W))
45    val inc = RegInit(1.U(64.W))
46
47    val cnt = RegInit(0.U(64.W))
48    val nextCnt = cnt + 1.U
49    cnt := Mux(nextCnt < freq, nextCnt, 0.U)
50    val tick = (nextCnt === freq)
51    when (tick) { mtime := mtime + inc }
52
53    var clintMapping = Seq(
54      0x8000 -> RegField.bytes(freq),
55      0x8008 -> RegField.bytes(inc),
56      0xbff8 -> RegField.bytes(mtime))
57
58    for (i <- 0 until numCores) {
59      clintMapping = clintMapping ++ Seq(
60        0x0000 + i*4 -> RegField.bytes(msip(i)),
61        0x4000 + i*8 -> RegField.bytes(mtimecmp(i))
62      )
63    }
64
65    node.regmap( mapping = clintMapping:_* )
66
67    val in = node.in.head._1
68    XSDebug(in.a.valid, "[A] channel valid ready=%d ", in.a.ready)
69    in.a.bits.dump(in.a.valid)
70
71    for (i <- 0 until numCores) {
72      io.mtip(i) := RegNext(mtime >= mtimecmp(i))
73      io.msip(i) := RegNext(msip(i) =/= 0.U)
74    }
75  }
76}
77