112 lines
7.2 KiB
Scala
112 lines
7.2 KiB
Scala
package FiveStage
|
|
import chisel3._
|
|
import chisel3.util.BitPat
|
|
import chisel3.util.ListLookup
|
|
|
|
|
|
/**
|
|
* This module is mostly done, but you will have to fill in the blanks in opcodeMap.
|
|
* You may want to add more signals to be decoded in this module depending on your
|
|
* design if you so desire.
|
|
*
|
|
* In the "classic" 5 stage decoder signals such as op1select and immType
|
|
* are not included, however I have added them to my design, and similarily you might
|
|
* find it useful to add more
|
|
*/
|
|
class Decoder() extends Module {
|
|
|
|
val io = IO(new Bundle {
|
|
val instruction = Input(new Instruction)
|
|
|
|
val controlSignals = Output(new ControlSignals)
|
|
val branchType = Output(UInt(3.W))
|
|
val op1Select = Output(UInt(1.W))
|
|
val op2Select = Output(UInt(1.W))
|
|
val immType = Output(UInt(3.W))
|
|
val ALUop = Output(UInt(4.W))
|
|
})
|
|
|
|
import lookup._
|
|
import Op1Select._
|
|
import Op2Select._
|
|
import branchType._
|
|
import ImmFormat._
|
|
|
|
val N = 0.asUInt(1.W)
|
|
val Y = 1.asUInt(1.W)
|
|
|
|
/**
|
|
* In scala we sometimes (ab)use the `->` operator to create tuples.
|
|
* The reason for this is that it serves as convenient sugar to make maps.
|
|
*
|
|
* This doesn't matter to you, just fill in the blanks in the style currently
|
|
* used, I just want to demystify some of the scala magic.
|
|
*
|
|
* `a -> b` == `(a, b)` == `Tuple2(a, b)`
|
|
*/
|
|
val opcodeMap: Array[(BitPat, List[UInt])] = Array(
|
|
|
|
// signal regWrite, memRead, memWrite, branch, jump, branchType, Op1Select, Op2Select, ImmSelect, ALUOp
|
|
ADD -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.ADD ),
|
|
SUB -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.SUB ),
|
|
AND -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.AND ),
|
|
OR -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.OR ),
|
|
XOR -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.XOR ),
|
|
SLT -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.SLT ),
|
|
SLTU -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.SLTU ),
|
|
SRA -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.SRA ),
|
|
SRL -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.SRL ),
|
|
SLL -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.SLL ),
|
|
|
|
// signal regWrite, memRead, memWrite, branch, jump, branchType, Op1Select, Op2Select, ImmSelect, ALUOp
|
|
ADDI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.ADD ),
|
|
ANDI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.AND ),
|
|
ORI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.OR ),
|
|
XORI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.XOR ),
|
|
SLTI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.SLT ),
|
|
SLTIU -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.SLTU ),
|
|
SRAI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.SRA ),
|
|
SRLI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.SRL ),
|
|
SLLI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.SLL ),
|
|
|
|
// signal regWrite, memRead, memWrite, branch, jump, branchType, Op1Select, Op2Select, ImmSelect, ALUOp
|
|
LUI -> List(Y, N, N, N, N, branchType.DC, Op1Select.DC, imm, ImmFormat.UTYPE, ALUOps.COPY_B),
|
|
AUIPC -> List(Y, N, N, N, N, branchType.DC, Op1Select.PC, imm, ImmFormat.UTYPE, ALUOps.ADD ),
|
|
|
|
// signal regWrite, memRead, memWrite, branch, jump, branchType, Op1Select, Op2Select, ImmSelect, ALUOp
|
|
LW -> List(Y, Y, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.ADD ),
|
|
SW -> List(N, N, Y, N, N, branchType.DC, rs1, imm, ImmFormat.STYPE, ALUOps.ADD ),
|
|
|
|
// signal regWrite, memRead, memWrite, branch, jump, branchType, Op1Select, Op2Select, ImmSelect, ALUOp
|
|
BEQ -> List(N, N, N, Y, N, branchType.beq, PC, imm, ImmFormat.BTYPE, ALUOps.ADD ),
|
|
BNE -> List(N, N, N, Y, N, branchType.neq, PC, imm, ImmFormat.BTYPE, ALUOps.ADD ),
|
|
BLT -> List(N, N, N, Y, N, branchType.lt, PC, imm, ImmFormat.BTYPE, ALUOps.ADD ),
|
|
BGE -> List(N, N, N, Y, N, branchType.gte, PC, imm, ImmFormat.BTYPE, ALUOps.ADD ),
|
|
BLTU -> List(N, N, N, Y, N, branchType.ltu, PC, imm, ImmFormat.BTYPE, ALUOps.ADD ),
|
|
BGEU -> List(N, N, N, Y, N, branchType.gteu, PC, imm, ImmFormat.BTYPE, ALUOps.ADD ),
|
|
|
|
// signal regWrite, memRead, memWrite, branch, jump, branchType, Op1Select, Op2Select, ImmSelect, ALUOp
|
|
JAL -> List(Y, N, N, Y, Y, branchType.jump, PC, imm, ImmFormat.JTYPE, ALUOps.ADD ),
|
|
JALR -> List(Y, N, N, Y, Y, branchType.jump, rs1, imm, ImmFormat.ITYPE, ALUOps.ADDR ),
|
|
)
|
|
|
|
|
|
val NOP = List(N, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.DC)
|
|
|
|
val decodedControlSignals = ListLookup(
|
|
io.instruction.asUInt(),
|
|
NOP,
|
|
opcodeMap)
|
|
|
|
io.controlSignals.regWrite := decodedControlSignals(0)
|
|
io.controlSignals.memRead := decodedControlSignals(1)
|
|
io.controlSignals.memWrite := decodedControlSignals(2)
|
|
io.controlSignals.branch := decodedControlSignals(3)
|
|
io.controlSignals.jump := decodedControlSignals(4)
|
|
|
|
io.branchType := decodedControlSignals(5)
|
|
io.op1Select := decodedControlSignals(6)
|
|
io.op2Select := decodedControlSignals(7)
|
|
io.immType := decodedControlSignals(8)
|
|
io.ALUop := decodedControlSignals(9)
|
|
}
|