| @@ -28,7 +28,7 @@ class CPU extends MultiIOModule { | |||
| val ID = Module(new InstructionDecode) | |||
| val IF = Module(new InstructionFetch) | |||
| // val EX = Module(new Execute) | |||
| val EX = Module(new Execute) | |||
| val MEM = Module(new MemoryFetch) | |||
| // val WB = Module(new Execute) (You may not need this one?) | |||
| @@ -54,4 +54,11 @@ class CPU extends MultiIOModule { | |||
| /** | |||
| 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), | |||
| 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), | |||
| /** | |||
| @@ -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 | |||
| import chisel3._ | |||
| import chisel3.util.{ BitPat, MuxCase } | |||
| import chisel3.util._ | |||
| import chisel3.experimental.MultiIOModule | |||
| @@ -21,6 +21,14 @@ class InstructionDecode extends MultiIOModule { | |||
| /** | |||
| * 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. | |||
| */ | |||
| 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( | |||
| new Bundle { | |||
| val PC = Output(UInt()) | |||
| val instruction = Output(new Instruction) | |||
| }) | |||
| val IMEM = Module(new IMEM) | |||
| @@ -37,15 +38,12 @@ class InstructionFetch extends MultiIOModule { | |||
| * | |||
| * You should expand on or rewrite the code below. | |||
| */ | |||
| io.PC := 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 { | |||
| val singleTest = "forward2.s" | |||
| // TODO: Change back after add test succedes | |||
| val singleTest = "addi.s" //"forward2.s" | |||
| val nopPadded = true | |||