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
|
||||
val is_jump = Output(Bool())
|
||||
|
||||
// DMem connections
|
||||
val memory_size = Input(DMemSize())
|
||||
val memory_en = Input(Bool())
|
||||
val memory_we = Input(Bool())
|
||||
|
||||
// Muxers
|
||||
// The naming convention is as follows : mux_xxx_yyy.
|
||||
// If the signal is hot, xxx is selected otherwise yyy is selected
|
||||
@@ -43,7 +48,7 @@ class CUInterface extends Bundle {
|
||||
}
|
||||
|
||||
object OpType extends ChiselEnum {
|
||||
val U, I, IR, J, B = Value
|
||||
val U, I, IR, J, B, S = Value
|
||||
}
|
||||
|
||||
object OpCode extends ChiselEnum {
|
||||
@@ -78,6 +83,9 @@ object OpCode extends ChiselEnum {
|
||||
|
||||
// Type B
|
||||
val OpBranch = "b1100011".U
|
||||
|
||||
// Type S
|
||||
val OpStore = "b0100011".U
|
||||
}
|
||||
|
||||
class ControlUnit() extends Module {
|
||||
@@ -87,6 +95,9 @@ class ControlUnit() extends Module {
|
||||
io.alu_opcode := AluOpCode.Add
|
||||
io.optype := OpType.U
|
||||
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_rega_pc := true.B;
|
||||
io.mux_regb_imm := true.B;
|
||||
@@ -164,6 +175,11 @@ class ControlUnit() extends Module {
|
||||
io.optype := OpType.B;
|
||||
opBranch(funct3, io);
|
||||
}
|
||||
|
||||
is(OpCode.OpStore) {
|
||||
io.optype := OpType.S
|
||||
opStore(funct3, io);
|
||||
}
|
||||
}
|
||||
|
||||
// Implements functions for all instruction of the opImm kind
|
||||
@@ -389,4 +405,30 @@ class ControlUnit() extends Module {
|
||||
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),
|
||||
0.U
|
||||
)
|
||||
val imm_s = Cat(
|
||||
Fill(20, io.instruction(31)),
|
||||
io.instruction(31, 25),
|
||||
io.instruction(11, 7)
|
||||
)
|
||||
|
||||
switch(io.op_type) {
|
||||
is(OpType.U) {
|
||||
@@ -53,5 +58,8 @@ class ImmediateDecoder extends Module {
|
||||
is(OpType.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 immediate_decoder = Module(new ImmediateDecoder());
|
||||
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
|
||||
|
||||
@@ -90,13 +95,10 @@ class Rv32i(sim: Boolean = true) extends Module {
|
||||
writeback_line
|
||||
);
|
||||
|
||||
io.dbus.addr := 0.U;
|
||||
io.dbus.wdata := 0.U;
|
||||
io.dbus.be := VecInit(false.B, false.B, false.B, false.B)
|
||||
io.dbus.en := false.B;
|
||||
dmem.io.data_in := rs2
|
||||
dmem.io.addr := writeback_line
|
||||
|
||||
io.ibus.wdata := 0.U;
|
||||
io.ibus.be := VecInit(false.B, false.B, false.B, false.B)
|
||||
|
||||
// locally(sim)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user