Implements stage 5

This commit is contained in:
2025-11-05 20:01:41 +01:00
parent 5df85799ef
commit 1462563e39
6 changed files with 107 additions and 29 deletions

8
.asm-lsp.toml Normal file
View File

@@ -0,0 +1,8 @@
[default_config]
version = "0.10.1"
assembler = "gas"
instruction_set = "riscv"
[default_config.opts]
diagnostics = true
default_diagnostics = true

18
bench/addi.s Normal file
View File

@@ -0,0 +1,18 @@
# expected: dead0000, dead0001, fffff800, ffffffff, 00000000
.text
_start:
lui x2, 0xdead0
lui x3, 0x0
# Add 0
addi x31, x2, 0x0
# Basic addition
addi x31, x2, 0x1
# Sign extension
addi x31, x3, -2048
addi x31, x3, -1
# Overflow
addi x31, x31, 0x1

View File

@@ -8,32 +8,52 @@ class CUInterface extends Bundle {
val instruction = Input(UInt(32.W))
val reg_file_we = Output(Bool())
val alu_opcode = Output(AluOpCode())
val optype = Output(OpType())
val mux_imm_alu = Output(Bool())
val mux_alu_imm = Output(Bool())
val mux_rega_pc = Output(Bool())
}
object OPCode extends ChiselEnum {
object OpType extends ChiselEnum {
val U, I = Value
}
object OpCode extends ChiselEnum {
val LUI = 0b0110111.U
val AUIPC = 0b0010111.U
val ADDI = 0b0010011.U
}
class ControlUnit() extends Module {
import OPCode._
import OpCode._
val io = IO(new CUInterface())
io.reg_file_we := false.B
io.alu_opcode := AluOpCode.Add
io.mux_imm_alu := false.B;
io.optype := OpType.U
io.mux_alu_imm := true.B;
io.mux_rega_pc := true.B;
switch(io.instruction(6, 0)) {
// U instructions
is(LUI) {
io.reg_file_we := true.B
io.mux_imm_alu := false.B;
io.mux_alu_imm := false.B
io.optype := OpType.U
}
is(AUIPC) {
io.alu_opcode := AluOpCode.Add
io.reg_file_we := true.B
io.mux_imm_alu := true.B;
io.mux_rega_pc := false.B
io.optype := OpType.U
}
// I instructions
is(ADDI) {
io.alu_opcode := AluOpCode.Add
io.reg_file_we := true.B
io.optype := OpType.I
}
}
}

View File

@@ -0,0 +1,31 @@
package projet
import chisel3._
import chisel3.util.switch
import chisel3.util.is
import chisel3.util.Cat
import chisel3.util.Fill
class ImmediateDecoder extends Module {
import projet.OpType
val io = IO(new Bundle {
val op_type = Input(OpType())
val instruction = Input(UInt(32.W))
val immediate = Output(UInt(32.W))
})
io.immediate := 0.U
// Decode imm-u
val imm_u = Cat(io.instruction(31, 12), 0.U(12.W));
// Decode imm-i
val imm_i = Cat(Fill(20, io.instruction(31)), io.instruction(31, 20));
switch(io.op_type) {
is(OpType.U) {
io.immediate := imm_u
}
is(OpType.I) {
io.immediate := imm_i
}
}
}

View File

@@ -25,25 +25,21 @@ class RegFile(sim: Boolean = false) extends Module {
}
when(io.we && io.rd_addr =/= 0.U) {
regs(io.rd_addr) := io.rd_data
regs(io.rd_addr) := io.rd_data
}
io.rs1_data := regs(io.rs1_addr)
io.rs2_data := regs(io.rs2_addr)
// Simulation stuff
val valid = WireInit(false.B);
when(io.we && io.rd_addr === 31.U)
{
io.x31 := io.rd_data
if (sim) {
valid := true.B
}
}.otherwise
{
io.x31 := regs(31)
}
if (sim) {
io.valid_x31.get := Delay.Delay(valid, 1, false.B)
io.valid_x31.get := false.B
}
io.x31 := "hDEADC0DE".U
when(io.we && io.rd_addr === 31.U) {
io.x31 := io.rd_data
if (sim) {
io.valid_x31.get := true.B
}
}
}

View File

@@ -1,7 +1,6 @@
package projet
import chisel3._
import chisel3.util.Cat
class Rv32i(sim: Boolean = true) extends Module {
val io = IO(new Bundle {
@@ -18,12 +17,15 @@ class Rv32i(sim: Boolean = true) extends Module {
reg_file.io.rd_data := 0.U;
io.x31 := reg_file.io.x31
if (sim) {
io.valid_x31.get := reg_file.io.valid_x31.get
io.valid_x31.get := reg_file.io.valid_x31.get && Delay.Delay(!reset.asBool, 1, false.B)
}
val alu = Module(new Alu());
val immediate_decoder = Module(new ImmediateDecoder());
val control_unit = Module(new ControlUnit());
immediate_decoder.io.instruction := instruction
immediate_decoder.io.op_type := control_unit.io.optype
alu.io.opcode := control_unit.io.alu_opcode;
reg_file.io.we := control_unit.io.reg_file_we
@@ -49,16 +51,19 @@ class Rv32i(sim: Boolean = true) extends Module {
val rd = instruction(11, 7)
reg_file.io.rd_addr := rd
// Decode imm-u
val imm_u = Cat(instruction(31, 12), 0.U(12.W));
// EXECUTE
alu.io.a := execute_pc;
alu.io.b := imm_u;
reg_file.io.rd_data := Mux(control_unit.io.mux_imm_alu, alu.io.out, imm_u);
val imm = immediate_decoder.io.immediate
alu.io.a := Mux(
control_unit.io.mux_rega_pc,
reg_file.io.rs1_data,
execute_pc
);
alu.io.b := imm;
reg_file.io.rd_data := Mux(control_unit.io.mux_alu_imm, alu.io.out, imm);
io.dbus.addr := 0.U;
io.dbus.wdata := 0.U;
io.dbus.be := VecInit(false.B, false.B, false.B, false.B)