1c6d43980SLemover/*************************************************************************************** 2c6d43980SLemover* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3f320e0f0SYinan Xu* Copyright (c) 2020-2021 Peng Cheng Laboratory 4c6d43980SLemover* 5c6d43980SLemover* XiangShan is licensed under Mulan PSL v2. 6c6d43980SLemover* You can use this software according to the terms and conditions of the Mulan PSL v2. 7c6d43980SLemover* You may obtain a copy of Mulan PSL v2 at: 8c6d43980SLemover* http://license.coscl.org.cn/MulanPSL2 9c6d43980SLemover* 10c6d43980SLemover* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11c6d43980SLemover* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12c6d43980SLemover* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13c6d43980SLemover* 14c6d43980SLemover* See the Mulan PSL v2 for more details. 15c6d43980SLemover***************************************************************************************/ 16c6d43980SLemover 175c7674feSYinan Xupackage xiangshan.backend.issue 185c7674feSYinan Xu 19*8891a219SYinan Xuimport org.chipsalliance.cde.config.Parameters 205c7674feSYinan Xuimport chisel3._ 215c7674feSYinan Xuimport chisel3.util._ 225c7674feSYinan Xuimport xiangshan._ 235c7674feSYinan Xuimport utils._ 243c02ee8fSwakafaimport utility._ 255c7674feSYinan Xu 265c7674feSYinan Xu 27605f31fcSYinan Xuclass BypassInfo(numWays: Int, dataBits: Int) extends Bundle { 28605f31fcSYinan Xu val valid = Vec(numWays, Bool()) 295c7674feSYinan Xu val data = UInt(dataBits.W) 305c7674feSYinan Xu} 315c7674feSYinan Xu 325c7674feSYinan Xuclass BypassNetworkIO(numWays: Int, numBypass: Int, dataBits: Int) extends Bundle { 335c7674feSYinan Xu val hold = Input(Bool()) 345c7674feSYinan Xu val source = Vec(numWays, Input(UInt(dataBits.W))) 355c7674feSYinan Xu val target = Vec(numWays, Output(UInt(dataBits.W))) 365c7674feSYinan Xu val bypass = Vec(numBypass, Input(new BypassInfo(numWays, dataBits))) 375c7674feSYinan Xu} 385c7674feSYinan Xu 39605f31fcSYinan Xuclass BypassNetwork(numWays: Int, numBypass: Int, dataBits: Int)(implicit p: Parameters) 405c7674feSYinan Xu extends XSModule { 41605f31fcSYinan Xu 425c7674feSYinan Xu val io = IO(new BypassNetworkIO(numWays, numBypass, dataBits)) 435c7674feSYinan Xu 44605f31fcSYinan Xu def doBypass(bypassValid: Seq[Bool], bypassData: Seq[UInt], baseData: UInt, debugIndex: Int = 0): UInt = { 45605f31fcSYinan Xu val bypassVec = VecInit(bypassValid) 46b56f947eSYinan Xu val target = Mux(bypassVec.asUInt.orR, ParallelMux(bypassValid, bypassData), baseData) 47605f31fcSYinan Xu 48605f31fcSYinan Xu XSError(PopCount(bypassVec) > 1.U, p"bypass mask ${Binary(bypassVec.asUInt)} is not one-hot\n") 49605f31fcSYinan Xu bypassVec.zipWithIndex.map { case (m, i) => 50605f31fcSYinan Xu XSDebug(bypassVec(i), p"target($debugIndex) bypassed from $i:0x${Hexadecimal(bypassData(i))}\n") 51605f31fcSYinan Xu } 52605f31fcSYinan Xu 53605f31fcSYinan Xu target 54605f31fcSYinan Xu } 55605f31fcSYinan Xu 56605f31fcSYinan Xu} 57605f31fcSYinan Xu 58605f31fcSYinan Xu// Bypass at the right: RegNext(data) and compute the bypassed data at the next clock cycle 59605f31fcSYinan Xuclass BypassNetworkRight(numWays: Int, numBypass: Int, dataBits: Int)(implicit p: Parameters) 60605f31fcSYinan Xu extends BypassNetwork(numWays, numBypass, dataBits) { 61605f31fcSYinan Xu 6243d10b70SYinan Xu val last_cycle_hold = RegInit(false.B) 6343d10b70SYinan Xu last_cycle_hold := io.hold 6443d10b70SYinan Xu 655c7674feSYinan Xu val target_reg = Reg(Vec(numWays, UInt(dataBits.W))) 66605f31fcSYinan Xu val bypass_reg = Reg(Vec(numBypass, new BypassInfo(numWays, dataBits))) 675c7674feSYinan Xu 6843d10b70SYinan Xu // When last cycle holds the data, no need to update it. 6943d10b70SYinan Xu when (io.hold && !last_cycle_hold) { 705c7674feSYinan Xu bypass_reg.map(_.valid.map(_ := false.B)) 7143d10b70SYinan Xu target_reg := io.target 7243d10b70SYinan Xu }.elsewhen(!io.hold) { 735c7674feSYinan Xu target_reg := io.source 745c7674feSYinan Xu for ((by_reg, by_io) <- bypass_reg.zip(io.bypass)) { 755c7674feSYinan Xu by_reg.data := by_io.data 765c7674feSYinan Xu by_reg.valid := by_io.valid 775c7674feSYinan Xu } 785c7674feSYinan Xu } 795c7674feSYinan Xu 805c7674feSYinan Xu // bypass data to target 815c7674feSYinan Xu for (i <- 0 until numWays) { 82605f31fcSYinan Xu io.target(i) := doBypass(bypass_reg.map(_.valid(i)), bypass_reg.map(_.data), target_reg(i)) 835c7674feSYinan Xu } 845c7674feSYinan Xu 85605f31fcSYinan Xu} 86605f31fcSYinan Xu 87605f31fcSYinan Xu// Bypass at the left: compute the bypassed data and RegNext(bypassed_data) 88605f31fcSYinan Xuclass BypassNetworkLeft(numWays: Int, numBypass: Int, dataBits: Int)(implicit p: Parameters) 89605f31fcSYinan Xu extends BypassNetwork(numWays, numBypass, dataBits) { 90605f31fcSYinan Xu 91605f31fcSYinan Xu val bypassedData = Reg(io.target.cloneType) 92605f31fcSYinan Xu 93605f31fcSYinan Xu when (!io.hold) { 94605f31fcSYinan Xu for ((by, i) <- bypassedData.zipWithIndex) { 95605f31fcSYinan Xu by := doBypass(io.bypass.map(_.valid(i)), io.bypass.map(_.data), io.source(i)) 965c7674feSYinan Xu } 975c7674feSYinan Xu } 98605f31fcSYinan Xu 99605f31fcSYinan Xu io.target := bypassedData 100605f31fcSYinan Xu 101605f31fcSYinan Xu} 102605f31fcSYinan Xu 103605f31fcSYinan Xuobject BypassNetwork { 10443d10b70SYinan Xu def apply( 10543d10b70SYinan Xu numWays: Int, 10643d10b70SYinan Xu numBypass: Int, 10743d10b70SYinan Xu dataBits: Int, 10843d10b70SYinan Xu optFirstStage: Boolean 10943d10b70SYinan Xu )(implicit p: Parameters): BypassNetwork = { 11043d10b70SYinan Xu if (optFirstStage) { 111605f31fcSYinan Xu Module(new BypassNetworkLeft(numWays, numBypass, dataBits)) 1125c7674feSYinan Xu } 11343d10b70SYinan Xu else { 11443d10b70SYinan Xu Module(new BypassNetworkRight(numWays, numBypass, dataBits)) 11543d10b70SYinan Xu } 11643d10b70SYinan Xu } 1175c7674feSYinan Xu} 118