TDT4255/src/main/scala/CPU.scala

141 lines
4.8 KiB
Scala

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
}