Lays groundword for Rv64i extension
Some base files had to be modified to support 64-bit architecture as well as the Makefile to load 64-bit words into memory
This commit is contained in:
153
src/main/scala/projet/Rv64i.scala
Normal file
153
src/main/scala/projet/Rv64i.scala
Normal file
@@ -0,0 +1,153 @@
|
||||
package projet
|
||||
|
||||
import chisel3._
|
||||
|
||||
class Rv64i(sim: Boolean = true) extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val ibus = Flipped(new BusInterface)
|
||||
val dbus = Flipped(new BusInterface)
|
||||
val x31 = Output(UInt(64.W))
|
||||
val valid_x31 = if (sim) Some(Output(Bool())) else None
|
||||
})
|
||||
|
||||
val reg_pc = RegInit(0.U(64.W));
|
||||
val reg_file = Module(new RegFile(sim));
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
dmem.io.sign_extend := control_unit.io.memory_sign_extend
|
||||
|
||||
control_unit.io.alu_comp_result := alu.io.comp_result
|
||||
|
||||
// PC delayed to execute stage for auipc op
|
||||
val execute_pc = Delay.Delay(reg_pc, 1, 0.U);
|
||||
// True if the instruction in the execute stage is a jump
|
||||
val is_jump = Delay.Delay(control_unit.io.is_jump, 1, false.B);
|
||||
|
||||
// Pipelining registers for mem stage
|
||||
val reg_rd_index = RegInit(0.U);
|
||||
val reg_execute_out = RegInit(0.U);
|
||||
val reg_mux_executeout_dout = RegInit(true.B);
|
||||
val reg_regile_we = RegInit(false.B);
|
||||
|
||||
// Insert no-op if jump
|
||||
val instruction =
|
||||
Mux(
|
||||
is_jump,
|
||||
"b00000000000000000000000000010011".U,
|
||||
io.ibus.rdata >> (execute_pc(2) * 32.U)
|
||||
);
|
||||
|
||||
immediate_decoder.io.instruction := instruction
|
||||
immediate_decoder.io.op_type := control_unit.io.optype
|
||||
alu.io.opcode := control_unit.io.alu_opcode;
|
||||
|
||||
// Reg file write-enable
|
||||
reg_regile_we := control_unit.io.reg_file_we;
|
||||
reg_file.io.we := reg_regile_we;
|
||||
|
||||
// Increment PC each clock
|
||||
val pc_adder_out = Mux(
|
||||
control_unit.io.mux_regpc_executepc,
|
||||
reg_pc,
|
||||
execute_pc
|
||||
) + Mux(
|
||||
control_unit.io.mux_incrpc4_imm,
|
||||
4.U,
|
||||
immediate_decoder.io.immediate
|
||||
);
|
||||
|
||||
// Fetch instruction
|
||||
io.ibus.en := true.B;
|
||||
io.ibus.addr := reg_pc;
|
||||
|
||||
control_unit.io.instruction := instruction;
|
||||
|
||||
// Decode rs1 index
|
||||
val rs1_index = instruction(19, 15)
|
||||
reg_file.io.rs1_addr := rs1_index
|
||||
// Decode rs2 index
|
||||
val rs2_index = instruction(24, 20)
|
||||
reg_file.io.rs2_addr := rs2_index
|
||||
// Decode rd index
|
||||
val rd_index = instruction(11, 7)
|
||||
reg_rd_index := rd_index;
|
||||
reg_file.io.rd_addr := reg_rd_index;
|
||||
|
||||
val writeback_line = Mux(
|
||||
reg_mux_executeout_dout,
|
||||
reg_execute_out,
|
||||
dmem.io.data_out
|
||||
);
|
||||
val rs1_data =
|
||||
Mux(
|
||||
rs1_index === reg_rd_index && rs1_index =/= 0.U,
|
||||
writeback_line,
|
||||
reg_file.io.rs1_data
|
||||
)
|
||||
val rs2_data =
|
||||
Mux(
|
||||
rs2_index === reg_rd_index && rs2_index =/= 0.U,
|
||||
writeback_line,
|
||||
reg_file.io.rs2_data
|
||||
)
|
||||
|
||||
// EXECUTE
|
||||
|
||||
val imm = immediate_decoder.io.immediate
|
||||
|
||||
alu.io.a := Mux(
|
||||
control_unit.io.mux_rega_pc,
|
||||
rs1_data,
|
||||
execute_pc
|
||||
);
|
||||
alu.io.b := Mux(control_unit.io.mux_regb_imm, rs2_data, imm);
|
||||
|
||||
// Select what to send on writeback line
|
||||
val execute_out = Mux(control_unit.io.mux_alu_imm, alu.io.out, imm);
|
||||
reg_execute_out := execute_out;
|
||||
|
||||
reg_mux_executeout_dout := control_unit.io.mux_executeout_dout;
|
||||
|
||||
reg_file.io.rd_data :=
|
||||
Mux(
|
||||
Delay.Delay(control_unit.io.mux_writeback_pc, 1, true.B),
|
||||
writeback_line,
|
||||
Delay.Delay(reg_pc, 1, 0.U)
|
||||
);
|
||||
|
||||
// Writeback pipelining registers
|
||||
reg_pc := Mux(
|
||||
Delay.Delay(control_unit.io.mux_pcadder_writeback, 1, true.B),
|
||||
pc_adder_out,
|
||||
writeback_line
|
||||
);
|
||||
|
||||
dmem.io.data_in := rs2_data
|
||||
dmem.io.addr := execute_out
|
||||
|
||||
io.ibus.wdata := 0.U;
|
||||
io.ibus.be := VecInit(
|
||||
false.B,
|
||||
false.B,
|
||||
false.B,
|
||||
false.B,
|
||||
false.B,
|
||||
false.B,
|
||||
false.B,
|
||||
false.B
|
||||
)
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user