xref: /XiangShan/src/main/scala/xiangshan/backend/decode/DecodeUnitComp.scala (revision 822120df13d14b93718f77e176868bc9ef203df2)
1/***************************************************************************************
2  * Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3  * Copyright (c) 2020-2021 Peng Cheng Laboratory
4  *
5  * XiangShan is licensed under Mulan PSL v2.
6  * You can use this software according to the terms and conditions of the Mulan PSL v2.
7  * You may obtain a copy of Mulan PSL v2 at:
8  *          http://license.coscl.org.cn/MulanPSL2
9  *
10  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13  *
14  * See the Mulan PSL v2 for more details.
15  ***************************************************************************************/
16
17package xiangshan.backend.decode
18
19import chipsalliance.rocketchip.config.Parameters
20import chisel3._
21import chisel3.util._
22import freechips.rocketchip.rocket.Instructions
23import freechips.rocketchip.util.uintToBitPat
24import utils._
25import utility._
26import xiangshan.ExceptionNO.illegalInstr
27import xiangshan._
28import freechips.rocketchip.rocket.Instructions._
29
30import scala.collection.Seq
31
32class DecodeUnitCompIO(implicit p: Parameters) extends XSBundle {
33  val enq = new Bundle { val ctrl_flow = Input(new CtrlFlow) }
34  val vconfig = Input(new VConfig)
35  val isComplex = Input(Vec(DecodeWidth - 1, Bool()))
36  val validFromIBuf = Input(Vec(DecodeWidth, Bool()))
37  val readyFromRename = Input(Vec(RenameWidth, Bool()))
38  val deq = new Bundle {
39    val cf_ctrl = Output(Vec(RenameWidth, new CfCtrl))
40    val isVset = Output(Bool())
41    val readyToIBuf = Output(Vec(DecodeWidth, Bool()))
42    val validToRename = Output(Vec(RenameWidth, Bool()))
43    val complexNum = Output(UInt(3.W))
44  }
45  val csrCtrl = Input(new CustomCSRCtrlIO)
46}
47
48class DecodeUnitComp(maxNumOfUop : Int)(implicit p : Parameters) extends XSModule with DecodeUnitConstants {
49  val io = IO(new DecodeUnitCompIO)
50  //input bits
51  val ctrl_flow = Wire(new CtrlFlow)
52  ctrl_flow := io.enq.ctrl_flow
53  //output bits
54  val cf_ctrl = Wire(Vec(RenameWidth, new CfCtrl()))
55  val validToRename = Wire(Vec(RenameWidth, Bool()))
56  val readyToIBuf = Wire(Vec(DecodeWidth, Bool()))
57  val complexNum = Wire(UInt(3.W))
58
59  //output of DecodeUnit
60  val cf_ctrl_u = Wire(new CfCtrl)
61  val isVset_u = Wire(Bool())
62  val isComplex_u = Wire(Bool())
63
64  //pre decode
65  val simple = Module(new DecodeUnit)
66  simple.io.enq.ctrl_flow := ctrl_flow
67  simple.io.vconfig := io.vconfig
68  simple.io.csrCtrl := io.csrCtrl
69  cf_ctrl_u := simple.io.deq.cf_ctrl
70  isVset_u := simple.io.deq.isVset
71  isComplex_u := simple.io.deq.isComplex
72
73  //Type of uop Div
74  val typeOfDiv = cf_ctrl_u.ctrl.uopDivType
75
76  //LMUL
77  val lmul = MuxLookup(simple.io.vconfig.vtype.vlmul, 1.U, Array(
78    "b001".U -> 2.U,
79    "b010".U -> 4.U,
80    "b011".U -> 8.U
81  ))
82  //number of uop
83  val numOfUop = MuxLookup(typeOfDiv, 1.U, Array(
84    UopDivType.DIR -> 2.U,
85    UopDivType.VEC_LMUL -> lmul,
86    UopDivType.VEC_MV_LMUL -> (lmul + 1.U)
87  ))
88
89  //uop div up to maxNumOfUop
90  val csBundle = Wire(Vec(maxNumOfUop, new CfCtrl))
91  csBundle.map { case dst => dst := cf_ctrl_u }
92
93  switch(typeOfDiv) {
94    is(UopDivType.DIR) {
95      when(isVset_u) {
96        csBundle(0).ctrl.uopIdx := 0.U
97        csBundle(0).ctrl.flushPipe := false.B
98        csBundle(0).ctrl.fuOpType := ALUOpType.vsetExchange(cf_ctrl_u.ctrl.fuOpType)
99        csBundle(1).ctrl.ldest := 32.U
100        csBundle(1).ctrl.flushPipe := FuType.isIntExu(cf_ctrl_u.ctrl.fuType) && ALUOpType.isVsetvli(cf_ctrl_u.ctrl.fuOpType) && cf_ctrl_u.ctrl.lsrc(0).orR
101      }
102    }
103    is(UopDivType.VEC_LMUL) {
104      for (i <- 0 until 8) {
105        csBundle(i).ctrl.srcType(3) := 0.U
106        csBundle(i).ctrl.lsrc(0) := ctrl_flow.instr(19, 15) + i.U
107        csBundle(i).ctrl.lsrc(1) := ctrl_flow.instr(24, 20) + i.U
108        csBundle(i).ctrl.ldest := ctrl_flow.instr(11, 7) + i.U
109        csBundle(i).ctrl.uopIdx := i.U
110      }
111      csBundle(numOfUop - 1.U).ctrl.uopIdx := "b11111".U
112    }
113  }
114
115  //uops dispatch
116  val normal :: ext :: Nil = Enum(2)
117  val stateReg = RegInit(normal)
118  val uopRes = RegInit(0.U)
119
120  //readyFromRename Counter
121  val readyCounter = PriorityMuxDefault(io.readyFromRename.map(x => !x).zip((0 to (RenameWidth - 1)).map(_.U)), RenameWidth.U)
122
123  switch(stateReg) {
124    is(normal) {
125      when(!io.validFromIBuf(0)) {
126        stateReg := normal
127        uopRes := 0.U
128      }.elsewhen(numOfUop > readyCounter && !readyCounter){
129        stateReg := ext
130        uopRes := numOfUop - readyCounter
131      }.otherwise {
132        stateReg := normal
133        uopRes := 0.U
134      }
135    }
136    is(ext) {
137      when(!io.validFromIBuf(0)) {
138        stateReg := normal
139        uopRes := 0.U
140      }.elsewhen(uopRes > readyCounter) {
141        stateReg := ext
142        uopRes := uopRes - readyCounter
143      }.otherwise {
144        stateReg := normal
145        uopRes := 0.U
146      }
147    }
148  }
149
150  for(i <- 0 until RenameWidth) {
151    cf_ctrl(i) := MuxCase(csBundle(i), Seq(
152      (stateReg === normal) -> csBundle(i),
153      (stateReg === ext) -> Mux((i.U + numOfUop -uopRes) < maxNumOfUop.U, csBundle(i.U + numOfUop - uopRes), csBundle(maxNumOfUop - 1))
154    ))
155  }
156
157
158  val validSimple = Wire(Vec(DecodeWidth - 1, Bool()))
159  validSimple.zip(io.validFromIBuf.drop(1).zip(io.isComplex)).map{ case (dst, (src1, src2)) => dst := src1 && !src2 }
160  val notInf = Wire(Vec(DecodeWidth - 1, Bool()))
161  notInf.zip(io.validFromIBuf.drop(1).zip(validSimple)).map{ case (dst, (src1, src2)) => dst := !src1 || src2 }
162  val notInfVec = Wire(Vec(DecodeWidth, Bool()))
163  notInfVec.drop(1).zip(0 until DecodeWidth - 1).map{ case (dst, i) => dst := Cat(notInf.take(i + 1)).andR}
164  notInfVec(0) := true.B
165
166  complexNum := 1.U
167  validToRename.map{ case dst => dst := false.B }
168  readyToIBuf .map{ case dst => dst := false.B }
169  switch(stateReg) {
170    is(normal) {
171      when(!io.validFromIBuf(0)) {
172        complexNum := 1.U
173        validToRename(0) := false.B
174        for (i <- 1 until RenameWidth) {
175          validToRename(i) := notInfVec(i - 1) && validSimple(i - 1)
176        }
177        readyToIBuf(0) := io.readyFromRename(0)
178        for(i <- 1 until DecodeWidth) {
179          readyToIBuf(i) := notInfVec(i - 1) && validSimple(i - 1) && io.readyFromRename(i)
180        }
181      }.elsewhen(numOfUop > readyCounter) {
182        complexNum := Mux(readyCounter === 0.U, 1.U, readyCounter)
183        for (i <- 0 until RenameWidth) {
184          validToRename(i) := Mux(readyCounter > i.U, true.B, false.B)
185        }
186        readyToIBuf.map{ case dst => dst := false.B }
187      }.otherwise {
188        complexNum := numOfUop
189        for (i <- 0 until RenameWidth) {
190          validToRename(i) := Mux(complexNum > i.U, true.B, validSimple(i.U - complexNum) && notInfVec(i.U - complexNum) && io.readyFromRename(i))
191        }
192        readyToIBuf(0) := true.B
193        for (i <- 1 until DecodeWidth) {
194          readyToIBuf(i) := Mux(RenameWidth.U - complexNum >= i.U, notInfVec(i - 1) && validSimple(i - 1) && io.readyFromRename(i), false.B)
195        }
196      }
197    }
198    is(ext) {
199      when(!io.validFromIBuf(0)) {
200        complexNum := 1.U
201        validToRename.map{ case dst => dst := false.B }
202        readyToIBuf.map{ case dst => dst := true.B }
203      }.elsewhen(uopRes > readyCounter) {
204        complexNum := Mux(readyCounter === 0.U, 1.U, readyCounter)
205        for (i <- 0 until RenameWidth) {
206          validToRename(i) := Mux(readyCounter > i.U, true.B, false.B)
207        }
208        readyToIBuf.map{ case dst => dst := false.B }
209      }.otherwise {
210        complexNum := uopRes
211        for (i <- 0 until RenameWidth) {
212          validToRename(i) := Mux(complexNum > i.U, true.B, validSimple(i.U - complexNum) && notInfVec(i.U - complexNum) && io.readyFromRename(i))
213        }
214        readyToIBuf(0) := true.B
215        for (i <- 1 until DecodeWidth) {
216          readyToIBuf(i) := Mux(RenameWidth.U - complexNum >= i.U, notInfVec(i - 1) && validSimple(i - 1) && io.readyFromRename(i), false.B)
217        }
218      }
219    }
220  }
221
222  io.deq.cf_ctrl := cf_ctrl
223  io.deq.isVset := isVset_u
224  io.deq.complexNum := complexNum
225  io.deq.validToRename := validToRename
226  io.deq.readyToIBuf := readyToIBuf
227
228}
229
230