diff --git a/bench/tests/op/sb.s b/bench/tests/op/sb.s index 5a8c076..b1d38d6 100644 --- a/bench/tests/op/sb.s +++ b/bench/tests/op/sb.s @@ -1,10 +1,24 @@ -# expected: 00010000 +# expected: 00000050, 000001AB .text _start: - addi x1, x0, 0x1 - sw x1, 28(x0) - nop - nop - nop + addi x1, x0, 0x5 + # Write x1 in the next addi instruction, position 12+3 bytes + # Due to type I immediate, x31 must contain 0x050 + sb x1, 15(x0) nop addi x31, x0, 0x0 + + # Create an instruction bytes per bytes + # addi x31, x0, 0x1AB -> 0x1AB00F93 + addi x1, x0, 0x93 + addi x2, x0, 0x0F + addi x3, x0, 0xB0 + addi x4, x0, 0x1A + sb x1, 52(x0) + sb x2, 53(x0) + sb x3, 54(x0) + sb x4, 55(x0) + nop + + # Instruction will be written here + nop diff --git a/bench/tests/op/sh.s b/bench/tests/op/sh.s new file mode 100644 index 0000000..37eed71 --- /dev/null +++ b/bench/tests/op/sh.s @@ -0,0 +1,22 @@ +# expected: 00000050, 000001AB + .text +_start: + addi x1, x0, 0x500 + # Write x1 in the next addi instruction, position 12+2 bytes + # Due to type I immediate, x31 must contain 0x050 + sh x1, 14(x0) + nop + addi x31, x0, 0x0 + + # Create an instruction bytes per bytes + # addi x31, x0, 0x1AB -> 0x1AB00F93 + lui x1, 0x0F93 + srli x1, x1, 12 + lui x2, 0x1AB0 + srli x2, x2, 12 + sh x1, 44(x0) + sh x2, 46(x0) + nop + + # Instruction will be written here + nop diff --git a/bench/tests/op/sw.s b/bench/tests/op/sw.s new file mode 100644 index 0000000..84cf33e --- /dev/null +++ b/bench/tests/op/sw.s @@ -0,0 +1,15 @@ +# expected: 000001AB + .text +_start: + # Create an instruction bytes per bytes + # addi x31, x0, 0x1AB -> 0x1AB00F93 + lui x1, 0x0F93 + srli x1, x1, 12 + lui x2, 0x1AB0 + slli x2, x2, 4 + or x1, x1, x2 + sw x1, 28(x0) + nop + + # Instruction will be written here + nop diff --git a/src/main/scala/projet/ControlUnit.scala b/src/main/scala/projet/ControlUnit.scala index f100ea0..6c829a2 100644 --- a/src/main/scala/projet/ControlUnit.scala +++ b/src/main/scala/projet/ControlUnit.scala @@ -86,6 +86,9 @@ object OpCode extends ChiselEnum { // Type S val OpStore = "b0100011".U + + // Type I + val OpLoad = "b0000011".U } class ControlUnit() extends Module { @@ -180,6 +183,11 @@ class ControlUnit() extends Module { io.optype := OpType.S opStore(funct3, io); } + + is(OpCode.OpLoad) { + io.optype := OpType.I + opLoad(funct3, io); + } } // Implements functions for all instruction of the opImm kind @@ -419,6 +427,7 @@ class ControlUnit() extends Module { io.mux_rega_pc := true.B io.mux_regb_imm := false.B io.memory_we := true.B + io.memory_en := true.B switch(funct3) { is(Funct3.SB) { io.memory_size := DMemSize.Byte @@ -431,4 +440,31 @@ class ControlUnit() extends Module { } } } + // Implements functions for all instruction of the OpLoad kind + def opLoad(funct3: UInt, io: CUInterface) = { + // Meaning of Funct3 in the context of an OpLoad instruction + object Funct3 extends ChiselEnum { + val LB = "b000".U + val LH = "b001".U + val LW = "b010".U + } + + io.alu_opcode := AluOpCode.Add + io.mux_alu_imm := true.B + io.mux_rega_pc := true.B + io.mux_regb_imm := false.B + io.reg_file_we := true.B + io.memory_en := true.B + switch(funct3) { + is(Funct3.LB) { + io.memory_size := DMemSize.Byte + } + is(Funct3.LH) { + io.memory_size := DMemSize.Half + } + is(Funct3.LW) { + io.memory_size := DMemSize.Word + } + } + } } diff --git a/src/main/scala/projet/DMem.scala b/src/main/scala/projet/DMem.scala index ad25cf0..c7f1928 100644 --- a/src/main/scala/projet/DMem.scala +++ b/src/main/scala/projet/DMem.scala @@ -3,6 +3,7 @@ package projet import chisel3._ import chisel3.util.switch import chisel3.util.is +import chisel3.util.Cat object DMemSize extends ChiselEnum { val Byte, Half, Word = Value @@ -20,21 +21,23 @@ class DMem extends Module { val data_out = Output(UInt(32.W)) }) - io.dbus.addr := io.addr; + io.dbus.addr := Cat(io.addr(31, 2), 0.U(2.W)); io.dbus.en := io.en; val bytes_enabled = VecInit(false.B, false.B, false.B, false.B) - val data = WireInit(0.U) + val data = WireInit(0.U(32.W)) + when(io.we) { switch(io.size) { is(DMemSize.Byte) { bytes_enabled(io.addr(1, 0)) := true.B - data := (io.data_in << (io.addr(1) * 16.U)) << - (io.addr(1) * 8.U) + data := io.data_in << (io.addr(1) * 16.U + io.addr(0) * 8.U) } is(DMemSize.Half) { bytes_enabled((io.addr(1) * 2.U(2.W))(1, 0)) := true.B - bytes_enabled((io.addr(1) * 2.U(2.W) + 1.U(2.W))(1, 0)) := true.B + bytes_enabled( + (io.addr(1) * 2.U(2.W) + 1.U(2.W))(1, 0) + ) := true.B data := io.data_in << (io.addr(1) * 16.U) } is(DMemSize.Word) { diff --git a/src/main/scala/projet/IDMem.scala b/src/main/scala/projet/IDMem.scala index 40b04f6..b5da30f 100644 --- a/src/main/scala/projet/IDMem.scala +++ b/src/main/scala/projet/IDMem.scala @@ -48,8 +48,6 @@ class dpram( // nom identique à celui du verilog val doutB = Output(UInt(DATA_WIDTH.W)) val dinB = Input(UInt(DATA_WIDTH.W)) val weB = Input(UInt(NUM_COL.W)) - - val ram_block = Output(UInt(DATA_WIDTH.W)) }) } @@ -136,8 +134,6 @@ class IDMem(sim: Boolean, addrWidth: Int, memFile: String = "") extends Module { ) ) - dontTouch(unifiedRam.io.ram_block) - unifiedRam.io.clkA := io.clki unifiedRam.io.clkB := io.clkd // instructions sur le port a diff --git a/src/main/scala/projet/Rv32i.scala b/src/main/scala/projet/Rv32i.scala index 835481f..3189283 100644 --- a/src/main/scala/projet/Rv32i.scala +++ b/src/main/scala/projet/Rv32i.scala @@ -95,7 +95,7 @@ class Rv32i(sim: Boolean = true) extends Module { writeback_line ); - dmem.io.data_in := rs2 + dmem.io.data_in := reg_file.io.rs2_data dmem.io.addr := writeback_line io.ibus.wdata := 0.U;