83 lines
2.4 KiB
Scala
83 lines
2.4 KiB
Scala
package projet
|
|
|
|
import chisel3._
|
|
import chisel3.util._
|
|
|
|
class Divider(width: Int, nCycles: Int) extends Module {
|
|
require(
|
|
nCycles >= 1 && nCycles <= width,
|
|
"nCycles must be between 1 and width"
|
|
)
|
|
|
|
val io = IO(new Bundle {
|
|
val dividend = Input(UInt(width.W))
|
|
val divisor = Input(UInt(width.W))
|
|
val word_mode = Input(Bool())
|
|
val start = Input(Bool())
|
|
val ready = Output(Bool())
|
|
val quotient = Output(UInt(width.W))
|
|
val remainder = Output(UInt(width.W))
|
|
})
|
|
|
|
val reg_dividend = Reg(UInt(width.W))
|
|
val reg_divisor = Reg(UInt((width * 2).W))
|
|
val reg_divisor_start = Reg(UInt(width.W))
|
|
val reg_quotient = Reg(UInt(width.W))
|
|
val reg_current_shift = Reg(UInt((log2Ceil(width) + 1).W))
|
|
|
|
val bits_per_cycle = ((width + nCycles - 1) / nCycles)
|
|
|
|
val cycles_remaining = RegInit(0.U(log2Ceil(nCycles + 1).W))
|
|
val busy = RegInit(false.B)
|
|
|
|
io.ready := !busy
|
|
io.quotient := reg_quotient
|
|
io.remainder := reg_dividend(width - 1, 0)
|
|
|
|
when(io.start && !busy) {
|
|
reg_dividend := io.dividend
|
|
reg_divisor := io.divisor << (width - 1)
|
|
reg_divisor_start := io.divisor
|
|
reg_quotient := 0.U
|
|
reg_current_shift := (width - 1).U
|
|
cycles_remaining := nCycles.U
|
|
busy := true.B
|
|
}
|
|
|
|
when(busy) {
|
|
val stages = Wire(Vec(bits_per_cycle + 1, UInt(width.W)))
|
|
val dstages = Wire(Vec(bits_per_cycle + 1, UInt((width * 2).W)))
|
|
val qstages = Wire(Vec(bits_per_cycle + 1, UInt(width.W)))
|
|
|
|
stages(0) := reg_dividend
|
|
dstages(0) := reg_divisor
|
|
qstages(0) := reg_quotient
|
|
|
|
for (i <- 0 until bits_per_cycle) {
|
|
val cur = stages(i)
|
|
val curD = dstages(i)
|
|
val curQ = qstages(i)
|
|
|
|
when(cur >= curD) {
|
|
stages(i + 1) := cur - curD
|
|
qstages(i + 1) := curQ + (1.U << (reg_current_shift - i.U))
|
|
}.otherwise {
|
|
stages(i + 1) := cur
|
|
qstages(i + 1) := curQ
|
|
|
|
}
|
|
dstages(i + 1) := curD >> 1
|
|
}
|
|
|
|
reg_dividend := stages(bits_per_cycle)
|
|
reg_divisor := dstages(bits_per_cycle)
|
|
reg_quotient := qstages(bits_per_cycle)
|
|
reg_current_shift := reg_current_shift - bits_per_cycle.U
|
|
|
|
cycles_remaining := cycles_remaining - 1.U
|
|
when(cycles_remaining === 1.U) {
|
|
busy := false.B
|
|
}
|
|
}
|
|
}
|