|
|
@@ -48,11 +48,6 @@ class CPU extends MultiIOModule { |
|
|
testHarness.currentPC := IF.testHarness.PC |
|
|
testHarness.currentPC := IF.testHarness.PC |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val NORMAL = 0.U |
|
|
|
|
|
val LOAD_FREEZE = 1.U |
|
|
|
|
|
val state = Reg(UInt(4.W)) |
|
|
|
|
|
state := NORMAL |
|
|
|
|
|
|
|
|
|
|
|
val freeze = Wire(Bool()) |
|
|
val freeze = Wire(Bool()) |
|
|
freeze := false.B |
|
|
freeze := false.B |
|
|
IFBarrier.freeze := freeze |
|
|
IFBarrier.freeze := freeze |
|
|
@@ -78,9 +73,22 @@ class CPU extends MultiIOModule { |
|
|
forwarder.WB := WBBarrier.out |
|
|
forwarder.WB := WBBarrier.out |
|
|
forwarder.writeback := writeback |
|
|
forwarder.writeback := writeback |
|
|
|
|
|
|
|
|
|
|
|
val predictor = Module(new BranchPredictor(128)).io |
|
|
|
|
|
predictor.update.enable := false.B |
|
|
|
|
|
predictor.update.PC := 0.U |
|
|
|
|
|
predictor.update.branchAddr := 0.U |
|
|
|
|
|
predictor.update.branchTaken := false.B |
|
|
|
|
|
|
|
|
|
|
|
when (predictor.misjump) { |
|
|
|
|
|
// Clear the barriers on a misjump |
|
|
|
|
|
IDBarrier.clear := true.B |
|
|
|
|
|
EXBarrier.clear := true.B |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// Stage 1 |
|
|
// Stage 1 |
|
|
IFBarrier.in := IF.io |
|
|
IFBarrier.in := IF.io |
|
|
IF.io.addr := IFBarrier.out.PC + 4.U |
|
|
|
|
|
|
|
|
predictor.PC := IFBarrier.out.PC |
|
|
|
|
|
IF.io.addr := predictor.nextAddr |
|
|
|
|
|
|
|
|
// Stage 2 |
|
|
// Stage 2 |
|
|
ID.io.instruction := IFBarrier.out.instruction |
|
|
ID.io.instruction := IFBarrier.out.instruction |
|
|
@@ -94,7 +102,7 @@ class CPU extends MultiIOModule { |
|
|
IDBarrier.in.ALUop := ID.io.ALUop |
|
|
IDBarrier.in.ALUop := ID.io.ALUop |
|
|
|
|
|
|
|
|
// Stage 3 |
|
|
// Stage 3 |
|
|
when (forwarder.loadFreeze && state =/= LOAD_FREEZE) { |
|
|
|
|
|
|
|
|
when (forwarder.loadFreeze && !RegNext(freeze)) { |
|
|
// Freeze the IF and ID barriers, repeating the instruction. |
|
|
// Freeze the IF and ID barriers, repeating the instruction. |
|
|
// EX is cleared, so the instruction isn't computed and written twice. |
|
|
// EX is cleared, so the instruction isn't computed and written twice. |
|
|
freeze := true.B |
|
|
freeze := true.B |
|
|
@@ -102,7 +110,6 @@ class CPU extends MultiIOModule { |
|
|
WBBarrier.freeze := false.B |
|
|
WBBarrier.freeze := false.B |
|
|
EXBarrier.freeze := false.B |
|
|
EXBarrier.freeze := false.B |
|
|
EXBarrier.clear := true.B |
|
|
EXBarrier.clear := true.B |
|
|
state := LOAD_FREEZE |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
EX.io.PC := IDBarrier.out.PC |
|
|
EX.io.PC := IDBarrier.out.PC |
|
|
@@ -121,6 +128,13 @@ class CPU extends MultiIOModule { |
|
|
EXBarrier.in.branch := EX.io.branch |
|
|
EXBarrier.in.branch := EX.io.branch |
|
|
|
|
|
|
|
|
// Stage 4 |
|
|
// Stage 4 |
|
|
|
|
|
when (EXBarrier.out.controlSignals.jump || EXBarrier.out.controlSignals.branch) { |
|
|
|
|
|
predictor.update.enable := true.B |
|
|
|
|
|
predictor.update.PC := EXBarrier.out.PC |
|
|
|
|
|
predictor.update.branchAddr := EXBarrier.out.result |
|
|
|
|
|
predictor.update.branchTaken := EXBarrier.out.branch |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
MEM.io.dataIn := forwarder.memWrite |
|
|
MEM.io.dataIn := forwarder.memWrite |
|
|
MEM.io.writeEnable := EXBarrier.out.controlSignals.memWrite |
|
|
MEM.io.writeEnable := EXBarrier.out.controlSignals.memWrite |
|
|
MEM.io.dataAddress := EXBarrier.out.result |
|
|
MEM.io.dataAddress := EXBarrier.out.result |
|
|
@@ -133,12 +147,6 @@ class CPU extends MultiIOModule { |
|
|
MEMBarrier.in.dataOut := MEM.io.dataOut |
|
|
MEMBarrier.in.dataOut := MEM.io.dataOut |
|
|
|
|
|
|
|
|
// Stage 5 |
|
|
// Stage 5 |
|
|
when (EXBarrier.out.branch) { |
|
|
|
|
|
IF.io.addr := EXBarrier.out.result |
|
|
|
|
|
IDBarrier.clear := true.B |
|
|
|
|
|
EXBarrier.clear := true.B |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ID.io.writeEnable := MEMBarrier.out.controlSignals.regWrite |
|
|
ID.io.writeEnable := MEMBarrier.out.controlSignals.regWrite |
|
|
ID.io.writeAddr := MEMBarrier.out.instruction.registerRd |
|
|
ID.io.writeAddr := MEMBarrier.out.instruction.registerRd |
|
|
ID.io.writeData := writeback |
|
|
ID.io.writeData := writeback |
|
|
|