feat(lsu): 实现amo指令
This commit is contained in:
parent
b21a26f947
commit
e81d0d2b8c
|
@ -139,5 +139,5 @@ class Core(implicit val config: CpuConfig) extends Module {
|
|||
io.inst.req := !instFifo.full && !reset.asBool
|
||||
|
||||
io.inst.complete_single_request := ctrl.fetchUnit.allow_to_go
|
||||
io.data.complete_single_request := ctrl.memoryUnit.allow_to_go
|
||||
io.data.complete_single_request := ctrl.memoryUnit.allow_to_go || ctrl.memoryUnit.complete_single_request
|
||||
}
|
||||
|
|
|
@ -88,12 +88,15 @@ class ExecuteCtrl(implicit val config: CpuConfig) extends Bundle {
|
|||
}
|
||||
|
||||
class MemoryCtrl extends Bundle {
|
||||
val fence_i = Output(Bool())
|
||||
val flush = Output(Bool())
|
||||
val mem_stall = Output(Bool())
|
||||
|
||||
val allow_to_go = Input(Bool())
|
||||
val do_flush = Input(Bool())
|
||||
|
||||
// to cache
|
||||
val fence_i = Output(Bool())
|
||||
val complete_single_request = Output(Bool()) // to dcache
|
||||
}
|
||||
|
||||
class WriteBackCtrl extends Bundle {
|
||||
|
|
|
@ -1,247 +0,0 @@
|
|||
package cpu.pipeline.memory
|
||||
|
||||
import chisel3._
|
||||
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(XLEN.W)
|
||||
})
|
||||
val out = Output(new Bundle {
|
||||
val en = Bool()
|
||||
val rlen = UInt(AXI_LEN_WID.W)
|
||||
val wen = Bool()
|
||||
val wstrb = UInt(AXI_STRB_WID.W)
|
||||
val addr = UInt(DATA_ADDR_WID.W)
|
||||
val wdata = UInt(XLEN.W)
|
||||
})
|
||||
}
|
||||
|
||||
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 allow_to_go = Bool()
|
||||
})
|
||||
val out = Output(new Bundle {
|
||||
val ready = Bool()
|
||||
val rdata = UInt(XLEN.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 DataMemoryAccess_MemoryUnit()
|
||||
val dataMemory = new DataMemoryAccess_DataMemory()
|
||||
})
|
||||
|
||||
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 imm = io.memoryUnit.in.info.imm
|
||||
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_load :: s_sc :: s_amo_l :: s_amo_l_wait :: s_amo_a :: s_amo_s :: s_wait_allow :: Nil = Enum(8)
|
||||
|
||||
val state = RegInit(s_idle)
|
||||
val atomMemReg = Reg(UInt(XLEN.W))
|
||||
val atomRegReg = Reg(UInt(XLEN.W))
|
||||
atomAlu.in.rdata := atomMemReg
|
||||
atomAlu.in.src2 := src2
|
||||
atomAlu.in.info := io.memoryUnit.in.info
|
||||
|
||||
val scInvalid = (src1 =/= lrAddr || !lr) && scReq
|
||||
|
||||
lsExe.in.info := DontCare
|
||||
lsExe.in.mem_addr := DontCare
|
||||
lsExe.in.mem_en := false.B
|
||||
lsExe.in.wdata := DontCare
|
||||
io.memoryUnit.out.ready := false.B
|
||||
|
||||
val allow_to_go = io.memoryUnit.in.allow_to_go
|
||||
|
||||
switch(state) {
|
||||
is(s_idle) { // calculate address
|
||||
lsExe.in.mem_en := io.memoryUnit.in.mem_en && !atomReq
|
||||
lsExe.in.mem_addr := src1 + imm
|
||||
lsExe.in.info.op := func
|
||||
lsExe.in.wdata := src2
|
||||
io.memoryUnit.out.ready := lsExe.out.ready && io.dataMemory.out.en || scInvalid
|
||||
// when(io.memoryUnit.out.ready) {
|
||||
// when(allow_to_go) {
|
||||
// state := s_idle
|
||||
// }
|
||||
// state := s_wait_allow;
|
||||
// }
|
||||
// when(amoReq) { state := s_amo_l }
|
||||
// when(lrReq) {
|
||||
// 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.out.ready && io.dataMemory.out.en
|
||||
// when(lsExe.out.ready) {
|
||||
// when(allow_to_go) {
|
||||
// state := s_idle
|
||||
// }
|
||||
// state := s_wait_allow;
|
||||
// }
|
||||
// }
|
||||
// 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.out.ready) {
|
||||
// state := s_amo_l_wait;
|
||||
// }
|
||||
// }
|
||||
|
||||
// is(s_amo_l_wait) {
|
||||
// lsExe.in.mem_en := false.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
|
||||
// atomMemReg := lsExe.out.rdata
|
||||
// atomRegReg := lsExe.out.rdata
|
||||
// when(lsExe.out.ready) {
|
||||
// state := s_amo_a;
|
||||
// }
|
||||
// }
|
||||
|
||||
// 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.out.ready && io.dataMemory.out.en
|
||||
// when(lsExe.out.ready) {
|
||||
// when(allow_to_go) {
|
||||
// state := s_idle
|
||||
// }
|
||||
// state := s_wait_allow;
|
||||
// }
|
||||
// }
|
||||
// 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 := src2
|
||||
// io.memoryUnit.out.ready := lsExe.out.ready && io.dataMemory.out.en
|
||||
// when(lsExe.out.ready) {
|
||||
// when(allow_to_go) {
|
||||
// state := s_idle
|
||||
// }
|
||||
// state := s_wait_allow;
|
||||
// }
|
||||
// }
|
||||
// is(s_wait_allow) {
|
||||
// lsExe.in.mem_en := false.B
|
||||
// lsExe.in.info.op := MuxCase(
|
||||
// func,
|
||||
// Seq(
|
||||
// lrReq -> Mux(atomWidthD, LSUOpType.ld, LSUOpType.lw),
|
||||
// scReq -> Mux(atomWidthD, LSUOpType.sd, LSUOpType.sw)
|
||||
// )
|
||||
// )
|
||||
// lsExe.in.mem_addr := Mux(amoReq || lrReq || scReq, src1, src1 + imm)
|
||||
// lsExe.in.wdata := DontCare
|
||||
// io.memoryUnit.out.ready := io.dataMemory.in.ready
|
||||
// when(allow_to_go && io.dataMemory.in.ready) {
|
||||
// state := s_idle
|
||||
// }
|
||||
// }
|
||||
}
|
||||
when(
|
||||
lsExe.out.loadAddrMisaligned ||
|
||||
lsExe.out.storeAddrMisaligned ||
|
||||
lsExe.out.loadAccessFault ||
|
||||
lsExe.out.storeAccessFault
|
||||
) {
|
||||
state := s_idle
|
||||
io.memoryUnit.out.ready := true.B
|
||||
}
|
||||
|
||||
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.ex.tval := io.dataMemory.out.addr
|
||||
io.memoryUnit.out.rdata := MuxCase(
|
||||
lsExe.out.rdata,
|
||||
Seq(
|
||||
(scReq) -> scInvalid,
|
||||
(amoReq) -> atomRegReg
|
||||
)
|
||||
)
|
||||
}
|
|
@ -0,0 +1,212 @@
|
|||
package cpu.pipeline.memory
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
import chisel3.util.experimental.BoringUtils
|
||||
|
||||
class Lsu_DataMemory extends Bundle {
|
||||
val in = Input(new Bundle {
|
||||
val acc_err = Bool()
|
||||
val ready = Bool()
|
||||
val rdata = UInt(XLEN.W)
|
||||
})
|
||||
val out = Output(new Bundle {
|
||||
val en = Bool()
|
||||
val rlen = UInt(AXI_LEN_WID.W)
|
||||
val wen = Bool()
|
||||
val wstrb = UInt(AXI_STRB_WID.W)
|
||||
val addr = UInt(DATA_ADDR_WID.W)
|
||||
val wdata = UInt(XLEN.W)
|
||||
})
|
||||
}
|
||||
|
||||
class Lsu_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 allow_to_go = Bool()
|
||||
})
|
||||
val out = Output(new Bundle {
|
||||
val ready = Bool()
|
||||
val rdata = UInt(XLEN.W)
|
||||
val ex = new ExceptionInfo()
|
||||
// 用于指示dcache完成一次请求
|
||||
val complete_single_request = Bool()
|
||||
|
||||
val set_lr = Bool()
|
||||
val set_lr_val = Bool()
|
||||
val set_lr_addr = UInt(DATA_ADDR_WID.W)
|
||||
})
|
||||
}
|
||||
|
||||
class Lsu(implicit val config: CpuConfig) extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val memoryUnit = new Lsu_MemoryUnit()
|
||||
val dataMemory = new Lsu_DataMemory()
|
||||
})
|
||||
|
||||
val atomAlu = Module(new AtomAlu()).io
|
||||
val lsExe = Module(new LsExecute()).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 imm = io.memoryUnit.in.info.imm
|
||||
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_sc :: s_amo_l :: s_amo_a :: s_amo_s :: Nil = Enum(5)
|
||||
|
||||
val state = RegInit(s_idle)
|
||||
val atomMemReg = Reg(UInt(XLEN.W))
|
||||
val atomRegReg = Reg(UInt(XLEN.W))
|
||||
atomAlu.in.rdata := atomMemReg
|
||||
atomAlu.in.src2 := src2
|
||||
atomAlu.in.info := io.memoryUnit.in.info
|
||||
|
||||
val scInvalid = (src1 =/= lrAddr || !lr) && scReq
|
||||
|
||||
lsExe.in.info := DontCare
|
||||
lsExe.in.mem_addr := DontCare
|
||||
lsExe.in.mem_en := false.B
|
||||
lsExe.in.wdata := DontCare
|
||||
io.memoryUnit.out.ready := false.B
|
||||
|
||||
val allow_to_go = io.memoryUnit.in.allow_to_go
|
||||
val complete_single_request = Wire(Bool())
|
||||
// 只有amo操作时该信号才发挥作用
|
||||
complete_single_request := false.B
|
||||
|
||||
io.memoryUnit.out.complete_single_request := complete_single_request
|
||||
|
||||
switch(state) {
|
||||
is(s_idle) { // calculate address
|
||||
lsExe.in.mem_en := io.memoryUnit.in.mem_en && !atomReq
|
||||
lsExe.in.mem_addr := src1 + imm
|
||||
lsExe.in.info.op := func
|
||||
lsExe.in.wdata := src2
|
||||
io.memoryUnit.out.ready := lsExe.out.ready || scInvalid
|
||||
when(amoReq) { state := s_amo_l }
|
||||
when(lrReq) {
|
||||
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.out.ready
|
||||
}
|
||||
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.out.ready) {
|
||||
state := s_amo_a;
|
||||
complete_single_request := true.B
|
||||
}
|
||||
atomMemReg := lsExe.out.rdata
|
||||
atomRegReg := lsExe.out.rdata
|
||||
}
|
||||
|
||||
is(s_amo_a) {
|
||||
complete_single_request := false.B
|
||||
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.out.ready
|
||||
when(allow_to_go) {
|
||||
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 := src2
|
||||
io.memoryUnit.out.ready := lsExe.out.ready
|
||||
when(allow_to_go) {
|
||||
state := s_idle
|
||||
}
|
||||
}
|
||||
}
|
||||
when(
|
||||
lsExe.out.loadAddrMisaligned ||
|
||||
lsExe.out.storeAddrMisaligned ||
|
||||
lsExe.out.loadAccessFault ||
|
||||
lsExe.out.storeAccessFault
|
||||
) {
|
||||
state := s_idle
|
||||
io.memoryUnit.out.ready := true.B
|
||||
}
|
||||
|
||||
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.ex.tval := io.dataMemory.out.addr
|
||||
io.memoryUnit.out.rdata := MuxCase(
|
||||
lsExe.out.rdata,
|
||||
Seq(
|
||||
(scReq) -> scInvalid,
|
||||
(amoReq) -> atomRegReg
|
||||
)
|
||||
)
|
||||
}
|
|
@ -20,16 +20,15 @@ class MemoryUnit(implicit val config: CpuConfig) extends Module {
|
|||
val decoderUnit = Output(Vec(config.commitNum, new RegWrite()))
|
||||
val csr = Flipped(new CsrMemoryUnit())
|
||||
val writeBackStage = Output(new MemoryUnitWriteBackUnit())
|
||||
val dataMemory = new DataMemoryAccess_DataMemory()
|
||||
val dataMemory = new Lsu_DataMemory()
|
||||
})
|
||||
|
||||
val dataMemoryAccess = Module(new DataMemoryAccess()).io
|
||||
val mou = Module(new Mou()).io
|
||||
val lsu = Module(new Lsu()).io
|
||||
val mou = Module(new Mou()).io
|
||||
|
||||
mou.in.info := io.memoryStage.inst0.info
|
||||
mou.in.pc := io.memoryStage.inst0.pc
|
||||
|
||||
dataMemoryAccess.memoryUnit.in.allow_to_go := io.ctrl.allow_to_go
|
||||
val mem_sel = VecInit(
|
||||
io.memoryStage.inst0.info.valid &&
|
||||
io.memoryStage.inst0.info.fusel === FuType.lsu &&
|
||||
|
@ -38,29 +37,30 @@ class MemoryUnit(implicit val config: CpuConfig) extends Module {
|
|||
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(
|
||||
lsu.memoryUnit.in.mem_en := mem_sel.reduce(_ || _)
|
||||
lsu.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(
|
||||
lsu.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(
|
||||
lsu.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
|
||||
lsu.dataMemory <> io.dataMemory
|
||||
lsu.memoryUnit.in.allow_to_go := io.ctrl.allow_to_go
|
||||
|
||||
val csr_sel =
|
||||
HasExcInt(io.writeBackStage.inst0.ex) || !HasExcInt(io.writeBackStage.inst1.ex)
|
||||
|
@ -87,11 +87,11 @@ class MemoryUnit(implicit val config: CpuConfig) extends Module {
|
|||
)
|
||||
)
|
||||
|
||||
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.csr.in.set_lr := lsu.memoryUnit.out.set_lr && io.ctrl.allow_to_go
|
||||
io.csr.in.set_lr_val := lsu.memoryUnit.out.set_lr_val
|
||||
io.csr.in.set_lr_addr := lsu.memoryUnit.out.set_lr_addr
|
||||
lsu.memoryUnit.in.lr := io.csr.out.lr
|
||||
lsu.memoryUnit.in.lr_addr := io.csr.out.lr_addr
|
||||
|
||||
io.decoderUnit(0).wen := io.writeBackStage.inst0.info.reg_wen
|
||||
io.decoderUnit(0).waddr := io.writeBackStage.inst0.info.reg_waddr
|
||||
|
@ -103,10 +103,10 @@ class MemoryUnit(implicit val config: CpuConfig) extends Module {
|
|||
io.writeBackStage.inst0.pc := io.memoryStage.inst0.pc
|
||||
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.rd_info.wdata(FuType.lsu) := lsu.memoryUnit.out.rdata
|
||||
io.writeBackStage.inst0.ex := Mux(
|
||||
mem_sel(0),
|
||||
dataMemoryAccess.memoryUnit.out.ex,
|
||||
lsu.memoryUnit.out.ex,
|
||||
io.memoryStage.inst0.ex
|
||||
)
|
||||
|
||||
|
@ -115,16 +115,19 @@ class MemoryUnit(implicit val config: CpuConfig) extends Module {
|
|||
io.writeBackStage.inst1.info.valid := io.memoryStage.inst1.info.valid &&
|
||||
!(io.fetchUnit.flush && csr_sel) // 指令0导致flush时,不应该提交指令1
|
||||
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.rd_info.wdata(FuType.lsu) := lsu.memoryUnit.out.rdata
|
||||
io.writeBackStage.inst1.ex := Mux(
|
||||
mem_sel(1),
|
||||
dataMemoryAccess.memoryUnit.out.ex,
|
||||
lsu.memoryUnit.out.ex,
|
||||
io.memoryStage.inst1.ex
|
||||
)
|
||||
|
||||
io.ctrl.flush := io.fetchUnit.flush
|
||||
io.ctrl.mem_stall := !dataMemoryAccess.memoryUnit.out.ready && dataMemoryAccess.memoryUnit.in.mem_en
|
||||
io.ctrl.fence_i := mou.out.fence_i
|
||||
io.ctrl.flush := io.fetchUnit.flush
|
||||
io.ctrl.mem_stall := !lsu.memoryUnit.out.ready && lsu.memoryUnit.in.mem_en
|
||||
|
||||
io.ctrl.fence_i := mou.out.fence_i
|
||||
io.ctrl.complete_single_request := lsu.memoryUnit.out.complete_single_request
|
||||
|
||||
io.fetchUnit.flush := io.ctrl.allow_to_go && (io.csr.out.flush || mou.out.fence_i)
|
||||
io.fetchUnit.target := Mux(io.csr.out.flush, io.csr.out.flush_pc, mou.out.target)
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@ import cpu.defines._
|
|||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
|
||||
class LSExe extends Module {
|
||||
class LsExecute extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val dataMemory = new DataMemoryAccess_DataMemory()
|
||||
val dataMemory = new Lsu_DataMemory()
|
||||
val in = Input(new Bundle {
|
||||
val mem_en = Bool()
|
||||
val mem_addr = UInt(DATA_ADDR_WID.W)
|
||||
|
@ -138,7 +138,7 @@ class LSExe extends Module {
|
|||
io.dataMemory.out.wdata := reqWdata
|
||||
|
||||
val is_amo = valid && LSUOpType.isAMO(op)
|
||||
io.out.ready := io.dataMemory.in.ready
|
||||
io.out.ready := io.dataMemory.in.ready && io.dataMemory.out.en
|
||||
io.out.rdata := Mux(partialLoad, rdataPartialLoad, rdataSel)
|
||||
io.out.loadAddrMisaligned := valid && !isStore && !is_amo && !addrAligned
|
||||
io.out.loadAccessFault := valid && !isStore && !is_amo && (acc_err || has_acc_err)
|
|
@ -2,8 +2,6 @@ import cpu._
|
|||
import circt.stage._
|
||||
|
||||
import cpu.pipeline.execute.Csr
|
||||
import cpu.pipeline.memory.LSExe
|
||||
import cpu.pipeline.memory.AtomAlu
|
||||
import cache.DCache
|
||||
|
||||
object TestMain extends App {
|
||||
|
|
Loading…
Reference in New Issue