fix(dcache): 修复取数据问题

This commit is contained in:
Liphen 2023-11-27 14:14:19 +08:00
parent 94352e1687
commit 152bc91507
5 changed files with 75 additions and 114 deletions

View File

@ -88,10 +88,10 @@ PuaCpu core(
.io_axi_r_valid (MAXI_rvalid), .io_axi_r_valid (MAXI_rvalid),
.io_axi_r_ready (MAXI_rready), .io_axi_r_ready (MAXI_rready),
// debug // debug
.debug_commit (debug_commit), .io_debug_wb_pc (debug_pc),
.debug_pc (debug_pc), .io_debug_wb_rf_wen (debug_commit),
.debug_reg_num (debug_reg_num), .io_debug_wb_rf_wnum (debug_reg_num),
.debug_wdata (debug_wdata) .io_debug_wb_rf_wdata (debug_wdata)
); );
endmodule endmodule

View File

@ -33,109 +33,100 @@ class DCache(implicit config: CpuConfig) extends Module {
val addr_err = io.cpu.addr(63, 32).orR val addr_err = io.cpu.addr(63, 32).orR
// default // default
val awvalid = RegInit(false.B)
val awaddr = RegInit(0.U(32.W))
val awsize = RegInit(0.U(3.W))
io.axi.aw.id := 1.U io.axi.aw.id := 1.U
io.axi.aw.addr := 0.U io.axi.aw.addr := awaddr
io.axi.aw.len := 0.U io.axi.aw.len := 0.U
io.axi.aw.size := 0.U io.axi.aw.size := awsize
io.axi.aw.burst := BURST_FIXED.U io.axi.aw.burst := BURST_INCR.U
io.axi.aw.valid := 0.U io.axi.aw.valid := awvalid
io.axi.aw.prot := 0.U io.axi.aw.prot := 0.U
io.axi.aw.lock := 0.U io.axi.aw.lock := 0.U
io.axi.aw.cache := 0.U io.axi.aw.cache := 0.U
io.axi.w.id := 1.U
io.axi.w.data := 0.U
io.axi.w.strb := 0.U
io.axi.w.last := 1.U
io.axi.w.valid := 0.U
io.axi.b.ready := 1.U
io.axi.ar.id := 1.U
io.axi.ar.addr := 0.U
io.axi.ar.len := 0.U
io.axi.ar.size := 0.U
io.axi.ar.burst := BURST_FIXED.U
val arvalid = RegInit(false.B)
io.axi.ar.valid := arvalid
io.axi.ar.prot := 0.U
io.axi.ar.cache := 0.U
io.axi.ar.lock := 0.U
io.axi.r.ready := true.B
io.cpu.rdata := 0.U
io.cpu.dcache_stall := status === s_uncached
io.cpu.acc_err := false.B val wvalid = RegInit(false.B)
io.axi.w.id := 1.U
io.axi.w.data := 0.U
io.axi.w.strb := 0.U
io.axi.w.last := 1.U
io.axi.w.valid := wvalid
io.axi.b.ready := 1.U
val araddr = RegInit(0.U(32.W))
val arsize = RegInit(0.U(3.W))
io.axi.ar.id := 1.U
io.axi.ar.addr := araddr
io.axi.ar.len := 0.U
io.axi.ar.size := arsize
io.axi.ar.burst := BURST_INCR.U
val arvalid = RegInit(false.B)
io.axi.ar.valid := arvalid
io.axi.ar.prot := 0.U
io.axi.ar.cache := 0.U
io.axi.ar.lock := 0.U
val rready = RegInit(false.B)
io.axi.r.ready := rready
val saved_rdata = RegInit(0.U(DATA_WID.W))
val acc_err = RegInit(false.B)
io.cpu.rdata := saved_rdata
io.cpu.dcache_stall := Mux(status === s_idle, io.cpu.en, status =/= s_save)
io.cpu.acc_err := acc_err
switch(status) { switch(status) {
is(s_idle) { is(s_idle) {
acc_err := false.B
when(io.cpu.en) { when(io.cpu.en) {
when(addr_err) { when(addr_err) {
io.cpu.acc_err := true.B acc_err := true.B
status := s_save status := s_save
}.otherwise { }.otherwise {
when(io.cpu.write) { when(io.cpu.write) {
io.axi.aw.addr := io.cpu.addr(31, 0) awaddr := io.cpu.addr(31, 0)
io.axi.aw.size := Cat(false.B, io.cpu.size) awsize := Cat(false.B, io.cpu.size)
io.axi.aw.valid := true.B awvalid := true.B
io.axi.w.data := io.cpu.wdata io.axi.w.data := io.cpu.wdata
io.axi.w.strb := wstrb_gen io.axi.w.strb := wstrb_gen
io.axi.w.valid := true.B wvalid := true.B
status := s_writeback status := s_writeback
}.otherwise { }.otherwise {
io.axi.ar.addr := io.cpu.addr(31, 0) araddr := io.cpu.addr(31, 0)
io.axi.ar.size := Cat(false.B, io.cpu.size) io.axi.ar.size := Cat(false.B, io.cpu.size)
arvalid := true.B arvalid := true.B
rready := true.B
status := s_uncached status := s_uncached
} }
} }
} }
} }
is(s_uncached) { is(s_uncached) {
when(io.axi.ar.ready) { when(io.axi.ar.ready && io.axi.ar.valid) {
arvalid := false.B arvalid := false.B
} }
when(io.axi.r.valid) { when(io.axi.r.valid) {
io.cpu.rdata := io.axi.r.data saved_rdata := io.axi.r.data
io.cpu.acc_err := io.axi.r.resp =/= RESP_OKEY.U acc_err := io.axi.r.resp =/= RESP_OKEY.U
status := s_save status := s_save
} }
} }
is(s_writeback) { is(s_writeback) {
when(io.axi.aw.ready) { when(io.axi.aw.ready) {
io.axi.aw.valid := false.B awvalid := false.B
} }
when(io.axi.w.ready) { when(io.axi.w.ready) {
io.axi.w.valid := false.B wvalid := false.B
} }
when(io.axi.b.valid) { when(io.axi.b.valid) {
io.cpu.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) { is(s_save) {
when(io.cpu.cpu_ready) { when(!io.cpu.dcache_stall && io.cpu.cpu_ready) {
io.cpu.acc_err := false.B status := s_idle
when(io.cpu.en) {
when(addr_err) {
io.cpu.acc_err := true.B
status := s_save
}.otherwise {
when(io.cpu.write) {
io.axi.aw.addr := io.cpu.addr(31, 0)
io.axi.aw.size := Cat(false.B, io.cpu.size)
io.axi.aw.valid := true.B
io.axi.w.data := io.cpu.wdata
io.axi.w.strb := wstrb_gen
io.axi.w.valid := true.B
status := s_writeback
}.otherwise {
io.axi.ar.addr := io.cpu.addr(31, 0)
io.axi.ar.size := Cat(false.B, io.cpu.size)
arvalid := true.B
status := s_uncached
}
}
}.otherwise {
status := s_idle
}
} }
} }
} }

View File

@ -224,9 +224,9 @@ class AXI extends Bundle {
val b = new B() // write response channel val b = new B() // write response channel
} }
class DEBUG(implicit config: CpuConfig) extends Bundle { class DEBUG extends Bundle {
val wb_pc = Output(UInt(32.W)) val wb_pc = Output(UInt(32.W))
val wb_rf_wen = Output(UInt(4.W)) val wb_rf_wen = Output(Bool())
val wb_rf_wnum = Output(UInt(5.W)) val wb_rf_wnum = Output(UInt(5.W))
val wb_rf_wdata = Output(UInt(32.W)) val wb_rf_wdata = Output(UInt(32.W))
} }

View File

@ -29,7 +29,7 @@ class DataMemoryAccess(implicit val config: CpuConfig) extends Module {
val out = Output(new Bundle { val out = Output(new Bundle {
val en = Bool() val en = Bool()
val rlen = UInt(2.W) val rlen = UInt(2.W)
val wen = UInt(4.W) val wen = Bool()
val addr = UInt(DATA_ADDR_WID.W) val addr = UInt(DATA_ADDR_WID.W)
val wdata = UInt(DATA_WID.W) val wdata = UInt(DATA_WID.W)
}) })
@ -81,17 +81,6 @@ class DataMemoryAccess(implicit val config: CpuConfig) extends Module {
) )
} }
io.dataMemory.out.wdata := genWdata(mem_wdata, op(1, 0)) io.dataMemory.out.wdata := genWdata(mem_wdata, op(1, 0))
def genWmask(addr: UInt, sizeEncode: UInt): UInt = { io.dataMemory.out.wen := LSUOpType.isStore(op) && io.memoryUnit.in.mem_en
LookupTree( io.dataMemory.out.rlen := op(1, 0)
sizeEncode,
List(
"b00".U -> 0x1.U, //0001 << addr(2:0)
"b01".U -> 0x3.U, //0011
"b10".U -> 0xf.U, //1111
"b11".U -> 0xff.U //11111111
)
) << addr(2, 0)
}
io.dataMemory.out.wen := genWmask(mem_addr, op(1, 0))
io.dataMemory.out.rlen := op(1, 0)
} }

