xref: /XiangShan/src/main/scala/xiangshan/backend/fu/Bku.scala (revision bb2f3f51dd67f6e16e0cc1ffe43368c9fc7e4aef)
13feeca58Szfw/***************************************************************************************
23feeca58Szfw* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
33feeca58Szfw* Copyright (c) 2020-2021 Peng Cheng Laboratory
43feeca58Szfw*
53feeca58Szfw* XiangShan is licensed under Mulan PSL v2.
63feeca58Szfw* You can use this software according to the terms and conditions of the Mulan PSL v2.
73feeca58Szfw* You may obtain a copy of Mulan PSL v2 at:
83feeca58Szfw*          http://license.coscl.org.cn/MulanPSL2
93feeca58Szfw*
103feeca58Szfw* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
113feeca58Szfw* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
123feeca58Szfw* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
133feeca58Szfw*
143feeca58Szfw* See the Mulan PSL v2 for more details.
153feeca58Szfw***************************************************************************************/
163feeca58Szfw
173feeca58Szfwpackage xiangshan.backend.fu
183feeca58Szfw
198891a219SYinan Xuimport org.chipsalliance.cde.config.Parameters
203feeca58Szfwimport chisel3._
213feeca58Szfwimport chisel3.util._
223c02ee8fSwakafaimport utility.{LookupTreeDefault, ParallelMux, ParallelXOR, SignExt, ZeroExt}
23*bb2f3f51STang Haojinimport utility.{XSDebug, XSError}
243feeca58Szfwimport xiangshan._
253feeca58Szfwimport xiangshan.backend.fu.util._
263feeca58Szfw
273feeca58Szfwclass CountModule(implicit p: Parameters) extends XSModule {
283feeca58Szfw  val io = IO(new Bundle() {
293feeca58Szfw    val src = Input(UInt(XLEN.W))
303feeca58Szfw    val func = Input(UInt())
31c0e98e86SYinan Xu    val regEnable = Input(Bool())
323feeca58Szfw    val out = Output(UInt(XLEN.W))
333feeca58Szfw  })
343feeca58Szfw
353feeca58Szfw  def encode(bits: UInt): UInt = {
363feeca58Szfw    LookupTreeDefault(bits, 0.U, List(0.U -> 2.U(2.W), 1.U -> 1.U(2.W)))
373feeca58Szfw  }
383feeca58Szfw  def clzi(msb: Int, left: UInt, right: UInt): UInt = {
393feeca58Szfw    Mux(left(msb),
403feeca58Szfw      Cat(left(msb) && right(msb), !right(msb), if(msb==1)right(0) else right(msb-1, 0)),
413feeca58Szfw      left)
423feeca58Szfw  }
433feeca58Szfw
44c0e98e86SYinan Xu  // stage 0
453feeca58Szfw  val c0 = Wire(Vec(32, UInt(2.W)))
463feeca58Szfw  val c1 = Wire(Vec(16, UInt(3.W)))
473feeca58Szfw  val countSrc = Mux(io.func(1), Reverse(io.src), io.src)
483feeca58Szfw
493feeca58Szfw  for(i <- 0 until 32){ c0(i) := encode(countSrc(2*i+1, 2*i)) }
503feeca58Szfw  for(i <- 0 until 16){ c1(i) := clzi(1, c0(i*2+1), c0(i*2)) }
51c0e98e86SYinan Xu
52c0e98e86SYinan Xu  // pipeline registers
53c0e98e86SYinan Xu  val funcReg = RegEnable(io.func, io.regEnable)
54c0e98e86SYinan Xu  val c2 = Reg(Vec(8, UInt(4.W)))
55c0e98e86SYinan Xu  val cpopTmp = Reg(Vec(4, UInt(5.W)))
56c0e98e86SYinan Xu  when (io.regEnable) {
57c0e98e86SYinan Xu    for (i <- 0 until 8) {
58c0e98e86SYinan Xu      c2(i) := clzi(2, c1(i*2+1), c1(i*2))
59c0e98e86SYinan Xu    }
60c0e98e86SYinan Xu    for (i <- 0 until 4) {
61c0e98e86SYinan Xu      cpopTmp(i) := PopCount(io.src(i*16+15, i*16))
62c0e98e86SYinan Xu    }
63c0e98e86SYinan Xu  }
64c0e98e86SYinan Xu
65c0e98e86SYinan Xu  // stage 1
66c0e98e86SYinan Xu  val c3 = Wire(Vec(4, UInt(5.W)))
67c0e98e86SYinan Xu  val c4 = Wire(Vec(2, UInt(6.W)))
68c0e98e86SYinan Xu
693feeca58Szfw  for(i <- 0 until  4){ c3(i) := clzi(3, c2(i*2+1), c2(i*2)) }
703feeca58Szfw  for(i <- 0 until  2){ c4(i) := clzi(4, c3(i*2+1), c3(i*2)) }
713feeca58Szfw  val zeroRes = clzi(5, c4(1), c4(0))
723feeca58Szfw  val zeroWRes = Mux(funcReg(1), c4(1), c4(0))
733feeca58Szfw
743feeca58Szfw  val cpopLo32 = cpopTmp(0) +& cpopTmp(1)
753feeca58Szfw  val cpopHi32 = cpopTmp(2) +& cpopTmp(3)
763feeca58Szfw
773feeca58Szfw  val cpopRes = cpopLo32 +& cpopHi32
783feeca58Szfw  val cpopWRes = cpopLo32
793feeca58Szfw
803feeca58Szfw  io.out := Mux(funcReg(2), Mux(funcReg(0), cpopWRes, cpopRes), Mux(funcReg(0), zeroWRes, zeroRes))
813feeca58Szfw}
823feeca58Szfw
833feeca58Szfwclass ClmulModule(implicit p: Parameters) extends XSModule {
843feeca58Szfw  val io = IO(new Bundle() {
853feeca58Szfw    val src = Vec(2, Input(UInt(XLEN.W)))
863feeca58Szfw    val func = Input(UInt())
87c0e98e86SYinan Xu    val regEnable = Input(Bool())
883feeca58Szfw    val out = Output(UInt(XLEN.W))
893feeca58Szfw  })
903feeca58Szfw
91c0e98e86SYinan Xu  // stage 0
923feeca58Szfw  val (src1, src2) = (io.src(0), io.src(1))
933feeca58Szfw
943feeca58Szfw  val mul0 = Wire(Vec(64, UInt(128.W)))
953feeca58Szfw  val mul1 = Wire(Vec(32, UInt(128.W)))
963feeca58Szfw  val mul2 = Wire(Vec(16, UInt(128.W)))
973feeca58Szfw
983feeca58Szfw  (0 until XLEN) map { i =>
993feeca58Szfw    mul0(i) := Mux(src1(i), if(i==0) src2 else Cat(src2, 0.U(i.W)), 0.U)
1003feeca58Szfw  }
1013feeca58Szfw  (0 until 32) map { i => mul1(i) := mul0(i*2) ^ mul0(i*2+1)}
1023feeca58Szfw  (0 until 16) map { i => mul2(i) := mul1(i*2) ^ mul1(i*2+1)}
1033feeca58Szfw
104c0e98e86SYinan Xu  // pipeline registers
105c0e98e86SYinan Xu  val funcReg = RegEnable(io.func, io.regEnable)
106c0e98e86SYinan Xu  val mul3 = Reg(Vec(8, UInt(128.W)))
107c0e98e86SYinan Xu  when (io.regEnable) {
108c0e98e86SYinan Xu    (0 until 8) map { i => mul3(i) := mul2(i*2) ^ mul2(i*2+1)}
109c0e98e86SYinan Xu  }
110c0e98e86SYinan Xu
111c0e98e86SYinan Xu  // stage 1
1123feeca58Szfw  val res = ParallelXOR(mul3)
1133feeca58Szfw
1143feeca58Szfw  val clmul  = res(63,0)
1153feeca58Szfw  val clmulh = res(127,64)
1163feeca58Szfw  val clmulr = res(126,63)
1173feeca58Szfw
1183feeca58Szfw  io.out := LookupTreeDefault(funcReg, clmul, List(
1193feeca58Szfw    BKUOpType.clmul  -> clmul,
1203feeca58Szfw    BKUOpType.clmulh -> clmulh,
1213feeca58Szfw    BKUOpType.clmulr -> clmulr
1223feeca58Szfw  ))
1233feeca58Szfw}
1243feeca58Szfw
1253feeca58Szfwclass MiscModule(implicit p: Parameters) extends XSModule {
1263feeca58Szfw  val io = IO(new Bundle() {
1273feeca58Szfw    val src = Vec(2, Input(UInt(XLEN.W)))
1283feeca58Szfw    val func = Input(UInt())
129c0e98e86SYinan Xu    val regEnable = Input(Bool())
1303feeca58Szfw    val out = Output(UInt(XLEN.W))
1313feeca58Szfw  })
1323feeca58Szfw
1333feeca58Szfw  val (src1, src2) = (io.src(0), io.src(1))
1343feeca58Szfw
1353feeca58Szfw  def xpermLUT(table: UInt, idx: UInt, width: Int) : UInt = {
1363feeca58Szfw    // ParallelMux((0 until XLEN/width).map( i => i.U -> table(i)).map( x => (x._1 === idx, x._2)))
1373feeca58Szfw    LookupTreeDefault(idx, 0.U(width.W), (0 until XLEN/width).map( i => i.U -> table(i*width+width-1, i*width)))
1383feeca58Szfw  }
1393feeca58Szfw
1403feeca58Szfw  val xpermnVec = Wire(Vec(16, UInt(4.W)))
1413feeca58Szfw  (0 until 16).map( i => xpermnVec(i) := xpermLUT(src1, src2(i*4+3, i*4), 4))
1423feeca58Szfw  val xpermn = Cat(xpermnVec.reverse)
1433feeca58Szfw
1443feeca58Szfw  val xpermbVec = Wire(Vec(8, UInt(8.W)))
1453feeca58Szfw  (0 until 8).map( i => xpermbVec(i) := Mux(src2(i*8+7, i*8+3).orR, 0.U, xpermLUT(src1, src2(i*8+2, i*8), 8)))
1463feeca58Szfw  val xpermb = Cat(xpermbVec.reverse)
1473feeca58Szfw
148c0e98e86SYinan Xu  io.out := RegEnable(Mux(io.func(0), xpermb, xpermn), io.regEnable)
1493feeca58Szfw}
1503feeca58Szfw
1513feeca58Szfwclass HashModule(implicit p: Parameters) extends XSModule {
1523feeca58Szfw  val io = IO(new Bundle() {
1533feeca58Szfw    val src = Input(UInt(XLEN.W))
1543feeca58Szfw    val func = Input(UInt())
155c0e98e86SYinan Xu    val regEnable = Input(Bool())
1563feeca58Szfw    val out = Output(UInt(XLEN.W))
1573feeca58Szfw  })
1583feeca58Szfw
1593feeca58Szfw  val src1 = io.src
1603feeca58Szfw
1613feeca58Szfw  val sha256sum0 = ROR32(src1, 2)  ^ ROR32(src1, 13) ^ ROR32(src1, 22)
1623feeca58Szfw  val sha256sum1 = ROR32(src1, 6)  ^ ROR32(src1, 11) ^ ROR32(src1, 25)
1633feeca58Szfw  val sha256sig0 = ROR32(src1, 7)  ^ ROR32(src1, 18) ^ SHR32(src1, 3)
1643feeca58Szfw  val sha256sig1 = ROR32(src1, 17) ^ ROR32(src1, 19) ^ SHR32(src1, 10)
1653feeca58Szfw  val sha512sum0 = ROR64(src1, 28) ^ ROR64(src1, 34) ^ ROR64(src1, 39)
1663feeca58Szfw  val sha512sum1 = ROR64(src1, 14) ^ ROR64(src1, 18) ^ ROR64(src1, 41)
1673feeca58Szfw  val sha512sig0 = ROR64(src1, 1)  ^ ROR64(src1, 8)  ^ SHR64(src1, 7)
1683feeca58Szfw  val sha512sig1 = ROR64(src1, 19) ^ ROR64(src1, 61) ^ SHR64(src1, 6)
1693feeca58Szfw  val sm3p0      = ROR32(src1, 23) ^ ROR32(src1, 15) ^ src1
1703feeca58Szfw  val sm3p1      = ROR32(src1, 9)  ^ ROR32(src1, 17) ^ src1
1713feeca58Szfw
1723feeca58Szfw  val shaSource = VecInit(Seq(
1733feeca58Szfw    SignExt(sha256sum0(31,0), XLEN),
1743feeca58Szfw    SignExt(sha256sum1(31,0), XLEN),
1753feeca58Szfw    SignExt(sha256sig0(31,0), XLEN),
1763feeca58Szfw    SignExt(sha256sig1(31,0), XLEN),
1773feeca58Szfw    sha512sum0,
1783feeca58Szfw    sha512sum1,
1793feeca58Szfw    sha512sig0,
1803feeca58Szfw    sha512sig1
1813feeca58Szfw  ))
1823feeca58Szfw  val sha = shaSource(io.func(2,0))
1833feeca58Szfw  val sm3 = Mux(io.func(0), SignExt(sm3p1(31,0), XLEN), SignExt(sm3p0(31,0), XLEN))
1843feeca58Szfw
185c0e98e86SYinan Xu  io.out := RegEnable(Mux(io.func(3), sm3, sha), io.regEnable)
1863feeca58Szfw}
1873feeca58Szfw
1883feeca58Szfwclass BlockCipherModule(implicit p: Parameters) extends XSModule {
1893feeca58Szfw  val io = IO(new Bundle() {
1903feeca58Szfw    val src = Vec(2, Input(UInt(XLEN.W)))
1913feeca58Szfw    val func = Input(UInt())
192c0e98e86SYinan Xu    val regEnable = Input(Bool())
1933feeca58Szfw    val out = Output(UInt(XLEN.W))
1943feeca58Szfw  })
1953feeca58Szfw
196c0e98e86SYinan Xu  val (src1, src2, func, funcReg) = (io.src(0), io.src(1), io.func, RegEnable(io.func, io.regEnable))
1973feeca58Szfw
1983feeca58Szfw  val src1Bytes = VecInit((0 until 8).map(i => src1(i*8+7, i*8)))
1993feeca58Szfw  val src2Bytes = VecInit((0 until 8).map(i => src2(i*8+7, i*8)))
2003feeca58Szfw
2013feeca58Szfw  // AES
2023feeca58Szfw  val aesSboxIn  = ForwardShiftRows(src1Bytes, src2Bytes)
2033feeca58Szfw  val aesSboxMid  = Reg(Vec(8, Vec(18, Bool())))
2043feeca58Szfw  val aesSboxOut  = Wire(Vec(8, UInt(8.W)))
2053feeca58Szfw
2063feeca58Szfw  val iaesSboxIn = InverseShiftRows(src1Bytes, src2Bytes)
2073feeca58Szfw  val iaesSboxMid  = Reg(Vec(8, Vec(18, Bool())))
2083feeca58Szfw  val iaesSboxOut = Wire(Vec(8, UInt(8.W)))
2093feeca58Szfw
2103feeca58Szfw  aesSboxOut.zip(aesSboxMid).zip(aesSboxIn)foreach { case ((out, mid), in) =>
211c0e98e86SYinan Xu    when (io.regEnable) {
2123feeca58Szfw      mid := SboxInv(SboxAesTop(in))
213c0e98e86SYinan Xu    }
2143feeca58Szfw    out := SboxAesOut(mid)
2153feeca58Szfw  }
2163feeca58Szfw
2173feeca58Szfw  iaesSboxOut.zip(iaesSboxMid).zip(iaesSboxIn)foreach { case ((out, mid), in) =>
218c0e98e86SYinan Xu    when (io.regEnable) {
2193feeca58Szfw      mid := SboxInv(SboxIaesTop(in))
220c0e98e86SYinan Xu    }
2213feeca58Szfw    out := SboxIaesOut(mid)
2223feeca58Szfw  }
2233feeca58Szfw
2243feeca58Szfw  val aes64es = aesSboxOut.asUInt
2253feeca58Szfw  val aes64ds = iaesSboxOut.asUInt
2263feeca58Szfw
227c0e98e86SYinan Xu  val imMinIn  = RegEnable(src1Bytes, io.regEnable)
2283feeca58Szfw
2293feeca58Szfw  val aes64esm = Cat(MixFwd(Seq(aesSboxOut(4), aesSboxOut(5), aesSboxOut(6), aesSboxOut(7))),
2303feeca58Szfw                     MixFwd(Seq(aesSboxOut(0), aesSboxOut(1), aesSboxOut(2), aesSboxOut(3))))
2313feeca58Szfw  val aes64dsm = Cat(MixInv(Seq(iaesSboxOut(4), iaesSboxOut(5), iaesSboxOut(6), iaesSboxOut(7))),
2323feeca58Szfw                     MixInv(Seq(iaesSboxOut(0), iaesSboxOut(1), iaesSboxOut(2), iaesSboxOut(3))))
2333feeca58Szfw  val aes64im  = Cat(MixInv(Seq(imMinIn(4), imMinIn(5), imMinIn(6), imMinIn(7))),
2343feeca58Szfw                     MixInv(Seq(imMinIn(0), imMinIn(1), imMinIn(2), imMinIn(3))))
2353feeca58Szfw
2363feeca58Szfw
2373feeca58Szfw  val rcon = WireInit(VecInit(Seq("h01".U, "h02".U, "h04".U, "h08".U,
2383feeca58Szfw                                  "h10".U, "h20".U, "h40".U, "h80".U,
2393feeca58Szfw                                  "h1b".U, "h36".U, "h00".U)))
2403feeca58Szfw
2413feeca58Szfw  val ksSboxIn  = Wire(Vec(4, UInt(8.W)))
2423feeca58Szfw  val ksSboxTop = Reg(Vec(4, Vec(21, Bool())))
2433feeca58Szfw  val ksSboxOut = Wire(Vec(4, UInt(8.W)))
2443feeca58Szfw  ksSboxIn(0) := Mux(src2(3,0) === "ha".U, src1Bytes(4), src1Bytes(5))
2453feeca58Szfw  ksSboxIn(1) := Mux(src2(3,0) === "ha".U, src1Bytes(5), src1Bytes(6))
2463feeca58Szfw  ksSboxIn(2) := Mux(src2(3,0) === "ha".U, src1Bytes(6), src1Bytes(7))
2473feeca58Szfw  ksSboxIn(3) := Mux(src2(3,0) === "ha".U, src1Bytes(7), src1Bytes(4))
2483feeca58Szfw  ksSboxOut.zip(ksSboxTop).zip(ksSboxIn).foreach{ case ((out, top), in) =>
249c0e98e86SYinan Xu    when (io.regEnable) {
2503feeca58Szfw      top := SboxAesTop(in)
251c0e98e86SYinan Xu    }
2523feeca58Szfw    out := SboxAesOut(SboxInv(top))
2533feeca58Szfw    }
2543feeca58Szfw
255c0e98e86SYinan Xu  val ks1Idx = RegEnable(src2(3,0), io.regEnable)
2563feeca58Szfw  val aes64ks1i = Cat(ksSboxOut.asUInt ^ rcon(ks1Idx), ksSboxOut.asUInt ^ rcon(ks1Idx))
2573feeca58Szfw
2583feeca58Szfw  val aes64ks2Temp = src1(63,32) ^ src2(31,0)
259c0e98e86SYinan Xu  val aes64ks2 = RegEnable(Cat(aes64ks2Temp ^ src2(63,32), aes64ks2Temp), io.regEnable)
2603feeca58Szfw
2613feeca58Szfw  val aesResult = LookupTreeDefault(funcReg, aes64es, List(
2623feeca58Szfw    BKUOpType.aes64es   -> aes64es,
2633feeca58Szfw    BKUOpType.aes64esm  -> aes64esm,
2643feeca58Szfw    BKUOpType.aes64ds   -> aes64ds,
2653feeca58Szfw    BKUOpType.aes64dsm  -> aes64dsm,
2663feeca58Szfw    BKUOpType.aes64im   -> aes64im,
2673feeca58Szfw    BKUOpType.aes64ks1i -> aes64ks1i,
2683feeca58Szfw    BKUOpType.aes64ks2  -> aes64ks2
2693feeca58Szfw  ))
2703feeca58Szfw
2713feeca58Szfw  // SM4
2723feeca58Szfw  val sm4SboxIn  = src2Bytes(func(1,0))
2733feeca58Szfw  val sm4SboxTop = Reg(Vec(21, Bool()))
274c0e98e86SYinan Xu  when (io.regEnable) {
2753feeca58Szfw    sm4SboxTop := SboxSm4Top(sm4SboxIn)
276c0e98e86SYinan Xu  }
2773feeca58Szfw  val sm4SboxOut = SboxSm4Out(SboxInv(sm4SboxTop))
2783feeca58Szfw
27919bcce38SFawang Zhang  val sm4ed = sm4SboxOut ^ (sm4SboxOut<<8) ^ (sm4SboxOut<<2) ^ (sm4SboxOut<<18) ^ ((sm4SboxOut&"h3f".U)<<26) ^ ((sm4SboxOut&"hc0".U)<<10)
28019bcce38SFawang Zhang  val sm4ks = sm4SboxOut ^ ((sm4SboxOut&"h07".U)<<29) ^ ((sm4SboxOut&"hfe".U)<<7) ^ ((sm4SboxOut&"h01".U)<<23) ^ ((sm4SboxOut&"hf8".U)<<13)
2813feeca58Szfw  val sm4Source = VecInit(Seq(
2823feeca58Szfw    sm4ed(31,0),
2833feeca58Szfw    Cat(sm4ed(23,0), sm4ed(31,24)),
2843feeca58Szfw    Cat(sm4ed(15,0), sm4ed(31,16)),
2853feeca58Szfw    Cat(sm4ed( 7,0), sm4ed(31,8)),
2863feeca58Szfw    sm4ks(31,0),
2873feeca58Szfw    Cat(sm4ks(23,0), sm4ks(31,24)),
2883feeca58Szfw    Cat(sm4ks(15,0), sm4ks(31,16)),
2893feeca58Szfw    Cat(sm4ks( 7,0), sm4ks(31,8))
2903feeca58Szfw  ))
291c0e98e86SYinan Xu  val sm4Result = SignExt((sm4Source(funcReg(2,0)) ^ RegEnable(src1(31,0), io.regEnable))(31,0), XLEN)
2923feeca58Szfw
2933feeca58Szfw  io.out := Mux(funcReg(3), sm4Result, aesResult)
2943feeca58Szfw}
2953feeca58Szfw
2963feeca58Szfwclass CryptoModule(implicit p: Parameters) extends XSModule {
2973feeca58Szfw  val io = IO(new Bundle() {
2983feeca58Szfw    val src = Vec(2, Input(UInt(XLEN.W)))
2993feeca58Szfw    val func = Input(UInt())
300c0e98e86SYinan Xu    val regEnable = Input(Bool())
3013feeca58Szfw    val out = Output(UInt(XLEN.W))
3023feeca58Szfw  })
3033feeca58Szfw
3043feeca58Szfw  val (src1, src2, func) = (io.src(0), io.src(1), io.func)
305c0e98e86SYinan Xu  val funcReg = RegEnable(func, io.regEnable)
3063feeca58Szfw
3073feeca58Szfw  val hashModule = Module(new HashModule)
3083feeca58Szfw  hashModule.io.src := src1
3093feeca58Szfw  hashModule.io.func := func
310c0e98e86SYinan Xu  hashModule.io.regEnable := io.regEnable
3113feeca58Szfw
3123feeca58Szfw  val blockCipherModule = Module(new BlockCipherModule)
3133feeca58Szfw  blockCipherModule.io.src(0) := src1
3143feeca58Szfw  blockCipherModule.io.src(1) := src2
3153feeca58Szfw  blockCipherModule.io.func := func
316c0e98e86SYinan Xu  blockCipherModule.io.regEnable := io.regEnable
3173feeca58Szfw
3183feeca58Szfw  io.out := Mux(funcReg(4), hashModule.io.out, blockCipherModule.io.out)
3193feeca58Szfw}
3203feeca58Szfw
3213b739f49SXuan Huclass Bku(cfg: FuConfig)(implicit p: Parameters) extends FuncUnit(cfg) with HasPipelineReg {
3223feeca58Szfw
323c0e98e86SYinan Xu  override def latency = 2
3243feeca58Szfw
325c0e98e86SYinan Xu  val (src1, src2, func) = (
3266a35d972SXuan Hu    io.in.bits.data.src(0),
3276a35d972SXuan Hu    io.in.bits.data.src(1),
3286a35d972SXuan Hu    io.in.bits.ctrl.fuOpType
3293feeca58Szfw  )
3303feeca58Szfw
3313feeca58Szfw  val countModule = Module(new CountModule)
3323feeca58Szfw  countModule.io.src := src1
3333feeca58Szfw  countModule.io.func := func
334c0e98e86SYinan Xu  countModule.io.regEnable := regEnable(1)
3353feeca58Szfw
3363feeca58Szfw  val clmulModule = Module(new ClmulModule)
3373feeca58Szfw  clmulModule.io.src(0) := src1
3383feeca58Szfw  clmulModule.io.src(1) := src2
3393feeca58Szfw  clmulModule.io.func := func
340c0e98e86SYinan Xu  clmulModule.io.regEnable := regEnable(1)
3413feeca58Szfw
3423feeca58Szfw  val miscModule = Module(new MiscModule)
3433feeca58Szfw  miscModule.io.src(0) := src1
3443feeca58Szfw  miscModule.io.src(1) := src2
3453feeca58Szfw  miscModule.io.func := func
346c0e98e86SYinan Xu  miscModule.io.regEnable := regEnable(1)
3473feeca58Szfw
3483feeca58Szfw  val cryptoModule = Module(new CryptoModule)
3493feeca58Szfw  cryptoModule.io.src(0) := src1
3503feeca58Szfw  cryptoModule.io.src(1) := src2
3513feeca58Szfw  cryptoModule.io.func := func
352c0e98e86SYinan Xu  cryptoModule.io.regEnable := regEnable(1)
3533feeca58Szfw
3543feeca58Szfw
355c0e98e86SYinan Xu  // CountModule, ClmulModule, MiscModule, and CryptoModule have a latency of 1 cycle
3563b739f49SXuan Hu  val funcReg = RegEnable(func, io.in.fire)
3573feeca58Szfw  val result = Mux(funcReg(5), cryptoModule.io.out,
3583feeca58Szfw                  Mux(funcReg(3), countModule.io.out,
3593feeca58Szfw                      Mux(funcReg(2),miscModule.io.out, clmulModule.io.out)))
3603feeca58Szfw
3616a35d972SXuan Hu  io.out.bits.res.data := RegEnable(result, regEnable(2))
362ea0f92d8Sczw  // connectNonPipedCtrlSingal
3633feeca58Szfw}
364