Implements stage 3

This commit is contained in:
2025-11-05 17:23:33 +01:00
parent 41c5da1a64
commit 3870e05613
4 changed files with 73 additions and 11 deletions

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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)
}

View File

@@ -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;