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 + 2.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 := true.B 166 csBundle(0).ctrl.vecWen := false.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 := true.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 vfmv.s.f 178 */ 179 csBundle(1).ctrl.srcType(0) := SrcType.fp 180 csBundle(1).ctrl.srcType(1) := SrcType.vp 181 csBundle(1).ctrl.srcType(2) := SrcType.vp 182 csBundle(1).ctrl.lsrc(0) := 33.U 183 csBundle(1).ctrl.lsrc(1) := 0.U 184 csBundle(1).ctrl.lsrc(2) := 33.U 185 csBundle(1).ctrl.ldest := 33.U 186 csBundle(1).ctrl.uopIdx := 1.U 187 csBundle(1).ctrl.fuType := FuType.vppu 188 csBundle(1).ctrl.fuOpType := VppuType.f2s 189 csBundle(1).ctrl.rfWen := false.B 190 csBundle(1).ctrl.fpWen := false.B 191 csBundle(1).ctrl.vecWen := true.B 192 /* 193 LMUL 194 */ 195 for (i <- 0 until 8) { 196 csBundle(i + 2).ctrl.srcType(0) := SrcType.vp 197 csBundle(i + 2).ctrl.srcType(3) := 0.U 198 csBundle(i + 2).ctrl.lsrc(0) := 33.U 199 csBundle(i + 2).ctrl.lsrc(1) := ctrl_flow.instr(24, 20) + i.U 200 csBundle(i + 2).ctrl.ldest := ctrl_flow.instr(11, 7) + i.U 201 csBundle(i + 2).ctrl.uopIdx := (i + 2).U 202 } 203 csBundle(numOfUop - 1.U).ctrl.uopIdx := "b11111".U 204 } 205 } 206 207 //uops dispatch 208 val normal :: ext :: Nil = Enum(2) 209 val stateReg = RegInit(normal) 210 val uopRes = RegInit(0.U) 211 212 //readyFromRename Counter 213 val readyCounter = PriorityMuxDefault(io.readyFromRename.map(x => !x).zip((0 to (RenameWidth - 1)).map(_.U)), RenameWidth.U) 214 215 switch(stateReg) { 216 is(normal) { 217 when(!io.validFromIBuf(0)) { 218 stateReg := normal 219 uopRes := 0.U 220 }.elsewhen(numOfUop > readyCounter && !readyCounter){ 221 stateReg := ext 222 uopRes := numOfUop - readyCounter 223 }.otherwise { 224 stateReg := normal 225 uopRes := 0.U 226 } 227 } 228 is(ext) { 229 when(!io.validFromIBuf(0)) { 230 stateReg := normal 231 uopRes := 0.U 232 }.elsewhen(uopRes > readyCounter) { 233 stateReg := ext 234 uopRes := uopRes - readyCounter 235 }.otherwise { 236 stateReg := normal 237 uopRes := 0.U 238 } 239 } 240 } 241 242 for(i <- 0 until RenameWidth) { 243 cf_ctrl(i) := MuxCase(csBundle(i), Seq( 244 (stateReg === normal) -> csBundle(i), 245 (stateReg === ext) -> Mux((i.U + numOfUop -uopRes) < maxNumOfUop.U, csBundle(i.U + numOfUop - uopRes), csBundle(maxNumOfUop - 1)) 246 )) 247 } 248 249 250 val validSimple = Wire(Vec(DecodeWidth - 1, Bool())) 251 validSimple.zip(io.validFromIBuf.drop(1).zip(io.isComplex)).map{ case (dst, (src1, src2)) => dst := src1 && !src2 } 252 val notInf = Wire(Vec(DecodeWidth - 1, Bool())) 253 notInf.zip(io.validFromIBuf.drop(1).zip(validSimple)).map{ case (dst, (src1, src2)) => dst := !src1 || src2 } 254 val notInfVec = Wire(Vec(DecodeWidth, Bool())) 255 notInfVec.drop(1).zip(0 until DecodeWidth - 1).map{ case (dst, i) => dst := Cat(notInf.take(i + 1)).andR} 256 notInfVec(0) := true.B 257 258 complexNum := 1.U 259 validToRename.map{ case dst => dst := false.B } 260 readyToIBuf .map{ case dst => dst := false.B } 261 switch(stateReg) { 262 is(normal) { 263 when(!io.validFromIBuf(0)) { 264 complexNum := 1.U 265 validToRename(0) := false.B 266 for (i <- 1 until RenameWidth) { 267 validToRename(i) := notInfVec(i - 1) && validSimple(i - 1) 268 } 269 readyToIBuf(0) := io.readyFromRename(0) 270 for(i <- 1 until DecodeWidth) { 271 readyToIBuf(i) := notInfVec(i - 1) && validSimple(i - 1) && io.readyFromRename(i) 272 } 273 }.elsewhen(numOfUop > readyCounter) { 274 complexNum := Mux(readyCounter === 0.U, 1.U, readyCounter) 275 for (i <- 0 until RenameWidth) { 276 validToRename(i) := Mux(readyCounter > i.U, true.B, false.B) 277 } 278 readyToIBuf.map{ case dst => dst := false.B } 279 }.otherwise { 280 complexNum := numOfUop 281 for (i <- 0 until RenameWidth) { 282 validToRename(i) := Mux(complexNum > i.U, true.B, validSimple(i.U - complexNum) && notInfVec(i.U - complexNum) && io.readyFromRename(i)) 283 } 284 readyToIBuf(0) := true.B 285 for (i <- 1 until DecodeWidth) { 286 readyToIBuf(i) := Mux(RenameWidth.U - complexNum >= i.U, notInfVec(i - 1) && validSimple(i - 1) && io.readyFromRename(i), false.B) 287 } 288 } 289 } 290 is(ext) { 291 when(!io.validFromIBuf(0)) { 292 complexNum := 1.U 293 validToRename.map{ case dst => dst := false.B } 294 readyToIBuf.map{ case dst => dst := true.B } 295 }.elsewhen(uopRes > readyCounter) { 296 complexNum := Mux(readyCounter === 0.U, 1.U, readyCounter) 297 for (i <- 0 until RenameWidth) { 298 validToRename(i) := Mux(readyCounter > i.U, true.B, false.B) 299 } 300 readyToIBuf.map{ case dst => dst := false.B } 301 }.otherwise { 302 complexNum := uopRes 303 for (i <- 0 until RenameWidth) { 304 validToRename(i) := Mux(complexNum > i.U, true.B, validSimple(i.U - complexNum) && notInfVec(i.U - complexNum) && io.readyFromRename(i)) 305 } 306 readyToIBuf(0) := true.B 307 for (i <- 1 until DecodeWidth) { 308 readyToIBuf(i) := Mux(RenameWidth.U - complexNum >= i.U, notInfVec(i - 1) && validSimple(i - 1) && io.readyFromRename(i), false.B) 309 } 310 } 311 } 312 } 313 314 io.deq.cf_ctrl := cf_ctrl 315 io.deq.isVset := isVset_u 316 io.deq.complexNum := complexNum 317 io.deq.validToRename := validToRename 318 io.deq.readyToIBuf := readyToIBuf 319 320} 321 322