Stage 10: not tested

This commit is contained in:
2025-11-07 18:37:58 +01:00
parent 036f432d76
commit 43a11c865b
4 changed files with 108 additions and 6 deletions

View File

@@ -16,6 +16,11 @@ class CUInterface extends Bundle {
// True if the decoded instruction is a jump // True if the decoded instruction is a jump
val is_jump = Output(Bool()) val is_jump = Output(Bool())
// DMem connections
val memory_size = Input(DMemSize())
val memory_en = Input(Bool())
val memory_we = Input(Bool())
// Muxers // Muxers
// The naming convention is as follows : mux_xxx_yyy. // The naming convention is as follows : mux_xxx_yyy.
// If the signal is hot, xxx is selected otherwise yyy is selected // If the signal is hot, xxx is selected otherwise yyy is selected
@@ -43,7 +48,7 @@ class CUInterface extends Bundle {
} }
object OpType extends ChiselEnum { object OpType extends ChiselEnum {
val U, I, IR, J, B = Value val U, I, IR, J, B, S = Value
} }
object OpCode extends ChiselEnum { object OpCode extends ChiselEnum {
@@ -78,6 +83,9 @@ object OpCode extends ChiselEnum {
// Type B // Type B
val OpBranch = "b1100011".U val OpBranch = "b1100011".U
// Type S
val OpStore = "b0100011".U
} }
class ControlUnit() extends Module { class ControlUnit() extends Module {
@@ -87,6 +95,9 @@ class ControlUnit() extends Module {
io.alu_opcode := AluOpCode.Add io.alu_opcode := AluOpCode.Add
io.optype := OpType.U io.optype := OpType.U
io.is_jump := false.B; io.is_jump := false.B;
io.memory_size := DMemSize.Word
io.memory_en := false.B
io.memory_we := false.B
io.mux_alu_imm := true.B; io.mux_alu_imm := true.B;
io.mux_rega_pc := true.B; io.mux_rega_pc := true.B;
io.mux_regb_imm := true.B; io.mux_regb_imm := true.B;
@@ -164,6 +175,11 @@ class ControlUnit() extends Module {
io.optype := OpType.B; io.optype := OpType.B;
opBranch(funct3, io); opBranch(funct3, io);
} }
is(OpCode.OpStore) {
io.optype := OpType.S
opStore(funct3, io);
}
} }
// Implements functions for all instruction of the opImm kind // Implements functions for all instruction of the opImm kind
@@ -389,4 +405,30 @@ class ControlUnit() extends Module {
io.is_jump := true.B; io.is_jump := true.B;
} }
} }
// Implements functions for all instruction of the OpStore kind
def opStore(funct3: UInt, io: CUInterface) = {
// Meaning of Funct3 in the context of an OpStore instruction
object Funct3 extends ChiselEnum {
val SB = "b000".U
val SH = "b001".U
val SW = "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.memory_we := true.B
switch(funct3) {
is(Funct3.SB) {
io.memory_size := DMemSize.Byte
}
is(Funct3.SH) {
io.memory_size := DMemSize.Half
}
is(Funct3.SW) {
io.memory_size := DMemSize.Word
}
}
}
} }

View File

@@ -0,0 +1,50 @@
package projet
import chisel3._
import chisel3.util.switch
import chisel3.util.is
object DMemSize extends ChiselEnum {
val Byte, Half, Word = Value
}
class DMem extends Module {
val io = IO(new Bundle {
val dbus = Flipped(new BusInterface)
// The size of the input data
val size = Input(DMemSize())
val en = Input(Bool())
val we = Input(Bool())
val addr = Input(UInt(32.W))
val data_in = Input(UInt(32.W))
val data_out = Output(UInt(32.W))
})
io.dbus.addr := io.addr;
io.dbus.en := io.en;
val bytes_enabled = VecInit(false.B, false.B, false.B, false.B)
val data = WireInit(0.U)
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)
}
is(DMemSize.Half) {
bytes_enabled(io.addr(1) * 2.U(2.W)) := true.B
bytes_enabled(io.addr(1) * 2.U(2.W) + 1.U(2.W)) := true.B
data := io.data_in << (io.addr(1) * 16.U)
}
is(DMemSize.Word) {
bytes_enabled :=
VecInit(true.B, true.B, true.B, true.B)
data := io.data_in
}
}
}
io.dbus.be := bytes_enabled
io.dbus.wdata := data
}

View File

@@ -36,6 +36,11 @@ class ImmediateDecoder extends Module {
io.instruction(11, 8), io.instruction(11, 8),
0.U 0.U
) )
val imm_s = Cat(
Fill(20, io.instruction(31)),
io.instruction(31, 25),
io.instruction(11, 7)
)
switch(io.op_type) { switch(io.op_type) {
is(OpType.U) { is(OpType.U) {
@@ -53,5 +58,8 @@ class ImmediateDecoder extends Module {
is(OpType.B) { is(OpType.B) {
io.immediate := imm_b io.immediate := imm_b
} }
is(OpType.S) {
io.immediate := imm_s
}
} }
} }

View File

@@ -22,6 +22,11 @@ class Rv32i(sim: Boolean = true) extends Module {
val alu = Module(new Alu()); val alu = Module(new Alu());
val immediate_decoder = Module(new ImmediateDecoder()); val immediate_decoder = Module(new ImmediateDecoder());
val control_unit = Module(new ControlUnit()); val control_unit = Module(new ControlUnit());
val dmem = Module(new DMem());
dmem.io.dbus <> io.dbus
dmem.io.en := control_unit.io.memory_en
dmem.io.we := control_unit.io.memory_we
dmem.io.size := control_unit.io.memory_size
control_unit.io.alu_comp_result := alu.io.comp_result control_unit.io.alu_comp_result := alu.io.comp_result
@@ -90,13 +95,10 @@ class Rv32i(sim: Boolean = true) extends Module {
writeback_line writeback_line
); );
io.dbus.addr := 0.U; dmem.io.data_in := rs2
io.dbus.wdata := 0.U; dmem.io.addr := writeback_line
io.dbus.be := VecInit(false.B, false.B, false.B, false.B)
io.dbus.en := false.B;
io.ibus.wdata := 0.U; io.ibus.wdata := 0.U;
io.ibus.be := VecInit(false.B, false.B, false.B, false.B) io.ibus.be := VecInit(false.B, false.B, false.B, false.B)
// locally(sim)
} }