Stage 7: Register to register operations, all tests passing
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
_start:
|
_start:
|
||||||
lui x2, 0xdead0
|
lui x2, 0xdead0
|
||||||
lui x3, 0x0
|
lui x3, 0x0
|
||||||
lui x4, 0x1
|
addi x4, x0, 0x1
|
||||||
addi x5, x0, (-1)
|
addi x5, x0, (-1)
|
||||||
|
|
||||||
# Add 0
|
# Add 0
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# expected: 00000000, 00000001, 00000001, 00000000
|
# expected: 00000000, 00000001, 00000000, 00000000
|
||||||
.text
|
.text
|
||||||
_start:
|
_start:
|
||||||
addi x1, x0, (-1)
|
addi x1, x0, (-1)
|
||||||
|
|||||||
@@ -10,8 +10,12 @@ class CUInterface extends Bundle {
|
|||||||
val alu_opcode = Output(AluOpCode())
|
val alu_opcode = Output(AluOpCode())
|
||||||
val optype = Output(OpType())
|
val optype = Output(OpType())
|
||||||
|
|
||||||
|
// Muxers
|
||||||
|
// The naming convention is as follows : mux_xxx_yyy.
|
||||||
|
// If the signal is hot, xxx is selected otherwise yyy is selected
|
||||||
val mux_alu_imm = Output(Bool())
|
val mux_alu_imm = Output(Bool())
|
||||||
val mux_rega_pc = Output(Bool())
|
val mux_rega_pc = Output(Bool())
|
||||||
|
val mux_regb_imm = Output(Bool())
|
||||||
}
|
}
|
||||||
|
|
||||||
object OpType extends ChiselEnum {
|
object OpType extends ChiselEnum {
|
||||||
@@ -26,7 +30,7 @@ object OpCode extends ChiselEnum {
|
|||||||
// Type I + Type IR
|
// Type I + Type IR
|
||||||
|
|
||||||
// Instruction format
|
// Instruction format
|
||||||
// xxx rd, rs1 imm
|
// xxx rd, rs1, imm
|
||||||
// Perfomrs some operation with rs1 and immediate
|
// Perfomrs some operation with rs1 and immediate
|
||||||
// and writes back to a register
|
// and writes back to a register
|
||||||
|
|
||||||
@@ -34,6 +38,14 @@ object OpCode extends ChiselEnum {
|
|||||||
// slti, sltiu
|
// slti, sltiu
|
||||||
val OpImm = 0b0010011.U
|
val OpImm = 0b0010011.U
|
||||||
|
|
||||||
|
// Instruction format
|
||||||
|
// xxx rd, rs1, rs2
|
||||||
|
// Perfomrs some operation with rs1 and rd2
|
||||||
|
// and writes back to a register
|
||||||
|
|
||||||
|
// add, and, or, xor, sll, srl, sra, slt, stlu
|
||||||
|
val OpR = 0b0110011.U;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -45,6 +57,7 @@ class ControlUnit() extends Module {
|
|||||||
io.optype := OpType.U
|
io.optype := OpType.U
|
||||||
io.mux_alu_imm := true.B;
|
io.mux_alu_imm := true.B;
|
||||||
io.mux_rega_pc := true.B;
|
io.mux_rega_pc := true.B;
|
||||||
|
io.mux_regb_imm := true.B;
|
||||||
|
|
||||||
// Decode instruction
|
// Decode instruction
|
||||||
val opcode = io.instruction(6, 0);
|
val opcode = io.instruction(6, 0);
|
||||||
@@ -55,14 +68,15 @@ class ControlUnit() extends Module {
|
|||||||
|
|
||||||
// U instructions
|
// U instructions
|
||||||
is(OpCode.LUI) {
|
is(OpCode.LUI) {
|
||||||
io.reg_file_we := true.B
|
io.reg_file_we := true.B // Write to regfile
|
||||||
io.mux_alu_imm := false.B
|
io.mux_alu_imm := false.B // Send immy directly to refile
|
||||||
io.optype := OpType.U
|
io.optype := OpType.U
|
||||||
}
|
}
|
||||||
is(OpCode.AUIPC) {
|
is(OpCode.AUIPC) {
|
||||||
io.alu_opcode := AluOpCode.Add
|
io.alu_opcode := AluOpCode.Add
|
||||||
io.reg_file_we := true.B
|
io.reg_file_we := true.B // Write to regfile
|
||||||
io.mux_rega_pc := false.B
|
io.mux_rega_pc := false.B // Send PC to ALU A
|
||||||
|
io.mux_alu_imm := false.B; // Send immu to ALU B
|
||||||
io.optype := OpType.U
|
io.optype := OpType.U
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +85,15 @@ class ControlUnit() extends Module {
|
|||||||
io.reg_file_we := true.B
|
io.reg_file_we := true.B
|
||||||
opImm(funct3, funct7, io);
|
opImm(funct3, funct7, io);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OpR instructions
|
||||||
|
is(OpCode.OpR) {
|
||||||
|
io.reg_file_we := true.B
|
||||||
|
opR(funct3, funct7, io);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Implements functions for all instruction of the opImm kind
|
// Implements functions for all instruction of the opImm kind
|
||||||
def opImm(funct3: UInt, funct7: UInt, io: CUInterface) =
|
def opImm(funct3: UInt, funct7: UInt, io: CUInterface) =
|
||||||
@@ -98,6 +120,10 @@ class ControlUnit() extends Module {
|
|||||||
val SRLI = 0b0000000.U
|
val SRLI = 0b0000000.U
|
||||||
val SRAI = 0b0100000.U
|
val SRAI = 0b0100000.U
|
||||||
}
|
}
|
||||||
|
|
||||||
|
io.mux_regb_imm := false.B; // OpImm are operations with imm, so send imm to ALU
|
||||||
|
io.mux_alu_imm := true.B;
|
||||||
|
io.mux_rega_pc := true.B;
|
||||||
switch(funct3)
|
switch(funct3)
|
||||||
{
|
{
|
||||||
// Type I
|
// Type I
|
||||||
@@ -162,6 +188,93 @@ class ControlUnit() extends Module {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Implements functions for all instruction of the opR kind
|
||||||
|
def opR(funct3: UInt, funct7: UInt, io: CUInterface) =
|
||||||
|
{
|
||||||
|
// Meaning of Funct3 in the context of an OpR instruction
|
||||||
|
object Funct3 extends ChiselEnum
|
||||||
|
{
|
||||||
|
// Type I
|
||||||
|
val ADD = 0b000.U
|
||||||
|
val AND = 0b111.U
|
||||||
|
val OR = 0b110.U
|
||||||
|
val XOR = 0b100.U
|
||||||
|
val SLL = 0b001.U
|
||||||
|
val SLT = 0b010.U
|
||||||
|
val SLTU = 0b011.U
|
||||||
|
|
||||||
|
// Arithmetic op (discriminate by Funct7)
|
||||||
|
val SRL_SRA = 0b101.U
|
||||||
|
}
|
||||||
|
|
||||||
|
// Meaning of Funct7 in the context of SHIFTR IR instructions
|
||||||
|
object IRFunct7 extends ChiselEnum
|
||||||
|
{
|
||||||
|
val SRL = 0b0000000.U
|
||||||
|
val SRA = 0b0100000.U
|
||||||
|
}
|
||||||
|
|
||||||
|
io.mux_regb_imm := true.B; // OpImm are operations with imm, so send imm to ALU
|
||||||
|
io.mux_rega_pc := true.B;
|
||||||
|
io.mux_alu_imm := true.B;
|
||||||
|
switch(funct3)
|
||||||
|
{
|
||||||
|
// Type I
|
||||||
|
is(Funct3.ADD)
|
||||||
|
{
|
||||||
|
io.alu_opcode := AluOpCode.Add
|
||||||
|
}
|
||||||
|
|
||||||
|
is(Funct3.AND)
|
||||||
|
{
|
||||||
|
io.alu_opcode := AluOpCode.And
|
||||||
|
}
|
||||||
|
|
||||||
|
is(Funct3.OR)
|
||||||
|
{
|
||||||
|
io.alu_opcode := AluOpCode.Or
|
||||||
|
}
|
||||||
|
|
||||||
|
is(Funct3.XOR)
|
||||||
|
{
|
||||||
|
io.alu_opcode := AluOpCode.Xor
|
||||||
|
}
|
||||||
|
|
||||||
|
is(Funct3.SLL)
|
||||||
|
{
|
||||||
|
io.alu_opcode := AluOpCode.ShiftLeft
|
||||||
|
}
|
||||||
|
|
||||||
|
is(Funct3.SLT)
|
||||||
|
{
|
||||||
|
io.alu_opcode := AluOpCode.LessThanSigned
|
||||||
|
}
|
||||||
|
|
||||||
|
is(Funct3.SLTU)
|
||||||
|
{
|
||||||
|
io.alu_opcode := AluOpCode.LessThanUnsigned
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type IR
|
||||||
|
is(Funct3.SRL_SRA)
|
||||||
|
{
|
||||||
|
switch(funct7)
|
||||||
|
{
|
||||||
|
is(IRFunct7.SRL)
|
||||||
|
{
|
||||||
|
io.alu_opcode := AluOpCode.ShiftRight
|
||||||
|
}
|
||||||
|
|
||||||
|
is(IRFunct7.SRA)
|
||||||
|
{
|
||||||
|
io.alu_opcode := AluOpCode.ShiftArithmeticRight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ class Rv32i(sim: Boolean = true) extends Module {
|
|||||||
reg_file.io.rs1_data,
|
reg_file.io.rs1_data,
|
||||||
execute_pc
|
execute_pc
|
||||||
);
|
);
|
||||||
alu.io.b := imm;
|
alu.io.b := Mux(control_unit.io.mux_regb_imm, reg_file.io.rs2_data, imm);
|
||||||
|
|
||||||
reg_file.io.rd_data := Mux(control_unit.io.mux_alu_imm, alu.io.out, imm);
|
reg_file.io.rd_data := Mux(control_unit.io.mux_alu_imm, alu.io.out, imm);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user