xref: /XiangShan/src/main/scala/xiangshan/backend/fu/SRT16Divider.scala (revision c49ebec88f6e402aefec681225e3537e2c511430)
1/***************************************************************************************
2* Copyright (c) 2024 Beijing Institute of Open Source Chip (BOSC)
3* Copyright (c) 2020-2024 Institute of Computing Technology, Chinese Academy of Sciences
4* Copyright (c) 2020-2021 Peng Cheng Laboratory
5*
6* XiangShan is licensed under Mulan PSL v2.
7* You can use this software according to the terms and conditions of the Mulan PSL v2.
8* You may obtain a copy of Mulan PSL v2 at:
9*          http://license.coscl.org.cn/MulanPSL2
10*
11* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
12* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
13* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
14*
15* See the Mulan PSL v2 for more details.
16*
17*
18* Acknowledgement
19*
20* This implementation is inspired by several key papers:
21* [1] Elisardo Antelo, Tomas Lang, Paolo Montuschi, and Alberto Nannarelli. "[Digit-recurrence dividers with reduced
22* logical depth.](https://doi.org/10.1109/TC.2005.115)" IEEE Transactions on Computers 54.7: 837-851. 2005.
23***************************************************************************************/
24
25// This file contains components originally written by Yifei He, see
26// https://github.com/OpenXiangShan/XS-Verilog-Library/tree/main/int_div_radix_4_v1
27// Email of original author: [email protected]
28
29package xiangshan.backend.fu
30
31import org.chipsalliance.cde.config.Parameters
32import chisel3._
33import chisel3.util._
34import utils._
35import utility._
36import xiangshan._
37import xiangshan.backend.fu.util.CSA3_2
38
39class SRT16DividerDataModule(len: Int) extends Module {
40  val io = IO(new Bundle() {
41    val src = Vec(2, Input(UInt(len.W)))
42    val valid, sign, kill_w, kill_r, isHi, isW = Input(Bool())
43    val in_ready = Output(Bool())
44    val out_valid = Output(Bool())
45    val out_validNext = Output(Bool())
46    val out_data = Output(UInt(len.W))
47    val out_ready = Input(Bool())
48  })
49
50  // consts
51  val lzc_width = log2Up(len)
52  val itn_len = 1 + len + 2 + 1
53
54  val (a, d, sign, valid, kill_w, kill_r, isHi, isW) =
55    (io.src(0), io.src(1), io.sign, io.valid, io.kill_w, io.kill_r, io.isHi, io.isW)
56  val in_fire = valid && io.in_ready
57  val out_fire = io.out_ready && io.out_valid
58  val newReq = in_fire
59  val s_idle :: s_pre_0 :: s_pre_1 :: s_iter :: s_post_0 :: s_post_1 :: s_finish :: Nil = Enum(7)
60  val quot_neg_2 :: quot_neg_1 :: quot_0 :: quot_pos_1 :: quot_pos_2 :: Nil = Enum(5)
61
62
63  val state = RegInit((1 << s_idle.litValue.toInt).U(7.W))
64
65  // reused wires
66//  val aNormAbs = Wire(UInt((len + 1).W)) // Inputs of xNormAbs regs below
67//  val dNormAbs = Wire(UInt((len + 1).W))
68  val quotIter = Wire(UInt(len.W))
69  val quotM1Iter = Wire(UInt(len.W))
70  val aLZC = Wire(UInt((lzc_width + 1).W))
71  val dLZC = Wire(UInt((lzc_width + 1).W))
72
73  val rNext = Wire(UInt(itn_len.W))
74  val rNextPd = Wire(UInt(itn_len.W))
75
76  val aInverter = Wire(UInt(len.W)) // results of global inverter
77  val dInverter = Wire(UInt(len.W))
78
79  val finalIter = Wire(Bool())
80  val special = Wire(Bool())
81
82  // reused regs
83//  val aNormAbsReg = RegEnable(aNormAbs, newReq | state(s_pre_0) | state(s_post_0)) // reg for normalized a & d and rem & rem+d
84//  val dNormAbsReg = RegEnable(dNormAbs, newReq | state(s_pre_0) | state(s_post_0))
85  val quotIterReg = RegEnable(quotIter, state(s_pre_1) | state(s_iter) | state(s_post_0))
86  val quotM1IterReg = RegEnable(quotM1Iter, state(s_pre_1) | state(s_iter) | state(s_post_0))
87  val specialReg = RegEnable(special, state(s_pre_1))
88  val aReg = RegEnable(a, in_fire)
89
90  when(kill_r) {
91    state := UIntToOH(s_idle, 7)
92  } .elsewhen(state(s_idle) && in_fire && !kill_w) {
93    state := UIntToOH(s_pre_0, 7)
94  } .elsewhen(state(s_pre_0)) { // leading zero detection
95    state := UIntToOH(s_pre_1, 7)
96  } .elsewhen(state(s_pre_1)) { // shift a/b
97    state := Mux(special, UIntToOH(s_post_1, 7), UIntToOH(s_iter, 7))
98  } .elsewhen(state(s_iter)) { // (ws[j+1], wc[j+1]) = 4(ws[j],wc[j]) - q(j+1)*d
99    state := Mux(finalIter, UIntToOH(s_post_0, 7), UIntToOH(s_iter, 7))
100  } .elsewhen(state(s_post_0)) { // if rem < 0, rem = rem + d
101    state := UIntToOH(s_post_1, 7)
102  } .elsewhen(state(s_post_1)) {
103    state := UIntToOH(s_finish, 7)
104  } .elsewhen(state(s_finish) && io.out_ready) {
105    state := UIntToOH(s_idle, 7)
106  } .otherwise {
107    state := state
108  }
109
110  // io.in_ready := state(s_idle)
111  aInverter := -Mux(state(s_idle), a, quotIterReg) // 64, 0
112  dInverter := -Mux(state(s_idle), d, quotM1IterReg) // 64, 0
113
114  val aSign = io.sign && a(len - 1) // 1
115  val dSign = io.sign && d(len - 1)
116  val dSignReg = RegEnable(dSign, newReq)
117
118  val aAbs = Mux(aSign, aInverter, a) // 64, 0
119  val dAbs = Mux(dSign, dInverter, d)
120  val aAbsReg = RegEnable(aAbs, newReq)
121  val dAbsReg = RegEnable(dAbs, newReq)
122
123  val aNorm = (aAbsReg(len - 1, 0) << aLZC(lzc_width - 1, 0))(len - 1, 0) // 64, 65
124  val dNorm = (dAbsReg(len - 1, 0) << dLZC(lzc_width - 1, 0))(len - 1, 0)
125
126  val aNormReg = RegEnable(aNorm, state(s_pre_0))
127  val dNormReg = RegEnable(dNorm, state(s_pre_0))
128
129//  aNormAbs := Mux1H(Seq(
130//    state(s_idle) -> Cat(0.U(1.W), aAbs), // 65, 0
131//    state(s_pre_0) -> Cat(0.U(1.W), aNorm), // 65, 0
132//    state(s_post_0) -> rNext(len + 3, 3) // remainder 65, 64. highest is sign bit
133//  ))
134//  dNormAbs := Mux1H(Seq(
135//    state(s_idle) -> Cat(0.U(1.W), dAbs),
136//    state(s_pre_0) -> Cat(0.U(1.W), dNorm),
137//    state(s_post_0) -> rNextPd(len + 3, 3)
138//    ))
139
140  // Second cycle, state is pre_0
141  // calculate lzc and move div* and lzc diff check if no_iter_needed
142
143  aLZC := PriorityEncoder(aAbsReg(len - 1, 0).asBools.reverse)
144  dLZC := PriorityEncoder(dAbsReg(len - 1, 0).asBools.reverse)
145  val aLZCReg = RegEnable(aLZC, state(s_pre_0)) // 7, 0
146  val dLZCReg = RegEnable(dLZC, state(s_pre_0))
147
148  val lzcWireDiff = Cat(0.U(1.W), dLZC(lzc_width - 1, 0)) - Cat(0.U(1.W), aLZC(lzc_width - 1, 0)) // 7, 0
149  val lzcRegDiff = Cat(0.U(1.W), dLZCReg(lzc_width - 1, 0)) - Cat(0.U(1.W), aLZCReg(lzc_width - 1, 0))
150//  val lzcDiff = Mux(state(s_pre_0), lzcWireDiff, lzcRegDiff)
151
152  // special case:
153  // divisor is 1 or -1; dividend has less bits than divisor; divisor is zero
154  // s_pre_0:
155  val dIsOne = dLZC(lzc_width - 1, 0).andR
156  val dIsZero = ~dNormReg.orR
157  val aIsZero = RegEnable(aLZC(lzc_width), state(s_pre_0))
158  val aTooSmall = RegEnable(aLZC(lzc_width) | lzcWireDiff(lzc_width), state(s_pre_0))
159  special := dIsOne | dIsZero | aTooSmall
160
161  val quotSpecial = Mux(dIsZero, VecInit(Seq.fill(len)(true.B)).asUInt,
162                            Mux(aTooSmall, 0.U,
163                              Mux(dSignReg, -aReg, aReg) //  signed 2^(len-1)
164                            ))
165  val remSpecial = Mux(dIsZero || aTooSmall, aReg, 0.U)
166  val quotSpecialReg = RegEnable(quotSpecial, state(s_pre_1))
167  val remSpecialReg = RegEnable(remSpecial, state(s_pre_1))
168
169  // s_pre_1
170  val quotSign = Mux(state(s_idle), aSign ^ dSign, true.B) // if not s_idle then must be s_pre_1 & dIsZero, and that we have
171  val rSign = aSign
172  val quotSignReg = RegEnable(quotSign, in_fire | (state(s_pre_1) & dIsZero))
173  val rSignReg = RegEnable(rSign, in_fire)
174
175  val rShift = lzcRegDiff(0)
176  val oddIter = lzcRegDiff(1) ^ lzcRegDiff(0)
177  val iterNum = Wire(UInt((lzc_width - 2).W))
178  val iterNumReg = RegEnable(iterNum, state(s_pre_1) | state(s_iter))
179  iterNum := Mux(state(s_pre_1), (lzcRegDiff + 1.U) >> 2, iterNumReg -% 1.U)
180  finalIter := iterNumReg === 0.U
181
182  val rSumInit = Cat(0.U(3.W), Mux(rShift, Cat(0.U(1.W), aNormReg), Cat(aNormReg, 0.U(1.W)))) //(1, 67), 0.001xxx
183  val rCarryInit = 0.U(itn_len.W)
184
185  val rSumInitTrunc = Cat(0.U(1.W), rSumInit(itn_len - 4, itn_len - 4 - 4 + 1)) // 0.00___
186  val mInitPos1 = MuxLookup(dNormReg(len-2, len-4), "b00100".U(5.W))(
187    Seq(
188      0.U -> "b00100".U(5.W),
189      1.U -> "b00100".U(5.W),
190      2.U -> "b00100".U(5.W),
191      3.U -> "b00110".U(5.W),
192      4.U -> "b00110".U(5.W),
193      5.U -> "b00110".U(5.W),
194      6.U -> "b00110".U(5.W),
195      7.U -> "b01000".U(5.W),
196    )
197  )
198  val mInitPos2 = MuxLookup(dNormReg(len-2, len-4), "b01100".U(5.W))(
199    Seq(
200      0.U -> "b01100".U(5.W),
201      1.U -> "b01110".U(5.W),
202      2.U -> "b01111".U(5.W),
203      3.U -> "b10000".U(5.W),
204      4.U -> "b10010".U(5.W),
205      5.U -> "b10100".U(5.W),
206      6.U -> "b10110".U(5.W),
207      7.U -> "b10110".U(5.W),
208    )
209  )
210  val initCmpPos1 = rSumInitTrunc >= mInitPos1
211  val initCmpPos2 = rSumInitTrunc >= mInitPos2
212  val qInit = Mux(initCmpPos2, UIntToOH(quot_pos_2, 5), Mux(initCmpPos1, UIntToOH(quot_pos_1, 5), UIntToOH(quot_0, 5)))
213
214  // in pre_1 we also obtain m_i + 16u * d for all u
215  // udNeg -> (rud, r2ud) -> (rudPmNeg, r2udPmNeg)
216  val dPos = Cat(0.U(1.W), dNormReg)                          // +d, 0.1xxx, (1, 64)
217  val dNeg = -Cat(0.U(1.W), dNormReg) // -d, 1.xxxx, (1, 64)
218  // val m = Wire(Vec(4, UInt(7.W)))     // we have to sigext them to calculate rqd-m_k
219
220  // index 0 is for q=-2 and 4 is for q=2!!!
221  val mNeg = Wire(Vec(4, UInt(12.W))) // selected m, extended to (6, 6) bits
222  val rudNeg = Wire(Vec(5, UInt(10.W))) // (4, 6)
223  val r2udNeg = Wire(Vec(5, UInt(12.W))) // (6, 6)
224
225  // Selection Block with improved timing
226  val rudPmNeg = Wire(Vec(5, Vec(4, UInt(10.W)))) // -(r*u*d+m_k), (5, 5) bits
227  val r2ws = Wire(UInt(10.W)) // r^2*ws (5, 5) bits
228  val r2wc = Wire(UInt(10.W))
229  // calculating exact values of w
230  val udNeg = Wire(Vec(5, UInt(itn_len.W))) // (3, 65), 1 signExt'ed Bit
231  // val r3udNeg = Wire(Vec(5, UInt(13.W)))
232
233  // Speculative Block
234  val r2udPmNeg = Wire(Vec(5, Vec(4, UInt(13.W)))) // -(r^2*d*d+m_k), (7, 6) bits. 1st index for q 2nd for m
235  val r3ws = Wire(UInt(13.W)) // r^3*ws, (7, 6) bits
236  val r3wc = Wire(UInt(13.W))
237  val qSpec = Wire(Vec(5, UInt(5.W))) // 5 speculative results of qNext2
238  // output wires
239  val qNext = Wire(UInt(5.W))
240  val qNext2 = Wire(UInt(5.W))
241  val rCarryIter = Wire(UInt(itn_len.W)) // (1, 67)
242  val rSumIter = Wire(UInt(itn_len.W))
243  // val r3wsIter = Wire(UInt(13.W))
244  // val r3wcIter = Wire(UInt(13.W))
245  // Input Regs of whole Spec + Sel + sum adder block
246  val qPrevReg = RegEnable(Mux(state(s_pre_1), qInit, qNext2), state(s_pre_1) | state(s_iter))
247  val rSumReg = RegEnable(Mux(state(s_pre_1), rSumInit, rSumIter), state(s_pre_1) | state(s_iter)) // (1, 67)
248  val rCarryReg = RegEnable(Mux(state(s_pre_1), rCarryInit, rCarryIter), state(s_pre_1) | state(s_iter))
249
250  // Give values to the regs and wires above...
251  val dForLookup = dPos(len-2, len-4)
252  mNeg := VecInit(Cat(SignExt(MuxLookup(dNormReg(len-2, len-4), "b00000000".U(7.W))(mLookUpTable2.minus_m(0)), 11), 0.U(1.W)), // (2, 5) -> (6, 6)
253                  Cat(SignExt(MuxLookup(dNormReg(len-2, len-4), "b00000000".U(7.W))(mLookUpTable2.minus_m(1)), 10) ,0.U(2.W)), // (3, 4) -> (6, 6)
254                  Cat(SignExt(MuxLookup(dNormReg(len-2, len-4), "b00000000".U(7.W))(mLookUpTable2.minus_m(2)), 10) ,0.U(2.W)),
255                  Cat(SignExt(MuxLookup(dNormReg(len-2, len-4), "b00000000".U(7.W))(mLookUpTable2.minus_m(3)), 11) ,0.U(1.W))
256  )
257  udNeg := VecInit( Cat(SignExt(dPos, 66), 0.U(2.W)),
258                    Cat(SignExt(dPos, 67), 0.U(1.W)),
259                    0.U,
260                    Cat(SignExt(dNeg, 67), 0.U(1.W)),
261                    Cat(SignExt(dNeg, 66), 0.U(2.W))
262  )
263
264  rudNeg := VecInit(Seq.tabulate(5){i => udNeg(i)(itn_len-2, itn_len-11)})
265  r2udNeg := VecInit(Seq.tabulate(5){i => udNeg(i)(itn_len-2, itn_len-13)})
266  // r3udNeg := VecInit(Seq.tabulate(5){i => udNeg(i)(itn_len-2, itn_len-13)})
267  rudPmNeg := VecInit(Seq.tabulate(5){i => VecInit(Seq.tabulate(4){ j => SignExt(rudNeg(i)(9, 1), 10) + mNeg(j)(10, 1)})})
268  r2udPmNeg := VecInit(Seq.tabulate(5){i => VecInit(Seq.tabulate(4){ j => SignExt(r2udNeg(i), 13) + SignExt(mNeg(j), 13)})})
269  r3ws := rSumReg(itn_len-1, itn_len-13)
270  r3wc := rCarryReg(itn_len-1, itn_len-13)
271
272  r2ws := rSumReg(itn_len-1, itn_len-10)
273  r2wc := rCarryReg(itn_len-1, itn_len-10)
274
275  val udNegReg = RegEnable(udNeg, state(s_pre_1))
276//  val rudNegReg = RegEnable(rudNeg, state(s_pre_1))
277  val rudPmNegReg = RegEnable(rudPmNeg, state(s_pre_1))
278  val r2udPmNegReg = RegEnable(r2udPmNeg, state(s_pre_1))
279
280  def DetectSign(signs: UInt, name: String): UInt = {
281    val qVec = Wire(Vec(5, Bool())).suggestName(name)
282    qVec(quot_neg_2) := signs(0) && signs(1) && signs(2)
283    qVec(quot_neg_1) := ~signs(0) && signs(1) && signs(2)
284    qVec(quot_0) := signs(2) && ~signs(1)
285    qVec(quot_pos_1) := signs(3) && ~signs(2) && ~signs(1)
286    qVec(quot_pos_2) := ~signs(3) && ~signs(2) && ~signs(1)
287    qVec.asUInt
288  }
289  // Selection block
290  val signs = VecInit(Seq.tabulate(4){ i => {
291    val csa = Module(new CSA3_2(10)).suggestName(s"csa_sel_${i}")
292    csa.io.in(0) := r2ws
293    csa.io.in(1) := r2wc
294    csa.io.in(2) := Mux1H(qPrevReg, rudPmNegReg.toSeq)(i) // rudPmNeg(OHToUInt(qPrevReg))(i)
295
296      (csa.io.out(0) + (csa.io.out(1)(8, 0) << 1))(9)
297    }})
298  qNext := DetectSign(signs.asUInt, s"sel_q")
299  val csaWide1 = Module(new CSA3_2(itn_len)).suggestName("csa_sel_wide_1")
300  val csaWide2 = Module(new CSA3_2(itn_len)).suggestName("csa_sel_wide_2")
301  csaWide1.io.in(0) := rSumReg << 2
302  csaWide1.io.in(1) := rCarryReg << 2
303  csaWide1.io.in(2) := Mux1H(qPrevReg, udNegReg.toSeq) << 2//udNeg(OHToUInt(qPrevReg)) << 2
304  csaWide2.io.in(0) := csaWide1.io.out(0) << 2
305  csaWide2.io.in(1) := (csaWide1.io.out(1) << 1)(itn_len-1, 0) << 2
306  csaWide2.io.in(2) := Mux1H(qNext, udNegReg.toSeq) << 2 // udNeg(OHToUInt(qNext)) << 2
307  rSumIter := Mux(~oddIter & finalIter, csaWide1.io.out(0), csaWide2.io.out(0))
308  rCarryIter := Mux(~oddIter & finalIter, (csaWide1.io.out(1) << 1)(itn_len-1, 0), (csaWide2.io.out(1) << 1)(itn_len-1, 0))
309  // r3wsIter := r3udNeg(OHToUInt(qNext))
310  // r3wcIter := (csaWide1.io.out(0)(itn_len-3, itn_len-16) + (csaWide1.io.out(1) << 1)(itn_len-3, itn_len-16))(13,1)
311  // Speculative block
312  qSpec := VecInit(Seq.tabulate(5){ q_spec => {
313      val csa1 = Module(new CSA3_2(13)).suggestName(s"csa_spec_${q_spec}")
314      csa1.io.in(0) := r3ws
315      csa1.io.in(1) := r3wc
316      csa1.io.in(2) := SignExt(udNegReg(q_spec)(itn_len-2, itn_len-11), 13) // (4, 6) -> (7, 6)
317      val signs2 = VecInit(Seq.tabulate(4){ i => {
318        val csa2 = Module(new CSA3_2(13)).suggestName(s"csa_spec_${q_spec}_${i}")
319        csa2.io.in(0) := csa1.io.out(0)
320        csa2.io.in(1) := (csa1.io.out(1) << 1)(12, 0)
321        csa2.io.in(2) := Mux1H(qPrevReg, r2udPmNegReg.toSeq)(i) // r2udPmNeg(OHToUInt(qPrevReg))(i)
322        (csa2.io.out(0) + (csa2.io.out(1)(11, 0) << 1))(12)
323      }})
324      val qVec2 = DetectSign(signs2.asUInt, s"spec_q_${q_spec}")
325      qVec2
326  }})
327  // qNext2 := qSpec(OHToUInt(qNext)) // TODO: Use Mux1H!!
328
329  qNext2 := Mux1H(qNext, qSpec.toSeq)
330
331  // on the fly quotient conversion
332  val quotHalfIter = Wire(UInt(64.W))
333  val quotM1HalfIter = Wire(UInt(64.W))
334  val quotIterNext = Wire(UInt(64.W))
335  val quotM1IterNext = Wire(UInt(64.W))
336  def OTFC(q: UInt, quot: UInt, quotM1: UInt): (UInt, UInt) = {
337    val quotNext = Mux1H(Seq(
338    q(quot_pos_2) -> (quot << 2 | "b10".U),
339    q(quot_pos_1) -> (quot << 2 | "b01".U),
340    q(quot_0)     -> (quot << 2 | "b00".U),
341    q(quot_neg_1) -> (quotM1 << 2 | "b11".U),
342    q(quot_neg_2) -> (quotM1 << 2 | "b10".U)
343    ))
344    val quotM1Next = Mux1H(Seq(
345    q(quot_pos_2) -> (quot << 2 | "b01".U),
346    q(quot_pos_1) -> (quot << 2 | "b00".U),
347    q(quot_0)     -> (quotM1 << 2 | "b11".U),
348    q(quot_neg_1) -> (quotM1 << 2 | "b10".U),
349    q(quot_neg_2) -> (quotM1 << 2 | "b01".U)
350    ))
351    (quotNext(len-1, 0), quotM1Next(len-1, 0))
352  }
353  quotHalfIter := OTFC(qPrevReg, quotIterReg, quotM1IterReg)._1
354  quotM1HalfIter := OTFC(qPrevReg, quotIterReg, quotM1IterReg)._2
355  quotIterNext := Mux(~oddIter && finalIter, quotHalfIter, OTFC(qNext, quotHalfIter, quotM1HalfIter)._1)
356  quotM1IterNext := Mux(~oddIter && finalIter, quotM1HalfIter, OTFC(qNext, quotHalfIter, quotM1HalfIter)._2)
357  // quotIter := Mux(state(s_pre_1),  0.U(len.W),
358  //                     Mux(state(s_iter), quotIterNext,
359  //                       Mux(quotSignReg, aInverter, quotIterReg)))
360  // quotM1Iter := Mux(state(s_pre_1),
361  //                       0.U(len.W), Mux(state(s_iter), quotM1IterNext,
362  //                         Mux(quotSignReg, dInverter, quotM1IterReg)))
363
364  quotIter := Mux(state(s_iter), quotIterNext,
365                    Mux(state(s_pre_1), 0.U(len.W),
366                      Mux(quotSignReg, aInverter, quotIterReg)))
367  quotM1Iter := Mux(state(s_iter), quotM1IterNext,
368                      Mux(state(s_pre_1), 0.U(len.W),
369                        Mux(quotSignReg, dInverter, quotM1IterReg)))
370  // finally, to the recovery stages!
371
372  when(rSignReg) {
373    rNext := ~rSumReg + ~rCarryReg + 2.U
374    rNextPd := ~rSumReg + ~rCarryReg + ~Cat(0.U(1.W), dNormReg, 0.U(3.W)) + 3.U
375  } .otherwise {
376    rNext := rSumReg + rCarryReg
377    rNextPd := rSumReg + rCarryReg + Cat(0.U(1.W), dNormReg, 0.U(3.W))
378  }
379  val rNextReg = RegEnable(rNext(len + 3, 3), state(s_post_0))
380  val rNextPdReg = RegEnable(rNextPd(len + 3, 3), state(s_post_0))
381  dontTouch(rNextReg)
382  // post_1
383  val r = rNextReg
384  val rPd = rNextPdReg
385  val rIsZero = ~(r.orR)
386  val needCorr = Mux(rSignReg, ~r(len) & r.orR, r(len)) // when we get pos rem for a<0 or neg rem for a>0
387  val rPreShifted = Mux(needCorr, rPd, r)
388  val rightShifter = Module(new RightShifter(len, lzc_width))
389  rightShifter.io.in := rPreShifted
390  rightShifter.io.shiftNum := dLZCReg
391  rightShifter.io.msb := Mux(~(rPreShifted.orR), 0.U, rSignReg)
392  val rShifted = rightShifter.io.out
393  val rFinal = RegEnable(Mux(specialReg, remSpecialReg, rShifted), state(s_post_1))// right shifted remainder. shift by the number of bits divisor is shifted
394  val qFinal = RegEnable(Mux(specialReg, quotSpecialReg, Mux(needCorr, quotM1IterReg, quotIterReg)), state(s_post_1))
395  val res = Mux(isHi, rFinal, qFinal)
396  io.out_data := Mux(isW,
397    SignExt(res(31, 0), len),
398    res
399  )
400  io.in_ready := state(s_idle)
401  io.out_valid := state(s_finish)
402  io.out_validNext := state(s_post_1)
403}
404
405object mLookUpTable2 {
406  // Usage :
407  // result := decoder(QMCMinimizer, index, mLookupTable.xxx)
408  val minus_m = Seq(
409    Seq( // -m[-1]
410      0.U -> "b00_11010".U(7.W),
411      1.U -> "b00_11110".U(7.W),
412      2.U -> "b01_00000".U(7.W),
413      3.U -> "b01_00100".U(7.W),
414      4.U -> "b01_00110".U(7.W),
415      5.U -> "b01_01010".U(7.W),
416      6.U -> "b01_01100".U(7.W),
417      7.U -> "b01_10000".U(7.W)
418    ),
419    Seq( // -m[0]
420      0.U -> "b000_0100".U(7.W),
421      1.U -> "b000_0110".U(7.W),
422      2.U -> "b000_0110".U(7.W),
423      3.U -> "b000_0110".U(7.W),
424      4.U -> "b000_1000".U(7.W),
425      5.U -> "b000_1000".U(7.W),
426      6.U -> "b000_1000".U(7.W),
427      7.U -> "b000_1000".U(7.W)
428    ),
429    Seq( //-m[1]
430      0.U -> "b111_1101".U(7.W),
431      1.U -> "b111_1100".U(7.W),
432      2.U -> "b111_1100".U(7.W),
433      3.U -> "b111_1100".U(7.W),
434      4.U -> "b111_1011".U(7.W),
435      5.U -> "b111_1010".U(7.W),
436      6.U -> "b111_1010".U(7.W),
437      7.U -> "b111_1010".U(7.W)
438    ),
439    Seq( //-m[2]
440      0.U -> "b11_01000".U(7.W),
441      1.U -> "b11_00100".U(7.W),
442      2.U -> "b11_00010".U(7.W),
443      3.U -> "b10_11110".U(7.W),
444      4.U -> "b10_11100".U(7.W),
445      5.U -> "b10_11000".U(7.W),
446      6.U -> "b10_10110".U(7.W),
447      7.U -> "b10_10010".U(7.W)
448    ))
449}
450