1package xiangshan.backend.issue 2 3import chisel3._ 4import chisel3.util._ 5import xiangshan._ 6 7trait IQConst{ 8 val iqSize = 8 9 val iqIdxWidth = log2Up(iqSize) 10 val layer1Size = iqSize 11 val layer2Size = iqSize/2 12} 13 14sealed abstract class IQBundle extends XSBundle with IQConst 15sealed abstract class IQModule extends XSModule with IQConst with NeedImpl 16 17sealed class CmpInputBundle extends IQBundle{ 18 val instRdy = Input(Bool()) 19 val roqIdx = Input(UInt(RoqIdxWidth.W)) 20 val iqIdx = Input(UInt(iqIdxWidth.W)) 21} 22 23 24sealed class CompareCircuitUnit(layer: Int = 0, id: Int = 0) extends IQModule { 25 val io = IO(new Bundle(){ 26 val in1 = new CmpInputBundle 27 val in2 = new CmpInputBundle 28 val out = Flipped(new CmpInputBundle) 29 }) 30 31 val roqIdx1 = io.in1.roqIdx 32 val roqIdx2 = io.in2.roqIdx 33 val iqIdx1 = io.in1.iqIdx 34 val iqIdx2 = io.in2.iqIdx 35 36 val inst1Rdy = io.in1.instRdy 37 val inst2Rdy = io.in2.instRdy 38 39 val readySignal = Cat(inst1Rdy,inst2Rdy) 40 41 switch (readySignal) { 42 is ("b00".U) { 43 io.out.instRdy := false.B 44 io.out.roqIdx := DontCare 45 io.out.iqIdx := DontCare 46 } 47 is ("b01".U) { 48 io.out.instRdy := inst2Rdy 49 io.out.roqIdx := roqIdx2 50 io.out.iqIdx := iqIdx2 51 } 52 is ("b10".U) { 53 io.out.instRdy := inst1Rdy 54 io.out.roqIdx := roqIdx1 55 io.out.iqIdx := iqIdx1 56 } 57 is ("b11".U) { 58 when(roqIdx1 < roqIdx2) { 59 io.out.instRdy := inst1Rdy 60 io.out.roqIdx := roqIdx1 61 io.out.iqIdx := iqIdx1 62 } .otherwise { 63 io.out.instRdy := inst2Rdy 64 io.out.roqIdx := roqIdx2 65 io.out.iqIdx := iqIdx2 66 } 67 } 68 } 69 70} 71 72class IssueQueue(val fuTypeInt: BigInt, val wakeupCnt: Int, val bypassCnt: Int) extends IQModule { 73 74 val useBypass = bypassCnt > 0 75 76 val io = IO(new Bundle() { 77 // flush Issue Queue 78 val redirect = Flipped(ValidIO(new Redirect)) 79 80 // enq Ctrl sigs at dispatch-2 81 val enqCtrl = Flipped(DecoupledIO(new MicroOp)) 82 // enq Data at next cycle (regfile has 1 cycle latency) 83 val enqData = Flipped(ValidIO(new ExuInput)) 84 85 // broadcast selected uop to other issue queues which has bypasses 86 val selectedUop = if(useBypass) DecoupledIO(new MicroOp) else null 87 88 // send to exu 89 val deq = DecoupledIO(new ExuInput) 90 91 // listen to write back bus 92 val wakeUpPorts = Vec(wakeupCnt, Flipped(DecoupledIO(new ExuOutput))) 93 94 // use bypass uops to speculative wake-up 95 val bypassUops = if(useBypass) Vec(bypassCnt, Flipped(DecoupledIO(new MicroOp))) else null 96 val bypassData = if(useBypass) Vec(bypassCnt, Flipped(DecoupledIO(new ExuOutput))) else null 97 }) 98 //--------------------------------------------------------- 99 // Issue Queue 100 //--------------------------------------------------------- 101 102 //Tag Queue 103 val ctrlFlow = Mem(iqSize,new CtrlFlow) 104 val ctrlSig = Mem(iqSize,new CtrlSignals) 105 val brMask = RegInit(VecInit(Seq.fill(iqSize)(0.U(BrqSize.W)))) 106 val valid = RegInit(VecInit(Seq.fill(iqSize)(false.B))) 107 val src1Rdy = RegInit(VecInit(Seq.fill(iqSize)(false.B))) 108 val src2Rdy = RegInit(VecInit(Seq.fill(iqSize)(false.B))) 109 val src3Rdy = RegInit(VecInit(Seq.fill(iqSize)(false.B))) 110 val prfSrc1 = Reg(Vec(iqSize, UInt(PhyRegIdxWidth.W))) 111 val prfSrc2 = Reg(Vec(iqSize, UInt(PhyRegIdxWidth.W))) 112 val prfSrc3 = Reg(Vec(iqSize, UInt(PhyRegIdxWidth.W))) 113 val prfDest = Reg(Vec(iqSize, UInt(PhyRegIdxWidth.W))) 114 val oldPDest = Reg(Vec(iqSize, UInt(PhyRegIdxWidth.W))) 115 val freelistAllocPrt = Reg(Vec(iqSize, UInt(PhyRegIdxWidth.W))) 116 val roqIdx = Reg(Vec(iqSize, UInt(RoqIdxWidth.W))) 117 118 val instRdy = WireInit(VecInit(List.tabulate(iqSize)(i => src1Rdy(i) && src2Rdy(i) && valid(i)))) 119 120 121 //tag enqueue 122 val iqEmty = !valid.asUInt.orR 123 val iqFull = valid.asUInt.andR 124 val iqAllowIn = !iqFull 125 io.enqCtrl.ready := iqAllowIn 126 127 //enqueue pointer 128 val emptySlot = ~valid.asUInt 129 val enqueueSelect = PriorityEncoder(emptySlot) 130 131 when(io.enqCtrl.fire()){ 132 ctrlFlow(enqueueSelect) := io.enqCtrl.bits.cf 133 ctrlSig(enqueueSelect) := io.enqCtrl.bits.ctrl 134 brMask(enqueueSelect) := io.enqCtrl.bits.brMask 135 valid(enqueueSelect) := true.B 136 src1Rdy(enqueueSelect) := io.enqCtrl.bits.src1State === SrcState.rdy 137 src2Rdy(enqueueSelect) := io.enqCtrl.bits.src2State === SrcState.rdy 138 src3Rdy(enqueueSelect) := io.enqCtrl.bits.src3State === SrcState.rdy 139 prfSrc1(enqueueSelect) := io.enqCtrl.bits.psrc1 140 prfSrc2(enqueueSelect) := io.enqCtrl.bits.psrc2 141 prfSrc3(enqueueSelect) := io.enqCtrl.bits.psrc3 142 prfDest(enqueueSelect) := io.enqCtrl.bits.pdest 143 oldPDest(enqueueSelect) := io.enqCtrl.bits.old_pdest 144 freelistAllocPrt(enqueueSelect) := io.enqCtrl.bits.freelistAllocPtr 145 roqIdx(enqueueSelect) := io.enqCtrl.bits.roqIdx 146 147 } 148 149 //Data Queue 150 val src1Data = Reg(Vec(iqSize, UInt(XLEN.W))) 151 val src2Data = Reg(Vec(iqSize, UInt(XLEN.W))) 152 val src3Data = Reg(Vec(iqSize, UInt(XLEN.W))) 153 154 val enqSelNext = RegNext(enqueueSelect) 155 val enqFireNext = RegNext(io.enqCtrl.fire()) 156 157 // Read RegFile 158 when (enqFireNext) { 159 src1Data(enqSelNext) := io.enqData.bits.src1 160 src2Data(enqSelNext) := io.enqData.bits.src2 161 src3Data(enqSelNext) := io.enqData.bits.src3 162 } 163 // From Common Data Bus(wakeUpPort) 164 val cdbValid = List.tabulate(wakeupCnt)(i => io.wakeUpPorts(i).valid) 165 val cdbData = List.tabulate(wakeupCnt)(i => io.wakeUpPorts(i).bits.data) 166 val cdbPdest = List.tabulate(wakeupCnt)(i => io.wakeUpPorts(i).bits.uop.pdest) 167 List.tabulate(iqSize)(i => 168 when (valid(i)) { 169 List.tabulate(wakeupCnt)(j => 170 when(!src1Rdy(i) && prfSrc1(i) === cdbPdest(j) && cdbValid(j)) { 171 src1Rdy(i) := true.B 172 src1Data(i) := cdbData(j) 173 } 174 ) 175 List.tabulate(wakeupCnt)(j => 176 when(!src2Rdy(i) && prfSrc2(i) === cdbPdest(j) && cdbValid(j)) { 177 src2Rdy(i) := true.B 178 src2Data(i) := cdbData(j) 179 } 180 ) 181 List.tabulate(wakeupCnt)(j => 182 when(!src3Rdy(i) && prfSrc3(i) === cdbPdest(j) && cdbValid(j)) { 183 src3Rdy(i) := true.B 184 src3Data(i) := cdbData(j) 185 } 186 ) 187 } 188 ) 189 190 // From byPass [speculative] (just for ALU to listen to other ALU's res, include itself) 191 // just need Tag(Ctrl). send out Tag when Tag is decided. other ALUIQ listen to them and decide Tag 192 193 194 //--------------------------------------------------------- 195 // Select Circuit 196 //--------------------------------------------------------- 197 //layer 1 198 val layer1CCUs = (0 until layer1Size by 2) map { i => 199 val CCU_1 = Module(new CompareCircuitUnit(layer = 1, id = i/2)) 200 CCU_1.io.in1.instRdy := instRdy(i) 201 CCU_1.io.in1.roqIdx := roqIdx(i) 202 CCU_1.io.in1.iqIdx := i.U 203 204 CCU_1.io.in2.instRdy := instRdy(i+1) 205 CCU_1.io.in2.roqIdx := roqIdx(i+1) 206 CCU_1.io.in2.iqIdx := (i+1).U 207 208 CCU_1 209 } 210 211 //layer 2 212 val layer2CCUs = (0 until layer2Size by 2) map { i => 213 val CCU_2 = Module(new CompareCircuitUnit(layer = 2, id = i/2)) 214 CCU_2.io.in1.instRdy := layer1CCUs(i).io.out.instRdy 215 CCU_2.io.in1.roqIdx := layer1CCUs(i).io.out.roqIdx 216 CCU_2.io.in1.iqIdx := layer1CCUs(i).io.out.iqIdx 217 218 CCU_2.io.in2.instRdy := layer1CCUs(i+1).io.out.instRdy 219 CCU_2.io.in2.roqIdx := layer1CCUs(i+1).io.out.roqIdx 220 CCU_2.io.in2.iqIdx := layer1CCUs(i+1).io.out.iqIdx 221 222 CCU_2 223 } 224 225 //layer 3 226 val CCU_3 = Module(new CompareCircuitUnit(layer = 3, id = 0)) 227 CCU_3.io.in1.instRdy := layer2CCUs(0).io.out.instRdy 228 CCU_3.io.in1.roqIdx := layer2CCUs(0).io.out.roqIdx 229 CCU_3.io.in1.iqIdx := layer2CCUs(0).io.out.iqIdx 230 231 CCU_3.io.in2.instRdy := layer2CCUs(1).io.out.instRdy 232 CCU_3.io.in2.roqIdx := layer2CCUs(1).io.out.roqIdx 233 CCU_3.io.in2.iqIdx := layer2CCUs(1).io.out.iqIdx 234 235 236 237 238 239 240} 241