xref: /XiangShan/src/main/scala/xiangshan/backend/fu/SRT4Divider.scala (revision 57bb43b5f11c3f1e89ac52f232fe73056b35d9bd)
1/***************************************************************************************
2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3* Copyright (c) 2020-2021 Peng Cheng Laboratory
4*
5* XiangShan is licensed under Mulan PSL v2.
6* You can use this software according to the terms and conditions of the Mulan PSL v2.
7* You may obtain a copy of Mulan PSL v2 at:
8*          http://license.coscl.org.cn/MulanPSL2
9*
10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13*
14* See the Mulan PSL v2 for more details.
15***************************************************************************************/
16
17// The "SRT4DividerDataModule" in this file is a scala rewrite of SRT4 divider by Yifei He, see
18// https://github.com/OpenXiangShan/XS-Verilog-Library/tree/main/int_div_radix_4_v1
19// Email of original author: [email protected]
20
21package xiangshan.backend.fu
22
23import chipsalliance.rocketchip.config.Parameters
24import chisel3._
25import chisel3.util._
26import utils.SignExt
27import xiangshan.backend.fu.util.CSA3_2
28
29/** A Radix-4 SRT Integer Divider
30  *
31  * 2 ~ (5 + (len+3)/2) cycles are needed for each division.
32  */
33class SRT4DividerDataModule(len: Int) extends Module {
34  val io = IO(new Bundle() {
35    val src = Vec(2, Input(UInt(len.W)))
36    val valid, sign, kill_w, kill_r, isHi, isW = Input(Bool())
37    val in_ready = Output(Bool())
38    val out_valid = Output(Bool())
39    val out_data = Output(UInt(len.W))
40    val out_ready = Input(Bool())
41  })
42
43  // consts
44  val lzc_width = log2Up(len)
45  val itn_len = 1 + len + 2 + 1
46  require(lzc_width == 6)
47
48  val (a, d, sign, valid, kill_w, kill_r, isHi, isW) =
49    (io.src(0), io.src(1), io.sign, io.valid, io.kill_w, io.kill_r, io.isHi, io.isW)
50  val in_fire = valid && io.in_ready
51  val out_fire = io.out_ready && io.out_valid
52  val newReq = in_fire
53  val startHandShake = io.in_ready && valid
54  val s_idle :: s_pre_0 :: s_pre_1 :: s_iter :: s_post_0 :: s_post_1 :: s_finish :: Nil = Enum(7)
55
56  val state = RegInit(UIntToOH(s_idle, 7))
57
58  val quot_neg_2 :: quot_neg_1 :: quot_0 :: quot_pos_1 :: quot_pos_2 :: Nil = Enum(5)
59
60  val finished = state(s_finish)
61
62  // reused wire declarations
63  val aIsZero = Wire(Bool())
64  val dIsZero = Wire(Bool())
65  val aTooSmall = Wire(Bool()) // this is output of reg!
66  val noIter = Wire(Bool()) // this is output of reg!
67  val finalIter = Wire(Bool())
68  val aLZC = Wire(UInt((lzc_width + 1).W))
69  val dLZC = Wire(UInt((lzc_width + 1).W))
70  val aNormAbs = Wire(UInt((len + 1).W))
71  val dNormAbs = Wire(UInt((len + 1).W))
72  val aInverter = Wire(UInt(len.W)) // results of global inverter
73  val dInverter = Wire(UInt(len.W))
74
75  val rPreShifted = Wire(UInt((len + 1).W))
76
77  val quotIter = Wire(UInt(len.W))
78  val quotM1Iter = Wire(UInt(len.W))
79  val qIterEnd = Wire(UInt(5.W))
80
81  val rNext = Wire(UInt(itn_len.W))
82  val rNextPd = Wire(UInt(itn_len.W)) // non-redundant remainder plus d, 68, 67
83  //reused ctrl regs
84
85  //reused other regs
86  val aNormAbsReg = RegEnable(aNormAbs, startHandShake | state(s_pre_0) | state(s_post_0)) // reg for normalized a & d and rem & rem+d
87  val dNormAbsReg = RegEnable(dNormAbs, startHandShake | state(s_pre_0) | state(s_post_0))
88  val quotIterReg = RegEnable(quotIter, state(s_pre_1) | state(s_iter) | state(s_post_0))
89  val quotM1IterReg = RegEnable(quotM1Iter, state(s_pre_1) | state(s_iter) | state(s_post_0))
90
91  when(kill_r) {
92    state := UIntToOH(s_idle, 7)
93  } .elsewhen(state(s_idle) && in_fire && !kill_w) {
94    state := UIntToOH(s_pre_0, 7)
95  } .elsewhen(state(s_pre_0)) { // leading zero detection
96    state := UIntToOH(s_pre_1, 7)
97  } .elsewhen(state(s_pre_1)) { // shift a/b
98    state := Mux(dIsZero | aTooSmall | noIter, UIntToOH(s_post_0, 7), UIntToOH(s_iter, 7))
99  } .elsewhen(state(s_iter)) { // (ws[j+1], wc[j+1]) = 4(ws[j],wc[j]) - q(j+1)*d
100    state := Mux(finalIter, UIntToOH(s_post_0, 7), UIntToOH(s_iter, 7))
101  } .elsewhen(state(s_post_0)) { // if rem < 0, rem = rem + d
102    state := UIntToOH(s_post_1, 7)
103  } .elsewhen(state(s_post_1)) {
104    state := UIntToOH(s_finish, 7)
105  } .elsewhen(state(s_finish) && out_fire) {
106    state := UIntToOH(s_idle, 7)
107  } .otherwise {
108    state := state
109  }
110
111  // First cycle:
112  // State is idle, we gain absolute value of a and b, using global inverter
113
114  io.in_ready := state(s_idle)
115
116  aInverter := -Mux(state(s_idle), a, quotIterReg) // 64, 0
117  dInverter := -Mux(state(s_idle), d, quotM1IterReg) // 64, 0
118
119  val aSign = io.sign && a(len - 1) // 1
120  val dSign = io.sign && d(len - 1)
121
122  val aAbs = Mux(aSign, aInverter, a) // 64, 0
123  val dAbs = Mux(dSign, dInverter, d)
124  val aNorm = (aNormAbsReg(len - 1, 0) << aLZC(lzc_width - 1, 0))(len - 1, 0) // 64, 65
125  val dNorm = (dNormAbsReg(len - 1, 0) << dLZC(lzc_width - 1, 0))(len - 1, 0)
126
127  aNormAbs := Mux1H(Seq(
128    state(s_idle) -> Cat(0.U(1.W), aAbs), // 65, 0
129    state(s_pre_0) -> Cat(0.U(1.W), aNorm), // 65, 0
130    state(s_post_0) -> rNext(len + 3, 3) // remainder 65, 64. highest is sign bit
131  ))
132  dNormAbs := Mux1H(Seq(
133    state(s_idle) -> Cat(0.U(1.W), dAbs),
134    state(s_pre_0) -> Cat(0.U(1.W), dNorm),
135    state(s_post_0) -> rNextPd(len + 3, 3)
136    ))
137
138  // Second cycle, state is pre_0
139  // calculate lzc and move div* and lzc diff check if no_iter_needed
140
141  aLZC := PriorityEncoder(aNormAbsReg(len - 1, 0).asBools().reverse)
142  dLZC := PriorityEncoder(dNormAbsReg(len - 1, 0).asBools().reverse)
143  val aLZCReg = RegEnable(aLZC, state(s_pre_0)) // 7, 0
144  val dLZCReg = RegEnable(dLZC, state(s_pre_0))
145
146
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  aIsZero := aLZC(lzc_width) // this is state pre_0
152  dIsZero := dLZCReg(lzc_width) // this is pre_1 and all stages after
153  val dIsOne = dLZC(lzc_width - 1, 0).andR() // this is pre_0
154  val noIterReg = RegEnable(dIsOne & aNormAbsReg(len - 1), state(s_pre_0)) // This means dividend has lzc 0 so iter is 17
155  noIter := noIterReg
156  val aTooSmallReg = RegEnable(aIsZero | lzcDiff(lzc_width), state(s_pre_0)) // a is zero or a smaller than d
157  aTooSmall := aTooSmallReg
158
159  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
160  val rSign = aSign
161  val quotSignReg = RegEnable(quotSign, startHandShake | (state(s_pre_1) & dIsZero))
162  val rSignReg = RegEnable(rSign, startHandShake)
163
164  val rShift = lzcDiff(0) // odd lzc diff, for SRT4
165  val rightShifted = Wire(UInt(len.W))
166  val rSumInit = Mux(aTooSmallReg | aIsZero, Cat(0.U(1.W), rightShifted, 0.U(3.W)), // right shift the dividend (which is already l-shifted)
167                    Mux(noIterReg, 0.U(itn_len.W), //
168                      Cat(0.U(3.W),
169                          Mux(rShift, Cat(0.U(1.W), aNormAbsReg(len - 1, 0)), Cat(aNormAbsReg(len - 1, 0), 0.U(1.W)))
170                        ) // Normal init value. 68, 67; For even lzcDiff, 0.001xxx0; for odd lzcDiff 0.0001xxx
171                      )
172                    ) // state is s_pre_1
173  val rCarryInit = 0.U(itn_len.W)
174
175  val rightShifter = Module(new RightShifter(len, lzc_width))
176  rightShifter.io.in := Mux(state(s_pre_1), aNormAbsReg(len - 1, 0), rPreShifted(len - 1, 0))
177  rightShifter.io.shiftNum := Mux(state(s_pre_1), aLZCReg,
178                                  Mux(aTooSmallReg | dIsZero, 0.U(lzc_width.W), dLZCReg))
179  rightShifter.io.msb := state(s_post_1) & rSignReg & rPreShifted(len)
180  rightShifted := rightShifter.io.out
181
182  // obtaining 1st quotient
183  val rSumInitTrunc = Cat(0.U(1.W), rSumInit(itn_len - 4, itn_len - 4 - 4 + 1)) // 0.00___
184  val mInitPos1 = MuxLookup(dNormAbsReg(len - 2, len - 2 - 3 + 1), "b00100".U(5.W),
185    Array(
186      0.U -> "b00100".U(5.W),
187      1.U -> "b00100".U(5.W),
188      2.U -> "b00100".U(5.W),
189      3.U -> "b00110".U(5.W),
190      4.U -> "b00110".U(5.W),
191      5.U -> "b00110".U(5.W),
192      6.U -> "b00110".U(5.W),
193      7.U -> "b01000".U(5.W),
194    )
195  )
196  val mInitPos2 = MuxLookup(dNormAbsReg(len - 2, len - 2 - 3 + 1), "b01100".U(5.W),
197    Array(
198      0.U -> "b01100".U(5.W),
199      1.U -> "b01110".U(5.W),
200      2.U -> "b01111".U(5.W),
201      3.U -> "b10000".U(5.W),
202      4.U -> "b10010".U(5.W),
203      5.U -> "b10100".U(5.W),
204      6.U -> "b10110".U(5.W),
205      7.U -> "b10110".U(5.W),
206    )
207  )
208  val initCmpPos1 = rSumInitTrunc >= mInitPos1
209  val initCmpPos2 = rSumInitTrunc >= mInitPos2
210  val qInit = Mux(initCmpPos2, UIntToOH(quot_pos_2, 5), Mux(initCmpPos1, UIntToOH(quot_pos_1, 5), UIntToOH(quot_0, 5)))
211  val qPrev = Mux(state(s_pre_1), qInit, qIterEnd)
212  val qPrevReg = RegEnable(qPrev, state(s_pre_1) | state(s_iter))
213  val specialDivisorReg = RegEnable(dNormAbsReg(len - 2, len - 2 - 3 + 1) === 0.U, state(s_pre_1)) // d=0.1000xxx
214  // rCarry and rSum in Iteration
215  val qXd = Mux1H(Seq(
216    qPrevReg(quot_neg_2) -> Cat(dNormAbsReg(len - 1, 0), 0.U(4.W)), // 68, 67 1.xxxxx0000
217    qPrevReg(quot_neg_1) -> Cat(0.U(1.W), dNormAbsReg(len - 1, 0), 0.U(3.W)), // 0.1xxxxx000
218    qPrevReg(quot_0)     -> 0.U(itn_len.W),
219    qPrevReg(quot_pos_1) -> ~Cat(0.U(1.W), dNormAbsReg(len - 1, 0), 0.U(3.W)), // don't forget to plus 1 later
220    qPrevReg(quot_pos_2) -> ~Cat(dNormAbsReg(len - 1, 0), 0.U(4.W))  // don't forget to plus 1 later
221  ))
222  val csa = Module(new CSA3_2(itn_len))
223
224  val rSumIter = csa.io.out(0)
225  val rCarryIter = Cat(csa.io.out(1)(itn_len - 2, 0), qPrevReg(quot_pos_1) | qPrevReg(quot_pos_2))
226  val rSumReg = RegEnable(Mux(state(s_pre_1), rSumInit, rSumIter), state(s_pre_1) | state(s_iter)) // 68, 67
227  val rCarryReg = RegEnable(Mux(state(s_pre_1), rCarryInit, rCarryIter), state(s_pre_1) | state(s_iter))
228  csa.io.in(0) := rSumReg << 2
229  csa.io.in(1) := rCarryReg << 2
230  csa.io.in(2) := qXd
231
232  val qds = Module(new SRT4QDS(len, itn_len))
233  qds.io.remSum := rSumReg
234  qds.io.remCarry := rCarryReg
235  qds.io.d := dNormAbsReg(len - 1, 0) // Maybe optimize here to lower power consumption?
236  qds.io.specialDivisor := specialDivisorReg
237  qds.io.qPrev := qPrevReg
238  qIterEnd := qds.io.qIterEnd
239
240  //on the fly conversion
241  val quotIterNext = Wire(UInt(len.W))
242  val quotIterM1Next = Wire(UInt(len.W))
243  quotIterNext := Mux1H(Seq(
244    qPrevReg(quot_pos_2) -> (quotIterReg << 2 | "b10".U),
245    qPrevReg(quot_pos_1) -> (quotIterReg << 2 | "b01".U),
246    qPrevReg(quot_0)     -> (quotIterReg << 2 | "b00".U),
247    qPrevReg(quot_neg_1) -> (quotM1IterReg << 2 | "b11".U),
248    qPrevReg(quot_neg_2) -> (quotM1IterReg << 2 | "b10".U)
249  ))
250  quotIterM1Next := Mux1H(Seq(
251    qPrevReg(quot_pos_2) -> (quotIterReg << 2 | "b01".U),
252    qPrevReg(quot_pos_1) -> (quotIterReg << 2 | "b00".U),
253    qPrevReg(quot_0)     -> (quotM1IterReg << 2 | "b11".U),
254    qPrevReg(quot_neg_1) -> (quotM1IterReg << 2 | "b10".U),
255    qPrevReg(quot_neg_2) -> (quotM1IterReg << 2 | "b01".U)
256  ))
257
258
259  quotIter := Mux(state(s_pre_1),
260                      Mux(dIsZero, VecInit(Seq.fill(len)(true.B)).asUInt,
261                        Mux(noIterReg, aNormAbsReg(len - 1, 0), 0.U(len.W))),
262                      Mux(state(s_iter), quotIterNext,
263                        Mux(quotSignReg, aInverter, quotIterReg)))
264  quotM1Iter := Mux(state(s_pre_1),
265                        0.U(len.W), Mux(state(s_iter), quotIterM1Next,
266                          Mux(quotSignReg, dInverter, quotM1IterReg)))
267
268
269  // iter num
270  val iterNum = Wire(UInt((lzc_width - 1).W))
271  val iterNumReg = RegEnable(iterNum, state(s_pre_1) | state(s_iter))
272
273  iterNum := Mux(state(s_pre_1), lzcDiff(lzc_width - 1, 1) +% lzcDiff(0), iterNumReg -% 1.U)
274  finalIter := iterNumReg === 0.U
275
276  // Post Process
277
278  when(rSignReg) {
279    rNext := ~rSumReg + ~rCarryReg + 2.U
280    rNextPd := ~rSumReg + ~rCarryReg + ~Cat(0.U(1.W), dNormAbsReg(len - 1, 0), 0.U(3.W)) + 3.U
281  } .otherwise {
282    rNext := rSumReg + rCarryReg
283    rNextPd := rSumReg + rCarryReg + Cat(0.U(1.W), dNormAbsReg(len - 1, 0), 0.U(3.W))
284  }
285
286  val r = aNormAbsReg
287  val rPd = dNormAbsReg
288  val rIsZero = ~(r.orR())
289  val needCorr = (~dIsZero & ~noIterReg) & Mux(rSignReg, ~r(len) & ~rIsZero, r(len)) // when we get pos rem for d<0 or neg rem for d>0
290  rPreShifted := Mux(needCorr, rPd, r)
291  val rFinal = RegEnable(rightShifted, state(s_post_1))// right shifted remainder. shift by the number of bits divisor is shifted
292  val qFinal = Mux(needCorr, quotM1IterReg, quotIterReg)
293  val res = Mux(isHi, rFinal, qFinal)
294  io.out_data := Mux(isW,
295    SignExt(res(31, 0), len),
296    res
297  )
298  io.in_ready := state(s_idle)
299  io.out_valid := state(s_finish) // state === s_finish
300}
301
302class RightShifter(len: Int, lzc_width: Int) extends Module {
303  val io = IO(new Bundle() {
304    val shiftNum = Input(UInt(lzc_width.W))
305    val in = Input(UInt(len.W))
306    val msb = Input(Bool())
307    val out = Output(UInt(len.W))
308  })
309  require(len == 64 || len == 32)
310  val shift = io.shiftNum
311  val msb = io.msb
312  val s0 = Mux(shift(0), Cat(VecInit(Seq.fill(1)(msb)).asUInt, io.in(len - 1, 1)), io.in)
313  val s1 = Mux(shift(1), Cat(VecInit(Seq.fill(2)(msb)).asUInt, s0(len - 1, 2)), s0)
314  val s2 = Mux(shift(2), Cat(VecInit(Seq.fill(4)(msb)).asUInt, s1(len - 1, 4)), s1)
315  val s3 = Mux(shift(3), Cat(VecInit(Seq.fill(8)(msb)).asUInt, s2(len - 1, 8)), s2)
316  val s4 = Mux(shift(4), Cat(VecInit(Seq.fill(16)(msb)).asUInt, s3(len - 1, 16)), s3)
317  val s5 = Wire(UInt(len.W))
318  if (len == 64) {
319    s5 := Mux(shift(5), Cat(VecInit(Seq.fill(32)(msb)).asUInt, s4(len - 1, 32)), s4)
320  } else if (len == 32) {
321    s5 := s4
322  }
323  io.out := s5
324}
325
326object mLookUpTable {
327  // Usage :
328  // result := decoder(QMCMinimizer, index, mLookupTable.xxx)
329  val minus_m = Seq(
330    Array( // -m[-1]
331      0.U -> "b00_11010".U,
332      1.U -> "b00_11110".U,
333      2.U -> "b01_00000".U,
334      3.U -> "b01_00100".U,
335      4.U -> "b01_00110".U,
336      5.U -> "b01_01010".U,
337      6.U -> "b01_01100".U,
338      7.U -> "b01_10000".U
339    ),
340    Array( // -m[0]
341      0.U -> "b000_0101".U,
342      1.U -> "b000_0110".U,
343      2.U -> "b000_0110".U,
344      3.U -> "b000_0110".U,
345      4.U -> "b000_1001".U,
346      5.U -> "b000_1000".U,
347      6.U -> "b000_1000".U,
348      7.U -> "b000_1000".U
349    ),
350    Array( //-m[1]
351      0.U -> "b111_1101".U,
352      1.U -> "b111_1100".U,
353      2.U -> "b111_1100".U,
354      3.U -> "b111_1100".U,
355      4.U -> "b111_1011".U,
356      5.U -> "b111_1010".U,
357      6.U -> "b111_1010".U,
358      7.U -> "b111_1010".U
359    ),
360    Array( //-m[2]
361      0.U -> "b11_01000".U,
362      1.U -> "b11_00100".U,
363      2.U -> "b11_00010".U,
364      3.U -> "b10_11110".U,
365      4.U -> "b10_11100".U,
366      5.U -> "b10_11000".U,
367      6.U -> "b10_10110".U,
368      7.U -> "b10_10010".U
369    ))
370}
371
372class SRT4QDS(len: Int, itn_len: Int) extends Module {
373  // srt4 quotientr digit selection
374  val io = IO(new Bundle() {
375    val remSum = Input(UInt(itn_len.W)) // 68, 67
376    val remCarry = Input(UInt(itn_len.W))
377    val d = Input(UInt(len.W)) // 64, 64
378    val specialDivisor = Input(Bool())
379    val qPrev = Input(UInt(5.W))
380    val qIterEnd = Output(UInt(5.W))
381  })
382  val remSumX16 = io.remSum << 4 // 72, 67 Top 2 bits unused
383  val remCarryX16 = io.remCarry << 4
384  def trunc25(rem: UInt): UInt = {rem(itn_len, itn_len - 7 + 1)}
385  def trunc34(rem: UInt): UInt = {rem(itn_len + 1, itn_len + 1 - 7 + 1)}
386
387  val quot_neg_2 :: quot_neg_1 :: quot_0 :: quot_pos_1 :: quot_pos_2 :: Nil = Enum(5)
388
389  val d = Cat(0.U(1.W), io.d, 0.U(3.W)) // 68, 67
390  val (dX4, dX8, dXNeg4, dXNeg8) = (d << 2, d(itn_len - 2, 0) << 3, ~(d << 2), ~(d(itn_len - 2, 0) << 3)) // 70, 67
391  val dForLookup = io.d(len - 2, len - 2 - 3 + 1)
392
393  val dXq = Mux1H(Seq(
394    io.qPrev(quot_neg_2) -> dX8,
395    io.qPrev(quot_neg_1) -> dX4,
396    io.qPrev(quot_0) -> 0.U((itn_len + 2).W),
397    io.qPrev(quot_pos_1) -> dXNeg4,
398    io.qPrev(quot_pos_2) -> dXNeg8
399  ))
400  val signs = VecInit(Seq.tabulate(4){ // -1 0 1 2
401    i => {
402      val csa1 = Module(new CSA3_2(7))
403      val csa2 = Module(new CSA3_2(7))
404      if (i == 1 || i == 2) {
405        csa1.io.in(0) := trunc34(remSumX16)
406        csa1.io.in(1) := trunc34(remCarryX16)
407        csa2.io.in(2) := trunc34(dXq)
408      } else {
409        csa1.io.in(0) := trunc25(remSumX16)
410        csa1.io.in(1) := trunc25(remCarryX16)
411        csa2.io.in(2) := trunc25(dXq)
412      }
413      csa1.io.in(2) := MuxLookup(dForLookup, "b0000000".U, mLookUpTable.minus_m(i))
414      csa2.io.in(0) := csa1.io.out(0)
415      csa2.io.in(1) := csa1.io.out(1)(5, 0) << 1
416      (csa2.io.out(0) + (csa2.io.out(1)(5, 0) << 1))(6)
417    }
418  })
419  val qVec = Wire(Vec(5, Bool()))
420  qVec(quot_neg_2) := signs(0) && signs(1) && signs(2)
421  qVec(quot_neg_1) := ~signs(0) && signs(1) && signs(2)
422  qVec(quot_0) := signs(2) && ~signs(1)
423  qVec(quot_pos_1) := signs(3) && ~signs(2) && ~signs(1)
424  qVec(quot_pos_2) := ~signs(3) && ~signs(2) && ~signs(1)
425  io.qIterEnd := qVec.asUInt
426  // assert(PopCount(qVec) === 1.U)
427}
428
429
430class SRT4Divider(len: Int)(implicit p: Parameters) extends AbstractDivider(len) {
431
432  val newReq = io.in.fire()
433
434  val uop = io.in.bits.uop
435  val uopReg = RegEnable(uop, newReq)
436  val ctrlReg = RegEnable(ctrl, newReq)
437
438  val divDataModule = Module(new SRT4DividerDataModule(len))
439
440  val kill_w = uop.robIdx.needFlush(io.redirectIn)
441  val kill_r = !divDataModule.io.in_ready && uopReg.robIdx.needFlush(io.redirectIn)
442
443  divDataModule.io.src(0) := io.in.bits.src(0)
444  divDataModule.io.src(1) := io.in.bits.src(1)
445  divDataModule.io.valid := io.in.valid
446  divDataModule.io.sign := sign
447  divDataModule.io.kill_w := kill_w
448  divDataModule.io.kill_r := kill_r
449  divDataModule.io.isHi := ctrlReg.isHi
450  divDataModule.io.isW := ctrlReg.isW
451  divDataModule.io.out_ready := io.out.ready
452
453  io.in.ready := divDataModule.io.in_ready
454  io.out.valid := divDataModule.io.out_valid
455  io.out.bits.data := divDataModule.io.out_data
456  io.out.bits.uop := uopReg
457}
458