summaryrefslogtreecommitdiff
path: root/core/src/main/scala/chisel3/internal/prefix.scala
blob: 1e4c5ff132563e0aaabe149f6d828c17fcaf6c96 (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
// SPDX-License-Identifier: Apache-2.0

package chisel3.internal

/** Use to add a prefix to any components generated in the provided scope.
  *
  * @example {{{
  *
  * val x1 = prefix("first") {
  *   // Anything generated here will be prefixed with "first"
  * }
  *
  * val x2 = prefix(mysignal) {
  *   // Anything generated here will be prefixed with the name of mysignal
  * }
  *
  * }}}
  */
private[chisel3] object prefix { // scalastyle:ignore

  /** Use to add a prefix to any components generated in the provided scope
    * The prefix is the name of the provided which, which may not be known yet.
    *
    * @param name The signal/instance whose name will be the prefix
    * @param f a function for which any generated components are given the prefix
    * @tparam T The return type of the provided function
    * @return The return value of the provided function
    */
  def apply[T](name: HasId)(f: => T): T = {
    val pushed = Builder.pushPrefix(name)
    val ret = f
    if (pushed) {
      Builder.popPrefix()
    }
    ret
  }

  /** Use to add a prefix to any components generated in the provided scope
    * The prefix is a string, which must be known when this function is used.
    *
    * @param name The name which will be the prefix
    * @param f a function for which any generated components are given the prefix
    * @tparam T The return type of the provided function
    * @return The return value of the provided function
    */
  def apply[T](name: String)(f: => T): T = {
    Builder.pushPrefix(name)
    val ret = f
    // Sometimes val's can occur between the Module.apply and Module constructor
    // This causes extra prefixes to be added, and subsequently cleared in the
    // Module constructor. Thus, we need to just make sure if the previous push
    // was an incorrect one, to not pop off an empty stack
    if (Builder.getPrefix.nonEmpty) Builder.popPrefix()
    ret
  }
}

/** Use to eliminate any existing prefixes within the provided scope.
  *
  * @example {{{
  *
  * val x1 = noPrefix {
  *   // Anything generated here will not be prefixed by anything outside this scope
  * }
  *
  * }}}
  */
private[chisel3] object noPrefix {

  /** Use to clear existing prefixes so no signals within the scope are prefixed by signals/names
    * outside the scope
    *
    * @param f a function for which any generated components are given the prefix
    * @tparam T The return type of the provided function
    * @return The return value of the provided function
    */
  def apply[T](f: => T): T = {
    val prefix = Builder.getPrefix
    Builder.clearPrefix()
    val ret = f
    Builder.setPrefix(prefix)
    ret
  }
}