Skip to content

Commit

Permalink
Handle timer interrupt in ifu
Browse files Browse the repository at this point in the history
  • Loading branch information
Bohan Hu committed Dec 2, 2020
1 parent 6312f41 commit 67f4508
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 9 deletions.
63 changes: 60 additions & 3 deletions src/main/scala/core/ifu.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class IFUIO extends Bundle {
val ifu2mmu = new MEM2MMU
val ifu2dmem = new MEM2dmem
val exceInfoOut = Output(new ExceptionInfo)
val intCtrl = Input(new INTCtrl)
}

/* TODOs:
Expand Down Expand Up @@ -147,8 +148,7 @@ class IFU extends Module {
Mux(io.pause, io.inst_out.inst_pc ,thisPC)))
io.inst_out.inst := RegNext(Mux(io.branchRedir.redir || io.exceptionRedir.redir, 0.U,
Mux(io.pause, io.inst_out.inst, thisInst)))
io.exceInfoOut := RegNext(Mux(io.branchRedir.redir || io.exceptionRedir.redir, 0.U.asTypeOf(new ExceptionInfo),
Mux(io.pause, io.exceInfoOut, thisExce)))


// 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)))
Expand All @@ -158,7 +158,64 @@ class IFU extends Module {
// io.inst_out.inst_pc := RegNext(Mux(io.branchRedir.redir || io.exceptionRedir.redir, 0.U, thisPC))
// io.inst_out.inst := RegNext(Mux(io.branchRedir.redir || io.exceptionRedir.redir, 0.U, thisInst))
// io.exceInfoOut := RegNext(Mux(io.branchRedir.redir || io.exceptionRedir.redir, 0.U.asTypeOf(new ExceptionInfo), thisExce))

val exceptionInfo = WireInit(thisExce)
val M = "b11".U
val S = "b01".U
val U = "b00".U
// io.inst_out.instValid := RegNext(Mux(io.pause, io.inst_out.instValid, Mux(io.branchRedir.redir || io.exceptionRedir.redir, false.B, thisInstValid)))
// Handle Interrupts Here
// If the instruction did not throw any exception in IF, we can attach the interrupt on this instruction
// the interrupt is order by priority, highest last
// We need a cause int signal to show whether the corresponding int is enabled
def MipAndMie(no: Int) = io.intCtrl.mip(no) && io.intCtrl.mie(no)
def makeInt(no: Int) = (no.U | 1.U << 63)
val causeInt = Wire(Bool())
causeInt := false.B
val sIntEnable = (io.intCtrl.privMode === S && io.intCtrl.sie || io.intCtrl.privMode === M)
when(MipAndMie(IntNo.STI) & io.intCtrl.sie & sIntEnable) {
exceptionInfo.cause := makeInt(IntNo.STI)
causeInt := true.B
}
when(MipAndMie(IntNo.SSI) & io.intCtrl.sie & sIntEnable) {
exceptionInfo.cause := makeInt(IntNo.SSI)
causeInt := true.B
}
/*
the platform-level interrupt controller may generate supervisor-level external interrupts.
Supervisor-level external interrupts are made pending based on the
logical-OR of the software- writable SEIP bit and the signal from the external interrupt controller
*/
when((io.intCtrl.mip(IntNo.SEI)) && io.intCtrl.mie(IntNo.SEI)) {
exceptionInfo.cause := makeInt(IntNo.SEI)
causeInt := true.B
}
when(MipAndMie(IntNo.MTI)) {
exceptionInfo.cause := makeInt(IntNo.MTI)
causeInt := true.B
}
when(MipAndMie(IntNo.MSI)) {
exceptionInfo.cause := makeInt(IntNo.MSI)
causeInt := true.B
}
when(MipAndMie(IntNo.MEI)) {
exceptionInfo.cause := makeInt(IntNo.MEI)
causeInt := true.B
}
// Until here, the value of exceptionInfo.cause has been the cause with the highest priority
// If we are in M mode, the S INT is disabled (unless is delegated)
// If we are in S mode,
// If M mode interrupts are disabled and we are in S mode,
when(exceptionInfo.cause(63) & io.intCtrl.intGlobalEnable & causeInt) { // If is interrupt, we need to consider whether the interrupt can be taken
when(io.intCtrl.mideleg(exceptionInfo.cause(5, 0))){
when((io.intCtrl.sie && io.intCtrl.privMode === S) || io.intCtrl.privMode === U) { // If is delegated to S mode
exceptionInfo.valid := true.B
}
}.otherwise {
exceptionInfo.valid := true.B
}
}
io.exceInfoOut := RegNext(Mux(io.branchRedir.redir || io.exceptionRedir.redir, 0.U.asTypeOf(new ExceptionInfo),
Mux(io.pause, io.exceInfoOut, exceptionInfo)))
}

