Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Backend: fix some bugs related to exu write
  • Loading branch information
ljwljwljwljw committed Feb 25, 2021
commit 2080835cfcd9ec2d99674929c6e4470a686e514f
14 changes: 3 additions & 11 deletions src/main/scala/xiangshan/backend/CtrlBlock.scala
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,7 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper {
val fpBusyTable = Module(new BusyTable(NRFpReadPorts, NRFpWritePorts))
val redirectGen = Module(new RedirectGenerator)

val roqWbSize = NRIntWritePorts + NRFpWritePorts + exuParameters.StuCnt

val roq = Module(new Roq(roqWbSize))
val roq = Module(new Roq(exuParameters.ExuCnt))

val backendRedirect = redirectGen.io.stage2Redirect
val frontendRedirect = redirectGen.io.stage3Redirect
Expand All @@ -227,7 +225,7 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper {

redirectGen.io.exuMispredict.zip(io.fromIntBlock.exuRedirect).map({case (x, y) =>
val misPred = y.valid && y.bits.redirect.cfiUpdate.isMisPred
val killedByOlder = y.bits.uop.roqIdx.needFlush(backendRedirect, flush)
val killedByOlder = y.bits.uop.roqIdx.needFlush(backendRedirect, flushReg)
x.valid := RegNext(misPred && !killedByOlder, init = false.B)
x.bits := RegEnable(y.bits, y.valid)
})
Expand Down Expand Up @@ -327,13 +325,7 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper {
fpBusyTable.io.read <> dispatch.io.readFpState

roq.io.redirect <> backendRedirect
roq.io.exeWbResults.zip(
io.fromIntBlock.wbRegs ++ io.fromFpBlock.wbRegs ++ io.fromLsBlock.stOut
).foreach{
case(x, y) =>
x.bits := y.bits
x.valid := y.valid
}
roq.io.exeWbResults <> (io.fromIntBlock.toRoq ++ io.fromFpBlock.toRoq ++ io.fromLsBlock.toRoq)

// TODO: is 'backendRedirect' necesscary?
io.toIntBlock.redirect <> backendRedirect
Expand Down
23 changes: 17 additions & 6 deletions src/main/scala/xiangshan/backend/FloatBlock.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import xiangshan.mem.HasLoadHelper

class FpBlockToCtrlIO extends XSBundle {
val wbRegs = Vec(NRFpWritePorts, ValidIO(new ExuOutput))
val toRoq = Vec(Exu.fpExuConfigs.size, ValidIO(new ExuOutput))
val numExist = Vec(exuParameters.FpExuCnt, Output(UInt(log2Ceil(IssQueSize).W)))
}

Expand Down Expand Up @@ -167,20 +168,30 @@ class FloatBlock
isFp = true
))
fpWbArbiter.io.in <> exeUnits.map(e =>
if(e.config.writeIntRf) WireInit(e.io.out) else e.io.out
fpOutValid(WireInit(e.io.out), connectReady = true)
) ++ wakeUpInRecode.slow

exeUnits.zip(recodeOut).zip(fpWbArbiter.io.in).filter(_._1._1.config.writeIntRf).foreach {
case ((exu, wInt), wFp) =>
exu.io.out.ready := wInt.fire() || wFp.fire()
}
for(((exu, rec), wFp) <- exeUnits.zip(recodeOut).zip(fpWbArbiter.io.in)) {
if(exu.config.writeIntRf){
val wIntFire = rec.fire() && rec.bits.uop.ctrl.rfWen
exu.io.out.ready := wIntFire || wFp.fire() || !exu.io.out.valid
} else {
exu.io.out.ready := wFp.fire() || !exu.io.out.valid
}
}

// set busytable and update roq
io.toCtrlBlock.wbRegs <> fpWbArbiter.io.out
io.toCtrlBlock.toRoq <> exeUnits.map(_.io.out).map(o => {
val v = Wire(Valid(new ExuOutput))
v.valid := o.fire()
v.bits := o.bits
v
})

fpRf.io.writePorts.zip(fpWbArbiter.io.out).foreach{
case (rf, wb) =>
rf.wen := wb.valid && wb.bits.uop.ctrl.fpWen
rf.wen := wb.valid
rf.addr := wb.bits.uop.pdest
rf.data := wb.bits.data
}
Expand Down
31 changes: 24 additions & 7 deletions src/main/scala/xiangshan/backend/IntegerBlock.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ package xiangshan.backend
import chisel3._
import chisel3.util._
import xiangshan._
import xiangshan.backend.exu.Exu.{ldExeUnitCfg, stExeUnitCfg}
import xiangshan.backend.exu.Exu.{jumpExeUnitCfg, ldExeUnitCfg, stExeUnitCfg}
import xiangshan.backend.exu._
import xiangshan.backend.fu.FenceToSbuffer
import xiangshan.backend.issue.{ReservationStation}
import xiangshan.backend.issue.ReservationStation
import xiangshan.backend.regfile.Regfile

class WakeUpBundle(numFast: Int, numSlow: Int) extends XSBundle {
Expand All @@ -22,6 +22,7 @@ class IntBlockToCtrlIO extends XSBundle {
// write back regfile signals after arbiter
// used to update busytable and roq state
val wbRegs = Vec(NRIntWritePorts, ValidIO(new ExuOutput))
val toRoq = Vec(Exu.intExuConfigs.size, ValidIO(new ExuOutput))
// write back to brq
val exuRedirect = Vec(exuParameters.AluCnt + exuParameters.JmpCnt, ValidIO(new ExuOutput))
val numExist = Vec(exuParameters.IntExuCnt, Output(UInt(log2Ceil(IssQueSize).W)))
Expand Down Expand Up @@ -261,20 +262,36 @@ class IntegerBlock
isFp = false
))
intWbArbiter.io.in <> exeUnits.map(e => {
if(e.config.writeFpRf) WireInit(e.io.out) else e.io.out
intOutValid(WireInit(e.io.out), connectReady = true)
}) ++ io.wakeUpIn.slow

exeUnits.zip(intWbArbiter.io.in).filter(_._1.config.writeFpRf).zip(io.wakeUpIn.slow).foreach{
case ((exu, wInt), wFp) =>
exu.io.out.ready := wFp.fire() || wInt.fire()
exeUnits.zip(intWbArbiter.io.in).foreach{
case (exu, wInt) =>
if(exu.config.writeFpRf){
val wakeUpOut = io.wakeUpOut.slow(0) // jmpExeUnit
val writeFpReady = wakeUpOut.fire() && wakeUpOut.bits.uop.ctrl.fpWen
val dontWriteRf = (exu.io.out.valid &&
!exu.io.out.bits.uop.ctrl.rfWen &&
!exu.io.out.bits.uop.ctrl.fpWen) || !exu.io.out.valid
exu.io.out.ready := wInt.fire() || writeFpReady || dontWriteRf
} else {
// some insts do not have 'rfWen', their output should be always ready
exu.io.out.ready := wInt.fire() || !(wInt.valid && !wInt.bits.uop.ctrl.rfWen)
}
}

// set busytable and update roq
io.toCtrlBlock.wbRegs <> intWbArbiter.io.out
io.toCtrlBlock.toRoq <> exeUnits.map(_.io.out).map(o => {
val v = Wire(Valid(new ExuOutput))
v.valid := o.fire()
v.bits := o.bits
v
})

intRf.io.writePorts.zip(intWbArbiter.io.out).foreach {
case (rf, wb) =>
rf.wen := wb.valid && wb.bits.uop.ctrl.rfWen
rf.wen := wb.valid
rf.addr := wb.bits.uop.pdest
rf.data := wb.bits.data
}
Expand Down
14 changes: 9 additions & 5 deletions src/main/scala/xiangshan/backend/MemBlock.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import xiangshan.backend.issue.{ReservationStation}
import xiangshan.backend.regfile.RfReadPort

class LsBlockToCtrlIO extends XSBundle {
val stOut = Vec(exuParameters.StuCnt, ValidIO(new ExuOutput)) // write to roq
val toRoq = Vec(exuParameters.LsExuCnt, ValidIO(new ExuOutput))
val numExist = Vec(exuParameters.LsExuCnt, Output(UInt(log2Ceil(IssQueSize).W)))
val replay = ValidIO(new Redirect)
}
Expand Down Expand Up @@ -119,6 +119,10 @@ class MemBlockImp(outer: MemBlock) extends LazyModuleImp(outer)
loadUnits.head.io.ldout.ready := ldOut0.ready

val exeWbReqs = ldOut0 +: loadUnits.tail.map(_.io.ldout)
for((toRoq, ldOut) <- io.toCtrlBlock.toRoq.take(exuParameters.LduCnt).zip(exeWbReqs)){
toRoq.valid := ldOut.fire()
toRoq.bits := ldOut.bits
}

val readPortIndex = Seq(0, 1, 2, 4)
io.fromIntBlock.readIntRf.foreach(_.addr := DontCare)
Expand Down Expand Up @@ -236,17 +240,17 @@ class MemBlockImp(outer: MemBlock) extends LazyModuleImp(outer)
stu.io.stin <> rs.io.deq
stu.io.lsq <> lsq.io.storeIn(i)

io.toCtrlBlock.stOut(i).valid := stu.io.stout.valid
io.toCtrlBlock.stOut(i).bits := stu.io.stout.bits
io.toCtrlBlock.toRoq(i + exuParameters.LduCnt).valid := stu.io.stout.valid
io.toCtrlBlock.toRoq(i + exuParameters.LduCnt).bits := stu.io.stout.bits
stu.io.stout.ready := true.B
}

// mmio store writeback will use store writeback port 0
lsq.io.mmioStout.ready := false.B
when (lsq.io.mmioStout.valid && !storeUnits(0).io.stout.valid) {
io.toCtrlBlock.stOut(0).valid := true.B
io.toCtrlBlock.toRoq(0 + exuParameters.LduCnt).valid := true.B
io.toCtrlBlock.toRoq(0 + exuParameters.LduCnt).bits := lsq.io.mmioStout.bits
lsq.io.mmioStout.ready := true.B
io.toCtrlBlock.stOut(0).bits := lsq.io.mmioStout.bits
}

// Lsq
Expand Down
6 changes: 3 additions & 3 deletions src/main/scala/xiangshan/backend/exu/Exu.scala
Original file line number Diff line number Diff line change
Expand Up @@ -209,13 +209,13 @@ object Exu {
val storeExuConfigs = Seq.fill(exuParameters.StuCnt)(stExeUnitCfg)

val intExuConfigs = jumpExeUnitCfg +: (
Seq.fill(exuParameters.AluCnt)(aluExeUnitCfg) ++
Seq.fill(exuParameters.MduCnt)(mulDivExeUnitCfg)
Seq.fill(exuParameters.MduCnt)(mulDivExeUnitCfg) ++
Seq.fill(exuParameters.AluCnt)(aluExeUnitCfg)
)

val fpExuConfigs =
Seq.fill(exuParameters.FmacCnt)(fmacExeUnitCfg) ++
Seq.fill(exuParameters.FmiscCnt)(fmiscExeUnitCfg)

val exuConfigs: Seq[ExuConfig] = intExuConfigs ++ fpExuConfigs
val exuConfigs: Seq[ExuConfig] = intExuConfigs ++ fpExuConfigs ++ loadExuConfigs ++ storeExuConfigs
}
53 changes: 28 additions & 25 deletions src/main/scala/xiangshan/backend/roq/Roq.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import chisel3.util._
import xiangshan._
import utils._
import xiangshan.backend.LSUOpType
import xiangshan.backend.exu.Exu
import xiangshan.backend.ftq.FtqPtr
import xiangshan.mem.{LqPtr, SqPtr}

Expand Down Expand Up @@ -734,39 +735,41 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
exceptionGen.io.enq(i).bits.exceptionVec := selectFrontend(io.enq.req(i).bits.cf.exceptionVec, false, true)
exceptionGen.io.enq(i).bits.flushPipe := io.enq.req(i).bits.ctrl.flushPipe
}

