Initial Chisel core implementation
This commit is contained in:
150
src/main/scala/decode/Decoder.scala
Normal file
150
src/main/scala/decode/Decoder.scala
Normal file
@@ -0,0 +1,150 @@
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
class Decoder(p: CoreParams = CoreParams()) extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val pc = Input(UInt(p.xlen.W))
|
||||
val inst = Input(UInt(32.W))
|
||||
val out = Output(new DecodedInst(p))
|
||||
})
|
||||
|
||||
val opcode = io.inst(6, 0)
|
||||
val rd = io.inst(11, 7)
|
||||
val funct3 = io.inst(14, 12)
|
||||
val rs1 = io.inst(19, 15)
|
||||
val rs2 = io.inst(24, 20)
|
||||
val funct7 = io.inst(31, 25)
|
||||
|
||||
val immI = Consts.signExtend(io.inst(31, 20), 12)
|
||||
val immS = Consts.signExtend(Cat(io.inst(31, 25), io.inst(11, 7)), 12)
|
||||
val immB = Consts.signExtend(Cat(io.inst(31), io.inst(7), io.inst(30, 25), io.inst(11, 8), 0.U(1.W)), 13)
|
||||
val immU = Consts.signExtend(Cat(io.inst(31, 12), 0.U(12.W)), 32)
|
||||
val immJ = Consts.signExtend(Cat(io.inst(31), io.inst(19, 12), io.inst(20), io.inst(30, 21), 0.U(1.W)), 21)
|
||||
|
||||
val d = WireDefault(0.U.asTypeOf(new DecodedInst(p)))
|
||||
d.valid := true.B
|
||||
d.pc := io.pc
|
||||
d.inst := io.inst
|
||||
d.rs1 := rs1
|
||||
d.rs2 := rs2
|
||||
d.rd := rd
|
||||
d.funct3 := funct3
|
||||
d.funct7 := funct7
|
||||
d.immI := immI
|
||||
d.immS := immS
|
||||
d.immB := immB
|
||||
d.immU := immU
|
||||
d.immJ := immJ
|
||||
d.memWidth := MuxLookup(funct3, 3.U)(Seq(
|
||||
"b000".U -> 0.U,
|
||||
"b001".U -> 1.U,
|
||||
"b010".U -> 2.U,
|
||||
"b011".U -> 3.U,
|
||||
"b100".U -> 0.U,
|
||||
"b101".U -> 1.U,
|
||||
"b110".U -> 2.U
|
||||
))
|
||||
d.memSigned := !funct3(2)
|
||||
d.illegal := false.B
|
||||
|
||||
switch(opcode) {
|
||||
is("b0110111".U) {
|
||||
d.isLui := true.B
|
||||
d.writesRd := rd =/= 0.U
|
||||
d.opClass := Consts.OP_ALU
|
||||
d.aluFn := Consts.ALU_COPY_B
|
||||
}
|
||||
is("b0010111".U) {
|
||||
d.isAuipc := true.B
|
||||
d.writesRd := rd =/= 0.U
|
||||
d.opClass := Consts.OP_ALU
|
||||
d.aluFn := Consts.ALU_ADD
|
||||
}
|
||||
is("b1101111".U) {
|
||||
d.isJal := true.B
|
||||
d.writesRd := rd =/= 0.U
|
||||
d.opClass := Consts.OP_BRANCH
|
||||
}
|
||||
is("b1100111".U) {
|
||||
d.isJalr := true.B
|
||||
d.writesRd := rd =/= 0.U
|
||||
d.opClass := Consts.OP_BRANCH
|
||||
}
|
||||
is("b1100011".U) {
|
||||
d.isBranch := true.B
|
||||
d.opClass := Consts.OP_BRANCH
|
||||
}
|
||||
is("b0000011".U) {
|
||||
d.isLoad := true.B
|
||||
d.writesRd := rd =/= 0.U
|
||||
d.opClass := Consts.OP_LOAD
|
||||
}
|
||||
is("b0100011".U) {
|
||||
d.isStore := true.B
|
||||
d.opClass := Consts.OP_STORE
|
||||
}
|
||||
is("b0010011".U, "b0011011".U) {
|
||||
d.isOpImm := true.B
|
||||
d.isWord := opcode === "b0011011".U
|
||||
d.writesRd := rd =/= 0.U
|
||||
d.opClass := Consts.OP_ALU
|
||||
d.aluFn := MuxLookup(funct3, Consts.ALU_ADD)(Seq(
|
||||
"b000".U -> Consts.ALU_ADD,
|
||||
"b001".U -> Consts.ALU_SLL,
|
||||
"b010".U -> Consts.ALU_SLT,
|
||||
"b011".U -> Consts.ALU_SLTU,
|
||||
"b100".U -> Consts.ALU_XOR,
|
||||
"b101".U -> Mux(funct7(5), Consts.ALU_SRA, Consts.ALU_SRL),
|
||||
"b110".U -> Consts.ALU_OR,
|
||||
"b111".U -> Consts.ALU_AND
|
||||
))
|
||||
}
|
||||
is("b0110011".U, "b0111011".U) {
|
||||
d.isOp := true.B
|
||||
d.isWord := opcode === "b0111011".U
|
||||
d.writesRd := rd =/= 0.U
|
||||
d.opClass := Consts.OP_ALU
|
||||
d.aluFn := Mux(funct7 === "b0000001".U, MuxLookup(funct3, Consts.ALU_MUL)(Seq(
|
||||
"b000".U -> Consts.ALU_MUL,
|
||||
"b100".U -> Consts.ALU_DIV,
|
||||
"b101".U -> Consts.ALU_DIVU,
|
||||
"b110".U -> Consts.ALU_REM,
|
||||
"b111".U -> Consts.ALU_REMU
|
||||
)), MuxLookup(funct3, Consts.ALU_ADD)(Seq(
|
||||
"b000".U -> Mux(funct7(5), Consts.ALU_SUB, Consts.ALU_ADD),
|
||||
"b001".U -> Consts.ALU_SLL,
|
||||
"b010".U -> Consts.ALU_SLT,
|
||||
"b011".U -> Consts.ALU_SLTU,
|
||||
"b100".U -> Consts.ALU_XOR,
|
||||
"b101".U -> Mux(funct7(5), Consts.ALU_SRA, Consts.ALU_SRL),
|
||||
"b110".U -> Consts.ALU_OR,
|
||||
"b111".U -> Consts.ALU_AND
|
||||
)))
|
||||
}
|
||||
is("b0001111".U) {
|
||||
d.opClass := Consts.OP_SYSTEM
|
||||
}
|
||||
is("b1110011".U) {
|
||||
d.isSystem := true.B
|
||||
d.writesRd := rd =/= 0.U && funct3 =/= 0.U
|
||||
d.opClass := Consts.OP_SYSTEM
|
||||
}
|
||||
is("b0101111".U) {
|
||||
d.isLoad := true.B
|
||||
d.isStore := true.B
|
||||
d.writesRd := rd =/= 0.U
|
||||
d.memWidth := Mux(funct3 === "b010".U, 2.U, 3.U)
|
||||
d.opClass := Consts.OP_LOAD
|
||||
}
|
||||
}
|
||||
|
||||
when(opcode =/= "b0110111".U && opcode =/= "b0010111".U && opcode =/= "b1101111".U &&
|
||||
opcode =/= "b1100111".U && opcode =/= "b1100011".U && opcode =/= "b0000011".U &&
|
||||
opcode =/= "b0100011".U && opcode =/= "b0010011".U && opcode =/= "b0011011".U &&
|
||||
opcode =/= "b0110011".U && opcode =/= "b0111011".U && opcode =/= "b0001111".U &&
|
||||
opcode =/= "b1110011".U && opcode =/= "b0101111".U) {
|
||||
d.illegal := true.B
|
||||
}
|
||||
|
||||
io.out := d
|
||||
}
|
||||
Reference in New Issue
Block a user