| @@ -1,82 +1,79 @@ | |||||
| package FiveStage | package FiveStage | ||||
| import chisel3._ | 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 | |||||
| } | } | ||||
| @@ -22,10 +22,10 @@ class CPU extends MultiIOModule { | |||||
| /** | /** | ||||
| You need to create the classes for these yourself | 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 ID = Module(new InstructionDecode) | ||||
| val IF = Module(new InstructionFetch) | val IF = Module(new InstructionFetch) | ||||
| @@ -51,6 +51,18 @@ 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()) | |||||
| freeze := false.B | |||||
| IFBarrier.freeze := freeze | |||||
| IDBarrier.freeze := freeze | |||||
| EXBarrier.freeze := freeze | |||||
| MEMBarrier.freeze := freeze | |||||
| // Stage 1 | // Stage 1 | ||||
| IFBarrier.in := IF.io | IFBarrier.in := IF.io | ||||
| @@ -66,11 +78,27 @@ class CPU extends MultiIOModule { | |||||
| IDBarrier.in.ALUop := ID.io.ALUop | IDBarrier.in.ALUop := ID.io.ALUop | ||||
| // Stage 3 | // 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.PC := IDBarrier.out.PC | ||||
| EX.io.controlSignals := IDBarrier.out.controlSignals | EX.io.controlSignals := IDBarrier.out.controlSignals | ||||
| EX.io.branchType := IDBarrier.out.branchType | 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.imm := IDBarrier.out.imm | ||||
| EX.io.ALUop := IDBarrier.out.ALUop | EX.io.ALUop := IDBarrier.out.ALUop | ||||
| @@ -19,7 +19,7 @@ import LogParser._ | |||||
| object Manifest { | object Manifest { | ||||
| // TODO: Change back after add test succedes | // TODO: Change back after add test succedes | ||||
| val singleTest = "addi.s" //"forward2.s" | |||||
| val singleTest = "load.s" //"forward2.s" | |||||
| val nopPadded = false | val nopPadded = false | ||||
| @@ -80,7 +80,7 @@ class SingleTest extends FlatSpec with Matchers { | |||||
| class AllTests extends FlatSpec with Matchers { | class AllTests extends FlatSpec with Matchers { | ||||
| it should "just werk" in { | 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") | say(s"testing $testname") | ||||
| val opts = Manifest.allTestOptions(testname) | val opts = Manifest.allTestOptions(testname) | ||||
| (testname, TestRunner.run(opts)) | (testname, TestRunner.run(opts)) | ||||