xref: /XiangShan/src/main/scala/utils/BitsUtils.scala (revision 195ef4a53ab54326d879e884c4e1568f424f2668)
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
17package utils
18
19import chisel3._
20import chisel3.util._
21
22import scala.math.min
23
24/** Scan an input signal with fixed length.
25 * Set 1 at the end of the length-fixed scan chain if the scanned bits meet the condition.
26 *
27 * @example {{{
28 * val data = Seq(false.B, true.B, true.B, false.B, true.B)
29 * def condition(input: Seq[Bool]) : Bool = input(0) && input(1)
30 * val onesLen2EndVec = FixLengthScanSetEnd(data, 2, condition)
31 * assert(VecInit(onesLen2EndVec).asUInt === VecInit(Seq(false.B, false.B, true.B, false.B, false.B)).asUInt)
32 * }}}
33 */
34object FixedLengthScanSetEnd {
35  def apply(input: Seq[Bool], scanLen: Int, condition: Seq[Bool] => Bool) : Seq[Bool] = {
36    require(scanLen > 0)
37    val res: Vec[Bool] = VecInit(Seq.fill(input.size)(false.B))
38    for (i <- (scanLen - 1) until input.size) {
39      res(i) := condition((1 - scanLen until 1).map(_ + i).map(input(_)))
40    }
41    res
42  }
43}
44
45object ConsecutiveOnesSetEnd {
46  def apply(input: Seq[Bool], thres: Int): Seq[Bool] = {
47    def condition(input: Seq[Bool]): Bool = input.reduce(_ && _)
48    FixedLengthScanSetEnd(input, thres, condition)
49  }
50}
51
52object ConsecutiveOnes {
53  def apply(input: Seq[Bool], thres: Int): Bool = {
54    require(thres > 0)
55    ConsecutiveOnesSetEnd(input, thres).reduce(_ || _)
56  }
57}