103 lines
3.5 KiB
Scala
103 lines
3.5 KiB
Scala
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)
|
|
}
|