Implements stage 5
This commit is contained in:
8
.asm-lsp.toml
Normal file
8
.asm-lsp.toml
Normal 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
18
bench/addi.s
Normal 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
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
31
src/main/scala/projet/ImmediateDecoder.scala
Normal file
31
src/main/scala/projet/ImmediateDecoder.scala
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,18 +32,14 @@ class RegFile(sim: Boolean = false) extends Module {
|
||||
io.rs2_data := regs(io.rs2_addr)
|
||||
|
||||
// Simulation stuff
|
||||
val valid = WireInit(false.B);
|
||||
when(io.we && io.rd_addr === 31.U)
|
||||
{
|
||||
if (sim) {
|
||||
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) {
|
||||
valid := true.B
|
||||
io.valid_x31.get := true.B
|
||||
}
|
||||
}.otherwise
|
||||
{
|
||||
io.x31 := regs(31)
|
||||
}
|
||||
if (sim) {
|
||||
io.valid_x31.get := Delay.Delay(valid, 1, false.B)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,15 +51,18 @@ 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;
|
||||
val imm = immediate_decoder.io.immediate
|
||||
|
||||
reg_file.io.rd_data := Mux(control_unit.io.mux_imm_alu, alu.io.out, imm_u);
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user