xref: /XiangShan/src/main/scala/xiangshan/backend/decode/DecodeUnitComp.scala (revision f6e6a3456de9c27becb43cf8a013b2fda9e74f13)
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 xiangshan.backend.fu.fpu.FPU
29import freechips.rocketchip.rocket.Instructions._
30import yunsuan.VppuType
31import scala.collection.Seq
32
33class DecodeUnitCompIO(implicit p: Parameters) extends XSBundle {
34  val enq = new Bundle { val ctrl_flow = Input(new CtrlFlow) }
35  val vconfig = Input(new VConfig)
36  val isComplex = Input(Vec(DecodeWidth - 1, Bool()))
37  val validFromIBuf = Input(Vec(DecodeWidth, Bool()))
38  val readyFromRename = Input(Vec(RenameWidth, Bool()))
39  val deq = new Bundle {
40    val cf_ctrl = Output(Vec(RenameWidth, new CfCtrl))
41    val isVset = Output(Bool())
42    val readyToIBuf = Output(Vec(DecodeWidth, Bool()))
43    val validToRename = Output(Vec(RenameWidth, Bool()))
44    val complexNum = Output(UInt(3.W))
45  }
46  val csrCtrl = Input(new CustomCSRCtrlIO)
47}
48
49class DecodeUnitComp(maxNumOfUop : Int)(implicit p : Parameters) extends XSModule with DecodeUnitConstants {
50  val io = IO(new DecodeUnitCompIO)
51  //input bits
52  val ctrl_flow = Wire(new CtrlFlow)
53  ctrl_flow := io.enq.ctrl_flow
54  //output bits
55  val cf_ctrl = Wire(Vec(RenameWidth, new CfCtrl()))
56  val validToRename = Wire(Vec(RenameWidth, Bool()))
57  val readyToIBuf = Wire(Vec(DecodeWidth, Bool()))
58  val complexNum = Wire(UInt(3.W))
59
60  //output of DecodeUnit
61  val cf_ctrl_u = Wire(new CfCtrl)
62  val isVset_u = Wire(Bool())
63  val isComplex_u = Wire(Bool())
64
65  //pre decode
66  val simple = Module(new DecodeUnit)
67  simple.io.enq.ctrl_flow := ctrl_flow
68  simple.io.vconfig := io.vconfig
69  simple.io.csrCtrl := io.csrCtrl
70  cf_ctrl_u := simple.io.deq.cf_ctrl
71  isVset_u := simple.io.deq.isVset
72  isComplex_u := simple.io.deq.isComplex
73
74  //Type of uop Div
75  val typeOfDiv = cf_ctrl_u.ctrl.uopDivType
76
77  //LMUL
78  val lmul = MuxLookup(simple.io.vconfig.vtype.vlmul, 1.U, Array(
79    "b001".U -> 2.U,
80    "b010".U -> 4.U,
81    "b011".U -> 8.U
82  ))
83  //number of uop
84  val numOfUop = MuxLookup(typeOfDiv, 1.U, Array(
85    UopDivType.VEC_MV -> 2.U,
86    UopDivType.DIR -> 2.U,
87    UopDivType.VEC_LMUL -> lmul,
88    UopDivType.VEC_MV_LMUL -> (lmul + 1.U)
89  ))
90
91  //uop div up to maxNumOfUop
92  val csBundle = Wire(Vec(maxNumOfUop, new CfCtrl))
93  csBundle.map { case dst => dst := cf_ctrl_u }
94
95  switch(typeOfDiv) {
96    is(UopDivType.DIR) {
97      when(isVset_u) {
98        csBundle(0).ctrl.uopIdx.flags := false.B
99        csBundle(0).ctrl.uopIdx.value := 0.U
100        csBundle(0).ctrl.flushPipe := false.B
101        csBundle(0).ctrl.fuOpType := ALUOpType.vsetExchange(cf_ctrl_u.ctrl.fuOpType)
102        csBundle(1).ctrl.ldest := 32.U
103        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
104      }
105    }
106    is(UopDivType.VEC_LMUL) {
107      for (i <- 0 until 8) {
108        csBundle(i).ctrl.srcType(3) := 0.U
109        csBundle(i).ctrl.lsrc(0) := ctrl_flow.instr(19, 15) + i.U
110        csBundle(i).ctrl.lsrc(1) := ctrl_flow.instr(24, 20) + i.U
111        csBundle(i).ctrl.ldest := ctrl_flow.instr(11, 7) + i.U
112        csBundle(i).ctrl.uopIdx.flags := false.B
113        csBundle(i).ctrl.uopIdx.value := i.U
114      }
115      csBundle(numOfUop - 1.U).ctrl.uopIdx.flags := true.B
116    }
117    is(UopDivType.VEC_MV) {
118      /*
119      FMV.D.X
120       */
121      csBundle(0).ctrl.srcType(0) := SrcType.reg
122      csBundle(0).ctrl.srcType(1) := SrcType.imm
123      csBundle(0).ctrl.lsrc(1) := 0.U
124      csBundle(0).ctrl.ldest := 33.U
125      csBundle(0).ctrl.uopIdx.flags := false.B
126      csBundle(0).ctrl.uopIdx.value := 0.U
127      csBundle(0).ctrl.fuType := FuType.i2f
128      csBundle(0).ctrl.rfWen := false.B
129      csBundle(0).ctrl.fpWen := true.B
130      csBundle(0).ctrl.vecWen := false.B
131      csBundle(0).ctrl.fpu.isAddSub := false.B
132      csBundle(0).ctrl.fpu.typeTagIn := FPU.D
133      csBundle(0).ctrl.fpu.typeTagOut := FPU.D
134      csBundle(0).ctrl.fpu.fromInt := true.B
135      csBundle(0).ctrl.fpu.wflags := false.B
136      csBundle(0).ctrl.fpu.fpWen := true.B
137      csBundle(0).ctrl.fpu.div := false.B
138      csBundle(0).ctrl.fpu.sqrt := false.B
139      csBundle(0).ctrl.fpu.fcvt := false.B
140      /*
141      vfmv.s.f
142       */
143      csBundle(1).ctrl.srcType(0) := SrcType.fp
144      csBundle(1).ctrl.srcType(1) := SrcType.vp
145      csBundle(1).ctrl.srcType(2) := SrcType.vp
146      csBundle(1).ctrl.lsrc(0) := 33.U
147      csBundle(1).ctrl.lsrc(1) := 0.U
148      csBundle(1).ctrl.lsrc(2) := ctrl_flow.instr(11, 7)
149      csBundle(1).ctrl.ldest := ctrl_flow.instr(11, 7)
150      csBundle(1).ctrl.uopIdx.flags := true.B
151      csBundle(1).ctrl.uopIdx.value := 1.U
152      csBundle(1).ctrl.fuType := FuType.vppu
153      csBundle(1).ctrl.fuOpType := VppuType.f2s
154      csBundle(1).ctrl.rfWen := false.B
155      csBundle(1).ctrl.fpWen := false.B
156      csBundle(1).ctrl.vecWen := true.B
157    }
158    is(UopDivType.VEC_MV_LMUL) {
159      /*
160      FMV.D.X
161       */
162      csBundle(0).ctrl.srcType(0) := SrcType.reg
163      csBundle(0).ctrl.srcType(1) := SrcType.imm
164      csBundle(0).ctrl.lsrc(1) := 0.U
165      csBundle(0).ctrl.ldest := 33.U
166      csBundle(0).ctrl.uopIdx.flags := false.B
167      csBundle(0).ctrl.uopIdx.value := 0.U
168      csBundle(0).ctrl.fuType := FuType.i2f
169      csBundle(0).ctrl.rfWen := false.B
170      csBundle(0).ctrl.fpWen := false.B
171      csBundle(0).ctrl.vecWen := true.B
172      csBundle(0).ctrl.fpu.isAddSub := false.B
173      csBundle(0).ctrl.fpu.typeTagIn := FPU.D
174      csBundle(0).ctrl.fpu.typeTagOut := FPU.D
175      csBundle(0).ctrl.fpu.fromInt := true.B
176      csBundle(0).ctrl.fpu.wflags := false.B
177      csBundle(0).ctrl.fpu.fpWen := false.B
178      csBundle(0).ctrl.fpu.div := false.B
179      csBundle(0).ctrl.fpu.sqrt := false.B
180      csBundle(0).ctrl.fpu.fcvt := false.B
181      /*
182      LMUL
183       */
184      for (i <- 0 until 8) {
185        csBundle(i + 1).ctrl.srcType(0) := SrcType.vp
186        csBundle(i + 1).ctrl.srcType(3) := 0.U
187        csBundle(i + 1).ctrl.lsrc(0) := 33.U
188        csBundle(i + 1).ctrl.lsrc(1) := ctrl_flow.instr(24, 20) + i.U
189        csBundle(i + 1).ctrl.ldest := ctrl_flow.instr(11, 7) + i.U
190        csBundle(i + 1).ctrl.uopIdx.flags := false.B
191        csBundle(i + 1).ctrl.uopIdx.value := (i + 1).U
192      }
193      csBundle(numOfUop - 1.U).ctrl.uopIdx.flags := true.B
194    }
195  }
196
197  //uops dispatch
198  val normal :: ext :: Nil = Enum(2)
199  val stateReg = RegInit(normal)
200  val uopRes = RegInit(0.U)
201
202  //readyFromRename Counter
203  val readyCounter = PriorityMuxDefault(io.readyFromRename.map(x => !x).zip((0 to (RenameWidth - 1)).map(_.U)), RenameWidth.U)
204
205  switch(stateReg) {
206    is(normal) {
207      when(!io.validFromIBuf(0)) {
208        stateReg := normal
209        uopRes := 0.U
210      }.elsewhen((numOfUop > readyCounter) && (readyCounter =/= 0.U)){
211        stateReg := ext
212        uopRes := numOfUop - readyCounter
213      }.otherwise {
214        stateReg := normal
215        uopRes := 0.U
216      }
217    }
218    is(ext) {
219      when(!io.validFromIBuf(0)) {
220        stateReg := normal
221        uopRes := 0.U
222      }.elsewhen(uopRes > readyCounter) {
223        stateReg := ext
224        uopRes := uopRes - readyCounter
225      }.otherwise {
226        stateReg := normal
227        uopRes := 0.U
228      }
229    }
230  }
231
232  for(i <- 0 until RenameWidth) {
233    cf_ctrl(i) := MuxCase(csBundle(i), Seq(
234      (stateReg === normal) -> csBundle(i),
235      (stateReg === ext) -> Mux((i.U + numOfUop -uopRes) < maxNumOfUop.U, csBundle(i.U + numOfUop - uopRes), csBundle(maxNumOfUop - 1))
236    ))
237  }
238
239
240  val validSimple = Wire(Vec(DecodeWidth - 1, Bool()))
241  validSimple.zip(io.validFromIBuf.drop(1).zip(io.isComplex)).map{ case (dst, (src1, src2)) => dst := src1 && !src2 }
242  val notInf = Wire(Vec(DecodeWidth - 1, Bool()))
243  notInf.zip(io.validFromIBuf.drop(1).zip(validSimple)).map{ case (dst, (src1, src2)) => dst := !src1 || src2 }
244  val notInfVec = Wire(Vec(DecodeWidth, Bool()))
245  notInfVec.drop(1).zip(0 until DecodeWidth - 1).map{ case (dst, i) => dst := Cat(notInf.take(i + 1)).andR}
246  notInfVec(0) := true.B
247
248  complexNum := 1.U
249  validToRename.map{ case dst => dst := false.B }
250  readyToIBuf .map{ case dst => dst := false.B }
251  switch(stateReg) {
252    is(normal) {
253      when(!io.validFromIBuf(0)) {
254        complexNum := 1.U
255        validToRename(0) := false.B
256        for (i <- 1 until RenameWidth) {
257          validToRename(i) := notInfVec(i - 1) && validSimple(i - 1)
258        }
259        readyToIBuf(0) := io.readyFromRename(0)
260        for(i <- 1 until DecodeWidth) {
261          readyToIBuf(i) := notInfVec(i - 1) && validSimple(i - 1) && io.readyFromRename(i)
262        }
263      }.elsewhen(numOfUop > readyCounter) {
264        complexNum := Mux(readyCounter === 0.U, 1.U, readyCounter)
265        for (i <- 0 until RenameWidth) {
266          validToRename(i) := Mux(readyCounter > i.U, true.B, false.B)
267        }
268        readyToIBuf.map{ case dst => dst := false.B }
269      }.otherwise {
270        complexNum := numOfUop
271        for (i <- 0 until RenameWidth) {
272          validToRename(i) := Mux(complexNum > i.U, true.B, validSimple(i.U - complexNum) && notInfVec(i.U - complexNum) && io.readyFromRename(i))
273        }
274        readyToIBuf(0) := true.B
275        for (i <- 1 until DecodeWidth) {
276          readyToIBuf(i) := Mux(RenameWidth.U - complexNum >= i.U, notInfVec(i - 1) && validSimple(i - 1) && io.readyFromRename(i), false.B)
277        }
278      }
279    }
280    is(ext) {
281      when(!io.validFromIBuf(0)) {
282        complexNum := 1.U
283        validToRename.map{ case dst => dst := false.B }
284        readyToIBuf.map{ case dst => dst := true.B }
285      }.elsewhen(uopRes > readyCounter) {
286        complexNum := Mux(readyCounter === 0.U, 1.U, readyCounter)
287        for (i <- 0 until RenameWidth) {
288          validToRename(i) := Mux(readyCounter > i.U, true.B, false.B)
289        }
290        readyToIBuf.map{ case dst => dst := false.B }
291      }.otherwise {
292        complexNum := uopRes
293        for (i <- 0 until RenameWidth) {
294          validToRename(i) := Mux(complexNum > i.U, true.B, validSimple(i.U - complexNum) && notInfVec(i.U - complexNum) && io.readyFromRename(i))
295        }
296        readyToIBuf(0) := true.B
297        for (i <- 1 until DecodeWidth) {
298          readyToIBuf(i) := Mux(RenameWidth.U - complexNum >= i.U, notInfVec(i - 1) && validSimple(i - 1) && io.readyFromRename(i), false.B)
299        }
300      }
301    }
302  }
303
304  io.deq.cf_ctrl := cf_ctrl
305  io.deq.isVset := isVset_u
306  io.deq.complexNum := complexNum
307  io.deq.validToRename := validToRename
308  io.deq.readyToIBuf := readyToIBuf
309
310}
311
312