From ed04c13a7677a4e49123d8c772dceb47bf3d9d71 Mon Sep 17 00:00:00 2001 From: supersurviveur Date: Mon, 17 Nov 2025 17:47:52 +0100 Subject: [PATCH] Refactor Rv64i --- src/main/scala/projet/Alu.scala | 146 +++++++++++++------------- src/main/scala/projet/Constants.scala | 2 +- src/main/scala/projet/Rv64i.scala | 53 +++++----- 3 files changed, 101 insertions(+), 100 deletions(-) diff --git a/src/main/scala/projet/Alu.scala b/src/main/scala/projet/Alu.scala index 3c44fde..fd60136 100644 --- a/src/main/scala/projet/Alu.scala +++ b/src/main/scala/projet/Alu.scala @@ -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( diff --git a/src/main/scala/projet/Constants.scala b/src/main/scala/projet/Constants.scala index b74f896..def0bec 100644 --- a/src/main/scala/projet/Constants.scala +++ b/src/main/scala/projet/Constants.scala @@ -1,5 +1,5 @@ package projet object Constants { - def DIVISION_CYCLES_COUNT = 32 + def DIVISION_CYCLES_COUNT = 64 } diff --git a/src/main/scala/projet/Rv64i.scala b/src/main/scala/projet/Rv64i.scala index 2a464c2..67eae89 100644 --- a/src/main/scala/projet/Rv64i.scala +++ b/src/main/scala/projet/Rv64i.scala @@ -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 }