Skip to content

Commit

Permalink
Connect the MMU with PTW
Browse files Browse the repository at this point in the history
  • Loading branch information
Bohan Hu committed Oct 25, 2020
1 parent 0f53ca4 commit 0656b75
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 20 deletions.
8 changes: 7 additions & 1 deletion src/main/scala/core/csrFile.scala
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,13 @@ class CSRFile extends Module {
io.csrMMU.tsr := mstatus.asTypeOf(new mstatus).TSR
io.csrMMU.tvm := mstatus.asTypeOf(new mstatus).TVM
io.csrMMU.satpPPN := satp(43,0)
io.csrMMU.enableLSVM := false.B // TODO!!!

// Apply MPRV Rules
when(mstatus.asTypeOf(new mstatus).MPRV && satp(63, 60) === 8.U && (mstatus.asTypeOf(new mstatus).MPP =/= M)) {
io.csrMMU.enableLSVM := true.B
}.otherwise {
io.csrMMU.enableLSVM := io.csrMMU.enableSv39
}

// To Decoder
io.intCtrl.mie := mie
Expand Down
49 changes: 42 additions & 7 deletions src/main/scala/mmu/mmu.scala
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package mmu
import chisel3._
import _root_.core.MEM2MMU
import _root_.core.CSRMMU
import chisel3.stage.ChiselStage
class MMUIO extends Bundle {
val addrReq = Input(Bool())
val vAddr = Input(UInt(64.W))
val storeReq = Input(Bool())
val enableSv39 = Input(Bool())
val enableLSPaged = Input(Bool())
val mem2mmu = Flipped(new MEM2MMU)
val isStore = Input(Bool())
val flush = Input(Bool())
val dmemreq = new DMEMReq
val csr2mmu = Flipped(new CSRMMU)
}
// LSU send VAddr to MMU, MMU returns the PAddr with valid signal
// LSU then use the translated address to access the memory
Expand All @@ -18,7 +21,39 @@ class MMUIO extends Bundle {

class MMU (isDMMU: Boolean)extends Module {
val io = IO(new MMUIO)
val tlb = Module(new TLB)

// TODO: Add TLB Here
// val tlb = Module(new TLB)
val ptw = Module(new PTW(isDMMU))
// PTW <> MMU
ptw.io.reqReady := io.mem2mmu.reqReady
ptw.io.reqVAddr := io.mem2mmu.reqVAddr
io.mem2mmu.respPAddr := ptw.io.respPaddr
io.mem2mmu.respValid := ptw.io.respValid
io.mem2mmu.respPageFault := ptw.io.pageFault

// Fake TLB(always miss)
ptw.io.tlbQuery.hit := false.B
ptw.io.tlbQuery.paddr := 0.U

// CSR ----> PTW Signals
ptw.io.enableSv39 := io.csr2mmu.enableSv39
ptw.io.translation_ls_en := io.csr2mmu.enableLSVM
ptw.io.satp_PPN := io.csr2mmu.satpPPN
ptw.io.mxr := io.csr2mmu.mxr
ptw.io.satp_ASID := io.csr2mmu.asid

// ptw ctrl
ptw.io.flush := io.flush
if(!isDMMU) {
ptw.io.reqIsStore := io.isStore
} else {
ptw.io.reqIsStore := false.B
}
io.dmemreq <> ptw.io.memReq

}

object MMU extends App {
val stage = new ChiselStage
stage.emitVerilog(new MMU(false))
}
41 changes: 29 additions & 12 deletions src/main/scala/mmu/ptw.scala
Original file line number Diff line number Diff line change
Expand Up @@ -47,38 +47,49 @@ class PTWIO extends Bundle {
val mxr = Input(Bool())
// DMem request
val memReq = new DMEMReq
// TLB Query
val tlbQuery = new TLBQuery
// TLB Update
val tlbUpdate = Flipped(new TLBUpdate)
// TODO: TLB Query
val tlbQuery = Flipped(new TLBQuery)
// TODO: TLB Update
// val tlbUpdate = Flipped(new TLBUpdate)

// TODO: PMP Access Exception
}

class PTW(isDPTW: Boolean) extends Module {
val io = IO(new PTWIO)
val sIDLE :: sWAIT_PTE_Entry :: sHANDLE_PTE_Entry :: sERROR :: sWAIT_AFTER_FLUSH :: Nil = Enum(5)
val pteLevelReg = Reg(UInt(2.W))
val stateReg = Reg(UInt())
val ptrReg = Reg(UInt(64.W))
val pteLevelReg = Reg(UInt(2.W))
val stateReg = Reg(UInt())
val ptrReg = Reg(UInt(64.W))
val isGlobalMappingReg = Reg(Bool())
val pteReg = Reg(UInt(64.W)).asTypeOf(new PTE)
io.respValid := false.B
io.memReq.rreq := false.B
io.pageFault := false.B
io.busy := stateReg =/= sIDLE
val pteReg = Reg(UInt(64.W)).asTypeOf(new PTE)
io.respValid := false.B
io.memReq.rreq := false.B
io.pageFault := false.B
io.busy := stateReg =/= sIDLE
io.tlbQuery.vaddr := io.reqVAddr
io.respPaddr := 0.U
// TODO: Handle SUM
// If TLB hit, stay in IDLE mode
// Also need to consider whether the Sv39 translation is enabled
switch(stateReg) {
is(sIDLE) {
pteLevelReg := 1.U
// Data request has higher priority
if (isDPTW) {
when(!io.enableSv39 | !io.translation_ls_en) {
io.respValid := true.B
io.respPaddr := io.reqVAddr
}
when(io.enableSv39 && io.translation_ls_en && io.reqReady && !io.tlbQuery.hit) {
stateReg := sWAIT_PTE_Entry
ptrReg := Cat(io.satp_PPN, io.reqVAddr(63, 30), 0.U(3.W)) // Root Page Table PPN
}
} else {
when(!io.enableSv39) {
io.respValid := true.B
io.respPaddr := io.reqVAddr
}
when(io.enableSv39 && io.reqReady && !io.tlbQuery.hit) { // Instruction Request
stateReg := sWAIT_PTE_Entry
ptrReg := Cat(io.satp_PPN, io.reqVAddr(63, 30), 0.U(3.W)) // Root Page Table PPN
Expand Down Expand Up @@ -116,6 +127,11 @@ class PTW(isDPTW: Boolean) extends Module {
given the current privilege mode and the value of the SUM and MXR fields of the mstatus register.
If not, stop and raise a page-fault exception corresponding to the original access type.
*/
switch(pteLevelReg) {
is(1.U) { io.respPaddr := Cat(pteReg.ppn2, io.reqVAddr(29,0)) }
is(2.U) { io.respPaddr := Cat(pteReg.ppn2, pteReg.ppn1, io.reqVAddr(20,0)) }
is(3.U) { io.respPaddr := Cat(pteReg.ppn2, pteReg.ppn1, pteReg.ppn0, io.reqVAddr(11,0)) }
}
if (isDPTW) { // isDPTW, check the following conditions
when(pteReg.A && (pteReg.R || (pteReg.X && io.mxr))) {
stateReg := sIDLE
Expand Down Expand Up @@ -175,6 +191,7 @@ class PTW(isDPTW: Boolean) extends Module {
}
}
is(sERROR) {
io.respValid := true.B
io.pageFault := true.B
stateReg := sIDLE
pteLevelReg := 1.U
Expand Down

0 comments on commit 0656b75

Please sign in to comment.