diff --git a/chisel/playground/src/pipeline/decoder/DecoderUnit.scala b/chisel/playground/src/pipeline/decoder/DecoderUnit.scala index 7ff1311..43a5c3b 100644 --- a/chisel/playground/src/pipeline/decoder/DecoderUnit.scala +++ b/chisel/playground/src/pipeline/decoder/DecoderUnit.scala @@ -119,10 +119,11 @@ class DecoderUnit(implicit val config: CpuConfig) extends Module with HasExcepti decoder(0).io.out.info.imm ) (0 until (INT_WID)).foreach(i => io.executeStage.inst0.ex.interrupt(i) := io.csr.interrupt(i)) - io.executeStage.inst0.ex.exception.map(_ := false.B) - io.executeStage.inst0.ex.exception(illegalInstr) := !info(0).inst_legal - io.executeStage.inst0.ex.exception(instrAccessFault) := io.instFifo.inst(0).acc_err - io.executeStage.inst0.ex.exception(instrAddrMisaligned) := io.instFifo.inst(0).addr_err + io.executeStage.inst0.ex.exception.map(_ := false.B) + io.executeStage.inst0.ex.exception(illegalInstr) := !info(0).inst_legal + io.executeStage.inst0.ex.exception(instrAccessFault) := io.instFifo.inst(0).acc_err + io.executeStage.inst0.ex.exception(instrAddrMisaligned) := pc(0)(1, 0).orR || + io.fetchUnit.target(1, 0).orR && io.fetchUnit.branch io.executeStage.inst0.ex.exception(breakPoint) := info(0).inst(31, 20) === privEbreak && info(0).op === CSROpType.jmp io.executeStage.inst0.ex.exception(ecallM) := info(0).inst(31, 20) === privEcall && @@ -131,10 +132,12 @@ class DecoderUnit(implicit val config: CpuConfig) extends Module with HasExcepti info(0).op === CSROpType.jmp && priv_mode === ModeS && info(0).fusel === FuType.csr io.executeStage.inst0.ex.exception(ecallU) := info(0).inst(31, 20) === privEcall && info(0).op === CSROpType.jmp && priv_mode === ModeU && info(0).fusel === FuType.csr - io.executeStage.inst0.ex.tval := Mux( - io.executeStage.inst0.ex.exception(instrAccessFault) || io.executeStage.inst0.ex.exception(instrAddrMisaligned), - io.instFifo.inst(0).pc, - 0.U + io.executeStage.inst0.ex.tval := MuxCase( + 0.U, + Seq( + pc(0)(1, 0).orR -> pc(0), + (io.fetchUnit.target(1, 0).orR && io.fetchUnit.branch) -> io.fetchUnit.target + ) ) io.executeStage.inst0.jb_info.jump_regiser := jumpCtrl.out.jump_register @@ -157,10 +160,11 @@ class DecoderUnit(implicit val config: CpuConfig) extends Module with HasExcepti decoder(1).io.out.info.imm ) (0 until (INT_WID)).foreach(i => io.executeStage.inst1.ex.interrupt(i) := io.csr.interrupt(i)) - io.executeStage.inst1.ex.exception.map(_ := false.B) - io.executeStage.inst1.ex.exception(illegalInstr) := !info(1).inst_legal - io.executeStage.inst1.ex.exception(instrAccessFault) := io.instFifo.inst(1).acc_err - io.executeStage.inst1.ex.exception(instrAddrMisaligned) := io.instFifo.inst(1).addr_err + io.executeStage.inst1.ex.exception.map(_ := false.B) + io.executeStage.inst1.ex.exception(illegalInstr) := !info(1).inst_legal + io.executeStage.inst1.ex.exception(instrAccessFault) := io.instFifo.inst(1).acc_err + io.executeStage.inst1.ex.exception(instrAddrMisaligned) := pc(1)(1, 0).orR || + io.fetchUnit.target(1, 0).orR && io.fetchUnit.branch io.executeStage.inst1.ex.exception(breakPoint) := info(1).inst(31, 20) === privEbreak && info(1).op === CSROpType.jmp io.executeStage.inst1.ex.exception(ecallM) := info(1).inst(31, 20) === privEcall && @@ -170,10 +174,12 @@ class DecoderUnit(implicit val config: CpuConfig) extends Module with HasExcepti io.executeStage.inst1.ex.exception(ecallU) := info(1).inst(31, 20) === privEcall && info(1).op === CSROpType.jmp && priv_mode === ModeU && info(1).fusel === FuType.csr - io.executeStage.inst1.ex.tval := Mux( - io.executeStage.inst1.ex.exception(instrAccessFault) || io.executeStage.inst1.ex.exception(instrAddrMisaligned), - io.instFifo.inst(1).pc, - 0.U + io.executeStage.inst1.ex.tval := MuxCase( + 0.U, + Seq( + pc(1)(1, 0).orR -> pc(1), + (io.fetchUnit.target(1, 0).orR && io.fetchUnit.branch) -> io.fetchUnit.target + ) ) } diff --git a/chisel/playground/src/pipeline/execute/Csr.scala b/chisel/playground/src/pipeline/execute/Csr.scala index ba5a9d8..314dd6b 100644 --- a/chisel/playground/src/pipeline/execute/Csr.scala +++ b/chisel/playground/src/pipeline/execute/Csr.scala @@ -12,8 +12,8 @@ class CsrMemoryUnit(implicit val config: CpuConfig) extends Bundle { val inst = Vec( config.fuNum, new Bundle { - val pc = UInt(PC_WID.W) - val ex = new ExceptionInfo() + val pc = UInt(PC_WID.W) + val ex = new ExceptionInfo() val info = new InstInfo() } ) @@ -26,10 +26,10 @@ class CsrMemoryUnit(implicit val config: CpuConfig) extends Bundle { class CsrExecuteUnit(implicit val config: CpuConfig) extends Bundle { val in = Input(new Bundle { - val valid = Bool() - val info = new InstInfo() - val src_info = new SrcInfo() - val ex = new ExceptionInfo() + val valid = Bool() + val info = new InstInfo() + val src_info = new SrcInfo() + val ex = new ExceptionInfo() }) val out = Output(new Bundle { val rdata = UInt(DATA_WID.W) @@ -219,7 +219,7 @@ class Csr(implicit val config: CpuConfig) extends Module with HasCSRConst { val mem_addr = mem_inst(31, 20) // 不带前缀的信号为exe阶段的信号 val valid = io.executeUnit.in.valid - val info = io.executeUnit.in.info + val info = io.executeUnit.in.info val op = io.executeUnit.in.info.op val fusel = io.executeUnit.in.info.fusel val addr = io.executeUnit.in.info.inst(31, 20) @@ -273,12 +273,31 @@ class Csr(implicit val config: CpuConfig) extends Module with HasCSRConst { val interruptNO = IntPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(mem_ex.interrupt(i), i.U, sum)) val causeNO = (has_interrupt << (XLEN - 1)) | Mux(has_interrupt, interruptNO, exceptionNO) + val has_instrPageFault = mem_ex.exception(instrPageFault) + val has_loadPageFault = mem_ex.exception(loadPageFault) + val has_storePageFault = mem_ex.exception(storePageFault) + val has_loadAddrMisaligned = mem_ex.exception(loadAddrMisaligned) + val has_storeAddrMisaligned = mem_ex.exception(storeAddrMisaligned) + val has_instrAddrMisaligned = mem_ex.exception(instrAddrMisaligned) + val tval_wen = has_interrupt || - !(mem_ex.exception(instrPageFault) || - mem_ex.exception(loadPageFault) || - mem_ex.exception(storePageFault) || - mem_ex.exception(loadAddrMisaligned) || - mem_ex.exception(storeAddrMisaligned)) + !(has_instrPageFault || + has_loadPageFault || + has_storePageFault || + has_instrAddrMisaligned || + has_loadAddrMisaligned || + has_storeAddrMisaligned) + + when( + has_instrPageFault || + has_loadPageFault || + has_storePageFault || + has_instrAddrMisaligned || + has_loadAddrMisaligned || + has_storeAddrMisaligned + ) { + mtval := SignedExtend(mem_ex.tval, XLEN) + } when(has_exc_int) { val mstatusOld = WireInit(mstatus.asTypeOf(new Mstatus)) diff --git a/chisel/playground/src/pipeline/execute/ExeAccessMemCtrl.scala b/chisel/playground/src/pipeline/execute/ExeAccessMemCtrl.scala index 8e576db..ba3cfeb 100644 --- a/chisel/playground/src/pipeline/execute/ExeAccessMemCtrl.scala +++ b/chisel/playground/src/pipeline/execute/ExeAccessMemCtrl.scala @@ -78,6 +78,11 @@ class ExeAccessMemCtrl(implicit val config: CpuConfig) extends Module { io.inst(i).ex.out := io.inst(i).ex.in io.inst(i).ex.out.exception(loadAddrMisaligned) := !store_inst && !addr_aligned(i) io.inst(i).ex.out.exception(storeAddrMisaligned) := store_inst && !addr_aligned(i) + io.inst(i).ex.out.tval := Mux( + io.inst(i).ex.in.exception.asUInt.orR, + io.inst(i).ex.in.tval, + mem_addr(i) + ) } io.inst(0).mem_sel := (io.inst(0).info.fusel === FuType.lsu) && !(io.inst(0).ex.out.exception.asUInt.orR || io.inst(0).ex.out.interrupt.asUInt.orR) && diff --git a/chisel/playground/src/pipeline/execute/ExecuteUnit.scala b/chisel/playground/src/pipeline/execute/ExecuteUnit.scala index 4c104eb..b859078 100644 --- a/chisel/playground/src/pipeline/execute/ExecuteUnit.scala +++ b/chisel/playground/src/pipeline/execute/ExecuteUnit.scala @@ -76,12 +76,12 @@ class ExecuteUnit(implicit val config: CpuConfig) extends Module { ) // input accessMemCtrl - accessMemCtrl.inst(0).info := io.executeStage.inst0.info - accessMemCtrl.inst(0).src_info := io.executeStage.inst0.src_info - accessMemCtrl.inst(0).ex.in := io.executeStage.inst0.ex - accessMemCtrl.inst(1).info := io.executeStage.inst1.info - accessMemCtrl.inst(1).src_info := io.executeStage.inst1.src_info - accessMemCtrl.inst(1).ex.in := io.executeStage.inst1.ex + accessMemCtrl.inst(0).info := io.executeStage.inst0.info + accessMemCtrl.inst(0).src_info := io.executeStage.inst0.src_info + accessMemCtrl.inst(0).ex.in := io.executeStage.inst0.ex + accessMemCtrl.inst(1).info := io.executeStage.inst1.info + accessMemCtrl.inst(1).src_info := io.executeStage.inst1.src_info + accessMemCtrl.inst(1).ex.in := io.executeStage.inst1.ex // input fu fu.ctrl <> io.ctrl.fu @@ -90,8 +90,8 @@ class ExecuteUnit(implicit val config: CpuConfig) extends Module { !MDUOpType.isDiv(io.executeStage.inst0.info.op) fu.inst(0).div_en := io.executeStage.inst0.info.fusel === FuType.mdu && MDUOpType.isDiv(io.executeStage.inst0.info.op) - fu.inst(0).info := io.executeStage.inst0.info - fu.inst(0).src_info := io.executeStage.inst0.src_info + fu.inst(0).info := io.executeStage.inst0.info + fu.inst(0).src_info := io.executeStage.inst0.src_info fu.inst(0).ex.in := Mux(io.executeStage.inst0.info.fusel === FuType.lsu, accessMemCtrl.inst(0).ex.out, io.executeStage.inst0.ex) fu.inst(1).pc := io.executeStage.inst1.pc @@ -99,7 +99,7 @@ class ExecuteUnit(implicit val config: CpuConfig) extends Module { !MDUOpType.isDiv(io.executeStage.inst1.info.op) fu.inst(1).div_en := io.executeStage.inst1.info.fusel === FuType.mdu && MDUOpType.isDiv(io.executeStage.inst1.info.op) - fu.inst(1).info := io.executeStage.inst1.info + fu.inst(1).info := io.executeStage.inst1.info fu.inst(1).src_info := io.executeStage.inst1.src_info fu.inst(1).ex.in := io.executeStage.inst1.ex fu.branch.pred_branch := io.executeStage.inst0.jb_info.pred_branch @@ -121,16 +121,16 @@ class ExecuteUnit(implicit val config: CpuConfig) extends Module { io.ctrl.fu_stall := fu.stall_req - io.memoryStage.inst0.mem.en := accessMemCtrl.mem.out.en - io.memoryStage.inst0.mem.ren := accessMemCtrl.mem.out.ren - io.memoryStage.inst0.mem.wen := accessMemCtrl.mem.out.wen - io.memoryStage.inst0.mem.addr := accessMemCtrl.mem.out.addr - io.memoryStage.inst0.mem.wdata := accessMemCtrl.mem.out.wdata - io.memoryStage.inst0.mem.sel := accessMemCtrl.inst.map(_.mem_sel) - io.memoryStage.inst0.mem.info := accessMemCtrl.mem.out.info + io.memoryStage.inst0.mem.en := accessMemCtrl.mem.out.en + io.memoryStage.inst0.mem.ren := accessMemCtrl.mem.out.ren + io.memoryStage.inst0.mem.wen := accessMemCtrl.mem.out.wen + io.memoryStage.inst0.mem.addr := accessMemCtrl.mem.out.addr + io.memoryStage.inst0.mem.wdata := accessMemCtrl.mem.out.wdata + io.memoryStage.inst0.mem.sel := accessMemCtrl.inst.map(_.mem_sel) + io.memoryStage.inst0.mem.info := accessMemCtrl.mem.out.info io.memoryStage.inst0.pc := io.executeStage.inst0.pc - io.memoryStage.inst0.info := io.executeStage.inst0.info + io.memoryStage.inst0.info := io.executeStage.inst0.info io.memoryStage.inst0.rd_info.wdata(FuType.alu) := fu.inst(0).result.alu io.memoryStage.inst0.rd_info.wdata(FuType.mdu) := fu.inst(0).result.mdu io.memoryStage.inst0.rd_info.wdata(FuType.csr) := io.csr.out.rdata @@ -150,9 +150,18 @@ class ExecuteUnit(implicit val config: CpuConfig) extends Module { ) ) ) + io.memoryStage.inst0.ex.exception(instrAddrMisaligned) := io.executeStage.inst0.ex.exception(instrAddrMisaligned) || + io.fetchUnit.branch && io.fetchUnit.target(1, 0).orR + io.memoryStage.inst0.ex.tval := MuxCase( + io.executeStage.inst0.ex.tval, + Seq( + (io.executeStage.inst0.ex.exception(instrAddrMisaligned)) -> io.executeStage.inst0.ex.tval, + (io.fetchUnit.branch && io.fetchUnit.target(1, 0).orR) -> io.fetchUnit.target + ) + ) io.memoryStage.inst1.pc := io.executeStage.inst1.pc - io.memoryStage.inst1.info := io.executeStage.inst1.info + io.memoryStage.inst1.info := io.executeStage.inst1.info io.memoryStage.inst1.rd_info.wdata(FuType.alu) := fu.inst(1).result.alu io.memoryStage.inst1.rd_info.wdata(FuType.mdu) := fu.inst(1).result.mdu io.memoryStage.inst1.rd_info.wdata(FuType.csr) := io.csr.out.rdata @@ -172,6 +181,15 @@ class ExecuteUnit(implicit val config: CpuConfig) extends Module { ) ) ) + io.memoryStage.inst1.ex.exception(instrAddrMisaligned) := io.executeStage.inst1.ex.exception(instrAddrMisaligned) || + io.fetchUnit.branch && io.fetchUnit.target(1, 0).orR + io.memoryStage.inst1.ex.tval := MuxCase( + io.executeStage.inst1.ex.tval, + Seq( + (io.executeStage.inst1.ex.exception(instrAddrMisaligned)) -> io.executeStage.inst1.ex.tval, + (io.fetchUnit.branch && io.fetchUnit.target(1, 0).orR) -> io.fetchUnit.target + ) + ) io.decoderUnit.forward(0).exe.wen := io.memoryStage.inst0.info.reg_wen io.decoderUnit.forward(0).exe.waddr := io.memoryStage.inst0.info.reg_waddr