summaryrefslogtreecommitdiff
path: root/src/main/scala/chisel3/util/Conditional.scala
blob: 58a304053198ecc6395be8e14e0f4ac9430ad8d3 (plain)
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// // SPDX-License-Identifier: Apache-2.0

// /** Conditional blocks.
//   */

// package chisel3.util

// import scala.language.reflectiveCalls

// import chisel3._

// /** Implementation details for [[switch]]. See [[switch]] and [[chisel3.util.is is]] for the
//   * user-facing API.
//   * @note DO NOT USE. This API is subject to change without warning.
//   */
// class SwitchContext[T <: Element](cond: T, whenContext: Option[WhenContext], lits: Set[BigInt]) {
//   def is(
//     v:     Iterable[T]
//   )(block: => Any
//   )(
//     implicit sourceInfo: SourceInfo,
//     compileOptions:      CompileOptions
//   ): SwitchContext[T] = {
//     if (!v.isEmpty) {
//       val newLits = v.map { w =>
//         require(w.litOption.isDefined, "is condition must be literal")
//         val value = w.litValue
//         require(!lits.contains(value), "all is conditions must be mutually exclusive!")
//         value
//       }
//       // def instead of val so that logic ends up in legal place
//       def p = v.map(_.asUInt === cond.asUInt).reduce(_ || _)
//       whenContext match {
//         case Some(w) => new SwitchContext(cond, Some(w.elsewhen(p)(block)), lits ++ newLits)
//         case None    => new SwitchContext(cond, Some(when(p)(block)), lits ++ newLits)
//       }
//     } else {
//       this
//     }
//   }
//   def is(v: T)(block: => Any)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SwitchContext[T] =
//     is(Seq(v))(block)
//   def is(
//     v:     T,
//     vr:    T*
//   )(block: => Any
//   )(
//     implicit sourceInfo: SourceInfo,
//     compileOptions:      CompileOptions
//   ): SwitchContext[T] = is(v :: vr.toList)(block)
// }

// /** Use to specify cases in a [[switch]] block, equivalent to a [[when$ when]] block comparing to
//   * the condition variable.
//   *
//   * @note illegal outside a [[switch]] block
//   * @note must be a literal
//   * @note each is must be mutually exclusive
//   * @note dummy implementation, a macro inside [[switch]] transforms this into the actual
//   * implementation
//   */
// object is {
//   // TODO: Begin deprecation of non-type-parameterized is statements.
//   /** Executes `block` if the switch condition is equal to any of the values in `v`.
//     */
//   def apply(v: Iterable[Element])(block: => Any) {
//     require(false, "The 'is' keyword may not be used outside of a switch.")
//   }

//   /** Executes `block` if the switch condition is equal to `v`.
//     */
//   def apply(v: Element)(block: => Any) {
//     require(false, "The 'is' keyword may not be used outside of a switch.")
//   }

//   /** Executes `block` if the switch condition is equal to any of the values in the argument list.
//     */
//   def apply(v: Element, vr: Element*)(block: => Any) {
//     require(false, "The 'is' keyword may not be used outside of a switch.")
//   }
// }

// /** Conditional logic to form a switch block. See [[is$ is]] for the case API.
//   *
//   * @example {{{
//   * switch (myState) {
//   *   is (state1) {
//   *     // some logic here that runs when myState === state1
//   *   }
//   *   is (state2) {
//   *     // some logic here that runs when myState === state2
//   *   }
//   * }
//   * }}}
//   */
// object switch {
//   def apply[T <: Element](cond: T)(x: => Any): Unit = macro impl
//   def impl(c: Context)(cond: c.Tree)(x: c.Tree): c.Tree = {
//     import c.universe._
//     val q"..$body" = x
//     val res = body.foldLeft(q"""new chisel3.util.SwitchContext($cond, None, Set.empty)""") {
//       case (acc, tree) =>
//         tree match {
//           // TODO: remove when Chisel compatibility package is removed
//           case q"Chisel.`package`.is.apply( ..$params )( ..$body )" => q"$acc.is( ..$params )( ..$body )"
//           case q"chisel3.util.is.apply( ..$params )( ..$body )"     => q"$acc.is( ..$params )( ..$body )"
//           case b                                                    => throw new Exception(s"Cannot include blocks that do not begin with is() in switch.")
//         }
//     }
//     q"""{ $res }"""
//   }
// }