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