Merge branch 'rv64i' into rv64im

This commit is contained in:
2025-11-11 19:17:46 +01:00
9 changed files with 216 additions and 71 deletions

View File

@@ -7,7 +7,7 @@ import chisel3.util.Cat
import chisel3.util.Fill
object AluOpCode extends ChiselEnum {
val Add, AddW, Sub, Mul, Mulh, Mulhsu, Mulhu, Div, Divu, Rem, Remu, Mulw,
val Add, 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 =
@@ -23,122 +23,87 @@ class Alu extends Module {
val out = Output(UInt(64.W))
val opcode = Input(AluOpCode())
val comp_result = Output(Bool())
// ~~ Rv64i ~~
// If word_mode is enabled, operations are performed
// on 32-bit-truncated inputs and then sign extended to 64bits
val word_mode = Input(Bool())
})
io.out := 0.U;
io.comp_result := false.B;
val out = WireInit(0.U(64.W))
val op_a = WireInit(0.U(64.W))
val op_b = WireInit(0.U(64.W))
// Defaults
op_a := io.a
op_b := io.b
io.out := out
// Truncate operands, sext result
when(io.word_mode) {
op_a := io.a(31, 0)
op_b := io.b(31, 0)
io.out := SignExtend.Sext(out(31, 0), 64)
}
switch(io.opcode) {
is(Add) {
io.out := io.a + io.b;
out := io.a + io.b;
}
is(Sub) {
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));
out := io.a - io.b;
}
is(And) {
io.out := io.a & io.b;
out := io.a & io.b;
}
is(Or) {
io.out := io.a | io.b;
out := io.a | io.b;
}
is(Xor) {
io.out := io.a ^ io.b;
out := io.a ^ io.b;
}
is(ShiftLeft) {
io.out := io.a << io.b(5, 0);
out := io.a << io.b(5, 0);
}
is(ShiftRight) {
io.out := io.a >> io.b(5, 0);
out := io.a >> io.b(5, 0);
}
is(ShiftArithmeticRight) {
// >> means arithmetic shift for SInts
io.out := (io.a.asSInt >> io.b(5, 0)).asUInt;
out := (io.a.asSInt >> io.b(5, 0)).asUInt;
}
is(LessThanUnsigned) {
val less_than = io.a < io.b;
io.out := less_than;
out := less_than;
io.comp_result := less_than;
}
is(LessThanSigned) {
val less_than = io.a.asSInt < io.b.asSInt
io.out := less_than
out := less_than
io.comp_result := less_than;
}
is(GreaterEqualUnsigned) {
val geq_than = io.a >= io.b;
io.out := geq_than
out := geq_than
io.comp_result := geq_than;
}
is(GreaterEqualSigned) {
val geq_than = io.a.asSInt >= io.b.asSInt
io.out := geq_than
out := geq_than
io.comp_result := geq_than;
}