diff --git a/src/main/scala/Barriers.scala b/src/main/scala/Barriers.scala new file mode 100644 index 0000000..b010faa --- /dev/null +++ b/src/main/scala/Barriers.scala @@ -0,0 +1,96 @@ +package FiveStage + +import chisel3._ +import chisel3.util.ShiftRegister + + +class IFBarrier extends Module { + val io = IO(new Bundle { + val in = Input(new Bundle { + val PC = UInt() + val instruction = new Instruction + }) + val stage2 = Output(new Bundle { + val instruction = new Instruction + }) + val stage3 = Output(new Bundle { + val PC = UInt() + }) + val stage5 = Output(new Bundle { + val PC = UInt() + val instruction = new Instruction + }) + }) + + io.stage2 := io.in + io.stage3 := ShiftRegister(io.in, 1) + io.stage5 := ShiftRegister(io.in, 3) +} + + +class IDBarrier extends Module { + val io = IO(new Bundle { + val in = Input(new Bundle { + 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 stage3 = Output(new Bundle { + 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 stage4 = Output(new Bundle { + val controlSignals = new ControlSignals + val reg2 = UInt(32.W) + }) + val stage5 = Output(new Bundle { + val controlSignals = new ControlSignals + val reg2 = UInt(32.W) + }) + }) + + io.stage3 := io.in + io.stage4 := ShiftRegister(io.in, 1) + io.stage5 := ShiftRegister(io.in, 2) +} + + +class EXBarrier extends Module { + val io = IO(new Bundle { + val in = Input(new Bundle { + val result = UInt(32.W) + val branch = Bool() + }) + val stage4 = Output(new Bundle { + val result = UInt(32.W) + val branch = Bool() + }) + val stage5 = Output(new Bundle { + val result = UInt(32.W) + }) + }) + + io.stage4 := io.in + io.stage5 := ShiftRegister(io.in, 1) +} + + +class MEMBarrier extends Module { + val io = IO(new Bundle { + val in = Input(new Bundle { + val dataOut = UInt(32.W) + }) + val stage5 = Output(new Bundle { + val dataOut = UInt(32.W) + }) + }) + + io.stage5 := io.in +} diff --git a/src/main/scala/CPU.scala b/src/main/scala/CPU.scala index fa99e76..8caf1f4 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).io + val IDBarrier = Module(new IDBarrier).io + val EXBarrier = Module(new EXBarrier).io + val MEMBarrier = Module(new MEMBarrier).io val ID = Module(new InstructionDecode) val IF = Module(new InstructionFetch) @@ -58,43 +58,47 @@ class CPU extends MultiIOModule { // The IF gets the instruction, but it won't be ready until the next cycle //printf(p"S1: PC=${Hexadecimal(IF.io.PC)} || ") + IFBarrier.in := IF.io // Stage 2 - ID.io.instruction := IF.io.instruction - //printf(p"S2: Opcode=${IF.io.instruction.opcode}, rd=${IF.io.instruction.registerRd}, rs1=${IF.io.instruction.registerRs1}, rs2=${IF.io.instruction.registerRs2} || ") + ID.io.instruction := IFBarrier.stage2.instruction + IDBarrier.in := ID.io // Stage 3 - EX.io.PC := ShiftRegister(IF.io.PC, 2) - EX.io.controlSignals := ID.io.controlSignals - EX.io.branchType := ID.io.branchType - EX.io.ALUop := ID.io.ALUop - EX.io.reg1 := ID.io.reg1 - EX.io.reg2 := ID.io.reg2 - EX.io.imm := ID.io.imm + EX.io.PC := IFBarrier.stage3.PC + EX.io.controlSignals := IDBarrier.stage3.controlSignals + EX.io.branchType := IDBarrier.stage3.branchType + EX.io.ALUop := IDBarrier.stage3.ALUop + EX.io.reg1 := IDBarrier.stage3.reg1 + EX.io.reg2 := IDBarrier.stage3.reg2 + EX.io.imm := IDBarrier.stage3.imm + + EXBarrier.in := EX.io //printf(p"S3: ALUop=${ID.io.ALUop}, reg1=${ID.io.reg1.asSInt}, reg2=${ID.io.reg2.asSInt}, imm=${ID.io.imm.asSInt} || ") // Stage 4 - MEM.io.dataIn := ShiftRegister(ID.io.reg2, 1) - MEM.io.dataAddress := EX.io.result - MEM.io.writeEnable := ShiftRegister(ID.io.controlSignals.memWrite, 1) + MEM.io.dataIn := IDBarrier.stage4.reg2 + MEM.io.writeEnable := IDBarrier.stage4.controlSignals.memWrite + MEM.io.dataAddress := EXBarrier.stage4.result - IF.io.jumpEnable := EX.io.branch - IF.io.jumpAddr := EX.io.result + IF.io.jumpEnable := EXBarrier.stage4.branch + IF.io.jumpAddr := EXBarrier.stage4.result + + MEMBarrier.in := MEM.io //printf(p"S4: res=${EX.io.result} || ") // Stage 5 - val exResult = ShiftRegister(EX.io.result, 1) // From stage 4 - ID.io.writeEnable := ShiftRegister(ID.io.controlSignals.regWrite, 2) // From stage 3 - ID.io.writeAddr := ShiftRegister(IF.io.instruction.registerRd, 3) // From stage 2 - ID.io.writeData := exResult + ID.io.writeEnable := IDBarrier.stage5.controlSignals.regWrite + ID.io.writeAddr := IFBarrier.stage5.instruction.registerRd + ID.io.writeData := EXBarrier.stage5.result - when (ShiftRegister(ID.io.controlSignals.memToReg, 2)) { - ID.io.writeData := MEM.io.dataOut + when (IDBarrier.stage5.controlSignals.memToReg) { + ID.io.writeData := MEMBarrier.stage5.dataOut } - when (ShiftRegister(ID.io.controlSignals.jump, 2)) { - ID.io.writeData := ShiftRegister(IF.io.PC, 4) + 4.U + when (IDBarrier.stage5.controlSignals.jump) { + ID.io.writeData := IFBarrier.stage5.PC + 4.U } //printf(p"S5: WB=${ID.io.writeData}")