View File

@ -2,37 +2,18 @@ package cpu.pipeline.writeback
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._
import cpu.defines.DEBUG
class CommitBuffer( class CommitBuffer(
depth: Int = 32, depth: Int = 32)
) extends Module { extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val flush = Input(Bool()) val flush = Input(Bool())
val enq = Flipped( val enq = Flipped(Vec(2, new DEBUG()))
Vec( val deq = new DEBUG()
2,
new Bundle {
val wb_pc = Output(UInt(32.W))
val wb_rf_wen = Output(UInt(4.W))
val wb_rf_wnum = Output(UInt(5.W))
val wb_rf_wdata = Output(UInt(32.W))
},
),
)
val deq = new Bundle {
val wb_pc = Output(UInt(32.W))
val wb_rf_wen = Output(UInt(4.W))
val wb_rf_wnum = Output(UInt(5.W))
val wb_rf_wdata = Output(UInt(32.W))
}
}) })
val ram = RegInit(VecInit(Seq.fill(depth)(0.U.asTypeOf(new Bundle { val ram = RegInit(VecInit(Seq.fill(depth)(0.U.asTypeOf(new DEBUG()))))
val wb_pc = UInt(32.W)
val wb_rf_wen = UInt(4.W)
val wb_rf_wnum = UInt(5.W)
val wb_rf_wdata = UInt(32.W)
}))))
val enq_ptr = RegInit(0.U(log2Ceil(depth).W)) val enq_ptr = RegInit(0.U(log2Ceil(depth).W))
val deq_ptr = RegInit(0.U(log2Ceil(depth).W)) val deq_ptr = RegInit(0.U(log2Ceil(depth).W))
val maybe_full = RegInit(false.B) val maybe_full = RegInit(false.B)
@ -51,8 +32,8 @@ class CommitBuffer(
Seq( Seq(
io.flush -> 0.U, io.flush -> 0.U,
(do_enq(0) && do_enq(1)) -> (enq_ptr + 2.U), (do_enq(0) && do_enq(1)) -> (enq_ptr + 2.U),
(do_enq(0) || do_enq(1)) -> (enq_ptr + 1.U), (do_enq(0) || do_enq(1)) -> (enq_ptr + 1.U)
), )
) )
when(do_enq(0)) { when(do_enq(0)) {