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