From 3870e05613114e30f3ae832295bba92886afb0ea Mon Sep 17 00:00:00 2001 From: supersurviveur Date: Wed, 5 Nov 2025 17:23:33 +0100 Subject: [PATCH] Implements stage 3 --- src/main/scala/projet/ControlUnit.scala | 27 +++++++++++++++++++++++++ src/main/scala/projet/Delay.scala | 16 +++++++++++++++ src/main/scala/projet/RegFile.scala | 15 ++++++++++++++ src/main/scala/projet/Rv32i.scala | 26 ++++++++++++++---------- 4 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 src/main/scala/projet/ControlUnit.scala create mode 100644 src/main/scala/projet/Delay.scala diff --git a/src/main/scala/projet/ControlUnit.scala b/src/main/scala/projet/ControlUnit.scala new file mode 100644 index 0000000..8235a6f --- /dev/null +++ b/src/main/scala/projet/ControlUnit.scala @@ -0,0 +1,27 @@ +package projet + +import chisel3._ +import chisel3.util.switch +import chisel3.util.is + +class CUInterface extends Bundle { + val instruction = Input(UInt(32.W)) + val reg_file_we = Output(Bool()) +} + +object OPCode extends ChiselEnum { + val LUI = 0b0110111.U +} + +class ControlUnit() extends Module { + import OPCode._ + + val io = IO(new CUInterface()) + + io.reg_file_we := false.B + switch(io.instruction(6, 0)) { + is(LUI) { + io.reg_file_we := true.B + } + } +} diff --git a/src/main/scala/projet/Delay.scala b/src/main/scala/projet/Delay.scala new file mode 100644 index 0000000..90f52e0 --- /dev/null +++ b/src/main/scala/projet/Delay.scala @@ -0,0 +1,16 @@ +package projet + +import chisel3.Data +import chisel3.RegInit + +object Delay { + def Delay[T <: Data](x: T, n: Int, init: T): T = { + require(n >= 0) + if (n == 0) x + else { + val reg = RegInit(init); + reg := Delay(x, n - 1, init) + reg + } + } +} diff --git a/src/main/scala/projet/RegFile.scala b/src/main/scala/projet/RegFile.scala index dc8145f..599297a 100644 --- a/src/main/scala/projet/RegFile.scala +++ b/src/main/scala/projet/RegFile.scala @@ -11,6 +11,9 @@ class RegFile(sim: Boolean = false) extends Module { val we = Input(Bool()) val rs1_data = Output(UInt(32.W)) val rs2_data = Output(UInt(32.W)) + + val x31 = Output(UInt(32.W)) + val valid_x31 = if (sim) Some(Output(Bool())) else None }) val regs = Mem(32, UInt(32.W)) @@ -21,9 +24,21 @@ class RegFile(sim: Boolean = false) extends Module { } } + val valid = WireInit(false.B); when(io.we && io.rd_addr =/= 0.U) { regs(io.rd_addr) := io.rd_data + + if (sim) { + when(io.rd_addr === 31.U) { + valid := true.B + } + } + } + if (sim) { + io.valid_x31.get := Delay.Delay(valid, 2, false.B) } io.rs1_data := regs(io.rs1_addr) io.rs2_data := regs(io.rs2_addr) + + io.x31 := regs(31) } diff --git a/src/main/scala/projet/Rv32i.scala b/src/main/scala/projet/Rv32i.scala index e4df6d6..c26d902 100644 --- a/src/main/scala/projet/Rv32i.scala +++ b/src/main/scala/projet/Rv32i.scala @@ -1,6 +1,7 @@ package projet import chisel3._ +import chisel3.util.Cat class Rv32i(sim: Boolean = true) extends Module { val io = IO(new Bundle { @@ -13,7 +14,12 @@ class Rv32i(sim: Boolean = true) extends Module { val reg_pc = RegInit(0.U(32.W)); val reg_file = Module(new RegFile(sim)); reg_file.io.rd_data := 0.U; - reg_file.io.we := 0.U; + io.x31 := reg_file.io.x31 + if (sim) { + io.valid_x31.get := reg_file.io.valid_x31.get + } + val control_unit = Module(new ControlUnit()); + reg_file.io.we := control_unit.io.reg_file_we // Increment PC each clock reg_pc := reg_pc + 4.U; @@ -22,26 +28,24 @@ class Rv32i(sim: Boolean = true) extends Module { io.ibus.en := true.B; io.ibus.addr := reg_pc; - val insn = io.ibus.rdata; + val instruction = io.ibus.rdata; + control_unit.io.instruction := instruction; // Decode rs1 index - val rs1 = insn(19, 15) + val rs1 = instruction(19, 15) reg_file.io.rs1_addr := rs1 // Decode rs2 index - val rs2 = insn(24, 20) + val rs2 = instruction(24, 20) reg_file.io.rs2_addr := rs2 // Decode rd index - val rd = insn(11, 7) + val rd = instruction(11, 7) reg_file.io.rd_addr := rd // Decode imm-u - val imm_u = insn(31, 12) + val imm_u = instruction(31, 12) - // Debug instruction - io.x31 := reg_file.io.rs1_data; - if (sim) { - io.valid_x31.get := true.B; - } + // Send imm-u to the register file + reg_file.io.rd_data := Cat(imm_u, 0.U(12.W)) io.dbus.addr := 0.U; io.dbus.wdata := 0.U;