1package xiangshan.backend.issue 2 3import chipsalliance.rocketchip.config.Parameters 4import chisel3._ 5import chisel3.util._ 6import xiangshan._ 7import utils._ 8 9 10class BypassInfo(numWays: Int, dataBits: Int, optBuf: Boolean = false) extends Bundle { 11 val validWidth = (if (optBuf) dataBits else 1) 12 13 val valid = Vec(numWays, UInt(validWidth.W)) 14 val data = UInt(dataBits.W) 15 16 override def cloneType: BypassInfo.this.type = 17 new BypassInfo(numWays, dataBits, optBuf).asInstanceOf[this.type] 18} 19 20class BypassNetworkIO(numWays: Int, numBypass: Int, dataBits: Int) extends Bundle { 21 val hold = Input(Bool()) 22 val source = Vec(numWays, Input(UInt(dataBits.W))) 23 val target = Vec(numWays, Output(UInt(dataBits.W))) 24 val bypass = Vec(numBypass, Input(new BypassInfo(numWays, dataBits))) 25 26 override def cloneType: BypassNetworkIO.this.type = 27 new BypassNetworkIO(numWays, numBypass, dataBits).asInstanceOf[this.type] 28} 29 30class BypassNetwork(numWays: Int, numBypass: Int, dataBits: Int, optBuf: Boolean)(implicit p: Parameters) 31 extends XSModule { 32 val io = IO(new BypassNetworkIO(numWays, numBypass, dataBits)) 33 34 val target_reg = Reg(Vec(numWays, UInt(dataBits.W))) 35 val bypass_reg = Reg(Vec(numBypass, new BypassInfo(numWays, dataBits, optBuf))) 36 37 when (io.hold) { 38 target_reg := io.target 39 if (optBuf) { 40 bypass_reg.map(_.valid.map(_ := 0.U)) 41 } 42 else { 43 bypass_reg.map(_.valid.map(_ := false.B)) 44 } 45 }.otherwise { 46 target_reg := io.source 47 for ((by_reg, by_io) <- bypass_reg.zip(io.bypass)) { 48 by_reg.data := by_io.data 49 if (optBuf) { 50 // duplicate bypass mask to avoid too many FO4s and hurting timing 51 by_reg.valid := VecInit(by_io.valid.map(v => Cat(Seq.fill(dataBits)(v)))) 52 } 53 else { 54 by_reg.valid := by_io.valid 55 } 56 } 57 } 58 59 // bypass data to target 60 for (i <- 0 until numWays) { 61 if (optBuf) { 62 val bypassData = VecInit((0 until dataBits).map(j => { 63 val mask = VecInit(bypass_reg.map(_.valid(i)(j))) 64 Mux(mask.asUInt.orR, Mux1H(mask, bypass_reg.map(_.data(j))), target_reg(i)(j)) 65 })).asUInt 66 io.target(i) := bypassData 67 } 68 else { 69 val mask = VecInit(bypass_reg.map(_.valid(i).asBool)) 70 io.target(i) := Mux(mask.asUInt.orR, Mux1H(mask, bypass_reg.map(_.data)), target_reg(i)) 71 72 XSError(PopCount(mask) > 1.U, p"bypass mask ${Binary(mask.asUInt)} is not one-hot\n") 73 mask.zipWithIndex.map { case (m, j) => 74 XSDebug(mask(j), p"target($i) bypassed from $j:0x${Hexadecimal(bypass_reg(j).data)}\n") 75 } 76 } 77 } 78} 79