diff --git a/src/main/scala/Barriers.scala b/src/main/scala/Barriers.scala index 7f4581b..d2ebc56 100644 --- a/src/main/scala/Barriers.scala +++ b/src/main/scala/Barriers.scala @@ -1,82 +1,79 @@ package FiveStage import chisel3._ -import chisel3.util.ShiftRegister +import chisel3.experimental.MultiIOModule -class IFBarrier extends Module { - class IFBundle extends Bundle { - val PC = UInt() - val instruction = new Instruction +object BarrierReg { + def apply[T <: Data](in: T)(implicit freeze: Bool): Data = { + val reg = RegNext(in) + val old = RegNext(reg) + + when (freeze) { + reg := old + } + + reg } +} + - val io = IO(new Bundle { - val in = Input(new IFBundle) - val out = Output(new IFBundle) - }) +class Barrier[B <: Bundle](b: B) extends MultiIOModule { + implicit val freeze = IO(Input(Bool())) + val in = IO(Input(b)) + val out = IO(Output(b)) - io.out.instruction := io.in.instruction - io.out.PC := ShiftRegister(io.in.PC, 1) + out := BarrierReg(in) } -class IDBarrier extends Module { - class IDBundle extends Bundle { - val PC = UInt() - val instruction = new Instruction - val controlSignals = new ControlSignals - val branchType = UInt(3.W) - val reg1 = UInt(32.W) - val reg2 = UInt(32.W) - val imm = UInt(32.W) - val ALUop = UInt(4.W) - } +class IFBundle extends Bundle { + val PC = UInt() + val instruction = new Instruction +} - val io = IO(new Bundle { - val in = Input(new IDBundle) - val out = Output(new IDBundle) - }) - io.out := ShiftRegister(io.in, 1) +class IFBarrier extends Barrier(new IFBundle) { + out.instruction := in.instruction + out.PC := BarrierReg(in.PC) } -class EXBarrier extends Module { - class EXBundle extends Bundle { - val PC = UInt() - val instruction = new Instruction - val controlSignals = new ControlSignals - val reg2 = UInt(32.W) - val result = UInt(32.W) - val branch = Bool() - } +class IDBundle extends IFBundle { + val controlSignals = new ControlSignals + val branchType = UInt(3.W) + val reg1 = UInt(32.W) + val reg2 = UInt(32.W) + val imm = UInt(32.W) + val ALUop = UInt(4.W) +} + - val io = IO(new Bundle { - val in = Input(new EXBundle) - val out = Output(new EXBundle) - }) +class IDBarrier extends Barrier(new IDBundle) {} - io.out := ShiftRegister(io.in, 1) + +class EXBundle extends IFBundle { + val controlSignals = new ControlSignals + val reg2 = UInt(32.W) + val result = UInt(32.W) + val branch = Bool() } -class MEMBarrier extends Module { - class MEMBundle extends Bundle { - val PC = UInt() - val instruction = new Instruction - val controlSignals = new ControlSignals - val result = UInt(32.W) - val dataOut = UInt(32.W) - } +class EXBarrier extends Barrier(new EXBundle) {} + + +class MEMBundle extends IFBundle { + val controlSignals = new ControlSignals + val result = UInt(32.W) + val dataOut = UInt(32.W) +} - val io = IO(new Bundle { - val in = Input(new MEMBundle) - val out = Output(new MEMBundle) - }) - io.out.PC := ShiftRegister(io.in.PC, 1) - io.out.instruction := ShiftRegister(io.in.instruction, 1) - io.out.controlSignals := ShiftRegister(io.in.controlSignals, 1) - io.out.result := ShiftRegister(io.in.result, 1) - io.out.dataOut := io.in.dataOut +class MEMBarrier extends Barrier(new MEMBundle) { + out.PC := BarrierReg(in.PC) + out.instruction := BarrierReg(in.instruction) + out.controlSignals := BarrierReg(in.controlSignals) + out.result := BarrierReg(in.result) + out.dataOut := in.dataOut } diff --git a/src/main/scala/CPU.scala b/src/main/scala/CPU.scala index defc20a..3153281 100644 --- a/src/main/scala/CPU.scala +++ b/src/main/scala/CPU.scala @@ -22,10 +22,10 @@ class CPU extends MultiIOModule { /** You need to create the classes for these yourself */ - val IFBarrier = Module(new IFBarrier).io - val IDBarrier = Module(new IDBarrier).io - val EXBarrier = Module(new EXBarrier).io - val MEMBarrier = Module(new MEMBarrier).io + val IFBarrier = Module(new IFBarrier) + val IDBarrier = Module(new IDBarrier) + val EXBarrier = Module(new EXBarrier) + val MEMBarrier = Module(new MEMBarrier) val ID = Module(new InstructionDecode) val IF = Module(new InstructionFetch) @@ -51,6 +51,18 @@ class CPU extends MultiIOModule { 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()) + freeze := false.B + IFBarrier.freeze := freeze + IDBarrier.freeze := freeze + EXBarrier.freeze := freeze + MEMBarrier.freeze := freeze + // Stage 1 IFBarrier.in := IF.io @@ -66,11 +78,27 @@ class CPU extends MultiIOModule { IDBarrier.in.ALUop := ID.io.ALUop // Stage 3 + val exToRs1 = IDBarrier.out.instruction.registerRs1 === 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 memToRs2 = IDBarrier.out.instruction.registerRs2 === MEMBarrier.out.instruction.registerRd + val ldToRs1 = exToRs1 && EXBarrier.out.controlSignals.memRead + val ldToRs2 = exToRs2 && EXBarrier.out.controlSignals.memRead + + when ((ldToRs1 || ldToRs2) && state =/= LOAD_FREEZE) { + freeze := true.B + MEMBarrier.freeze := false.B + 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)) + EX.io.PC := IDBarrier.out.PC EX.io.controlSignals := IDBarrier.out.controlSignals EX.io.branchType := IDBarrier.out.branchType - EX.io.reg1 := IDBarrier.out.reg1 - EX.io.reg2 := IDBarrier.out.reg2 + EX.io.reg1 := rs1 + EX.io.reg2 := rs2 EX.io.imm := IDBarrier.out.imm EX.io.ALUop := IDBarrier.out.ALUop diff --git a/src/test/scala/Manifest.scala b/src/test/scala/Manifest.scala index 921c5e2..6c9f19c 100644 --- a/src/test/scala/Manifest.scala +++ b/src/test/scala/Manifest.scala @@ -19,7 +19,7 @@ import LogParser._ object Manifest { // TODO: Change back after add test succedes - val singleTest = "addi.s" //"forward2.s" + val singleTest = "load.s" //"forward2.s" val nopPadded = false @@ -80,7 +80,7 @@ class SingleTest extends FlatSpec with Matchers { class AllTests extends FlatSpec with Matchers { it should "just werk" in { - val werks = getAllTestNames.filterNot(_ == "convolution.s").map{testname => + val werks = getAllTestNames.filterNot(_ == "convolution.s").map{testname => say(s"testing $testname") val opts = Manifest.allTestOptions(testname) (testname, TestRunner.run(opts))