feat: 通过所有测试用例

This commit is contained in:
Liphen 2023-12-07 21:14:40 +08:00
parent 87fc0f60ee
commit 2a16d26278
6 changed files with 98 additions and 70 deletions

View File

@ -119,7 +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
memoryUnit.dataMemory.in.ready := io.data.dcache_ready
io.data.en := memoryUnit.dataMemory.out.en
io.data.size := memoryUnit.dataMemory.out.rlen
io.data.wen := memoryUnit.dataMemory.out.wen

View File

@ -15,11 +15,9 @@ class DCache(implicit config: CpuConfig) extends Module {
})
// * fsm * //
val s_idle :: s_uncached :: s_writeback :: s_save :: Nil = Enum(4)
val s_idle :: s_uncached :: s_writeback :: Nil = Enum(3)
val status = RegInit(s_idle)
io.cpu.valid := status === s_save
val addr_err = io.cpu.addr(63, 32).orR
// default
@ -69,11 +67,7 @@ class DCache(implicit config: CpuConfig) extends Module {
val mmio_read_stall = !io.cpu.wen.orR
val mmio_write_stall = io.cpu.wen.orR && !io.axi.w.ready
val cached_stall = false.B
io.cpu.dcache_stall := Mux(
status === s_idle && !acc_err,
Mux(io.cpu.en, (cached_stall || mmio_read_stall || mmio_write_stall), io.cpu.fence),
status =/= s_save
)
io.cpu.dcache_ready := status === s_idle
io.cpu.rdata := saved_rdata
io.cpu.acc_err := acc_err
@ -83,7 +77,7 @@ class DCache(implicit config: CpuConfig) extends Module {
when(io.cpu.en) {
when(addr_err) {
acc_err := true.B
status := s_save
status := s_idle
}.otherwise {
when(io.cpu.wen) {
awaddr := io.cpu.addr(31, 0)
@ -110,7 +104,7 @@ class DCache(implicit config: CpuConfig) extends Module {
when(io.axi.r.valid) {
saved_rdata := io.axi.r.data
acc_err := io.axi.r.resp =/= RESP_OKEY.U
status := s_save
status := s_idle
}
}
is(s_writeback) {
@ -122,11 +116,6 @@ class DCache(implicit config: CpuConfig) extends Module {
}
when(io.axi.b.valid) {
acc_err := io.axi.b.resp =/= RESP_OKEY.U
status := s_save
}
}
is(s_save) {
when(!io.cpu.dcache_stall) {
status := s_idle
}
}

View File

@ -132,9 +132,8 @@ class Cache_DCache extends Bundle {
val wstrb = Output(UInt(AXI_STRB_WID.W))
val rdata = Input(UInt(XLEN.W))
val valid = Input(Bool())
val acc_err = Input(Bool())
val dcache_stall = Input(Bool())
val dcache_ready = Input(Bool())
}
// axi

View File

@ -32,6 +32,8 @@ class DataMemoryAccess_MemoryUnit extends Bundle {
val lr = Bool()
val lr_addr = UInt(DATA_ADDR_WID.W)
val allow_to_go = Bool()
})
val out = Output(new Bundle {
val ready = Bool()
@ -86,7 +88,7 @@ class DataMemoryAccess(implicit val config: CpuConfig) extends Module {
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 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))
@ -97,25 +99,42 @@ class DataMemoryAccess(implicit val config: CpuConfig) extends Module {
val scInvalid = (src1 =/= lrAddr || !lr) && scReq
lsExe.in.info := io.memoryUnit.in.info
lsExe.in.mem_addr := 0.U
lsExe.in.info := DontCare
lsExe.in.mem_addr := DontCare
lsExe.in.mem_en := false.B
lsExe.in.wdata := 0.U
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 || scInvalid
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) { state := s_lr }
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) {
@ -125,10 +144,21 @@ class DataMemoryAccess(implicit val config: CpuConfig) extends Module {
lsExe.in.wdata := DontCare
io.memoryUnit.out.ready := false.B
when(lsExe.out.ready) {
state := s_amo_a;
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) {
@ -146,19 +176,12 @@ class DataMemoryAccess(implicit val config: CpuConfig) extends Module {
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.memoryUnit.out.ready := lsExe.out.ready && io.dataMemory.out.en
when(lsExe.out.ready) {
state := s_idle;
when(allow_to_go) {
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.out.ready
when(lsExe.out.ready) {
state := s_idle;
state := s_wait_allow;
}
}
is(s_sc) {
@ -166,15 +189,38 @@ class DataMemoryAccess(implicit val config: CpuConfig) extends Module {
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.memoryUnit.out.ready := lsExe.out.ready && io.dataMemory.out.en
when(lsExe.out.ready) {
state := s_idle;
}
}
}
when(lsExe.out.loadAddrMisaligned || lsExe.out.storeAddrMisaligned) {
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
io.memoryUnit.out.ready := true.B
}
@ -189,6 +235,13 @@ class DataMemoryAccess(implicit val config: CpuConfig) extends Module {
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 := lsExe.out.rdata
io.memoryUnit.out.rdata := MuxCase(
lsExe.out.rdata,
Seq(
(scReq) -> scInvalid,
(amoReq) -> atomRegReg
)
)
}

View File

@ -71,7 +71,6 @@ class LSExe extends Module {
val valid = io.in.mem_en
val addr = io.in.mem_addr
val addrLatch = RegNext(addr)
val op = io.in.info.op
val isStore = valid && LSUOpType.isStore(op)
@ -88,7 +87,7 @@ class LSExe extends Module {
val acc_err = io.dataMemory.in.acc_err
val rdataSel64 = LookupTree(
addrLatch(2, 0),
addr(2, 0),
List(
"b000".U -> rdata(63, 0),
"b001".U -> rdata(63, 8),
@ -101,7 +100,7 @@ class LSExe extends Module {
)
)
val rdataSel32 = LookupTree(
addrLatch(1, 0),
addr(1, 0),
List(
"b00".U -> rdata(31, 0),
"b01".U -> rdata(31, 8),
@ -131,19 +130,6 @@ class LSExe extends Module {
)
)
// val s_idle :: s_wait_resp :: Nil = Enum(2)
// val state = RegInit(s_idle)
// switch(state) {
// is(s_idle) {
// when(io.dataMemory.in.ready && io.dataMemory.out.en) { state := s_wait_resp }
// }
// is(s_wait_resp) {
// when(io.dataMemory.in.ready) { state := s_idle }
// }
// }
io.dataMemory.out.en := valid && !io.out.storeAddrMisaligned && !io.out.loadAddrMisaligned && !has_acc_err
io.dataMemory.out.rlen := size
io.dataMemory.out.wen := isStore

View File

@ -24,6 +24,7 @@ class MemoryUnit(implicit val config: CpuConfig) extends Module {
})
val dataMemoryAccess = Module(new DataMemoryAccess()).io
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 &&