Reduces LUT needed by mul extension
This commit is contained in:
82
src/main/scala/projet/Divider.scala
Normal file
82
src/main/scala/projet/Divider.scala
Normal file
@@ -0,0 +1,82 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user