package xiangshan.backend.rename import chisel3._ import chisel3.util._ import xiangshan._ class RatReadPort extends XSBundle { val addr = Input(UInt(5.W)) val rdata = Output(UInt(XLEN.W)) } class RatWritePort extends XSBundle { val wen = Input(Bool()) val addr = Input(UInt(5.W)) val wdata = Input(UInt(XLEN.W)) } class RenameTable(float: Boolean) extends XSModule { val io = IO(new Bundle() { val redirect = Flipped(ValidIO(new Redirect)) val walkWen = Input(Bool()) val readPorts = Vec({if(float) 4 else 3} * RenameWidth, new RatReadPort) val specWritePorts = Vec(RenameWidth, new RatWritePort) val archWritePorts = Vec(CommitWidth, new RatWritePort) }) // speculative rename table val spec_table = RegInit(VecInit(Seq.tabulate(32)(i => i.U(PhyRegIdxWidth.W)))) // arch state rename table val arch_table = RegInit(VecInit(Seq.tabulate(32)(i => i.U(PhyRegIdxWidth.W)))) // When redirect happens (mis-prediction), don't update the rename table // However, when mis-prediction and walk happens at the same time, rename table needs to be updated for(w <- io.specWritePorts){ when(w.wen && (!io.redirect.valid || io.walkWen)) { spec_table(w.addr) := w.wdata } } for((r, i) <- io.readPorts.zipWithIndex){ r.rdata := spec_table(r.addr) // for(w <- io.specWritePorts.take(i/{if(float) 4 else 3})){ // bypass // when(w.wen && (w.addr === r.addr)){ r.rdata := w.wdata } // } } for(w <- io.archWritePorts){ when(w.wen){ arch_table(w.addr) := w.wdata } } val flush = io.redirect.valid && io.redirect.bits.isUnconditional() when (flush) { spec_table := arch_table // spec table needs to be updated when flushPipe for (w <- io.archWritePorts) { when(w.wen){ spec_table(w.addr) := w.wdata } } } if (!env.FPGAPlatform) { ExcitingUtils.addSource( arch_table, if(float) "DEBUG_FP_ARCH_RAT" else "DEBUG_INI_ARCH_RAT", ExcitingUtils.Debug ) } }