diff --git a/bench/tests/op/addw.s b/bench/tests/op/addw.s new file mode 100644 index 0000000..586bd94 --- /dev/null +++ b/bench/tests/op/addw.s @@ -0,0 +1,19 @@ +# expected: 0000000000000000, FFFFFFFFFFFFFFFF, 0000000000000010, 0000000000000000 + .text +_start: + # 0 addition + li x1, 0 + addw x31, x0, x1 + + # all bits addition + sign extension to 32 bits then 64 bits + li x1, 0x00000000FFFFFFFF + addw x31, x0, x1 + + # simple addition + li x1, 8 + li x2, 8 + addw x31, x1, x2 + + # 32bits trim + li x1, 0xFFFFFFFF00000000 + addw x31, x0, x1 diff --git a/bench/tests/op/ld.s b/bench/tests/op/ld.s new file mode 100644 index 0000000..55ee01d --- /dev/null +++ b/bench/tests/op/ld.s @@ -0,0 +1,7 @@ +# expected: 1023456789ABCDEF + .text +_start: + li x1, 0x1023456789ABCDEF + sd x1, 100(x0) + + ld x31, 100(x0) diff --git a/bench/tests/op/lw.s b/bench/tests/op/lw.s index 2876a82..71887bc 100644 --- a/bench/tests/op/lw.s +++ b/bench/tests/op/lw.s @@ -1,7 +1,11 @@ -# expected: 123451BC +# expected: 123451BC, FFFFFFFFF0000000 .text _start: lui x1, 0x12345 ori x1, x1, 0x1BC sw x1, 100(x0) lw x31, 100(x0) + + li x1, 0x00000000F0000000 + sw x1, 100(x0) + lw x31, 100(x0) diff --git a/bench/tests/op/lwu.s b/bench/tests/op/lwu.s new file mode 100644 index 0000000..390cc49 --- /dev/null +++ b/bench/tests/op/lwu.s @@ -0,0 +1,6 @@ +# expected: 00000000FFFFFFFF + .text +_start: + li x1, 0xFFFFFFFFFFFFFFFF + sw x1, 100(x0) + lwu x31, 100(x0) diff --git a/bench/tests/op/sd.s b/bench/tests/op/sd.s new file mode 100644 index 0000000..2515344 --- /dev/null +++ b/bench/tests/op/sd.s @@ -0,0 +1,9 @@ +# expected: 000000009ABCDEF0, 0000000012345678 + .text +_start: + li x1, 0x123456789ABCDEF0 + sd x1, 128(x0) + + lwu x31, 128(x0) + lwu x31, 132(x0) + diff --git a/bench/tests/op/slliw.s b/bench/tests/op/slliw.s new file mode 100644 index 0000000..6bd3e7d --- /dev/null +++ b/bench/tests/op/slliw.s @@ -0,0 +1,10 @@ +# expected: 0000000000000000, FFFFFFFF80000000 + .text +_start: + # Shift out of 32bits + li x1, 0x0000000080000000 + slliw x31, x1, 1 + + # Test sign extension + li x1, 0x0000000040000000 + slliw x31, x1, 1 diff --git a/bench/tests/op/sllw.s b/bench/tests/op/sllw.s new file mode 100644 index 0000000..561643b --- /dev/null +++ b/bench/tests/op/sllw.s @@ -0,0 +1,16 @@ +# expected: 0000000000000000, FFFFFFFF80000000, 0000000000000000 + .text +_start: + # Shift out of 32bits + li x1, 0x0000000080000000 + li x2, 1 + sllw x31, x1, x2 + + # Test sign extension + li x1, 0x0000000040000000 + li x2, 1 + sllw x31, x1, x2 + + li x1, 1 + li x2, 33 + sllw x31, x1, x2 diff --git a/bench/tests/op/sraiw.s b/bench/tests/op/sraiw.s index dccc130..4497746 100644 --- a/bench/tests/op/sraiw.s +++ b/bench/tests/op/sraiw.s @@ -1,4 +1,4 @@ -# expected: 0000000000000000, 000000003fffffff, ffffffffc0000000, ffffffffffffffff, ffffffffffffffff +# expected: 0000000000000000, 000000003FFFFFFF, FFFFFFFFC0000000, FFFFFFFFFFFFFFFF, FFFFFFFFFFFFFFFF .text _start: # Test 1: 1 >> 1 => 0 diff --git a/bench/tests/op/sraw.s b/bench/tests/op/sraw.s new file mode 100644 index 0000000..f226e79 --- /dev/null +++ b/bench/tests/op/sraw.s @@ -0,0 +1,27 @@ +# expected: 0000000000000000, 000000003FFFFFFF, FFFFFFFFC0000000, FFFFFFFFFFFFFFFF, FFFFFFFFFFFFFFFF + .text +_start: + # Test 1: 1 >> 1 => 0 + li x1, 1 + li x2, 1 + sraw x31, x1, x2 # x31 = 0 + + # Test 2: 0x7fffffff >> 1 => 0x3fffffff + li x1, 0x7fffffff + li x2, 1 + sraw x31, x1, x2 # x31 = 0x000000003fffffff + + # Test 3: 0x80000000 >> 1 => 0xc0000000 (sign-extended) + li x1, 0x80000000 + li x2, 1 + sraw x31, x1, x2 # x31 = 0xffffffffc0000000 + + # Test 4: 0x80000000 >> 31 => 0xffffffff (-1) + li x1, 0x80000000 + li x2, 31 + sraw x31, x1, x2 # x31 = 0xffffffffffffffff + + # Test 5: 0xffffffff >> 31 => 0xffffffff (-1) + li x1, -1 + li x2, 31 + sraw x31, x1, x2 # x31 = 0xffffffffffffffff diff --git a/bench/tests/op/srliw.s b/bench/tests/op/srliw.s new file mode 100644 index 0000000..a16e186 --- /dev/null +++ b/bench/tests/op/srliw.s @@ -0,0 +1,14 @@ +# expected: 0000000000000000, 000000003fffffff, 0000000040000000 + .text +_start: + # Test 1: 1 >> 1 => 0 + li x1, 1 + srliw x31, x1, 1 # x31 = 0 + + # Test 2: 0x7fffffff >> 1 => 0x3fffffff + li x1, 0x7fffffff + srliw x31, x1, 1 # x31 = 0x000000003fffffff + + # Test 3: 0x80000000 >> 1 => 0x40000000 (not sign-extended) + li x1, 0x80000000 + srliw x31, x1, 1 # x31 = 0xffffffffc0000000 diff --git a/bench/tests/op/srlw.s b/bench/tests/op/srlw.s new file mode 100644 index 0000000..bc2ba1d --- /dev/null +++ b/bench/tests/op/srlw.s @@ -0,0 +1,22 @@ +# expected: 0000000000000000, 000000003fffffff, 0000000040000000, 0000000000000000 + .text +_start: + # Test 1: 1 >> 1 => 0 + li x1, 1 + li x2, 1 + srlw x31, x1, x2 # x31 = 0 + + # Test 2: 0x7fffffff >> 1 => 0x3fffffff + li x1, 0x7fffffff + li x2, 1 + srlw x31, x1, x2 # x31 = 0x000000003fffffff + + # Test 3: 0x80000000 >> 1 => 0x40000000 (not sign-extended) + li x1, 0x80000000 + li x2, 1 + srlw x31, x1, x2 # x31 = 0xffffffffc0000000 + + li x1, 0x40000000 + li x2, 33 + srlw x31, x1, x2 + diff --git a/bench/tests/op/subw.s b/bench/tests/op/subw.s new file mode 100644 index 0000000..b9c3df3 --- /dev/null +++ b/bench/tests/op/subw.s @@ -0,0 +1,19 @@ +# expected: 0000000000000000, FFFFFFFFFFFFFFFF, 0000000000000004, 0000000000000000 + .text +_start: + # 0 sub + li x1, 0 + subw x31, x0, x1 + + # all bits sub + sign extension to 32 bits then 64 bits + li x1, 1 + subw x31, x0, x1 + + # simple subtraction + li x1, 8 + li x2, 4 + subw x31, x1, x2 + + # 32bits trim + li x1, 0xFFFFFFFF00000000 + subw x31, x1, x1 diff --git a/src/main/scala/projet/ControlUnit.scala b/src/main/scala/projet/ControlUnit.scala index a948783..9c93fd3 100644 --- a/src/main/scala/projet/ControlUnit.scala +++ b/src/main/scala/projet/ControlUnit.scala @@ -9,6 +9,7 @@ import projet.op.OpBranch import projet.op.OpStore import projet.op.OpLoad import projet.op.OpImmW +import projet.op.OpRW class CUInterface extends Bundle { val instruction = Input(UInt(32.W)) @@ -113,6 +114,9 @@ object OpCode extends ChiselEnum { // ~~ Rv64i ~~ val OpImmW = "b0011011".U + + // TypeR + val OpRW = "b0111011".U } class ControlUnit() extends Module { @@ -213,5 +217,9 @@ class ControlUnit() extends Module { is(OpCode.OpImmW) { OpImmW.opImmW(io); } + + is(OpCode.OpRW) { + OpRW.opRW(io); + } } } diff --git a/src/main/scala/projet/DMem.scala b/src/main/scala/projet/DMem.scala index 4094238..956e2dd 100644 --- a/src/main/scala/projet/DMem.scala +++ b/src/main/scala/projet/DMem.scala @@ -80,7 +80,7 @@ class DMem extends Module { } // Data out is available one cycle after the read request - val read_addr = Delay.Delay(io.addr, 2, 0.U); + val read_addr = Delay.Delay(io.addr, 1, 0.U); val read_sign_extend = Delay.Delay(io.sign_extend, 1, false.B); when(Delay.Delay(io.en && !io.we, 1, false.B)) { switch(Delay.Delay(io.size, 1, DMemSize.Byte)) { diff --git a/src/main/scala/projet/op/OpLoad.scala b/src/main/scala/projet/op/OpLoad.scala index 310e28e..40ae693 100644 --- a/src/main/scala/projet/op/OpLoad.scala +++ b/src/main/scala/projet/op/OpLoad.scala @@ -39,6 +39,7 @@ object OpLoad { io.reg_file_we := true.B io.memory_en := true.B io.memory_we := false.B + io.memory_sign_extend := false.B; switch(funct3) { // Byte load is(Funct3.LB) { @@ -61,16 +62,15 @@ object OpLoad { // Word load is(Funct3.LW) { io.memory_size := DMemSize.Word + io.memory_sign_extend := true.B; } is(Funct3.LWU) { io.memory_size := DMemSize.Word - io.memory_sign_extend := true.B; } // Long load is(Funct3.LD) { io.memory_size := DMemSize.Long - io.memory_sign_extend := true.B; } } } diff --git a/src/main/scala/projet/op/OpRW.scala b/src/main/scala/projet/op/OpRW.scala index 2972c52..6ded8d4 100644 --- a/src/main/scala/projet/op/OpRW.scala +++ b/src/main/scala/projet/op/OpRW.scala @@ -5,7 +5,6 @@ import chisel3.util.switch import projet.CUInterface import projet.AluOpCode import chisel3.util.is -import projet.OpType object OpRW { // Implements functions for all instruction of the opImm, w kind