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.mem 18 19import org.chipsalliance.cde.config.Parameters 20import chisel3._ 21import chisel3.util._ 22import utils._ 23import utility._ 24import xiangshan._ 25import xiangshan.backend.rob.RobPtr 26import xiangshan.backend.Bundles._ 27import xiangshan.mem._ 28import xiangshan.backend.fu.vector.Bundles._ 29 30 31class VfofDataBundle(implicit p: Parameters) extends VLSUBundle{ 32 val uop = new DynInst 33 val vl = UInt(elemIdxBits.W) 34} 35 36 37class VfofBuffer(implicit p: Parameters) extends VLSUModule{ 38 val io = IO(new VfofDataBuffIO()) 39 40 val entries = RegInit(0.U.asTypeOf(new VfofDataBundle())) 41 val valid = RegInit(false.B) 42 43 val entriesIsFixVl = entries.uop.vpu.lastUop && entries.uop.vpu.isVleff 44 45 //Enq 46 io.in.map(_.ready := true.B) 47 val enqIsfof = io.in.map { x => 48 x.valid && x.bits.uop.vpu.isVleff 49 } 50 51 val enqValid = enqIsfof.reduce(_ || _) 52 val enqBits = ParallelPriorityMux(enqIsfof, io.in.map(_.bits)) 53 val enqNeedCancel = enqBits.uop.robIdx.needFlush(io.redirect) 54 val enqIsFixVl = enqBits.uop.vpu.isVleff && enqBits.uop.vpu.lastUop 55 56 XSError(entries.uop.robIdx.value =/= enqBits.uop.robIdx.value && valid && enqValid, "There should be no new fof instrction coming in\n") 57 XSError(entriesIsFixVl && valid && enqValid, "A new fof instrction enters when exiting the team\n") 58 59 when(enqValid && !enqNeedCancel) { 60 when(!valid){ 61 entries.uop := enqBits.uop 62 entries.vl := 0.U 63 entries.vuopIdx := 0.U 64 }.elsewhen(valid && enqIsFixVl){ 65 entries.uop := enqBits.uop 66 } 67 } 68 69 //Control Signal 70 val needRedirect = entries.uop.robIdx.needFlush(io.redirect) 71 72 when(enqValid && !enqNeedCancel) { 73 valid := true.B //Enq 74 }.elsewhen(needRedirect) { 75 valid := false.B //Redirect 76 }.elsewhen(io.uopWriteback.fire) { 77 valid := false.B //Deq 78 } 79 80 //Gather writeback information 81 val wbIsfof = io.mergeUopWriteback.map{ x => x.valid && x.bits.uop.robIdx.value === entries.uop.robIdx.value } 82 83 def getOldest(valid: Seq[Bool], bits: Seq[DynInst]): DynInst = { 84 def getOldest_recursion[T <: Data](valid: Seq[Bool], bits: Seq[DynInst]): (Seq[Bool], Seq[DynInst]) = { 85 assert(valid.length == bits.length) 86 if (valid.length == 1) { 87 (valid, bits) 88 } else if (valid.length == 2) { 89 val res = Seq.fill(2)(Wire(ValidIO(chiselTypeOf(bits(0))))) 90 for (i <- res.indices) { 91 res(i).valid := valid(i) 92 res(i).bits := bits(i) 93 } 94 val oldest = Mux( 95 !valid(1) || (bits(1).vpu.vl > bits(0).vpu.vl), 96 res(0), 97 res(1) 98 ) 99 (Seq(oldest.valid), Seq(oldest.bits)) 100 } else { 101 val left = getOldest_recursion(valid.take(valid.length / 2), bits.take(valid.length / 2)) 102 val right = getOldest_recursion(valid.drop(valid.length / 2), bits.drop(valid.length / 2)) 103 getOldest_recursion(left._1 ++ right._1, left._2 ++ right._2) 104 } 105 } 106 getOldest_recursion(valid, bits)._2.head 107 } 108 109 //Update uop vl 110 io.mergeUopWriteback.map{_.ready := true.B} 111 val wbUpdateBits = getOldest(wbIsfof, io.mergeUopWriteback.map(_.bits.uop)) 112 val wbUpdateValid = wbIsfof.reduce(_ || _) && (wbUpdateBits.vpu.vl < entries.vl || !entries.vl.orR) && valid && !needRedirect 113 114 when(wbUpdateValid) { entries.vl := wbUpdateBits.vpu.vl } 115 116 //Deq 117 io.uopWriteback.bits := 0.U.asTypeOf(new MemExuOutput(isVector = true)) 118 io.uopWriteback.bits.uop := entries.uop 119 io.uopWriteback.bits.data := entries.vl 120 io.uopWriteback.bits.uop.vpu.vl := entries.vl 121 io.uopWriteback.bits.mask.get := Fill(VLEN, 1.U) 122 io.uopWriteback.bits.uop.vpu.vmask := Fill(VLEN, 1.U) 123 io.uopWriteback.valid := valid && entries.uop.vpu.lastUop && entries.uop.vpu.isVleff && !needRedirect 124 125 when(io.uopWriteback.fire) { valid := false.B } 126 127} 128