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