1*730cfbc0SXuan Hupackage xiangshan.backend.datapath 2*730cfbc0SXuan Hu 3*730cfbc0SXuan Huimport chipsalliance.rocketchip.config.Parameters 4*730cfbc0SXuan Huimport chisel3._ 5*730cfbc0SXuan Huimport chisel3.util._ 6*730cfbc0SXuan Huimport difftest.{DifftestFpWriteback, DifftestIntWriteback} 7*730cfbc0SXuan Huimport xiangshan.backend.BackendParams 8*730cfbc0SXuan Huimport xiangshan.backend.Bundles.{ExuOutput, WriteBackBundle} 9*730cfbc0SXuan Huimport xiangshan.backend.regfile.RfWritePortWithConfig 10*730cfbc0SXuan Huimport xiangshan.{Redirect, XSBundle, XSModule} 11*730cfbc0SXuan Hu 12*730cfbc0SXuan Huclass WbArbiterIO()(implicit p: Parameters, params: WbArbiterParams) extends XSBundle { 13*730cfbc0SXuan Hu val flush = Flipped(ValidIO(new Redirect)) 14*730cfbc0SXuan Hu val in: MixedVec[DecoupledIO[WriteBackBundle]] = Flipped(params.genInput) 15*730cfbc0SXuan Hu val out: MixedVec[ValidIO[WriteBackBundle]] = params.genOutput 16*730cfbc0SXuan Hu 17*730cfbc0SXuan Hu def inGroup: Map[Int, IndexedSeq[DecoupledIO[WriteBackBundle]]] = in.groupBy(_.bits.params.port) 18*730cfbc0SXuan Hu} 19*730cfbc0SXuan Hu 20*730cfbc0SXuan Huclass WbArbiter(params: WbArbiterParams)(implicit p: Parameters) extends XSModule { 21*730cfbc0SXuan Hu val io = IO(new WbArbiterIO()(p, params)) 22*730cfbc0SXuan Hu // Todo: Sorted by priority 23*730cfbc0SXuan Hu private val inGroup: Map[Int, IndexedSeq[DecoupledIO[WriteBackBundle]]] = io.inGroup 24*730cfbc0SXuan Hu 25*730cfbc0SXuan Hu private val arbiters: Seq[Option[Arbiter[WriteBackBundle]]] = Seq.tabulate(params.numOut) { x => { 26*730cfbc0SXuan Hu if (inGroup.contains(x)) { 27*730cfbc0SXuan Hu Some(Module(new Arbiter(new WriteBackBundle(inGroup.values.head.head.bits.params), inGroup(x).length))) 28*730cfbc0SXuan Hu } else { 29*730cfbc0SXuan Hu None 30*730cfbc0SXuan Hu } 31*730cfbc0SXuan Hu }} 32*730cfbc0SXuan Hu 33*730cfbc0SXuan Hu arbiters.zipWithIndex.foreach { case (arb, i) => 34*730cfbc0SXuan Hu if (arb.nonEmpty) { 35*730cfbc0SXuan Hu arb.get.io.in.zip(inGroup(i)).foreach { case (arbIn, wbIn) => 36*730cfbc0SXuan Hu arbIn <> wbIn 37*730cfbc0SXuan Hu } 38*730cfbc0SXuan Hu } 39*730cfbc0SXuan Hu } 40*730cfbc0SXuan Hu 41*730cfbc0SXuan Hu io.out.zip(arbiters).foreach { case (wbOut, arb) => 42*730cfbc0SXuan Hu if (arb.nonEmpty) { 43*730cfbc0SXuan Hu val arbOut = arb.get.io.out 44*730cfbc0SXuan Hu arbOut.ready := true.B 45*730cfbc0SXuan Hu wbOut.valid := arbOut.valid 46*730cfbc0SXuan Hu wbOut.bits := arbOut.bits 47*730cfbc0SXuan Hu } else { 48*730cfbc0SXuan Hu wbOut := 0.U.asTypeOf(wbOut) 49*730cfbc0SXuan Hu } 50*730cfbc0SXuan Hu } 51*730cfbc0SXuan Hu 52*730cfbc0SXuan Hu def getInOutMap: Map[Int, Int] = { 53*730cfbc0SXuan Hu (params.wbCfgs.indices zip params.wbCfgs.map(_.port)).toMap 54*730cfbc0SXuan Hu } 55*730cfbc0SXuan Hu} 56*730cfbc0SXuan Hu 57*730cfbc0SXuan Huclass WbDataPathIO()(implicit p: Parameters, params: BackendParams) extends XSBundle { 58*730cfbc0SXuan Hu val flush = Flipped(ValidIO(new Redirect())) 59*730cfbc0SXuan Hu 60*730cfbc0SXuan Hu val fromTop = new Bundle { 61*730cfbc0SXuan Hu val hartId = Input(UInt(8.W)) 62*730cfbc0SXuan Hu } 63*730cfbc0SXuan Hu 64*730cfbc0SXuan Hu val fromIntExu: MixedVec[MixedVec[DecoupledIO[ExuOutput]]] = Flipped(params.intSchdParams.get.genExuOutputDecoupledBundle) 65*730cfbc0SXuan Hu 66*730cfbc0SXuan Hu val fromVfExu: MixedVec[MixedVec[DecoupledIO[ExuOutput]]] = Flipped(params.vfSchdParams.get.genExuOutputDecoupledBundle) 67*730cfbc0SXuan Hu 68*730cfbc0SXuan Hu val fromMemExu: MixedVec[MixedVec[DecoupledIO[ExuOutput]]] = Flipped(params.memSchdParams.get.genExuOutputDecoupledBundle) 69*730cfbc0SXuan Hu 70*730cfbc0SXuan Hu val toIntPreg = Flipped(MixedVec(Vec(params.intPregParams.numWrite, 71*730cfbc0SXuan Hu new RfWritePortWithConfig(params.intPregParams.dataCfg, params.intPregParams.addrWidth)))) 72*730cfbc0SXuan Hu 73*730cfbc0SXuan Hu val toVfPreg = Flipped(MixedVec(Vec(params.vfPregParams.numWrite, 74*730cfbc0SXuan Hu new RfWritePortWithConfig(params.vfPregParams.dataCfg, params.vfPregParams.addrWidth)))) 75*730cfbc0SXuan Hu 76*730cfbc0SXuan Hu val toCtrlBlock = new Bundle { 77*730cfbc0SXuan Hu val writeback: MixedVec[ValidIO[ExuOutput]] = params.genWrite2CtrlBundles 78*730cfbc0SXuan Hu } 79*730cfbc0SXuan Hu} 80*730cfbc0SXuan Hu 81*730cfbc0SXuan Huclass WbDataPath(params: BackendParams)(implicit p: Parameters) extends XSModule { 82*730cfbc0SXuan Hu val io = IO(new WbDataPathIO()(p, params)) 83*730cfbc0SXuan Hu 84*730cfbc0SXuan Hu // alias 85*730cfbc0SXuan Hu val intArbiterInputs = (io.fromIntExu ++ io.fromVfExu ++ io.fromMemExu).flatten.filter(_.bits.params.writeIntRf) 86*730cfbc0SXuan Hu val vfArbiterInputs = (io.fromIntExu ++ io.fromVfExu ++ io.fromMemExu).flatten.filter(_.bits.params.writeVfRf) 87*730cfbc0SXuan Hu println(s"[WbDataPath] write int preg: " + 88*730cfbc0SXuan Hu s"IntExu(${io.fromIntExu.flatten.count(_.bits.params.writeIntRf)}) " + 89*730cfbc0SXuan Hu s"VfExu(${io.fromVfExu.flatten.count(_.bits.params.writeIntRf)}) " + 90*730cfbc0SXuan Hu s"MemExu(${io.fromMemExu.flatten.count(_.bits.params.writeIntRf)})" 91*730cfbc0SXuan Hu ) 92*730cfbc0SXuan Hu println(s"[WbDataPath] write vf preg: " + 93*730cfbc0SXuan Hu s"IntExu(${io.fromIntExu.flatten.count(_.bits.params.writeVfRf)}) " + 94*730cfbc0SXuan Hu s"VfExu(${io.fromVfExu.flatten.count(_.bits.params.writeVfRf)}) " + 95*730cfbc0SXuan Hu s"MemExu(${io.fromMemExu.flatten.count(_.bits.params.writeVfRf)})" 96*730cfbc0SXuan Hu ) 97*730cfbc0SXuan Hu 98*730cfbc0SXuan Hu // modules 99*730cfbc0SXuan Hu private val intWbArbiter = Module(new WbArbiter(params.getIntWbArbiterParams)) 100*730cfbc0SXuan Hu private val vfWbArbiter = Module(new WbArbiter(params.getVfWbArbiterParams)) 101*730cfbc0SXuan Hu println(s"[WbDataPath] int preg write back port num: ${intWbArbiter.io.out.size}, active port: ${intWbArbiter.io.inGroup.keys.toSeq.sorted}") 102*730cfbc0SXuan Hu println(s"[WbDataPath] vf preg write back port num: ${vfWbArbiter.io.out.size}, active port: ${vfWbArbiter.io.inGroup.keys.toSeq.sorted}") 103*730cfbc0SXuan Hu 104*730cfbc0SXuan Hu // module assign 105*730cfbc0SXuan Hu intWbArbiter.io.flush <> io.flush 106*730cfbc0SXuan Hu require(intWbArbiter.io.in.size == intArbiterInputs.size, s"intWbArbiter input size: ${intWbArbiter.io.in.size}, all vf wb size: ${intArbiterInputs.size}") 107*730cfbc0SXuan Hu intWbArbiter.io.in.zip(intArbiterInputs).foreach { case (arbiterIn, in) => 108*730cfbc0SXuan Hu arbiterIn.valid := in.valid 109*730cfbc0SXuan Hu in.ready := arbiterIn.ready 110*730cfbc0SXuan Hu arbiterIn.bits.fromExuOutput(in.bits) 111*730cfbc0SXuan Hu } 112*730cfbc0SXuan Hu private val intWbArbiterOut = intWbArbiter.io.out 113*730cfbc0SXuan Hu 114*730cfbc0SXuan Hu vfWbArbiter.io.flush <> io.flush 115*730cfbc0SXuan Hu require(vfWbArbiter.io.in.size == vfArbiterInputs.size, s"vfWbArbiter input size: ${vfWbArbiter.io.in.size}, all vf wb size: ${vfArbiterInputs.size}") 116*730cfbc0SXuan Hu vfWbArbiter.io.in.zip(vfArbiterInputs).foreach { case (arbiterIn, in) => 117*730cfbc0SXuan Hu arbiterIn.valid := in.valid 118*730cfbc0SXuan Hu in.ready := arbiterIn.ready 119*730cfbc0SXuan Hu arbiterIn.bits.fromExuOutput(in.bits) 120*730cfbc0SXuan Hu } 121*730cfbc0SXuan Hu 122*730cfbc0SXuan Hu private val vfWbArbiterOut = vfWbArbiter.io.out 123*730cfbc0SXuan Hu 124*730cfbc0SXuan Hu private val intExuInputs = io.fromIntExu.flatten 125*730cfbc0SXuan Hu private val intExuWBs = WireInit(MixedVecInit(io.fromIntExu.flatten)) 126*730cfbc0SXuan Hu private val vfExuInputs = io.fromVfExu.flatten 127*730cfbc0SXuan Hu private val vfExuWBs = WireInit(MixedVecInit(io.fromVfExu.flatten)) 128*730cfbc0SXuan Hu private val memExuInputs = io.fromMemExu.flatten 129*730cfbc0SXuan Hu private val memExuWBs = WireInit(MixedVecInit(io.fromMemExu.flatten)) 130*730cfbc0SXuan Hu 131*730cfbc0SXuan Hu // only fired port can write back to ctrl block 132*730cfbc0SXuan Hu (intExuWBs zip intExuInputs).foreach { case (wb, input) => wb.valid := input.fire } 133*730cfbc0SXuan Hu (vfExuWBs zip vfExuInputs).foreach { case (wb, input) => wb.valid := input.fire } 134*730cfbc0SXuan Hu (memExuWBs zip memExuInputs).foreach { case (wb, input) => wb.valid := input.fire } 135*730cfbc0SXuan Hu 136*730cfbc0SXuan Hu // the ports not writting back pregs are always ready 137*730cfbc0SXuan Hu (intExuInputs ++ vfExuInputs ++ memExuInputs).foreach( x => 138*730cfbc0SXuan Hu if (x.bits.params.hasNoDataWB) x.ready := true.B 139*730cfbc0SXuan Hu ) 140*730cfbc0SXuan Hu 141*730cfbc0SXuan Hu // io assign 142*730cfbc0SXuan Hu private val toIntPreg: MixedVec[RfWritePortWithConfig] = MixedVecInit(intWbArbiterOut.map(x => x.bits.asIntRfWriteBundle(x.fire))) 143*730cfbc0SXuan Hu private val toVfPreg: MixedVec[RfWritePortWithConfig] = MixedVecInit(vfWbArbiterOut.map(x => x.bits.asVfRfWriteBundle(x.fire))) 144*730cfbc0SXuan Hu 145*730cfbc0SXuan Hu private val wb2Ctrl = intExuWBs ++ vfExuWBs ++ memExuWBs 146*730cfbc0SXuan Hu 147*730cfbc0SXuan Hu io.toIntPreg := toIntPreg 148*730cfbc0SXuan Hu io.toVfPreg := toVfPreg 149*730cfbc0SXuan Hu io.toCtrlBlock.writeback.zip(wb2Ctrl).foreach { case (sink, source) => 150*730cfbc0SXuan Hu sink.valid := source.valid 151*730cfbc0SXuan Hu sink.bits := source.bits 152*730cfbc0SXuan Hu source.ready := true.B 153*730cfbc0SXuan Hu } 154*730cfbc0SXuan Hu 155*730cfbc0SXuan Hu if (env.EnableDifftest || env.AlwaysBasicDiff) { 156*730cfbc0SXuan Hu intWbArbiterOut.foreach(out => { 157*730cfbc0SXuan Hu val difftest = Module(new DifftestIntWriteback) 158*730cfbc0SXuan Hu difftest.io.clock := clock 159*730cfbc0SXuan Hu difftest.io.coreid := io.fromTop.hartId 160*730cfbc0SXuan Hu difftest.io.valid := out.fire && out.bits.rfWen 161*730cfbc0SXuan Hu difftest.io.dest := out.bits.pdest 162*730cfbc0SXuan Hu difftest.io.data := out.bits.data 163*730cfbc0SXuan Hu }) 164*730cfbc0SXuan Hu } 165*730cfbc0SXuan Hu 166*730cfbc0SXuan Hu if (env.EnableDifftest || env.AlwaysBasicDiff) { 167*730cfbc0SXuan Hu vfWbArbiterOut.foreach(out => { 168*730cfbc0SXuan Hu val difftest = Module(new DifftestFpWriteback) 169*730cfbc0SXuan Hu difftest.io.clock := clock 170*730cfbc0SXuan Hu difftest.io.coreid := io.fromTop.hartId 171*730cfbc0SXuan Hu difftest.io.valid := out.fire // all fp instr will write fp rf 172*730cfbc0SXuan Hu difftest.io.dest := out.bits.pdest 173*730cfbc0SXuan Hu difftest.io.data := out.bits.data 174*730cfbc0SXuan Hu }) 175*730cfbc0SXuan Hu } 176*730cfbc0SXuan Hu 177*730cfbc0SXuan Hu} 178*730cfbc0SXuan Hu 179*730cfbc0SXuan Hu 180*730cfbc0SXuan Hu 181*730cfbc0SXuan Hu 182