package FiveStage import chisel3._ import chisel3.util.{BitPat, MuxCase, MuxLookup} import chisel3.experimental.MultiIOModule class InstructionDecode extends MultiIOModule { // Don't touch the test harness val testHarness = IO( new Bundle { val registerSetup = Input(new RegisterSetupSignals) val registerPeek = Output(UInt(32.W)) val testUpdates = Output(new RegisterUpdates) }) val io = IO( new Bundle { val instruction = Input(new Instruction) val pc = Input(UInt(32.W)) val op1 = Output(SInt(32.W)) val isOp1RValue = Output(Bool()) val op2 = Output(SInt(32.W)) val isOp2RValue = Output(Bool()) val r1Value = Output(UInt(32.W)) val r1Address = Output(UInt(5.W)) val r2Value = Output(UInt(32.W)) val r2Address = Output(UInt(5.W)) val ALUOp = Output(UInt(4.W)) val writeAddrIn = Input(UInt(5.W)) val writeAddrOut = Output(UInt(5.W)) val writeEnableIn = Input(Bool()) val writeEnableOut = Output(Bool()) val writeData = Input(UInt(32.W)) val memWrite = Output(Bool()) val memRead = Output(Bool()) val branchType = Output(UInt(3.W)) val jump = Output(Bool()) val returnAddr = Output(UInt(32.W)) val stall = Output(Bool()) } ) val registers = Module(new Registers) val decoder = Module(new Decoder).io registers.testHarness.setup := testHarness.registerSetup testHarness.registerPeek := registers.io.readData1 testHarness.testUpdates := registers.testHarness.testUpdates registers.io.readAddress1 := io.instruction.registerRs1 registers.io.readAddress2 := io.instruction.registerRs2 registers.io.writeEnable := io.writeEnableIn registers.io.writeAddress := io.writeAddrIn registers.io.writeData := io.writeData decoder.instruction := io.instruction val select1Map = Array( Op1Select.rs1 -> registers.io.readData1.asSInt(), Op1Select.PC -> io.pc.asSInt(), ) io.op1 := MuxLookup(decoder.op1Select, 0.S(32.W), select1Map) val select2ImmMap = Array( ImmFormat.ITYPE -> decoder.instruction.immediateIType, ImmFormat.STYPE -> decoder.instruction.immediateSType, ImmFormat.BTYPE -> decoder.instruction.immediateBType, ImmFormat.UTYPE -> decoder.instruction.immediateUType, ImmFormat.JTYPE -> decoder.instruction.immediateJType, ImmFormat.SHAMT -> decoder.instruction.immediateZType, ) val select2Map = Array( Op2Select.imm -> MuxLookup(decoder.immType, 0.S(32.W), select2ImmMap), Op2Select.rs2 -> registers.io.readData2.asSInt(), ) io.op2 := MuxLookup(decoder.op2Select, 0.S(32.W), select2Map) io.isOp1RValue := decoder.op1Select === Op1Select.rs1 io.r1Value := registers.io.readData1 io.r1Address := registers.io.readAddress1 io.isOp2RValue := decoder.op2Select === Op2Select.rs2 io.r2Value := registers.io.readData2 io.r2Address := registers.io.readAddress2 io.ALUOp := decoder.ALUop io.branchType := decoder.branchType io.writeAddrOut := decoder.instruction.registerRd val stallDelay = RegInit(Bool(), false.B) val stall = Mux(stallDelay, false.B, decoder.controlSignals.memRead) io.stall := stall stallDelay := stall io.jump := Mux(stallDelay, false.B, decoder.controlSignals.jump) io.returnAddr := io.pc + 4.U io.writeEnableOut := Mux(stallDelay, false.B, decoder.controlSignals.regWrite) io.memRead := Mux(stallDelay, false.B, decoder.controlSignals.memRead) io.memWrite := Mux(stallDelay, false.B, decoder.controlSignals.memWrite) }