Refactor Rv64i
This commit is contained in:
@@ -65,19 +65,19 @@ class Alu extends Module {
|
||||
|
||||
val in_computation = RegInit(false.B)
|
||||
|
||||
// // Division
|
||||
// val divider = Module(new Divider(64, Constants.DIVISION_CYCLES_COUNT))
|
||||
// divider.io.word_mode := io.word_mode
|
||||
// divider.io.dividend := op_a_unsigned
|
||||
// divider.io.divisor := op_b_unsigned
|
||||
// divider.io.start := false.B
|
||||
// def div_by_zero() = {
|
||||
// when(io.word_mode) {
|
||||
// out := (-1).S(32.W).asUInt
|
||||
// }.otherwise {
|
||||
// out := (-1).S(64.W).asUInt
|
||||
// }
|
||||
// }
|
||||
// Division
|
||||
val divider = Module(new Divider(64, Constants.DIVISION_CYCLES_COUNT))
|
||||
divider.io.word_mode := io.word_mode
|
||||
divider.io.dividend := op_a_unsigned
|
||||
divider.io.divisor := op_b_unsigned
|
||||
divider.io.start := false.B
|
||||
def div_by_zero() = {
|
||||
when(io.word_mode) {
|
||||
out := (-1).S(32.W).asUInt
|
||||
}.otherwise {
|
||||
out := (-1).S(64.W).asUInt
|
||||
}
|
||||
}
|
||||
|
||||
// Multiplication
|
||||
val multiplication_res = op_a * op_b // Mul non signée
|
||||
@@ -123,54 +123,54 @@ class Alu extends Module {
|
||||
out := multiplication_high;
|
||||
}
|
||||
|
||||
// is(Div) {
|
||||
// when(op_b === 0.U) {
|
||||
// div_by_zero()
|
||||
// }.elsewhen(op_a_sign ^ op_b_sign) {
|
||||
// out := Utils.two_complement(divider.io.quotient, io.word_mode)
|
||||
// }.otherwise {
|
||||
// out := divider.io.quotient
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// is(Divu) {
|
||||
// divider.io.dividend := op_a
|
||||
// divider.io.divisor := op_b
|
||||
// when(op_b === 0.U) {
|
||||
// div_by_zero()
|
||||
// }.otherwise { out := divider.io.quotient; }
|
||||
// }
|
||||
//
|
||||
// is(Rem) {
|
||||
// when(op_b === 0.U) {
|
||||
// out := op_a
|
||||
// }.elsewhen(
|
||||
// op_a_sign && !op_b_sign && divider.io.remainder =/= 0.U
|
||||
// ) {
|
||||
// out := op_b - divider.io.remainder
|
||||
// }.elsewhen(
|
||||
// !op_a_sign && op_b_sign && divider.io.remainder =/= 0.U
|
||||
// ) {
|
||||
// out := Utils.two_complement(
|
||||
// Utils.two_complement(op_b) - divider.io.remainder,
|
||||
// io.word_mode
|
||||
// )
|
||||
// }.elsewhen(op_a_sign && op_b_sign) {
|
||||
// out := Utils.two_complement(divider.io.remainder, io.word_mode)
|
||||
// }.otherwise {
|
||||
// out := divider.io.remainder
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// is(Remu) {
|
||||
// divider.io.dividend := op_a
|
||||
// divider.io.divisor := op_b
|
||||
// when(op_b === 0.U) {
|
||||
// out := op_a
|
||||
// }.otherwise {
|
||||
// out := divider.io.remainder
|
||||
// }
|
||||
// }
|
||||
is(Div) {
|
||||
when(op_b === 0.U) {
|
||||
div_by_zero()
|
||||
}.elsewhen(op_a_sign ^ op_b_sign) {
|
||||
out := Utils.two_complement(divider.io.quotient, io.word_mode)
|
||||
}.otherwise {
|
||||
out := divider.io.quotient
|
||||
}
|
||||
}
|
||||
|
||||
is(Divu) {
|
||||
divider.io.dividend := op_a
|
||||
divider.io.divisor := op_b
|
||||
when(op_b === 0.U) {
|
||||
div_by_zero()
|
||||
}.otherwise { out := divider.io.quotient; }
|
||||
}
|
||||
|
||||
is(Rem) {
|
||||
when(op_b === 0.U) {
|
||||
out := op_a
|
||||
}.elsewhen(
|
||||
op_a_sign && !op_b_sign && divider.io.remainder =/= 0.U
|
||||
) {
|
||||
out := op_b - divider.io.remainder
|
||||
}.elsewhen(
|
||||
!op_a_sign && op_b_sign && divider.io.remainder =/= 0.U
|
||||
) {
|
||||
out := Utils.two_complement(
|
||||
Utils.two_complement(op_b) - divider.io.remainder,
|
||||
io.word_mode
|
||||
)
|
||||
}.elsewhen(op_a_sign && op_b_sign) {
|
||||
out := Utils.two_complement(divider.io.remainder, io.word_mode)
|
||||
}.otherwise {
|
||||
out := divider.io.remainder
|
||||
}
|
||||
}
|
||||
|
||||
is(Remu) {
|
||||
divider.io.dividend := op_a
|
||||
divider.io.divisor := op_b
|
||||
when(op_b === 0.U) {
|
||||
out := op_a
|
||||
}.otherwise {
|
||||
out := divider.io.remainder
|
||||
}
|
||||
}
|
||||
|
||||
is(And) {
|
||||
out := op_a & op_b;
|
||||
@@ -231,18 +231,18 @@ class Alu extends Module {
|
||||
}
|
||||
}
|
||||
|
||||
// switch(io.opcode) {
|
||||
// is(Div, Divu, Rem, Remu) {
|
||||
// when(!in_computation) {
|
||||
// divider.io.start := true.B
|
||||
// in_computation := true.B
|
||||
// }.elsewhen(divider.io.ready) {
|
||||
// io.should_stop_stall := true.B
|
||||
// in_computation := false.B
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
switch(io.opcode) {
|
||||
is(Div, Divu, Rem, Remu) {
|
||||
when(!in_computation) {
|
||||
divider.io.start := true.B
|
||||
in_computation := true.B
|
||||
}.elsewhen(divider.io.ready) {
|
||||
io.should_stop_stall := true.B
|
||||
in_computation := false.B
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Special overflow cases for Div and Rem
|
||||
when(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
package projet
|
||||
|
||||
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 reg_pc = RegInit("x10000".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
|
||||
}
|
||||
|
||||
// Define components
|
||||
val alu = Module(new Alu());
|
||||
val immediate_decoder = Module(new ImmediateDecoder());
|
||||
val control_unit = Module(new ControlUnit());
|
||||
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.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
|
||||
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) {
|
||||
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)
|
||||
)
|
||||
|
||||
// Manage the stalled state of the processor
|
||||
val stalled_instruction = RegInit(0.U)
|
||||
val 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
|
||||
}
|
||||
|
||||
// Currently executed instruction
|
||||
val instruction = Mux(is_stalled, stalled_instruction, decoded_instruction)
|
||||
|
||||
// Pipelining registers for mem stage
|
||||
@@ -167,18 +180,6 @@ class Rv64i(sim: Boolean = true) extends Module {
|
||||
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
|
||||
)
|
||||
|
||||
when(is_immediatly_stalled) {
|
||||
reg_pc := reg_pc
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user