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