184226e46SZihao Yupackage device 284226e46SZihao Yu 384226e46SZihao Yuimport chisel3._ 484226e46SZihao Yuimport chisel3.util._ 50161df2aSZihao Yuimport chisel3.util.experimental.BoringUtils 684226e46SZihao Yu 7ce6a2d5bSZihao Yuimport bus.axi4._ 8f10a0bcbSZihao Yuimport utils._ 984226e46SZihao Yu 10891d22aaSZihao Yuclass TimerIO extends Bundle { 11891d22aaSZihao Yu val mtip = Output(Bool()) 12891d22aaSZihao Yu} 13891d22aaSZihao Yu 14891d22aaSZihao Yuclass AXI4Timer(sim: Boolean = false) extends AXI4SlaveModule(new AXI4Lite, new TimerIO) { 1587557494SZihao Yu val mtime = RegInit(0.U(64.W)) // unit: us 16891d22aaSZihao Yu val mtimecmp = RegInit(0.U(64.W)) 17891d22aaSZihao Yu 1887557494SZihao Yu val clk = (if (!sim) 40 /* 40MHz / 1000000 */ else 10000) 19*ac65130dSZihao Yu val freq = RegInit(clk.U(16.W)) 20*ac65130dSZihao Yu val inc = RegInit(1.U(16.W)) 21*ac65130dSZihao Yu 22*ac65130dSZihao Yu val cnt = RegInit(0.U(16.W)) 23*ac65130dSZihao Yu val nextCnt = cnt + 1.U 24*ac65130dSZihao Yu cnt := Mux(nextCnt < freq, nextCnt, 0.U) 25*ac65130dSZihao Yu val tick = (nextCnt === freq) 26*ac65130dSZihao Yu when (tick) { mtime := mtime + inc } 27891d22aaSZihao Yu 280161df2aSZihao Yu if (sim) { 290161df2aSZihao Yu val isWFI = WireInit(false.B) 300161df2aSZihao Yu BoringUtils.addSink(isWFI, "isWFI") 310161df2aSZihao Yu when (isWFI) { mtime := mtime + 100000.U } 320161df2aSZihao Yu } 330161df2aSZihao Yu 34891d22aaSZihao Yu val mapping = Map( 35434b30e4SZihao Yu RegMap(0x4000, mtimecmp), 36*ac65130dSZihao Yu RegMap(0x8000, freq), 37*ac65130dSZihao Yu RegMap(0x8008, inc), 38434b30e4SZihao Yu RegMap(0xbff8, mtime) 39891d22aaSZihao Yu ) 40434b30e4SZihao Yu def getOffset(addr: UInt) = addr(15,0) 41891d22aaSZihao Yu 42434b30e4SZihao Yu RegMap.generate(mapping, getOffset(raddr), in.r.bits.data, 43434b30e4SZihao Yu getOffset(waddr), in.w.fire(), in.w.bits.data, MaskExpand(in.w.bits.strb)) 44891d22aaSZihao Yu 454c8d1f11SZihao Yu io.extra.get.mtip := RegNext(mtime >= mtimecmp) 4684226e46SZihao Yu} 47