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
## 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)
ELFFLAGS :=$(ASFLAGS) $(MEM_DIR)/crt.o -Os -fno-unroll-loops
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.util.switch
import chisel3.util.is
import chisel3.util.Cat
import chisel3.util.Fill
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,
GreaterEqualSigned, GreaterEqualUnsigned, Equal = Value
GreaterEqualSigned, GreaterEqualUnsigned, Equal =
Value
}
class Alu extends Module {
@@ -32,6 +36,63 @@ class Alu extends Module {
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) {
io.out := io.a & io.b;
}

View File

@@ -78,9 +78,12 @@ object OpCode extends ChiselEnum {
// Perfomrs some operation with rs1 and rd2
// 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;
// mulw, divw, remw
val OpMw = "b0111011".U;
// Type J
val JAL = "b1101111".U
@@ -150,6 +153,12 @@ class ControlUnit() extends Module {
opR(funct3, funct7, io);
}
// OpMw instructions
is(OpCode.OpMw) {
io.reg_file_we := true.B // Write to regfile
opMw(funct3, io);
}
// J instructions
is(OpCode.JAL) {
io.alu_opcode := AluOpCode.Add // ALU is unused
@@ -305,7 +314,7 @@ class ControlUnit() extends Module {
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_alu_imm := true.B;
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
@@ -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
}
}
}
}