Adds extension M instructions: not tested

This commit is contained in:
2025-11-11 13:10:19 +01:00
parent 9daa296892
commit 8cff4de02e
6 changed files with 205 additions and 5 deletions

View File

@@ -50,7 +50,7 @@ OBJCOPY := $(PREFIX)objcopy
OBTOMEM := common/objtomem.awk OBTOMEM := common/objtomem.awk
## Flags ## Flags
ASFLAGS :=-march=rv64i -mabi=lp64 -ffreestanding -nostdlib -T $(BENCH_DIR)/link.ld ASFLAGS :=-march=rv64im -mabi=lp64 -ffreestanding -nostdlib -T $(BENCH_DIR)/link.ld
CFLAGS :=$(ASFLAGS) CFLAGS :=$(ASFLAGS)
ELFFLAGS :=$(ASFLAGS) $(MEM_DIR)/crt.o -Os -fno-unroll-loops ELFFLAGS :=$(ASFLAGS) $(MEM_DIR)/crt.o -Os -fno-unroll-loops
ODFLAGS :=-j .text -j .rodata -j .data -s ODFLAGS :=-j .text -j .rodata -j .data -s

18
bench/tests/op/mul.s Normal file
View File

@@ -0,0 +1,18 @@
# expected: 0000000000000000, ffffffffdead0000, 045680e900000000, 0000000021530000
.text
_start:
lui x2, 0xdead0
lui x3, 0x0
addi x4, x0, 0x1
addi x5, x0, (-1)
lui x6, 0xdead0
# Mul 0
mul x31, x2, x3
# Basic multiplications
mul x31, x2, x4
mul x31, x2, x6
# Overflow
mul x31, x5, x2

18
bench/tests/op/mulh.s Normal file
View File

@@ -0,0 +1,18 @@
# expected: 0000000000000000, 0000000000000000, ffffffffbd5a0000, ffffffffdeacffff
.text
_start:
lui x2, 0xdead0
lui x3, 0x0
addi x4, x0, 0x1
addi x5, x0, (-1)
lui x6, 0xdead0
# Mul 0
mulh x31, x2, x3
# Basic multiplications
mulh x31, x2, x4
mulh x31, x2, x6
# Overflow
mulh x31, x5, x2

18
bench/tests/op/mulhsu.s Normal file
View File

@@ -0,0 +1,18 @@
# expected: 0000000000000000, 0000000000000000, ffffffffbd5a0000, ffffffffdeacffff
.text
_start:
lui x2, 0xdead0
lui x3, 0x0
addi x4, x0, 0x1
addi x5, x0, (-1)
lui x6, 0xdead0
# Mul 0
mulhsu x31, x2, x3
# Basic multiplications
mulhsu x31, x2, x4
mulhsu x31, x2, x6
# Overflow
mulhsu x31, x5, x2

View File

