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.rdata := io.data.rdata
|
||||||
memoryUnit.dataMemory.in.acc_err := io.data.acc_err
|
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.en := memoryUnit.dataMemory.out.en
|
||||||
io.data.size := memoryUnit.dataMemory.out.rlen
|
io.data.size := memoryUnit.dataMemory.out.rlen
|
||||||
io.data.wen := memoryUnit.dataMemory.out.wen
|
io.data.wen := memoryUnit.dataMemory.out.wen
|
||||||
|
|
|
@ -15,10 +15,8 @@ class DCache(implicit config: CpuConfig) extends Module {
|
||||||
})
|
})
|
||||||
|
|
||||||
// * fsm * //
|
// * 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)
|
val status = RegInit(s_idle)
|
||||||
|
|
||||||
io.cpu.valid := status === s_save
|
|
||||||
|
|
||||||
val addr_err = io.cpu.addr(63, 32).orR
|
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_read_stall = !io.cpu.wen.orR
|
||||||
val mmio_write_stall = io.cpu.wen.orR && !io.axi.w.ready
|
val mmio_write_stall = io.cpu.wen.orR && !io.axi.w.ready
|
||||||
val cached_stall = false.B
|
val cached_stall = false.B
|
||||||
io.cpu.dcache_stall := Mux(
|
io.cpu.dcache_ready := status === s_idle
|
||||||
status === s_idle && !acc_err,
|
io.cpu.rdata := saved_rdata
|
||||||
Mux(io.cpu.en, (cached_stall || mmio_read_stall || mmio_write_stall), io.cpu.fence),
|
io.cpu.acc_err := acc_err
|
||||||
status =/= s_save
|
|
||||||
)
|
|
||||||
io.cpu.rdata := saved_rdata
|
|
||||||
io.cpu.acc_err := acc_err
|
|
||||||
|
|
||||||
switch(status) {
|
switch(status) {
|
||||||
is(s_idle) {
|
is(s_idle) {
|
||||||
|
@ -83,7 +77,7 @@ class DCache(implicit config: CpuConfig) extends Module {
|
||||||
when(io.cpu.en) {
|
when(io.cpu.en) {
|
||||||
when(addr_err) {
|
when(addr_err) {
|
||||||
acc_err := true.B
|
acc_err := true.B
|
||||||
status := s_save
|
status := s_idle
|
||||||
}.otherwise {
|
}.otherwise {
|
||||||
when(io.cpu.wen) {
|
when(io.cpu.wen) {
|
||||||
awaddr := io.cpu.addr(31, 0)
|
awaddr := io.cpu.addr(31, 0)
|
||||||
|
@ -110,7 +104,7 @@ class DCache(implicit config: CpuConfig) extends Module {
|
||||||
when(io.axi.r.valid) {
|
when(io.axi.r.valid) {
|
||||||
saved_rdata := io.axi.r.data
|
saved_rdata := io.axi.r.data
|
||||||
acc_err := io.axi.r.resp =/= RESP_OKEY.U
|
acc_err := io.axi.r.resp =/= RESP_OKEY.U
|
||||||
status := s_save
|
status := s_idle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is(s_writeback) {
|
is(s_writeback) {
|
||||||
|
@ -122,12 +116,7 @@ class DCache(implicit config: CpuConfig) extends Module {
|
||||||
}
|
}
|
||||||
when(io.axi.b.valid) {
|
when(io.axi.b.valid) {
|
||||||
acc_err := io.axi.b.resp =/= RESP_OKEY.U
|
acc_err := io.axi.b.resp =/= RESP_OKEY.U
|
||||||
status := s_save
|
status := s_idle
|
||||||
}
|
|
||||||
}
|
|
||||||
is(s_save) {
|
|
||||||
when(!io.cpu.dcache_stall) {
|
|
||||||
status := s_idle
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,9 +132,8 @@ class Cache_DCache extends Bundle {
|
||||||
val wstrb = Output(UInt(AXI_STRB_WID.W))
|
val wstrb = Output(UInt(AXI_STRB_WID.W))
|
||||||
|
|
||||||
val rdata = Input(UInt(XLEN.W))
|
val rdata = Input(UInt(XLEN.W))
|
||||||
val valid = Input(Bool())
|
|
||||||
val acc_err = Input(Bool())
|
val acc_err = Input(Bool())
|
||||||
val dcache_stall = Input(Bool())
|
val dcache_ready = Input(Bool())
|
||||||
}
|
}
|
||||||
|
|
||||||
// axi
|
// axi
|
||||||
|
|
|
@ -32,6 +32,8 @@ class DataMemoryAccess_MemoryUnit extends Bundle {
|
||||||
|
|
||||||
val lr = Bool()
|
val lr = Bool()
|
||||||
val lr_addr = UInt(DATA_ADDR_WID.W)
|
val lr_addr = UInt(DATA_ADDR_WID.W)
|
||||||
|
|
||||||
|
val allow_to_go = Bool()
|
||||||
})
|
})
|
||||||
val out = Output(new Bundle {
|
val out = Output(new Bundle {
|
||||||
val ready = Bool()
|
val ready = Bool()
|
||||||
|
@ -86,7 +88,7 @@ class DataMemoryAccess(implicit val config: CpuConfig) extends Module {
|
||||||
lr := io.memoryUnit.in.lr
|
lr := io.memoryUnit.in.lr
|
||||||
lrAddr := io.memoryUnit.in.lr_addr
|
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 state = RegInit(s_idle)
|
||||||
val atomMemReg = Reg(UInt(XLEN.W))
|
val atomMemReg = Reg(UInt(XLEN.W))
|
||||||
|
@ -97,25 +99,42 @@ class DataMemoryAccess(implicit val config: CpuConfig) extends Module {
|
||||||
|
|
||||||
val scInvalid = (src1 =/= lrAddr || !lr) && scReq
|
val scInvalid = (src1 =/= lrAddr || !lr) && scReq
|
||||||
|
|
||||||
lsExe.in.info := io.memoryUnit.in.info
|
lsExe.in.info := DontCare
|
||||||
lsExe.in.mem_addr := 0.U
|
lsExe.in.mem_addr := DontCare
|
||||||
lsExe.in.mem_en := false.B
|
lsExe.in.mem_en := false.B
|
||||||
lsExe.in.wdata := 0.U
|
lsExe.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
|
||||||
|
|
||||||
switch(state) {
|
switch(state) {
|
||||||
is(s_idle) { // calculate address
|
is(s_idle) { // calculate address
|
||||||
lsExe.in.mem_en := io.memoryUnit.in.mem_en && !atomReq
|
lsExe.in.mem_en := io.memoryUnit.in.mem_en && !atomReq
|
||||||
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 && io.dataMemory.out.en || scInvalid
|
||||||
state := s_idle
|
when(io.memoryUnit.out.ready) {
|
||||||
|
when(allow_to_go) {
|
||||||
|
state := s_idle
|
||||||
|
}
|
||||||
|
state := s_wait_allow;
|
||||||
|
}
|
||||||
when(amoReq) { state := s_amo_l }
|
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) }
|
when(scReq) { state := Mux(scInvalid, s_idle, s_sc) }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
is(s_amo_l) {
|
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.info.op := Mux(atomWidthD, 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) {
|
||||||
|
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) {
|
when(lsExe.out.ready) {
|
||||||
state := s_amo_a;
|
state := s_amo_a;
|
||||||
}
|
}
|
||||||
atomMemReg := lsExe.out.rdata
|
|
||||||
atomRegReg := lsExe.out.rdata
|
|
||||||
}
|
}
|
||||||
|
|
||||||
is(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.mem_addr := src1
|
||||||
lsExe.in.info.op := Mux(atomWidthD, LSUOpType.sd, LSUOpType.sw)
|
lsExe.in.info.op := Mux(atomWidthD, LSUOpType.sd, LSUOpType.sw)
|
||||||
lsExe.in.wdata := atomMemReg
|
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) {
|
when(lsExe.out.ready) {
|
||||||
state := s_idle;
|
when(allow_to_go) {
|
||||||
}
|
state := s_idle
|
||||||
}
|
}
|
||||||
is(s_lr) {
|
state := s_wait_allow;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is(s_sc) {
|
is(s_sc) {
|
||||||
|
@ -166,16 +189,39 @@ class DataMemoryAccess(implicit val config: CpuConfig) extends Module {
|
||||||
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(atomWidthD, 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 && io.dataMemory.out.en
|
||||||
when(lsExe.out.ready) {
|
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
|
state := s_idle
|
||||||
io.memoryUnit.out.ready := true.B
|
io.memoryUnit.out.ready := true.B
|
||||||
io.memoryUnit.out.ready := true.B
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setLr := io.memoryUnit.out.ready && (lrReq || scReq)
|
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(storeAddrMisaligned) := lsExe.out.storeAddrMisaligned
|
||||||
io.memoryUnit.out.ex.exception(loadAccessFault) := lsExe.out.loadAccessFault
|
io.memoryUnit.out.ex.exception(loadAccessFault) := lsExe.out.loadAccessFault
|
||||||
io.memoryUnit.out.ex.exception(storeAccessFault) := lsExe.out.storeAccessFault
|
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 valid = io.in.mem_en
|
||||||
val addr = io.in.mem_addr
|
val addr = io.in.mem_addr
|
||||||
val addrLatch = RegNext(addr)
|
val op = io.in.info.op
|
||||||
val op = io.in.info.op
|
|
||||||
|
|
||||||
val isStore = valid && LSUOpType.isStore(op)
|
val isStore = valid && LSUOpType.isStore(op)
|
||||||
val partialLoad = !isStore && (op =/= LSUOpType.ld)
|
val partialLoad = !isStore && (op =/= LSUOpType.ld)
|
||||||
|
@ -88,7 +87,7 @@ class LSExe extends Module {
|
||||||
val acc_err = io.dataMemory.in.acc_err
|
val acc_err = io.dataMemory.in.acc_err
|
||||||
|
|
||||||
val rdataSel64 = LookupTree(
|
val rdataSel64 = LookupTree(
|
||||||
addrLatch(2, 0),
|
addr(2, 0),
|
||||||
List(
|
List(
|
||||||
"b000".U -> rdata(63, 0),
|
"b000".U -> rdata(63, 0),
|
||||||
"b001".U -> rdata(63, 8),
|
"b001".U -> rdata(63, 8),
|
||||||
|
@ -101,7 +100,7 @@ class LSExe extends Module {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
val rdataSel32 = LookupTree(
|
val rdataSel32 = LookupTree(
|
||||||
addrLatch(1, 0),
|
addr(1, 0),
|
||||||
List(
|
List(
|
||||||
"b00".U -> rdata(31, 0),
|
"b00".U -> rdata(31, 0),
|
||||||
"b01".U -> rdata(31, 8),
|
"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.en := valid && !io.out.storeAddrMisaligned && !io.out.loadAddrMisaligned && !has_acc_err
|
||||||
io.dataMemory.out.rlen := size
|
io.dataMemory.out.rlen := size
|
||||||
io.dataMemory.out.wen := isStore
|
io.dataMemory.out.wen := isStore
|
||||||
|
|
|
@ -24,6 +24,7 @@ class MemoryUnit(implicit val config: CpuConfig) extends Module {
|
||||||
})
|
})
|
||||||
|
|
||||||
val dataMemoryAccess = Module(new DataMemoryAccess()).io
|
val dataMemoryAccess = Module(new DataMemoryAccess()).io
|
||||||
|
dataMemoryAccess.memoryUnit.in.allow_to_go := io.ctrl.allow_to_go
|
||||||
val mem_sel = VecInit(
|
val mem_sel = VecInit(
|
||||||
io.memoryStage.inst0.info.valid &&
|
io.memoryStage.inst0.info.valid &&
|
||||||
io.memoryStage.inst0.info.fusel === FuType.lsu &&
|
io.memoryStage.inst0.info.fusel === FuType.lsu &&
|
||||||
|
|
Loading…
Reference in New Issue