1package xiangshan.backend.rename 2 3import chipsalliance.rocketchip.config.Parameters 4import chisel3._ 5import chisel3.util._ 6import xiangshan._ 7import utils._ 8 9class BusyTableReadIO(implicit p: Parameters) extends XSBundle { 10 val req = Input(UInt(PhyRegIdxWidth.W)) 11 val resp = Output(Bool()) 12} 13 14class BusyTable(numReadPorts: Int, numWritePorts: Int)(implicit p: Parameters) extends XSModule { 15 val io = IO(new Bundle() { 16 val flush = Input(Bool()) 17 // set preg state to busy 18 val allocPregs = Vec(RenameWidth, Flipped(ValidIO(UInt(PhyRegIdxWidth.W)))) 19 // set preg state to ready (write back regfile + roq walk) 20 val wbPregs = Vec(numWritePorts, Flipped(ValidIO(UInt(PhyRegIdxWidth.W)))) 21 // read preg state 22 val read = Vec(numReadPorts, new BusyTableReadIO) 23 }) 24 25 val table = RegInit(0.U(NRPhyRegs.W)) 26 27 def reqVecToMask(rVec: Vec[Valid[UInt]]): UInt = { 28 ParallelOR(rVec.map(v => Mux(v.valid, UIntToOH(v.bits), 0.U))) 29 } 30 31 val wbMask = reqVecToMask(io.wbPregs) 32 val allocMask = reqVecToMask(io.allocPregs) 33 34 val tableAfterWb = table & (~wbMask).asUInt 35 val tableAfterAlloc = tableAfterWb | allocMask 36 37 io.read.map(r => r.resp := !table(r.req)) 38 39 table := tableAfterAlloc 40 41 when(io.flush){ 42 table := 0.U(NRPhyRegs.W) 43 } 44 45 XSDebug(p"table : ${Binary(table)}\n") 46 XSDebug(p"tableNext: ${Binary(tableAfterAlloc)}\n") 47 XSDebug(p"allocMask: ${Binary(allocMask)}\n") 48 XSDebug(p"wbMask : ${Binary(wbMask)}\n") 49 for (i <- 0 until NRPhyRegs) { 50 XSDebug(table(i), "%d is busy\n", i.U) 51 } 52 53 XSPerfAccumulate("busy_count", PopCount(table)) 54} 55