184226e46SZihao Yupackage device 284226e46SZihao Yu 384226e46SZihao Yuimport chisel3._ 463934268Slinjiaweiimport chipsalliance.rocketchip.config.Parameters 563934268Slinjiaweiimport freechips.rocketchip.diplomacy.AddressSet 6f10a0bcbSZihao Yuimport utils._ 784226e46SZihao Yu 8891d22aaSZihao Yuclass TimerIO extends Bundle { 9891d22aaSZihao Yu val mtip = Output(Bool()) 10891d22aaSZihao Yu} 11891d22aaSZihao Yu 1263934268Slinjiaweiclass AXI4Timer 1363934268Slinjiawei( 1463934268Slinjiawei sim: Boolean = false, 15*a2e9bde6SAllen address: Seq[AddressSet] 1663934268Slinjiawei)(implicit p: Parameters) 1763934268Slinjiawei extends AXI4SlaveModule(address, executable = false, _extra = new TimerIO) 1863934268Slinjiawei{ 1963934268Slinjiawei override lazy val module = new AXI4SlaveModuleImp[TimerIO](this){ 2087557494SZihao Yu val mtime = RegInit(0.U(64.W)) // unit: us 21891d22aaSZihao Yu val mtimecmp = RegInit(0.U(64.W)) 22891d22aaSZihao Yu 2387557494SZihao Yu val clk = (if (!sim) 40 /* 40MHz / 1000000 */ else 10000) 24ac65130dSZihao Yu val freq = RegInit(clk.U(16.W)) 255fd0e682SLinJiawei val inc = RegInit(1000.U(16.W)) 26ac65130dSZihao Yu 27ac65130dSZihao Yu val cnt = RegInit(0.U(16.W)) 28ac65130dSZihao Yu val nextCnt = cnt + 1.U 29ac65130dSZihao Yu cnt := Mux(nextCnt < freq, nextCnt, 0.U) 30ac65130dSZihao Yu val tick = (nextCnt === freq) 31ac65130dSZihao Yu when (tick) { mtime := mtime + inc } 32891d22aaSZihao Yu 33891d22aaSZihao Yu val mapping = Map( 34434b30e4SZihao Yu RegMap(0x4000, mtimecmp), 35ac65130dSZihao Yu RegMap(0x8000, freq), 36ac65130dSZihao Yu RegMap(0x8008, inc), 37434b30e4SZihao Yu RegMap(0xbff8, mtime) 38891d22aaSZihao Yu ) 39434b30e4SZihao Yu def getOffset(addr: UInt) = addr(15,0) 40891d22aaSZihao Yu 41434b30e4SZihao Yu RegMap.generate(mapping, getOffset(raddr), in.r.bits.data, 42434b30e4SZihao Yu getOffset(waddr), in.w.fire(), in.w.bits.data, MaskExpand(in.w.bits.strb)) 43891d22aaSZihao Yu 444c8d1f11SZihao Yu io.extra.get.mtip := RegNext(mtime >= mtimecmp) 4584226e46SZihao Yu } 4663934268Slinjiawei} 47