object IFU extends App {
Expand Down
14 changes: 8 additions & 6 deletions src/main/scala/core/mem.scala
Original file line number Diff line number Diff line change
Expand Up @@ -159,17 +159,19 @@ class MEM extends Module {
SZ_BU -> 1.U
)
)
val dataSizeReg = RegInit(dataSize)
dataSizeReg := dataSize
val signExt = io.MemType === SZ_B || io.MemType === SZ_H || io.MemType === SZ_W
val dataFromMem = WireInit(io.mem2dmem.memRdata)
val memRdataRaw = MuxLookup(dataSize, dataFromMem, // Including Word Select
val memRdataRaw = MuxLookup(dataSizeReg, dataFromMem, // Including Word Select
Array( // Byte, Addressed by addr[2:0]
1.U -> dataFromMem.asTypeOf(DataTypesUtils.Bytes)(accessVAddr(2, 0)),
2.U -> dataFromMem.asTypeOf(DataTypesUtils.HalfWords)(accessVAddr(2, 1)),
4.U -> dataFromMem.asTypeOf(DataTypesUtils.Words)(accessVAddr(2)),
8.U -> dataFromMem
)
)
val memRdataRawExt = MuxLookup(dataSize, dataFromMem, // Including Word Select
val memRdataRawExt = MuxLookup(dataSizeReg, dataFromMem, // Including Word Select
Array( // Byte, Addressed by addr[2:0]
1.U -> dataFromMem.asTypeOf(DataTypesUtils.Bytes)(accessVAddr(2, 0)),
2.U -> dataFromMem.asTypeOf(DataTypesUtils.HalfWords)(accessVAddr(2, 1)),
Expand Down Expand Up @@ -204,8 +206,8 @@ class MEM extends Module {
io.mem2mmu.reqReady := false.B
io.mem2mmu.reqVAddr := accessVAddr
val rDataReg = Reg(UInt(64.W))
val amoSrc1 = Mux(dataSize === 4.U, io.R2Val(31,0), io.R2Val)
val amoSrc2 = Mux(dataSize === 4.U, Mux(accessVAddr(2),rDataReg(63,32) ,rDataReg(31,0)), rDataReg)
val amoSrc1 = Mux(dataSizeReg === 4.U, io.R2Val(31,0), io.R2Val)
val amoSrc2 = Mux(dataSizeReg === 4.U, Mux(accessVAddr(2),rDataReg(63,32) ,rDataReg(31,0)), rDataReg)
val amoWData = MuxLookup(io.fuOp, amoSrc2,
Array(
LSU_ASWAP -> amoSrc1,
Expand All @@ -220,8 +222,8 @@ class MEM extends Module {
)
)
io.mem2dmem.memAddr := translatedPAddr
io.mem2dmem.memWdata := DataTypesUtils.WDataGen(dataSize, accessVAddr, Mux(isAMO && !isSC, amoWData, io.R2Val))
io.mem2dmem.memWmask := DataTypesUtils.Byte2BitMask(DataTypesUtils.ByteMaskGen(dataSize, accessVAddr))
io.mem2dmem.memWdata := DataTypesUtils.WDataGen(dataSizeReg, accessVAddr, Mux(isAMO && !isSC, amoWData, io.R2Val))
io.mem2dmem.memWmask := DataTypesUtils.Byte2BitMask(DataTypesUtils.ByteMaskGen(dataSizeReg, accessVAddr))
io.mem2dmem.memWen := false.B
io.mem2dmem.memRreq := false.B
io.memResult := Mux(signExt, memRdataRawExt, memRdataRaw)
Expand Down
1 change: 1 addition & 0 deletions src/main/scala/core/top.scala
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class Top extends Module {
ifu.io.exceptionRedir := csrFile.io.ifRedir
ifu.io.pause := exu.io.pauseReq
ifu.io.ifu2mmu <> immu.io.mem2mmu
ifu.io.intCtrl <> csrFile.io.intCtrl

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)
Expand Down

0 comments on commit 67f4508

Please sign in to comment.