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