重构lsExecute
This commit is contained in:
parent
2e774df884
commit
1effd2929a
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue