提交 08a5995c 编写于 作者: Y Yinan Xu

Merge remote-tracking branch 'origin/master' into opt-lq-wbsel

...@@ -23,7 +23,9 @@ int main(int argc, char* argv[]){ ...@@ -23,7 +23,9 @@ int main(int argc, char* argv[]){
fd = tryLock(argv[1]); fd = tryLock(argv[1]);
if(fd > 0){ if(fd > 0){
getlogin_r(user, BUF_SIZE); getlogin_r(user, BUF_SIZE);
write(fd, user, strlen(user)); int len = strlen(user);
user[len] = '\0';
write(fd, user, len+1);
break; break;
} else { } else {
// someone is holding the lock... // someone is holding the lock...
......
...@@ -182,7 +182,7 @@ class CfiUpdateInfo extends XSBundle { ...@@ -182,7 +182,7 @@ class CfiUpdateInfo extends XSBundle {
class CtrlFlow extends XSBundle { class CtrlFlow extends XSBundle {
val instr = UInt(32.W) val instr = UInt(32.W)
val pc = UInt(VAddrBits.W) val pc = UInt(VAddrBits.W)
val exceptionVec = Vec(16, Bool()) val exceptionVec = ExceptionVec()
val intrVec = Vec(12, Bool()) val intrVec = Vec(12, Bool())
val brUpdate = new CfiUpdateInfo val brUpdate = new CfiUpdateInfo
val crossPageIPFFix = Bool() val crossPageIPFFix = Bool()
......
...@@ -237,4 +237,4 @@ class IntegerBlock ...@@ -237,4 +237,4 @@ class IntegerBlock
rf.addr := wb.bits.uop.pdest rf.addr := wb.bits.uop.pdest
rf.data := wb.bits.data rf.data := wb.bits.data
} }
} }
\ No newline at end of file
...@@ -458,10 +458,8 @@ class DecodeUnit extends XSModule with DecodeUnitConstants { ...@@ -458,10 +458,8 @@ class DecodeUnit extends XSModule with DecodeUnitConstants {
cs.ldest := Mux(cs.fpWen || cs.rfWen, ctrl_flow.instr(RD_MSB,RD_LSB), 0.U) cs.ldest := Mux(cs.fpWen || cs.rfWen, ctrl_flow.instr(RD_MSB,RD_LSB), 0.U)
// fill in exception vector // fill in exception vector
cf_ctrl.cf.exceptionVec.map(_ := false.B) cf_ctrl.cf.exceptionVec := io.enq.ctrl_flow.exceptionVec
cf_ctrl.cf.exceptionVec(illegalInstr) := cs.selImm === SelImm.INVALID_INSTR cf_ctrl.cf.exceptionVec(illegalInstr) := cs.selImm === SelImm.INVALID_INSTR
cf_ctrl.cf.exceptionVec(instrPageFault) := io.enq.ctrl_flow.exceptionVec(instrPageFault)
cf_ctrl.cf.exceptionVec(instrAccessFault) := io.enq.ctrl_flow.exceptionVec(instrAccessFault)
// fix frflags // fix frflags
// fflags zero csrrs rd csr // fflags zero csrrs rd csr
......
...@@ -8,9 +8,10 @@ import utils.{XSDebug, XSError, XSInfo} ...@@ -8,9 +8,10 @@ import utils.{XSDebug, XSError, XSInfo}
import xiangshan.backend.roq.{RoqPtr, RoqEnqIO} import xiangshan.backend.roq.{RoqPtr, RoqEnqIO}
import xiangshan.backend.rename.RenameBypassInfo import xiangshan.backend.rename.RenameBypassInfo
import xiangshan.mem.LsqEnqIO import xiangshan.mem.LsqEnqIO
import xiangshan.backend.fu.HasExceptionNO
// read rob and enqueue // read rob and enqueue
class Dispatch1 extends XSModule { class Dispatch1 extends XSModule with HasExceptionNO {
val io = IO(new Bundle() { val io = IO(new Bundle() {
// from rename // from rename
val fromRename = Vec(RenameWidth, Flipped(DecoupledIO(new MicroOp))) val fromRename = Vec(RenameWidth, Flipped(DecoupledIO(new MicroOp)))
...@@ -116,6 +117,7 @@ class Dispatch1 extends XSModule { ...@@ -116,6 +117,7 @@ class Dispatch1 extends XSModule {
// thisIsBlocked: this instruction is blocked by itself (based on noSpecExec) // thisIsBlocked: this instruction is blocked by itself (based on noSpecExec)
// nextCanOut: next instructions can out (based on blockBackward) // nextCanOut: next instructions can out (based on blockBackward)
// notBlockedByPrevious: previous instructions can enqueue // notBlockedByPrevious: previous instructions can enqueue
val hasException = VecInit(io.fromRename.map(r => selectFrontend(r.bits.cf.exceptionVec).asUInt.orR))
val thisIsBlocked = VecInit((0 until RenameWidth).map(i => { val thisIsBlocked = VecInit((0 until RenameWidth).map(i => {
// for i > 0, when Roq is empty but dispatch1 have valid instructions to enqueue, it's blocked // for i > 0, when Roq is empty but dispatch1 have valid instructions to enqueue, it's blocked
if (i > 0) isNoSpecExec(i) && (!io.enqRoq.isEmpty || Cat(io.fromRename.take(i).map(_.valid)).orR) if (i > 0) isNoSpecExec(i) && (!io.enqRoq.isEmpty || Cat(io.fromRename.take(i).map(_.valid)).orR)
...@@ -156,17 +158,17 @@ class Dispatch1 extends XSModule { ...@@ -156,17 +158,17 @@ class Dispatch1 extends XSModule {
// We use notBlockedByPrevious here. // We use notBlockedByPrevious here.
io.toIntDq.needAlloc(i) := io.fromRename(i).valid && isInt(i) io.toIntDq.needAlloc(i) := io.fromRename(i).valid && isInt(i)
io.toIntDq.req(i).bits := updatedUop(i) io.toIntDq.req(i).bits := updatedUop(i)
io.toIntDq.req(i).valid := io.fromRename(i).valid && isInt(i) && thisCanActualOut(i) && io.toIntDq.req(i).valid := io.fromRename(i).valid && !hasException(i) && isInt(i) && thisCanActualOut(i) &&
io.enqLsq.canAccept && io.enqRoq.canAccept && io.toFpDq.canAccept && io.toLsDq.canAccept io.enqLsq.canAccept && io.enqRoq.canAccept && io.toFpDq.canAccept && io.toLsDq.canAccept
io.toFpDq.needAlloc(i) := io.fromRename(i).valid && isFp(i) io.toFpDq.needAlloc(i) := io.fromRename(i).valid && isFp(i)
io.toFpDq.req(i).bits := updatedUop(i) io.toFpDq.req(i).bits := updatedUop(i)
io.toFpDq.req(i).valid := io.fromRename(i).valid && isFp(i) && thisCanActualOut(i) && io.toFpDq.req(i).valid := io.fromRename(i).valid && !hasException(i) && isFp(i) && thisCanActualOut(i) &&
io.enqLsq.canAccept && io.enqRoq.canAccept && io.toIntDq.canAccept && io.toLsDq.canAccept io.enqLsq.canAccept && io.enqRoq.canAccept && io.toIntDq.canAccept && io.toLsDq.canAccept
io.toLsDq.needAlloc(i) := io.fromRename(i).valid && isLs(i) io.toLsDq.needAlloc(i) := io.fromRename(i).valid && isLs(i)
io.toLsDq.req(i).bits := updatedUop(i) io.toLsDq.req(i).bits := updatedUop(i)
io.toLsDq.req(i).valid := io.fromRename(i).valid && isLs(i) && thisCanActualOut(i) && io.toLsDq.req(i).valid := io.fromRename(i).valid && !hasException(i) && isLs(i) && thisCanActualOut(i) &&
io.enqLsq.canAccept && io.enqRoq.canAccept && io.toIntDq.canAccept && io.toFpDq.canAccept io.enqLsq.canAccept && io.enqRoq.canAccept && io.toIntDq.canAccept && io.toFpDq.canAccept
XSDebug(io.toIntDq.req(i).valid, p"pc 0x${Hexadecimal(io.toIntDq.req(i).bits.cf.pc)} int index $i\n") XSDebug(io.toIntDq.req(i).valid, p"pc 0x${Hexadecimal(io.toIntDq.req(i).bits.cf.pc)} int index $i\n")
......
...@@ -88,6 +88,7 @@ class Dispatch2Int extends XSModule { ...@@ -88,6 +88,7 @@ class Dispatch2Int extends XSModule {
val src2Ready = VecInit((0 until 4).map(i => io.regRdy(i * 2 + 1))) val src2Ready = VecInit((0 until 4).map(i => io.regRdy(i * 2 + 1)))
enq.bits.src1State := src1Ready(readPortIndex(i)) enq.bits.src1State := src1Ready(readPortIndex(i))
enq.bits.src2State := src2Ready(readPortIndex(i)) enq.bits.src2State := src2Ready(readPortIndex(i))
enq.bits.src3State := DontCare
XSInfo(enq.fire(), p"pc 0x${Hexadecimal(enq.bits.cf.pc)} with type ${enq.bits.ctrl.fuType} " + XSInfo(enq.fire(), p"pc 0x${Hexadecimal(enq.bits.cf.pc)} with type ${enq.bits.ctrl.fuType} " +
p"srcState(${enq.bits.src1State} ${enq.bits.src2State}) " + p"srcState(${enq.bits.src1State} ${enq.bits.src2State}) " +
......
...@@ -83,6 +83,7 @@ class Dispatch2Ls extends XSModule { ...@@ -83,6 +83,7 @@ class Dispatch2Ls extends XSModule {
enq.bits.src2State := Mux(io.fromDq(indexVec(i)).bits.ctrl.src2Type === SrcType.fp, enq.bits.src2State := Mux(io.fromDq(indexVec(i)).bits.ctrl.src2Type === SrcType.fp,
io.fpRegRdy(i - exuParameters.LduCnt), io.intRegRdy(readPort(i) + 1)) io.fpRegRdy(i - exuParameters.LduCnt), io.intRegRdy(readPort(i) + 1))
} }
enq.bits.src3State := DontCare
XSInfo(enq.fire(), p"pc 0x${Hexadecimal(enq.bits.cf.pc)} with type ${enq.bits.ctrl.fuType} " + XSInfo(enq.fire(), p"pc 0x${Hexadecimal(enq.bits.cf.pc)} with type ${enq.bits.ctrl.fuType} " +
p"srcState(${enq.bits.src1State} ${enq.bits.src2State}) " + p"srcState(${enq.bits.src1State} ${enq.bits.src2State}) " +
......
...@@ -120,13 +120,21 @@ abstract class Exu(val config: ExuConfig) extends XSModule { ...@@ -120,13 +120,21 @@ abstract class Exu(val config: ExuConfig) extends XSModule {
def writebackArb(in: Seq[DecoupledIO[FuOutput]], out: DecoupledIO[ExuOutput]): Arbiter[FuOutput] = { def writebackArb(in: Seq[DecoupledIO[FuOutput]], out: DecoupledIO[ExuOutput]): Arbiter[FuOutput] = {
if (needArbiter) { if (needArbiter) {
val arb = Module(new Arbiter(new FuOutput(in.head.bits.len), in.size)) if(in.size == 1){
arb.io.in <> in in.head.ready := out.ready
arb.io.out.ready := out.ready out.bits.data := in.head.bits.data
out.bits.data := arb.io.out.bits.data out.bits.uop := in.head.bits.uop
out.bits.uop := arb.io.out.bits.uop out.valid := in.head.valid
out.valid := arb.io.out.valid null
arb } else {
val arb = Module(new Arbiter(new FuOutput(in.head.bits.len), in.size))
arb.io.in <> in
arb.io.out.ready := out.ready
out.bits.data := arb.io.out.bits.data
out.bits.uop := arb.io.out.bits.uop
out.valid := arb.io.out.valid
arb
}
} else { } else {
in.foreach(_.ready := out.ready) in.foreach(_.ready := out.ready)
val sel = Mux1H(in.map(x => x.valid -> x)) val sel = Mux1H(in.map(x => x.valid -> x))
......
...@@ -14,8 +14,8 @@ class FmiscExeUnit extends Exu(fmiscExeUnitCfg) { ...@@ -14,8 +14,8 @@ class FmiscExeUnit extends Exu(fmiscExeUnitCfg) {
val toFpUnits = Seq(f2f, fdivSqrt) val toFpUnits = Seq(f2f, fdivSqrt)
val toIntUnits = Seq(f2i) val toIntUnits = Seq(f2i)
assert(fpArb.io.in.length == toFpUnits.size) assert(toFpUnits.size == 1 || fpArb.io.in.length == toFpUnits.size)
assert(intArb.io.in.length == toIntUnits.size) assert(toIntUnits.size == 1 || intArb.io.in.length == toIntUnits.size)
val input = io.fromFp val input = io.fromFp
val isRVF = input.bits.uop.ctrl.isRVF val isRVF = input.bits.uop.ctrl.isRVF
......
...@@ -56,15 +56,20 @@ class Wb(cfgs: Seq[ExuConfig], numOut: Int, isFp: Boolean) extends XSModule { ...@@ -56,15 +56,20 @@ class Wb(cfgs: Seq[ExuConfig], numOut: Int, isFp: Boolean) extends XSModule {
mulReq.size mulReq.size
) )
val arbiters = for(i <- mulReq.indices) yield { for(i <- mulReq.indices) {
val other = arbReq(i).getOrElse(Seq())
val arb = Module(new Arbiter(new ExuOutput, 1+other.size))
arb.io.in <> mulReq(i) +: other
val out = io.out(directConnect.size + i) val out = io.out(directConnect.size + i)
out.valid := arb.io.out.valid val other = arbReq(i).getOrElse(Seq())
out.bits := arb.io.out.bits if(other.isEmpty){
arb.io.out.ready := true.B out.valid := mulReq(i).valid
arb out.bits := mulReq(i).bits
mulReq(i).ready := true.B
} else {
val arb = Module(new Arbiter(new ExuOutput, 1+other.size))
arb.io.in <> mulReq(i) +: other
out.valid := arb.io.out.valid
out.bits := arb.io.out.bits
arb.io.out.ready := true.B
}
} }
if(portUsed < numOut){ if(portUsed < numOut){
...@@ -78,10 +83,11 @@ class Wb(cfgs: Seq[ExuConfig], numOut: Int, isFp: Boolean) extends XSModule { ...@@ -78,10 +83,11 @@ class Wb(cfgs: Seq[ExuConfig], numOut: Int, isFp: Boolean) extends XSModule {
} }
for(i <- mulReq.indices){ for(i <- mulReq.indices){
sb.append(s"[ ${cfgs(io.in.indexOf(mulReq(i))).name} ") sb.append(s"[ ${cfgs(io.in.indexOf(mulReq(i))).name} ")
val useArb = arbReq(i).nonEmpty
for(req <- arbReq(i).getOrElse(Nil)){ for(req <- arbReq(i).getOrElse(Nil)){
sb.append(s"${cfgs(io.in.indexOf(req)).name} ") sb.append(s"${cfgs(io.in.indexOf(req)).name} ")
} }
sb.append(s"] -> arb -> out #${directConnect.size + i}\n") sb.append(s"] -> ${if(useArb) "arb ->" else ""} out #${directConnect.size + i}\n")
} }
println(sb) println(sb)
......
...@@ -47,6 +47,62 @@ trait HasExceptionNO { ...@@ -47,6 +47,62 @@ trait HasExceptionNO {
storeAddrMisaligned, storeAddrMisaligned,
loadAddrMisaligned loadAddrMisaligned
) )
val frontendSet = List(
// instrAddrMisaligned,
instrAccessFault,
illegalInstr,
instrPageFault
)
val csrSet = List(
illegalInstr,
breakPoint,
ecallU,
ecallS,
ecallM
)
val loadUnitSet = List(
loadAddrMisaligned,
loadAccessFault,
loadPageFault
)
val storeUnitSet = List(
storeAddrMisaligned,
storeAccessFault,
storePageFault
)
val atomicsUnitSet = (loadUnitSet ++ storeUnitSet).distinct
val allPossibleSet = (frontendSet ++ csrSet ++ loadUnitSet ++ storeUnitSet).distinct
def partialSelect(vec: Vec[Bool], select: Seq[Int], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] = {
if (dontCareBits) {
val new_vec = Wire(ExceptionVec())
new_vec := DontCare
select.map(i => new_vec(i) := vec(i))
return new_vec
}
else if (falseBits) {
val new_vec = Wire(ExceptionVec())
new_vec.map(_ := false.B)
select.map(i => new_vec(i) := vec(i))
return new_vec
}
else {
val new_vec = Wire(Vec(select.length, Bool()))
select.zipWithIndex.map{ case(s, i) => new_vec(i) := vec(s) }
return new_vec
}
}
def selectFrontend(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] =
partialSelect(vec, frontendSet, dontCareBits, falseBits)
def selectCSR(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] =
partialSelect(vec, csrSet, dontCareBits, falseBits)
def selectLoad(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] =
partialSelect(vec, loadUnitSet, dontCareBits, falseBits)
def selectStore(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] =
partialSelect(vec, storeUnitSet, dontCareBits, falseBits)
def selectAtomics(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] =
partialSelect(vec, atomicsUnitSet, dontCareBits, falseBits)
def selectAll(vec: Vec[Bool], dontCareBits: Boolean = true, falseBits: Boolean = false): Vec[Bool] =
partialSelect(vec, allPossibleSet, dontCareBits, falseBits)
} }
class FpuCsrIO extends XSBundle { class FpuCsrIO extends XSBundle {
...@@ -580,6 +636,17 @@ class CSR extends FunctionUnit with HasCSRConst ...@@ -580,6 +636,17 @@ class CSR extends FunctionUnit with HasCSRConst
io.in.ready := true.B io.in.ready := true.B
io.out.valid := valid io.out.valid := valid
val csrExceptionVec = WireInit(cfIn.exceptionVec)
csrExceptionVec(breakPoint) := io.in.valid && isEbreak
csrExceptionVec(ecallM) := priviledgeMode === ModeM && io.in.valid && isEcall
csrExceptionVec(ecallS) := priviledgeMode === ModeS && io.in.valid && isEcall
csrExceptionVec(ecallU) := priviledgeMode === ModeU && io.in.valid && isEcall
// Trigger an illegal instr exception when:
// * unimplemented csr is being read/written
// * csr access is illegal
csrExceptionVec(illegalInstr) := (isIllegalAddr || isIllegalAccess) && wen
cfOut.exceptionVec := csrExceptionVec
/** /**
* Exception and Intr * Exception and Intr
*/ */
...@@ -613,25 +680,7 @@ class CSR extends FunctionUnit with HasCSRConst ...@@ -613,25 +680,7 @@ class CSR extends FunctionUnit with HasCSRConst
val hasLoadAccessFault = csrio.exception.bits.cf.exceptionVec(loadAccessFault) && raiseException val hasLoadAccessFault = csrio.exception.bits.cf.exceptionVec(loadAccessFault) && raiseException
val hasStoreAccessFault = csrio.exception.bits.cf.exceptionVec(storeAccessFault) && raiseException val hasStoreAccessFault = csrio.exception.bits.cf.exceptionVec(storeAccessFault) && raiseException
val csrExceptionVec = Wire(Vec(16, Bool())) val raiseExceptionVec = csrio.exception.bits.cf.exceptionVec
csrExceptionVec.map(_ := false.B)
csrExceptionVec(breakPoint) := io.in.valid && isEbreak
csrExceptionVec(ecallM) := priviledgeMode === ModeM && io.in.valid && isEcall
csrExceptionVec(ecallS) := priviledgeMode === ModeS && io.in.valid && isEcall
csrExceptionVec(ecallU) := priviledgeMode === ModeU && io.in.valid && isEcall
// Trigger an illegal instr exception when:
// * unimplemented csr is being read/written
// * csr access is illegal
csrExceptionVec(illegalInstr) := (isIllegalAddr || isIllegalAccess) && wen
csrExceptionVec(loadPageFault) := hasLoadPageFault
csrExceptionVec(storePageFault) := hasStorePageFault
csrExceptionVec(loadAccessFault) := hasLoadAccessFault
csrExceptionVec(storeAccessFault) := hasStoreAccessFault
val iduExceptionVec = cfIn.exceptionVec
val exceptionVec = csrExceptionVec.asUInt() | iduExceptionVec.asUInt()
cfOut.exceptionVec.zipWithIndex.map{case (e, i) => e := exceptionVec(i) }
val raiseExceptionVec = csrio.exception.bits.cf.exceptionVec.asUInt()
val exceptionNO = ExcPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(raiseExceptionVec(i), i.U, sum)) val exceptionNO = ExcPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(raiseExceptionVec(i), i.U, sum))
val causeNO = (raiseIntr << (XLEN-1)).asUInt() | Mux(raiseIntr, intrNO, exceptionNO) val causeNO = (raiseIntr << (XLEN-1)).asUInt() | Mux(raiseIntr, intrNO, exceptionNO)
......
...@@ -501,6 +501,7 @@ class ReservationStationData ...@@ -501,6 +501,7 @@ class ReservationStationData
val exuInput = io.deq.bits val exuInput = io.deq.bits
exuInput := DontCare exuInput := DontCare
exuInput.uop := uop(deq) exuInput.uop := uop(deq)
exuInput.uop.cf.exceptionVec := 0.U.asTypeOf(ExceptionVec())
val regValues = List.tabulate(srcNum)(i => dataRead(Mux(sel.valid, sel.bits, deq), i)) val regValues = List.tabulate(srcNum)(i => dataRead(Mux(sel.valid, sel.bits, deq), i))
XSDebug(io.deq.fire(), p"[regValues] " + List.tabulate(srcNum)(idx => p"reg$idx: ${Hexadecimal(regValues(idx))}").reduce((p1, p2) => p1 + " " + p2) + "\n") XSDebug(io.deq.fire(), p"[regValues] " + List.tabulate(srcNum)(idx => p"reg$idx: ${Hexadecimal(regValues(idx))}").reduce((p1, p2) => p1 + " " + p2) + "\n")
exuInput.src1 := regValues(0) exuInput.src1 := regValues(0)
...@@ -542,6 +543,7 @@ class ReservationStationData ...@@ -542,6 +543,7 @@ class ReservationStationData
bpQueue.io.redirect := io.redirect bpQueue.io.redirect := io.redirect
io.selectedUop.valid := bpQueue.io.out.valid io.selectedUop.valid := bpQueue.io.out.valid
io.selectedUop.bits := bpQueue.io.out.bits io.selectedUop.bits := bpQueue.io.out.bits
io.selectedUop.bits.cf.exceptionVec := 0.U.asTypeOf(ExceptionVec())
XSDebug(io.selectedUop.valid, p"SelUop: pc:0x${Hexadecimal(io.selectedUop.bits.cf.pc)}" + XSDebug(io.selectedUop.valid, p"SelUop: pc:0x${Hexadecimal(io.selectedUop.bits.cf.pc)}" +
p" roqIdx:${io.selectedUop.bits.roqIdx} pdest:${io.selectedUop.bits.pdest} " + p" roqIdx:${io.selectedUop.bits.roqIdx} pdest:${io.selectedUop.bits.pdest} " +
......
...@@ -54,12 +54,9 @@ class RoqEnqIO extends XSBundle { ...@@ -54,12 +54,9 @@ class RoqEnqIO extends XSBundle {
class RoqDispatchData extends RoqCommitInfo { class RoqDispatchData extends RoqCommitInfo {
val crossPageIPFFix = Bool() val crossPageIPFFix = Bool()
val exceptionVec = Vec(16, Bool())
} }
class RoqWbData extends XSBundle { class RoqWbData extends XSBundle {
// mostly for exceptions
val exceptionVec = Vec(16, Bool())
val fflags = UInt(5.W) val fflags = UInt(5.W)
val flushPipe = Bool() val flushPipe = Bool()
} }
...@@ -70,7 +67,7 @@ class RoqDeqPtrWrapper extends XSModule with HasCircularQueuePtrHelper { ...@@ -70,7 +67,7 @@ class RoqDeqPtrWrapper extends XSModule with HasCircularQueuePtrHelper {
val state = Input(UInt(2.W)) val state = Input(UInt(2.W))
val deq_v = Vec(CommitWidth, Input(Bool())) val deq_v = Vec(CommitWidth, Input(Bool()))
val deq_w = Vec(CommitWidth, Input(Bool())) val deq_w = Vec(CommitWidth, Input(Bool()))
val deq_exceptionVec = Vec(CommitWidth, Input(UInt(16.W))) val deq_exceptionVec = Vec(CommitWidth, Input(ExceptionVec()))
val deq_flushPipe = Vec(CommitWidth, Input(Bool())) val deq_flushPipe = Vec(CommitWidth, Input(Bool()))
// for flush: when exception occurs, reset deqPtrs to range(0, CommitWidth) // for flush: when exception occurs, reset deqPtrs to range(0, CommitWidth)
val intrBitSetReg = Input(Bool()) val intrBitSetReg = Input(Bool())
...@@ -83,15 +80,16 @@ class RoqDeqPtrWrapper extends XSModule with HasCircularQueuePtrHelper { ...@@ -83,15 +80,16 @@ class RoqDeqPtrWrapper extends XSModule with HasCircularQueuePtrHelper {
val deqPtrVec = RegInit(VecInit((0 until CommitWidth).map(_.U.asTypeOf(new RoqPtr)))) val deqPtrVec = RegInit(VecInit((0 until CommitWidth).map(_.U.asTypeOf(new RoqPtr))))
val possibleException = VecInit(io.deq_exceptionVec.map(selectAll(_, false)))
// for exceptions (flushPipe included) and interrupts: // for exceptions (flushPipe included) and interrupts:
// only consider the first instruction // only consider the first instruction
val intrEnable = io.intrBitSetReg && !io.hasNoSpecExec && !CommitType.isLoadStore(io.commitType) val intrEnable = io.intrBitSetReg && !io.hasNoSpecExec && !CommitType.isLoadStore(io.commitType)
val exceptionEnable = io.deq_w(0) && (io.deq_exceptionVec(0).orR || io.deq_flushPipe(0)) val exceptionEnable = io.deq_w(0) && (possibleException(0).asUInt.orR || io.deq_flushPipe(0))
val redirectOutValid = io.state === 0.U && io.deq_v(0) && (intrEnable || exceptionEnable) val redirectOutValid = io.state === 0.U && io.deq_v(0) && (intrEnable || exceptionEnable)
// for normal commits: only to consider when there're no exceptions // for normal commits: only to consider when there're no exceptions
// we don't need to consider whether the first instruction has exceptions since it wil trigger exceptions. // we don't need to consider whether the first instruction has exceptions since it wil trigger exceptions.
val commitBlocked = VecInit((0 until CommitWidth).map(i => if (i == 0) false.B else io.deq_exceptionVec(i).orR || io.deq_flushPipe(i))) val commitBlocked = VecInit((0 until CommitWidth).map(i => if (i == 0) false.B else possibleException(i).asUInt.orR || io.deq_flushPipe(i)))
val canCommit = VecInit((0 until CommitWidth).map(i => io.deq_v(i) && io.deq_w(i) && !commitBlocked(i))) val canCommit = VecInit((0 until CommitWidth).map(i => io.deq_v(i) && io.deq_w(i) && !commitBlocked(i)))
val normalCommitCnt = PriorityEncoder(canCommit.map(c => !c) :+ true.B) val normalCommitCnt = PriorityEncoder(canCommit.map(c => !c) :+ true.B)
// when io.intrBitSetReg, only one instruction is allowed to commit // when io.intrBitSetReg, only one instruction is allowed to commit
...@@ -118,7 +116,7 @@ class RoqEnqPtrWrapper extends XSModule with HasCircularQueuePtrHelper { ...@@ -118,7 +116,7 @@ class RoqEnqPtrWrapper extends XSModule with HasCircularQueuePtrHelper {
val state = Input(UInt(2.W)) val state = Input(UInt(2.W))
val deq_v = Input(Bool()) val deq_v = Input(Bool())
val deq_w = Input(Bool()) val deq_w = Input(Bool())
val deq_exceptionVec = Input(UInt(16.W)) val deq_exceptionVec = Input(ExceptionVec())
val deq_flushPipe = Input(Bool()) val deq_flushPipe = Input(Bool())
val intrBitSetReg = Input(Bool()) val intrBitSetReg = Input(Bool())
val hasNoSpecExec = Input(Bool()) val hasNoSpecExec = Input(Bool())
...@@ -137,7 +135,7 @@ class RoqEnqPtrWrapper extends XSModule with HasCircularQueuePtrHelper { ...@@ -137,7 +135,7 @@ class RoqEnqPtrWrapper extends XSModule with HasCircularQueuePtrHelper {
// for exceptions (flushPipe included) and interrupts: // for exceptions (flushPipe included) and interrupts:
// only consider the first instruction // only consider the first instruction
val intrEnable = io.intrBitSetReg && !io.hasNoSpecExec && !CommitType.isLoadStore(io.commitType) val intrEnable = io.intrBitSetReg && !io.hasNoSpecExec && !CommitType.isLoadStore(io.commitType)
val exceptionEnable = io.deq_w && (io.deq_exceptionVec.orR || io.deq_flushPipe) val exceptionEnable = io.deq_w && (selectAll(io.deq_exceptionVec, false).asUInt.orR || io.deq_flushPipe)
val redirectOutValid = io.state === 0.U && io.deq_v && (intrEnable || exceptionEnable) val redirectOutValid = io.state === 0.U && io.deq_v && (intrEnable || exceptionEnable)
// enqueue // enqueue
...@@ -264,28 +262,8 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper { ...@@ -264,28 +262,8 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
val writebackData = Module(new SyncDataModuleTemplate(new RoqWbData, RoqSize, CommitWidth, numWbPorts)) val writebackData = Module(new SyncDataModuleTemplate(new RoqWbData, RoqSize, CommitWidth, numWbPorts))
val writebackDataRead = writebackData.io.rdata val writebackDataRead = writebackData.io.rdata
def mergeExceptionVec(dpData: RoqDispatchData, wbData: RoqWbData) = { val exceptionVecWritePortNum = RenameWidth + 1 + 2 + 2 // CSR, 2*load, 2*store
// these exceptions can be determined before dispatch. val exceptionData = Module(new SyncDataModuleTemplate(ExceptionVec(), RoqSize, CommitWidth, exceptionVecWritePortNum))
// by default, let all exceptions be determined by dispatch.
// mergeVec(instrAddrMisaligned) := dpData(instrAddrMisaligned)
// mergeVec(instrAccessFault) := dpData(instrAccessFault)
// mergeVec(instrPageFault) := dpData(instrPageFault)
val mergeVec = WireInit(dpData.exceptionVec)
// these exceptions are determined in execution units
mergeVec(illegalInstr) := wbData.exceptionVec(illegalInstr)
mergeVec(breakPoint) := wbData.exceptionVec(breakPoint)
mergeVec(loadAddrMisaligned) := wbData.exceptionVec(loadAddrMisaligned)
mergeVec(loadAccessFault) := wbData.exceptionVec(loadAccessFault)
mergeVec(storeAddrMisaligned) := wbData.exceptionVec(storeAddrMisaligned)
mergeVec(storeAccessFault) := wbData.exceptionVec(storeAccessFault)
mergeVec(ecallU) := wbData.exceptionVec(ecallU)
mergeVec(ecallS) := wbData.exceptionVec(ecallS)
mergeVec(ecallM) := wbData.exceptionVec(ecallM)
mergeVec(loadPageFault) := wbData.exceptionVec(loadPageFault)
mergeVec(storePageFault) := wbData.exceptionVec(storePageFault)
// returns the merged exception vector
mergeVec
}
io.roqDeqPtr := deqPtr io.roqDeqPtr := deqPtr
...@@ -357,7 +335,7 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper { ...@@ -357,7 +335,7 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
val deqWritebackData = writebackDataRead(0) val deqWritebackData = writebackDataRead(0)
val debug_deqUop = debug_microOp(deqPtr.value) val debug_deqUop = debug_microOp(deqPtr.value)
val deqExceptionVec = mergeExceptionVec(deqDispatchData, deqWritebackData) val deqExceptionVec = exceptionData.io.rdata(0)
// For MMIO instructions, they should not trigger interrupts since they may be sent to lower level before it writes back. // For MMIO instructions, they should not trigger interrupts since they may be sent to lower level before it writes back.
// However, we cannot determine whether a load/store instruction is MMIO. // However, we cannot determine whether a load/store instruction is MMIO.
// Thus, we don't allow load/store instructions to trigger an interrupt. // Thus, we don't allow load/store instructions to trigger an interrupt.
...@@ -419,7 +397,7 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper { ...@@ -419,7 +397,7 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
io.commits.isWalk := state =/= s_idle io.commits.isWalk := state =/= s_idle
val commit_v = Mux(state === s_idle, VecInit(deqPtrVec.map(ptr => valid(ptr.value))), VecInit(walkPtrVec.map(ptr => valid(ptr.value)))) val commit_v = Mux(state === s_idle, VecInit(deqPtrVec.map(ptr => valid(ptr.value))), VecInit(walkPtrVec.map(ptr => valid(ptr.value))))
val commit_w = VecInit(deqPtrVec.map(ptr => writebacked(ptr.value))) val commit_w = VecInit(deqPtrVec.map(ptr => writebacked(ptr.value)))
val commit_exception = dispatchDataRead.zip(writebackDataRead).map{ case (d, w) => mergeExceptionVec(d, w).asUInt.orR } val commit_exception = exceptionData.io.rdata.map(_.asUInt.orR)
val commit_block = VecInit((0 until CommitWidth).map(i => !commit_w(i) || commit_exception(i) || writebackDataRead(i).flushPipe)) val commit_block = VecInit((0 until CommitWidth).map(i => !commit_w(i) || commit_exception(i) || writebackDataRead(i).flushPipe))
for (i <- 0 until CommitWidth) { for (i <- 0 until CommitWidth) {
// defaults: state === s_idle and instructions commit // defaults: state === s_idle and instructions commit
...@@ -493,7 +471,7 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper { ...@@ -493,7 +471,7 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
deqPtrGenModule.io.state := state deqPtrGenModule.io.state := state
deqPtrGenModule.io.deq_v := commit_v deqPtrGenModule.io.deq_v := commit_v
deqPtrGenModule.io.deq_w := commit_w deqPtrGenModule.io.deq_w := commit_w
deqPtrGenModule.io.deq_exceptionVec := VecInit(dispatchDataRead.zip(writebackDataRead).map{ case (d, w) => mergeExceptionVec(d, w).asUInt }) deqPtrGenModule.io.deq_exceptionVec := exceptionData.io.rdata
deqPtrGenModule.io.deq_flushPipe := writebackDataRead.map(_.flushPipe) deqPtrGenModule.io.deq_flushPipe := writebackDataRead.map(_.flushPipe)
deqPtrGenModule.io.intrBitSetReg := intrBitSetReg deqPtrGenModule.io.intrBitSetReg := intrBitSetReg
deqPtrGenModule.io.hasNoSpecExec := hasNoSpecExec deqPtrGenModule.io.hasNoSpecExec := hasNoSpecExec
...@@ -505,7 +483,7 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper { ...@@ -505,7 +483,7 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
enqPtrGenModule.io.state := state enqPtrGenModule.io.state := state
enqPtrGenModule.io.deq_v := commit_v(0) enqPtrGenModule.io.deq_v := commit_v(0)
enqPtrGenModule.io.deq_w := commit_w(0) enqPtrGenModule.io.deq_w := commit_w(0)
enqPtrGenModule.io.deq_exceptionVec := deqExceptionVec.asUInt enqPtrGenModule.io.deq_exceptionVec := deqExceptionVec
enqPtrGenModule.io.deq_flushPipe := writebackDataRead(0).flushPipe enqPtrGenModule.io.deq_flushPipe := writebackDataRead(0).flushPipe
enqPtrGenModule.io.intrBitSetReg := intrBitSetReg enqPtrGenModule.io.intrBitSetReg := intrBitSetReg
enqPtrGenModule.io.hasNoSpecExec := hasNoSpecExec enqPtrGenModule.io.hasNoSpecExec := hasNoSpecExec
...@@ -598,7 +576,7 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper { ...@@ -598,7 +576,7 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
// enqueue logic set 6 writebacked to false // enqueue logic set 6 writebacked to false
for (i <- 0 until RenameWidth) { for (i <- 0 until RenameWidth) {
when (canEnqueue(i)) { when (canEnqueue(i)) {
writebacked(enqPtrVec(i).value) := false.B writebacked(enqPtrVec(i).value) := selectFrontend(io.enq.req(i).bits.cf.exceptionVec, false).asUInt.orR
} }
} }
// writeback logic set numWbPorts writebacked to true // writeback logic set numWbPorts writebacked to true
...@@ -639,19 +617,41 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper { ...@@ -639,19 +617,41 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
wdata.sqIdx := req.sqIdx wdata.sqIdx := req.sqIdx
wdata.pc := req.cf.pc wdata.pc := req.cf.pc
wdata.crossPageIPFFix := req.cf.crossPageIPFFix wdata.crossPageIPFFix := req.cf.crossPageIPFFix
wdata.exceptionVec := req.cf.exceptionVec // wdata.exceptionVec := req.cf.exceptionVec
} }
dispatchData.io.raddr := commitReadAddr_next dispatchData.io.raddr := commitReadAddr_next
writebackData.io.wen := io.exeWbResults.map(_.valid) writebackData.io.wen := io.exeWbResults.map(_.valid)
writebackData.io.waddr := io.exeWbResults.map(_.bits.uop.roqIdx.value) writebackData.io.waddr := io.exeWbResults.map(_.bits.uop.roqIdx.value)
writebackData.io.wdata.zip(io.exeWbResults.map(_.bits)).map{ case (wdata, wb) => writebackData.io.wdata.zip(io.exeWbResults.map(_.bits)).map{ case (wdata, wb) =>
wdata.exceptionVec := wb.uop.cf.exceptionVec
wdata.fflags := wb.fflags wdata.fflags := wb.fflags
wdata.flushPipe := wb.uop.ctrl.flushPipe wdata.flushPipe := wb.uop.ctrl.flushPipe
} }
writebackData.io.raddr := commitReadAddr_next writebackData.io.raddr := commitReadAddr_next
for (i <- 0 until RenameWidth) {
exceptionData.io.wen(i) := canEnqueue(i)
exceptionData.io.waddr(i) := enqPtrVec(i).value
exceptionData.io.wdata(i) := selectAll(io.enq.req(i).bits.cf.exceptionVec, false, true)
}
def connectWbExc(index: Int, i: Int) = {
exceptionData.io.wen(index) := io.exeWbResults(i).valid
exceptionData.io.waddr(index) := io.exeWbResults(i).bits.uop.roqIdx.value
}
// csr
connectWbExc(RenameWidth, 6)
exceptionData.io.wdata(RenameWidth) := selectCSR(io.exeWbResults(6).bits.uop.cf.exceptionVec)
// load
connectWbExc(RenameWidth+1, 4)
exceptionData.io.wdata(RenameWidth+1) := selectAtomics(io.exeWbResults(4).bits.uop.cf.exceptionVec)
connectWbExc(RenameWidth+2, 5)
exceptionData.io.wdata(RenameWidth+2) := selectAtomics(io.exeWbResults(5).bits.uop.cf.exceptionVec)
// store
connectWbExc(RenameWidth+3, 16)
exceptionData.io.wdata(RenameWidth+3) := selectStore(io.exeWbResults(16).bits.uop.cf.exceptionVec)
connectWbExc(RenameWidth+4, 17)
exceptionData.io.wdata(RenameWidth+4) := selectStore(io.exeWbResults(17).bits.uop.cf.exceptionVec)
exceptionData.io.raddr := VecInit(deqPtrVec_next.map(_.value))
/** /**
* debug info * debug info
......
...@@ -41,7 +41,6 @@ class LsPipelineBundle extends XSBundle { ...@@ -41,7 +41,6 @@ class LsPipelineBundle extends XSBundle {
val miss = Bool() val miss = Bool()
val tlbMiss = Bool() val tlbMiss = Bool()
val mmio = Bool() val mmio = Bool()
val rollback = Bool()
val forwardMask = Vec(8, Bool()) val forwardMask = Vec(8, Bool())
val forwardData = Vec(8, UInt(8.W)) val forwardData = Vec(8, UInt(8.W))
......
...@@ -10,6 +10,7 @@ import xiangshan.cache.{DCacheLineIO, DCacheWordIO, MemoryOpConstants, TlbReques ...@@ -10,6 +10,7 @@ import xiangshan.cache.{DCacheLineIO, DCacheWordIO, MemoryOpConstants, TlbReques
import xiangshan.backend.LSUOpType import xiangshan.backend.LSUOpType
import xiangshan.mem._ import xiangshan.mem._
import xiangshan.backend.roq.RoqPtr import xiangshan.backend.roq.RoqPtr
import xiangshan.backend.fu.HasExceptionNO
class LqPtr extends CircularQueuePtr(LqPtr.LoadQueueSize) { } class LqPtr extends CircularQueuePtr(LqPtr.LoadQueueSize) { }
...@@ -58,6 +59,7 @@ class LoadQueue extends XSModule ...@@ -58,6 +59,7 @@ class LoadQueue extends XSModule
with HasDCacheParameters with HasDCacheParameters
with HasCircularQueuePtrHelper with HasCircularQueuePtrHelper
with HasLoadHelper with HasLoadHelper
with HasExceptionNO
{ {
val io = IO(new Bundle() { val io = IO(new Bundle() {
val enq = new LqEnqIO val enq = new LqEnqIO
...@@ -150,7 +152,7 @@ class LoadQueue extends XSModule ...@@ -150,7 +152,7 @@ class LoadQueue extends XSModule
vaddrModule.io.wen(i) := false.B vaddrModule.io.wen(i) := false.B
when(io.loadIn(i).fire()) { when(io.loadIn(i).fire()) {
when(io.loadIn(i).bits.miss) { when(io.loadIn(i).bits.miss) {
XSInfo(io.loadIn(i).valid, "load miss write to lq idx %d pc 0x%x vaddr %x paddr %x data %x mask %x forwardData %x forwardMask: %x mmio %x roll %x exc %x\n", XSInfo(io.loadIn(i).valid, "load miss write to lq idx %d pc 0x%x vaddr %x paddr %x data %x mask %x forwardData %x forwardMask: %x mmio %x\n",
io.loadIn(i).bits.uop.lqIdx.asUInt, io.loadIn(i).bits.uop.lqIdx.asUInt,
io.loadIn(i).bits.uop.cf.pc, io.loadIn(i).bits.uop.cf.pc,
io.loadIn(i).bits.vaddr, io.loadIn(i).bits.vaddr,
...@@ -159,12 +161,10 @@ class LoadQueue extends XSModule ...@@ -159,12 +161,10 @@ class LoadQueue extends XSModule
io.loadIn(i).bits.mask, io.loadIn(i).bits.mask,
io.loadIn(i).bits.forwardData.asUInt, io.loadIn(i).bits.forwardData.asUInt,
io.loadIn(i).bits.forwardMask.asUInt, io.loadIn(i).bits.forwardMask.asUInt,
io.loadIn(i).bits.mmio, io.loadIn(i).bits.mmio
io.loadIn(i).bits.rollback,
io.loadIn(i).bits.uop.cf.exceptionVec.asUInt
) )
}.otherwise { }.otherwise {
XSInfo(io.loadIn(i).valid, "load hit write to cbd lqidx %d pc 0x%x vaddr %x paddr %x data %x mask %x forwardData %x forwardMask: %x mmio %x roll %x exc %x\n", XSInfo(io.loadIn(i).valid, "load hit write to cbd lqidx %d pc 0x%x vaddr %x paddr %x data %x mask %x forwardData %x forwardMask: %x mmio %x\n",
io.loadIn(i).bits.uop.lqIdx.asUInt, io.loadIn(i).bits.uop.lqIdx.asUInt,
io.loadIn(i).bits.uop.cf.pc, io.loadIn(i).bits.uop.cf.pc,
io.loadIn(i).bits.vaddr, io.loadIn(i).bits.vaddr,
...@@ -173,9 +173,7 @@ class LoadQueue extends XSModule ...@@ -173,9 +173,7 @@ class LoadQueue extends XSModule
io.loadIn(i).bits.mask, io.loadIn(i).bits.mask,
io.loadIn(i).bits.forwardData.asUInt, io.loadIn(i).bits.forwardData.asUInt,
io.loadIn(i).bits.forwardMask.asUInt, io.loadIn(i).bits.forwardMask.asUInt,
io.loadIn(i).bits.mmio, io.loadIn(i).bits.mmio
io.loadIn(i).bits.rollback,
io.loadIn(i).bits.uop.cf.exceptionVec.asUInt
) )
} }
val loadWbIndex = io.loadIn(i).bits.uop.lqIdx.value val loadWbIndex = io.loadIn(i).bits.uop.lqIdx.value
...@@ -187,7 +185,6 @@ class LoadQueue extends XSModule ...@@ -187,7 +185,6 @@ class LoadQueue extends XSModule
loadWbData.mask := io.loadIn(i).bits.mask loadWbData.mask := io.loadIn(i).bits.mask
loadWbData.data := io.loadIn(i).bits.data // fwd data loadWbData.data := io.loadIn(i).bits.data // fwd data
loadWbData.fwdMask := io.loadIn(i).bits.forwardMask loadWbData.fwdMask := io.loadIn(i).bits.forwardMask
loadWbData.exception := io.loadIn(i).bits.uop.cf.exceptionVec.asUInt
dataModule.io.wbWrite(i, loadWbIndex, loadWbData) dataModule.io.wbWrite(i, loadWbIndex, loadWbData)
dataModule.io.wb.wen(i) := true.B dataModule.io.wb.wen(i) := true.B
...@@ -196,11 +193,10 @@ class LoadQueue extends XSModule ...@@ -196,11 +193,10 @@ class LoadQueue extends XSModule
vaddrModule.io.wen(i) := true.B vaddrModule.io.wen(i) := true.B
debug_mmio(loadWbIndex) := io.loadIn(i).bits.mmio debug_mmio(loadWbIndex) := io.loadIn(i).bits.mmio
val dcacheMissed = io.loadIn(i).bits.miss && !io.loadIn(i).bits.mmio val dcacheMissed = io.loadIn(i).bits.miss && !io.loadIn(i).bits.mmio
miss(loadWbIndex) := dcacheMissed && !io.loadIn(i).bits.uop.cf.exceptionVec.asUInt.orR miss(loadWbIndex) := dcacheMissed
// listening(loadWbIndex) := dcacheMissed pending(loadWbIndex) := io.loadIn(i).bits.mmio
pending(loadWbIndex) := io.loadIn(i).bits.mmio && !io.loadIn(i).bits.uop.cf.exceptionVec.asUInt.orR
} }
} }
...@@ -312,7 +308,7 @@ class LoadQueue extends XSModule ...@@ -312,7 +308,7 @@ class LoadQueue extends XSModule
loadWbSelVGen(0):= loadEvenSelVec.asUInt.orR loadWbSelVGen(0):= loadEvenSelVec.asUInt.orR
loadWbSelGen(1) := Cat(getFirstOne(loadOddSelVec, oddDeqMask), 1.U(1.W)) loadWbSelGen(1) := Cat(getFirstOne(loadOddSelVec, oddDeqMask), 1.U(1.W))
loadWbSelVGen(1) := loadOddSelVec.asUInt.orR loadWbSelVGen(1) := loadOddSelVec.asUInt.orR
val loadWbSel = Wire(Vec(LoadPipelineWidth, UInt(log2Up(LoadQueueSize).W))) val loadWbSel = Wire(Vec(LoadPipelineWidth, UInt(log2Up(LoadQueueSize).W)))
val loadWbSelV = RegInit(VecInit(List.fill(LoadPipelineWidth)(false.B))) val loadWbSelV = RegInit(VecInit(List.fill(LoadPipelineWidth)(false.B)))
(0 until LoadPipelineWidth).map(i => { (0 until LoadPipelineWidth).map(i => {
...@@ -333,7 +329,7 @@ class LoadQueue extends XSModule ...@@ -333,7 +329,7 @@ class LoadQueue extends XSModule
wbSelectedMask(i) := UIntToOH(loadWbSelGen(i)) wbSelectedMask(i) := UIntToOH(loadWbSelGen(i))
} }
}) })
// Stage 1 // Stage 1
// Use indexes generated in cycle 0 to read data // Use indexes generated in cycle 0 to read data
// writeback data to cdb // writeback data to cdb
...@@ -357,10 +353,9 @@ class LoadQueue extends XSModule ...@@ -357,10 +353,9 @@ class LoadQueue extends XSModule
val rdataPartialLoad = rdataHelper(seluop, rdataSel) val rdataPartialLoad = rdataHelper(seluop, rdataSel)
// writeback missed int/fp load // writeback missed int/fp load
// //
// Int load writeback will finish (if not blocked) in one cycle // Int load writeback will finish (if not blocked) in one cycle
io.ldout(i).bits.uop := seluop io.ldout(i).bits.uop := seluop
io.ldout(i).bits.uop.cf.exceptionVec := dataModule.io.wb.rdata(i).exception.asBools
io.ldout(i).bits.uop.lqIdx := loadWbSel(i).asTypeOf(new LqPtr) io.ldout(i).bits.uop.lqIdx := loadWbSel(i).asTypeOf(new LqPtr)
io.ldout(i).bits.data := rdataPartialLoad io.ldout(i).bits.data := rdataPartialLoad
io.ldout(i).bits.redirectValid := false.B io.ldout(i).bits.redirectValid := false.B
......
...@@ -15,7 +15,6 @@ class LQDataEntry extends XSBundle { ...@@ -15,7 +15,6 @@ class LQDataEntry extends XSBundle {
val paddr = UInt(PAddrBits.W) val paddr = UInt(PAddrBits.W)
val mask = UInt(8.W) val mask = UInt(8.W)
val data = UInt(XLEN.W) val data = UInt(XLEN.W)
val exception = UInt(16.W) // TODO: opt size
val fwdMask = Vec(8, Bool()) val fwdMask = Vec(8, Bool())
} }
...@@ -236,7 +235,6 @@ class LoadQueueData(size: Int, wbNumRead: Int, wbNumWrite: Int) extends XSModule ...@@ -236,7 +235,6 @@ class LoadQueueData(size: Int, wbNumRead: Int, wbNumWrite: Int) extends XSModule
// data module // data module
val paddrModule = Module(new PaddrModule(size, numRead = 3, numWrite = 2)) val paddrModule = Module(new PaddrModule(size, numRead = 3, numWrite = 2))
val maskModule = Module(new MaskModule(size, numRead = 3, numWrite = 2)) val maskModule = Module(new MaskModule(size, numRead = 3, numWrite = 2))
val exceptionModule = Module(new AsyncDataModuleTemplate(UInt(16.W), size, numRead = 3, numWrite = 2))
val coredataModule = Module(new CoredataModule(size, numRead = 3, numWrite = 3)) val coredataModule = Module(new CoredataModule(size, numRead = 3, numWrite = 3))
// read data // read data
...@@ -244,26 +242,22 @@ class LoadQueueData(size: Int, wbNumRead: Int, wbNumWrite: Int) extends XSModule ...@@ -244,26 +242,22 @@ class LoadQueueData(size: Int, wbNumRead: Int, wbNumWrite: Int) extends XSModule
(0 until wbNumRead).map(i => { (0 until wbNumRead).map(i => {
paddrModule.io.raddr(i) := io.wb.raddr(i) paddrModule.io.raddr(i) := io.wb.raddr(i)
maskModule.io.raddr(i) := io.wb.raddr(i) maskModule.io.raddr(i) := io.wb.raddr(i)
exceptionModule.io.raddr(i) := io.wb.raddr(i)
coredataModule.io.raddr(i) := io.wb.raddr(i) coredataModule.io.raddr(i) := io.wb.raddr(i)
io.wb.rdata(i).paddr := paddrModule.io.rdata(i) io.wb.rdata(i).paddr := paddrModule.io.rdata(i)
io.wb.rdata(i).mask := maskModule.io.rdata(i) io.wb.rdata(i).mask := maskModule.io.rdata(i)
io.wb.rdata(i).data := coredataModule.io.rdata(i) io.wb.rdata(i).data := coredataModule.io.rdata(i)
io.wb.rdata(i).exception := exceptionModule.io.rdata(i)
io.wb.rdata(i).fwdMask := DontCare io.wb.rdata(i).fwdMask := DontCare
}) })
// read port wbNumRead // read port wbNumRead
paddrModule.io.raddr(wbNumRead) := io.uncache.raddr paddrModule.io.raddr(wbNumRead) := io.uncache.raddr
maskModule.io.raddr(wbNumRead) := io.uncache.raddr maskModule.io.raddr(wbNumRead) := io.uncache.raddr
exceptionModule.io.raddr(wbNumRead) := io.uncache.raddr
coredataModule.io.raddr(wbNumRead) := io.uncache.raddr coredataModule.io.raddr(wbNumRead) := io.uncache.raddr
io.uncache.rdata.paddr := paddrModule.io.rdata(wbNumRead) io.uncache.rdata.paddr := paddrModule.io.rdata(wbNumRead)
io.uncache.rdata.mask := maskModule.io.rdata(wbNumRead) io.uncache.rdata.mask := maskModule.io.rdata(wbNumRead)
io.uncache.rdata.data := exceptionModule.io.rdata(wbNumRead) io.uncache.rdata.data := coredataModule.io.rdata(wbNumRead)
io.uncache.rdata.exception := coredataModule.io.rdata(wbNumRead)
io.uncache.rdata.fwdMask := DontCare io.uncache.rdata.fwdMask := DontCare
// write data // write data
...@@ -271,19 +265,16 @@ class LoadQueueData(size: Int, wbNumRead: Int, wbNumWrite: Int) extends XSModule ...@@ -271,19 +265,16 @@ class LoadQueueData(size: Int, wbNumRead: Int, wbNumWrite: Int) extends XSModule
(0 until wbNumWrite).map(i => { (0 until wbNumWrite).map(i => {
paddrModule.io.wen(i) := false.B paddrModule.io.wen(i) := false.B
maskModule.io.wen(i) := false.B maskModule.io.wen(i) := false.B
exceptionModule.io.wen(i) := false.B
coredataModule.io.wen(i) := false.B coredataModule.io.wen(i) := false.B
coredataModule.io.fwdMaskWen(i) := false.B coredataModule.io.fwdMaskWen(i) := false.B
coredataModule.io.paddrWen(i) := false.B coredataModule.io.paddrWen(i) := false.B
paddrModule.io.waddr(i) := io.wb.waddr(i) paddrModule.io.waddr(i) := io.wb.waddr(i)
maskModule.io.waddr(i) := io.wb.waddr(i) maskModule.io.waddr(i) := io.wb.waddr(i)
exceptionModule.io.waddr(i) := io.wb.waddr(i)
coredataModule.io.waddr(i) := io.wb.waddr(i) coredataModule.io.waddr(i) := io.wb.waddr(i)
paddrModule.io.wdata(i) := io.wb.wdata(i).paddr paddrModule.io.wdata(i) := io.wb.wdata(i).paddr
maskModule.io.wdata(i) := io.wb.wdata(i).mask maskModule.io.wdata(i) := io.wb.wdata(i).mask
exceptionModule.io.wdata(i) := io.wb.wdata(i).exception
coredataModule.io.wdata(i) := io.wb.wdata(i).data coredataModule.io.wdata(i) := io.wb.wdata(i).data
coredataModule.io.fwdMaskWdata(i) := io.wb.wdata(i).fwdMask.asUInt coredataModule.io.fwdMaskWdata(i) := io.wb.wdata(i).fwdMask.asUInt
coredataModule.io.paddrWdata(i) := io.wb.wdata(i).paddr coredataModule.io.paddrWdata(i) := io.wb.wdata(i).paddr
...@@ -291,7 +282,6 @@ class LoadQueueData(size: Int, wbNumRead: Int, wbNumWrite: Int) extends XSModule ...@@ -291,7 +282,6 @@ class LoadQueueData(size: Int, wbNumRead: Int, wbNumWrite: Int) extends XSModule
when(io.wb.wen(i)){ when(io.wb.wen(i)){
paddrModule.io.wen(i) := true.B paddrModule.io.wen(i) := true.B
maskModule.io.wen(i) := true.B maskModule.io.wen(i) := true.B
exceptionModule.io.wen(i) := true.B
coredataModule.io.wen(i) := true.B coredataModule.io.wen(i) := true.B
coredataModule.io.fwdMaskWen(i) := true.B coredataModule.io.fwdMaskWen(i) := true.B
coredataModule.io.paddrWen(i) := true.B coredataModule.io.paddrWen(i) := true.B
......
...@@ -52,8 +52,6 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue ...@@ -52,8 +52,6 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
dataModule.io := DontCare dataModule.io := DontCare
val vaddrModule = Module(new AsyncDataModuleTemplate(UInt(VAddrBits.W), StoreQueueSize, numRead = 1, numWrite = StorePipelineWidth)) val vaddrModule = Module(new AsyncDataModuleTemplate(UInt(VAddrBits.W), StoreQueueSize, numRead = 1, numWrite = StorePipelineWidth))
vaddrModule.io := DontCare vaddrModule.io := DontCare
val exceptionModule = Module(new AsyncDataModuleTemplate(UInt(16.W), StoreQueueSize, numRead = StorePipelineWidth, numWrite = StorePipelineWidth))
exceptionModule.io := DontCare
// state & misc // state & misc
val allocated = RegInit(VecInit(List.fill(StoreQueueSize)(false.B))) // sq entry has been allocated val allocated = RegInit(VecInit(List.fill(StoreQueueSize)(false.B))) // sq entry has been allocated
...@@ -83,7 +81,6 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue ...@@ -83,7 +81,6 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
dataModule.io.raddr(i) := deqPtrExt(i).value dataModule.io.raddr(i) := deqPtrExt(i).value
} }
vaddrModule.io.raddr(0) := io.exceptionAddr.lsIdx.sqIdx.value vaddrModule.io.raddr(0) := io.exceptionAddr.lsIdx.sqIdx.value
exceptionModule.io.raddr(0) := deqPtr // read exception
/** /**
* Enqueue at dispatch * Enqueue at dispatch
...@@ -123,14 +120,11 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue ...@@ -123,14 +120,11 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
for (i <- 0 until StorePipelineWidth) { for (i <- 0 until StorePipelineWidth) {
dataModule.io.wen(i) := false.B dataModule.io.wen(i) := false.B
vaddrModule.io.wen(i) := false.B vaddrModule.io.wen(i) := false.B
exceptionModule.io.wen(i) := false.B when (io.storeIn(i).fire()) {
when(io.storeIn(i).fire()) {
val stWbIndex = io.storeIn(i).bits.uop.sqIdx.value val stWbIndex = io.storeIn(i).bits.uop.sqIdx.value
val hasException = io.storeIn(i).bits.uop.cf.exceptionVec.asUInt.orR datavalid(stWbIndex) := !io.storeIn(i).bits.mmio
val hasWritebacked = !io.storeIn(i).bits.mmio || hasException writebacked(stWbIndex) := !io.storeIn(i).bits.mmio
datavalid(stWbIndex) := hasWritebacked pending(stWbIndex) := io.storeIn(i).bits.mmio
writebacked(stWbIndex) := hasWritebacked
pending(stWbIndex) := !hasWritebacked // valid mmio require
val storeWbData = Wire(new SQDataEntry) val storeWbData = Wire(new SQDataEntry)
storeWbData := DontCare storeWbData := DontCare
...@@ -145,21 +139,15 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue ...@@ -145,21 +139,15 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
vaddrModule.io.wdata(i) := io.storeIn(i).bits.vaddr vaddrModule.io.wdata(i) := io.storeIn(i).bits.vaddr
vaddrModule.io.wen(i) := true.B vaddrModule.io.wen(i) := true.B
exceptionModule.io.waddr(i) := stWbIndex
exceptionModule.io.wdata(i) := io.storeIn(i).bits.uop.cf.exceptionVec.asUInt
exceptionModule.io.wen(i) := true.B
mmio(stWbIndex) := io.storeIn(i).bits.mmio mmio(stWbIndex) := io.storeIn(i).bits.mmio
XSInfo("store write to sq idx %d pc 0x%x vaddr %x paddr %x data %x mmio %x roll %x exc %x\n", XSInfo("store write to sq idx %d pc 0x%x vaddr %x paddr %x data %x mmio %x\n",
io.storeIn(i).bits.uop.sqIdx.value, io.storeIn(i).bits.uop.sqIdx.value,
io.storeIn(i).bits.uop.cf.pc, io.storeIn(i).bits.uop.cf.pc,
io.storeIn(i).bits.vaddr, io.storeIn(i).bits.vaddr,
io.storeIn(i).bits.paddr, io.storeIn(i).bits.paddr,
io.storeIn(i).bits.data, io.storeIn(i).bits.data,
io.storeIn(i).bits.mmio, io.storeIn(i).bits.mmio
io.storeIn(i).bits.rollback,
io.storeIn(i).bits.uop.cf.exceptionVec.asUInt
) )
} }
} }
...@@ -258,7 +246,6 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue ...@@ -258,7 +246,6 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
io.mmioStout.valid := allocated(deqPtr) && datavalid(deqPtr) && !writebacked(deqPtr) io.mmioStout.valid := allocated(deqPtr) && datavalid(deqPtr) && !writebacked(deqPtr)
io.mmioStout.bits.uop := uop(deqPtr) io.mmioStout.bits.uop := uop(deqPtr)
io.mmioStout.bits.uop.sqIdx := deqPtrExt(0) io.mmioStout.bits.uop.sqIdx := deqPtrExt(0)
io.mmioStout.bits.uop.cf.exceptionVec := exceptionModule.io.rdata(0).asBools
io.mmioStout.bits.data := dataModuleRead(0).data // dataModuleRead.read(deqPtr) io.mmioStout.bits.data := dataModuleRead(0).data // dataModuleRead.read(deqPtr)
io.mmioStout.bits.redirectValid := false.B io.mmioStout.bits.redirectValid := false.B
io.mmioStout.bits.redirect := DontCare io.mmioStout.bits.redirect := DontCare
......
...@@ -25,6 +25,7 @@ class AtomicsUnit extends XSModule with MemoryOpConstants{ ...@@ -25,6 +25,7 @@ class AtomicsUnit extends XSModule with MemoryOpConstants{
val s_invalid :: s_tlb :: s_flush_sbuffer_req :: s_flush_sbuffer_resp :: s_cache_req :: s_cache_resp :: s_finish :: Nil = Enum(7) val s_invalid :: s_tlb :: s_flush_sbuffer_req :: s_flush_sbuffer_resp :: s_cache_req :: s_cache_resp :: s_finish :: Nil = Enum(7)
val state = RegInit(s_invalid) val state = RegInit(s_invalid)
val in = Reg(new ExuInput()) val in = Reg(new ExuInput())
val exceptionVec = RegInit(0.U.asTypeOf(ExceptionVec()))
val atom_override_xtval = RegInit(false.B) val atom_override_xtval = RegInit(false.B)
// paddr after translation // paddr after translation
val paddr = Reg(UInt()) val paddr = Reg(UInt())
...@@ -89,11 +90,11 @@ class AtomicsUnit extends XSModule with MemoryOpConstants{ ...@@ -89,11 +90,11 @@ class AtomicsUnit extends XSModule with MemoryOpConstants{
"b10".U -> (in.src1(1,0) === 0.U), //w "b10".U -> (in.src1(1,0) === 0.U), //w
"b11".U -> (in.src1(2,0) === 0.U) //d "b11".U -> (in.src1(2,0) === 0.U) //d
)) ))
in.uop.cf.exceptionVec(storeAddrMisaligned) := !addrAligned exceptionVec(storeAddrMisaligned) := !addrAligned
in.uop.cf.exceptionVec(storePageFault) := io.dtlb.resp.bits.excp.pf.st exceptionVec(storePageFault) := io.dtlb.resp.bits.excp.pf.st
in.uop.cf.exceptionVec(loadPageFault) := io.dtlb.resp.bits.excp.pf.ld exceptionVec(loadPageFault) := io.dtlb.resp.bits.excp.pf.ld
in.uop.cf.exceptionVec(storeAccessFault) := io.dtlb.resp.bits.excp.af.st exceptionVec(storeAccessFault) := io.dtlb.resp.bits.excp.af.st
in.uop.cf.exceptionVec(loadAccessFault) := io.dtlb.resp.bits.excp.af.ld exceptionVec(loadAccessFault) := io.dtlb.resp.bits.excp.af.ld
val exception = !addrAligned || val exception = !addrAligned ||
io.dtlb.resp.bits.excp.pf.st || io.dtlb.resp.bits.excp.pf.st ||
io.dtlb.resp.bits.excp.pf.ld || io.dtlb.resp.bits.excp.pf.ld ||
...@@ -215,6 +216,7 @@ class AtomicsUnit extends XSModule with MemoryOpConstants{ ...@@ -215,6 +216,7 @@ class AtomicsUnit extends XSModule with MemoryOpConstants{
when (state === s_finish) { when (state === s_finish) {
io.out.valid := true.B io.out.valid := true.B
io.out.bits.uop := in.uop io.out.bits.uop := in.uop
io.out.bits.uop.cf.exceptionVec := exceptionVec
io.out.bits.uop.diffTestDebugLrScValid := is_lrsc_valid io.out.bits.uop.diffTestDebugLrScValid := is_lrsc_valid
io.out.bits.data := resp_data io.out.bits.data := resp_data
io.out.bits.redirectValid := false.B io.out.bits.redirectValid := false.B
......
...@@ -91,7 +91,7 @@ class LoadUnit_S1 extends XSModule { ...@@ -91,7 +91,7 @@ class LoadUnit_S1 extends XSModule {
val s1_uop = io.in.bits.uop val s1_uop = io.in.bits.uop
val s1_paddr = io.dtlbResp.bits.paddr val s1_paddr = io.dtlbResp.bits.paddr
val s1_exception = io.out.bits.uop.cf.exceptionVec.asUInt.orR val s1_exception = selectLoad(io.out.bits.uop.cf.exceptionVec, false).asUInt.orR
val s1_tlb_miss = io.dtlbResp.bits.miss val s1_tlb_miss = io.dtlbResp.bits.miss
val s1_mmio = !s1_tlb_miss && io.dtlbResp.bits.mmio val s1_mmio = !s1_tlb_miss && io.dtlbResp.bits.mmio
val s1_mask = io.in.bits.mask val s1_mask = io.in.bits.mask
...@@ -148,7 +148,7 @@ class LoadUnit_S2 extends XSModule with HasLoadHelper { ...@@ -148,7 +148,7 @@ class LoadUnit_S2 extends XSModule with HasLoadHelper {
val s2_paddr = io.in.bits.paddr val s2_paddr = io.in.bits.paddr
val s2_tlb_miss = io.in.bits.tlbMiss val s2_tlb_miss = io.in.bits.tlbMiss
val s2_mmio = io.in.bits.mmio val s2_mmio = io.in.bits.mmio
val s2_exception = io.in.bits.uop.cf.exceptionVec.asUInt.orR val s2_exception = selectLoad(io.in.bits.uop.cf.exceptionVec, false).asUInt.orR
val s2_cache_miss = io.dcacheResp.bits.miss val s2_cache_miss = io.dcacheResp.bits.miss
val s2_cache_replay = io.dcacheResp.bits.replay val s2_cache_replay = io.dcacheResp.bits.replay
...@@ -193,7 +193,9 @@ class LoadUnit_S2 extends XSModule with HasLoadHelper { ...@@ -193,7 +193,9 @@ class LoadUnit_S2 extends XSModule with HasLoadHelper {
// so we do not need to care about flush in load / store unit's out.valid // so we do not need to care about flush in load / store unit's out.valid
io.out.bits := io.in.bits io.out.bits := io.in.bits
io.out.bits.data := rdataPartialLoad io.out.bits.data := rdataPartialLoad
io.out.bits.miss := s2_cache_miss && !fullForward // when exception occurs, set it to not miss and let it write back to roq (via int port)
io.out.bits.miss := s2_cache_miss && !fullForward && !s2_exception
io.out.bits.uop.ctrl.fpWen := io.in.bits.uop.ctrl.fpWen && !s2_exception
io.out.bits.mmio := s2_mmio io.out.bits.mmio := s2_mmio
io.in.ready := io.out.ready || !io.in.valid io.in.ready := io.out.ready || !io.in.valid
...@@ -270,12 +272,14 @@ class LoadUnit extends XSModule with HasLoadHelper { ...@@ -270,12 +272,14 @@ class LoadUnit extends XSModule with HasLoadHelper {
// Load queue will be updated at s2 for both hit/miss int/fp load // Load queue will be updated at s2 for both hit/miss int/fp load
io.lsq.loadIn.valid := load_s2.io.out.valid io.lsq.loadIn.valid := load_s2.io.out.valid
io.lsq.loadIn.bits := load_s2.io.out.bits io.lsq.loadIn.bits := load_s2.io.out.bits
val s2Valid = load_s2.io.out.valid && (!load_s2.io.out.bits.miss || load_s2.io.out.bits.uop.cf.exceptionVec.asUInt.orR)
// write to rob and writeback bus
val s2_wb_valid = load_s2.io.out.valid && !load_s2.io.out.bits.miss
val refillFpLoad = io.lsq.ldout.bits.uop.ctrl.fpWen val refillFpLoad = io.lsq.ldout.bits.uop.ctrl.fpWen
// Int load, if hit, will be writebacked at s2 // Int load, if hit, will be writebacked at s2
val intHitLoadOut = Wire(Valid(new ExuOutput)) val intHitLoadOut = Wire(Valid(new ExuOutput))
intHitLoadOut.valid := s2Valid && !load_s2.io.out.bits.uop.ctrl.fpWen intHitLoadOut.valid := s2_wb_valid && !load_s2.io.out.bits.uop.ctrl.fpWen
intHitLoadOut.bits.uop := load_s2.io.out.bits.uop intHitLoadOut.bits.uop := load_s2.io.out.bits.uop
intHitLoadOut.bits.data := load_s2.io.out.bits.data intHitLoadOut.bits.data := load_s2.io.out.bits.data
intHitLoadOut.bits.redirectValid := false.B intHitLoadOut.bits.redirectValid := false.B
...@@ -289,10 +293,10 @@ class LoadUnit extends XSModule with HasLoadHelper { ...@@ -289,10 +293,10 @@ class LoadUnit extends XSModule with HasLoadHelper {
io.ldout.bits := Mux(intHitLoadOut.valid, intHitLoadOut.bits, io.lsq.ldout.bits) io.ldout.bits := Mux(intHitLoadOut.valid, intHitLoadOut.bits, io.lsq.ldout.bits)
io.ldout.valid := intHitLoadOut.valid || io.lsq.ldout.valid && !refillFpLoad io.ldout.valid := intHitLoadOut.valid || io.lsq.ldout.valid && !refillFpLoad
// Fp load, if hit, will be send to recoder at s2, then it will be recoded & writebacked at s3 // Fp load, if hit, will be send to recoder at s2, then it will be recoded & writebacked at s3
val fpHitLoadOut = Wire(Valid(new ExuOutput)) val fpHitLoadOut = Wire(Valid(new ExuOutput))
fpHitLoadOut.valid := s2Valid && load_s2.io.out.bits.uop.ctrl.fpWen fpHitLoadOut.valid := s2_wb_valid && load_s2.io.out.bits.uop.ctrl.fpWen
fpHitLoadOut.bits := intHitLoadOut.bits fpHitLoadOut.bits := intHitLoadOut.bits
val fpLoadOut = Wire(Valid(new ExuOutput)) val fpLoadOut = Wire(Valid(new ExuOutput))
......
...@@ -90,7 +90,7 @@ class StoreUnit_S1 extends XSModule { ...@@ -90,7 +90,7 @@ class StoreUnit_S1 extends XSModule {
io.lsq.bits.uop.cf.exceptionVec(storeAccessFault) := io.dtlbResp.bits.excp.af.st io.lsq.bits.uop.cf.exceptionVec(storeAccessFault) := io.dtlbResp.bits.excp.af.st
// mmio inst with exception will be writebacked immediately // mmio inst with exception will be writebacked immediately
val hasException = io.out.bits.uop.cf.exceptionVec.asUInt.orR val hasException = selectStore(io.out.bits.uop.cf.exceptionVec, false).asUInt.orR
io.out.valid := io.in.valid && (!io.out.bits.mmio || hasException) && !s1_tlb_miss io.out.valid := io.in.valid && (!io.out.bits.mmio || hasException) && !s1_tlb_miss
io.out.bits := io.lsq.bits io.out.bits := io.lsq.bits
......
...@@ -110,6 +110,10 @@ package object xiangshan { ...@@ -110,6 +110,10 @@ package object xiangshan {
def isException(level: UInt) = level(1) && level(0) def isException(level: UInt) = level(1) && level(0)
} }
object ExceptionVec {
def apply() = Vec(16, Bool())
}
object PMAMode { object PMAMode {
def R = "b1".U << 0 //readable def R = "b1".U << 0 //readable
def W = "b1".U << 1 //writeable def W = "b1".U << 1 //writeable
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册