提交 cafc71ed 编写于 作者: L LinJiawei

Wbu: update arbiter

上级 74fe9f47
......@@ -208,10 +208,8 @@ class Backend(implicit val p: XSConfig) extends XSModule
fpRf.io.readPorts <> dispatch.io.readFpRf ++ issueQueues.flatMap(_.io.readFpRf)
memRf.io.readPorts <> issueQueues.flatMap(_.io.readIntRf)
val wbIntIdx = exuConfigs.zipWithIndex.filter(_._1.writeIntRf).map(_._2)
val wbFpIdx = exuConfigs.zipWithIndex.filter(_._1.writeFpRf).map(_._2)
val wbu = Module(new Wbu(wbIntIdx, wbFpIdx))
val wbu = Module(new Wbu(exuConfigs))
wbu.io.in <> exeWbReqs
val wbIntResults = wbu.io.toIntRf
......
......@@ -64,4 +64,7 @@ object Exu {
val mulDivExeUnitCfg = ExuConfig("MulDivExu", Array(mulCfg, divCfg), enableBypass = false)
val ldExeUnitCfg = ExuConfig("LoadExu", Array(lduCfg), enableBypass = false)
val stExeUnitCfg =ExuConfig("StoreExu", Array(stuCfg), enableBypass = false)
val fmacExeUnitCfg = ExuConfig("FmacExu", Array(fmacCfg), enableBypass = false)
val fmiscExeUnitCfg = ExuConfig("FmiscExu", Array(fmiscCfg), enableBypass = false)
val fmiscDivExeUnitCfg = ExuConfig("FmiscDivExu", Array(fmiscCfg, fDivSqrtCfg), enableBypass = false)
}
......@@ -38,7 +38,7 @@ class WriteBackArbMtoN(m: Int, n: Int) extends XSModule {
}
class Wbu(wbIntIdx: Array[Int], wbFpIdx: Array[Int]) extends XSModule{
class Wbu(exuConfigs: Array[ExuConfig]) extends XSModule{
val io = IO(new Bundle() {
val in = Vec(exuParameters.ExuCnt, Flipped(DecoupledIO(new ExuOutput)))
......@@ -47,33 +47,42 @@ class Wbu(wbIntIdx: Array[Int], wbFpIdx: Array[Int]) extends XSModule{
val toFpRf = Vec(NRFpWritePorts, ValidIO(new ExuOutput))
})
require(io.in.length == exuConfigs.length)
def exuOutToRfReq
(exuOutVec: Vec[DecoupledIO[ExuOutput]], fp: Boolean): Seq[(DecoupledIO[ExuOutput], Int)] = {
val wbIdxSet = if(fp) wbFpIdx else wbIntIdx
exuOutVec.zipWithIndex.filter(x => wbIdxSet.contains(x._2)).map({
case(exuOut, idx) =>
val req = Wire(Decoupled(new ExuOutput))
req.valid := exuOut.valid && {if(fp) exuOut.bits.uop.ctrl.fpWen else exuOut.bits.uop.ctrl.rfWen}
req.bits := exuOut.bits
(req, idx)
})
(exuOut: DecoupledIO[ExuOutput], fp: Boolean): DecoupledIO[ExuOutput] = {
val req = Wire(Decoupled(new ExuOutput))
req.valid := exuOut.valid && {
if(fp) exuOut.bits.uop.ctrl.fpWen else exuOut.bits.uop.ctrl.rfWen
}
req.bits := exuOut.bits
req
}
val wbIntReq = exuOutToRfReq(io.in, fp = false)
// ((ExuOutput, ExuConfig), index) => ((WbReq, ExuConfig), index)
val wbInt = io.in.zip(exuConfigs).zipWithIndex.
filter(_._1._2.writeIntRf).map(x =>
((exuOutToRfReq(x._1._1, fp = false), x._1._2), x._2))
val wbFpReq = exuOutToRfReq(io.in, fp = true)
val wbIntReq = wbInt.map(_._1)
for(i <- io.in.indices){
val intReqIdx = wbIntReq.map(_._2).indexOf(i)
val fpReqIdx = wbFpReq.map(_._2).indexOf(i)
val wbFp = io.in.zip(exuConfigs).zipWithIndex.
filter(_._1._2.writeFpRf).map(x =>
((exuOutToRfReq(x._1._1, fp = true), x._1._2), x._2))
val wbFpReq = wbFp.map(_._1)
val wbInt = intReqIdx >= 0
val wbFp = fpReqIdx >= 0
for(i <- io.in.indices){
val writeIntReqIdx = wbInt.map(_._2).indexOf(i)
val writeFpReqIdx = wbFp.map(_._2).indexOf(i)
val writeIntRf = writeIntReqIdx >= 0
val writeFpRf = writeFpReqIdx >= 0
val iReq = if(wbInt) wbIntReq(intReqIdx)._1 else null
val fReq = if(wbFp) wbFpReq(fpReqIdx)._1 else null
val iReq = if(writeIntRf) wbIntReq(writeIntReqIdx)._1 else null
val fReq = if(writeFpRf) wbFpReq(writeFpReqIdx)._1 else null
if(wbInt && wbFp){
if(writeIntRf && writeFpRf){
io.in(i).ready := Mux(iReq.valid,
iReq.ready,
Mux(fReq.valid,
......@@ -82,46 +91,104 @@ class Wbu(wbIntIdx: Array[Int], wbFpIdx: Array[Int]) extends XSModule{
)
)
assert(!(iReq.valid && fReq.valid), s"Error: iReq and fReq valid at same time, idx=$i")
} else if(wbInt){
io.in(i).ready := Mux(iReq.valid, iReq.ready, true.B)
} else if(wbFp){
io.in(i).ready := Mux(fReq.valid, fReq.ready, true.B)
} else if(writeIntRf){
io.in(i).ready := iReq.ready
} else if(writeFpRf){
io.in(i).ready := fReq.ready
} else {
// store
io.in(i).ready := true.B
}
exuConfigs(i) match {
case Exu.aluExeUnitCfg =>
io.toRoq(i).valid := io.in(i).fire() && !io.in(i).bits.redirectValid
case Exu.jmpExeUnitCfg =>
io.toRoq(i).valid := io.in(i).fire() && !io.in(i).bits.redirectValid
case _ =>
io.toRoq(i).valid := io.in(i).fire()
}
io.toRoq(i).bits := io.in(i).bits
}
if(wbIntIdx.length < NRIntWritePorts){
io.toIntRf.take(wbIntIdx.length).zip(wbIntReq.map(_._1)).foreach(x => {
x._1.bits := x._2.bits
x._1.valid := x._2.valid
x._2.ready := true.B
})
io.toIntRf.drop(wbIntIdx.length).foreach(_ <> DontCare)
} else {
val intArb = Module(new WriteBackArbMtoN(wbIntIdx.length, NRIntWritePorts))
intArb.io.in <> wbIntReq.map(_._1)
io.toIntRf <> intArb.io.out
def directConnect(rfWrite: Valid[ExuOutput], wbReq: DecoupledIO[ExuOutput]) = {
rfWrite.bits := wbReq.bits
rfWrite.valid := wbReq.valid
wbReq.ready := true.B
}
def splitN[T](in: Seq[T], n: Int): Seq[Option[Seq[T]]] = {
require(n > 0)
if(in.size < n) Seq(Some(in)) ++ Seq.fill(n-1)(None)
else {
val m = in.size/n
Some(in.take(m)) +: splitN(in.drop(m), n-1)
}
}
if(wbFpIdx.length < NRFpWritePorts){
io.toFpRf.take(wbFpIdx.length).zip(wbFpReq.map(_._1)).foreach(x => {
x._1.bits := x._2.bits
x._1.valid := x._2.valid
x._2.ready := true.B
})
io.toFpRf.drop(wbFpIdx.length).foreach(_ <> DontCare)
if(wbIntReq.size <= NRIntWritePorts){ // write ports are enough
io.toIntRf.
take(wbIntReq.size).
zip(wbIntReq).
foreach(x => directConnect(x._1, x._2._1))
if(wbIntReq.size < NRIntWritePorts){
println(s"Warrning: ${NRIntWritePorts-wbIntReq.size} int write ports are not used!")
io.toIntRf.drop(wbIntReq.size).foreach(_ <> DontCare)
}
} else {
val fpArb = Module(new WriteBackArbMtoN(wbFpIdx.length, NRFpWritePorts))
fpArb.io.in <> wbFpReq.map(_._1)
io.toFpRf <> fpArb.io.out
val directReq = wbIntReq.filter(w => Seq(Exu.ldExeUnitCfg, Exu.aluExeUnitCfg).contains(w._2))
val mulReq = wbIntReq.filter(w => Seq(Exu.mulExeUnitCfg, Exu.mulDivExeUnitCfg).contains(w._2))
val otherReq = splitN(
wbIntReq.filterNot(w => Seq(
Exu.ldExeUnitCfg, Exu.aluExeUnitCfg, Exu.mulDivExeUnitCfg, Exu.mulExeUnitCfg
).contains(w._2)),
mulReq.size
)
require(directReq.size + mulReq.size <= NRIntWritePorts)
// alu && load: direct connect
io.toIntRf.take(directReq.size).zip(directReq).foreach(x => directConnect(x._1, x._2._1))
for( i <- mulReq.indices){
val arbiter = Module(new Arbiter(new ExuOutput, 1+otherReq(i).getOrElse(Seq()).size))
arbiter.io.in <> (mulReq(i) +: otherReq(i).getOrElse(Seq())).map(_._1)
io.toIntRf.drop(directReq.size)(i) := arbiter.io.out
arbiter.io.out.ready := true.B
}
if(directReq.size + mulReq.size < NRIntWritePorts){
println(s"Warrning: ${NRIntWritePorts-directReq.size-mulReq.size} int write ports are not used!")
io.toIntRf.drop(directReq.size + mulReq.size).foreach(_ <> DontCare)
}
}
io.toRoq.zip(io.in).foreach({
case(roq, in) =>
roq.valid := in.fire() && !in.bits.redirectValid
roq.bits := in.bits
})
if(wbFpReq.size <= NRFpWritePorts){
io.toFpRf.
take(wbFpReq.size).
zip(wbFpReq).
foreach(x => directConnect(x._1, x._2._1))
if(wbFpReq.size < NRFpWritePorts){
println(s"Warrning: ${NRFpWritePorts-wbFpReq.size} fp write ports are not used!")
io.toFpRf.drop(wbFpReq.size).foreach(_ <> DontCare)
}
} else {
val directReq = wbFpReq.filter(w => Seq(Exu.ldExeUnitCfg, Exu.fmacExeUnitCfg).contains(w._2))
val fmiscReq = wbFpReq.filter(w => Seq(Exu.fmiscExeUnitCfg, Exu.fmiscDivExeUnitCfg).contains(w._2))
val otherReq = splitN(
wbFpReq.filterNot(w => Seq(
Exu.ldExeUnitCfg, Exu.fmacExeUnitCfg, Exu.fmiscExeUnitCfg, Exu.fmiscDivExeUnitCfg
).contains(w._2)),
fmiscReq.size
)
require(directReq.size + fmiscReq.size <= NRFpWritePorts)
io.toFpRf.take(directReq.size).zip(directReq).foreach(x => directConnect(x._1, x._2._1))
for( i <- fmiscReq.indices){
val arbiter = Module(new Arbiter(new ExuOutput, 1+otherReq(i).getOrElse(Seq()).size))
arbiter.io.in <> (fmiscReq(i) +: otherReq(i).getOrElse(Seq())).map(_._1)
io.toFpRf.drop(directReq.size)(i) := arbiter.io.out
arbiter.io.out.ready := true.B
}
if(directReq.size + fmiscReq.size < NRFpWritePorts){
println(s"Warrning: ${NRFpWritePorts-directReq.size-fmiscReq.size} fp write ports are not used!")
io.toFpRf.drop(directReq.size + fmiscReq.size).foreach(_ <> DontCare)
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册