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