Stage 6: implementation, untested
This commit is contained in:
@@ -15,18 +15,29 @@ class CUInterface extends Bundle {
|
||||
}
|
||||
|
||||
object OpType extends ChiselEnum {
|
||||
val U, I = Value
|
||||
val U, I, IR = Value
|
||||
}
|
||||
|
||||
object OpCode extends ChiselEnum {
|
||||
// Type U
|
||||
val LUI = 0b0110111.U
|
||||
val AUIPC = 0b0010111.U
|
||||
val ADDI = 0b0010011.U
|
||||
|
||||
// Type I + Type IR
|
||||
|
||||
// Instruction format
|
||||
// xxx rd, rs1 imm
|
||||
// Perfomrs some operation with rs1 and immediate
|
||||
// and writes back to a register
|
||||
|
||||
// addi, andi, ori, xori, slli, srli, srai,
|
||||
// slti, sltiu
|
||||
val OpImm = 0b0010011.U
|
||||
|
||||
}
|
||||
|
||||
class ControlUnit() extends Module {
|
||||
import OpCode._
|
||||
|
||||
class ControlUnit() extends Module {
|
||||
val io = IO(new CUInterface())
|
||||
|
||||
io.reg_file_we := false.B
|
||||
@@ -34,26 +45,111 @@ class ControlUnit() extends Module {
|
||||
io.optype := OpType.U
|
||||
io.mux_alu_imm := true.B;
|
||||
io.mux_rega_pc := true.B;
|
||||
switch(io.instruction(6, 0)) {
|
||||
|
||||
// Decode instruction
|
||||
val opcode = io.instruction(6, 0);
|
||||
val funct3 = io.instruction(14, 12);
|
||||
val funct7 = io.instruction(31, 25);
|
||||
|
||||
switch(opcode) {
|
||||
|
||||
// U instructions
|
||||
is(LUI) {
|
||||
is(OpCode.LUI) {
|
||||
io.reg_file_we := true.B
|
||||
io.mux_alu_imm := false.B
|
||||
io.optype := OpType.U
|
||||
}
|
||||
is(AUIPC) {
|
||||
is(OpCode.AUIPC) {
|
||||
io.alu_opcode := AluOpCode.Add
|
||||
io.reg_file_we := true.B
|
||||
io.mux_rega_pc := false.B
|
||||
io.optype := OpType.U
|
||||
}
|
||||
|
||||
// I instructions
|
||||
is(ADDI) {
|
||||
io.alu_opcode := AluOpCode.Add
|
||||
// OpImm instructions
|
||||
is(OpCode.OpImm) {
|
||||
io.reg_file_we := true.B
|
||||
io.optype := OpType.I
|
||||
opImm(funct3, funct7, io);
|
||||
}
|
||||
}
|
||||
|
||||
// Implements functions for all instruction of the opImm kind
|
||||
def opImm(funct3: UInt, funct7: UInt, io: CUInterface) =
|
||||
{
|
||||
// Meaning of Funct3 in the context of an OpImm instruction
|
||||
object Funct3 extends ChiselEnum
|
||||
{
|
||||
// Type I
|
||||
val ADDI = 000.U
|
||||
val SLTI = 010.U
|
||||
val SLTIU = 011.U
|
||||
val XORI = 100.U
|
||||
val ORI = 110.U
|
||||
val ANDI = 111.U
|
||||
|
||||
// Type IR
|
||||
val SLLI = 001.U
|
||||
val SRLI_SRAI = 101.U // Right shifts
|
||||
}
|
||||
|
||||
// Meaning of Funct7 in the context of SHIFTR IR instructions
|
||||
object IRFunct7 extends ChiselEnum
|
||||
{
|
||||
val SRLI = 0000000.U
|
||||
val SRAI = 0100000.U
|
||||
}
|
||||
switch(funct3)
|
||||
{
|
||||
// Type I
|
||||
is(Funct3.ADDI)
|
||||
{
|
||||
io.alu_opcode := AluOpCode.Add
|
||||
io.optype := OpType.I
|
||||
}
|
||||
|
||||
is(Funct3.ANDI)
|
||||
{
|
||||
io.alu_opcode := AluOpCode.And
|
||||
io.optype := OpType.I
|
||||
}
|
||||
|
||||
is(Funct3.ORI)
|
||||
{
|
||||
io.alu_opcode := AluOpCode.Or
|
||||
io.optype := OpType.I
|
||||
}
|
||||
|
||||
is(Funct3.XORI)
|
||||
{
|
||||
io.alu_opcode := AluOpCode.Xor
|
||||
io.optype := OpType.I
|
||||
}
|
||||
|
||||
is(Funct3.SLLI)
|
||||
{
|
||||
io.alu_opcode := AluOpCode.ShiftLeft
|
||||
io.optype := OpType.I
|
||||
}
|
||||
|
||||
// Type IR
|
||||
is(Funct3.SRLI_SRAI)
|
||||
{
|
||||
io.optype := OpType.IR
|
||||
switch(funct7)
|
||||
{
|
||||
is(IRFunct7.SRLI)
|
||||
{
|
||||
io.alu_opcode := AluOpCode.ShiftRight
|
||||
}
|
||||
|
||||
is(IRFunct7.SRAI)
|
||||
{
|
||||
io.alu_opcode := AluOpCode.ShiftArithmeticRight
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user