rv64im: passing tests

This commit is contained in:
2025-11-12 11:50:09 +01:00
parent 7a1221b16e
commit cfacd6a9fc
16 changed files with 321 additions and 60 deletions

25
bench/tests/op/div.s Normal file
View File

@@ -0,0 +1,25 @@
# expected: ffffffffffffffff, ffffffffffffffff, dead0, 1, 8000000000000000, 7
.text
_start:
li x2, 0xdead0
li x3, 0x0
li x4, 0x1
li x5, (-1)
li x6, 0xdead0
li x7, (-2355)
li x8, (-324)
li x9, 0x8000000000000000
# Div by 0
div x31, x2, x3
div x31, x5, x3
# Basic divisions
div x31, x2, x4
div x31, x2, x6
# Overflow
div x31, x9, x5
# Signed / signed
div x31, x7, x8

14
bench/tests/op/divu.s Normal file
View File

@@ -0,0 +1,14 @@
# expected: ffffffffffffffff, dead0, 1
.text
_start:
li x2, 0xdead0
li x3, 0x0
li x4, 0x1
li x6, 0xdead0
# Div by 0
divu x31, x2, x3
# Basic divisions
divu x31, x2, x4
divu x31, x2, x6

14
bench/tests/op/divuw.s Normal file
View File

@@ -0,0 +1,14 @@
# expected: ffffffffffffffff, dead0, 1
.text
_start:
li x2, 0xdead0
li x3, 0x0
li x4, 0x1
li x6, 0xdead0
# Div by 0
divuw x31, x2, x3
# Basic divisions
divuw x31, x2, x4
divuw x31, x2, x6

25
bench/tests/op/divw.s Normal file
View File

@@ -0,0 +1,25 @@
# expected: ffffffffffffffff, ffffffffffffffff, dead0, 1, ffffffff80000000, 7
.text
_start:
li x2, 0xdead0
li x3, 0x0
li x4, 0x1
li x5, (-1)
li x6, 0xdead0
li x7, (-2355)
li x8, (-324)
li x9, 0x80000000
# Div by 0
divw x31, x2, x3
divw x31, x5, x3
# Basic divisions
divw x31, x2, x4
divw x31, x2, x6
# Overflow
divw x31, x9, x5
# Signed / signed
divw x31, x7, x8

View File

@@ -1,11 +1,12 @@
# expected: 0000000000000000, ffffffffdead0000, 045680e900000000, 0000000021530000
# expected: 0000000000000000, 00000000000dead0, c1b080e900, -dead0, 54a029
.text
_start:
lui x2, 0xdead0
lui x3, 0x0
addi x4, x0, 0x1
addi x5, x0, (-1)
lui x6, 0xdead0
li x2, 0xdead0
li x3, 0x0
li x4, 0x1
li x5, (-1)
li x6, 0xdead0
li x7, (-2355)
# Mul 0
mul x31, x2, x3
@@ -16,3 +17,6 @@ _start:
# Overflow
mul x31, x5, x2
# Signed * signed
mul x31, x7, x7

View File

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

View File

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

20
bench/tests/op/mulhu.s Normal file
View File

@@ -0,0 +1,20 @@
# expected: 0000000000000000, 0000000000000000, c1b080e9, deacf, deacf
.text
_start:
li x2, 0xdead0
li x3, 0x0
li x4, 0x1
li x5, (-1)
li x6, 0xdead0
li x7, 0xdead00000000
# Mul 0
mulhu x31, x2, x3
# Basic multiplications
mulhu x31, x2, x4
mulhu x31, x7, x7
# Overflow
mulhu x31, x5, x2
mulhu x31, x2, x5

22
bench/tests/op/mulw.s Normal file
View File

@@ -0,0 +1,22 @@
# expected: 0000000000000000, 00000000000dead0, ffffffffb080e900, -dead0, 54a029
.text
_start:
li x2, 0xdead0
li x3, 0x0
li x4, 0x1
li x5, (-1)
li x6, 0xdead0
li x7, (-2355)
# Mul 0
mulw x31, x2, x3
# Basic multiplications
mulw x31, x2, x4
mulw x31, x2, x6
# Overflow
mulw x31, x5, x2
# Signed * signed
mulw x31, x7, x7

27
bench/tests/op/rem.s Normal file
View File

@@ -0,0 +1,27 @@
# expected: dead0, ffffffffffffffff, 0, 0, 18, 0, -57
.text
_start:
li x1, 0x0293
li x2, 0xdead0
li x3, 0x0
li x4, 0x1
li x5, (-1)
li x6, 0xdead0
li x7, (-2355)
li x8, (-324)
li x9, 0x8000000000000000
# Remainder by 0
rem x31, x2, x3
rem x31, x5, x3
# Basic remainders
rem x31, x2, x4
rem x31, x2, x6
rem x31, x6, x1
# Overflow
rem x31, x9, x5
# Signed / signed
rem x31, x7, x8

27
bench/tests/op/remu.s Normal file
View File