val csr_wb_idx = Exu.exuConfigs.indexOf(Exu.jumpExeUnitCfg)
val atomic_wb_idx = Exu.exuConfigs.indexOf(Exu.ldExeUnitCfg)
val load_wb_idxes = Exu.exuConfigs.zipWithIndex.filter(_._1 == Exu.ldExeUnitCfg).drop(1).map(_._2)
val store_wb_idxes = Exu.exuConfigs.zipWithIndex.filter(_._1 == Exu.stExeUnitCfg).map(_._2)
val all_exception_possibilities = Seq(csr_wb_idx, atomic_wb_idx) ++ load_wb_idxes ++ store_wb_idxes
all_exception_possibilities.zipWithIndex.map{ case (p, i) => connect_exception(i, p) }
def connect_exception(index: Int, wb_index: Int) = {
exceptionGen.io.wb(index).valid := io.exeWbResults(wb_index).valid
exceptionGen.io.wb(index).bits.roqIdx := io.exeWbResults(wb_index).bits.uop.roqIdx
val selectFunc = (if (wb_index == 6) selectCSR(_, _, _)
else if (wb_index == 4) selectAtomics(_, _, _)
else if (wb_index == 5) selectLoad(_, _, _)
else selectStore(_, _, _))
val selectFunc = if (wb_index == csr_wb_idx) selectCSR _
else if (wb_index == atomic_wb_idx) selectAtomics _
else if (load_wb_idxes.contains(wb_index)) selectLoad _
else {
assert(store_wb_idxes.contains(wb_index))
selectStore _
}
exceptionGen.io.wb(index).bits.exceptionVec := selectFunc(io.exeWbResults(wb_index).bits.uop.cf.exceptionVec, false, true)
exceptionGen.io.wb(index).bits.flushPipe := io.exeWbResults(wb_index).bits.uop.ctrl.flushPipe
}
val all_exception_possibilities = Seq(6, 4, 5, 16, 17)
all_exception_possibilities.zipWithIndex.map{ case (p, i) => connect_exception(i, p) }

