BitUtils.scala 3.4 KB
Newer Older
1 2 3 4
package utils

import chisel3._
import chisel3.util._
5
import scala.math.min
6 7 8 9

object WordShift {
  def apply(data: UInt, wordIndex: UInt, step: Int) = (data << (wordIndex * step.U))
}
Z
Zihao Yu 已提交
10 11 12 13

object MaskExpand {
 def apply(m: UInt) = Cat(m.asBools.map(Fill(8, _)).reverse)
}
Z
Zihao Yu 已提交
14

Z
Zihao Yu 已提交
15 16 17 18 19 20
object MaskData {
 def apply(oldData: UInt, newData: UInt, fullmask: UInt) = {
   (newData & fullmask) | (oldData & ~fullmask)
 }
}

Z
Zihao Yu 已提交
21 22 23 24
object SignExt {
  def apply(a: UInt, len: Int) = {
    val aLen = a.getWidth
    val signBit = a(aLen-1)
W
William Wang 已提交
25
    if (aLen >= len) a(len-1,0) else Cat(Fill(len - aLen, signBit), a)
Z
Zihao Yu 已提交
26 27 28 29 30 31
  }
}

object ZeroExt {
  def apply(a: UInt, len: Int) = {
    val aLen = a.getWidth
W
William Wang 已提交
32
    if (aLen >= len) a(len-1,0) else Cat(0.U((len - aLen).W), a)
Z
Zihao Yu 已提交
33 34
  }
}
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54

object Or {
  // Fill 1s from low bits to high bits
  def leftOR(x: UInt): UInt = leftOR(x, x.getWidth, x.getWidth)
  def leftOR(x: UInt, width: Integer, cap: Integer = 999999): UInt = {
    val stop = min(width, cap)
    def helper(s: Int, x: UInt): UInt =
      if (s >= stop) x else helper(s+s, x | (x << s)(width-1,0))
    helper(1, x)(width-1, 0)
  }

  // Fill 1s form high bits to low bits
  def rightOR(x: UInt): UInt = rightOR(x, x.getWidth, x.getWidth)
  def rightOR(x: UInt, width: Integer, cap: Integer = 999999): UInt = {
    val stop = min(width, cap)
    def helper(s: Int, x: UInt): UInt =
      if (s >= stop) x else helper(s+s, x | (x >> s))
    helper(1, x)(width-1, 0)
  }
}
A
Allen 已提交
55 56 57 58 59 60

object OneHot {
  def OH1ToOH(x: UInt): UInt = (x << 1 | 1.U) & ~Cat(0.U(1.W), x)
  def OH1ToUInt(x: UInt): UInt = OHToUInt(OH1ToOH(x))
  def UIntToOH1(x: UInt, width: Int): UInt = ~((-1).S(width.W).asUInt << x)(width-1, 0)
  def UIntToOH1(x: UInt): UInt = UIntToOH1(x, (1 << x.getWidth) - 1)
A
Allen 已提交
61 62
  def checkOneHot(in: Bits): Unit = assert(PopCount(in) <= 1.U)
  def checkOneHot(in: Iterable[Bool]): Unit = assert(PopCount(in) <= 1.U)
A
Allen 已提交
63
}
64

G
GouLingrui 已提交
65 66
object LowerMask {
  def apply(a: UInt, len: Int) = {
L
Lingrui98 已提交
67 68 69 70 71 72 73 74 75 76 77 78 79
    ParallelOR((0 until len).map(i => a >> i.U))
  }
  def apply(a: UInt): UInt = {
    apply(a, a.getWidth)
  }
}

object HigherMask {
  def apply(a: UInt, len: Int) = {
    Reverse(LowerMask(Reverse(a), len))
  }
  def apply(a: UInt): UInt = {
    apply(a, a.getWidth)
G
GouLingrui 已提交
80 81 82
  }
}

L
Lingrui98 已提交
83 84 85 86 87 88 89 90 91 92 93 94
object LowerMaskFromLowest {
  def apply(a: UInt) = {
    LowerMask(PriorityEncoderOH(a))
  }
}

object HigherMaskFromHighest {
  def apply(a: UInt) = {
    Reverse(LowerMask(PriorityEncoderOH(Reverse(a))))
  }
}

G
GouLingrui 已提交
95 96
object LowestBit {
  def apply(a: UInt, len: Int) = {
L
Lingrui98 已提交
97
    Mux(a(0), 1.U(len.W), Reverse((ParallelOR((0 until len).map(i => Reverse(a(len - 1, 0)) >> i.U)) + 1.U) >> 1.U))
G
GouLingrui 已提交
98 99 100 101 102 103 104 105
  }
}

object HighestBit {
  def apply(a: UInt, len: Int) = {
    Reverse(LowestBit(Reverse(a), len))
  }
}
W
William Wang 已提交
106 107 108 109 110

object GenMask {
  // generate w/r mask
  def apply(high: Int, low: Int) = {
    require(high > low)
L
LinJiawei 已提交
111
    (VecInit(List.fill(high+1)(true.B)).asUInt >> low << low).asUInt()
W
William Wang 已提交
112 113
  }
  def apply(pos: Int) = {
L
LinJiawei 已提交
114
    (1.U << pos).asUInt()
W
William Wang 已提交
115
  }
Y
Yinan Xu 已提交
116 117 118
}

object UIntToMask {
119
  def apply(ptr: UInt, length: Integer) = UIntToOH(ptr)(length - 1, 0) - 1.U
Y
Yinan Xu 已提交
120
}
121 122 123 124 125 126 127 128 129 130 131 132

object GetEvenBits {
  def apply(input: UInt): UInt = {
    VecInit((0 until input.getWidth/2).map(i => {input(2*i)})).asUInt
  }
}


object GetOddBits {
  def apply(input: UInt): UInt = {
    VecInit((0 until input.getWidth/2).map(i => {input(2*i+1)})).asUInt
  }
133 134 135 136 137 138 139
}

object XORFold {
  def apply(input: UInt, reswidth: Int): UInt = {
    require(input.getWidth*2>=reswidth)
    input(reswidth-1, 0) ^ input(2*reswidth-1, reswidth)
  }
140
}