Refactor Rv64i
This commit is contained in:
@@ -65,19 +65,19 @@ class Alu extends Module {
|
|||||||
|
|
||||||
val in_computation = RegInit(false.B)
|
val in_computation = RegInit(false.B)
|
||||||
|
|
||||||
// // Division
|
// Division
|
||||||
// val divider = Module(new Divider(64, Constants.DIVISION_CYCLES_COUNT))
|
val divider = Module(new Divider(64, Constants.DIVISION_CYCLES_COUNT))
|
||||||
// divider.io.word_mode := io.word_mode
|
divider.io.word_mode := io.word_mode
|
||||||
// divider.io.dividend := op_a_unsigned
|
divider.io.dividend := op_a_unsigned
|
||||||
// divider.io.divisor := op_b_unsigned
|
divider.io.divisor := op_b_unsigned
|
||||||
// divider.io.start := false.B
|
divider.io.start := false.B
|
||||||
// def div_by_zero() = {
|
def div_by_zero() = {
|
||||||
// when(io.word_mode) {
|
when(io.word_mode) {
|
||||||
// out := (-1).S(32.W).asUInt
|
out := (-1).S(32.W).asUInt
|
||||||
// }.otherwise {
|
}.otherwise {
|
||||||
// out := (-1).S(64.W).asUInt
|
out := (-1).S(64.W).asUInt
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// Multiplication
|
// Multiplication
|
||||||
val multiplication_res = op_a * op_b // Mul non signée
|
val multiplication_res = op_a * op_b // Mul non signée
|
||||||
@@ -123,54 +123,54 @@ class Alu extends Module {
|
|||||||
out := multiplication_high;
|
out := multiplication_high;
|
||||||
}
|
}
|
||||||
|
|
||||||
// is(Div) {
|
is(Div) {
|
||||||
// when(op_b === 0.U) {
|
when(op_b === 0.U) {
|
||||||
// div_by_zero()
|
div_by_zero()
|
||||||
// }.elsewhen(op_a_sign ^ op_b_sign) {
|
}.elsewhen(op_a_sign ^ op_b_sign) {
|
||||||
// out := Utils.two_complement(divider.io.quotient, io.word_mode)
|
out := Utils.two_complement(divider.io.quotient, io.word_mode)
|
||||||
// }.otherwise {
|
}.otherwise {
|
||||||
// out := divider.io.quotient
|
out := divider.io.quotient
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// is(Divu) {
|
is(Divu) {
|
||||||
// divider.io.dividend := op_a
|
divider.io.dividend := op_a
|
||||||
// divider.io.divisor := op_b
|
divider.io.divisor := op_b
|
||||||
// when(op_b === 0.U) {
|
when(op_b === 0.U) {
|
||||||
// div_by_zero()
|
div_by_zero()
|
||||||
// }.otherwise { out := divider.io.quotient; }
|
}.otherwise { out := divider.io.quotient; }
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// is(Rem) {
|
is(Rem) {
|
||||||
// when(op_b === 0.U) {
|
when(op_b === 0.U) {
|
||||||
// out := op_a
|
out := op_a
|
||||||
// }.elsewhen(
|
}.elsewhen(
|
||||||
// op_a_sign && !op_b_sign && divider.io.remainder =/= 0.U
|
op_a_sign && !op_b_sign && divider.io.remainder =/= 0.U
|
||||||
// ) {
|
) {
|
||||||
// out := op_b - divider.io.remainder
|
out := op_b - divider.io.remainder
|
||||||
// }.elsewhen(
|
}.elsewhen(
|
||||||
// !op_a_sign && op_b_sign && divider.io.remainder =/= 0.U
|
!op_a_sign && op_b_sign && divider.io.remainder =/= 0.U
|
||||||
// ) {
|
) {
|
||||||
// out := Utils.two_complement(
|
out := Utils.two_complement(
|
||||||
// Utils.two_complement(op_b) - divider.io.remainder,
|
Utils.two_complement(op_b) - divider.io.remainder,
|
||||||
// io.word_mode
|
io.word_mode
|
||||||
// )
|
)
|
||||||
// }.elsewhen(op_a_sign && op_b_sign) {
|
}.elsewhen(op_a_sign && op_b_sign) {
|
||||||
// out := Utils.two_complement(divider.io.remainder, io.word_mode)
|
out := Utils.two_complement(divider.io.remainder, io.word_mode)
|
||||||
// }.otherwise {
|
}.otherwise {
|
||||||
// out := divider.io.remainder
|
out := divider.io.remainder
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// is(Remu) {
|
is(Remu) {
|
||||||
// divider.io.dividend := op_a
|
divider.io.dividend := op_a
|
||||||
// divider.io.divisor := op_b
|
divider.io.divisor := op_b
|
||||||
// when(op_b === 0.U) {
|
when(op_b === 0.U) {
|
||||||
// out := op_a
|
out := op_a
|
||||||
// }.otherwise {
|
}.otherwise {
|
||||||
// out := divider.io.remainder
|
out := divider.io.remainder
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
is(And) {
|
is(And) {
|
||||||
out := op_a & op_b;
|
out := op_a & op_b;
|
||||||
@@ -231,18 +231,18 @@ class Alu extends Module {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// switch(io.opcode) {
|
switch(io.opcode) {
|
||||||
// is(Div, Divu, Rem, Remu) {
|
is(Div, Divu, Rem, Remu) {
|
||||||
// when(!in_computation) {
|
when(!in_computation) {
|
||||||
// divider.io.start := true.B
|
divider.io.start := true.B
|
||||||
// in_computation := true.B
|
in_computation := true.B
|
||||||
// }.elsewhen(divider.io.ready) {
|
}.elsewhen(divider.io.ready) {
|
||||||
// io.should_stop_stall := true.B
|
io.should_stop_stall := true.B
|
||||||
// in_computation := false.B
|
in_computation := false.B
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
|
|
||||||
// Special overflow cases for Div and Rem
|
// Special overflow cases for Div and Rem
|
||||||
when(
|
when(
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
package projet
|
package projet
|
||||||
|
|
||||||
object Constants {
|
object Constants {
|
||||||
def DIVISION_CYCLES_COUNT = 32
|
def DIVISION_CYCLES_COUNT = 64
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,32 +10,43 @@ class Rv64i(sim: Boolean = true) extends Module {
|
|||||||
val valid_x31 = if (sim) Some(Output(Bool())) else None
|
val valid_x31 = if (sim) Some(Output(Bool())) else None
|
||||||
})
|
})
|
||||||
|
|
||||||
val reg_pc = RegInit("x10000".U(64.W));
|
// Define components
|
||||||
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 alu = Module(new Alu());
|
||||||
val immediate_decoder = Module(new ImmediateDecoder());
|
val immediate_decoder = Module(new ImmediateDecoder());
|
||||||
val control_unit = Module(new ControlUnit());
|
val control_unit = Module(new ControlUnit());
|
||||||
val dmem = Module(new DMem());
|
val dmem = Module(new DMem());
|
||||||
|
val reg_file = Module(new RegFile(sim));
|
||||||
|
|
||||||
|
// PC
|
||||||
|
val reg_pc = RegInit("x10000".U(64.W));
|
||||||
|
// PC delayed to execute stage for auipc op
|
||||||
|
val execute_pc = Delay.Delay(reg_pc, 1, "x10000".U(64.W));
|
||||||
|
// True if the instruction in the execute stage is a jump
|
||||||
|
val is_jump = Delay.Delay(control_unit.io.is_jump, 1, false.B);
|
||||||
|
|
||||||
dmem.io.dbus <> io.dbus
|
dmem.io.dbus <> io.dbus
|
||||||
dmem.io.en := control_unit.io.memory_en
|
dmem.io.en := control_unit.io.memory_en
|
||||||
dmem.io.we := control_unit.io.memory_we
|
dmem.io.we := control_unit.io.memory_we
|
||||||
dmem.io.size := control_unit.io.memory_size
|
dmem.io.size := control_unit.io.memory_size
|
||||||
dmem.io.sign_extend := control_unit.io.memory_sign_extend
|
dmem.io.sign_extend := control_unit.io.memory_sign_extend
|
||||||
|
|
||||||
control_unit.io.alu_comp_result := alu.io.comp_result
|
control_unit.io.alu_comp_result := alu.io.comp_result
|
||||||
alu.io.word_mode := control_unit.io.alu_word_mode
|
alu.io.word_mode := control_unit.io.alu_word_mode
|
||||||
|
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
|
||||||
|
)
|
||||||
|
io.x31 := reg_file.io.x31
|
||||||
|
if (sim) {
|
||||||
|
io.valid_x31.get := reg_file.io.valid_x31.get
|
||||||
|
}
|
||||||
|
|
||||||
// PC delayed to execute stage for auipc op
|
|
||||||
val execute_pc = Delay.Delay(reg_pc, 1, "x10000".U(64.W));
|
|
||||||
// True if the instruction in the execute stage is a jump
|
|
||||||
val is_jump = Delay.Delay(control_unit.io.is_jump, 1, false.B);
|
|
||||||
|
|
||||||
if (sim) {
|
if (sim) {
|
||||||
val log = SimLog.file("core_pc.log");
|
val log = SimLog.file("core_pc.log");
|
||||||
@@ -52,6 +63,7 @@ class Rv64i(sim: Boolean = true) extends Module {
|
|||||||
io.ibus.rdata >> (execute_pc(2) * 32.U)
|
io.ibus.rdata >> (execute_pc(2) * 32.U)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Manage the stalled state of the processor
|
||||||
val stalled_instruction = RegInit(0.U)
|
val stalled_instruction = RegInit(0.U)
|
||||||
val should_stop_stall =
|
val should_stop_stall =
|
||||||
control_unit.io.should_stop_stall || alu.io.should_stop_stall
|
control_unit.io.should_stop_stall || alu.io.should_stop_stall
|
||||||
@@ -67,6 +79,7 @@ class Rv64i(sim: Boolean = true) extends Module {
|
|||||||
is_stalled := false.B
|
is_stalled := false.B
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Currently executed instruction
|
||||||
val instruction = Mux(is_stalled, stalled_instruction, decoded_instruction)
|
val instruction = Mux(is_stalled, stalled_instruction, decoded_instruction)
|
||||||
|
|
||||||
// Pipelining registers for mem stage
|
// Pipelining registers for mem stage
|
||||||
@@ -167,18 +180,6 @@ class Rv64i(sim: Boolean = true) extends Module {
|
|||||||
dmem.io.data_in := rs2_data
|
dmem.io.data_in := rs2_data
|
||||||
dmem.io.addr := execute_out
|
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
|
|
||||||
)
|
|
||||||
|
|
||||||
when(is_immediatly_stalled) {
|
when(is_immediatly_stalled) {
|
||||||
reg_pc := reg_pc
|
reg_pc := reg_pc
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user