Compare commits
3 commits
9e12c60d27
...
bb89461843
Author | SHA1 | Date | |
---|---|---|---|
bb89461843 | |||
3216c89dae | |||
e0b6634a93 |
10 changed files with 87 additions and 33 deletions
|
@ -90,6 +90,9 @@ class CPU extends MultiIOModule {
|
||||||
IDBarrier.in.r2Address := ID.io.r2Address
|
IDBarrier.in.r2Address := ID.io.r2Address
|
||||||
IDBarrier.in.ALUop := ID.io.ALUOp
|
IDBarrier.in.ALUop := ID.io.ALUOp
|
||||||
IDBarrier.in.returnAddr := ID.io.returnAddr
|
IDBarrier.in.returnAddr := ID.io.returnAddr
|
||||||
|
IDBarrier.in.branchAddr := ID.io.branchAddr
|
||||||
|
IDBarrier.in.nextOpAddr := ID.io.nextOpAddr
|
||||||
|
IDBarrier.in.branchPrediction := ID.io.branchPrediction
|
||||||
IDBarrier.in.jump := ID.io.jump
|
IDBarrier.in.jump := ID.io.jump
|
||||||
IDBarrier.in.branchType := ID.io.branchType
|
IDBarrier.in.branchType := ID.io.branchType
|
||||||
IDBarrier.in.writeEnable := ID.io.writeEnableOut
|
IDBarrier.in.writeEnable := ID.io.writeEnableOut
|
||||||
|
@ -103,10 +106,12 @@ class CPU extends MultiIOModule {
|
||||||
EX.io.branchType := IDBarrier.out.branchType
|
EX.io.branchType := IDBarrier.out.branchType
|
||||||
EX.io.rs1ValueIn := forward(IDBarrier.out.r1Value, IDBarrier.out.r1Address, true.B, mem = MEMBarrier.forwardMem, wb = MEMBarrier.forwardWb, id = MEMBarrier.forwardId).asSInt()
|
EX.io.rs1ValueIn := forward(IDBarrier.out.r1Value, IDBarrier.out.r1Address, true.B, mem = MEMBarrier.forwardMem, wb = MEMBarrier.forwardWb, id = MEMBarrier.forwardId).asSInt()
|
||||||
EX.io.rs2ValueIn := forward(IDBarrier.out.r2Value, IDBarrier.out.r2Address, true.B, mem = MEMBarrier.forwardMem, wb = MEMBarrier.forwardWb, id = MEMBarrier.forwardId).asSInt()
|
EX.io.rs2ValueIn := forward(IDBarrier.out.r2Value, IDBarrier.out.r2Address, true.B, mem = MEMBarrier.forwardMem, wb = MEMBarrier.forwardWb, id = MEMBarrier.forwardId).asSInt()
|
||||||
|
EX.io.branchAddr := IDBarrier.out.branchAddr
|
||||||
|
EX.io.nextOpAddr := IDBarrier.out.nextOpAddr
|
||||||
|
EX.io.branchPrediction := IDBarrier.out.branchPrediction
|
||||||
|
|
||||||
EXBarrier.in.r2Value := EX.io.rs2ValueOut.asUInt()
|
EXBarrier.in.r2Value := EX.io.rs2ValueOut.asUInt()
|
||||||
EXBarrier.in.ALUResult := EX.io.ALUResult.asUInt()
|
EXBarrier.in.ALUResult := EX.io.ALUResult.asUInt()
|
||||||
EXBarrier.branchIn := EX.io.branch
|
|
||||||
EXBarrier.in.jump := IDBarrier.out.jump
|
EXBarrier.in.jump := IDBarrier.out.jump
|
||||||
EXBarrier.in.returnAddr := IDBarrier.out.returnAddr
|
EXBarrier.in.returnAddr := IDBarrier.out.returnAddr
|
||||||
EXBarrier.in.writeEnable := IDBarrier.out.writeEnable
|
EXBarrier.in.writeEnable := IDBarrier.out.writeEnable
|
||||||
|
@ -126,19 +131,29 @@ class CPU extends MultiIOModule {
|
||||||
MEMBarrier.in.writeEnable := EXBarrier.out.writeEnable
|
MEMBarrier.in.writeEnable := EXBarrier.out.writeEnable
|
||||||
MEMBarrier.in.writeAddr := EXBarrier.out.writeAddr
|
MEMBarrier.in.writeAddr := EXBarrier.out.writeAddr
|
||||||
|
|
||||||
|
// Fast branching forwarding
|
||||||
|
ID.io.forwardEx := EXBarrier.forwardEx
|
||||||
|
ID.io.forwardMem := MEMBarrier.forwardMem
|
||||||
|
ID.io.forwardWb := MEMBarrier.forwardWb
|
||||||
|
ID.io.forwardId := MEMBarrier.forwardId
|
||||||
|
|
||||||
// Write back
|
// Write back
|
||||||
ID.io.writeData := MEMBarrier.out.data
|
ID.io.writeData := MEMBarrier.out.data
|
||||||
ID.io.writeEnableIn := MEMBarrier.out.writeEnable
|
ID.io.writeEnableIn := MEMBarrier.out.writeEnable
|
||||||
ID.io.writeAddrIn := MEMBarrier.out.writeAddr
|
ID.io.writeAddrIn := MEMBarrier.out.writeAddr
|
||||||
|
|
||||||
// Branching
|
// Branching
|
||||||
IF.io.branch := EXBarrier.branchOut
|
IF.io.branch := ID.io.branchPrediction || EX.io.misprediction
|
||||||
IF.io.branchAddress := EXBarrier.branchAddr
|
IF.io.branchAddress := Mux(EX.io.misprediction, EX.io.actualBranchAddr, ID.io.branchAddr)
|
||||||
|
|
||||||
|
// Flush
|
||||||
|
IFBarrier.flush := EX.io.misprediction
|
||||||
|
|
||||||
|
// Update branch prediction
|
||||||
|
ID.io.hasBranchResult := EX.io.branchOperation
|
||||||
|
ID.io.branchResult := EX.io.branchTaken
|
||||||
|
|
||||||
// Stall
|
// Stall
|
||||||
IF.io.stall := IDBarrier.stall
|
IF.io.stall := IDBarrier.stall
|
||||||
IFBarrier.stall := IDBarrier.stall
|
IFBarrier.stall := IDBarrier.stall
|
||||||
|
|
||||||
// Flush
|
|
||||||
IFBarrier.flush := EXBarrier.flush
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ class Decoder() extends Module {
|
||||||
|
|
||||||
// signal regWrite, memRead, memWrite, branch, jump, branchType, Op1Select, Op2Select, ImmSelect, ALUOp
|
// signal regWrite, memRead, memWrite, branch, jump, branchType, Op1Select, Op2Select, ImmSelect, ALUOp
|
||||||
JAL -> List(Y, N, N, Y, Y, branchType.jump, PC, imm, ImmFormat.JTYPE, ALUOps.ADD ),
|
JAL -> List(Y, N, N, Y, Y, branchType.jump, PC, imm, ImmFormat.JTYPE, ALUOps.ADD ),
|
||||||
JALR -> List(Y, N, N, Y, Y, branchType.jump, rs1, imm, ImmFormat.ITYPE, ALUOps.ADDR ),
|
JALR -> List(Y, N, N, Y, Y, branchType.jump, rs1, imm, ImmFormat.ITYPE, ALUOps.ADD ),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,13 @@ class Execute extends MultiIOModule {
|
||||||
val rs2ValueIn = Input(SInt(32.W))
|
val rs2ValueIn = Input(SInt(32.W))
|
||||||
val rs2ValueOut = Output(SInt(32.W))
|
val rs2ValueOut = Output(SInt(32.W))
|
||||||
val branchType = Input(UInt(3.W))
|
val branchType = Input(UInt(3.W))
|
||||||
val branch = Output(Bool())
|
val branchPrediction = Input(Bool())
|
||||||
|
val branchAddr = Input(UInt(32.W))
|
||||||
|
val nextOpAddr = Input(UInt(32.W))
|
||||||
|
val actualBranchAddr = Output(UInt(32.W))
|
||||||
|
val branchTaken = Output(Bool())
|
||||||
|
val branchOperation = Output(Bool())
|
||||||
|
val misprediction = Output(Bool())
|
||||||
val ALUOp = Input(UInt(4.W))
|
val ALUOp = Input(UInt(4.W))
|
||||||
val ALUResult = Output(SInt(32.W))
|
val ALUResult = Output(SInt(32.W))
|
||||||
}
|
}
|
||||||
|
@ -31,7 +37,6 @@ class Execute extends MultiIOModule {
|
||||||
ALUOps.SRA -> (io.op1 >> io.op2(4, 0)),
|
ALUOps.SRA -> (io.op1 >> io.op2(4, 0)),
|
||||||
ALUOps.SRL -> (io.op1.asUInt() >> io.op2(4, 0)).asSInt(),
|
ALUOps.SRL -> (io.op1.asUInt() >> io.op2(4, 0)).asSInt(),
|
||||||
ALUOps.SLL -> (io.op1.asUInt() << io.op2(4, 0)).asSInt(),
|
ALUOps.SLL -> (io.op1.asUInt() << io.op2(4, 0)).asSInt(),
|
||||||
ALUOps.ADDR -> ((io.op1 + io.op2) & -2.S),
|
|
||||||
ALUOps.COPY_A -> io.op1,
|
ALUOps.COPY_A -> io.op1,
|
||||||
ALUOps.COPY_B -> io.op2,
|
ALUOps.COPY_B -> io.op2,
|
||||||
)
|
)
|
||||||
|
@ -47,6 +52,9 @@ class Execute extends MultiIOModule {
|
||||||
)
|
)
|
||||||
|
|
||||||
io.rs2ValueOut := io.rs2ValueIn
|
io.rs2ValueOut := io.rs2ValueIn
|
||||||
io.branch := MuxLookup(io.branchType, false.B, BranchALUOpsMap)
|
io.branchTaken := MuxLookup(io.branchType, false.B, BranchALUOpsMap)
|
||||||
|
io.misprediction := io.branchOperation && (io.branchTaken =/= io.branchPrediction)
|
||||||
|
io.actualBranchAddr := Mux(io.branchTaken, io.branchAddr, io.nextOpAddr)
|
||||||
|
io.branchOperation := io.branchType =/= branchType.DC
|
||||||
io.ALUResult := MuxLookup(io.ALUOp, 0.S(32.W), ALUOpsMap)
|
io.ALUResult := MuxLookup(io.ALUOp, 0.S(32.W), ALUOpsMap)
|
||||||
}
|
}
|
|
@ -19,17 +19,14 @@ class EXBarrier extends MultiIOModule {
|
||||||
new Bundle {
|
new Bundle {
|
||||||
val in = Input(new EXBarrierIO)
|
val in = Input(new EXBarrierIO)
|
||||||
val out = Output(new EXBarrierIO)
|
val out = Output(new EXBarrierIO)
|
||||||
val flush = Output(Bool())
|
val forwardEx = Output(new Forwarding)
|
||||||
val branchAddr = Output(UInt(32.W))
|
|
||||||
val branchIn = Input(Bool())
|
|
||||||
val branchOut = Output(Bool())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
val delay = Reg(new EXBarrierIO)
|
val delay = Reg(new EXBarrierIO)
|
||||||
delay := io.in
|
delay := io.in
|
||||||
io.out := delay
|
io.out := delay
|
||||||
|
|
||||||
io.flush := io.branchIn
|
io.forwardEx.write := io.in.writeEnable
|
||||||
io.branchOut := io.branchIn
|
io.forwardEx.writeAddr := io.in.writeAddr
|
||||||
io.branchAddr := io.in.ALUResult
|
io.forwardEx.writeData := Mux(io.in.jump, io.in.returnAddr, io.in.ALUResult)
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ class InstructionDecode extends MultiIOModule {
|
||||||
val io = IO(
|
val io = IO(
|
||||||
new Bundle {
|
new Bundle {
|
||||||
val instruction = Input(new Instruction)
|
val instruction = Input(new Instruction)
|
||||||
|
val hasBranchResult = Input(Bool())
|
||||||
|
val branchResult = Input(Bool())
|
||||||
val pc = Input(UInt(32.W))
|
val pc = Input(UInt(32.W))
|
||||||
val op1 = Output(SInt(32.W))
|
val op1 = Output(SInt(32.W))
|
||||||
val isOp1RValue = Output(Bool())
|
val isOp1RValue = Output(Bool())
|
||||||
|
@ -37,11 +39,43 @@ class InstructionDecode extends MultiIOModule {
|
||||||
val memWrite = Output(Bool())
|
val memWrite = Output(Bool())
|
||||||
val memRead = Output(Bool())
|
val memRead = Output(Bool())
|
||||||
val branchType = Output(UInt(3.W))
|
val branchType = Output(UInt(3.W))
|
||||||
|
val branchPrediction = Output(Bool())
|
||||||
val jump = Output(Bool())
|
val jump = Output(Bool())
|
||||||
val returnAddr = Output(UInt(32.W))
|
val returnAddr = Output(UInt(32.W))
|
||||||
|
val branchAddr = Output(UInt(32.W))
|
||||||
|
val nextOpAddr = Output(UInt(32.W))
|
||||||
|
|
||||||
|
val forwardEx = Input(new Forwarding)
|
||||||
|
val forwardMem = Input(new Forwarding)
|
||||||
|
val forwardWb = Input(new Forwarding)
|
||||||
|
val forwardId = Input(new Forwarding)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def forward(data: UInt, addr: UInt, useForward: Bool, ex: Forwarding, mem: Forwarding, wb: Forwarding, id: Forwarding): UInt = {
|
||||||
|
Mux(
|
||||||
|
!useForward,
|
||||||
|
data,
|
||||||
|
Mux(
|
||||||
|
ex.valid && ex.writeAddr === addr,
|
||||||
|
ex.writeData,
|
||||||
|
Mux(
|
||||||
|
mem.valid && mem.writeAddr === addr,
|
||||||
|
mem.writeData,
|
||||||
|
Mux(
|
||||||
|
wb.valid && wb.writeAddr === addr,
|
||||||
|
wb.writeData,
|
||||||
|
Mux(
|
||||||
|
id.valid && id.writeAddr === addr,
|
||||||
|
id.writeData,
|
||||||
|
data,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
val registers = Module(new Registers)
|
val registers = Module(new Registers)
|
||||||
val decoder = Module(new Decoder).io
|
val decoder = Module(new Decoder).io
|
||||||
|
|
||||||
|
@ -94,4 +128,12 @@ class InstructionDecode extends MultiIOModule {
|
||||||
io.writeEnableOut := decoder.controlSignals.regWrite
|
io.writeEnableOut := decoder.controlSignals.regWrite
|
||||||
io.memRead := decoder.controlSignals.memRead
|
io.memRead := decoder.controlSignals.memRead
|
||||||
io.memWrite := decoder.controlSignals.memWrite
|
io.memWrite := decoder.controlSignals.memWrite
|
||||||
|
|
||||||
|
val op1 = forward(io.op1.asUInt(), io.r1Address, io.isOp1RValue, ex = io.forwardEx, mem = io.forwardMem, wb = io.forwardWb, id = io.forwardId).asSInt()
|
||||||
|
io.branchAddr := ((op1 + io.op2) & -2.S).asUInt()
|
||||||
|
io.nextOpAddr := io.pc + 4.U
|
||||||
|
|
||||||
|
val lastBranchWasTaken = RegInit(Bool(), true.B)
|
||||||
|
lastBranchWasTaken := Mux(io.hasBranchResult, io.branchResult, lastBranchWasTaken)
|
||||||
|
io.branchPrediction := Mux(io.branchType =/= branchType.DC, lastBranchWasTaken, false.B)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,9 @@ class IDBarrierIO extends Bundle {
|
||||||
val r2Value = UInt(32.W)
|
val r2Value = UInt(32.W)
|
||||||
val r2Address = UInt(5.W)
|
val r2Address = UInt(5.W)
|
||||||
val returnAddr = UInt(32.W)
|
val returnAddr = UInt(32.W)
|
||||||
|
val branchAddr = UInt(32.W)
|
||||||
|
val nextOpAddr = UInt(32.W)
|
||||||
|
val branchPrediction = Bool()
|
||||||
val jump = Bool()
|
val jump = Bool()
|
||||||
val ALUop = UInt(4.W)
|
val ALUop = UInt(4.W)
|
||||||
val branchType = UInt(3.W)
|
val branchType = UInt(3.W)
|
||||||
|
|
|
@ -46,9 +46,9 @@ class InstructionFetch extends MultiIOModule {
|
||||||
*
|
*
|
||||||
* You should expand on or rewrite the code below.
|
* You should expand on or rewrite the code below.
|
||||||
*/
|
*/
|
||||||
io.PC := PC
|
io.PC := Mux(io.branch, io.branchAddress, PC)
|
||||||
IMEM.io.instructionAddress := PC
|
IMEM.io.instructionAddress := io.PC
|
||||||
PC := Mux(io.branch, io.branchAddress, Mux(io.stall, PC, PC + 4.U))
|
PC := Mux(io.branch, io.branchAddress + 4.U, Mux(io.stall, PC, PC + 4.U))
|
||||||
|
|
||||||
val instruction = Wire(new Instruction)
|
val instruction = Wire(new Instruction)
|
||||||
instruction := IMEM.io.instruction.asTypeOf(new Instruction)
|
instruction := IMEM.io.instruction.asTypeOf(new Instruction)
|
||||||
|
|
|
@ -20,22 +20,12 @@ class IFBarrier extends MultiIOModule {
|
||||||
|
|
||||||
val instruction = Reg(new Instruction)
|
val instruction = Reg(new Instruction)
|
||||||
val replay = RegInit(Bool(), false.B)
|
val replay = RegInit(Bool(), false.B)
|
||||||
val flushRemaining = RegInit(UInt(2.W), 0.U)
|
|
||||||
flushRemaining := Mux(
|
|
||||||
io.flush,
|
|
||||||
1.U,
|
|
||||||
Mux(
|
|
||||||
flushRemaining === 0.U,
|
|
||||||
0.U,
|
|
||||||
flushRemaining - 1.U
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
replay := io.stall
|
replay := io.stall
|
||||||
instruction := io.instructionIn
|
instruction := io.instructionIn
|
||||||
|
|
||||||
io.instructionOut := Mux(
|
io.instructionOut := Mux(
|
||||||
io.stall || io.flush || flushRemaining > 0.U,
|
io.stall || io.flush,
|
||||||
Instruction.NOP,
|
Instruction.NOP,
|
||||||
Mux(
|
Mux(
|
||||||
replay,
|
replay,
|
||||||
|
|
|
@ -119,7 +119,6 @@ object ALUOps {
|
||||||
val SRA = 9.U(4.W)
|
val SRA = 9.U(4.W)
|
||||||
val COPY_A = 10.U(4.W)
|
val COPY_A = 10.U(4.W)
|
||||||
val COPY_B = 11.U(4.W)
|
val COPY_B = 11.U(4.W)
|
||||||
val ADDR = 12.U(4.W)
|
|
||||||
|
|
||||||
val DC = 15.U(4.W)
|
val DC = 15.U(4.W)
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ import LogParser._
|
||||||
|
|
||||||
object Manifest {
|
object Manifest {
|
||||||
|
|
||||||
val singleTest = "branch.s"
|
val singleTest = "square.s"
|
||||||
|
|
||||||
val nopPadded = false
|
val nopPadded = false
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue