Stage 10: not tested
This commit is contained in:
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
50
src/main/scala/projet/DMem.scala
Normal file
50
src/main/scala/projet/DMem.scala
Normal 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
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user