fix: pass remaining riscv isa tests
This commit is contained in:
@@ -15,6 +15,7 @@ class OoOBackend(p: CoreParams = CoreParams()) extends Module {
|
||||
val commitEntry = Output(Vec(p.issueWidth, new RobEntry(p)))
|
||||
val flush = Output(Bool())
|
||||
val redirectPc = Output(UInt(p.xlen.W))
|
||||
val invalidateICache = Output(Bool())
|
||||
|
||||
val dmemReqValid = Output(Bool())
|
||||
val dmemReq = Output(new MemRequest(p))
|
||||
@@ -81,7 +82,14 @@ class OoOBackend(p: CoreParams = CoreParams()) extends Module {
|
||||
val loadPendingRob = Reg(UInt(robBits.W))
|
||||
val loadPendingPhys = Reg(UInt(physBits.W))
|
||||
val loadPendingLq = Reg(UInt(log2Ceil(p.loadQueueEntries).W))
|
||||
val loadRespValid = lsu.io.respValid && loadPending
|
||||
val forwardPending = RegInit(false.B)
|
||||
val forwardPendingRob = Reg(UInt(robBits.W))
|
||||
val forwardPendingPhys = Reg(UInt(physBits.W))
|
||||
val forwardPendingLq = Reg(UInt(log2Ceil(p.loadQueueEntries).W))
|
||||
val forwardPendingData = Reg(UInt(p.xlen.W))
|
||||
val loadRespValid = (lsu.io.respValid && loadPending) || forwardPending
|
||||
val loadRespData = Mux(forwardPending, forwardPendingData, lsu.io.respData)
|
||||
val loadRespPageFault = !forwardPending && lsu.io.pageFault
|
||||
val memIssue = Wire(Vec(p.issueWidth, Bool()))
|
||||
for (i <- 0 until p.issueWidth) {
|
||||
memIssue(i) := issue.io.outValid(i) && (issue.io.out(i).decoded.isLoad || issue.io.out(i).decoded.isStore)
|
||||
@@ -95,15 +103,20 @@ class OoOBackend(p: CoreParams = CoreParams()) extends Module {
|
||||
val memSlot0 = memIssue(0)
|
||||
val memSlot1 = !memSlot0 && memIssue(1)
|
||||
val memSlot = Mux(memSlot0, 0.U, 1.U)
|
||||
val canIssueMem = !loadPending
|
||||
val canIssueMem = !loadPending && !forwardPending
|
||||
val issue_io_outReady_0 = Wire(Bool())
|
||||
val issue_io_outReady_1 = Wire(Bool())
|
||||
dontTouch(issue_io_outReady_0)
|
||||
dontTouch(issue_io_outReady_1)
|
||||
val isMem0 = issue.io.out(0).decoded.isLoad || issue.io.out(0).decoded.isStore
|
||||
val isMem1 = issue.io.out(1).decoded.isLoad || issue.io.out(1).decoded.isStore
|
||||
val memReady0 = !isMem0 || (lsu.io.reqReady && canIssueMem)
|
||||
val memReady1 = !isMem1 || (lsu.io.reqReady && canIssueMem && !memSlot0)
|
||||
val loadBlocked0 = issue.io.out(0).decoded.isLoad && sq.io.forwardBlock
|
||||
val loadBlocked1 = issue.io.out(1).decoded.isLoad && sq.io.forwardBlock
|
||||
val amoBlocked0 = issue.io.out(0).decoded.isAmo && (sq.io.olderStoreValid || sq.io.drainValid)
|
||||
val amoBlocked1 = issue.io.out(1).decoded.isAmo && (sq.io.olderStoreValid || sq.io.drainValid)
|
||||
val memReady0 = (!isMem0 || (lsu.io.reqReady && canIssueMem && !amoBlocked0 && !loadBlocked0)) &&
|
||||
!loadPending && !forwardPending
|
||||
val memReady1 = !isMem1 || (lsu.io.reqReady && canIssueMem && !memSlot0 && !amoBlocked1 && !loadBlocked1)
|
||||
issue_io_outReady_0 := memReady0
|
||||
issue_io_outReady_1 := memReady1 && !stallSecondCsrRead
|
||||
issue.io.outReady := VecInit(Seq(issue_io_outReady_0, issue_io_outReady_1))
|
||||
@@ -118,11 +131,22 @@ class OoOBackend(p: CoreParams = CoreParams()) extends Module {
|
||||
val memDecoded = issue.io.out(memSlot).decoded
|
||||
val memSrc1 = Mux(memSlot0, prf.io.rdata(0), prf.io.rdata(2))
|
||||
val memSrc2 = Mux(memSlot0, prf.io.rdata(1), prf.io.rdata(3))
|
||||
val memAddr = memSrc1 + Mux(memDecoded.isStore, memDecoded.immS, memDecoded.immI)
|
||||
val memAddr = memSrc1 + Mux(memDecoded.isAmo, 0.U, Mux(memDecoded.isStore, memDecoded.immS, memDecoded.immI))
|
||||
|
||||
val loadEnq = (memSlot0 || memSlot1) && memDecoded.isLoad && issue.io.outReady(memSlot)
|
||||
val storeEnq = (memSlot0 || memSlot1) && memDecoded.isStore && issue.io.outReady(memSlot)
|
||||
val lsuLoadReq = loadEnq && !sq.io.forwardValid
|
||||
val sqForwardValid = sq.io.forwardValid && !memDecoded.isAmo
|
||||
val forwardLoad = loadEnq && sqForwardValid
|
||||
val lsuLoadReq = loadEnq && !sqForwardValid
|
||||
val forwardByte = sq.io.forwardData(7, 0)
|
||||
val forwardHalf = sq.io.forwardData(15, 0)
|
||||
val forwardWord = sq.io.forwardData(31, 0)
|
||||
val forwardSelected = MuxLookup(memDecoded.memWidth, sq.io.forwardData)(Seq(
|
||||
0.U -> Mux(memDecoded.memSigned, Consts.signExtend(forwardByte, 8), forwardByte),
|
||||
1.U -> Mux(memDecoded.memSigned, Consts.signExtend(forwardHalf, 16), forwardHalf),
|
||||
2.U -> Mux(memDecoded.memSigned, Consts.signExtend(forwardWord, 32), forwardWord),
|
||||
3.U -> sq.io.forwardData
|
||||
))
|
||||
|
||||
lq.io.enqValid := loadEnq
|
||||
lq.io.enqRobIdx := issue.io.out(memSlot).robIdx
|
||||
@@ -131,7 +155,11 @@ class OoOBackend(p: CoreParams = CoreParams()) extends Module {
|
||||
lq.io.addr := memAddr
|
||||
lq.io.size := memDecoded.memWidth
|
||||
lq.io.complete := loadRespValid
|
||||
lq.io.completeIdx := loadPendingLq
|
||||
lq.io.completeIdx := Mux(forwardPending, forwardPendingLq, loadPendingLq)
|
||||
lq.io.commitValid := VecInit((0 until p.issueWidth).map(i =>
|
||||
commit.io.commitReady(i) && rename.io.commitValid(i) &&
|
||||
rename.io.commitEntry(i).opClass === Consts.OP_LOAD))
|
||||
lq.io.commitRobIdx := VecInit((0 until p.issueWidth).map(i => rename.io.commitEntry(i).robIdx))
|
||||
lq.io.storeAddrValid := storeEnq
|
||||
lq.io.storeRobIdx := issue.io.out(memSlot).robIdx
|
||||
lq.io.storeAddr := memAddr
|
||||
@@ -159,13 +187,15 @@ class OoOBackend(p: CoreParams = CoreParams()) extends Module {
|
||||
sq.io.flush := commit.io.flush
|
||||
|
||||
lsu.io.reqValid := lsuLoadReq || sq.io.drainValid
|
||||
lsu.io.req := Mux(sq.io.drainValid, sq.io.drain, 0.U.asTypeOf(new MemRequest(p)))
|
||||
when(lsuLoadReq) {
|
||||
lsu.io.req.addr := memAddr
|
||||
lsu.io.req.data := 0.U
|
||||
lsu.io.req.isStore := false.B
|
||||
lsu.io.req.size := memDecoded.memWidth
|
||||
}
|
||||
val loadReq = WireDefault(0.U.asTypeOf(new MemRequest(p)))
|
||||
loadReq.addr := memAddr
|
||||
loadReq.data := memSrc2
|
||||
loadReq.isStore := false.B
|
||||
loadReq.isSigned := memDecoded.memSigned || memDecoded.isAmo
|
||||
loadReq.isAmo := memDecoded.isAmo
|
||||
loadReq.amoOp := memDecoded.amoOp
|
||||
loadReq.size := memDecoded.memWidth
|
||||
lsu.io.req := Mux(lsuLoadReq, loadReq, sq.io.drain)
|
||||
lsu.io.dmemRespValid := io.dmemRespValid
|
||||
lsu.io.dmemRespData := io.dmemRespData
|
||||
lsu.io.satp := csr.io.satp
|
||||
@@ -190,7 +220,16 @@ class OoOBackend(p: CoreParams = CoreParams()) extends Module {
|
||||
|
||||
when(commit.io.flush) {
|
||||
loadPending := false.B
|
||||
}.elsewhen(loadEnq && !sq.io.forwardValid) {
|
||||
forwardPending := false.B
|
||||
}.elsewhen(forwardLoad) {
|
||||
forwardPending := true.B
|
||||
forwardPendingRob := issue.io.out(memSlot).robIdx
|
||||
forwardPendingPhys := issue.io.out(memSlot).prd
|
||||
forwardPendingLq := lq.io.enqIdx
|
||||
forwardPendingData := forwardSelected
|
||||
}.elsewhen(forwardPending) {
|
||||
forwardPending := false.B
|
||||
}.elsewhen(loadEnq && !sqForwardValid) {
|
||||
loadPending := true.B
|
||||
loadPendingRob := issue.io.out(memSlot).robIdx
|
||||
loadPendingPhys := issue.io.out(memSlot).prd
|
||||
@@ -218,8 +257,8 @@ class OoOBackend(p: CoreParams = CoreParams()) extends Module {
|
||||
val isLoadRespSlot = i.U === 0.U && loadRespValid
|
||||
val useExecWb = exec(i).io.outValid && decoded.writesRd && !decoded.isLoad
|
||||
wb(i).io.valid := useExecWb || isLoadRespSlot
|
||||
wb(i).io.physDest := Mux(isLoadRespSlot, loadPendingPhys, issue.io.out(i).prd)
|
||||
wb(i).io.data := Mux(isLoadRespSlot, lsu.io.respData, Mux(decoded.isLui, decoded.immU,
|
||||
wb(i).io.physDest := Mux(isLoadRespSlot, Mux(forwardPending, forwardPendingPhys, loadPendingPhys), issue.io.out(i).prd)
|
||||
wb(i).io.data := Mux(isLoadRespSlot, loadRespData, Mux(decoded.isLui, decoded.immU,
|
||||
Mux(decoded.isAuipc, decoded.pc + decoded.immU,
|
||||
Mux(decoded.isJal || decoded.isJalr, decoded.pc + 4.U,
|
||||
Mux(decoded.isSystem && decoded.funct3 =/= 0.U, csrRData(i), exec(i).io.result)))))
|
||||
@@ -244,16 +283,17 @@ class OoOBackend(p: CoreParams = CoreParams()) extends Module {
|
||||
|
||||
val completeLoadResp = i.U === 0.U && loadRespValid
|
||||
completeValid(i) := (issueFire(i) && !decoded.isLoad) || completeLoadResp
|
||||
completeIdx(i) := Mux(completeLoadResp, loadPendingRob, issue.io.out(i).robIdx)
|
||||
completeIdx(i) := Mux(completeLoadResp, Mux(forwardPending, forwardPendingRob, loadPendingRob), issue.io.out(i).robIdx)
|
||||
completeException(i) := (issueFire(i) && (decoded.illegal || isEcall || isEbreak || lq.io.violation)) ||
|
||||
(completeLoadResp && lsu.io.pageFault)
|
||||
completeCause(i) := Mux(completeLoadResp && lsu.io.pageFault, 13.U,
|
||||
(completeLoadResp && loadRespPageFault)
|
||||
completeCause(i) := Mux(completeLoadResp && loadRespPageFault, 13.U,
|
||||
Mux(issueFire(i) && isEbreak, 3.U,
|
||||
Mux(issueFire(i) && isEcall, 11.U,
|
||||
Mux(issueFire(i) && decoded.illegal, 2.U, 0.U))))
|
||||
completeBadAddr(i) := decoded.pc
|
||||
completeMispredict(i) := issueFire(i) &&
|
||||
(decoded.isJal || decoded.isJalr || isMret || (decoded.isBranch && exec(i).io.branchTaken))
|
||||
(decoded.isJal || decoded.isJalr || isMret || decoded.isFenceI ||
|
||||
(decoded.isBranch && exec(i).io.branchTaken))
|
||||
completeRedirectPc(i) := Mux(isEcall || isEbreak, csr.io.mtvec, Mux(isMret, csr.io.mepc, branchRedirect))
|
||||
completeCsrValid(i) := issueFire(i) && decoded.isSystem && decoded.funct3 =/= 0.U &&
|
||||
!(decoded.funct3(1) && decoded.rs1 === 0.U)
|
||||
@@ -271,6 +311,7 @@ class OoOBackend(p: CoreParams = CoreParams()) extends Module {
|
||||
io.commitEntry := rename.io.commitEntry
|
||||
io.flush := commit.io.flush
|
||||
io.redirectPc := Mux(commit.io.exception, csr.io.mtvec, commit.io.redirectPc)
|
||||
io.invalidateICache := commit.io.fenceI
|
||||
}
|
||||
|
||||
object OoOBackend extends App {
|
||||
|
||||
Reference in New Issue
Block a user