1730cfbc0SXuan Hupackage xiangshan.backend.datapath 2730cfbc0SXuan Hu 3730cfbc0SXuan Huimport chipsalliance.rocketchip.config.Parameters 4730cfbc0SXuan Huimport chisel3._ 5730cfbc0SXuan Huimport chisel3.util._ 6730cfbc0SXuan Huimport difftest.{DifftestFpWriteback, DifftestIntWriteback} 7730cfbc0SXuan Huimport xiangshan.backend.BackendParams 8730cfbc0SXuan Huimport xiangshan.backend.Bundles.{ExuOutput, WriteBackBundle} 9730cfbc0SXuan Huimport xiangshan.backend.regfile.RfWritePortWithConfig 10730cfbc0SXuan Huimport xiangshan.{Redirect, XSBundle, XSModule} 11730cfbc0SXuan Hu 12730cfbc0SXuan Huclass WbArbiterIO()(implicit p: Parameters, params: WbArbiterParams) extends XSBundle { 13730cfbc0SXuan Hu val flush = Flipped(ValidIO(new Redirect)) 14730cfbc0SXuan Hu val in: MixedVec[DecoupledIO[WriteBackBundle]] = Flipped(params.genInput) 15730cfbc0SXuan Hu val out: MixedVec[ValidIO[WriteBackBundle]] = params.genOutput 16730cfbc0SXuan Hu 17730cfbc0SXuan Hu def inGroup: Map[Int, IndexedSeq[DecoupledIO[WriteBackBundle]]] = in.groupBy(_.bits.params.port) 18730cfbc0SXuan Hu} 19730cfbc0SXuan Hu 20730cfbc0SXuan Huclass WbArbiter(params: WbArbiterParams)(implicit p: Parameters) extends XSModule { 21730cfbc0SXuan Hu val io = IO(new WbArbiterIO()(p, params)) 22730cfbc0SXuan Hu // Todo: Sorted by priority 23730cfbc0SXuan Hu private val inGroup: Map[Int, IndexedSeq[DecoupledIO[WriteBackBundle]]] = io.inGroup 24730cfbc0SXuan Hu 25730cfbc0SXuan Hu private val arbiters: Seq[Option[Arbiter[WriteBackBundle]]] = Seq.tabulate(params.numOut) { x => { 26730cfbc0SXuan Hu if (inGroup.contains(x)) { 27730cfbc0SXuan Hu Some(Module(new Arbiter(new WriteBackBundle(inGroup.values.head.head.bits.params), inGroup(x).length))) 28730cfbc0SXuan Hu } else { 29730cfbc0SXuan Hu None 30730cfbc0SXuan Hu } 31730cfbc0SXuan Hu }} 32730cfbc0SXuan Hu 33730cfbc0SXuan Hu arbiters.zipWithIndex.foreach { case (arb, i) => 34730cfbc0SXuan Hu if (arb.nonEmpty) { 35730cfbc0SXuan Hu arb.get.io.in.zip(inGroup(i)).foreach { case (arbIn, wbIn) => 36730cfbc0SXuan Hu arbIn <> wbIn 37730cfbc0SXuan Hu } 38730cfbc0SXuan Hu } 39730cfbc0SXuan Hu } 40730cfbc0SXuan Hu 41730cfbc0SXuan Hu io.out.zip(arbiters).foreach { case (wbOut, arb) => 42730cfbc0SXuan Hu if (arb.nonEmpty) { 43730cfbc0SXuan Hu val arbOut = arb.get.io.out 44730cfbc0SXuan Hu arbOut.ready := true.B 45730cfbc0SXuan Hu wbOut.valid := arbOut.valid 46730cfbc0SXuan Hu wbOut.bits := arbOut.bits 47730cfbc0SXuan Hu } else { 48730cfbc0SXuan Hu wbOut := 0.U.asTypeOf(wbOut) 49730cfbc0SXuan Hu } 50730cfbc0SXuan Hu } 51730cfbc0SXuan Hu 52730cfbc0SXuan Hu def getInOutMap: Map[Int, Int] = { 53730cfbc0SXuan Hu (params.wbCfgs.indices zip params.wbCfgs.map(_.port)).toMap 54730cfbc0SXuan Hu } 55730cfbc0SXuan Hu} 56730cfbc0SXuan Hu 57730cfbc0SXuan Huclass WbDataPathIO()(implicit p: Parameters, params: BackendParams) extends XSBundle { 58730cfbc0SXuan Hu val flush = Flipped(ValidIO(new Redirect())) 59730cfbc0SXuan Hu 60730cfbc0SXuan Hu val fromTop = new Bundle { 61730cfbc0SXuan Hu val hartId = Input(UInt(8.W)) 62730cfbc0SXuan Hu } 63730cfbc0SXuan Hu 64730cfbc0SXuan Hu val fromIntExu: MixedVec[MixedVec[DecoupledIO[ExuOutput]]] = Flipped(params.intSchdParams.get.genExuOutputDecoupledBundle) 65730cfbc0SXuan Hu 66730cfbc0SXuan Hu val fromVfExu: MixedVec[MixedVec[DecoupledIO[ExuOutput]]] = Flipped(params.vfSchdParams.get.genExuOutputDecoupledBundle) 67730cfbc0SXuan Hu 68730cfbc0SXuan Hu val fromMemExu: MixedVec[MixedVec[DecoupledIO[ExuOutput]]] = Flipped(params.memSchdParams.get.genExuOutputDecoupledBundle) 69730cfbc0SXuan Hu 70730cfbc0SXuan Hu val toIntPreg = Flipped(MixedVec(Vec(params.intPregParams.numWrite, 71730cfbc0SXuan Hu new RfWritePortWithConfig(params.intPregParams.dataCfg, params.intPregParams.addrWidth)))) 72730cfbc0SXuan Hu 73730cfbc0SXuan Hu val toVfPreg = Flipped(MixedVec(Vec(params.vfPregParams.numWrite, 74730cfbc0SXuan Hu new RfWritePortWithConfig(params.vfPregParams.dataCfg, params.vfPregParams.addrWidth)))) 75730cfbc0SXuan Hu 76730cfbc0SXuan Hu val toCtrlBlock = new Bundle { 77730cfbc0SXuan Hu val writeback: MixedVec[ValidIO[ExuOutput]] = params.genWrite2CtrlBundles 78730cfbc0SXuan Hu } 79730cfbc0SXuan Hu} 80730cfbc0SXuan Hu 81730cfbc0SXuan Huclass WbDataPath(params: BackendParams)(implicit p: Parameters) extends XSModule { 82730cfbc0SXuan Hu val io = IO(new WbDataPathIO()(p, params)) 83730cfbc0SXuan Hu 84730cfbc0SXuan Hu // alias 85730cfbc0SXuan Hu val intArbiterInputs = (io.fromIntExu ++ io.fromVfExu ++ io.fromMemExu).flatten.filter(_.bits.params.writeIntRf) 86730cfbc0SXuan Hu val vfArbiterInputs = (io.fromIntExu ++ io.fromVfExu ++ io.fromMemExu).flatten.filter(_.bits.params.writeVfRf) 87730cfbc0SXuan Hu println(s"[WbDataPath] write int preg: " + 88730cfbc0SXuan Hu s"IntExu(${io.fromIntExu.flatten.count(_.bits.params.writeIntRf)}) " + 89730cfbc0SXuan Hu s"VfExu(${io.fromVfExu.flatten.count(_.bits.params.writeIntRf)}) " + 90730cfbc0SXuan Hu s"MemExu(${io.fromMemExu.flatten.count(_.bits.params.writeIntRf)})" 91730cfbc0SXuan Hu ) 92730cfbc0SXuan Hu println(s"[WbDataPath] write vf preg: " + 93730cfbc0SXuan Hu s"IntExu(${io.fromIntExu.flatten.count(_.bits.params.writeVfRf)}) " + 94730cfbc0SXuan Hu s"VfExu(${io.fromVfExu.flatten.count(_.bits.params.writeVfRf)}) " + 95730cfbc0SXuan Hu s"MemExu(${io.fromMemExu.flatten.count(_.bits.params.writeVfRf)})" 96730cfbc0SXuan Hu ) 97730cfbc0SXuan Hu 98730cfbc0SXuan Hu // modules 99730cfbc0SXuan Hu private val intWbArbiter = Module(new WbArbiter(params.getIntWbArbiterParams)) 100730cfbc0SXuan Hu private val vfWbArbiter = Module(new WbArbiter(params.getVfWbArbiterParams)) 101730cfbc0SXuan Hu println(s"[WbDataPath] int preg write back port num: ${intWbArbiter.io.out.size}, active port: ${intWbArbiter.io.inGroup.keys.toSeq.sorted}") 102730cfbc0SXuan Hu println(s"[WbDataPath] vf preg write back port num: ${vfWbArbiter.io.out.size}, active port: ${vfWbArbiter.io.inGroup.keys.toSeq.sorted}") 103730cfbc0SXuan Hu 104730cfbc0SXuan Hu // module assign 105730cfbc0SXuan Hu intWbArbiter.io.flush <> io.flush 106730cfbc0SXuan Hu require(intWbArbiter.io.in.size == intArbiterInputs.size, s"intWbArbiter input size: ${intWbArbiter.io.in.size}, all vf wb size: ${intArbiterInputs.size}") 107730cfbc0SXuan Hu intWbArbiter.io.in.zip(intArbiterInputs).foreach { case (arbiterIn, in) => 108*5c5405a5SXuan Hu arbiterIn.valid := in.valid && in.bits.intWen.get 109730cfbc0SXuan Hu in.ready := arbiterIn.ready 110730cfbc0SXuan Hu arbiterIn.bits.fromExuOutput(in.bits) 111730cfbc0SXuan Hu } 112730cfbc0SXuan Hu private val intWbArbiterOut = intWbArbiter.io.out 113730cfbc0SXuan Hu 114730cfbc0SXuan Hu vfWbArbiter.io.flush <> io.flush 115730cfbc0SXuan Hu require(vfWbArbiter.io.in.size == vfArbiterInputs.size, s"vfWbArbiter input size: ${vfWbArbiter.io.in.size}, all vf wb size: ${vfArbiterInputs.size}") 116730cfbc0SXuan Hu vfWbArbiter.io.in.zip(vfArbiterInputs).foreach { case (arbiterIn, in) => 117*5c5405a5SXuan Hu arbiterIn.valid := in.valid && (in.bits.fpWen.getOrElse(false.B) || in.bits.vecWen.getOrElse(false.B)) 118730cfbc0SXuan Hu in.ready := arbiterIn.ready 119730cfbc0SXuan Hu arbiterIn.bits.fromExuOutput(in.bits) 120730cfbc0SXuan Hu } 121730cfbc0SXuan Hu 122730cfbc0SXuan Hu private val vfWbArbiterOut = vfWbArbiter.io.out 123730cfbc0SXuan Hu 124730cfbc0SXuan Hu private val intExuInputs = io.fromIntExu.flatten 125730cfbc0SXuan Hu private val intExuWBs = WireInit(MixedVecInit(io.fromIntExu.flatten)) 126730cfbc0SXuan Hu private val vfExuInputs = io.fromVfExu.flatten 127730cfbc0SXuan Hu private val vfExuWBs = WireInit(MixedVecInit(io.fromVfExu.flatten)) 128730cfbc0SXuan Hu private val memExuInputs = io.fromMemExu.flatten 129730cfbc0SXuan Hu private val memExuWBs = WireInit(MixedVecInit(io.fromMemExu.flatten)) 130730cfbc0SXuan Hu 131730cfbc0SXuan Hu // only fired port can write back to ctrl block 132730cfbc0SXuan Hu (intExuWBs zip intExuInputs).foreach { case (wb, input) => wb.valid := input.fire } 133730cfbc0SXuan Hu (vfExuWBs zip vfExuInputs).foreach { case (wb, input) => wb.valid := input.fire } 134730cfbc0SXuan Hu (memExuWBs zip memExuInputs).foreach { case (wb, input) => wb.valid := input.fire } 135730cfbc0SXuan Hu 136730cfbc0SXuan Hu // the ports not writting back pregs are always ready 137730cfbc0SXuan Hu (intExuInputs ++ vfExuInputs ++ memExuInputs).foreach( x => 138730cfbc0SXuan Hu if (x.bits.params.hasNoDataWB) x.ready := true.B 139730cfbc0SXuan Hu ) 140730cfbc0SXuan Hu 141730cfbc0SXuan Hu // io assign 142730cfbc0SXuan Hu private val toIntPreg: MixedVec[RfWritePortWithConfig] = MixedVecInit(intWbArbiterOut.map(x => x.bits.asIntRfWriteBundle(x.fire))) 143730cfbc0SXuan Hu private val toVfPreg: MixedVec[RfWritePortWithConfig] = MixedVecInit(vfWbArbiterOut.map(x => x.bits.asVfRfWriteBundle(x.fire))) 144730cfbc0SXuan Hu 145730cfbc0SXuan Hu private val wb2Ctrl = intExuWBs ++ vfExuWBs ++ memExuWBs 146730cfbc0SXuan Hu 147730cfbc0SXuan Hu io.toIntPreg := toIntPreg 148730cfbc0SXuan Hu io.toVfPreg := toVfPreg 149730cfbc0SXuan Hu io.toCtrlBlock.writeback.zip(wb2Ctrl).foreach { case (sink, source) => 150730cfbc0SXuan Hu sink.valid := source.valid 151730cfbc0SXuan Hu sink.bits := source.bits 152730cfbc0SXuan Hu source.ready := true.B 153730cfbc0SXuan Hu } 154730cfbc0SXuan Hu 155730cfbc0SXuan Hu if (env.EnableDifftest || env.AlwaysBasicDiff) { 156730cfbc0SXuan Hu intWbArbiterOut.foreach(out => { 157730cfbc0SXuan Hu val difftest = Module(new DifftestIntWriteback) 158730cfbc0SXuan Hu difftest.io.clock := clock 159730cfbc0SXuan Hu difftest.io.coreid := io.fromTop.hartId 160730cfbc0SXuan Hu difftest.io.valid := out.fire && out.bits.rfWen 161730cfbc0SXuan Hu difftest.io.dest := out.bits.pdest 162730cfbc0SXuan Hu difftest.io.data := out.bits.data 163730cfbc0SXuan Hu }) 164730cfbc0SXuan Hu } 165730cfbc0SXuan Hu 166730cfbc0SXuan Hu if (env.EnableDifftest || env.AlwaysBasicDiff) { 167730cfbc0SXuan Hu vfWbArbiterOut.foreach(out => { 168730cfbc0SXuan Hu val difftest = Module(new DifftestFpWriteback) 169730cfbc0SXuan Hu difftest.io.clock := clock 170730cfbc0SXuan Hu difftest.io.coreid := io.fromTop.hartId 171730cfbc0SXuan Hu difftest.io.valid := out.fire // all fp instr will write fp rf 172730cfbc0SXuan Hu difftest.io.dest := out.bits.pdest 173730cfbc0SXuan Hu difftest.io.data := out.bits.data 174730cfbc0SXuan Hu }) 175730cfbc0SXuan Hu } 176730cfbc0SXuan Hu 177730cfbc0SXuan Hu} 178730cfbc0SXuan Hu 179730cfbc0SXuan Hu 180730cfbc0SXuan Hu 181730cfbc0SXuan Hu 182