重构lsExecute

This commit is contained in:
Liphen 2024-01-22 16:50:45 +08:00
parent 2e774df884
commit 1effd2929a
2 changed files with 73 additions and 72 deletions

View File

@ -55,8 +55,8 @@ class Lsu(implicit val cpuConfig: CpuConfig) extends Module {
val dataMemory = new Lsu_DataMemory() val dataMemory = new Lsu_DataMemory()
}) })
val atomAlu = Module(new AtomAlu()).io val atomAlu = Module(new AtomAlu()).io
val lsExe = Module(new LsExecute()).io val lsExecute = Module(new LsExecute()).io
val valid = io.memoryUnit.in.mem_en val valid = io.memoryUnit.in.mem_en
val src1 = io.memoryUnit.in.src_info.src1_data val src1 = io.memoryUnit.in.src_info.src1_data
@ -95,10 +95,10 @@ class Lsu(implicit val cpuConfig: CpuConfig) extends Module {
val sc_invalid = (src1 =/= lr_addr || !lr) && sc_req val sc_invalid = (src1 =/= lr_addr || !lr) && sc_req
lsExe.in.info := DontCare lsExecute.in.info := DontCare
lsExe.in.mem_addr := DontCare lsExecute.in.mem_addr := DontCare
lsExe.in.mem_en := false.B lsExecute.in.mem_en := false.B
lsExe.in.wdata := DontCare lsExecute.in.wdata := DontCare
io.memoryUnit.out.ready := false.B io.memoryUnit.out.ready := false.B
val allow_to_go = io.memoryUnit.in.allow_to_go val allow_to_go = io.memoryUnit.in.allow_to_go
@ -110,62 +110,62 @@ 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 && !atom_req lsExecute.in.mem_en := io.memoryUnit.in.mem_en && !atom_req
lsExe.in.mem_addr := src1 + imm lsExecute.in.mem_addr := src1 + imm
lsExe.in.info.op := func lsExecute.in.info.op := func
lsExe.in.wdata := src2 lsExecute.in.wdata := src2
io.memoryUnit.out.ready := lsExe.out.ready || sc_invalid io.memoryUnit.out.ready := lsExecute.out.ready || sc_invalid
when(amo_req) { when(amo_req) {
lsExe.in.mem_en := true.B lsExecute.in.mem_en := true.B
lsExe.in.mem_addr := src1 lsExecute.in.mem_addr := src1
lsExe.in.info.op := Mux(atom_d, LSUOpType.ld, LSUOpType.lw) lsExecute.in.info.op := Mux(atom_d, LSUOpType.ld, LSUOpType.lw)
lsExe.in.wdata := DontCare lsExecute.in.wdata := DontCare
io.memoryUnit.out.ready := false.B io.memoryUnit.out.ready := false.B
when(lsExe.out.ready) { when(lsExecute.out.ready) {
state := s_amo_a; state := s_amo_a;
// 告诉dcache已经完成一次访存操作可以进入下一次访存 // 告诉dcache已经完成一次访存操作可以进入下一次访存
complete_single_request := true.B complete_single_request := true.B
} }
atom_wdata := lsExe.out.rdata atom_wdata := lsExecute.out.rdata
atom_rdata := lsExe.out.rdata atom_rdata := lsExecute.out.rdata
} }
when(lr_req) { when(lr_req) {
lsExe.in.mem_en := true.B lsExecute.in.mem_en := true.B
lsExe.in.mem_addr := src1 lsExecute.in.mem_addr := src1
lsExe.in.info.op := Mux(atom_d, LSUOpType.ld, LSUOpType.lw) lsExecute.in.info.op := Mux(atom_d, LSUOpType.ld, LSUOpType.lw)
lsExe.in.wdata := DontCare lsExecute.in.wdata := DontCare
io.memoryUnit.out.ready := lsExe.out.ready io.memoryUnit.out.ready := lsExecute.out.ready
} }
when(sc_req) { state := Mux(sc_invalid, 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 lsExecute.in.mem_en := true.B
lsExe.in.mem_addr := src1 lsExecute.in.mem_addr := src1
lsExe.in.info.op := Mux(atom_d, LSUOpType.sd, LSUOpType.sw) lsExecute.in.info.op := Mux(atom_d, LSUOpType.sd, LSUOpType.sw)
lsExe.in.wdata := src2 lsExecute.in.wdata := src2
io.memoryUnit.out.ready := lsExe.out.ready io.memoryUnit.out.ready := lsExecute.out.ready
when(allow_to_go) { when(allow_to_go) {
state := s_idle state := s_idle
} }
} }
is(s_amo_a) { // 2 is(s_amo_a) { // 2
lsExe.in.mem_en := false.B lsExecute.in.mem_en := false.B
lsExe.in.mem_addr := DontCare lsExecute.in.mem_addr := DontCare
lsExe.in.info.op := DontCare lsExecute.in.info.op := DontCare
lsExe.in.wdata := DontCare lsExecute.in.wdata := DontCare
io.memoryUnit.out.ready := false.B io.memoryUnit.out.ready := false.B
state := s_amo_s state := s_amo_s
atom_wdata := atomAlu.out.result atom_wdata := atomAlu.out.result
} }
is(s_amo_s) { // 3 is(s_amo_s) { // 3
lsExe.in.mem_en := true.B lsExecute.in.mem_en := true.B
lsExe.in.mem_addr := src1 lsExecute.in.mem_addr := src1
lsExe.in.info.op := Mux(atom_d, LSUOpType.sd, LSUOpType.sw) lsExecute.in.info.op := Mux(atom_d, LSUOpType.sd, LSUOpType.sw)
lsExe.in.wdata := atom_wdata lsExecute.in.wdata := atom_wdata
io.memoryUnit.out.ready := lsExe.out.ready io.memoryUnit.out.ready := lsExecute.out.ready
when(allow_to_go) { when(allow_to_go) {
state := s_idle state := s_idle
} }
@ -173,24 +173,25 @@ class Lsu(implicit val cpuConfig: CpuConfig) extends Module {
} }
when( when(
lsExe.out.addr_misaligned || lsExecute.out.addr_misaligned ||
lsExe.out.access_fault || lsExecute.out.access_fault ||
lsExe.out.page_fault lsExecute.out.page_fault
) { ) {
state := s_idle state := s_idle
io.memoryUnit.out.ready := true.B io.memoryUnit.out.ready := true.B
complete_single_request := false.B // 发生例外时应该由ctrl的allow to go控制 complete_single_request := false.B // 发生例外时应该由ctrl的allow to go控制
} }
io.dataMemory <> lsExe.dataMemory io.dataMemory <> lsExecute.dataMemory
io.memoryUnit.out.ex := io.memoryUnit.in.ex io.memoryUnit.out.ex := io.memoryUnit.in.ex
io.memoryUnit.out.ex.exception(loadAddrMisaligned) := (load_req || lr_req) && lsExe.out.addr_misaligned io.memoryUnit.out.ex.exception(loadAddrMisaligned) := (load_req || lr_req) && lsExecute.out.addr_misaligned
io.memoryUnit.out.ex.exception(loadAccessFault) := (load_req || lr_req) && lsExe.out.access_fault io.memoryUnit.out.ex.exception(loadAccessFault) := (load_req || lr_req) && lsExecute.out.access_fault
io.memoryUnit.out.ex.exception(loadPageFault) := (load_req || lr_req) && lsExe.out.page_fault io.memoryUnit.out.ex.exception(loadPageFault) := (load_req || lr_req) && lsExecute.out.page_fault
io.memoryUnit.out.ex.exception(storeAddrMisaligned) := (store_req || sc_req || amo_req) && lsExe.out.addr_misaligned io.memoryUnit.out.ex
io.memoryUnit.out.ex.exception(storeAccessFault) := (store_req || sc_req || amo_req) && lsExe.out.addr_misaligned .exception(storeAddrMisaligned) := (store_req || sc_req || amo_req) && lsExecute.out.addr_misaligned
io.memoryUnit.out.ex.exception(storePageFault) := (store_req || sc_req || amo_req) && lsExe.out.page_fault io.memoryUnit.out.ex.exception(storeAccessFault) := (store_req || sc_req || amo_req) && lsExecute.out.addr_misaligned
io.memoryUnit.out.ex.exception(storePageFault) := (store_req || sc_req || amo_req) && lsExecute.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
@ -200,7 +201,7 @@ class Lsu(implicit val cpuConfig: CpuConfig) extends Module {
io.memoryUnit.out.ex.tval(storePageFault) := io.dataMemory.out.addr io.memoryUnit.out.ex.tval(storePageFault) := io.dataMemory.out.addr
io.memoryUnit.out.rdata := MuxCase( io.memoryUnit.out.rdata := MuxCase(
lsExe.out.rdata, lsExecute.out.rdata,
Seq( Seq(
(sc_req) -> sc_invalid, (sc_req) -> sc_invalid,
(amo_req) -> atom_rdata (amo_req) -> atom_rdata

View File

@ -72,19 +72,19 @@ class LsExecute extends Module {
val addr = io.in.mem_addr val addr = io.in.mem_addr
val op = io.in.info.op val op = io.in.info.op
val isStore = valid && LSUOpType.isStore(op) val is_store = valid && LSUOpType.isStore(op)
val partialLoad = !isStore && (op =/= LSUOpType.ld) val partial_load = !is_store && (op =/= LSUOpType.ld)
val size = op(1, 0) val size = op(1, 0)
val reqAddr = if (XLEN == 32) SignedExtend(addr, XLEN) else addr val req_addr = if (XLEN == 32) SignedExtend(addr, XLEN) else addr
val reqWdata = if (XLEN == 32) genWdata32(io.in.wdata, size) else genWdata(io.in.wdata, size) val req_wdata = if (XLEN == 32) genWdata32(io.in.wdata, size) else genWdata(io.in.wdata, size)
val reqWmask = if (XLEN == 32) genWmask32(addr, size) else genWmask(addr, size) val req_wmask = if (XLEN == 32) genWmask32(addr, size) else genWmask(addr, size)
val rdata = io.dataMemory.in.rdata val rdata = io.dataMemory.in.rdata
val access_fault = io.dataMemory.in.access_fault val access_fault = io.dataMemory.in.access_fault
val page_fault = io.dataMemory.in.page_fault val page_fault = io.dataMemory.in.page_fault
val rdataSel64 = LookupTree( val rdata64 = LookupTree(
addr(2, 0), addr(2, 0),
List( List(
"b000".U -> rdata(63, 0), "b000".U -> rdata(63, 0),
@ -97,7 +97,7 @@ class LsExecute extends Module {
"b111".U -> rdata(63, 56) "b111".U -> rdata(63, 56)
) )
) )
val rdataSel32 = LookupTree( val rdata32 = LookupTree(
addr(1, 0), addr(1, 0),
List( List(
"b00".U -> rdata(31, 0), "b00".U -> rdata(31, 0),
@ -106,19 +106,19 @@ class LsExecute extends Module {
"b11".U -> rdata(31, 24) "b11".U -> rdata(31, 24)
) )
) )
val rdataSel = if (XLEN == 32) rdataSel32 else rdataSel64 val rdata_result = if (XLEN == 32) rdata32 else rdata64
val rdataPartialLoad = LookupTree( val rdata_partial_result = LookupTree(
op, op,
List( List(
LSUOpType.lb -> SignedExtend(rdataSel(7, 0), XLEN), LSUOpType.lb -> SignedExtend(rdata_result(7, 0), XLEN),
LSUOpType.lh -> SignedExtend(rdataSel(15, 0), XLEN), LSUOpType.lh -> SignedExtend(rdata_result(15, 0), XLEN),
LSUOpType.lw -> SignedExtend(rdataSel(31, 0), XLEN), LSUOpType.lw -> SignedExtend(rdata_result(31, 0), XLEN),
LSUOpType.lbu -> ZeroExtend(rdataSel(7, 0), XLEN), LSUOpType.lbu -> ZeroExtend(rdata_result(7, 0), XLEN),
LSUOpType.lhu -> ZeroExtend(rdataSel(15, 0), XLEN), LSUOpType.lhu -> ZeroExtend(rdata_result(15, 0), XLEN),
LSUOpType.lwu -> ZeroExtend(rdataSel(31, 0), XLEN) LSUOpType.lwu -> ZeroExtend(rdata_result(31, 0), XLEN)
) )
) )
val addrAligned = LookupTree( val addr_aligned = LookupTree(
op(1, 0), op(1, 0),
List( List(
"b00".U -> true.B, //b "b00".U -> true.B, //b
@ -130,14 +130,14 @@ class LsExecute extends Module {
io.dataMemory.out.en := valid && !io.out.addr_misaligned io.dataMemory.out.en := valid && !io.out.addr_misaligned
io.dataMemory.out.rlen := size io.dataMemory.out.rlen := size
io.dataMemory.out.wen := isStore io.dataMemory.out.wen := is_store
io.dataMemory.out.wstrb := reqWmask io.dataMemory.out.wstrb := req_wmask
io.dataMemory.out.addr := reqAddr io.dataMemory.out.addr := req_addr
io.dataMemory.out.wdata := reqWdata io.dataMemory.out.wdata := req_wdata
io.out.ready := io.dataMemory.in.ready && io.dataMemory.out.en io.out.ready := io.dataMemory.in.ready && io.dataMemory.out.en
io.out.rdata := Mux(partialLoad, rdataPartialLoad, rdataSel) io.out.rdata := Mux(partial_load, rdata_partial_result, rdata_result)
io.out.addr_misaligned := valid && !addrAligned io.out.addr_misaligned := valid && !addr_aligned
io.out.access_fault := valid && access_fault io.out.access_fault := valid && access_fault
io.out.page_fault := valid && page_fault io.out.page_fault := valid && page_fault
} }