1/*************************************************************************************** 2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3* 4* XiangShan is licensed under Mulan PSL v2. 5* You can use this software according to the terms and conditions of the Mulan PSL v2. 6* You may obtain a copy of Mulan PSL v2 at: 7* http://license.coscl.org.cn/MulanPSL2 8* 9* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12* 13* See the Mulan PSL v2 for more details. 14***************************************************************************************/ 15 16package xiangshan.backend.issue 17 18import chipsalliance.rocketchip.config.Parameters 19import chisel3._ 20import chisel3.util._ 21import xiangshan._ 22import utils._ 23 24 25class BypassInfo(numWays: Int, dataBits: Int, optBuf: Boolean = false) extends Bundle { 26 val validWidth = (if (optBuf) dataBits else 1) 27 28 val valid = Vec(numWays, UInt(validWidth.W)) 29 val data = UInt(dataBits.W) 30 31 override def cloneType: BypassInfo.this.type = 32 new BypassInfo(numWays, dataBits, optBuf).asInstanceOf[this.type] 33} 34 35class BypassNetworkIO(numWays: Int, numBypass: Int, dataBits: Int) extends Bundle { 36 val hold = Input(Bool()) 37 val source = Vec(numWays, Input(UInt(dataBits.W))) 38 val target = Vec(numWays, Output(UInt(dataBits.W))) 39 val bypass = Vec(numBypass, Input(new BypassInfo(numWays, dataBits))) 40 41 override def cloneType: BypassNetworkIO.this.type = 42 new BypassNetworkIO(numWays, numBypass, dataBits).asInstanceOf[this.type] 43} 44 45class BypassNetwork(numWays: Int, numBypass: Int, dataBits: Int, optBuf: Boolean)(implicit p: Parameters) 46 extends XSModule { 47 val io = IO(new BypassNetworkIO(numWays, numBypass, dataBits)) 48 49 val target_reg = Reg(Vec(numWays, UInt(dataBits.W))) 50 val bypass_reg = Reg(Vec(numBypass, new BypassInfo(numWays, dataBits, optBuf))) 51 52 when (io.hold) { 53 target_reg := io.target 54 if (optBuf) { 55 bypass_reg.map(_.valid.map(_ := 0.U)) 56 } 57 else { 58 bypass_reg.map(_.valid.map(_ := false.B)) 59 } 60 }.otherwise { 61 target_reg := io.source 62 for ((by_reg, by_io) <- bypass_reg.zip(io.bypass)) { 63 by_reg.data := by_io.data 64 if (optBuf) { 65 // duplicate bypass mask to avoid too many FO4s and hurting timing 66 by_reg.valid := VecInit(by_io.valid.map(v => Cat(Seq.fill(dataBits)(v)))) 67 } 68 else { 69 by_reg.valid := by_io.valid 70 } 71 } 72 } 73 74 // bypass data to target 75 for (i <- 0 until numWays) { 76 if (optBuf) { 77 val bypassData = VecInit((0 until dataBits).map(j => { 78 val mask = VecInit(bypass_reg.map(_.valid(i)(j))) 79 Mux(mask.asUInt.orR, Mux1H(mask, bypass_reg.map(_.data(j))), target_reg(i)(j)) 80 })).asUInt 81 io.target(i) := bypassData 82 } 83 else { 84 val mask = VecInit(bypass_reg.map(_.valid(i).asBool)) 85 io.target(i) := Mux(mask.asUInt.orR, Mux1H(mask, bypass_reg.map(_.data)), target_reg(i)) 86 87 XSError(PopCount(mask) > 1.U, p"bypass mask ${Binary(mask.asUInt)} is not one-hot\n") 88 mask.zipWithIndex.map { case (m, j) => 89 XSDebug(mask(j), p"target($i) bypassed from $j:0x${Hexadecimal(bypass_reg(j).data)}\n") 90 } 91 } 92 } 93} 94