修改cache代码
This commit is contained in:
parent
8913ae5da0
commit
e266678e90
|
@ -9,20 +9,122 @@ import cpu.defines._
|
|||
import cpu.CpuConfig
|
||||
import cpu.defines.Const._
|
||||
|
||||
class WriteBufferUnit extends Bundle {
|
||||
val data = UInt(DATA_WID.W)
|
||||
val addr = UInt(DATA_ADDR_WID.W)
|
||||
val strb = UInt(4.W)
|
||||
val size = UInt(2.W)
|
||||
}
|
||||
|
||||
class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val cpu = Flipped(new Cache_DCache())
|
||||
val axi = new DCache_AXIInterface()
|
||||
val cpu = Flipped(new Cache_DCache())
|
||||
val axi = new DCache_AXIInterface()
|
||||
})
|
||||
|
||||
// * fsm * //
|
||||
val s_idle :: s_read :: s_write :: s_finishwait :: Nil = Enum(4)
|
||||
val state = RegInit(s_idle)
|
||||
val status = RegInit(s_idle)
|
||||
|
||||
val wstrb_gen = Wire(UInt(8.W))
|
||||
wstrb_gen := MuxLookup(io.cpu.size, "b1111_1111".U)(
|
||||
Seq(
|
||||
0.U -> ("b1".U << io.cpu.addr(2, 0)),
|
||||
1.U -> ("b11".U << Cat(io.cpu.addr(2, 1), 0.U(1.W))),
|
||||
2.U -> ("b1111".U << Cat(io.cpu.addr(2), 0.U(2.W))),
|
||||
3.U -> ("b1111_1111".U)
|
||||
)
|
||||
)
|
||||
|
||||
io.cpu.valid := status === s_finishwait
|
||||
|
||||
val addr_err = io.cpu.addr(63, 32).orR
|
||||
|
||||
// default
|
||||
io.axi.aw.addr := 0.U
|
||||
io.axi.aw.len := 0.U
|
||||
io.axi.aw.size := 0.U
|
||||
io.axi.aw.burst := BURST_FIXED.U
|
||||
io.axi.aw.valid := 0.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.addr := 0.U
|
||||
io.axi.ar.len := 0.U
|
||||
io.axi.ar.size := 0.U
|
||||
io.axi.ar.burst := BURST_FIXED.U
|
||||
io.axi.ar.valid := 0.U
|
||||
io.axi.r.ready := 1.U
|
||||
io.cpu.rdata := 0.U
|
||||
|
||||
switch(status) {
|
||||
is(s_idle) {
|
||||
when(io.cpu.en) {
|
||||
when(addr_err) {
|
||||
io.cpu.acc_err := true.B
|
||||
status := s_finishwait
|
||||
}.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_write
|
||||
}.otherwise {
|
||||
io.axi.ar.addr := io.cpu.addr(31, 0)
|
||||
io.axi.ar.size := Cat(false.B, io.cpu.size)
|
||||
io.axi.ar.valid := true.B
|
||||
status := s_read
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is(s_read) {
|
||||
when(io.axi.ar.ready) {
|
||||
io.axi.ar.valid := false.B
|
||||
}
|
||||
when(io.axi.r.valid) {
|
||||
io.cpu.rdata := io.axi.r.data
|
||||
io.cpu.acc_err := io.axi.r.resp =/= RESP_OKEY.U
|
||||
status := s_finishwait
|
||||
}
|
||||
}
|
||||
is(s_write) {
|
||||
when(io.axi.aw.ready) {
|
||||
io.axi.aw.valid := false.B
|
||||
}
|
||||
when(io.axi.w.ready) {
|
||||
io.axi.w.valid := false.B
|
||||
}
|
||||
when(io.axi.b.valid) {
|
||||
io.cpu.acc_err := io.axi.b.resp =/= RESP_OKEY.U
|
||||
status := s_finishwait
|
||||
}
|
||||
}
|
||||
is(s_finishwait) {
|
||||
when(io.cpu.ready) {
|
||||
io.cpu.acc_err := false.B
|
||||
when(io.cpu.en) {
|
||||
when(addr_err) {
|
||||
io.cpu.acc_err := true.B
|
||||
status := s_finishwait
|
||||
}.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_write
|
||||
}.otherwise {
|
||||
io.axi.ar.addr := io.cpu.addr(31, 0)
|
||||
io.axi.ar.size := Cat(false.B, io.cpu.size)
|
||||
io.axi.ar.valid := true.B
|
||||
status := s_read
|
||||
}
|
||||
}
|
||||
}.otherwise {
|
||||
status := s_idle
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ class ICache(implicit config: CpuConfig) extends Module {
|
|||
io.cpu.valid := status === s_finishwait
|
||||
val addr_err = io.cpu.addr.orR
|
||||
|
||||
// default
|
||||
io.axi.ar.addr := 0.U
|
||||
io.axi.ar.len := 0.U
|
||||
io.axi.ar.size := 2.U
|
||||
|
@ -32,12 +33,14 @@ class ICache(implicit config: CpuConfig) extends Module {
|
|||
switch(status) {
|
||||
is(s_idle) {
|
||||
when(io.cpu.en) {
|
||||
io.cpu.acc_err := true.B
|
||||
status := s_finishwait
|
||||
}.otherwise {
|
||||
io.axi.ar.addr := Cat(io.cpu.addr(31, 2), 0.U(2.W))
|
||||
io.axi.ar.valid := true.B
|
||||
status := s_read
|
||||
when(addr_err) {
|
||||
io.cpu.acc_err := true.B
|
||||
status := s_finishwait
|
||||
}.otherwise {
|
||||
io.axi.ar.addr := Cat(io.cpu.addr(31, 2), 0.U(2.W))
|
||||
io.axi.ar.valid := true.B
|
||||
status := s_read
|
||||
}
|
||||
}
|
||||
}
|
||||
is(s_read) {
|
||||
|
|
|
@ -116,10 +116,10 @@ class WriteBackCtrl extends Bundle {
|
|||
// cpu to icache
|
||||
class Cache_ICache(implicit val config: CpuConfig) extends Bundle {
|
||||
// read inst request from cpu
|
||||
val en = Output(Bool())
|
||||
val ready = Output(Bool())
|
||||
val addr = Output(UInt(INST_ADDR_WID.W)) // virtual address and next virtual address
|
||||
val fence = Output(Bool())
|
||||
val en = Output(Bool())
|
||||
val ready = Output(Bool())
|
||||
val addr = Output(UInt(INST_ADDR_WID.W)) // virtual address and next virtual address
|
||||
val fence_i = Output(Bool())
|
||||
|
||||
// read inst result
|
||||
val rdata = Input(UInt(INST_WID.W))
|
||||
|
@ -129,20 +129,17 @@ class Cache_ICache(implicit val config: CpuConfig) extends Bundle {
|
|||
|
||||
// cpu to dcache
|
||||
class Cache_DCache extends Bundle {
|
||||
val cpu_stall = Output(Bool())
|
||||
val dcache_stall = Input(Bool())
|
||||
val addr = Output(UInt(DATA_ADDR_WID.W))
|
||||
val size = Output(UInt(2.W))
|
||||
val en = Output(Bool())
|
||||
val write = Output(Bool())
|
||||
val wdata = Output(UInt(DATA_WID.W))
|
||||
val ready = Output(Bool())
|
||||
val fence_i = Output(Bool())
|
||||
|
||||
val execute_addr = Output(UInt(32.W))
|
||||
// 连接 mem unit
|
||||
val rdata = Input(UInt(32.W))
|
||||
val en = Output(Bool())
|
||||
val wen = Output(UInt(4.W))
|
||||
val rlen = Output(UInt(2.W))
|
||||
val wdata = Output(UInt(32.W))
|
||||
val addr = Output(UInt(32.W))
|
||||
|
||||
val fence = Output(Bool())
|
||||
val fence_addr = Output(UInt(32.W))
|
||||
val rdata = Input(UInt(DATA_WID.W))
|
||||
val valid = Input(Bool())
|
||||
val acc_err = Input(Bool())
|
||||
}
|
||||
|
||||
// axi
|
||||
|
@ -210,11 +207,11 @@ class ICache_AXIInterface extends Bundle {
|
|||
}
|
||||
|
||||
class DCache_AXIInterface extends ICache_AXIInterface {
|
||||
val aw = Decoupled(new AW())
|
||||
|
||||
val w = Decoupled(new W())
|
||||
|
||||
val b = Flipped(Decoupled())
|
||||
val aw = new AW()
|
||||
val w = new W()
|
||||
val b = new B()
|
||||
val ar = new AR()
|
||||
val r = new R()
|
||||
}
|
||||
|
||||
class Cache_AXIInterface extends Bundle {
|
||||
|
|
|
@ -146,13 +146,12 @@ trait Constants {
|
|||
val INST_ADDR_WID = PC_WID
|
||||
|
||||
// data ram
|
||||
val DATA_ADDR_WID = 32
|
||||
val DATA_ADDR_WID = PC_WID
|
||||
|
||||
// GPR RegFile
|
||||
val AREG_NUM = 32
|
||||
val REG_ADDR_WID = 5
|
||||
val DATA_WID = 32
|
||||
val HILO_WID = 64
|
||||
val DATA_WID = 64
|
||||
|
||||
// CP0寄存器
|
||||
// CP0 Register (5.w), Select (3.w)
|
||||
|
|
Loading…
Reference in New Issue