| @@ -28,7 +28,7 @@ class CPU extends MultiIOModule { | |||||
| val ID = Module(new InstructionDecode) | val ID = Module(new InstructionDecode) | ||||
| val IF = Module(new InstructionFetch) | val IF = Module(new InstructionFetch) | ||||
| // val EX = Module(new Execute) | |||||
| val EX = Module(new Execute) | |||||
| val MEM = Module(new MemoryFetch) | val MEM = Module(new MemoryFetch) | ||||
| // val WB = Module(new Execute) (You may not need this one?) | // val WB = Module(new Execute) (You may not need this one?) | ||||
| @@ -54,4 +54,11 @@ class CPU extends MultiIOModule { | |||||
| /** | /** | ||||
| TODO: Your code here | TODO: Your code here | ||||
| */ | */ | ||||
| ID.io.PC := IF.io.PC | |||||
| ID.io.instruction := IF.io.instruction | |||||
| EX.io.ALUop := ID.io.ALUop | |||||
| EX.io.data1 := ID.io.data1 | |||||
| EX.io.data2 := ID.io.data2 | |||||
| ID.io.regWriteData := EX.io.result | |||||
| } | } | ||||
| @@ -52,6 +52,7 @@ class Decoder() extends Module { | |||||
| SW -> List(N, N, N, Y, N, N, branchType.DC, rs1, imm, STYPE, ALUOps.ADD), | SW -> List(N, N, N, Y, N, N, branchType.DC, rs1, imm, STYPE, ALUOps.ADD), | ||||
| ADD -> List(N, Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.ADD), | ADD -> List(N, Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.ADD), | ||||
| ADDI -> List(N, Y, N, N, N, N, branchType.DC, rs1, imm, ITYPE, ALUOps.ADD), | |||||
| SUB -> List(N, Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.SUB), | SUB -> List(N, Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.SUB), | ||||
| /** | /** | ||||
| @@ -0,0 +1,41 @@ | |||||
| package FiveStage | |||||
| import chisel3._ | |||||
| import chisel3.util._ | |||||
| class Execute extends Module { | |||||
| val io = IO( | |||||
| new Bundle { | |||||
| val ALUop = Input(UInt(4.W)) | |||||
| val data1 = Input(UInt(32.W)) | |||||
| val data2 = Input(UInt(32.W)) | |||||
| val result = Output(UInt(32.W)) | |||||
| }) | |||||
| val data1S = io.data1.asSInt | |||||
| val data2S = io.data2.asSInt | |||||
| val data1U = io.data1.asUInt | |||||
| val data2U = io.data2.asUInt | |||||
| val ALUopMap = Array( | |||||
| ALUOps.ADD -> (data1S + data2S).asUInt, | |||||
| ALUOps.SUB -> (data1S - data2S).asUInt, | |||||
| ALUOps.AND -> (data1U & data2U), | |||||
| ALUOps.OR -> (data1U | data2U), | |||||
| ALUOps.XOR -> (data1U ^ data2U), | |||||
| // TODO: SLT. Set GPR? | |||||
| //ALUOps.SLT -> (data1S < data2S).asUInt, | |||||
| //ALUOps.SLTU -> (data1U < data2U), | |||||
| //ALUOps.SLL -> (data1S << data2U).asUInt, | |||||
| //ALUOps.SRL -> (data1S >> data2U).asUInt, | |||||
| //ALUOps.SRA -> (data1S >> data2U).asUInt, // TODO: SRA sign-extend? | |||||
| //ALUOps.COPY_A -> (data1U), | |||||
| //ALUOps.COPY_B -> (data2U), | |||||
| ) | |||||
| io.result := MuxLookup( | |||||
| io.ALUop, | |||||
| 0.U(32.W), | |||||
| ALUopMap, | |||||
| ) | |||||
| } | |||||
| @@ -1,6 +1,6 @@ | |||||
| package FiveStage | package FiveStage | ||||
| import chisel3._ | import chisel3._ | ||||
| import chisel3.util.{ BitPat, MuxCase } | |||||
| import chisel3.util._ | |||||
| import chisel3.experimental.MultiIOModule | import chisel3.experimental.MultiIOModule | ||||
| @@ -21,6 +21,14 @@ class InstructionDecode extends MultiIOModule { | |||||
| /** | /** | ||||
| * TODO: Your code here. | * TODO: Your code here. | ||||
| */ | */ | ||||
| val PC = Input(UInt(32.W)) | |||||
| val instruction = Input(new Instruction) | |||||
| val regWriteData = Input(UInt(32.W)) | |||||
| val controlSignals = Output(new ControlSignals) | |||||
| val data1 = Output(UInt(32.W)) | |||||
| val data2 = Output(UInt(32.W)) | |||||
| val ALUop = Output(UInt(4.W)) | |||||
| } | } | ||||
| ) | ) | ||||
| @@ -39,11 +47,47 @@ class InstructionDecode extends MultiIOModule { | |||||
| /** | /** | ||||
| * TODO: Your code here. | * TODO: Your code here. | ||||
| */ | */ | ||||
| registers.io.readAddress1 := 0.U | |||||
| registers.io.readAddress2 := 0.U | |||||
| registers.io.writeEnable := false.B | |||||
| registers.io.writeAddress := 0.U | |||||
| registers.io.writeData := 0.U | |||||
| decoder.instruction := io.instruction | |||||
| registers.io.readAddress1 := io.instruction.registerRs1 | |||||
| registers.io.readAddress2 := io.instruction.registerRs2 | |||||
| registers.io.writeEnable := decoder.controlSignals.regWrite | |||||
| registers.io.writeAddress := io.instruction.registerRd | |||||
| registers.io.writeData := io.regWriteData | |||||
| io.controlSignals := decoder.controlSignals | |||||
| io.ALUop := decoder.ALUop | |||||
| io.data1 := 0.U | |||||
| io.data2 := 0.U | |||||
| decoder.instruction := 0.U.asTypeOf(new Instruction) | |||||
| switch (decoder.op1Select) { | |||||
| is (Op1Select.rs1) { | |||||
| io.data1 := registers.io.readData1 | |||||
| } | |||||
| is (Op1Select.PC) { | |||||
| io.data1 := io.PC | |||||
| } | |||||
| } | |||||
| switch (decoder.op2Select) { | |||||
| is (Op2Select.rs2) { | |||||
| io.data2 := registers.io.readData2 | |||||
| } | |||||
| is (Op2Select.imm) { | |||||
| val immTypeMap = Array( | |||||
| ImmFormat.ITYPE -> io.instruction.immediateIType, | |||||
| ImmFormat.STYPE -> io.instruction.immediateSType, | |||||
| ImmFormat.BTYPE -> io.instruction.immediateBType, | |||||
| ImmFormat.UTYPE -> io.instruction.immediateUType, | |||||
| ImmFormat.JTYPE -> io.instruction.immediateJType, | |||||
| ImmFormat.SHAMT -> 0.S, // TODO: Implement SHAMT | |||||
| ) | |||||
| io.data2 := MuxLookup( | |||||
| decoder.immType, | |||||
| 0.S, | |||||
| immTypeMap, | |||||
| ).pad(32).asUInt | |||||
| } | |||||
| } | |||||
| } | } | ||||
| @@ -19,6 +19,7 @@ class InstructionFetch extends MultiIOModule { | |||||
| val io = IO( | val io = IO( | ||||
| new Bundle { | new Bundle { | ||||
| val PC = Output(UInt()) | val PC = Output(UInt()) | ||||
| val instruction = Output(new Instruction) | |||||
| }) | }) | ||||
| val IMEM = Module(new IMEM) | val IMEM = Module(new IMEM) | ||||
| @@ -37,15 +38,12 @@ class InstructionFetch extends MultiIOModule { | |||||
| * | * | ||||
| * You should expand on or rewrite the code below. | * You should expand on or rewrite the code below. | ||||
| */ | */ | ||||
| io.PC := PC | |||||
| IMEM.io.instructionAddress := PC | IMEM.io.instructionAddress := PC | ||||
| // PC := PC + 4.U | |||||
| val instruction = Wire(new Instruction) | |||||
| instruction := IMEM.io.instruction.asTypeOf(new Instruction) | |||||
| PC := PC + 4.U | |||||
| io.PC := PC | |||||
| io.instruction := IMEM.io.instruction.asTypeOf(new Instruction) | |||||
| /** | /** | ||||
| @@ -18,7 +18,8 @@ import LogParser._ | |||||
| object Manifest { | object Manifest { | ||||
| val singleTest = "forward2.s" | |||||
| // TODO: Change back after add test succedes | |||||
| val singleTest = "addi.s" //"forward2.s" | |||||
| val nopPadded = true | val nopPadded = true | ||||