Skip to content

Commit

Permalink
Add tlb
Browse files Browse the repository at this point in the history
  • Loading branch information
Bohan Hu committed Nov 13, 2020
1 parent 150e638 commit 85bc202
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 7 deletions.
9 changes: 5 additions & 4 deletions src/main/scala/mmu/mmu.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class MMUIO extends Bundle {
class MMU (isDMMU: Boolean) extends Module {
val io = IO(new MMUIO)
// TODO: Add TLB Here
// val tlb = Module(new TLB)
val tlb = Module(new TLB)
val ptw = Module(new PTW(isDMMU))
// PTW <> MMU
ptw.io.reqReady := io.mem2mmu.reqReady
Expand All @@ -32,9 +32,10 @@ class MMU (isDMMU: Boolean) extends Module {
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
// TLB
ptw.io.tlbQuery <> tlb.io.tlbQuery
ptw.io.tlbUpdate <> tlb.io.tlbUpdate
ptw.io.flush := io.flush

// CSR ----> PTW Signals
ptw.io.enableSv39 := io.csr2mmu.enableSv39
Expand Down
15 changes: 14 additions & 1 deletion src/main/scala/mmu/ptw.scala
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,18 @@ class PTW(isDPTW: Boolean) extends Module {
io.memReq.memRreq := false.B
io.pageFault := false.B
io.busy := stateReg =/= sIDLE
io.tlbQuery.vaddr := io.reqVAddr
io.respPaddr := 0.U
io.memReq.memWdata := 0.U
io.memReq.memWen := 0.U
io.memReq.memWmask := 0.U
io.memReq.memAddr := ptrReg
// TLB Update
io.tlbUpdate.pte := pteConverted
io.tlbUpdate.vpn := io.reqVAddr
io.tlbUpdate.is1G := false.B
io.tlbUpdate.is2M := false.B
io.tlbUpdate.is4K := false.B

// TODO: Handle SUM
// If TLB hit, stay in IDLE mode
// Also need to consider whether the Sv39 translation is enabled
Expand Down Expand Up @@ -141,11 +147,17 @@ class PTW(isDPTW: Boolean) extends Module {
is(2.U) { io.respPaddr := Cat(pteConverted.ppn2, pteConverted.ppn1, io.reqVAddr(20,0))}
is(3.U) { io.respPaddr := Cat(pteConverted.ppn2, pteConverted.ppn1, pteConverted.ppn0, io.reqVAddr(11,0))}
}
switch(pteLevelReg) {
is(1.U) { io.tlbUpdate.is1G := true.B }
is(2.U) { io.tlbUpdate.is2M := true.B }
is(3.U) { io.tlbUpdate.is4K := true.B }
}
if (isDPTW) { // isDPTW, check the following conditions
// TODO: when(pteConverted.A && (pteConverted.R || (pteConverted.X && io.mxr))) {
when((pteConverted.R || (pteConverted.X && io.mxr))) {
stateReg := sIDLE
io.respValid := true.B
io.tlbUpdate.valid := true.B
pteLevelReg := 1.U
}.otherwise {
stateReg := sERROR
Expand All @@ -170,6 +182,7 @@ class PTW(isDPTW: Boolean) extends Module {
stateReg := sERROR
}.otherwise {
io.respValid := true.B
io.tlbUpdate.valid := true.B
stateReg := sIDLE
pteLevelReg := 1.U
}
Expand Down
61 changes: 59 additions & 2 deletions src/main/scala/mmu/tlb.scala
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
package mmu
import chisel3._
import chisel3.util.Counter
class TLBEntry extends Bundle {
val valid = Bool()
val vpn = UInt(27.W)
val asid = UInt(16.W) // From SATP
val pte = new PTE
val is4K = Bool()
val is2M = Bool()
val is1G = Bool()
}

class TLBUpdate extends Bundle {
val enable = Input(Bool())
val addr = Input(UInt(64.W))
val entry = Input(new TLBEntry)
}

class TLBQuery extends Bundle {
val hit = Output(Bool())
val vaddr = Input(UInt(64.W))
Expand All @@ -21,6 +25,59 @@ class TLB extends Module{
val io = IO(new Bundle() {
val tlbUpdate = new TLBUpdate
val tlbQuery = new TLBQuery
val flush = Input(Bool())
})

val vpn0In = io.tlbQuery.vaddr(20,12)
val vpn1In = io.tlbQuery.vaddr(29,21)
val vpn2In = io.tlbQuery.vaddr(38,30)

val cnt = RegInit(0.U)
when(cnt < 8.U) {
cnt := cnt + 1.U
when(cnt === 7.U) {
cnt := 0.U
}
}
val tlbUpdate = WireInit(io.tlbUpdate.entry)

val tlbRegs = Mem(8, new TLBEntry)
when(io.tlbUpdate.enable) {
tlbRegs(cnt) := tlbUpdate
tlbRegs(cnt).valid := true.B
}
io.tlbQuery.hit := false.B
io.paddr := 0.U
for( i <- 0 to 8 ) {
val tlbEntry = tlbRegs(i)
val tlbEntryTag = tlbEntry.vpn
val vpn0_hit = (vpn0In === tlbEntryTag(20,12))
val vpn1_hit = (vpn1In === tlbEntryTag(29,21))
val vpn2_hit = (vpn2In === tlbEntryTag(38,30))
when(vpn2_hit && tlbEntry.valid) {
when(tlbEntry.is1G) {
// 1G Page
io.tlbQuery.hit := true.B
io.paddr := Cat(tlbEntry.pte.ppn2, io.reqVAddr(29,0)))
}.elsewhen(vpn1_hit) {
when(tlbEntry.is2M) {
// 2M Page
io.tlbQuery.hit := true.B
io.paddr := Cat(tlbEntry.pte.ppn2, tlbEntry.pte.ppn1, io.reqVAddr(20,0))
}.elsewhen(vpn0_hit) {
// 4K Page
io.tlbQuery.hit := true.B
io.paddr := Cat(tlbEntry.pte.ppn2, tlbEntry.pte.ppn1, tlbEntry.pte.ppn0, io.reqVAddr(11,0))
}
}
}
when(io.flush) {
tlbRegs(i).valid := false.B
}
}
}

object tlb extends App {
val stage = new ChiselStage
stage.emitVerilog(new tlb)
}

0 comments on commit 85bc202

Please sign in to comment.