1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
// SPDX-License-Identifier: Apache-2.0
package chisel3.util
import chisel3._
/** For each element in a list, muxes (looks up) between cases (one per list element) based on a
* common address.
*
* @note This appears to be an odd, specialized operator that we haven't seen used much, and seems
* to be a holdover from chisel2. This may be deprecated and removed, usage is not
* recommended.
*
* @param addr common select for cases, shared (same) across all list elements
* @param default default value for each list element, should the address not match any case
* @param mapping list of cases, where each entry consists of a [[chisel3.util.BitPat BitPath]] (compared against addr) and
* a list of elements (same length as default) that is the output value for that
* element (will have the same index in the output).
*
* @example {{{
* ListLookup(2.U, // address for comparison
* List(10.U, 11.U, 12.U), // default "row" if none of the following cases match
* Array(BitPat(2.U) -> List(20.U, 21.U, 22.U), // this "row" hardware-selected based off address 2.U
* BitPat(3.U) -> List(30.U, 31.U, 32.U))
* ) // hardware-evaluates to List(20.U, 21.U, 22.U)
* // Note: if given address 0.U, the above would hardware evaluate to List(10.U, 11.U, 12.U)
* }}}
*/
object ListLookup {
def apply[T <: Data](addr: UInt, default: List[T], mapping: Array[(BitPat, List[T])]): List[T] = {
val map = mapping.map(m => (m._1 === addr, m._2))
default.zipWithIndex.map {
case (d, i) =>
map.foldRight(d)((m, n) => Mux(m._1, m._2(i), n))
}
}
}
/** Muxes between cases based on whether an address matches any pattern for a case.
* Similar to [[chisel3.util.MuxLookup MuxLookup]], but uses [[chisel3.util.BitPat BitPat]] for address comparison.
*
* @note This appears to be an odd, specialized operator that we haven't seen used much, and seems
* to be a holdover from chisel2. This may be deprecated and removed, usage is not
* recommended.
*
* @param addr address to select between cases
* @param default default value should the address not match any case
* @param mapping list of cases, where each entry consists of a [[chisel3.util.BitPat BitPat]] (compared against addr) and the
* output value if the BitPat matches
*/
object Lookup {
def apply[T <: Bits](addr: UInt, default: T, mapping: Seq[(BitPat, T)]): T =
ListLookup(addr, List(default), mapping.map(m => (m._1, List(m._2))).toArray).head
}
|