fix(icache): 当地址未对齐时不应访存

This commit is contained in:
Liphen 2024-03-09 16:12:56 +08:00
parent 5e7a2eb162
commit f7fb3c4677
7 changed files with 45 additions and 34 deletions

View File

@ -66,13 +66,14 @@ class Core(implicit val cpuConfig: CpuConfig) extends Module {
instFifo.decoderUint <> decodeUnit.instFifo
for (i <- 0 until cpuConfig.instFetchNum) {
instFifo.write(i).pht_index := bpu.instBuffer.pht_index(i)
bpu.instBuffer.pc(i) := instFifo.write(i).pc
instFifo.wen(i) := io.inst.inst_valid(i)
instFifo.write(i).pc := io.inst.addr(0) + (i * 4).U
instFifo.write(i).inst := io.inst.inst(i)
instFifo.write(i).access_fault := io.inst.access_fault
instFifo.write(i).page_fault := io.inst.page_fault
instFifo.write(i).pht_index := bpu.instBuffer.pht_index(i)
bpu.instBuffer.pc(i) := instFifo.write(i).pc
instFifo.wen(i) := io.inst.inst_valid(i)
instFifo.write(i).pc := io.inst.addr(0) + (i * 4).U
instFifo.write(i).inst := io.inst.inst(i)
instFifo.write(i).access_fault := io.inst.access_fault
instFifo.write(i).page_fault := io.inst.page_fault
instFifo.write(i).addr_misaligned := io.inst.addr_misaligned
}
decodeUnit.regfile <> regfile.read

View File

@ -214,26 +214,34 @@ class ICache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
r <> io.axi.r.bits
rready <> io.axi.r.ready
val access_fault = RegInit(false.B)
val page_fault = RegInit(false.B)
// sv39的63-39位需要与第38位相同
val access_fault = RegInit(false.B)
val page_fault = RegInit(false.B)
val addr_misaligned = RegInit(false.B)
// sv39的63-39位不与第38位相同或者地址未对齐时地址错
val addr_err =
io.cpu
.addr(use_next_addr)(XLEN - 1, VADDR_WID)
.asBools
.map(_ =/= io.cpu.addr(use_next_addr)(VADDR_WID - 1))
.reduce(_ || _)
.reduce(_ || _) ||
io.cpu.addr(use_next_addr)(log2Ceil(INST_WID / 8) - 1, 0).orR
io.cpu.access_fault := access_fault //TODO实现cached段中的访存response错误
io.cpu.page_fault := page_fault
io.cpu.access_fault := access_fault //TODO实现cached段中的访存response错误
io.cpu.page_fault := page_fault
io.cpu.addr_misaligned := addr_misaligned
switch(state) {
is(s_idle) {
access_fault := false.B // 在idle时清除access_fault
page_fault := false.B // 在idle时清除page_fault
access_fault := false.B // 在idle时清除access_fault
page_fault := false.B // 在idle时清除page_fault
addr_misaligned := false.B // 在idle时清除addr_misaligned
when(io.cpu.req) {
when(addr_err) {
access_fault := true.B
when(io.cpu.addr(use_next_addr)(log2Ceil(INST_WID / 8) - 1, 0).orR) {
addr_misaligned := true.B
}.otherwise {
access_fault := true.B
}
state := s_wait
rdata_in_wait(0).inst := Instructions.NOP
rdata_in_wait(0).valid := true.B
@ -307,9 +315,10 @@ class ICache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
is(s_wait) {
// 等待流水线的allow_to_go信号防止多次发出读请求
when(io.cpu.complete_single_request) {
access_fault := false.B // 清除access_fault
page_fault := false.B // 清除page_fault
state := s_idle
access_fault := false.B // 清除access_fault
page_fault := false.B // 清除page_fault
addr_misaligned := false.B // 清除addr_misaligned
state := s_idle
(0 until instFetchNum).foreach(i => rdata_in_wait(i).valid := false.B)
}
}

View File

@ -124,11 +124,12 @@ class Cache_ICache(implicit val cpuConfig: CpuConfig) extends Bundle {
val dcache_stall = Output(Bool())
// read inst result
val inst = Input(Vec(cpuConfig.instFetchNum, UInt(XLEN.W)))
val inst_valid = Input(Vec(cpuConfig.instFetchNum, Bool()))
val access_fault = Input(Bool())
val page_fault = Input(Bool())
val icache_stall = Input(Bool()) // icache_stall
val inst = Input(Vec(cpuConfig.instFetchNum, UInt(XLEN.W)))
val inst_valid = Input(Vec(cpuConfig.instFetchNum, Bool()))
val access_fault = Input(Bool())
val page_fault = Input(Bool())
val addr_misaligned = Input(Bool())
val icache_stall = Input(Bool()) // icache_stall
// tlb
val tlb = new Tlb_ICache()

View File

@ -22,7 +22,6 @@ object Priviledged extends HasInstrType with CoreParameter {
EBREAK -> List(InstrI, FuType.csr, CSROpType.jmp),
MRET -> List(InstrI, FuType.csr, CSROpType.jmp),
FENCE -> List(InstrS, FuType.mou, MOUOpType.fence), // nop InstrS -> !wen
WFI -> List(InstrI, FuType.alu, ALUOpType.add) // nop
// FENCE -> List(InstrB, FuType.mou, MOUOpType.fencei)
WFI -> List(InstrI, FuType.alu, ALUOpType.add) // nop rd = x0
) ++ (if (cpuConfig.hasSMode) table_s else Array.empty)
}

View File

@ -129,7 +129,7 @@ class DecodeUnit(implicit val cpuConfig: CpuConfig) extends Module with HasExcep
io.executeStage.inst(i).ex.exception(illegalInstr) := !info(i).inst_legal
io.executeStage.inst(i).ex.exception(instrAccessFault) := io.instFifo.inst(i).access_fault
io.executeStage.inst(i).ex.exception(instrPageFault) := io.instFifo.inst(i).page_fault
io.executeStage.inst(i).ex.exception(instrAddrMisaligned) := pc(i)(log2Ceil(INST_WID / 8) - 1, 0).orR ||
io.executeStage.inst(i).ex.exception(instrAddrMisaligned) := io.instFifo.inst(i).addr_misaligned ||
io.fetchUnit.target(log2Ceil(INST_WID / 8) - 1, 0).orR && io.fetchUnit.branch
io.executeStage.inst(i).ex.exception(breakPoint) := info(i).inst(31, 20) === privEbreak &&
info(i).op === CSROpType.jmp && info(i).fusel === FuType.csr

View File

@ -7,12 +7,13 @@ import cpu.{BranchPredictorConfig, CpuConfig}
import cpu.pipeline.decode.DecodeUnitInstFifo
class IfIdData extends Bundle {
val bpuConfig = new BranchPredictorConfig()
val inst = UInt(XLEN.W)
val pht_index = UInt(bpuConfig.phtDepth.W)
val access_fault = Bool()
val page_fault = Bool()
val pc = UInt(XLEN.W)
val bpuConfig = new BranchPredictorConfig()
val inst = UInt(XLEN.W)
val pht_index = UInt(bpuConfig.phtDepth.W)
val addr_misaligned = Bool()
val access_fault = Bool()
val page_fault = Bool()
val pc = UInt(XLEN.W)
}
class InstFifo(implicit val cpuConfig: CpuConfig) extends Module {

@ -1 +1 @@
Subproject commit bf80bb15c01626d4fe1a6c4085b279d033291279
Subproject commit 1cc25d6abc214775b47d467b8fb16ceed814ffd6