xref: /XiangShan/src/main/scala/xiangshan/backend/issue/IssueQueue.scala (revision 7b95ae632631ca2abe4b1968257f1e5da59e2d1e)
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