xref: /XiangShan/src/main/scala/device/AXI4Timer.scala (revision 6393426847885f18093a4107e7efe6beb0089bd2)
184226e46SZihao Yupackage device
284226e46SZihao Yu
384226e46SZihao Yuimport chisel3._
40161df2aSZihao Yuimport chisel3.util.experimental.BoringUtils
5*63934268Slinjiaweiimport chipsalliance.rocketchip.config.Parameters
6*63934268Slinjiaweiimport freechips.rocketchip.diplomacy.AddressSet
7f10a0bcbSZihao Yuimport utils._
884226e46SZihao Yu
9891d22aaSZihao Yuclass TimerIO extends Bundle {
10891d22aaSZihao Yu  val mtip = Output(Bool())
11891d22aaSZihao Yu}
12891d22aaSZihao Yu
13*63934268Slinjiaweiclass AXI4Timer
14*63934268Slinjiawei(
15*63934268Slinjiawei  sim: Boolean = false,
16*63934268Slinjiawei  address: AddressSet
17*63934268Slinjiawei)(implicit p: Parameters)
18*63934268Slinjiawei  extends AXI4SlaveModule(address, executable = false, _extra = new TimerIO)
19*63934268Slinjiawei{
20*63934268Slinjiawei  override lazy val module = new AXI4SlaveModuleImp[TimerIO](this){
2187557494SZihao Yu    val mtime = RegInit(0.U(64.W))  // unit: us
22891d22aaSZihao Yu    val mtimecmp = RegInit(0.U(64.W))
23891d22aaSZihao Yu
2487557494SZihao Yu    val clk = (if (!sim) 40 /* 40MHz / 1000000 */ else 10000)
25ac65130dSZihao Yu    val freq = RegInit(clk.U(16.W))
265fd0e682SLinJiawei    val inc = RegInit(1000.U(16.W))
27ac65130dSZihao Yu
28ac65130dSZihao Yu    val cnt = RegInit(0.U(16.W))
29ac65130dSZihao Yu    val nextCnt = cnt + 1.U
30ac65130dSZihao Yu    cnt := Mux(nextCnt < freq, nextCnt, 0.U)
31ac65130dSZihao Yu    val tick = (nextCnt === freq)
32ac65130dSZihao Yu    when (tick) { mtime := mtime + inc }
33891d22aaSZihao Yu
340161df2aSZihao Yu    if (sim) {
350161df2aSZihao Yu      val isWFI = WireInit(false.B)
360161df2aSZihao Yu      BoringUtils.addSink(isWFI, "isWFI")
370161df2aSZihao Yu      when (isWFI) { mtime := mtime + 100000.U }
380161df2aSZihao Yu    }
390161df2aSZihao Yu
40891d22aaSZihao Yu    val mapping = Map(
41434b30e4SZihao Yu      RegMap(0x4000, mtimecmp),
42ac65130dSZihao Yu      RegMap(0x8000, freq),
43ac65130dSZihao Yu      RegMap(0x8008, inc),
44434b30e4SZihao Yu      RegMap(0xbff8, mtime)
45891d22aaSZihao Yu    )
46434b30e4SZihao Yu    def getOffset(addr: UInt) = addr(15,0)
47891d22aaSZihao Yu
48434b30e4SZihao Yu    RegMap.generate(mapping, getOffset(raddr), in.r.bits.data,
49434b30e4SZihao Yu      getOffset(waddr), in.w.fire(), in.w.bits.data, MaskExpand(in.w.bits.strb))
50891d22aaSZihao Yu
514c8d1f11SZihao Yu    io.extra.get.mtip := RegNext(mtime >= mtimecmp)
5284226e46SZihao Yu  }
53*63934268Slinjiawei}
54