summaryrefslogtreecommitdiff
path: root/core/src/main/scala/chisel3/experimental/package.scala
blob: 8018159fc64ede707c2b0a2ade716a7380cb3ca9 (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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
// SPDX-License-Identifier: Apache-2.0

package chisel3

import chisel3.internal.NamedComponent
import chisel3.internal.sourceinfo.SourceInfo

/** Package for experimental features, which may have their API changed, be removed, etc.
  *
  * Because its contents won't necessarily have the same level of stability and support as
  * non-experimental, you must explicitly import this package to use its contents.
  */
package object experimental {
  import scala.language.implicitConversions
  import chisel3.internal.BaseModule

  // Implicit conversions for BlackBox Parameters
  implicit def fromIntToIntParam(x: Int): IntParam = IntParam(BigInt(x))
  implicit def fromLongToIntParam(x: Long): IntParam = IntParam(BigInt(x))
  implicit def fromBigIntToIntParam(x: BigInt): IntParam = IntParam(x)
  implicit def fromDoubleToDoubleParam(x: Double): DoubleParam = DoubleParam(x)
  implicit def fromStringToStringParam(x: String): StringParam = StringParam(x)

  type ChiselEnum = EnumFactory

  // Rocket Chip-style clonemodule

  /** A record containing the results of CloneModuleAsRecord
    * The apply method is retrieves the element with the supplied name.
    */
  type ClonePorts = BaseModule.ClonePorts

  object CloneModuleAsRecord {
    /** Clones an existing module and returns a record of all its top-level ports.
      * Each element of the record is named with a string matching the
      * corresponding port's name and shares the port's type.
      * @example {{{
      * val q1 = Module(new Queue(UInt(32.W), 2))
      * val q2_io = CloneModuleAsRecord(q1)("io").asInstanceOf[q1.io.type]
      * q2_io.enq <> q1.io.deq
      * }}}
      */
    def apply(proto: BaseModule)(implicit sourceInfo: chisel3.internal.sourceinfo.SourceInfo, compileOptions: CompileOptions): ClonePorts = {
      BaseModule.cloneIORecord(proto)
    }
  }

  val requireIsHardware = chisel3.internal.requireIsHardware
  val requireIsChiselType =  chisel3.internal.requireIsChiselType
  type Direction = ActualDirection
  val Direction = ActualDirection

  implicit class ChiselRange(val sc: StringContext) extends AnyVal {

    import scala.language.experimental.macros

    /** Specifies a range using mathematical range notation. Variables can be interpolated using
      * standard string interpolation syntax.
      * @example {{{
      * UInt(range"[0, 2)")
      * UInt(range"[0, \$myInt)")
      * UInt(range"[0, \${myInt + 2})")
      * }}}
      */
    def range(args: Any*): chisel3.internal.firrtl.IntervalRange = macro chisel3.internal.RangeTransform.apply
  }

  class dump extends chisel3.internal.naming.dump
  class treedump extends chisel3.internal.naming.treedump
  /** Experimental macro for naming Chisel hardware values
    *
    * By default, Chisel uses reflection for naming which only works for public fields of `Bundle`
    * and `Module` classes. Applying this macro annotation to a `class` or `object` enables Chisel
    * to name any hardware values within the annotated `class` or `object.
    *
    * @example {{{
    * import chisel3._
    * import chisel3.experimental.chiselName
    *
    * @chiselName
    * class MyModule extends Module {
    *   val io = IO(new Bundle {
    *     val in = Input(UInt(8.W))
    *     val out = Output(UInt(8.W))
    *   })
    *   def createReg(): Unit = {
    *     // @chiselName allows Chisel to name this Reg
    *     val myReg = RegInit(io.in)
    *     io.out := myReg
    *   }
    *   createReg()
    * }
    * }}}
    */
  class chiselName extends chisel3.internal.naming.chiselName
  /** Do not name instances of this type in [[chiselName]]
    *
    * By default, `chiselName` will include `val` names of instances of annotated classes as a
    * prefix in final naming. Mixing in this trait to a `class`, `object`, or anonymous `class`
    * instances will exclude the `val` name from `chiselName` naming.
    *
    * @example {{{
    * import chisel3._
    * import chisel3.experimental.{chiselName, NoChiselNamePrefix}
    *
    * // Note that this is not a Module
    * @chiselName
    * class Counter(w: Int) {
    *   val myReg = RegInit(0.U(w.W))
    *   myReg := myReg + 1.U
    * }
    *
    * @chiselName
    * class MyModule extends Module {
    *   val io = IO(new Bundle {
    *     val out = Output(UInt(8.W))
    *   })
    *   // Name of myReg will be "counter0_myReg"
    *   val counter0 = new Counter(8)
    *   // Name of myReg will be "myReg"
    *   val counter1 = new Counter(8) with NoChiselNamePrefix
    *   io.out := counter0.myReg + counter1.myReg
    * }
    * }}}
    */
  trait NoChiselNamePrefix

  object BundleLiterals {
    implicit class AddBundleLiteralConstructor[T <: Record](x: T) {
      def Lit(elems: (T => (Data, Data))*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
        x._makeLit(elems: _*)
      }
    }
  }

  /** This class provides the `Lit` method needed to define a `Vec` literal
    */
  object VecLiterals {
    implicit class AddVecLiteralConstructor[T <: Data](x: Vec[T]) {
      /** Given a generator of a list tuples of the form [Int, Data]
        * constructs a Vec literal, parallel concept to `BundleLiteral`
        *
        * @param elems tuples of an index and a literal value
        * @return
        */
      def Lit(elems: (Int, T)*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = {
        x._makeLit(elems: _*)
      }
    }

    implicit class AddObjectLiteralConstructor(x: Vec.type) {
      /** This provides an literal construction method for cases using
        * object `Vec` as in `Vec.Lit(1.U, 2.U)`
        */
      def Lit[T <: Data](elems: T*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = {
        require(elems.nonEmpty, s"Lit.Vec(...) must have at least one element")
        val indexElements = elems.zipWithIndex.map { case (element, index) => (index, element)}
        val widestElement = elems.maxBy(_.getWidth)
        val vec: Vec[T] = Vec.apply(indexElements.length, chiselTypeOf(widestElement))
        vec.Lit(indexElements:_*)
      }
    }
  }

  // Use to add a prefix to any component generated in input scope
  val prefix = chisel3.internal.prefix
  // Use to remove prefixes not in provided scope
  val noPrefix = chisel3.internal.noPrefix

  /** Base simulation-only component. */
  abstract class BaseSim extends NamedComponent {
    _parent.foreach(_.addId(this))
  }
}