diff --git a/chisel/playground/src/Core.scala b/chisel/playground/src/Core.scala index 1b50732..66978e8 100644 --- a/chisel/playground/src/Core.scala +++ b/chisel/playground/src/Core.scala @@ -44,7 +44,6 @@ class Core(implicit val config: CpuConfig) extends Module { ctrl.memoryUnit <> memoryUnit.ctrl ctrl.writeBackUnit <> writeBackUnit.ctrl ctrl.cacheCtrl.iCache_stall := io.inst.icache_stall - ctrl.cacheCtrl.dCache_stall := io.data.dcache_stall fetchUnit.memory <> memoryUnit.fetchUnit fetchUnit.execute <> executeUnit.fetchUnit @@ -120,6 +119,7 @@ class Core(implicit val config: CpuConfig) extends Module { memoryUnit.dataMemory.in.rdata := io.data.rdata memoryUnit.dataMemory.in.acc_err := io.data.acc_err + memoryUnit.dataMemory.in.ready := !io.data.dcache_stall io.data.en := memoryUnit.dataMemory.out.en io.data.size := memoryUnit.dataMemory.out.rlen io.data.wen := memoryUnit.dataMemory.out.wen diff --git a/chisel/playground/src/ctrl/Ctrl.scala b/chisel/playground/src/ctrl/Ctrl.scala index cc25911..3c1b0cd 100644 --- a/chisel/playground/src/ctrl/Ctrl.scala +++ b/chisel/playground/src/ctrl/Ctrl.scala @@ -17,15 +17,16 @@ class Ctrl(implicit val config: CpuConfig) extends Module { val writeBackUnit = Flipped(new WriteBackCtrl()) }) - val inst0_lw_stall = (io.executeUnit.inst(0).mem_wreg) && + val inst0_lw_stall = (io.executeUnit.inst(0).mem_wreg) && io.executeUnit.inst(0).reg_waddr.orR && (io.decoderUnit.inst0.src1.ren && io.decoderUnit.inst0.src1.raddr === io.executeUnit.inst(0).reg_waddr || io.decoderUnit.inst0.src2.ren && io.decoderUnit.inst0.src2.raddr === io.executeUnit.inst(0).reg_waddr) - val inst1_lw_stall = (io.executeUnit.inst(1).mem_wreg) && + val inst1_lw_stall = (io.executeUnit.inst(1).mem_wreg) && io.executeUnit.inst(1).reg_waddr.orR && (io.decoderUnit.inst0.src1.ren && io.decoderUnit.inst0.src1.raddr === io.executeUnit.inst(1).reg_waddr || io.decoderUnit.inst0.src2.ren && io.decoderUnit.inst0.src2.raddr === io.executeUnit.inst(1).reg_waddr) val lw_stall = inst0_lw_stall || inst1_lw_stall // TODO: 这里的stall信号可能不对 - val longest_stall = io.executeUnit.fu_stall || io.cacheCtrl.iCache_stall || io.cacheCtrl.dCache_stall + val longest_stall = + io.executeUnit.fu_stall || io.cacheCtrl.iCache_stall || io.memoryUnit.mem_stall io.fetchUnit.allow_to_go := !io.cacheCtrl.iCache_stall io.decoderUnit.allow_to_go := !(lw_stall || longest_stall) diff --git a/chisel/playground/src/defines/Bundles.scala b/chisel/playground/src/defines/Bundles.scala index f8362f1..b970c0f 100644 --- a/chisel/playground/src/defines/Bundles.scala +++ b/chisel/playground/src/defines/Bundles.scala @@ -55,7 +55,6 @@ class SrcReadSignal extends Bundle { class CacheCtrl extends Bundle { val iCache_stall = Output(Bool()) - val dCache_stall = Output(Bool()) } class FetchUnitCtrl extends Bundle { @@ -85,7 +84,7 @@ class ExecuteFuCtrl extends Bundle { class ExecuteCtrl(implicit val config: CpuConfig) extends Bundle { val inst = Output(Vec(config.fuNum, new MemRead())) val fu_stall = Output(Bool()) - val flush = Output(Bool()) + val flush = Output(Bool()) val allow_to_go = Input(Bool()) val do_flush = Input(Bool()) @@ -94,7 +93,8 @@ class ExecuteCtrl(implicit val config: CpuConfig) extends Bundle { } class MemoryCtrl extends Bundle { - val flush = Output(Bool()) + val flush = Output(Bool()) + val mem_stall = Output(Bool()) val allow_to_go = Input(Bool()) val do_flush = Input(Bool()) diff --git a/chisel/playground/src/pipeline/execute/Csr.scala b/chisel/playground/src/pipeline/execute/Csr.scala index 529264f..3627e9f 100644 --- a/chisel/playground/src/pipeline/execute/Csr.scala +++ b/chisel/playground/src/pipeline/execute/Csr.scala @@ -17,10 +17,16 @@ class CsrMemoryUnit(implicit val config: CpuConfig) extends Bundle { val info = new InstInfo() } ) + val set_lr = Bool() + val set_lr_val = Bool() + val set_lr_addr = UInt(DATA_ADDR_WID.W) }) val out = Output(new Bundle { val flush = Bool() val flush_pc = UInt(PC_WID.W) + + val lr = Bool() + val lr_addr = UInt(DATA_ADDR_WID.W) }) } @@ -104,20 +110,20 @@ class Csr(implicit val config: CpuConfig) extends Module with HasCSRConst { val wdata = Wire(UInt(XLEN.W)) // Atom LR/SC Control Bits - val setLr = WireInit(Bool(), false.B) - val setLrVal = WireInit(Bool(), false.B) - val setLrAddr = WireInit(UInt(XLEN.W), DontCare) //TODO : need check - val lr = RegInit(Bool(), false.B) - val lrAddr = RegInit(UInt(XLEN.W), 0.U) - BoringUtils.addSink(setLr, "set_lr") - BoringUtils.addSink(setLrVal, "set_lr_val") - BoringUtils.addSink(setLrAddr, "set_lr_addr") - BoringUtils.addSource(lr, "lr") - BoringUtils.addSource(lrAddr, "lr_addr") + val set_lr = WireInit(Bool(), false.B) + val set_lr_val = WireInit(Bool(), false.B) + val set_lr_addr = WireInit(UInt(DATA_ADDR_WID.W), 0.U) + val lr = RegInit(Bool(), false.B) + val lr_addr = RegInit(UInt(DATA_ADDR_WID.W), 0.U) + set_lr := io.memoryUnit.in.set_lr + set_lr_val := io.memoryUnit.in.set_lr_val + set_lr_addr := io.memoryUnit.in.set_lr_addr + io.memoryUnit.out.lr := lr + io.memoryUnit.out.lr_addr := lr_addr - when(setLr) { - lr := setLrVal - lrAddr := setLrAddr + when(set_lr) { + lr := set_lr_val + lr_addr := set_lr_addr } // Side Effect diff --git a/chisel/playground/src/pipeline/execute/ExecuteUnit.scala b/chisel/playground/src/pipeline/execute/ExecuteUnit.scala index a35dbb8..9fedcbf 100644 --- a/chisel/playground/src/pipeline/execute/ExecuteUnit.scala +++ b/chisel/playground/src/pipeline/execute/ExecuteUnit.scala @@ -113,6 +113,7 @@ class ExecuteUnit(implicit val config: CpuConfig) extends Module { io.memoryStage.inst0.pc := io.executeStage.inst0.pc io.memoryStage.inst0.info := io.executeStage.inst0.info + io.memoryStage.inst0.src_info := io.executeStage.inst0.src_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 @@ -137,6 +138,7 @@ class ExecuteUnit(implicit val config: CpuConfig) extends Module { io.memoryStage.inst1.pc := io.executeStage.inst1.pc io.memoryStage.inst1.info := io.executeStage.inst1.info + io.memoryStage.inst1.src_info := io.executeStage.inst1.src_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 diff --git a/chisel/playground/src/pipeline/memory/DataMemoryAccess.scala b/chisel/playground/src/pipeline/memory/DataMemoryAccess.scala index adb0f53..119b58f 100644 --- a/chisel/playground/src/pipeline/memory/DataMemoryAccess.scala +++ b/chisel/playground/src/pipeline/memory/DataMemoryAccess.scala @@ -5,10 +5,12 @@ import chisel3.util._ import cpu.defines._ import cpu.defines.Const._ import cpu.CpuConfig +import chisel3.util.experimental.BoringUtils class DataMemoryAccess_DataMemory extends Bundle { val in = Input(new Bundle { val acc_err = Bool() + val ready = Bool() val rdata = UInt(DATA_WID.W) }) val out = Output(new Bundle { @@ -21,85 +23,170 @@ class DataMemoryAccess_DataMemory extends Bundle { }) } +class DataMemoryAccess_MemoryUnit extends Bundle { + val in = Input(new Bundle { + val mem_en = Bool() + val info = new InstInfo() + val src_info = new SrcInfo() + val ex = new ExceptionInfo() + + val lr = Bool() + val lr_addr = UInt(DATA_ADDR_WID.W) + }) + val out = Output(new Bundle { + val ready = Bool() + val rdata = UInt(DATA_WID.W) + val ex = new ExceptionInfo() + + val set_lr = Bool() + val set_lr_val = Bool() + val set_lr_addr = UInt(DATA_ADDR_WID.W) + }) +} + class DataMemoryAccess(implicit val config: CpuConfig) extends Module { val io = IO(new Bundle { - val memoryUnit = new Bundle { - val in = Input(new Bundle { - val mem_en = Bool() - val info = new InstInfo() - val mem_wdata = UInt(DATA_WID.W) - val mem_addr = UInt(DATA_ADDR_WID.W) - val mem_sel = Vec(config.fuNum, Bool()) - val ex = Vec(config.fuNum, new ExceptionInfo()) - }) - val out = Output(new Bundle { - val acc_err = Bool() - val rdata = Output(UInt(DATA_WID.W)) - }) - } - + val memoryUnit = new DataMemoryAccess_MemoryUnit() val dataMemory = new DataMemoryAccess_DataMemory() }) - val mem_addr = io.memoryUnit.in.mem_addr - val mem_addr2 = mem_addr(1, 0) - val mem_rdata = io.dataMemory.in.rdata - val mem_wdata = io.memoryUnit.in.mem_wdata - val op = io.memoryUnit.in.info.op - io.dataMemory.out.en := io.memoryUnit.in.mem_en && - (io.memoryUnit.in.mem_sel(0) && - !(HasExcInt(io.memoryUnit.in.ex(0))) || - io.memoryUnit.in.mem_sel(1) && - !(HasExcInt(io.memoryUnit.in.ex(0))) && !(HasExcInt(io.memoryUnit.in.ex(1)))) - io.dataMemory.out.addr := mem_addr - val rdata = LookupTree( - mem_addr(2, 0), - List( - "b000".U -> mem_rdata(63, 0), - "b001".U -> mem_rdata(63, 8), - "b010".U -> mem_rdata(63, 16), - "b011".U -> mem_rdata(63, 24), - "b100".U -> mem_rdata(63, 32), - "b101".U -> mem_rdata(63, 40), - "b110".U -> mem_rdata(63, 48), - "b111".U -> mem_rdata(63, 56) - ) - ) - io.memoryUnit.out.acc_err := io.dataMemory.in.acc_err - io.memoryUnit.out.rdata := MuxLookup(op, rdata(XLEN - 1, 0))( - List( - LSUOpType.lb -> SignedExtend(rdata(7, 0), XLEN), - LSUOpType.lh -> SignedExtend(rdata(15, 0), XLEN), - LSUOpType.lw -> SignedExtend(rdata(31, 0), XLEN), - LSUOpType.lbu -> ZeroExtend(rdata(7, 0), XLEN), - LSUOpType.lhu -> ZeroExtend(rdata(15, 0), XLEN), - LSUOpType.lwu -> ZeroExtend(rdata(31, 0), XLEN) - ) - ) - def genWdata(data: UInt, sizeEncode: UInt): UInt = { - LookupTree( - sizeEncode, - List( - "b00".U -> Fill(8, data(7, 0)), - "b01".U -> Fill(4, data(15, 0)), - "b10".U -> Fill(2, data(31, 0)), - "b11".U -> data - ) - ) + + val atomAlu = Module(new AtomAlu()).io + val lsExe = Module(new LSExe()).io + + val valid = io.memoryUnit.in.mem_en + val src1 = io.memoryUnit.in.src_info.src1_data + val src2 = io.memoryUnit.in.src_info.src2_data + val func = io.memoryUnit.in.info.op + val inst = io.memoryUnit.in.info.inst + + val storeReq = valid & LSUOpType.isStore(func) + val loadReq = valid & LSUOpType.isLoad(func) + val atomReq = valid & LSUOpType.isAtom(func) + val amoReq = valid & LSUOpType.isAMO(func) + val lrReq = valid & LSUOpType.isLR(func) + val scReq = valid & LSUOpType.isSC(func) + + val aq = inst(26) + val rl = inst(25) + val funct3 = inst(14, 12) + + val atomWidthW = !funct3(0) + val atomWidthD = funct3(0) + + // Atom LR/SC Control Bits + val setLr = Wire(Bool()) + val setLrVal = Wire(Bool()) + val setLrAddr = Wire(UInt(DATA_ADDR_WID.W)) + val lr = WireInit(Bool(), false.B) + val lrAddr = WireInit(UInt(DATA_ADDR_WID.W), DontCare) + io.memoryUnit.out.set_lr := setLr + io.memoryUnit.out.set_lr_val := setLrVal + io.memoryUnit.out.set_lr_addr := setLrAddr + lr := io.memoryUnit.in.lr + lrAddr := io.memoryUnit.in.lr_addr + + val s_idle :: s_lr :: s_sc :: s_amo_l :: s_amo_a :: s_amo_s :: Nil = Enum(6) + + val state = RegInit(s_idle) + val atomMemReg = Reg(UInt(XLEN.W)) + val atomRegReg = Reg(UInt(XLEN.W)) + atomAlu.in.rdata := atomMemReg + atomAlu.in.wdata := io.dataMemory.out.wdata + atomAlu.in.info := io.memoryUnit.in.info + + val scInvalid = (src1 =/= lrAddr || !lr) && scReq + + lsExe.in.info := io.memoryUnit.in.info + lsExe.in.mem_addr := 0.U + lsExe.in.mem_en := false.B + lsExe.in.wdata := 0.U + io.memoryUnit.out.ready := false.B + + switch(state) { + is(s_idle) { // calculate address + lsExe.in.mem_en := io.memoryUnit.in.mem_en && !atomReq + lsExe.in.mem_addr := src1 + src2 + lsExe.in.info.op := func + lsExe.in.wdata := io.memoryUnit.in.src_info.src2_data + io.memoryUnit.out.ready := lsExe.dataMemory.in.ready || scInvalid + state := s_idle + + when(amoReq) { state := s_amo_l } + when(lrReq) { state := s_lr } + when(scReq) { state := Mux(scInvalid, s_idle, s_sc) } + + } + + is(s_amo_l) { + lsExe.in.mem_en := true.B + lsExe.in.mem_addr := src1 + lsExe.in.info.op := Mux(atomWidthD, LSUOpType.ld, LSUOpType.lw) + lsExe.in.wdata := DontCare + io.memoryUnit.out.ready := false.B + when(lsExe.dataMemory.in.ready) { + state := s_amo_a; + } + atomMemReg := lsExe.out.rdata + atomRegReg := lsExe.out.rdata + } + + is(s_amo_a) { + lsExe.in.mem_en := false.B + lsExe.in.mem_addr := DontCare + lsExe.in.info.op := DontCare + lsExe.in.wdata := DontCare + io.memoryUnit.out.ready := false.B + state := s_amo_s + atomMemReg := atomAlu.out.result + } + + is(s_amo_s) { + lsExe.in.mem_en := true.B + lsExe.in.mem_addr := src1 + lsExe.in.info.op := Mux(atomWidthD, LSUOpType.sd, LSUOpType.sw) + lsExe.in.wdata := atomMemReg + io.memoryUnit.out.ready := lsExe.dataMemory.in.ready + when(lsExe.dataMemory.in.ready) { + state := s_idle; + } + } + is(s_lr) { + lsExe.in.mem_en := true.B + lsExe.in.mem_addr := src1 + lsExe.in.info.op := Mux(atomWidthD, LSUOpType.ld, LSUOpType.lw) + lsExe.in.wdata := DontCare + io.memoryUnit.out.ready := lsExe.dataMemory.in.ready + when(lsExe.dataMemory.in.ready) { + state := s_idle; + } + } + is(s_sc) { + lsExe.in.mem_en := true.B + lsExe.in.mem_addr := src1 + lsExe.in.info.op := Mux(atomWidthD, LSUOpType.sd, LSUOpType.sw) + lsExe.in.wdata := io.memoryUnit.in.src_info.src2_data + io.memoryUnit.out.ready := lsExe.dataMemory.in.ready + when(lsExe.dataMemory.in.ready) { + state := s_idle; + } + } } - def genWmask(addr: UInt, sizeEncode: UInt): UInt = { - LookupTree( - sizeEncode, - List( - "b00".U -> 0x1.U, //0001 << addr(2:0) - "b01".U -> 0x3.U, //0011 - "b10".U -> 0xf.U, //1111 - "b11".U -> 0xff.U //11111111 - ) - ) << addr(2, 0) + when(lsExe.out.loadAddrMisaligned || lsExe.out.storeAddrMisaligned) { + state := s_idle + io.memoryUnit.out.ready := true.B + io.memoryUnit.out.ready := true.B } - io.dataMemory.out.wdata := genWdata(mem_wdata, op(1, 0)) - io.dataMemory.out.wen := LSUOpType.isStore(op) && io.memoryUnit.in.mem_en - io.dataMemory.out.wstrb := genWmask(mem_addr, op(1, 0)) - io.dataMemory.out.rlen := op(1, 0) + setLr := io.memoryUnit.out.ready && (lrReq || scReq) + setLrVal := lrReq + setLrAddr := src1 + + io.dataMemory <> lsExe.dataMemory + + io.memoryUnit.out.ex := io.memoryUnit.in.ex + io.memoryUnit.out.ex.exception(loadAddrMisaligned) := lsExe.out.loadAddrMisaligned + io.memoryUnit.out.ex.exception(storeAddrMisaligned) := lsExe.out.storeAddrMisaligned + io.memoryUnit.out.ex.exception(loadAccessFault) := lsExe.out.loadAccessFault + io.memoryUnit.out.ex.exception(storeAccessFault) := lsExe.out.storeAccessFault + io.memoryUnit.out.rdata := lsExe.out.rdata } diff --git a/chisel/playground/src/pipeline/memory/LSExe.scala b/chisel/playground/src/pipeline/memory/LSExe.scala index e111496..32b8bb6 100644 --- a/chisel/playground/src/pipeline/memory/LSExe.scala +++ b/chisel/playground/src/pipeline/memory/LSExe.scala @@ -18,6 +18,8 @@ class LSExe extends Module { val out = Output(new Bundle { val loadAddrMisaligned = Bool() val storeAddrMisaligned = Bool() + val loadAccessFault = Bool() + val storeAccessFault = Bool() val rdata = UInt(DATA_WID.W) }) }) @@ -136,5 +138,7 @@ class LSExe extends Module { val is_amo = valid && LSUOpType.isAMO(op) io.out.rdata := Mux(partialLoad, rdataPartialLoad, rdataSel) io.out.loadAddrMisaligned := valid && !isStore && !is_amo && !addrAligned + io.out.loadAccessFault := valid && !isStore && !is_amo && acc_err io.out.storeAddrMisaligned := valid && (isStore || is_amo) && !addrAligned + io.out.storeAccessFault := valid && (isStore || is_amo) && acc_err } diff --git a/chisel/playground/src/pipeline/memory/MemoryUnit.scala b/chisel/playground/src/pipeline/memory/MemoryUnit.scala index cbeeb66..653d993 100644 --- a/chisel/playground/src/pipeline/memory/MemoryUnit.scala +++ b/chisel/playground/src/pipeline/memory/MemoryUnit.scala @@ -24,16 +24,37 @@ class MemoryUnit(implicit val config: CpuConfig) extends Module { }) val dataMemoryAccess = Module(new DataMemoryAccess()).io - dataMemoryAccess.memoryUnit.in.mem_en := io.memoryStage.inst0.mem.en - dataMemoryAccess.memoryUnit.in.info := io.memoryStage.inst0.mem.info - dataMemoryAccess.memoryUnit.in.mem_wdata := io.memoryStage.inst0.mem.wdata - dataMemoryAccess.memoryUnit.in.mem_addr := io.memoryStage.inst0.mem.addr - dataMemoryAccess.memoryUnit.in.mem_sel := io.memoryStage.inst0.mem.sel - dataMemoryAccess.memoryUnit.in.ex(0) := io.memoryStage.inst0.ex - dataMemoryAccess.memoryUnit.in.ex(1) := io.memoryStage.inst1.ex - dataMemoryAccess.dataMemory.in.acc_err := io.dataMemory.in.acc_err - dataMemoryAccess.dataMemory.in.rdata := io.dataMemory.in.rdata - io.dataMemory.out := dataMemoryAccess.dataMemory.out + val mem_sel = VecInit( + io.memoryStage.inst0.info.valid && + io.memoryStage.inst0.info.fusel === FuType.lsu && + !HasExcInt(io.memoryStage.inst0.ex), + io.memoryStage.inst1.info.valid && + io.memoryStage.inst1.info.fusel === FuType.lsu && + !HasExcInt(io.memoryStage.inst1.ex) && !HasExcInt(io.memoryStage.inst0.ex) + ) + dataMemoryAccess.memoryUnit.in.mem_en := mem_sel.reduce(_ || _) + dataMemoryAccess.memoryUnit.in.info := MuxCase( + 0.U.asTypeOf(new InstInfo()), + Seq( + mem_sel(0) -> io.memoryStage.inst0.info, + mem_sel(1) -> io.memoryStage.inst1.info + ) + ) + dataMemoryAccess.memoryUnit.in.src_info := MuxCase( + 0.U.asTypeOf(new SrcInfo()), + Seq( + mem_sel(0) -> io.memoryStage.inst0.src_info, + mem_sel(1) -> io.memoryStage.inst1.src_info + ) + ) + dataMemoryAccess.memoryUnit.in.ex := MuxCase( + 0.U.asTypeOf(new ExceptionInfo()), + Seq( + mem_sel(0) -> io.memoryStage.inst0.ex, + mem_sel(1) -> io.memoryStage.inst1.ex + ) + ) + dataMemoryAccess.dataMemory <> io.dataMemory io.decoderUnit(0).wen := io.writeBackStage.inst0.info.reg_wen io.decoderUnit(0).waddr := io.writeBackStage.inst0.info.reg_waddr @@ -46,22 +67,22 @@ class MemoryUnit(implicit val config: CpuConfig) extends Module { io.writeBackStage.inst0.info := io.memoryStage.inst0.info io.writeBackStage.inst0.rd_info.wdata := io.memoryStage.inst0.rd_info.wdata io.writeBackStage.inst0.rd_info.wdata(FuType.lsu) := dataMemoryAccess.memoryUnit.out.rdata - io.writeBackStage.inst0.ex := io.memoryStage.inst0.ex - io.writeBackStage.inst0.ex.exception(loadAccessFault) := io.memoryStage.inst0.mem.sel(0) && - LSUOpType.isLoad(io.memoryStage.inst0.info.op) && dataMemoryAccess.memoryUnit.out.acc_err - io.writeBackStage.inst0.ex.exception(storeAccessFault) := io.memoryStage.inst0.mem.sel(0) && - LSUOpType.isStore(io.memoryStage.inst0.info.op) && dataMemoryAccess.memoryUnit.out.acc_err + io.writeBackStage.inst0.ex := Mux( + mem_sel(0), + dataMemoryAccess.memoryUnit.out.ex, + io.memoryStage.inst0.ex + ) io.writeBackStage.inst0.commit := io.memoryStage.inst0.info.valid io.writeBackStage.inst1.pc := io.memoryStage.inst1.pc io.writeBackStage.inst1.info := io.memoryStage.inst1.info io.writeBackStage.inst1.rd_info.wdata := io.memoryStage.inst1.rd_info.wdata io.writeBackStage.inst1.rd_info.wdata(FuType.lsu) := dataMemoryAccess.memoryUnit.out.rdata - io.writeBackStage.inst1.ex := io.memoryStage.inst1.ex - io.writeBackStage.inst1.ex.exception(loadAccessFault) := io.memoryStage.inst0.mem.sel(1) && - LSUOpType.isLoad(io.memoryStage.inst1.info.op) && dataMemoryAccess.memoryUnit.out.acc_err - io.writeBackStage.inst1.ex.exception(storeAccessFault) := io.memoryStage.inst0.mem.sel(1) && - LSUOpType.isStore(io.memoryStage.inst1.info.op) && dataMemoryAccess.memoryUnit.out.acc_err + io.writeBackStage.inst1.ex := Mux( + mem_sel(1), + dataMemoryAccess.memoryUnit.out.ex, + io.memoryStage.inst1.ex + ) io.writeBackStage.inst1.commit := io.memoryStage.inst1.info.valid && !(HasExcInt(io.writeBackStage.inst0.ex)) @@ -80,8 +101,15 @@ class MemoryUnit(implicit val config: CpuConfig) extends Module { 0.U.asTypeOf(new InstInfo()) ) + io.csr.in.set_lr := dataMemoryAccess.memoryUnit.out.set_lr && io.ctrl.allow_to_go + io.csr.in.set_lr_val := dataMemoryAccess.memoryUnit.out.set_lr_val + io.csr.in.set_lr_addr := dataMemoryAccess.memoryUnit.out.set_lr_addr + dataMemoryAccess.memoryUnit.in.lr := io.csr.out.lr + dataMemoryAccess.memoryUnit.in.lr_addr := io.csr.out.lr_addr + io.fetchUnit.flush := io.csr.out.flush && io.ctrl.allow_to_go io.fetchUnit.target := Mux(io.csr.out.flush, io.csr.out.flush_pc, io.writeBackStage.inst0.pc + 4.U) - io.ctrl.flush := io.fetchUnit.flush + io.ctrl.flush := io.fetchUnit.flush + io.ctrl.mem_stall := !dataMemoryAccess.memoryUnit.out.ready && dataMemoryAccess.memoryUnit.in.mem_en }