| @@ -5,92 +5,78 @@ import chisel3.util.ShiftRegister | |||||
| class IFBarrier extends Module { | class IFBarrier extends Module { | ||||
| class IFBundle extends Bundle { | |||||
| val PC = UInt() | |||||
| val instruction = new Instruction | |||||
| } | |||||
| val io = IO(new Bundle { | 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 | |||||
| }) | |||||
| val in = Input(new IFBundle) | |||||
| val out = Output(new IFBundle) | |||||
| }) | }) | ||||
| io.stage2 := io.in | |||||
| io.stage3 := ShiftRegister(io.in, 1) | |||||
| io.stage5 := ShiftRegister(io.in, 3) | |||||
| io.out.instruction := io.in.instruction | |||||
| io.out.PC := ShiftRegister(io.in.PC, 1) | |||||
| } | } | ||||
| class IDBarrier extends Module { | 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) | |||||
| } | |||||
| val io = IO(new Bundle { | 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) | |||||
| }) | |||||
| val in = Input(new IDBundle) | |||||
| val out = Output(new IDBundle) | |||||
| }) | }) | ||||
| io.stage3 := io.in | |||||
| io.stage4 := ShiftRegister(io.in, 1) | |||||
| io.stage5 := ShiftRegister(io.in, 2) | |||||
| io.out := ShiftRegister(io.in, 1) | |||||
| } | } | ||||
| class EXBarrier extends Module { | 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() | |||||
| } | |||||
| val io = IO(new Bundle { | 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) | |||||
| }) | |||||
| val in = Input(new EXBundle) | |||||
| val out = Output(new EXBundle) | |||||
| }) | }) | ||||
| io.stage4 := io.in | |||||
| io.stage5 := ShiftRegister(io.in, 1) | |||||
| io.out := ShiftRegister(io.in, 1) | |||||
| } | } | ||||
| class MEMBarrier extends Module { | 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) | |||||
| } | |||||
| val io = IO(new Bundle { | 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) | |||||
| }) | |||||
| val in = Input(new MEMBundle) | |||||
| val out = Output(new MEMBundle) | |||||
| }) | }) | ||||
| io.stage5 := io.in | |||||
| 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 | |||||
| } | } | ||||
| @@ -55,53 +55,59 @@ class CPU extends MultiIOModule { | |||||
| TODO: Your code here | TODO: Your code here | ||||
| */ | */ | ||||
| // Stage 1 | // Stage 1 | ||||
| // 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 | IFBarrier.in := IF.io | ||||
| // Stage 2 | // Stage 2 | ||||
| ID.io.instruction := IFBarrier.stage2.instruction | |||||
| IDBarrier.in := ID.io | |||||
| ID.io.instruction := IFBarrier.out.instruction | |||||
| IDBarrier.in.instruction := IFBarrier.out.instruction | |||||
| IDBarrier.in.PC := IFBarrier.out.PC | |||||
| IDBarrier.in.controlSignals := ID.io.controlSignals | |||||
| IDBarrier.in.branchType := ID.io.branchType | |||||
| IDBarrier.in.reg1 := ID.io.reg1 | |||||
| IDBarrier.in.reg2 := ID.io.reg2 | |||||
| IDBarrier.in.imm := ID.io.imm | |||||
| IDBarrier.in.ALUop := ID.io.ALUop | |||||
| // Stage 3 | // Stage 3 | ||||
| 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} || ") | |||||
| 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.imm := IDBarrier.out.imm | |||||
| EX.io.ALUop := IDBarrier.out.ALUop | |||||
| EXBarrier.in.PC := IDBarrier.out.PC | |||||
| EXBarrier.in.instruction := IDBarrier.out.instruction | |||||
| EXBarrier.in.controlSignals := IDBarrier.out.controlSignals | |||||
| EXBarrier.in.reg2 := IDBarrier.out.reg2 | |||||
| EXBarrier.in.result := EX.io.result | |||||
| EXBarrier.in.branch := EX.io.branch | |||||
| // Stage 4 | // Stage 4 | ||||
| MEM.io.dataIn := IDBarrier.stage4.reg2 | |||||
| MEM.io.writeEnable := IDBarrier.stage4.controlSignals.memWrite | |||||
| MEM.io.dataAddress := EXBarrier.stage4.result | |||||
| IF.io.jumpEnable := EXBarrier.stage4.branch | |||||
| IF.io.jumpAddr := EXBarrier.stage4.result | |||||
| MEM.io.dataIn := EXBarrier.out.reg2 | |||||
| MEM.io.writeEnable := EXBarrier.out.controlSignals.memWrite | |||||
| MEM.io.dataAddress := EXBarrier.out.result | |||||
| MEMBarrier.in := MEM.io | |||||
| IF.io.jumpEnable := EXBarrier.out.branch | |||||
| IF.io.jumpAddr := EXBarrier.out.result | |||||
| //printf(p"S4: res=${EX.io.result} || ") | |||||
| MEMBarrier.in.PC := EXBarrier.out.PC | |||||
| MEMBarrier.in.instruction := EXBarrier.out.instruction | |||||
| MEMBarrier.in.controlSignals := EXBarrier.out.controlSignals | |||||
| MEMBarrier.in.result := EXBarrier.out.result | |||||
| MEMBarrier.in.dataOut := MEM.io.dataOut | |||||
| // Stage 5 | // Stage 5 | ||||
| ID.io.writeEnable := IDBarrier.stage5.controlSignals.regWrite | |||||
| ID.io.writeAddr := IFBarrier.stage5.instruction.registerRd | |||||
| ID.io.writeData := EXBarrier.stage5.result | |||||
| ID.io.writeEnable := MEMBarrier.out.controlSignals.regWrite | |||||
| ID.io.writeAddr := MEMBarrier.out.instruction.registerRd | |||||
| ID.io.writeData := MEMBarrier.out.result | |||||
| when (IDBarrier.stage5.controlSignals.memToReg) { | |||||
| ID.io.writeData := MEMBarrier.stage5.dataOut | |||||
| when (MEMBarrier.out.controlSignals.memToReg) { | |||||
| ID.io.writeData := MEMBarrier.out.dataOut | |||||
| } | } | ||||
| when (IDBarrier.stage5.controlSignals.jump) { | |||||
| ID.io.writeData := IFBarrier.stage5.PC + 4.U | |||||
| when (MEMBarrier.out.controlSignals.jump) { | |||||
| ID.io.writeData := MEMBarrier.out.PC + 4.U | |||||
| } | } | ||||
| //printf(p"S5: WB=${ID.io.writeData}") | |||||
| //printf("\n\n") | |||||
| } | } | ||||
| @@ -31,6 +31,6 @@ class Execute extends Module { | |||||
| comparator.data1 := io.reg1 | comparator.data1 := io.reg1 | ||||
| comparator.data2 := io.reg2 | comparator.data2 := io.reg2 | ||||
| io.result := ShiftRegister(alu.result, 1) | |||||
| io.branch := ShiftRegister(io.controlSignals.jump | (comparator.result & io.controlSignals.branch), 1) | |||||
| io.result := alu.result | |||||
| io.branch := io.controlSignals.jump | (comparator.result & io.controlSignals.branch) | |||||
| } | } | ||||
| @@ -38,14 +38,6 @@ class InstructionDecode extends MultiIOModule { | |||||
| val registers = Module(new Registers) | val registers = Module(new Registers) | ||||
| val decoder = Module(new Decoder).io | val decoder = Module(new Decoder).io | ||||
| val reg1 = RegInit(UInt(32.W), 0.U) | |||||
| val reg2 = RegInit(UInt(32.W), 0.U) | |||||
| val imm = RegInit(UInt(32.W), 0.U) | |||||
| val ALUop = RegInit(UInt(4.W), 0.U) | |||||
| val branchType = RegInit(UInt(3.W), 0.U) | |||||
| val controlSignals = Reg(new ControlSignals) | |||||
| /** | /** | ||||
| * Setup. You should not change this code | * Setup. You should not change this code | ||||
| */ | */ | ||||
| @@ -65,19 +57,12 @@ class InstructionDecode extends MultiIOModule { | |||||
| registers.io.writeAddress := io.writeAddr | registers.io.writeAddress := io.writeAddr | ||||
| registers.io.writeData := io.writeData | registers.io.writeData := io.writeData | ||||
| ALUop := decoder.ALUop | |||||
| io.ALUop := ALUop | |||||
| controlSignals := decoder.controlSignals | |||||
| io.controlSignals := controlSignals | |||||
| branchType := decoder.branchType | |||||
| io.branchType := branchType | |||||
| reg1 := registers.io.readData1 | |||||
| reg2 := registers.io.readData2 | |||||
| io.ALUop := decoder.ALUop | |||||
| io.controlSignals := decoder.controlSignals | |||||
| io.branchType := decoder.branchType | |||||
| io.reg1 := reg1 | |||||
| io.reg2 := reg2 | |||||
| io.imm := imm | |||||
| io.reg1 := registers.io.readData1 | |||||
| io.reg2 := registers.io.readData2 | |||||
| val immTypeMap = Array( | val immTypeMap = Array( | ||||
| @@ -89,7 +74,7 @@ class InstructionDecode extends MultiIOModule { | |||||
| ImmFormat.SHAMT -> 0.S, // TODO: Implement SHAMT | ImmFormat.SHAMT -> 0.S, // TODO: Implement SHAMT | ||||
| ) | ) | ||||
| imm := MuxLookup( | |||||
| io.imm := MuxLookup( | |||||
| decoder.immType, | decoder.immType, | ||||
| 0.S, | 0.S, | ||||
| immTypeMap, | immTypeMap, | ||||