val fflagsDataModule = Module(new SyncDataModuleTemplate(UInt(5.W), RoqSize, CommitWidth, 7))
var wPortIdx = 0
// 4 FMACs
for (i <- 0 until 4) {
fflagsDataModule.io.wen (wPortIdx) := io.exeWbResults(8+i).valid
fflagsDataModule.io.waddr(wPortIdx) := io.exeWbResults(8+i).bits.uop.roqIdx.value
fflagsDataModule.io.wdata(wPortIdx) := io.exeWbResults(8+i).bits.fflags
wPortIdx = wPortIdx + 1
}
// 2 FMISCs (the first one includes I2F from JumpUnit)
for (i <- 0 until 2) {
fflagsDataModule.io.wen (wPortIdx) := io.exeWbResults(14+i).valid
fflagsDataModule.io.waddr(wPortIdx) := io.exeWbResults(14+i).bits.uop.roqIdx.value
fflagsDataModule.io.wdata(wPortIdx) := io.exeWbResults(14+i).bits.fflags
wPortIdx = wPortIdx + 1
val fflags_wb = io.exeWbResults.zip(Exu.exuConfigs).filter(_._2 match {
case Exu.fmacExeUnitCfg => true
case Exu.fmiscExeUnitCfg => true
case Exu.jumpExeUnitCfg => true
case _ => false
}).map(_._1)
val fflagsDataModule = Module(new SyncDataModuleTemplate(
UInt(5.W), RoqSize, CommitWidth, fflags_wb.size)
)
for(i <- fflags_wb.indices){
fflagsDataModule.io.wen (i) := fflags_wb(i).valid
fflagsDataModule.io.waddr(i) := fflags_wb(i).bits.uop.roqIdx.value
fflagsDataModule.io.wdata(i) := fflags_wb(i).bits.fflags
}
// 1 FMISC (Int Wb)
fflagsDataModule.io.wen (wPortIdx) := io.exeWbResults(7).valid
fflagsDataModule.io.waddr(wPortIdx) := io.exeWbResults(7).bits.uop.roqIdx.value
fflagsDataModule.io.wdata(wPortIdx) := io.exeWbResults(7).bits.fflags
fflagsDataModule.io.raddr := VecInit(deqPtrVec_next.map(_.value))
fflagsDataRead := fflagsDataModule.io.rdata

Expand Down