|
|
@@ -26,6 +26,7 @@ class CPU extends MultiIOModule { |
|
|
val IDBarrier = Module(new IDBarrier) |
|
|
val IDBarrier = Module(new IDBarrier) |
|
|
val EXBarrier = Module(new EXBarrier) |
|
|
val EXBarrier = Module(new EXBarrier) |
|
|
val MEMBarrier = Module(new MEMBarrier) |
|
|
val MEMBarrier = Module(new MEMBarrier) |
|
|
|
|
|
val WBBarrier = Module(new WBBarrier) |
|
|
|
|
|
|
|
|
val ID = Module(new InstructionDecode) |
|
|
val ID = Module(new InstructionDecode) |
|
|
val IF = Module(new InstructionFetch) |
|
|
val IF = Module(new InstructionFetch) |
|
|
@@ -62,9 +63,22 @@ class CPU extends MultiIOModule { |
|
|
IDBarrier.freeze := freeze |
|
|
IDBarrier.freeze := freeze |
|
|
EXBarrier.freeze := freeze |
|
|
EXBarrier.freeze := freeze |
|
|
MEMBarrier.freeze := freeze |
|
|
MEMBarrier.freeze := freeze |
|
|
|
|
|
WBBarrier.freeze := freeze |
|
|
|
|
|
|
|
|
|
|
|
val clear = Wire(Bool()) |
|
|
|
|
|
clear := false.B |
|
|
|
|
|
IFBarrier.clear := clear |
|
|
|
|
|
IDBarrier.clear := clear |
|
|
|
|
|
EXBarrier.clear := clear |
|
|
|
|
|
MEMBarrier.clear := clear |
|
|
|
|
|
WBBarrier.clear := clear |
|
|
|
|
|
|
|
|
|
|
|
// The value that is written back to the register |
|
|
|
|
|
val writeback = Wire(UInt(32.W)) |
|
|
|
|
|
|
|
|
// Stage 1 |
|
|
// Stage 1 |
|
|
IFBarrier.in := IF.io |
|
|
IFBarrier.in := IF.io |
|
|
|
|
|
IF.io.addr := IFBarrier.out.next |
|
|
|
|
|
|
|
|
// Stage 2 |
|
|
// Stage 2 |
|
|
ID.io.instruction := IFBarrier.out.instruction |
|
|
ID.io.instruction := IFBarrier.out.instruction |
|
|
@@ -82,17 +96,61 @@ class CPU extends MultiIOModule { |
|
|
val exToRs2 = IDBarrier.out.instruction.registerRs2 === EXBarrier.out.instruction.registerRd |
|
|
val exToRs2 = IDBarrier.out.instruction.registerRs2 === EXBarrier.out.instruction.registerRd |
|
|
val memToRs1 = IDBarrier.out.instruction.registerRs1 === MEMBarrier.out.instruction.registerRd |
|
|
val memToRs1 = IDBarrier.out.instruction.registerRs1 === MEMBarrier.out.instruction.registerRd |
|
|
val memToRs2 = IDBarrier.out.instruction.registerRs2 === MEMBarrier.out.instruction.registerRd |
|
|
val memToRs2 = IDBarrier.out.instruction.registerRs2 === MEMBarrier.out.instruction.registerRd |
|
|
val ldToRs1 = exToRs1 && EXBarrier.out.controlSignals.memRead |
|
|
|
|
|
val ldToRs2 = exToRs2 && EXBarrier.out.controlSignals.memRead |
|
|
|
|
|
|
|
|
val wbToRs1 = IDBarrier.out.instruction.registerRs1 === WBBarrier.out.instruction.registerRd |
|
|
|
|
|
val wbToRs2 = IDBarrier.out.instruction.registerRs2 === WBBarrier.out.instruction.registerRd |
|
|
|
|
|
val ldToRs1 = exToRs1 && EXBarrier.out.controlSignals.memToReg |
|
|
|
|
|
val ldToRs2 = exToRs2 && EXBarrier.out.controlSignals.memToReg |
|
|
|
|
|
|
|
|
|
|
|
//printf(p"0x${Hexadecimal(IF.io.PC)}: EX in: ${IDBarrier.out.instruction.registerRs1}, MEM out: ${MEMBarrier.out.instruction.registerRd}\n") |
|
|
|
|
|
|
|
|
when ((ldToRs1 || ldToRs2) && state =/= LOAD_FREEZE) { |
|
|
when ((ldToRs1 || ldToRs2) && state =/= LOAD_FREEZE) { |
|
|
|
|
|
//printf(p"0x${Hexadecimal(IF.io.PC)}: Load freeze\n") |
|
|
|
|
|
// Freeze all barriers (repeating the instruction) until the value is loaded from memory |
|
|
freeze := true.B |
|
|
freeze := true.B |
|
|
|
|
|
|
|
|
|
|
|
// The MEM and WB carry out their instructions, but MEM is cleared so it doesn't repeat |
|
|
|
|
|
// the instruction. This carries through to WB next cycle. |
|
|
MEMBarrier.freeze := false.B |
|
|
MEMBarrier.freeze := false.B |
|
|
|
|
|
WBBarrier.freeze := false.B |
|
|
|
|
|
EXBarrier.freeze := false.B |
|
|
|
|
|
EXBarrier.clear := true.B |
|
|
state := LOAD_FREEZE |
|
|
state := LOAD_FREEZE |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
val rs1 = Mux(exToRs1, EXBarrier.out.result, Mux(memToRs1, MEMBarrier.out.result, IDBarrier.out.reg1)) |
|
|
|
|
|
val rs2 = Mux(exToRs2, EXBarrier.out.result, Mux(memToRs2, MEMBarrier.out.result, IDBarrier.out.reg2)) |
|
|
|
|
|
|
|
|
//printf(p"0x${Hexadecimal(IF.io.PC)}: freeze: $freeze, exR1: ${IDBarrier.out.instruction.registerRs1}, rd: ${IF.io.instruction.registerRd}, IF: ${IFBarrier.out.instruction.opcode}, ID: ${IDBarrier.out.instruction.opcode}, EX: ${EXBarrier.out.instruction.opcode}, MEM: ${MEMBarrier.out.instruction.opcode}, WB: ${WBBarrier.out.instruction.opcode}\n") |
|
|
|
|
|
|
|
|
|
|
|
//printf(p"0x${Hexadecimal(IF.io.PC)}: next: 0x${Hexadecimal(IFBarrier.out.next)}, IF: 0x${Hexadecimal(IFBarrier.out.PC)}, ID: 0x${Hexadecimal(IDBarrier.out.PC)}, EX: 0x${Hexadecimal(EXBarrier.out.PC)}, MEM: 0x${Hexadecimal(MEMBarrier.out.PC)}, WB: 0x${Hexadecimal(WBBarrier.out.PC)}, freeze: $freeze\n") |
|
|
|
|
|
|
|
|
|
|
|
val rs1 = Wire(UInt(32.W)) |
|
|
|
|
|
when (ldToRs1) { |
|
|
|
|
|
rs1 := MEMBarrier.out.dataOut |
|
|
|
|
|
}.elsewhen (exToRs1) { |
|
|
|
|
|
rs1 := EXBarrier.out.result |
|
|
|
|
|
}.elsewhen (memToRs1) { |
|
|
|
|
|
rs1 := writeback |
|
|
|
|
|
}.elsewhen (wbToRs1) { |
|
|
|
|
|
rs1 := WBBarrier.out.writeback |
|
|
|
|
|
}.otherwise { |
|
|
|
|
|
rs1 := IDBarrier.out.reg1 |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
val rs2 = Wire(UInt(32.W)) |
|
|
|
|
|
when (ldToRs2) { |
|
|
|
|
|
rs2 := MEMBarrier.out.dataOut |
|
|
|
|
|
}.elsewhen (exToRs2) { |
|
|
|
|
|
rs2 := EXBarrier.out.result |
|
|
|
|
|
}.elsewhen (memToRs2) { |
|
|
|
|
|
rs2 := writeback |
|
|
|
|
|
}.elsewhen (wbToRs2) { |
|
|
|
|
|
rs2 := WBBarrier.out.writeback |
|
|
|
|
|
}.otherwise { |
|
|
|
|
|
rs2 := IDBarrier.out.reg2 |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//printf(p"0x${Hexadecimal(IF.io.PC)}: Reg write: ${MEMBarrier.out.controlSignals.regWrite}, ExToR1: $exToRs1, MEMToR1: $memToRs1, wbToR1: $wbToRs1, R1: $rs1, EX: ${EXBarrier.out.result}, MEM: ${MEMBarrier.out.dataOut}, WB: ${WBBarrier.out.writeback}}\n") |
|
|
|
|
|
|
|
|
|
|
|
//printf(p"0x${Hexadecimal(IF.io.PC)}: Next: 0x${Hexadecimal(IFBarrier.out.next)}, freeze: $freeze, IF: ${IFBarrier.out.instruction}, ID: ${IDBarrier.out.instruction}, EX: ${EXBarrier.out.instruction}, MEM: ${MEMBarrier.out.instruction}\n") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
EX.io.PC := IDBarrier.out.PC |
|
|
EX.io.PC := IDBarrier.out.PC |
|
|
EX.io.controlSignals := IDBarrier.out.controlSignals |
|
|
EX.io.controlSignals := IDBarrier.out.controlSignals |
|
|
@@ -114,8 +172,9 @@ class CPU extends MultiIOModule { |
|
|
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 |
|
|
|
|
|
|
|
|
IF.io.jumpEnable := EXBarrier.out.branch |
|
|
|
|
|
IF.io.jumpAddr := EXBarrier.out.result |
|
|
|
|
|
|
|
|
when (EXBarrier.out.branch) { |
|
|
|
|
|
//IF.io.addr := EXBarrier.out.result |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
MEMBarrier.in.PC := EXBarrier.out.PC |
|
|
MEMBarrier.in.PC := EXBarrier.out.PC |
|
|
MEMBarrier.in.instruction := EXBarrier.out.instruction |
|
|
MEMBarrier.in.instruction := EXBarrier.out.instruction |
|
|
@@ -124,15 +183,28 @@ class CPU extends MultiIOModule { |
|
|
MEMBarrier.in.dataOut := MEM.io.dataOut |
|
|
MEMBarrier.in.dataOut := MEM.io.dataOut |
|
|
|
|
|
|
|
|
// Stage 5 |
|
|
// Stage 5 |
|
|
ID.io.writeEnable := MEMBarrier.out.controlSignals.regWrite |
|
|
|
|
|
ID.io.writeAddr := MEMBarrier.out.instruction.registerRd |
|
|
|
|
|
ID.io.writeData := MEMBarrier.out.result |
|
|
|
|
|
|
|
|
when (freeze) { |
|
|
|
|
|
ID.io.writeEnable := false.B |
|
|
|
|
|
ID.io.writeAddr := 0.U |
|
|
|
|
|
ID.io.writeData := 0.U |
|
|
|
|
|
}.otherwise { |
|
|
|
|
|
ID.io.writeEnable := MEMBarrier.out.controlSignals.regWrite |
|
|
|
|
|
ID.io.writeAddr := MEMBarrier.out.instruction.registerRd |
|
|
|
|
|
ID.io.writeData := writeback |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
WBBarrier.in.PC := MEMBarrier.out.PC |
|
|
|
|
|
WBBarrier.in.instruction := MEMBarrier.out.instruction |
|
|
|
|
|
WBBarrier.in.controlSignals := MEMBarrier.out.controlSignals |
|
|
|
|
|
WBBarrier.in.writeback := writeback |
|
|
|
|
|
|
|
|
|
|
|
writeback := MEMBarrier.out.result |
|
|
|
|
|
|
|
|
when (MEMBarrier.out.controlSignals.memToReg) { |
|
|
when (MEMBarrier.out.controlSignals.memToReg) { |
|
|
ID.io.writeData := MEMBarrier.out.dataOut |
|
|
|
|
|
|
|
|
writeback := MEMBarrier.out.dataOut |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
when (MEMBarrier.out.controlSignals.jump) { |
|
|
when (MEMBarrier.out.controlSignals.jump) { |
|
|
ID.io.writeData := MEMBarrier.out.PC + 4.U |
|
|
|
|
|
|
|
|
writeback := MEMBarrier.out.PC + 4.U |
|
|
} |
|
|
} |
|
|
} |
|
|
} |