重构lsu

This commit is contained in:
Liphen 2024-01-22 16:43:02 +08:00
parent 33e20fa99c
commit 2e774df884
4 changed files with 59 additions and 72 deletions

View File

@ -91,8 +91,8 @@ class Core(implicit val cpuConfig: CpuConfig) extends Module {
ctrl.executeUnit.do_flush && ctrl.executeUnit.allow_to_go || ctrl.executeUnit.do_flush && ctrl.executeUnit.allow_to_go ||
!ctrl.decodeUnit.allow_to_go && ctrl.executeUnit.allow_to_go !ctrl.decodeUnit.allow_to_go && ctrl.executeUnit.allow_to_go
executeStage.ctrl.clear(1) := ctrl.memoryUnit.flush || executeStage.ctrl.clear(1) := ctrl.memoryUnit.flush ||
(ctrl.executeUnit.do_flush && decodeUnit.instFifo.allow_to_go(1)) || ctrl.executeUnit.do_flush && decodeUnit.instFifo.allow_to_go(1) ||
(ctrl.executeUnit.allow_to_go && !decodeUnit.instFifo.allow_to_go(1)) !decodeUnit.instFifo.allow_to_go(1) && ctrl.executeUnit.allow_to_go
executeStage.ctrl.allow_to_go(0) := ctrl.executeUnit.allow_to_go executeStage.ctrl.allow_to_go(0) := ctrl.executeUnit.allow_to_go
executeStage.ctrl.allow_to_go(1) := decodeUnit.instFifo.allow_to_go(1) executeStage.ctrl.allow_to_go(1) := decodeUnit.instFifo.allow_to_go(1)

View File

@ -13,9 +13,9 @@ class CsrMemoryUnit(implicit val cpuConfig: CpuConfig) extends Bundle {
val ex = new ExceptionInfo() val ex = new ExceptionInfo()
val info = new InstInfo() val info = new InstInfo()
val set_lr = Bool() val lr_wen = Bool()
val set_lr_val = Bool() val lr_wbit = Bool()
val set_lr_addr = UInt(XLEN.W) val lr_waddr = UInt(XLEN.W)
}) })
val out = Output(new Bundle { val out = Output(new Bundle {
val flush = Bool() val flush = Bool()
@ -153,20 +153,18 @@ class Csr(implicit val cpuConfig: CpuConfig) extends Module with HasCSRConst {
val wdata = Wire(UInt(XLEN.W)) val wdata = Wire(UInt(XLEN.W))
// Atom LR/SC Control Bits // Atom LR/SC Control Bits
val set_lr = WireInit(Bool(), false.B) val lr_wen = io.memoryUnit.in.lr_wen
val set_lr_val = WireInit(Bool(), false.B) val lr_wbit = io.memoryUnit.in.lr_wbit
val set_lr_addr = WireInit(UInt(XLEN.W), 0.U) val lr_waddr = io.memoryUnit.in.lr_waddr
val lr = RegInit(Bool(), false.B) val lr = RegInit(Bool(), false.B)
val lr_addr = RegInit(UInt(XLEN.W), 0.U) val lr_addr = RegInit(UInt(XLEN.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 := lr
io.memoryUnit.out.lr_addr := lr_addr io.memoryUnit.out.lr_addr := lr_addr
when(set_lr) { when(lr_wen) {
lr := set_lr_val lr := lr_wbit
lr_addr := set_lr_addr lr_addr := lr_waddr
} }
// Side Effect // Side Effect

View File

@ -43,9 +43,9 @@ class Lsu_MemoryUnit extends Bundle {
// 用于指示dcache完成一次请求 // 用于指示dcache完成一次请求
val complete_single_request = Bool() val complete_single_request = Bool()
val set_lr = Bool() val lr_wen = Bool()
val set_lr_val = Bool() val lr_wbit = Bool()
val set_lr_addr = UInt(XLEN.W) val lr_waddr = UInt(XLEN.W)
}) })
} }
@ -65,42 +65,35 @@ class Lsu(implicit val cpuConfig: CpuConfig) extends Module {
val func = io.memoryUnit.in.info.op val func = io.memoryUnit.in.info.op
val inst = io.memoryUnit.in.info.inst val inst = io.memoryUnit.in.info.inst
val storeReq = valid & LSUOpType.isStore(func) val store_req = valid & LSUOpType.isStore(func)
val loadReq = valid & LSUOpType.isLoad(func) val load_req = valid & LSUOpType.isLoad(func)
val atomReq = valid & LSUOpType.isAtom(func) val atom_req = valid & LSUOpType.isAtom(func)
val amoReq = valid & LSUOpType.isAMO(func) val amo_req = valid & LSUOpType.isAMO(func)
val lrReq = valid & LSUOpType.isLR(func) val lr_req = valid & LSUOpType.isLR(func)
val scReq = valid & LSUOpType.isSC(func) val sc_req = valid & LSUOpType.isSC(func)
val aq = inst(26)
val rl = inst(25)
val funct3 = inst(14, 12) val funct3 = inst(14, 12)
val atom_d = funct3(0)
val atomWidthW = !funct3(0)
val atomWidthD = funct3(0)
// Atom LR/SC Control Bits // Atom LR/SC Control Bits
val setLr = Wire(Bool()) val lr = WireInit(Bool(), false.B)
val setLrVal = Wire(Bool()) val lr_addr = WireInit(UInt(XLEN.W), DontCare)
val setLrAddr = Wire(UInt(XLEN.W)) io.memoryUnit.out.lr_wen := io.memoryUnit.out.ready && (lr_req || sc_req)
val lr = WireInit(Bool(), false.B) io.memoryUnit.out.lr_wbit := lr_req
val lrAddr = WireInit(UInt(XLEN.W), DontCare) io.memoryUnit.out.lr_waddr := src1
io.memoryUnit.out.set_lr := setLr lr := io.memoryUnit.in.lr
io.memoryUnit.out.set_lr_val := setLrVal lr_addr := io.memoryUnit.in.lr_addr
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_a :: s_amo_s :: Nil = Enum(4) val s_idle :: s_sc :: s_amo_a :: s_amo_s :: Nil = Enum(4)
val state = RegInit(s_idle) val state = RegInit(s_idle)
val atomMemReg = Reg(UInt(XLEN.W)) val atom_wdata = Reg(UInt(XLEN.W))
val atomRegReg = Reg(UInt(XLEN.W)) val atom_rdata = Reg(UInt(XLEN.W))
atomAlu.in.rdata := atomMemReg atomAlu.in.rdata := atom_wdata
atomAlu.in.src2 := src2 atomAlu.in.src2 := src2
atomAlu.in.info := io.memoryUnit.in.info atomAlu.in.info := io.memoryUnit.in.info
val scInvalid = (src1 =/= lrAddr || !lr) && scReq val sc_invalid = (src1 =/= lr_addr || !lr) && sc_req
lsExe.in.info := DontCare lsExe.in.info := DontCare
lsExe.in.mem_addr := DontCare lsExe.in.mem_addr := DontCare
@ -117,15 +110,15 @@ class Lsu(implicit val cpuConfig: CpuConfig) extends Module {
switch(state) { switch(state) {
is(s_idle) { // 0 is(s_idle) { // 0
lsExe.in.mem_en := io.memoryUnit.in.mem_en && !atomReq lsExe.in.mem_en := io.memoryUnit.in.mem_en && !atom_req
lsExe.in.mem_addr := src1 + imm lsExe.in.mem_addr := src1 + imm
lsExe.in.info.op := func lsExe.in.info.op := func
lsExe.in.wdata := src2 lsExe.in.wdata := src2
io.memoryUnit.out.ready := lsExe.out.ready || scInvalid io.memoryUnit.out.ready := lsExe.out.ready || sc_invalid
when(amoReq) { when(amo_req) {
lsExe.in.mem_en := true.B lsExe.in.mem_en := true.B
lsExe.in.mem_addr := src1 lsExe.in.mem_addr := src1
lsExe.in.info.op := Mux(atomWidthD, LSUOpType.ld, LSUOpType.lw) lsExe.in.info.op := Mux(atom_d, LSUOpType.ld, LSUOpType.lw)
lsExe.in.wdata := DontCare lsExe.in.wdata := DontCare
io.memoryUnit.out.ready := false.B io.memoryUnit.out.ready := false.B
when(lsExe.out.ready) { when(lsExe.out.ready) {
@ -133,23 +126,23 @@ class Lsu(implicit val cpuConfig: CpuConfig) extends Module {
// 告诉dcache已经完成一次访存操作可以进入下一次访存 // 告诉dcache已经完成一次访存操作可以进入下一次访存
complete_single_request := true.B complete_single_request := true.B
} }
atomMemReg := lsExe.out.rdata atom_wdata := lsExe.out.rdata
atomRegReg := lsExe.out.rdata atom_rdata := lsExe.out.rdata
} }
when(lrReq) { when(lr_req) {
lsExe.in.mem_en := true.B lsExe.in.mem_en := true.B
lsExe.in.mem_addr := src1 lsExe.in.mem_addr := src1
lsExe.in.info.op := Mux(atomWidthD, LSUOpType.ld, LSUOpType.lw) lsExe.in.info.op := Mux(atom_d, LSUOpType.ld, LSUOpType.lw)
lsExe.in.wdata := DontCare lsExe.in.wdata := DontCare
io.memoryUnit.out.ready := lsExe.out.ready io.memoryUnit.out.ready := lsExe.out.ready
} }
when(scReq) { state := Mux(scInvalid, s_idle, s_sc) } when(sc_req) { state := Mux(sc_invalid, s_idle, s_sc) }
} }
is(s_sc) { // 1 is(s_sc) { // 1
lsExe.in.mem_en := true.B lsExe.in.mem_en := true.B
lsExe.in.mem_addr := src1 lsExe.in.mem_addr := src1
lsExe.in.info.op := Mux(atomWidthD, LSUOpType.sd, LSUOpType.sw) lsExe.in.info.op := Mux(atom_d, LSUOpType.sd, LSUOpType.sw)
lsExe.in.wdata := src2 lsExe.in.wdata := src2
io.memoryUnit.out.ready := lsExe.out.ready io.memoryUnit.out.ready := lsExe.out.ready
when(allow_to_go) { when(allow_to_go) {
@ -164,14 +157,14 @@ class Lsu(implicit val cpuConfig: CpuConfig) extends Module {
lsExe.in.wdata := DontCare lsExe.in.wdata := DontCare
io.memoryUnit.out.ready := false.B io.memoryUnit.out.ready := false.B
state := s_amo_s state := s_amo_s
atomMemReg := atomAlu.out.result atom_wdata := atomAlu.out.result
} }
is(s_amo_s) { // 3 is(s_amo_s) { // 3
lsExe.in.mem_en := true.B lsExe.in.mem_en := true.B
lsExe.in.mem_addr := src1 lsExe.in.mem_addr := src1
lsExe.in.info.op := Mux(atomWidthD, LSUOpType.sd, LSUOpType.sw) lsExe.in.info.op := Mux(atom_d, LSUOpType.sd, LSUOpType.sw)
lsExe.in.wdata := atomMemReg lsExe.in.wdata := atom_wdata
io.memoryUnit.out.ready := lsExe.out.ready io.memoryUnit.out.ready := lsExe.out.ready
when(allow_to_go) { when(allow_to_go) {
state := s_idle state := s_idle
@ -189,19 +182,15 @@ class Lsu(implicit val cpuConfig: CpuConfig) extends Module {
complete_single_request := false.B // 发生例外时应该由ctrl的allow to go控制 complete_single_request := false.B // 发生例外时应该由ctrl的allow to go控制
} }
setLr := io.memoryUnit.out.ready && (lrReq || scReq)
setLrVal := lrReq
setLrAddr := src1
io.dataMemory <> lsExe.dataMemory io.dataMemory <> lsExe.dataMemory
io.memoryUnit.out.ex := io.memoryUnit.in.ex io.memoryUnit.out.ex := io.memoryUnit.in.ex
io.memoryUnit.out.ex.exception(loadAddrMisaligned) := (loadReq || lrReq) && lsExe.out.addr_misaligned io.memoryUnit.out.ex.exception(loadAddrMisaligned) := (load_req || lr_req) && lsExe.out.addr_misaligned
io.memoryUnit.out.ex.exception(loadAccessFault) := (loadReq || lrReq) && lsExe.out.access_fault io.memoryUnit.out.ex.exception(loadAccessFault) := (load_req || lr_req) && lsExe.out.access_fault
io.memoryUnit.out.ex.exception(loadPageFault) := (loadReq || lrReq) && lsExe.out.page_fault io.memoryUnit.out.ex.exception(loadPageFault) := (load_req || lr_req) && lsExe.out.page_fault
io.memoryUnit.out.ex.exception(storeAddrMisaligned) := (storeReq || scReq || amoReq) && lsExe.out.addr_misaligned io.memoryUnit.out.ex.exception(storeAddrMisaligned) := (store_req || sc_req || amo_req) && lsExe.out.addr_misaligned
io.memoryUnit.out.ex.exception(storeAccessFault) := (storeReq || scReq || amoReq) && lsExe.out.addr_misaligned io.memoryUnit.out.ex.exception(storeAccessFault) := (store_req || sc_req || amo_req) && lsExe.out.addr_misaligned
io.memoryUnit.out.ex.exception(storePageFault) := (storeReq || scReq || amoReq) && lsExe.out.page_fault io.memoryUnit.out.ex.exception(storePageFault) := (store_req || sc_req || amo_req) && lsExe.out.page_fault
io.memoryUnit.out.ex.tval(loadAddrMisaligned) := io.dataMemory.out.addr io.memoryUnit.out.ex.tval(loadAddrMisaligned) := io.dataMemory.out.addr
io.memoryUnit.out.ex.tval(loadAccessFault) := io.dataMemory.out.addr io.memoryUnit.out.ex.tval(loadAccessFault) := io.dataMemory.out.addr
@ -213,8 +202,8 @@ class Lsu(implicit val cpuConfig: CpuConfig) extends Module {
io.memoryUnit.out.rdata := MuxCase( io.memoryUnit.out.rdata := MuxCase(
lsExe.out.rdata, lsExe.out.rdata,
Seq( Seq(
(scReq) -> scInvalid, (sc_req) -> sc_invalid,
(amoReq) -> atomRegReg (amo_req) -> atom_rdata
) )
) )
} }

View File

@ -66,9 +66,9 @@ class MemoryUnit(implicit val cpuConfig: CpuConfig) extends Module {
io.csr.in.info := selectInstField(csr_sel, io.memoryStage.inst.map(_.info)) io.csr.in.info := selectInstField(csr_sel, io.memoryStage.inst.map(_.info))
} }
io.csr.in.set_lr := lsu.memoryUnit.out.set_lr && io.ctrl.allow_to_go io.csr.in.lr_wen := lsu.memoryUnit.out.lr_wen && io.ctrl.allow_to_go
io.csr.in.set_lr_val := lsu.memoryUnit.out.set_lr_val io.csr.in.lr_wbit := lsu.memoryUnit.out.lr_wbit
io.csr.in.set_lr_addr := lsu.memoryUnit.out.set_lr_addr io.csr.in.lr_waddr := lsu.memoryUnit.out.lr_waddr
lsu.memoryUnit.in.lr := io.csr.out.lr lsu.memoryUnit.in.lr := io.csr.out.lr
lsu.memoryUnit.in.lr_addr := io.csr.out.lr_addr lsu.memoryUnit.in.lr_addr := io.csr.out.lr_addr