xref: /XiangShan/src/main/scala/xiangshan/backend/decode/DecodeUnitComp.scala (revision 3d1a5c10d2fde8e6060376fb66514ec8346a9049)
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 =>
94    dst := cf_ctrl_u
95    dst.ctrl.firstUop := false.B
96    dst.ctrl.lastUop := false.B
97  }
98
99  csBundle(0).ctrl.firstUop := true.B
100  csBundle(numOfUop - 1.U).ctrl.lastUop := true.B
101
102  switch(typeOfDiv) {
103    is(UopDivType.DIR) {
104      when(isVset_u) {
105        csBundle(0).ctrl.flushPipe := ALUOpType.isVsetvli(cf_ctrl_u.ctrl.fuOpType) && cf_ctrl_u.ctrl.lsrc(0).orR
106        csBundle(0).ctrl.fuOpType := ALUOpType.vsetExchange(cf_ctrl_u.ctrl.fuOpType)
107        csBundle(1).ctrl.ldest := 32.U
108        csBundle(1).ctrl.flushPipe := false.B
109      }
110    }
111    is(UopDivType.VEC_LMUL) {
112      for (i <- 0 until 8) {
113        csBundle(i).ctrl.srcType(3) := 0.U
114        csBundle(i).ctrl.lsrc(0) := ctrl_flow.instr(19, 15) + i.U
115        csBundle(i).ctrl.lsrc(1) := ctrl_flow.instr(24, 20) + i.U
116        csBundle(i).ctrl.ldest := ctrl_flow.instr(11, 7) + i.U
117        csBundle(i).ctrl.uopIdx := i.U
118      }
119    }
120    is(UopDivType.VEC_MV) {
121      /*
122      FMV.D.X
123       */
124      csBundle(0).ctrl.srcType(0) := SrcType.reg
125      csBundle(0).ctrl.srcType(1) := SrcType.imm
126      csBundle(0).ctrl.lsrc(1) := 0.U
127      csBundle(0).ctrl.ldest := 33.U
128      csBundle(0).ctrl.fuType := FuType.i2f
129      csBundle(0).ctrl.rfWen := false.B
130      csBundle(0).ctrl.fpWen := true.B
131      csBundle(0).ctrl.vecWen := false.B
132      csBundle(0).ctrl.fpu.isAddSub := false.B
133      csBundle(0).ctrl.fpu.typeTagIn := FPU.D
134      csBundle(0).ctrl.fpu.typeTagOut := FPU.D
135      csBundle(0).ctrl.fpu.fromInt := true.B
136      csBundle(0).ctrl.fpu.wflags := false.B
137      csBundle(0).ctrl.fpu.fpWen := true.B
138      csBundle(0).ctrl.fpu.div := false.B
139      csBundle(0).ctrl.fpu.sqrt := false.B
140      csBundle(0).ctrl.fpu.fcvt := false.B
141      /*
142      vfmv.s.f
143       */
144      csBundle(1).ctrl.srcType(0) := SrcType.fp
145      csBundle(1).ctrl.srcType(1) := SrcType.vp
146      csBundle(1).ctrl.srcType(2) := SrcType.vp
147      csBundle(1).ctrl.lsrc(0) := 33.U
148      csBundle(1).ctrl.lsrc(1) := 0.U
149      csBundle(1).ctrl.lsrc(2) := ctrl_flow.instr(11, 7)
150      csBundle(1).ctrl.ldest := ctrl_flow.instr(11, 7)
151      csBundle(1).ctrl.fuType := FuType.vppu
152      csBundle(1).ctrl.fuOpType := VppuType.f2s
153      csBundle(1).ctrl.rfWen := false.B
154      csBundle(1).ctrl.fpWen := false.B
155      csBundle(1).ctrl.vecWen := true.B
156    }
157    is(UopDivType.VEC_MV_LMUL) {
158      /*
159      FMV.D.X
160       */
161      csBundle(0).ctrl.srcType(0) := SrcType.reg
162      csBundle(0).ctrl.srcType(1) := SrcType.imm
163      csBundle(0).ctrl.lsrc(1) := 0.U
164      csBundle(0).ctrl.ldest := 33.U
165      csBundle(0).ctrl.fuType := FuType.i2f
166      csBundle(0).ctrl.rfWen := false.B
167      csBundle(0).ctrl.fpWen := false.B
168      csBundle(0).ctrl.vecWen := true.B
169      csBundle(0).ctrl.fpu.isAddSub := false.B
170      csBundle(0).ctrl.fpu.typeTagIn := FPU.D
171      csBundle(0).ctrl.fpu.typeTagOut := FPU.D
172      csBundle(0).ctrl.fpu.fromInt := true.B
173      csBundle(0).ctrl.fpu.wflags := false.B
174      csBundle(0).ctrl.fpu.fpWen := false.B
175      csBundle(0).ctrl.fpu.div := false.B
176      csBundle(0).ctrl.fpu.sqrt := false.B
177      csBundle(0).ctrl.fpu.fcvt := false.B
178      /*
179      LMUL
180       */
181      for (i <- 0 until 8) {
182        csBundle(i + 1).ctrl.srcType(0) := SrcType.vp
183        csBundle(i + 1).ctrl.srcType(3) := 0.U
184        csBundle(i + 1).ctrl.lsrc(0) := 33.U
185        csBundle(i + 1).ctrl.lsrc(1) := ctrl_flow.instr(24, 20) + i.U
186        csBundle(i + 1).ctrl.ldest := ctrl_flow.instr(11, 7) + i.U
187        csBundle(i + 1).ctrl.uopIdx := i.U
188      }
189    }
190  }
191
192  //uops dispatch
193  val normal :: ext :: Nil = Enum(2)
194  val stateReg = RegInit(normal)
195  val uopRes = RegInit(0.U)
196
197  //readyFromRename Counter
198  val readyCounter = PriorityMuxDefault(io.readyFromRename.map(x => !x).zip((0 to (RenameWidth - 1)).map(_.U)), RenameWidth.U)
199
200  switch(stateReg) {
201    is(normal) {
202      when(!io.validFromIBuf(0)) {
203        stateReg := normal
204        uopRes := 0.U
205      }.elsewhen((numOfUop > readyCounter) && (readyCounter =/= 0.U)){
206        stateReg := ext
207        uopRes := numOfUop - readyCounter
208      }.otherwise {
209        stateReg := normal
210        uopRes := 0.U
211      }
212    }
213    is(ext) {
214      when(!io.validFromIBuf(0)) {
215        stateReg := normal
216        uopRes := 0.U
217      }.elsewhen(uopRes > readyCounter) {
218        stateReg := ext
219        uopRes := uopRes - readyCounter
220      }.otherwise {
221        stateReg := normal
222        uopRes := 0.U
223      }
224    }
225  }
226
227  for(i <- 0 until RenameWidth) {
228    cf_ctrl(i) := MuxCase(csBundle(i), Seq(
229      (stateReg === normal) -> csBundle(i),
230      (stateReg === ext) -> Mux((i.U + numOfUop -uopRes) < maxNumOfUop.U, csBundle(i.U + numOfUop - uopRes), csBundle(maxNumOfUop - 1))
231    ))
232  }
233
234
235  val validSimple = Wire(Vec(DecodeWidth - 1, Bool()))
236  validSimple.zip(io.validFromIBuf.drop(1).zip(io.isComplex)).map{ case (dst, (src1, src2)) => dst := src1 && !src2 }
237  val notInf = Wire(Vec(DecodeWidth - 1, Bool()))
238  notInf.zip(io.validFromIBuf.drop(1).zip(validSimple)).map{ case (dst, (src1, src2)) => dst := !src1 || src2 }
239  val notInfVec = Wire(Vec(DecodeWidth, Bool()))
240  notInfVec.drop(1).zip(0 until DecodeWidth - 1).map{ case (dst, i) => dst := Cat(notInf.take(i + 1)).andR}
241  notInfVec(0) := true.B
242
243  complexNum := 1.U
244  validToRename.map{ case dst => dst := false.B }
245  readyToIBuf .map{ case dst => dst := false.B }
246  switch(stateReg) {
247    is(normal) {
248      when(!io.validFromIBuf(0)) {
249        complexNum := 1.U
250        validToRename(0) := false.B
251        for (i <- 1 until RenameWidth) {
252          validToRename(i) := notInfVec(i - 1) && validSimple(i - 1)
253        }
254        readyToIBuf(0) := io.readyFromRename(0)
255        for(i <- 1 until DecodeWidth) {
256          readyToIBuf(i) := notInfVec(i - 1) && validSimple(i - 1) && io.readyFromRename(i)
257        }
258      }.elsewhen(numOfUop > readyCounter) {
259        complexNum := Mux(readyCounter === 0.U, 1.U, readyCounter)
260        for (i <- 0 until RenameWidth) {
261          validToRename(i) := Mux(readyCounter > i.U, true.B, false.B)
262        }
263        readyToIBuf.map{ case dst => dst := false.B }
264      }.otherwise {
265        complexNum := numOfUop
266        for (i <- 0 until RenameWidth) {
267          validToRename(i) := Mux(complexNum > i.U, true.B, validSimple(i.U - complexNum) && notInfVec(i.U - complexNum) && io.readyFromRename(i))
268        }
269        readyToIBuf(0) := true.B
270        for (i <- 1 until DecodeWidth) {
271          readyToIBuf(i) := Mux(RenameWidth.U - complexNum >= i.U, notInfVec(i - 1) && validSimple(i - 1) && io.readyFromRename(i), false.B)
272        }
273      }
274    }
275    is(ext) {
276      when(!io.validFromIBuf(0)) {
277        complexNum := 1.U
278        validToRename.map{ case dst => dst := false.B }
279        readyToIBuf.map{ case dst => dst := true.B }
280      }.elsewhen(uopRes > readyCounter) {
281        complexNum := Mux(readyCounter === 0.U, 1.U, readyCounter)
282        for (i <- 0 until RenameWidth) {
283          validToRename(i) := Mux(readyCounter > i.U, true.B, false.B)
284        }
285        readyToIBuf.map{ case dst => dst := false.B }
286      }.otherwise {
287        complexNum := uopRes
288        for (i <- 0 until RenameWidth) {
289          validToRename(i) := Mux(complexNum > i.U, true.B, validSimple(i.U - complexNum) && notInfVec(i.U - complexNum) && io.readyFromRename(i))
290        }
291        readyToIBuf(0) := true.B
292        for (i <- 1 until DecodeWidth) {
293          readyToIBuf(i) := Mux(RenameWidth.U - complexNum >= i.U, notInfVec(i - 1) && validSimple(i - 1) && io.readyFromRename(i), false.B)
294        }
295      }
296    }
297  }
298
299  io.deq.cf_ctrl := cf_ctrl
300  io.deq.isVset := isVset_u
301  io.deq.complexNum := complexNum
302  io.deq.validToRename := validToRename
303  io.deq.readyToIBuf := readyToIBuf
304
305}
306
307