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