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