import chisel3._ import chisel3.util._ import _root_.circt.stage.ChiselStage class OoOBackend(p: CoreParams = CoreParams()) extends Module { private val physBits = log2Ceil(p.physRegs) private val robBits = log2Ceil(p.robEntries) val io = IO(new Bundle { val decodeValid = Input(Vec(p.issueWidth, Bool())) val decode = Input(Vec(p.issueWidth, new DecodedInst(p))) val decodeReady = Output(Bool()) val commitValid = Output(Vec(p.issueWidth, Bool())) 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 sfenceVma = Output(Bool()) val setPriv = Output(Bool()) val targetPriv = Output(UInt(2.W)) val dmemReqValid = Output(Bool()) val dmemReq = Output(new MemRequest(p)) val dmemRespValid = Input(Bool()) val dmemRespData = Input(UInt(p.xlen.W)) val satp = Input(UInt(p.xlen.W)) val satpOut = Output(UInt(p.xlen.W)) val currentPriv = Input(UInt(2.W)) }) val rename = Module(new RenameStage(p)) val issue = Module(new IssueStage(p)) val prf = Module(new PhysicalRegFile(p)) val exec = Seq.fill(p.issueWidth)(Module(new ExecStage(p))) val wb = Seq.fill(p.issueWidth)(Module(new WriteBackStage(p))) val commit = Module(new CommitStage(p)) val lq = Module(new LoadQueue(p)) val sq = Module(new StoreQueue(p)) val lsu = Module(new LSU(p)) val csr = Module(new CSRFile(p)) val completeValid = Wire(Vec(p.issueWidth, Bool())) val completeIdx = Wire(Vec(p.issueWidth, UInt(robBits.W))) val completeException = Wire(Vec(p.issueWidth, Bool())) val completeCause = Wire(Vec(p.issueWidth, UInt(p.xlen.W))) val completeBadAddr = Wire(Vec(p.issueWidth, UInt(p.xlen.W))) val completeMispredict = Wire(Vec(p.issueWidth, Bool())) val completeRedirectPc = Wire(Vec(p.issueWidth, UInt(p.xlen.W))) val completeCsrValid = Wire(Vec(p.issueWidth, Bool())) val completeCsrAddr = Wire(Vec(p.issueWidth, UInt(12.W))) val completeCsrCmd = Wire(Vec(p.issueWidth, UInt(3.W))) val completeCsrRs1 = Wire(Vec(p.issueWidth, UInt(p.xlen.W))) val completeCsrZimm = Wire(Vec(p.issueWidth, UInt(5.W))) val completeFenceI = Wire(Vec(p.issueWidth, Bool())) val completeSfenceVma = Wire(Vec(p.issueWidth, Bool())) val completeXret = Wire(Vec(p.issueWidth, Bool())) val completeXretIsMret = Wire(Vec(p.issueWidth, Bool())) val wakeup = Wire(Vec(p.issueWidth, new Wakeup(p))) val wakeupReg = RegInit(VecInit(Seq.fill(p.issueWidth)(0.U.asTypeOf(new Wakeup(p))))) val csrRData = Wire(Vec(p.issueWidth, UInt(p.xlen.W))) dontTouch(completeValid) dontTouch(completeIdx) dontTouch(completeException) dontTouch(completeCause) dontTouch(completeRedirectPc) rename.io.inValid := VecInit((0 until p.issueWidth).map(i => io.decodeValid(i) && issue.io.inReady(i))) rename.io.in := io.decode rename.io.wbValid := VecInit(wb.map(_.io.wen)) rename.io.wbPhys := VecInit(wb.map(_.io.waddr)) rename.io.completeValid := completeValid rename.io.completeIdx := completeIdx rename.io.completeException := completeException rename.io.completeCause := completeCause rename.io.completeBadAddr := completeBadAddr rename.io.completeMispredict := completeMispredict rename.io.completeRedirectPc := completeRedirectPc rename.io.completeCsrValid := completeCsrValid rename.io.completeCsrAddr := completeCsrAddr rename.io.completeCsrCmd := completeCsrCmd rename.io.completeCsrRs1 := completeCsrRs1 rename.io.completeCsrZimm := completeCsrZimm rename.io.completeFenceI := completeFenceI rename.io.completeSfenceVma := completeSfenceVma rename.io.completeXret := completeXret rename.io.completeXretIsMret := completeXretIsMret rename.io.commitReady := commit.io.commitReady rename.io.commitMapValid := commit.io.commitMapValid rename.io.commitArch := commit.io.commitArch rename.io.commitPhys := commit.io.commitPhys rename.io.commitFreeOld := commit.io.freeOldPhys rename.io.commitOldPhys := commit.io.oldPhys rename.io.flush := commit.io.flush issue.io.inValid := rename.io.outValid issue.io.in := rename.io.out issue.io.wakeup := wakeupReg issue.io.robHeadValid := rename.io.commitEntry(0).valid issue.io.robHeadIdx := rename.io.commitEntry(0).robIdx val loadPending = RegInit(false.B) val loadPendingRob = Reg(UInt(robBits.W)) val loadPendingPhys = Reg(UInt(physBits.W)) val loadPendingLq = Reg(UInt(log2Ceil(p.loadQueueEntries).W)) 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 loadRespFault = !forwardPending && (lsu.io.pageFault || lsu.io.accessFault || lsu.io.misaligned) val storeCheckPending = RegInit(false.B) val storeCheckPendingRob = Reg(UInt(robBits.W)) dontTouch(storeCheckPending) val storeCheckRespNow = Wire(Bool()) val storeCheckRespPending = storeCheckPending && lsu.io.respValid val storeCheckResp = storeCheckRespNow || storeCheckRespPending val storeCheckFault = storeCheckResp && (lsu.io.pageFault || lsu.io.accessFault || lsu.io.misaligned) 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) } val csrReadReq = Wire(Vec(p.issueWidth, Bool())) for (i <- 0 until p.issueWidth) { val decoded = issue.io.out(i).decoded csrReadReq(i) := issue.io.outValid(i) && decoded.isSystem && decoded.funct3 =/= 0.U } val stallSecondCsrRead = csrReadReq(0) && csrReadReq(1) val memSlot0 = memIssue(0) val memSlot1 = !memSlot0 && memIssue(1) val memSlot = Mux(memSlot0, 0.U, 1.U) val canIssueMem = !loadPending && !forwardPending && !storeCheckPending 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 serializing0 = issue.io.out(0).decoded.isSystem || issue.io.out(0).decoded.isFenceI || issue.io.out(0).decoded.isSfenceVma || issue.io.out(0).decoded.isWfi val serializing1 = issue.io.out(1).decoded.isSystem || issue.io.out(1).decoded.isFenceI || issue.io.out(1).decoded.isSfenceVma || issue.io.out(1).decoded.isWfi val serializingReady0 = !serializing0 || (rename.io.commitEntry(0).valid && rename.io.commitEntry(0).robIdx === issue.io.out(0).robIdx) val serializingReady1 = !serializing1 || (rename.io.commitEntry(0).valid && rename.io.commitEntry(0).robIdx === issue.io.out(1).robIdx) dontTouch(serializingReady0) dontTouch(serializingReady1) 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 robHeadValid = rename.io.commitEntry(0).valid val issue0AtHead = robHeadValid && rename.io.commitEntry(0).robIdx === issue.io.out(0).robIdx val issue1AtHead = robHeadValid && rename.io.commitEntry(0).robIdx === issue.io.out(1).robIdx val olderSerializingAtHead0 = robHeadValid && !issue0AtHead && (rename.io.commitEntry(0).csrValid || rename.io.commitEntry(0).fenceI || rename.io.commitEntry(0).sfenceVma || rename.io.commitEntry(0).xret) val olderSerializingAtHead1 = robHeadValid && !issue1AtHead && (rename.io.commitEntry(0).csrValid || rename.io.commitEntry(0).fenceI || rename.io.commitEntry(0).sfenceVma || rename.io.commitEntry(0).xret) val memReady0 = (!isMem0 || (lsu.io.reqReady && canIssueMem && !amoBlocked0 && !loadBlocked0)) && !loadPending && !forwardPending && serializingReady0 && !olderSerializingAtHead0 val memReady1 = (!isMem1 || (lsu.io.reqReady && canIssueMem && !memSlot0 && !amoBlocked1 && !loadBlocked1)) && serializingReady1 && !olderSerializingAtHead1 val baseIssueReady0 = memReady0 && !storeCheckPending val baseIssueReady1 = memReady1 && !storeCheckPending val slot0WouldIssueSerializing = issue.io.outValid(0) && baseIssueReady0 && serializing0 val slot1WouldIssueSerializing = issue.io.outValid(1) && baseIssueReady1 && serializing1 issue_io_outReady_0 := baseIssueReady0 && !slot1WouldIssueSerializing issue_io_outReady_1 := baseIssueReady1 && !slot0WouldIssueSerializing && !(stallSecondCsrRead && issue_io_outReady_0) issue.io.outReady := VecInit(Seq(issue_io_outReady_0, issue_io_outReady_1)) val issueFire = Wire(Vec(p.issueWidth, Bool())) for (i <- 0 until p.issueWidth) { issueFire(i) := issue.io.outValid(i) && issue.io.outReady(i) } issue.io.flush := commit.io.flush io.decodeReady := rename.io.canAccept && issue.io.inReady.asUInt.andR 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.isAmo, 0.U, Mux(memDecoded.isStore, memDecoded.immS, memDecoded.immI)) def accessBytes(size: UInt): UInt = MuxLookup(size, 8.U(4.W))(Seq( 0.U -> 1.U(4.W), 1.U -> 2.U(4.W), 2.U -> 4.U(4.W), 3.U -> 8.U(4.W) )) val loadEnq = (memSlot0 || memSlot1) && memDecoded.isLoad && issue.io.outReady(memSlot) val storeEnq = (memSlot0 || memSlot1) && memDecoded.isStore && issue.io.outReady(memSlot) val sqForwardValid = sq.io.forwardValid && !memDecoded.isAmo val forwardLoad = loadEnq && sqForwardValid val lsuLoadReq = loadEnq && !sqForwardValid val lsuStoreCheckReq = storeEnq 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 lq.io.addrValid := loadEnq lq.io.addrIdx := lq.io.enqIdx lq.io.addr := memAddr lq.io.size := memDecoded.memWidth lq.io.complete := loadRespValid 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 lq.io.storeSize := memDecoded.memWidth lq.io.flush := commit.io.flush sq.io.enqValid := storeEnq sq.io.enqRobIdx := issue.io.out(memSlot).robIdx sq.io.writeAddr := storeEnq sq.io.writeData := storeEnq sq.io.writeIdx := sq.io.enqIdx sq.io.addr := memAddr sq.io.data := memSrc2 sq.io.size := memDecoded.memWidth sq.io.loadAddr := memAddr sq.io.loadSize := memDecoded.memWidth sq.io.loadRobIdx := issue.io.out(memSlot).robIdx val commitStore0 = commit.io.commitReady(0) && rename.io.commitValid(0) && rename.io.commitEntry(0).opClass === Consts.OP_STORE val commitStore1 = commit.io.commitReady(1) && rename.io.commitValid(1) && rename.io.commitEntry(1).opClass === Consts.OP_STORE sq.io.commitValid := commitStore0 || commitStore1 sq.io.commitRobIdx := Mux(commitStore0, rename.io.commitEntry(0).robIdx, rename.io.commitEntry(1).robIdx) val storeDrainFire = sq.io.drainValid && !lsuLoadReq && !lsuStoreCheckReq && lsu.io.reqReady sq.io.drainReady := storeDrainFire sq.io.flush := commit.io.flush lsu.io.reqValid := lsuLoadReq || lsuStoreCheckReq || storeDrainFire lsu.io.checkOnly := lsuStoreCheckReq lsu.io.sfenceVma := commit.io.sfenceVma lsu.io.currentPriv := io.currentPriv lsu.io.mstatus := csr.io.mstatus 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 val storeCheckReq = WireDefault(0.U.asTypeOf(new MemRequest(p))) storeCheckReq.addr := memAddr storeCheckReq.data := memSrc2 storeCheckReq.isStore := true.B storeCheckReq.isSigned := false.B storeCheckReq.isAmo := false.B storeCheckReq.amoOp := 0.U storeCheckReq.size := memDecoded.memWidth lsu.io.req := Mux(lsuLoadReq, loadReq, Mux(lsuStoreCheckReq, storeCheckReq, sq.io.drain)) storeCheckRespNow := lsuStoreCheckReq && lsu.io.respValid lsu.io.dmemRespValid := io.dmemRespValid lsu.io.dmemRespData := io.dmemRespData lsu.io.satp := csr.io.satp io.satpOut := csr.io.satp io.dmemReqValid := lsu.io.dmemReqValid io.dmemReq := lsu.io.dmemReq val csrReadFire = VecInit((0 until p.issueWidth).map(i => csrReadReq(i) && issue.io.outReady(i))) csr.io.readAddr := Mux(csrReadFire(0), issue.io.out(0).decoded.inst(31, 20), issue.io.out(1).decoded.inst(31, 20)) csr.io.currentPriv := io.currentPriv csrRData(0) := csr.io.rdata csrRData(1) := csr.io.rdata csr.io.trap := commit.io.flush && commit.io.exception csr.io.trapPc := commit.io.trapPc csr.io.trapCause := commit.io.exceptionCause csr.io.trapTval := commit.io.badAddr val trapTargetPriv = PrivilegeTransitions.trapTargetPriv( io.currentPriv, commit.io.exceptionCause, false.B, csr.io.medeleg, csr.io.mideleg) csr.io.trapTargetPriv := trapTargetPriv csr.io.trapIsInterrupt := false.B csr.io.xret := commit.io.flush && commit.io.xret csr.io.xretIsMret := commit.io.xretIsMret val commitCsr0 = commit.io.commitReady(0) && rename.io.commitValid(0) && rename.io.commitEntry(0).csrValid val commitCsr1 = commit.io.commitReady(1) && rename.io.commitValid(1) && rename.io.commitEntry(1).csrValid val commitCsrEntry = Mux(commitCsr0, rename.io.commitEntry(0), rename.io.commitEntry(1)) csr.io.cmd.valid := commitCsr0 || commitCsr1 csr.io.cmd.addr := commitCsrEntry.csrAddr csr.io.cmd.cmd := commitCsrEntry.csrCmd csr.io.cmd.rs1 := commitCsrEntry.csrRs1 csr.io.cmd.zimm := commitCsrEntry.csrZimm when(commit.io.flush) { loadPending := false.B forwardPending := false.B storeCheckPending := 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 loadPendingLq := lq.io.enqIdx }.elsewhen(loadRespValid) { loadPending := false.B } when(!commit.io.flush) { when(storeCheckRespPending) { storeCheckPending := false.B }.elsewhen(lsuStoreCheckReq && !storeCheckRespNow) { storeCheckPending := true.B storeCheckPendingRob := issue.io.out(memSlot).robIdx } } for (i <- 0 until p.issueWidth) { prf.io.raddr(2 * i) := issue.io.out(i).prs1 prf.io.raddr(2 * i + 1) := issue.io.out(i).prs2 } for (i <- 0 until p.issueWidth) { val decoded = issue.io.out(i).decoded val src1Raw = prf.io.rdata(2 * i) val rs2Raw = prf.io.rdata(2 * i + 1) val src1 = MuxCase(src1Raw, (0 until p.issueWidth).map(w => (wakeupReg(w).valid && wakeupReg(w).phys =/= 0.U && wakeupReg(w).phys === issue.io.out(i).prs1) -> wakeupReg(w).data)) val rs2Val = MuxCase(rs2Raw, (0 until p.issueWidth).map(w => (wakeupReg(w).valid && wakeupReg(w).phys =/= 0.U && wakeupReg(w).phys === issue.io.out(i).prs2) -> wakeupReg(w).data)) val src2 = Mux(decoded.isOpImm || decoded.isLoad || decoded.isJalr, decoded.immI, rs2Val) exec(i).io.inValid := issueFire(i) exec(i).io.in := decoded exec(i).io.src1 := src1 exec(i).io.src2 := src2 val branchTarget = decoded.pc + decoded.immB val jalTarget = decoded.pc + decoded.immJ val jalrTarget = (src1 + decoded.immI) & (~1.U(p.xlen.W)) val controlTarget = Mux(decoded.isJal, jalTarget, Mux(decoded.isJalr, jalrTarget, branchTarget)) val controlTargetMisaligned = issueFire(i) && (decoded.isJal || decoded.isJalr || (decoded.isBranch && exec(i).io.branchTaken)) && controlTarget(1, 0) =/= 0.U dontTouch(controlTargetMisaligned) val branchRedirect = Mux(decoded.isJal, jalTarget, Mux(decoded.isJalr, jalrTarget, Mux(decoded.isBranch && exec(i).io.branchTaken, branchTarget, decoded.pc + 4.U))) val isEcall = decoded.isEcall val isEbreak = decoded.isEbreak val isMret = decoded.isMret val illegalPriv = (decoded.isMret && io.currentPriv =/= Privileged.PRV_M) || (decoded.isSret && io.currentPriv === Privileged.PRV_U) || (decoded.isSfenceVma && io.currentPriv === Privileged.PRV_U) val csrReadIllegal = csrReadFire(i) && csr.io.readIllegal val csrWrites = decoded.isSystem && decoded.funct3 =/= 0.U && !(decoded.funct3(1) && decoded.rs1 === 0.U) val csrWriteIllegal = csrWrites && !CSRPermission.writeAllowed(decoded.inst(31, 20), io.currentPriv) val illegalInst = !decoded.fetchException && (decoded.illegal || illegalPriv || csrReadIllegal || csrWriteIllegal) val dataAddr = src1 + Mux(decoded.isStore, decoded.immS, decoded.immI) val dataMisaligned = (dataAddr(2, 0) & (accessBytes(decoded.memWidth) - 1.U)) =/= 0.U val storeMisaligned = issueFire(i) && decoded.isStore && dataMisaligned val loadFaultNow = lsuLoadReq && lsu.io.respValid && (lsu.io.misaligned || lsu.io.pageFault || lsu.io.accessFault) val issueRaisesException = issueFire(i) && (decoded.fetchException || illegalInst || isEcall || isEbreak || lq.io.violation || storeMisaligned || controlTargetMisaligned) val loadRespHasFault = loadRespFault || loadFaultNow val isLoadRespSlot = i.U === 0.U && loadRespValid && !loadRespHasFault val useExecWb = exec(i).io.outValid && decoded.writesRd && !decoded.isLoad && !issueRaisesException wb(i).io.valid := useExecWb || isLoadRespSlot 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))))) prf.io.wen(i) := wb(i).io.wen prf.io.waddr(i) := wb(i).io.waddr prf.io.wdata(i) := wb(i).io.wdata wakeup(i).valid := wb(i).io.wen wakeup(i).phys := wb(i).io.waddr wakeup(i).data := wb(i).io.wdata val completeLoadResp = i.U === 0.U && (loadRespValid || loadFaultNow) val completeStoreResp = (i.U === 0.U && storeCheckRespPending) || (storeCheckRespNow && issueFire(i) && decoded.isStore) completeValid(i) := (issueFire(i) && !decoded.isLoad && !decoded.isStore) || completeLoadResp || completeStoreResp val storeCompleteIdx = Mux(storeCheckRespPending, storeCheckPendingRob, issue.io.out(i).robIdx) completeIdx(i) := Mux(completeStoreResp, storeCompleteIdx, Mux(completeLoadResp, Mux(loadFaultNow, issue.io.out(memSlot).robIdx, Mux(forwardPending, forwardPendingRob, loadPendingRob)), issue.io.out(i).robIdx)) val issueException = issueRaisesException val thisStoreCheckFault = completeStoreResp && storeCheckFault completeException(i) := issueException || (completeLoadResp && (loadRespFault || loadFaultNow)) || thisStoreCheckFault completeCause(i) := Mux(thisStoreCheckFault || (completeLoadResp && (loadRespFault || loadFaultNow)), lsu.io.faultCause, Mux(issueFire(i) && decoded.fetchException, decoded.fetchExceptionCause, Mux(issueFire(i) && isEbreak, Privileged.CAUSE_BREAKPOINT, Mux(issueFire(i) && isEcall, ExceptionSource.ecallCause(io.currentPriv), Mux(storeMisaligned, Privileged.CAUSE_STORE_ADDR_MISALIGNED, Mux(controlTargetMisaligned, Privileged.CAUSE_INSTR_ADDR_MISALIGNED, Mux(issueFire(i) && illegalInst, Privileged.CAUSE_ILLEGAL_INSTRUCTION, 0.U))))))) completeBadAddr(i) := Mux(thisStoreCheckFault || (completeLoadResp && (loadRespFault || loadFaultNow)), lsu.io.faultAddr, Mux(storeMisaligned, dataAddr, Mux(issueFire(i) && decoded.fetchException, decoded.fetchExceptionTval, Mux(controlTargetMisaligned, controlTarget, Mux(issueFire(i) && illegalInst, decoded.inst.pad(p.xlen), 0.U))))) completeMispredict(i) := issueFire(i) && (decoded.isJal || decoded.isJalr || decoded.isXret || decoded.isFenceI || decoded.isSfenceVma || decoded.isWfi || (decoded.isBranch && exec(i).io.branchTaken)) completeRedirectPc(i) := Mux(isEcall || isEbreak, csr.io.trapVector, Mux(decoded.isXret, PrivilegeTransitions.xretTargetPc(decoded.isMret, csr.io.mepc, csr.io.sepc), Mux(decoded.isWfi, decoded.pc + 4.U, branchRedirect))) completeCsrValid(i) := issueFire(i) && decoded.isSystem && decoded.funct3 =/= 0.U && !(decoded.funct3(1) && decoded.rs1 === 0.U) && !illegalInst completeCsrAddr(i) := decoded.inst(31, 20) completeCsrCmd(i) := decoded.funct3 completeCsrRs1(i) := src1 completeCsrZimm(i) := decoded.rs1 completeFenceI(i) := issueFire(i) && decoded.isFenceI completeSfenceVma(i) := issueFire(i) && decoded.isSfenceVma completeXret(i) := issueFire(i) && decoded.isXret completeXretIsMret(i) := issueFire(i) && decoded.isMret } wakeupReg := wakeup commit.io.robValid := rename.io.commitValid commit.io.robEntry := rename.io.commitEntry io.commitValid := VecInit((0 until p.issueWidth).map(i => rename.io.commitValid(i) && commit.io.commitReady(i))) io.commitEntry := rename.io.commitEntry io.flush := commit.io.flush val xretRedirectPc = PrivilegeTransitions.xretTargetPc(commit.io.xretIsMret, csr.io.mepc, csr.io.sepc) dontTouch(xretRedirectPc) io.redirectPc := Mux(commit.io.exception, csr.io.trapVector, Mux(commit.io.xret, xretRedirectPc, commit.io.redirectPc)) io.invalidateICache := commit.io.fenceI io.sfenceVma := commit.io.sfenceVma io.setPriv := commit.io.setPriv io.targetPriv := Mux(commit.io.exception, trapTargetPriv, Mux(commit.io.xret, PrivilegeTransitions.xretNextPriv(commit.io.xretIsMret, csr.io.mstatus), io.currentPriv)) } object OoOBackend extends App { ChiselStage.emitSystemVerilogFile( new OoOBackend(), args = Array("--target-dir", "generated"), firtoolOpts = Array("-disable-all-randomization", "-strip-debug-info") ) }