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