feat: 增加TLB,通过si-p测试
This commit is contained in:
parent
404e0d64e6
commit
4e300502db
|
@ -1 +1 @@
|
||||||
Subproject commit e89bb7ff9246a977b7e7ded2b611739e1246d33d
|
Subproject commit ef0f84099590846759803b50a8fa0cf256470361
|
|
@ -79,8 +79,8 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
|
||||||
val state = RegInit(s_idle)
|
val state = RegInit(s_idle)
|
||||||
|
|
||||||
// ptw的状态机
|
// ptw的状态机
|
||||||
val pte_handshake :: pte_send :: ptw_uncached :: ptw_cached :: pte_check :: pte_set :: Nil = Enum(6)
|
val ptw_handshake :: ptw_send :: ptw_cached :: ptw_uncached :: ptw_check :: ptw_set :: Nil = Enum(6)
|
||||||
val ptw_state = RegInit(pte_handshake)
|
val ptw_state = RegInit(ptw_handshake)
|
||||||
|
|
||||||
// 临时寄存器
|
// 临时寄存器
|
||||||
val ptw_scratch = RegInit(0.U.asTypeOf(new Bundle {
|
val ptw_scratch = RegInit(0.U.asTypeOf(new Bundle {
|
||||||
|
@ -103,6 +103,11 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
|
||||||
val offset = UInt(offsetWidth.W)
|
val offset = UInt(offsetWidth.W)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def bankAddr = new Bundle {
|
||||||
|
val index = UInt(bankIndexWidth.W)
|
||||||
|
val offset = UInt(bankOffsetWidth.W)
|
||||||
|
}
|
||||||
|
|
||||||
// exe级的index,用于访问第i行的数据
|
// exe级的index,用于访问第i行的数据
|
||||||
val exe_index = io.cpu.exe_addr(indexWidth + offsetWidth - 1, offsetWidth)
|
val exe_index = io.cpu.exe_addr(indexWidth + offsetWidth - 1, offsetWidth)
|
||||||
// mem级的bank的index,用于访问第i个bank的数据
|
// mem级的bank的index,用于访问第i个bank的数据
|
||||||
|
@ -361,7 +366,7 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.otherwise {
|
}.otherwise {
|
||||||
io.cpu.tlb.ptw.vpn.ready := ptw_state === pte_handshake
|
io.cpu.tlb.ptw.vpn.ready := ptw_state === ptw_handshake
|
||||||
when(io.cpu.fence_i) {
|
when(io.cpu.fence_i) {
|
||||||
// fence.i 需要将所有脏位为true的行写回
|
// fence.i 需要将所有脏位为true的行写回
|
||||||
when(dirty.asUInt.orR) {
|
when(dirty.asUInt.orR) {
|
||||||
|
@ -477,9 +482,10 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
|
||||||
) {
|
) {
|
||||||
valid(replace_index)(replace_way) := true.B
|
valid(replace_index)(replace_way) := true.B
|
||||||
do_replace := false.B
|
do_replace := false.B
|
||||||
when(ptw_scratch.working) {
|
ptw_scratch.replace := false.B
|
||||||
state := s_tlb_refill
|
when(ptw_scratch.working && io.cpu.tlb.ptw.access_type =/= AccessType.fetch) {
|
||||||
ptw_scratch.replace := false.B
|
// ptw复用的模式
|
||||||
|
state := s_tlb_refill
|
||||||
}.otherwise {
|
}.otherwise {
|
||||||
state := s_idle
|
state := s_idle
|
||||||
}
|
}
|
||||||
|
@ -525,7 +531,7 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is(s_tlb_refill) {
|
is(s_tlb_refill) {
|
||||||
io.cpu.tlb.ptw.vpn.ready := ptw_state === pte_handshake
|
io.cpu.tlb.ptw.vpn.ready := ptw_state === ptw_handshake
|
||||||
when(io.cpu.tlb.access_fault) {
|
when(io.cpu.tlb.access_fault) {
|
||||||
access_fault := true.B
|
access_fault := true.B
|
||||||
state := s_wait
|
state := s_wait
|
||||||
|
@ -563,7 +569,7 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
|
||||||
def raisePageFault(): Unit = {
|
def raisePageFault(): Unit = {
|
||||||
io.cpu.tlb.ptw.pte.valid := true.B
|
io.cpu.tlb.ptw.pte.valid := true.B
|
||||||
io.cpu.tlb.ptw.pte.bits.page_fault := true.B
|
io.cpu.tlb.ptw.pte.bits.page_fault := true.B
|
||||||
ptw_state := pte_handshake
|
ptw_state := ptw_handshake
|
||||||
}
|
}
|
||||||
|
|
||||||
def modeCheck(): Unit = {
|
def modeCheck(): Unit = {
|
||||||
|
@ -572,30 +578,30 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
|
||||||
when(pte.flag.u && !sum) {
|
when(pte.flag.u && !sum) {
|
||||||
raisePageFault()
|
raisePageFault()
|
||||||
}.otherwise {
|
}.otherwise {
|
||||||
ptw_state := pte_set
|
ptw_state := ptw_set
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is(ModeU) {
|
is(ModeU) {
|
||||||
when(!pte.flag.u) {
|
when(!pte.flag.u) {
|
||||||
raisePageFault()
|
raisePageFault()
|
||||||
}.otherwise {
|
}.otherwise {
|
||||||
ptw_state := pte_set
|
ptw_state := ptw_set
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(ptw_state) {
|
switch(ptw_state) {
|
||||||
is(pte_handshake) {
|
is(ptw_handshake) {
|
||||||
// 页表访问虚地址握手
|
// 页表访问虚地址握手
|
||||||
when(io.cpu.tlb.ptw.vpn.valid) {
|
when(io.cpu.tlb.ptw.vpn.valid) {
|
||||||
vpn_index := (level - 1).U
|
vpn_index := (level - 1).U
|
||||||
ppn := satp.ppn
|
ppn := satp.ppn
|
||||||
ptw_state := pte_send
|
ptw_state := ptw_send
|
||||||
ptw_scratch.working := true.B
|
ptw_scratch.working := true.B
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is(pte_send) {
|
is(ptw_send) {
|
||||||
val vpnn = Mux1H(
|
val vpnn = Mux1H(
|
||||||
Seq(
|
Seq(
|
||||||
(vpn_index === 0.U) -> vpn.vpn0,
|
(vpn_index === 0.U) -> vpn.vpn0,
|
||||||
|
@ -621,33 +627,35 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is(ptw_cached) {
|
is(ptw_cached) {
|
||||||
|
bank_raddr := ptw_scratch.paddr.index
|
||||||
|
tagRam.map(_.io.raddr := ptw_scratch.paddr.index)
|
||||||
for { i <- 0 until nway } {
|
for { i <- 0 until nway } {
|
||||||
tag_compare_valid(i) :=
|
tag_compare_valid(i) :=
|
||||||
tag(i) === ptw_scratch.paddr.tag && // tag相同
|
tag(i) === ptw_scratch.paddr.tag && // tag相同
|
||||||
valid(ptw_scratch.paddr.index)(i) // cache行有效位为真
|
valid(ptw_scratch.paddr.index)(i) // cache行有效位为真
|
||||||
}
|
}
|
||||||
when(cache_hit) {
|
when(!ptw_scratch.replace) {
|
||||||
val pte_temp = data(ptw_scratch.paddr.index)(select_way).asTypeOf(pteBundle)
|
when(cache_hit) {
|
||||||
when(!pte_temp.flag.v || !pte_temp.flag.r && pte_temp.flag.w) {
|
val pte_temp = data(ptw_scratch.paddr.offset.asTypeOf(bankAddr).index)(select_way).asTypeOf(pteBundle)
|
||||||
raisePageFault()
|
when(!pte_temp.flag.v || !pte_temp.flag.r && pte_temp.flag.w) {
|
||||||
}.otherwise {
|
raisePageFault()
|
||||||
when(pte_temp.flag.r || pte_temp.flag.x) {
|
|
||||||
// 找到了叶子页
|
|
||||||
pte := pte_temp
|
|
||||||
ptw_state := pte_check
|
|
||||||
}.otherwise {
|
}.otherwise {
|
||||||
// 该pte指向下一个页表
|
when(pte_temp.flag.r || pte_temp.flag.x) {
|
||||||
vpn_index := vpn_index - 1.U
|
// 找到了叶子页
|
||||||
when(vpn_index - 1.U < 0.U) {
|
pte := pte_temp
|
||||||
raisePageFault()
|
ptw_state := ptw_check
|
||||||
}.otherwise {
|
}.otherwise {
|
||||||
ppn := pte_temp.ppn
|
// 该pte指向下一个页表
|
||||||
ptw_state := pte_send
|
vpn_index := vpn_index - 1.U
|
||||||
|
when(vpn_index - 1.U < 0.U) {
|
||||||
|
raisePageFault()
|
||||||
|
}.otherwise {
|
||||||
|
ppn := pte_temp.ppn
|
||||||
|
ptw_state := ptw_send
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}.otherwise {
|
||||||
}.otherwise {
|
|
||||||
when(!ptw_scratch.replace) {
|
|
||||||
ptw_scratch.replace := true.B
|
ptw_scratch.replace := true.B
|
||||||
state := s_replace // 直接复用dcache的replace状态机,帮我们进行replace操作
|
state := s_replace // 直接复用dcache的replace状态机,帮我们进行replace操作
|
||||||
bank_windex := 0.U
|
bank_windex := 0.U
|
||||||
|
@ -657,7 +665,6 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
|
||||||
(0 until nbank).map(i => bank_replication(i) := data(i)(select_way))
|
(0 until nbank).map(i => bank_replication(i) := data(i)(select_way))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 进入replace状态机后,会在此处等待,直到cache hit
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is(ptw_uncached) {
|
is(ptw_uncached) {
|
||||||
|
@ -673,7 +680,7 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
|
||||||
when(pte_temp.flag.r || pte_temp.flag.x) {
|
when(pte_temp.flag.r || pte_temp.flag.x) {
|
||||||
// 找到了叶子页
|
// 找到了叶子页
|
||||||
pte := pte_temp
|
pte := pte_temp
|
||||||
ptw_state := pte_check
|
ptw_state := ptw_check
|
||||||
}.otherwise {
|
}.otherwise {
|
||||||
// 该pte指向下一个页表
|
// 该pte指向下一个页表
|
||||||
vpn_index := vpn_index - 1.U
|
vpn_index := vpn_index - 1.U
|
||||||
|
@ -681,13 +688,13 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
|
||||||
raisePageFault()
|
raisePageFault()
|
||||||
}.otherwise {
|
}.otherwise {
|
||||||
ppn := pte_temp.ppn
|
ppn := pte_temp.ppn
|
||||||
ptw_state := pte_send
|
ptw_state := ptw_send
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is(pte_check) {
|
is(ptw_check) {
|
||||||
// 检查权限
|
// 检查权限
|
||||||
switch(access_type) {
|
switch(access_type) {
|
||||||
is(AccessType.load) {
|
is(AccessType.load) {
|
||||||
|
@ -721,7 +728,7 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is(pte_set) {
|
is(ptw_set) {
|
||||||
when(
|
when(
|
||||||
vpn_index > 0.U && (
|
vpn_index > 0.U && (
|
||||||
vpn_index === 1.U && pte.ppn(0) ||
|
vpn_index === 1.U && pte.ppn(0) ||
|
||||||
|
@ -750,7 +757,7 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
|
||||||
}
|
}
|
||||||
io.cpu.tlb.ptw.pte.bits.entry.ppn := ppn_set.asUInt
|
io.cpu.tlb.ptw.pte.bits.entry.ppn := ppn_set.asUInt
|
||||||
|
|
||||||
ptw_state := pte_handshake
|
ptw_state := ptw_handshake
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,6 +229,7 @@ class Tlb extends Module with HasTlbConst with HasCSRConst {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is(search_pte) {
|
is(search_pte) {
|
||||||
|
req_ptw(0) := true.B
|
||||||
io.dcache.ptw.vpn.valid := true.B
|
io.dcache.ptw.vpn.valid := true.B
|
||||||
when(io.dcache.ptw.pte.valid) {
|
when(io.dcache.ptw.pte.valid) {
|
||||||
when(io.dcache.ptw.pte.bits.access_fault) {
|
when(io.dcache.ptw.pte.bits.access_fault) {
|
||||||
|
@ -330,6 +331,7 @@ class Tlb extends Module with HasTlbConst with HasCSRConst {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is(search_pte) {
|
is(search_pte) {
|
||||||
|
req_ptw(1) := true.B
|
||||||
io.dcache.ptw.vpn.valid := true.B
|
io.dcache.ptw.vpn.valid := true.B
|
||||||
when(io.dcache.ptw.pte.valid) {
|
when(io.dcache.ptw.pte.valid) {
|
||||||
when(io.dcache.ptw.pte.bits.access_fault) {
|
when(io.dcache.ptw.pte.bits.access_fault) {
|
||||||
|
|
|
@ -126,7 +126,7 @@ class Csr(implicit val cpuConfig: CpuConfig) extends Module with HasCSRConst {
|
||||||
// Supervisor Trap Setup
|
// Supervisor Trap Setup
|
||||||
// sstatus 状态寄存器,源自mstatus
|
// sstatus 状态寄存器,源自mstatus
|
||||||
val sstatusWmask = "h00000000000c0122".U(XLEN.W)
|
val sstatusWmask = "h00000000000c0122".U(XLEN.W)
|
||||||
val sstatusRmask = "h80000000000de762".U(XLEN.W)
|
val sstatusRmask = "h80000003000de762".U(XLEN.W)
|
||||||
// sedeleg 异常代理寄存器,未实现
|
// sedeleg 异常代理寄存器,未实现
|
||||||
// sideleg 中断代理寄存器,未实现
|
// sideleg 中断代理寄存器,未实现
|
||||||
// sie 中断使能寄存器,源自mie
|
// sie 中断使能寄存器,源自mie
|
||||||
|
|
Loading…
Reference in New Issue