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 freechips.rocketchip.rocket.Instructions._ 29 30import scala.collection.Seq 31 32class DecodeUnitCompIO(implicit p: Parameters) extends XSBundle { 33 val enq = new Bundle { val ctrl_flow = Input(new CtrlFlow) } 34 val vconfig = Input(new VConfig) 35 val isComplex = Input(Vec(DecodeWidth - 1, Bool())) 36 val validFromIBuf = Input(Vec(DecodeWidth, Bool())) 37 val readyFromRename = Input(Vec(RenameWidth, Bool())) 38 val deq = new Bundle { 39 val cf_ctrl = Output(Vec(RenameWidth, new CfCtrl)) 40 val isVset = Output(Bool()) 41 val readyToIBuf = Output(Vec(DecodeWidth, Bool())) 42 val validToRename = Output(Vec(RenameWidth, Bool())) 43 val complexNum = Output(UInt(3.W)) 44 } 45 val csrCtrl = Input(new CustomCSRCtrlIO) 46} 47 48class DecodeUnitComp(maxNumOfUop : Int)(implicit p : Parameters) extends XSModule with DecodeUnitConstants { 49 val io = IO(new DecodeUnitCompIO) 50 //input bits 51 val ctrl_flow = Wire(new CtrlFlow) 52 ctrl_flow := io.enq.ctrl_flow 53 //output bits 54 val cf_ctrl = Wire(Vec(RenameWidth, new CfCtrl())) 55 val validToRename = Wire(Vec(RenameWidth, Bool())) 56 val readyToIBuf = Wire(Vec(DecodeWidth, Bool())) 57 val complexNum = Wire(UInt(3.W)) 58 59 //output of DecodeUnit 60 val cf_ctrl_u = Wire(new CfCtrl) 61 val isVset_u = Wire(Bool()) 62 val isComplex_u = Wire(Bool()) 63 64 //pre decode 65 val simple = Module(new DecodeUnit) 66 simple.io.enq.ctrl_flow := ctrl_flow 67 simple.io.vconfig := io.vconfig 68 simple.io.csrCtrl := io.csrCtrl 69 cf_ctrl_u := simple.io.deq.cf_ctrl 70 isVset_u := simple.io.deq.isVset 71 isComplex_u := simple.io.deq.isComplex 72 73 //Type of uop Div 74 val typeOfDiv = cf_ctrl_u.ctrl.uopDivType 75 76 //LMUL 77 val lmul = MuxLookup(simple.io.vconfig.vtype.vlmul, 1.U, Array( 78 "b001".U -> 2.U, 79 "b010".U -> 4.U, 80 "b011".U -> 8.U 81 )) 82 //number of uop 83 val numOfUop = MuxLookup(typeOfDiv, 1.U, Array( 84 UopDivType.DIR -> 2.U, 85 UopDivType.VEC_LMUL -> lmul, 86 UopDivType.VEC_MV_LMUL -> (lmul + 1.U) 87 )) 88 89 //uop div up to maxNumOfUop 90 val csBundle = Wire(Vec(maxNumOfUop, new CfCtrl)) 91 csBundle.map { case dst => dst := cf_ctrl_u } 92 93 switch(typeOfDiv) { 94 is(UopDivType.DIR) { 95 when(isVset_u) { 96 csBundle(0).ctrl.uopIdx := 0.U 97 csBundle(0).ctrl.flushPipe := false.B 98 csBundle(0).ctrl.fuOpType := ALUOpType.vsetExchange(cf_ctrl_u.ctrl.fuOpType) 99 csBundle(1).ctrl.ldest := 32.U 100 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 101 } 102 } 103 is(UopDivType.VEC_LMUL) { 104 for (i <- 0 until 8) { 105 csBundle(i).ctrl.srcType(3) := 0.U 106 csBundle(i).ctrl.lsrc(0) := ctrl_flow.instr(19, 15) + i.U 107 csBundle(i).ctrl.lsrc(1) := ctrl_flow.instr(24, 20) + i.U 108 csBundle(i).ctrl.ldest := ctrl_flow.instr(11, 7) + i.U 109 csBundle(i).ctrl.uopIdx := i.U 110 } 111 csBundle(numOfUop - 1.U).ctrl.uopIdx := "b11111".U 112 } 113 } 114 115 //uops dispatch 116 val normal :: ext :: Nil = Enum(2) 117 val stateReg = RegInit(normal) 118 val uopRes = RegInit(0.U) 119 120 //readyFromRename Counter 121 val readyCounter = PriorityMuxDefault(io.readyFromRename.map(x => !x).zip((0 to (RenameWidth - 1)).map(_.U)), RenameWidth.U) 122 123 switch(stateReg) { 124 is(normal) { 125 when(!io.validFromIBuf(0)) { 126 stateReg := normal 127 uopRes := 0.U 128 }.elsewhen(numOfUop > readyCounter && !readyCounter){ 129 stateReg := ext 130 uopRes := numOfUop - readyCounter 131 }.otherwise { 132 stateReg := normal 133 uopRes := 0.U 134 } 135 } 136 is(ext) { 137 when(!io.validFromIBuf(0)) { 138 stateReg := normal 139 uopRes := 0.U 140 }.elsewhen(uopRes > readyCounter) { 141 stateReg := ext 142 uopRes := uopRes - readyCounter 143 }.otherwise { 144 stateReg := normal 145 uopRes := 0.U 146 } 147 } 148 } 149 150 for(i <- 0 until RenameWidth) { 151 cf_ctrl(i) := MuxCase(csBundle(i), Seq( 152 (stateReg === normal) -> csBundle(i), 153 (stateReg === ext) -> Mux((i.U + numOfUop -uopRes) < maxNumOfUop.U, csBundle(i.U + numOfUop - uopRes), csBundle(maxNumOfUop - 1)) 154 )) 155 } 156 157 158 val validSimple = Wire(Vec(DecodeWidth - 1, Bool())) 159 validSimple.zip(io.validFromIBuf.drop(1).zip(io.isComplex)).map{ case (dst, (src1, src2)) => dst := src1 && !src2 } 160 val notInf = Wire(Vec(DecodeWidth - 1, Bool())) 161 notInf.zip(io.validFromIBuf.drop(1).zip(validSimple)).map{ case (dst, (src1, src2)) => dst := !src1 || src2 } 162 val notInfVec = Wire(Vec(DecodeWidth, Bool())) 163 notInfVec.drop(1).zip(0 until DecodeWidth - 1).map{ case (dst, i) => dst := Cat(notInf.take(i + 1)).andR} 164 notInfVec(0) := true.B 165 166 complexNum := 1.U 167 validToRename.map{ case dst => dst := false.B } 168 readyToIBuf .map{ case dst => dst := false.B } 169 switch(stateReg) { 170 is(normal) { 171 when(!io.validFromIBuf(0)) { 172 complexNum := 1.U 173 validToRename(0) := false.B 174 for (i <- 1 until RenameWidth) { 175 validToRename(i) := notInfVec(i - 1) && validSimple(i - 1) 176 } 177 readyToIBuf(0) := io.readyFromRename(0) 178 for(i <- 1 until DecodeWidth) { 179 readyToIBuf(i) := notInfVec(i - 1) && validSimple(i - 1) && io.readyFromRename(i) 180 } 181 }.elsewhen(numOfUop > readyCounter) { 182 complexNum := Mux(readyCounter === 0.U, 1.U, readyCounter) 183 for (i <- 0 until RenameWidth) { 184 validToRename(i) := Mux(readyCounter > i.U, true.B, false.B) 185 } 186 readyToIBuf.map{ case dst => dst := false.B } 187 }.otherwise { 188 complexNum := numOfUop 189 for (i <- 0 until RenameWidth) { 190 validToRename(i) := Mux(complexNum > i.U, true.B, validSimple(i.U - complexNum) && notInfVec(i.U - complexNum) && io.readyFromRename(i)) 191 } 192 readyToIBuf(0) := true.B 193 for (i <- 1 until DecodeWidth) { 194 readyToIBuf(i) := Mux(RenameWidth.U - complexNum >= i.U, notInfVec(i - 1) && validSimple(i - 1) && io.readyFromRename(i), false.B) 195 } 196 } 197 } 198 is(ext) { 199 when(!io.validFromIBuf(0)) { 200 complexNum := 1.U 201 validToRename.map{ case dst => dst := false.B } 202 readyToIBuf.map{ case dst => dst := true.B } 203 }.elsewhen(uopRes > readyCounter) { 204 complexNum := Mux(readyCounter === 0.U, 1.U, readyCounter) 205 for (i <- 0 until RenameWidth) { 206 validToRename(i) := Mux(readyCounter > i.U, true.B, false.B) 207 } 208 readyToIBuf.map{ case dst => dst := false.B } 209 }.otherwise { 210 complexNum := uopRes 211 for (i <- 0 until RenameWidth) { 212 validToRename(i) := Mux(complexNum > i.U, true.B, validSimple(i.U - complexNum) && notInfVec(i.U - complexNum) && io.readyFromRename(i)) 213 } 214 readyToIBuf(0) := true.B 215 for (i <- 1 until DecodeWidth) { 216 readyToIBuf(i) := Mux(RenameWidth.U - complexNum >= i.U, notInfVec(i - 1) && validSimple(i - 1) && io.readyFromRename(i), false.B) 217 } 218 } 219 } 220 } 221 222 io.deq.cf_ctrl := cf_ctrl 223 io.deq.isVset := isVset_u 224 io.deq.complexNum := complexNum 225 io.deq.validToRename := validToRename 226 io.deq.readyToIBuf := readyToIBuf 227 228} 229 230