Stage 6: implementation, untested

This commit is contained in:
2025-11-06 16:18:01 +01:00
parent 1462563e39
commit 2779471523
9 changed files with 180 additions and 32 deletions

9
bench/op/andi.s Normal file
View File

@@ -0,0 +1,9 @@
# expected: 00000000, 00000010
.text
_start:
addi x1, x0, 0x100
andi x31, x1, 0x0FF
addi x1, x0, -1
andi x31, x1, 0x010

4
bench/op/ori.s Normal file
View File

@@ -0,0 +1,4 @@
# expected: 00000000, 00000010
.text
_start:

View File

@@ -4,29 +4,60 @@ import chisel3._
import chisel3.util.switch
import chisel3.util.is
object AluOpCode extends ChiselEnum
{
val Add = Value
object AluOpCode extends ChiselEnum {
val Add, And, Or, Xor, ShiftLeft, ShiftRight, ShiftArithmeticRight,
LessThanSigned, LessThanUnsigned = Value
}
class Alu extends Module {
import AluOpCode._
import AluOpCode._
val io = IO(new Bundle {
val a = Input(UInt(32.W))
val b = Input(UInt(32.W))
val out = Output(UInt(32.W))
val opcode = Input(AluOpCode())
})
val io = IO(new Bundle {
val a = Input(UInt(32.W))
val b = Input(UInt(32.W))
val out = Output(UInt(32.W))
val opcode = Input(AluOpCode())
})
io.out := 0.U;
io.out := 0.U;
switch(io.opcode)
{
is(Add)
{
io.out := io.a + io.b;
switch(io.opcode) {
is(Add) {
io.out := io.a + io.b;
}
is(And) {
io.out := io.a & io.b;
}
is(Or) {
io.out := io.a | io.b;
}
is(Xor) {
io.out := io.a ^ io.b;
}
is(ShiftLeft) {
io.out := io.a << io.b(4, 0);
}
is(ShiftRight) {
io.out := io.a >> io.b(4, 0);
}
is(ShiftArithmeticRight) {
// >> means arithmetic shift for SInts
io.out := (io.a.asSInt >> io.b(4, 0)).asUInt;
}
is(LessThanUnsigned) {
io.out := io.a < io.b
}
is(LessThanSigned) {
io.out := io.a.asSInt < io.b.asSInt
}
}
}
}

View File

@@ -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
}
}
}
}
}
}

View File

@@ -16,10 +16,11 @@ class ImmediateDecoder extends Module {
})
io.immediate := 0.U
// Decode imm-u
// Decode and construct immediates
val imm_u = Cat(io.instruction(31, 12), 0.U(12.W));
// Decode imm-i
val imm_i = Cat(Fill(20, io.instruction(31)), io.instruction(31, 20));
val imm_ir = io.instruction(24, 20);
switch(io.op_type) {
is(OpType.U) {
io.immediate := imm_u
@@ -27,5 +28,8 @@ class ImmediateDecoder extends Module {
is(OpType.I) {
io.immediate := imm_i
}
is(OpType.IR) {
io.immediate := imm_ir
}
}
}

View File

@@ -17,7 +17,11 @@ class Rv32i(sim: Boolean = true) extends Module {
reg_file.io.rd_data := 0.U;
io.x31 := reg_file.io.x31
if (sim) {
io.valid_x31.get := reg_file.io.valid_x31.get && Delay.Delay(!reset.asBool, 1, false.B)
io.valid_x31.get := reg_file.io.valid_x31.get && Delay.Delay(
!reset.asBool,
1,
false.B
)
}
val alu = Module(new Alu());