feat: 通过所有测试用例
This commit is contained in:
parent
87fc0f60ee
commit
2a16d26278
|
@ -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
|
||||
|
|
|
@ -15,10 +15,8 @@ class DCache(implicit config: CpuConfig) extends Module {
|
|||
})
|
||||
|
||||
// * fsm * //
|
||||
val s_idle :: s_uncached :: s_writeback :: s_save :: Nil = Enum(4)
|
||||
val status = RegInit(s_idle)
|
||||
|
||||
io.cpu.valid := status === s_save
|
||||
val s_idle :: s_uncached :: s_writeback :: Nil = Enum(3)
|
||||
val status = RegInit(s_idle)
|
||||
|
||||
val addr_err = io.cpu.addr(63, 32).orR
|
||||
|
||||
|
@ -69,13 +67,9 @@ 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.rdata := saved_rdata
|
||||
io.cpu.acc_err := acc_err
|
||||
io.cpu.dcache_ready := status === s_idle
|
||||
io.cpu.rdata := saved_rdata
|
||||
io.cpu.acc_err := acc_err
|
||||
|
||||
switch(status) {
|
||||
is(s_idle) {
|
||||
|
@ -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,12 +116,7 @@ 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
|
||||
status := s_idle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
state := s_idle
|
||||
|
||||
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) {
|
||||
|
@ -124,11 +143,22 @@ class DataMemoryAccess(implicit val config: CpuConfig) extends Module {
|
|||
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;
|
||||
}
|
||||
atomMemReg := lsExe.out.rdata
|
||||
atomRegReg := lsExe.out.rdata
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
when(allow_to_go) {
|
||||
state := s_idle
|
||||
}
|
||||
state := s_wait_allow;
|
||||
}
|
||||
}
|
||||
is(s_sc) {
|
||||
|
@ -166,16 +189,39 @@ 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(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) {
|
||||
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
|
||||
}
|
||||
|
||||
setLr := io.memoryUnit.out.ready && (lrReq || scReq)
|
||||
|
@ -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.ex.tval := io.dataMemory.out.addr
|
||||
io.memoryUnit.out.rdata := MuxCase(
|
||||
lsExe.out.rdata,
|
||||
Seq(
|
||||
(scReq) -> scInvalid,
|
||||
(amoReq) -> atomRegReg
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -69,10 +69,9 @@ 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 valid = io.in.mem_en
|
||||
val addr = io.in.mem_addr
|
||||
val op = io.in.info.op
|
||||
|
||||
val isStore = valid && LSUOpType.isStore(op)
|
||||
val partialLoad = !isStore && (op =/= LSUOpType.ld)
|
||||
|
@ -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
|
||||
|
|
|
@ -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 &&
|
||||
|
|
Loading…
Reference in New Issue