@@ -0,0 +1,27 @@
# expected: dead0, ffffffffffffffff, 0, 0, 18, 8000000000000000, fffffffffffff6cd
.text
_start:
li x1, 0x0293
li x2, 0xdead0
li x3, 0x0
li x4, 0x1
li x5, (-1)
li x6, 0xdead0
li x7, (-2355)
li x8, (-324)
li x9, 0x8000000000000000
# Remainder by 0
remu x31, x2, x3
remu x31, x5, x3
# Basic remainders
remu x31, x2, x4
remu x31, x2, x6
remu x31, x6, x1
# Overflow
remu x31, x9, x5
# Signed / signed
remu x31, x7, x8

27
bench/tests/op/remuw.s Normal file
View File

@@ -0,0 +1,27 @@
# expected: dead0, ffffffffffffffff, 0, 0, 18, ffffffff80000000, fffffffffffff6cd
.text
_start:
li x1, 0x0293
li x2, 0xdead0
li x3, 0x0
li x4, 0x1
li x5, (-1)
li x6, 0xdead0
li x7, (-2355)
li x8, (-324)
li x9, 0x80000000
# Remainder by 0
remuw x31, x2, x3
remuw x31, x5, x3
# Basic remainders
remuw x31, x2, x4
remuw x31, x2, x6
remuw x31, x6, x1
# Overflow
remuw x31, x9, x5
# Signed / signed
remuw x31, x7, x8

27
bench/tests/op/remw.s Normal file
View File

@@ -0,0 +1,27 @@
# expected: dead0, ffffffffffffffff, 0, 0, 18, 0, -57
.text
_start:
li x1, 0x0293
li x2, 0xdead0
li x3, 0x0
li x4, 0x1
li x5, (-1)
li x6, 0xdead0
li x7, (-2355)
li x8, (-324)
li x9, 0x80000000
# Remainder by 0
remw x31, x2, x3
remw x31, x5, x3
# Basic remainders
remw x31, x2, x4
remw x31, x2, x6
remw x31, x6, x1
# Overflow
remw x31, x9, x5
# Signed / signed
remw x31, x7, x8

View File

@@ -3,12 +3,10 @@ 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, Sub, Mul, Mulh, Mulhsu, Mulhu, Div, Divu, Rem, Remu, Mulw,
Divw, Divuw, Remw, Remuw, And, Or, Xor, ShiftLeft, ShiftRight,
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 =
Value
@@ -58,6 +56,58 @@ class Alu extends Module {
out := io.a - io.b;
}
is(Mul) {
out := (io.a.asSInt * io.b.asSInt).asUInt;
}
is(Mulh) {
out := ((io.a.asSInt * io.b.asSInt) >> 64.U).asUInt;
}
is(Mulhsu) {
out := ((io.a.asSInt * io.b).asSInt >> 64.U).asUInt;
}
is(Mulhu) {
out := (io.a * io.b) >> 64.U;
}
is(Div) {
when(io.b === 0.U) {
when(io.word_mode) {
out := (-1).S(32.W).asUInt
}.otherwise {
out := (-1).S(64.W).asUInt
}
}.otherwise {
out := (io.a.asSInt / io.b.asSInt).asUInt;
}
}
is(Divu) {
when(io.b === 0.U) {
out := "xFFFFFFFFFFFFFFFF".U
}.otherwise {
out := io.a / io.b;
}
}
is(Rem) {
when(io.b === 0.U) {
out := io.a
}.otherwise {
out := (io.a.asSInt % io.b.asSInt).asUInt;
}
}
is(Remu) {
when(io.b === 0.U) {
out := io.a
}.otherwise {
out := io.a % io.b;
}
}
is(And) {
out := io.a & io.b;
}

View File

@@ -163,7 +163,8 @@ class ControlUnit() extends Module {
// OpMw instructions
is(OpCode.OpMw) {
io.reg_file_we := true.B // Write to regfile
opMw(funct3, io);
io.alu_word_mode := true.B
opM(funct3, io);
}
// J instructions
@@ -614,36 +615,4 @@ class ControlUnit() extends Module {
}
}
}
// ~~ Rv64M ~~
// 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
}
}
}
}

View File

@@ -15,7 +15,14 @@ object ZzTopCommon extends AnyFreeSpec with ChiselSim {
.split(",")
.map(_.trim)
.filter(_.nonEmpty)
.map(str => BigInt(str, 16))
.map(str => {
if (str.charAt(0) == '-') {
BigInt("FFFFFFFFFFFFFFFF", 16) -
BigInt(str.substring(1), 16) + 1
} else {
BigInt(str, 16)
}
})
.toSeq
case None =>
Seq.empty
@@ -52,10 +59,10 @@ object ZzTopCommon extends AnyFreeSpec with ChiselSim {
if (cycles < timeout) {
// Vérifier la nouvelle valeur
val got = dut.io.x31.get.peek().litValue
trace += f"Valeur attendue = 0x$expected%08X, reçue = 0x$got%08X"
trace += f"Valeur attendue = 0x$expected%016X, reçue = 0x$got%016X"
if (got != expected) failTrace("Mauvaise sortie", trace)
} else {
trace += f"Valeur attendue = 0x$expected%08X, reçue = ⏰"
trace += f"Valeur attendue = 0x$expected%016X, reçue = ⏰"
failTrace("Simulation bloquée", trace)
}
}