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