Skip to content

Commit

Permalink
Passed P tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Bohan Hu committed Oct 29, 2020
1 parent cb06a9c commit df41bc2
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 42 deletions.
33 changes: 28 additions & 5 deletions src/main/scala/common/ram.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,34 @@ class SyncReadOnlyMem extends Module {
})
val ram = Module(new RAMHelper)
ram.io.clk := io.clk
io.data_valid := RegNext(!io.reset)
val raddr = RegInit(0.U)
raddr := Mux(io.pause, raddr, io.raddr)
ram.io.rIdx := Mux(io.pause, raddr(63,3), io.raddr(63, 3))
io.rdata := Mux(raddr(2), ram.io.rdata(63, 32), ram.io.rdata(31, 0))
// io.data_valid := RegNext(RegNext(RegNext(!io.reset & io.rreq)))
val sIDLE :: sHOLD :: sVALID :: Nil = Enum(3)
val state = RegInit(sIDLE)
val addrReg = RegInit(0.U)
val cnt = Reg(UInt(5.W))
io.rdata := 0.U
io.data_valid := false.B
switch(state) {
is(sIDLE) {
when(io.rreq) {
addrReg := io.raddr
state := sHOLD
}
}
is(sHOLD) {
cnt := cnt + 1.U
when(cnt === 5.U) {
state := sVALID
cnt := 0.U
}
}
is(sVALID) {
io.data_valid := true.B
io.rdata := Mux(addrReg(2), ram.io.rdata(63, 32), ram.io.rdata(31, 0))
state := sIDLE
}
}
ram.io.rIdx := addrReg(63,3)
ram.io.wIdx := 0.U
ram.io.wdata := 0.U
ram.io.wmask := 0.U
Expand Down
5 changes: 3 additions & 2 deletions src/main/scala/core/csrFile.scala
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ class CSRMMU extends Bundle {

class commitCSR extends Bundle {
val instValid = Input(Bool())
val inst = Input(UInt(32.W))
val csrWData = Input(UInt(64.W))
val csrAddr = Input(UInt(12.W))
val csrOp = Input(UInt(3.W))
Expand Down Expand Up @@ -575,8 +576,8 @@ class CSRFile extends Module {
// ================== Exception Handler Ends ===================

// TODO: Consider MPRV Bit
val isMret = io.commitCSR.csrOp === CSR_I && privMode === M
val isSret = io.commitCSR.csrOp === CSR_I && privMode === S
val isMret = io.commitCSR.inst === "b00110000001000000000000001110011".U
val isSret = io.commitCSR.inst === "b00010000001000000000000001110011".U
val isEret = isMret | isSret
// ================== ERET Handler Begins ===================
/*
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/core/exu.scala
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ class EXU extends Module {
io.mem2dmem.memWdata := mem.io.mem2dmem.memWdata
io.mem2dmem.memWen := mem.io.mem2dmem.memWen
io.mem2dmem.memWmask := mem.io.mem2dmem.memWmask
io.mem2dmem.memAddr := Mux(dmmu.io.dmemreq.memRreq, mem.io.mem2dmem.memAddr, mem.io.mem2dmem.memAddr)
io.mem2dmem.memAddr := Mux(dmmu.io.dmemreq.memRreq, dmmu.io.dmemreq.memAddr, mem.io.mem2dmem.memAddr)
dmmu.io.dmemreq.memRvalid := io.mem2dmem.memRvalid
dmmu.io.dmemreq.memWrDone := false.B
dmmu.io.dmemreq.memRdata := io.mem2dmem.memRdata
Expand Down
136 changes: 110 additions & 26 deletions src/main/scala/core/ifu.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package core

import chisel3._
import chisel3.stage.ChiselStage
import chisel3.util._

class InstBundle extends Bundle {
val inst_pc = UInt(64.W)
Expand All @@ -16,50 +17,133 @@ class InstBundle extends Bundle {

// In AXI interface, we leave 2 ports, 1 for inst req, 1 for mem req
class IFUIO extends Bundle {
val inst_pc = Output(UInt(64.W))
val inst_req = Output(Bool())
val rdata = Input(UInt(32.W))
val rvalid = Input(Bool())
val inst_out = Output(new InstBundle)
// val branchInfo = Flipped(new(BranchCtrlIO))
// val excInfo = Flipped(new (exceptionRedir))
val stallReq = Output(Bool())
val branchRedir = Input(new BranchRedir)
val exceptionRedir = Input(new ExceptionRedir)
val pause = Input(Bool())
val exceInfo = Output(new ExceptionInfo)
val ifu2mmu = new MEM2MMU
val ifu2dmem = new MEM2dmem
val exceInfoOut = Output(new ExceptionInfo)
}

/* TODOs:
1. Integrate 2 dmem into 1, and apply delay model on it(fixed delay with 5 cycs)
2. the dmem bridge provides 2 ports, one for inst, the other for data
3. I/D Cache combined as one, use unified ports
*/
class IFU extends Module {
val io = IO(new IFUIO)

val pc = RegInit(0x80000000L.U(64.W))
io.inst_pc := pc
io.inst_req := true.B
val sIDLE :: sWAIT_PADDR :: sWAIT_INST :: sPENDING :: sERROR :: Nil = Enum(5)
val state = RegInit(sIDLE)
val pendingRedirect = RegInit(false.B)
val pendingRedirectAddr = RegInit(0.U(64.W))
val pc = RegInit(0x80000000L.U(64.W)-4.U)
val thisInstValid = WireInit(false.B)
val thisPC = WireInit(0.U)
val thisInst = WireInit(0.U)
thisInst := io.ifu2dmem.memRdata
thisPC := pc
val thisExce = Wire(new ExceptionInfo)

val savedPC = Reg(UInt(64.W))
val savedInst = Reg(UInt(32.W))
val pendingExce = Reg(Bool())
val npc = Wire(UInt(64.W))
when(io.rvalid & !io.pause) {
pc := npc
val paddrPCReg = RegInit(0.U(64.W))

thisExce.cause := ExceptionNo.instrPageFault.U
thisExce.tval := thisInst
thisExce.epc := pc
thisExce.valid := false.B
io.ifu2dmem.memAddr := paddrPCReg
io.ifu2dmem.memWen := false.B
io.ifu2dmem.memWdata := 0.U
io.ifu2dmem.memWmask := 0.U
io.ifu2dmem.memRreq := false.B
io.ifu2mmu.reqVAddr := pc
io.ifu2mmu.reqReady := false.B

switch(state) {
is(sIDLE) {
pc := Mux(pendingRedirect, pendingRedirectAddr, npc)
pendingRedirect := false.B
io.ifu2mmu.reqReady := true.B
io.ifu2mmu.reqVAddr := Mux(pendingRedirect, pendingRedirectAddr, npc)
state := sWAIT_PADDR
pendingExce := false.B
}
is(sWAIT_PADDR) {
io.ifu2mmu.reqReady := true.B
io.ifu2mmu.reqVAddr := pc
when( io.ifu2mmu.respValid & !io.ifu2mmu.respPageFault ) {
paddrPCReg := io.ifu2mmu.respPAddr
state := sWAIT_INST
}.elsewhen( io.ifu2mmu.respValid && io.ifu2mmu.respPageFault ) {
when(io.pause) {
state := sPENDING
pendingExce := true.B
savedPC := pc
}.otherwise {
thisExce.valid := true.B
io.inst_out.instValid := ~pendingRedirect
state := sIDLE
}
}
when(io.exceptionRedir.redir) {
pendingRedirect := true.B
pendingRedirectAddr := io.exceptionRedir.redirPC
}.elsewhen(io.branchRedir.redir) {
pendingRedirect := true.B
pendingRedirectAddr := io.branchRedir.TargetPC
}
}
is(sWAIT_INST) {
io.ifu2dmem.memRreq := true.B
when(io.ifu2dmem.memRvalid & ~io.pause) { // We don't need to care about redir at this moment
// because the pipeline register will be cleared at next clock edge
state := sIDLE
thisInstValid := ~pendingRedirect
}
when(io.ifu2dmem.memRvalid & io.pause) {
savedInst := io.ifu2dmem.memRdata
savedPC := pc
}
when(io.exceptionRedir.redir) {
pendingRedirect := true.B
pendingRedirectAddr := io.exceptionRedir.redirPC
}.elsewhen(io.branchRedir.redir) {
pendingRedirect := true.B
pendingRedirectAddr := io.branchRedir.TargetPC
}
}
is(sPENDING) {
when(~io.pause) {
state := sIDLE
thisInstValid := ~pendingRedirect
thisInst := io.ifu2dmem.memRdata
thisPC := pc
thisExce.valid := pendingExce
}
}
}
// Add 'pausepending' state, when we want to transfer to IDLE state,
// but the next pipeline stages are stalled, they are not allowing new instructions in
// Just accept the instruction and go to the PENDING state, save the instruction
// Everytime we want to transfer to IDLE state(update PC),
// Remember to check whether we have pending or incoming flush or redirect request

when(io.exceptionRedir.redir) {
npc := io.exceptionRedir.redirPC
}.elsewhen(io.branchRedir.redir) {
npc := io.branchRedir.TargetPC
}.otherwise {
npc := pc + 4.U
}
io.stallReq := !io.rvalid

io.inst_out.inst := io.rdata
// TODO: Add exception handle

val exceptioInfo2decode = Wire(new ExceptionInfo)
exceptioInfo2decode.cause := 0.U
exceptioInfo2decode.epc := io.inst_out.inst_pc
exceptioInfo2decode.valid := false.B
exceptioInfo2decode.tval := io.rdata
io.inst_out.instValid := RegNext(Mux(io.pause, io.inst_out.instValid, Mux(io.branchRedir.redir || io.exceptionRedir.redir, false.B, io.rvalid)))
io.inst_out.inst_pc := RegNext(Mux(io.pause, io.inst_out.inst_pc, Mux(io.branchRedir.redir || io.exceptionRedir.redir, 0.U, io.inst_pc)))
io.exceInfo := exceptioInfo2decode
io.inst_out.instValid := RegNext(Mux(io.pause, io.inst_out.instValid, Mux(io.branchRedir.redir || io.exceptionRedir.redir, false.B, thisInstValid)))
io.inst_out.inst_pc := RegNext(Mux(io.pause, io.inst_out.inst_pc, Mux(io.branchRedir.redir || io.exceptionRedir.redir, 0.U, thisPC)))
io.inst_out.inst := RegNext(Mux(io.pause, io.inst_out.inst, Mux(io.branchRedir.redir || io.exceptionRedir.redir, 0.U, thisInst)))
io.exceInfoOut := RegNext(Mux(io.pause, io.exceInfoOut, Mux(io.branchRedir.redir || io.exceptionRedir.redir, 0.U.asTypeOf(new ExceptionInfo), thisExce)))
}

object IFU extends App {
Expand Down
24 changes: 19 additions & 5 deletions src/main/scala/core/top.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ import chisel3._
import chisel3.stage.ChiselStage
import chisel3.util.experimental.BoringUtils
import common.SyncReadWriteMem
import mmu._

class Top extends Module {
val io = IO(new Bundle() {
val pc = Output(UInt(64.W))
val instBundleOut = Output(new InstBundle)
})
val ifu = Module(new IFU)
val imem = Module(new common.SyncReadOnlyMem)
val immu = Module(new MMU(isDMMU = false))
val dmem = Module(new common.SyncReadWriteMem)
val decoder = Module(new Decode)
val exu = Module(new EXU)
Expand All @@ -22,19 +25,30 @@ class Top extends Module {
imem.io.reset := reset.asBool()
imem.io.pause := exu.io.pauseReq
// IFU <> IMEM
imem.io.rreq := ifu.io.inst_req
imem.io.raddr := (ifu.io.inst_pc - 0x80000000L.U(64.W))
ifu.io.rvalid:= imem.io.data_valid
ifu.io.rdata := imem.io.rdata

ifu.io.ifu2dmem.memRvalid:= imem.io.data_valid
ifu.io.ifu2dmem.memRdata := imem.io.rdata
ifu.io.ifu2dmem.memWrDone := false.B
immu.io.dmemreq.memRvalid:= imem.io.data_valid
immu.io.dmemreq.memRdata := imem.io.rdata
immu.io.dmemreq.memWrDone := false.B
immu.io.isStore := false.B
immu.io.flush := false.B // TODO
immu.io.csr2mmu <> csrFile.io.csrMMU
ifu.io.branchRedir := exu.io.exe2IF
ifu.io.exceptionRedir := csrFile.io.ifRedir
ifu.io.pause := exu.io.pauseReq
ifu.io.ifu2mmu <> immu.io.mem2mmu

imem.io.rreq := ifu.io.ifu2dmem.memRreq | immu.io.dmemreq.memRreq
imem.io.raddr := Mux(immu.io.dmemreq.memRreq, immu.io.dmemreq.memAddr, ifu.io.ifu2dmem.memAddr)


// IFU <> DECODER
decoder.io.instBundleIn := ifu.io.inst_out
decoder.io.intCtrl <> csrFile.io.intCtrl
decoder.io.regfileIO <> regfile.io.rdPort
decoder.io.exceptionInfoIF <> ifu.io.exceInfo
decoder.io.exceptionInfoIF <> ifu.io.exceInfoOut
decoder.io.PLIC_SEI := false.B

// DECODER <> EXU
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/core/wb.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class WB extends Module {
io.csrRw.instRd := io.regfileWrite.waddr
io.csrRw.instValid := io.instBundleIn.instValid
io.csrRw.instRs := io.instBundleIn.inst.asTypeOf(new CSRRInstruction).rs1

io.csrRw.inst := io.instBundleIn.inst
io.instBundleOut := io.instBundleIn
io.regfileWrite.waddr := io.exe2Commit.RdNum
io.regfileWrite.wen := io.exe2Commit.RFWen & io.instBundleIn.instValid & ~io.exe2Commit.exceInfo.valid
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/mmu/ptw.scala
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ class PTW(isDPTW: Boolean) extends Module {
}
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
ptrReg := Cat(io.satp_PPN, io.reqVAddr(38, 30), 0.U(3.W)) // Root Page Table PPN
}
} else {
when(!io.enableSv39) {
Expand All @@ -97,7 +97,7 @@ class PTW(isDPTW: Boolean) extends Module {
}
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
ptrReg := Cat(io.satp_PPN, io.reqVAddr(38, 30), 0.U(3.W)) // Root Page Table PPN
}
}
}
Expand Down

0 comments on commit df41bc2

Please sign in to comment.