package FiveStage import chisel3._ import chisel3.core.Input import chisel3.experimental.MultiIOModule import chisel3.experimental._ class CPU extends MultiIOModule { val testHarness = IO( new Bundle { val setupSignals = Input(new SetupSignals) val testReadouts = Output(new TestReadouts) val regUpdates = Output(new RegisterUpdates) val memUpdates = Output(new MemUpdates) val currentPC = Output(UInt(32.W)) } ) /** 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 ID = Module(new InstructionDecode) val IF = Module(new InstructionFetch) val EX = Module(new Execute) val MEM = Module(new MemoryFetch) // val WB = Module(new Execute) (You may not need this one?) /** * Setup. You should not change this code */ IF.testHarness.IMEMsetup := testHarness.setupSignals.IMEMsignals ID.testHarness.registerSetup := testHarness.setupSignals.registerSignals MEM.testHarness.DMEMsetup := testHarness.setupSignals.DMEMsignals testHarness.testReadouts.registerRead := ID.testHarness.registerPeek testHarness.testReadouts.DMEMread := MEM.testHarness.DMEMpeek /** spying stuff */ testHarness.regUpdates := ID.testHarness.testUpdates testHarness.memUpdates := MEM.testHarness.testUpdates testHarness.currentPC := IF.testHarness.PC /** TODO: Your code here */ def forward(data: UInt, addr: UInt, useForward: Bool, mem: Forwarding, wb: Forwarding, id: Forwarding): UInt = { Mux( !useForward, data, Mux( mem.valid && mem.writeAddr === addr, mem.writeData, Mux( wb.valid && wb.writeAddr === addr, wb.writeData, Mux( id.valid && id.writeAddr === addr, id.writeData, data, ) ) ) ) } IFBarrier.PCin := IF.io.PC IFBarrier.instructionIn := IF.io.instruction ID.io.instruction := IFBarrier.instructionOut ID.io.pc := IFBarrier.PCout IDBarrier.in.op1 := ID.io.op1 IDBarrier.in.op2 := ID.io.op2 IDBarrier.in.isOp1RValue := ID.io.isOp1RValue IDBarrier.in.isOp2RValue := ID.io.isOp2RValue IDBarrier.in.r1Value := ID.io.r1Value IDBarrier.in.r2Value := ID.io.r2Value IDBarrier.in.r1Address := ID.io.r1Address IDBarrier.in.r2Address := ID.io.r2Address IDBarrier.in.ALUop := ID.io.ALUOp IDBarrier.in.returnAddr := ID.io.returnAddr IDBarrier.in.jump := ID.io.jump IDBarrier.in.branchType := ID.io.branchType IDBarrier.in.writeEnable := ID.io.writeEnableOut IDBarrier.in.writeAddr := ID.io.writeAddrOut IDBarrier.in.memWrite := ID.io.memWrite IDBarrier.in.memRead := ID.io.memRead EX.io.op1 := forward(IDBarrier.out.op1.asUInt(), IDBarrier.out.r1Address, IDBarrier.out.isOp1RValue, mem = MEMBarrier.forwardMem, wb = MEMBarrier.forwardWb, id = MEMBarrier.forwardId).asSInt() EX.io.op2 := forward(IDBarrier.out.op2.asUInt(), IDBarrier.out.r2Address, IDBarrier.out.isOp2RValue, mem = MEMBarrier.forwardMem, wb = MEMBarrier.forwardWb, id = MEMBarrier.forwardId).asSInt() EX.io.ALUOp := IDBarrier.out.ALUop EX.io.branchType := IDBarrier.out.branchType EX.io.rs1ValueIn := forward(IDBarrier.out.r1Value, IDBarrier.out.r1Address, true.B, mem = MEMBarrier.forwardMem, wb = MEMBarrier.forwardWb, id = MEMBarrier.forwardId).asSInt() EX.io.rs2ValueIn := forward(IDBarrier.out.r2Value, IDBarrier.out.r2Address, true.B, mem = MEMBarrier.forwardMem, wb = MEMBarrier.forwardWb, id = MEMBarrier.forwardId).asSInt() EXBarrier.in.r2Value := EX.io.rs2ValueOut.asUInt() EXBarrier.in.ALUResult := EX.io.ALUResult.asUInt() EXBarrier.in.branch := EX.io.branch EXBarrier.in.jump := IDBarrier.out.jump EXBarrier.in.returnAddr := IDBarrier.out.returnAddr EXBarrier.in.writeEnable := IDBarrier.out.writeEnable EXBarrier.in.writeAddr := IDBarrier.out.writeAddr EXBarrier.in.memWrite := IDBarrier.out.memWrite EXBarrier.in.memRead := IDBarrier.out.memRead MEM.io.ALUResult := EXBarrier.out.ALUResult MEM.io.jump := EXBarrier.out.jump MEM.io.returnAddr := EXBarrier.out.returnAddr MEM.io.writeMem := EXBarrier.out.memWrite MEM.io.readMem := EXBarrier.out.memRead MEM.io.writeData := EXBarrier.out.r2Value MEMBarrier.memRead := EXBarrier.out.memRead MEMBarrier.in.data := MEM.io.dataOut MEMBarrier.in.writeEnable := EXBarrier.out.writeEnable MEMBarrier.in.writeAddr := EXBarrier.out.writeAddr // Write back ID.io.writeData := MEMBarrier.out.data ID.io.writeEnableIn := MEMBarrier.out.writeEnable ID.io.writeAddrIn := MEMBarrier.out.writeAddr // Branching IF.io.branch := EXBarrier.out.branch IF.io.branchAddress := EXBarrier.out.ALUResult // Stall IF.io.stall := IDBarrier.stall || ID.io.stall IFBarrier.stall := IDBarrier.stall }