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