@@ -3,11 +3,15 @@ package projet
import chisel3._ import chisel3._
import chisel3.util.switch import chisel3.util.switch
import chisel3.util.is import chisel3.util.is
import chisel3.util.Cat
import chisel3.util.Fill
object AluOpCode extends ChiselEnum { object AluOpCode extends ChiselEnum {
val Add, AddW, Sub, And, Or, Xor, ShiftLeft, ShiftRight, val Add, AddW, Sub, Mul, Mulh, Mulhsu, Mulhu, Div, Divu, Rem, Remu, Mulw,
Divw, Divuw, Remw, Remuw, And, Or, Xor, ShiftLeft, ShiftRight,
ShiftArithmeticRight, LessThanSigned, LessThanUnsigned, ShiftArithmeticRight, LessThanSigned, LessThanUnsigned,
GreaterEqualSigned, GreaterEqualUnsigned, Equal = Value GreaterEqualSigned, GreaterEqualUnsigned, Equal =
Value
} }
class Alu extends Module { class Alu extends Module {
@@ -32,6 +36,63 @@ class Alu extends Module {
io.out := io.a - io.b; io.out := io.a - io.b;
} }
is(Mul) {
io.out := (io.a.asSInt * io.b.asSInt).asUInt;
}
is(Mulh) {
io.out := ((io.a.asSInt * io.b.asSInt) >> 64.U).asUInt;
}
is(Mulhsu) {
io.out := ((io.a.asSInt * io.b).asSInt >> 64.U).asUInt;
}
is(Mulhu) {
io.out := (io.a * io.b) >> 64.U;
}
is(Div) {
io.out := (io.a.asSInt / io.b.asSInt).asUInt;
}
is(Divu) {
io.out := io.a / io.b;
}
is(Rem) {
io.out := (io.a.asSInt % io.b.asSInt).asUInt;
}
is(Remu) {
io.out := io.a % io.b;
}
is(Mulw) {
val res = (io.a.asSInt * io.b.asSInt).asUInt
io.out := Cat(Fill(32, res(31)), res(31, 0))
}
is(Divw) {
val res = (io.a(31, 0).asSInt / io.b(31, 0).asSInt).asUInt;
io.out := Cat(Fill(32, res(31)), res(31, 0));
}
is(Divuw) {
val res = io.a(31, 0) / io.b(31, 0);
io.out := Cat(Fill(32, res(31)), res(31, 0));
}
is(Remw) {
val res = (io.a(31, 0).asSInt % io.b(31, 0).asSInt).asUInt;
io.out := Cat(Fill(32, res(31)), res(31, 0));
}
is(Remuw) {
val res = io.a(31, 0) % io.b(31, 0);
io.out := Cat(Fill(32, res(31)), res(31, 0));
}
is(And) { is(And) {
io.out := io.a & io.b; io.out := io.a & io.b;
} }

View File

@@ -78,9 +78,12 @@ object OpCode extends ChiselEnum {
// Perfomrs some operation with rs1 and rd2 // Perfomrs some operation with rs1 and rd2
// and writes back to a register // and writes back to a register
// add, and, or, xor, sll, srl, sra, slt, stlu // add, and, or, xor, sll, srl, sra, slt, stlu, mul, mulh, mulhsu, mulhu, div, divu, rem, remu
val OpR = "b0110011".U; val OpR = "b0110011".U;
// mulw, divw, remw
val OpMw = "b0111011".U;
// Type J // Type J
val JAL = "b1101111".U val JAL = "b1101111".U
@@ -150,6 +153,12 @@ class ControlUnit() extends Module {
opR(funct3, funct7, io); opR(funct3, funct7, io);
} }
// OpMw instructions
is(OpCode.OpMw) {
io.reg_file_we := true.B // Write to regfile
opMw(funct3, io);
}
// J instructions // J instructions
is(OpCode.JAL) { is(OpCode.JAL) {
io.alu_opcode := AluOpCode.Add // ALU is unused io.alu_opcode := AluOpCode.Add // ALU is unused
@@ -305,7 +314,7 @@ class ControlUnit() extends Module {
val SUB = "b0100000".U val SUB = "b0100000".U
} }
io.mux_regb_imm := true.B; // OpImm are operations with imm, so send imm to ALU io.mux_regb_imm := true.B;
io.mux_rega_pc := true.B; io.mux_rega_pc := true.B;
io.mux_alu_imm := true.B; io.mux_alu_imm := true.B;
switch(funct3) { switch(funct3) {
@@ -358,6 +367,12 @@ class ControlUnit() extends Module {
} }
} }
} }
// Switch to mul extension
val RV32M_FUNCT7 = "b0000001".U
when(funct7 === RV32M_FUNCT7) {
opM(funct3, io);
}
} }
// Implements functions for all instruction of the branch kind // Implements functions for all instruction of the branch kind
@@ -505,4 +520,74 @@ class ControlUnit() extends Module {
} }
} }
} }
// Implements functions for instructions of the M extension of type R
def opM(funct3: UInt, io: CUInterface) = {
// Meaning of Funct3 in the context of an OpM instruction
object Funct3 extends ChiselEnum {
val MUL = "b000".U
val MULH = "b001".U
val MULHSU = "b010".U
val MULHU = "b011".U
val DIV = "b100".U
val DIVU = "b101".U
val REM = "b110".U
val REMU = "b111".U
}
switch(funct3) {
is(Funct3.MUL) {
io.alu_opcode := AluOpCode.Mul
}
is(Funct3.MULH) {
io.alu_opcode := AluOpCode.Mulh
}
is(Funct3.MULHSU) {
io.alu_opcode := AluOpCode.Mulhsu
}
is(Funct3.MULHU) {
io.alu_opcode := AluOpCode.Mulhu
}
is(Funct3.DIV) {
io.alu_opcode := AluOpCode.Div
}
is(Funct3.DIVU) {
io.alu_opcode := AluOpCode.Divu
}
is(Funct3.REM) {
io.alu_opcode := AluOpCode.Rem
}
is(Funct3.REMU) {
io.alu_opcode := AluOpCode.Remu
}
}
}
// Implements functions for instructions of the M extension with word size
def opMw(funct3: UInt, io: CUInterface) = {
// Meaning of Funct3 in the context of an OpMw instruction
object Funct3 extends ChiselEnum {
val MULW = "b000".U
val DIVW = "b100".U
val DIVUW = "b101".U
val REMW = "b110".U
val REMUW = "b111".U
}
switch(funct3) {
is(Funct3.MULW) {
io.alu_opcode := AluOpCode.Mulw
}
is(Funct3.DIVW) {
io.alu_opcode := AluOpCode.Divw
}
is(Funct3.DIVUW) {
io.alu_opcode := AluOpCode.Divuw
}
is(Funct3.REMW) {
io.alu_opcode := AluOpCode.Remw
}
is(Funct3.REMUW) {
io.alu_opcode := AluOpCode.Remuw
}
}
}
} }