summaryrefslogtreecommitdiff
path: root/chiselFrontend/src/main/scala/chisel3/core
diff options
context:
space:
mode:
Diffstat (limited to 'chiselFrontend/src/main/scala/chisel3/core')
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala974
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Annotation.scala138
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Assert.scala92
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Attach.scala45
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala332
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Binding.scala122
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Bits.scala1808
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/BlackBox.scala172
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Clock.scala38
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/CompileOptions.scala76
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Data.scala742
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Mem.scala216
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Module.scala355
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/MonoConnect.scala246
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/MultiClock.scala70
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Mux.scala51
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Printable.scala179
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Printf.scala100
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/RawModule.scala255
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Reg.scala175
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/SeqUtils.scala127
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/StrongEnum.scala344
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/When.scala85
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/package.scala420
24 files changed, 290 insertions, 6872 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
deleted file mode 100644
index 7e3920eb..00000000
--- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
+++ /dev/null
@@ -1,974 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3.core
-
-import scala.collection.immutable.ListMap
-import scala.collection.mutable.{ArrayBuffer, HashSet, LinkedHashMap}
-import scala.language.experimental.macros
-
-import chisel3.internal._
-import chisel3.internal.Builder.pushCommand
-import chisel3.internal.firrtl._
-import chisel3.internal.sourceinfo._
-import chisel3.SourceInfoDoc
-
-class AliasedAggregateFieldException(message: String) extends ChiselException(message)
-
-/** An abstract class for data types that solely consist of (are an aggregate
- * of) other Data objects.
- */
-sealed abstract class Aggregate extends Data {
- private[chisel3] override def bind(target: Binding, parentDirection: SpecifiedDirection) {
- binding = target
-
- val resolvedDirection = SpecifiedDirection.fromParent(parentDirection, specifiedDirection)
- val duplicates = getElements.groupBy(identity).collect { case (x, elts) if elts.size > 1 => x }
- if (!duplicates.isEmpty) {
- throw new AliasedAggregateFieldException(s"Aggregate $this contains aliased fields $duplicates")
- }
- for (child <- getElements) {
- child.bind(ChildBinding(this), resolvedDirection)
- }
-
- // Check that children obey the directionality rules.
- val childDirections = getElements.map(_.direction).toSet - ActualDirection.Empty
- direction = ActualDirection.fromChildren(childDirections, resolvedDirection) match {
- case Some(dir) => dir
- case None =>
- val childWithDirections = getElements zip getElements.map(_.direction)
- throw Binding.MixedDirectionAggregateException(
- s"Aggregate '$this' can't have elements that are both directioned and undirectioned: $childWithDirections")
- }
- }
-
- override def litOption: Option[BigInt] = ??? // TODO implement me
-
- /** Returns a Seq of the immediate contents of this Aggregate, in order.
- */
- def getElements: Seq[Data]
-
- private[chisel3] def width: Width = getElements.map(_.width).foldLeft(0.W)(_ + _)
- private[core] def legacyConnect(that: Data)(implicit sourceInfo: SourceInfo): Unit = {
- // If the source is a DontCare, generate a DefInvalid for the sink,
- // otherwise, issue a Connect.
- if (that == DontCare) {
- pushCommand(DefInvalid(sourceInfo, Node(this)))
- } else {
- pushCommand(BulkConnect(sourceInfo, Node(this), Node(that)))
- }
- }
-
- override def do_asUInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = {
- SeqUtils.do_asUInt(flatten.map(_.asUInt()))
- }
- private[core] override def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions): Unit = {
- var i = 0
- val bits = WireDefault(UInt(this.width), that) // handles width padding
- for (x <- flatten) {
- val fieldWidth = x.getWidth
- if (fieldWidth > 0) {
- x.connectFromBits(bits(i + fieldWidth - 1, i))
- i += fieldWidth
- } else {
- // There's a zero-width field in this bundle.
- // Zero-width fields can't really be assigned to, but the frontend complains if there are uninitialized fields,
- // so we assign it to DontCare. We can't use connectFromBits() on DontCare, so use := instead.
- x := DontCare
- }
- }
- }
-}
-
-trait VecFactory extends SourceInfoDoc {
- /** Creates a new [[Vec]] with `n` entries of the specified data type.
- *
- * @note elements are NOT assigned by default and have no value
- */
- def apply[T <: Data](n: Int, gen: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = {
- if (compileOptions.declaredTypeMustBeUnbound) {
- requireIsChiselType(gen, "vec type")
- }
- new Vec(gen.cloneTypeFull, n)
- }
-
- /** Truncate an index to implement modulo-power-of-2 addressing. */
- private[core] def truncateIndex(idx: UInt, n: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = { // scalastyle:ignore line.size.limit
- // scalastyle:off if.brace
- val w = (n-1).bitLength
- if (n <= 1) 0.U
- else if (idx.width.known && idx.width.get <= w) idx
- else if (idx.width.known) idx(w-1,0)
- else (idx | 0.U(w.W))(w-1,0)
- // scalastyle:on if.brace
- }
-}
-
-object Vec extends VecFactory
-// scalastyle:off line.size.limit
-/** A vector (array) of [[Data]] elements. Provides hardware versions of various
- * collection transformation functions found in software array implementations.
- *
- * Careful consideration should be given over the use of [[Vec]] vs
- * [[scala.collection.immutable.Seq Seq]] or some other Scala collection. In general [[Vec]] only
- * needs to be used when there is a need to express the hardware collection in a [[Reg]] or IO
- * [[Bundle]] or when access to elements of the array is indexed via a hardware signal.
- *
- * Example of indexing into a [[Vec]] using a hardware address and where the [[Vec]] is defined in
- * an IO [[Bundle]]
- *
- * {{{
- * val io = IO(new Bundle {
- * val in = Input(Vec(20, UInt(16.W)))
- * val addr = UInt(5.W)
- * val out = Output(UInt(16.W))
- * })
- * io.out := io.in(io.addr)
- * }}}
- *
- * @tparam T type of elements
- *
- * @note
- * - when multiple conflicting assignments are performed on a Vec element, the last one takes effect (unlike Mem, where the result is undefined)
- * - Vecs, unlike classes in Scala's collection library, are propagated intact to FIRRTL as a vector type, which may make debugging easier
- */
-// scalastyle:on line.size.limit
-sealed class Vec[T <: Data] private[core] (gen: => T, val length: Int)
- extends Aggregate with VecLike[T] {
- override def toString: String = {
- val elementType = sample_element.cloneType
- s"$elementType[$length]$bindingToString"
- }
-
- private[core] override def typeEquivalent(that: Data): Boolean = that match {
- case that: Vec[T] =>
- this.length == that.length &&
- (this.sample_element typeEquivalent that.sample_element)
- case _ => false
- }
-
- private[chisel3] override def bind(target: Binding, parentDirection: SpecifiedDirection) {
- binding = target
-
- val resolvedDirection = SpecifiedDirection.fromParent(parentDirection, specifiedDirection)
- sample_element.bind(SampleElementBinding(this), resolvedDirection)
- for (child <- getElements) { // assume that all children are the same
- child.bind(ChildBinding(this), resolvedDirection)
- }
-
- direction = sample_element.direction
- }
-
- // Note: the constructor takes a gen() function instead of a Seq to enforce
- // that all elements must be the same and because it makes FIRRTL generation
- // simpler.
- private val self: Seq[T] = Vector.fill(length)(gen)
- for ((elt, i) <- self.zipWithIndex)
- elt.setRef(this, i)
-
- /**
- * sample_element 'tracks' all changes to the elements.
- * For consistency, sample_element is always used for creating dynamically
- * indexed ports and outputing the FIRRTL type.
- *
- * Needed specifically for the case when the Vec is length 0.
- */
- private[chisel3] val sample_element: T = gen
-
- // allElements current includes sample_element
- // This is somewhat weird although I think the best course of action here is
- // to deprecate allElements in favor of dispatched functions to Data or
- // a pattern matched recursive descent
- private[chisel3] final override def allElements: Seq[Element] =
- (sample_element +: self).flatMap(_.allElements)
-
- /** Strong bulk connect, assigning elements in this Vec from elements in a Seq.
- *
- * @note the length of this Vec must match the length of the input Seq
- */
- def <> (that: Seq[T])(implicit sourceInfo: SourceInfo, moduleCompileOptions: CompileOptions): Unit = {
- if (this.length != that.length) {
- Builder.error("Vec and Seq being bulk connected have different lengths!")
- }
- for ((a, b) <- this zip that)
- a <> b
- }
-
- // TODO: eliminate once assign(Seq) isn't ambiguous with assign(Data) since Vec extends Seq and Data
- def <> (that: Vec[T])(implicit sourceInfo: SourceInfo, moduleCompileOptions: CompileOptions): Unit = this bulkConnect that.asInstanceOf[Data] // scalastyle:ignore line.size.limit
-
- /** Strong bulk connect, assigning elements in this Vec from elements in a Seq.
- *
- * @note the length of this Vec must match the length of the input Seq
- */
- def := (that: Seq[T])(implicit sourceInfo: SourceInfo, moduleCompileOptions: CompileOptions): Unit = {
- require(this.length == that.length)
- for ((a, b) <- this zip that)
- a := b
- }
-
- // TODO: eliminate once assign(Seq) isn't ambiguous with assign(Data) since Vec extends Seq and Data
- def := (that: Vec[T])(implicit sourceInfo: SourceInfo, moduleCompileOptions: CompileOptions): Unit = this connect that
-
- /** Creates a dynamically indexed read or write accessor into the array.
- */
- override def apply(p: UInt): T = macro CompileOptionsTransform.pArg
-
- /** @group SourceInfoTransformMacro */
- def do_apply(p: UInt)(implicit compileOptions: CompileOptions): T = {
- requireIsHardware(p, "vec index")
- val port = gen
-
- // Reconstruct the resolvedDirection (in Aggregate.bind), since it's not stored.
- // It may not be exactly equal to that value, but the results are the same.
- val reconstructedResolvedDirection = direction match {
- case ActualDirection.Input => SpecifiedDirection.Input
- case ActualDirection.Output => SpecifiedDirection.Output
- case ActualDirection.Bidirectional(ActualDirection.Default) | ActualDirection.Unspecified =>
- SpecifiedDirection.Unspecified
- case ActualDirection.Bidirectional(ActualDirection.Flipped) => SpecifiedDirection.Flip
- }
- // TODO port technically isn't directly child of this data structure, but the result of some
- // muxes / demuxes. However, this does make access consistent with the top-level bindings.
- // Perhaps there's a cleaner way of accomplishing this...
- port.bind(ChildBinding(this), reconstructedResolvedDirection)
-
- val i = Vec.truncateIndex(p, length)(UnlocatableSourceInfo, compileOptions)
- port.setRef(this, i)
-
- port
- }
-
- /** Creates a statically indexed read or write accessor into the array.
- */
- def apply(idx: Int): T = self(idx)
-
- override def cloneType: this.type = {
- new Vec(gen.cloneTypeFull, length).asInstanceOf[this.type]
- }
-
- override def getElements: Seq[Data] =
- (0 until length).map(apply(_))
-
- /** Default "pretty-print" implementation
- * Analogous to printing a Seq
- * Results in "Vec(elt0, elt1, ...)"
- */
- def toPrintable: Printable = {
- // scalastyle:off if.brace
- val elts =
- if (length == 0) List.empty[Printable]
- else self flatMap (e => List(e.toPrintable, PString(", "))) dropRight 1
- // scalastyle:on if.brace
- PString("Vec(") + Printables(elts) + PString(")")
- }
-}
-
-object VecInit extends SourceInfoDoc {
- /** Creates a new [[Vec]] composed of elements of the input Seq of [[Data]]
- * nodes.
- *
- * @note input elements should be of the same type (this is checked at the
- * FIRRTL level, but not at the Scala / Chisel level)
- * @note the width of all output elements is the width of the largest input
- * element
- * @note output elements are connected from the input elements
- */
- def apply[T <: Data](elts: Seq[T]): Vec[T] = macro VecTransform.apply_elts
-
- /** @group SourceInfoTransformMacro */
- def do_apply[T <: Data](elts: Seq[T])(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = {
- // REVIEW TODO: this should be removed in favor of the apply(elts: T*)
- // varargs constructor, which is more in line with the style of the Scala
- // collection API. However, a deprecation phase isn't possible, since
- // changing apply(elt0, elts*) to apply(elts*) causes a function collision
- // with apply(Seq) after type erasure. Workarounds by either introducing a
- // DummyImplicit or additional type parameter will break some code.
-
- // Check that types are homogeneous. Width mismatch for Elements is safe.
- require(!elts.isEmpty)
- elts.foreach(requireIsHardware(_, "vec element"))
-
- val vec = Wire(Vec(elts.length, cloneSupertype(elts, "Vec")))
-
- // TODO: try to remove the logic for this mess
- elts.head.direction match {
- case ActualDirection.Input | ActualDirection.Output | ActualDirection.Unspecified =>
- // When internal wires are involved, driver / sink must be specified explicitly, otherwise
- // the system is unable to infer which is driver / sink
- (vec zip elts).foreach(x => x._1 := x._2)
- case ActualDirection.Bidirectional(_) =>
- // For bidirectional, must issue a bulk connect so subelements are resolved correctly.
- // Bulk connecting two wires may not succeed because Chisel frontend does not infer
- // directions.
- (vec zip elts).foreach(x => x._1 <> x._2)
- }
- vec
- }
-
- /** Creates a new [[Vec]] composed of the input [[Data]] nodes.
- *
- * @note input elements should be of the same type (this is checked at the
- * FIRRTL level, but not at the Scala / Chisel level)
- * @note the width of all output elements is the width of the largest input
- * element
- * @note output elements are connected from the input elements
- */
- def apply[T <: Data](elt0: T, elts: T*): Vec[T] = macro VecTransform.apply_elt0
-
- /** @group SourceInfoTransformMacro */
- def do_apply[T <: Data](elt0: T, elts: T*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] =
- apply(elt0 +: elts.toSeq)
-
- /** Creates a new [[Vec]] of length `n` composed of the results of the given
- * function applied over a range of integer values starting from 0.
- *
- * @param n number of elements in the vector (the function is applied from
- * 0 to `n-1`)
- * @param gen function that takes in an Int (the index) and returns a
- * [[Data]] that becomes the output element
- */
- def tabulate[T <: Data](n: Int)(gen: (Int) => T): Vec[T] = macro VecTransform.tabulate
-
- /** @group SourceInfoTransformMacro */
- def do_tabulate[T <: Data](n: Int)(gen: (Int) => T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = // scalastyle:ignore line.size.limit
- apply((0 until n).map(i => gen(i)))
-}
-
-/** A trait for [[Vec]]s containing common hardware generators for collection
- * operations.
- */
-trait VecLike[T <: Data] extends collection.IndexedSeq[T] with HasId with SourceInfoDoc {
- def apply(p: UInt): T = macro CompileOptionsTransform.pArg
-
- /** @group SourceInfoTransformMacro */
- def do_apply(p: UInt)(implicit compileOptions: CompileOptions): T
-
- // IndexedSeq has its own hashCode/equals that we must not use
- override def hashCode: Int = super[HasId].hashCode
- override def equals(that: Any): Boolean = super[HasId].equals(that)
-
- @chiselRuntimeDeprecated
- @deprecated("Use Vec.apply instead", "chisel3")
- def read(idx: UInt)(implicit compileOptions: CompileOptions): T = do_apply(idx)(compileOptions)
-
- @chiselRuntimeDeprecated
- @deprecated("Use Vec.apply instead", "chisel3")
- def write(idx: UInt, data: T)(implicit compileOptions: CompileOptions): Unit = {
- do_apply(idx)(compileOptions).:=(data)(DeprecatedSourceInfo, compileOptions)
- }
-
- /** Outputs true if p outputs true for every element.
- */
- def forall(p: T => Bool): Bool = macro SourceInfoTransform.pArg
-
- /** @group SourceInfoTransformMacro */
- def do_forall(p: T => Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool =
- (this map p).fold(true.B)(_ && _)
-
- /** Outputs true if p outputs true for at least one element.
- */
- def exists(p: T => Bool): Bool = macro SourceInfoTransform.pArg
-
- /** @group SourceInfoTransformMacro */
- def do_exists(p: T => Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool =
- (this map p).fold(false.B)(_ || _)
-
- /** Outputs true if the vector contains at least one element equal to x (using
- * the === operator).
- */
- def contains(x: T)(implicit ev: T <:< UInt): Bool = macro VecTransform.contains
-
- /** @group SourceInfoTransformMacro */
- def do_contains(x: T)(implicit sourceInfo: SourceInfo, ev: T <:< UInt, compileOptions: CompileOptions): Bool =
- this.exists(_ === x)
-
- /** Outputs the number of elements for which p is true.
- */
- def count(p: T => Bool): UInt = macro SourceInfoTransform.pArg
-
- /** @group SourceInfoTransformMacro */
- def do_count(p: T => Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
- SeqUtils.count(this map p)
-
- /** Helper function that appends an index (literal value) to each element,
- * useful for hardware generators which output an index.
- */
- private def indexWhereHelper(p: T => Bool) = this map p zip (0 until length).map(i => i.asUInt)
-
- /** Outputs the index of the first element for which p outputs true.
- */
- def indexWhere(p: T => Bool): UInt = macro SourceInfoTransform.pArg
-
- /** @group SourceInfoTransformMacro */
- def do_indexWhere(p: T => Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
- SeqUtils.priorityMux(indexWhereHelper(p))
-
- /** Outputs the index of the last element for which p outputs true.
- */
- def lastIndexWhere(p: T => Bool): UInt = macro SourceInfoTransform.pArg
-
- /** @group SourceInfoTransformMacro */
- def do_lastIndexWhere(p: T => Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
- SeqUtils.priorityMux(indexWhereHelper(p).reverse)
-
- /** Outputs the index of the element for which p outputs true, assuming that
- * the there is exactly one such element.
- *
- * The implementation may be more efficient than a priority mux, but
- * incorrect results are possible if there is not exactly one true element.
- *
- * @note the assumption that there is only one element for which p outputs
- * true is NOT checked (useful in cases where the condition doesn't always
- * hold, but the results are not used in those cases)
- */
- def onlyIndexWhere(p: T => Bool): UInt = macro SourceInfoTransform.pArg
-
- /** @group SourceInfoTransformMacro */
- def do_onlyIndexWhere(p: T => Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
- SeqUtils.oneHotMux(indexWhereHelper(p))
-}
-
-/** Base class for Aggregates based on key values pairs of String and Data
- *
- * Record should only be extended by libraries and fairly sophisticated generators.
- * RTL writers should use [[Bundle]]. See [[Record#elements]] for an example.
- */
-abstract class Record(private[chisel3] implicit val compileOptions: CompileOptions) extends Aggregate {
- private[chisel3] override def bind(target: Binding, parentDirection: SpecifiedDirection): Unit = {
- try {
- super.bind(target, parentDirection)
- } catch { // nasty compatibility mode shim, where anything flies
- case e: Binding.MixedDirectionAggregateException if !compileOptions.dontAssumeDirectionality =>
- val resolvedDirection = SpecifiedDirection.fromParent(parentDirection, specifiedDirection)
- direction = resolvedDirection match {
- case SpecifiedDirection.Unspecified => ActualDirection.Bidirectional(ActualDirection.Default)
- case SpecifiedDirection.Flip => ActualDirection.Bidirectional(ActualDirection.Flipped)
- case _ => ActualDirection.Bidirectional(ActualDirection.Default)
- }
- }
- }
-
- /** Creates a Bundle literal of this type with specified values. this must be a chisel type.
- *
- * @param elems literal values, specified as a pair of the Bundle field to the literal value.
- * The Bundle field is specified as a function from an object of this type to the field.
- * Fields that aren't initialized to DontCare, and assignment to a wire will overwrite any
- * existing value with DontCare.
- * @return a Bundle literal of this type with subelement values specified
- *
- * @example {{{
- * class MyBundle extends Bundle {
- * val a = UInt(8.W)
- * val b = Bool()
- * }
- *
- * (mew MyBundle).Lit(
- * _.a -> 42.U,
- * _.b -> true.B
- * )
- * }}}
- */
- private[chisel3] def _makeLit(elems: (this.type => (Data, Data))*): this.type = { // scalastyle:ignore line.size.limit method.length method.name cyclomatic.complexity
- // Returns pairs of all fields, element-level and containers, in a Record and their path names
- def getRecursiveFields(data: Data, path: String): Seq[(Data, String)] = data match {
- case data: Record => data.elements.map { case (fieldName, fieldData) =>
- getRecursiveFields(fieldData, s"$path.$fieldName")
- }.fold(Seq(data -> path)) { _ ++ _ }
- case data => Seq(data -> path) // we don't support or recurse into other Aggregate types here
- }
-
- // Returns pairs of corresponding fields between two Records of the same type
- def getMatchedFields(x: Data, y: Data): Seq[(Data, Data)] = (x, y) match {
- case (x: Element, y: Element) =>
- require(x typeEquivalent y)
- Seq(x -> y)
- case (x: Record, y: Record) =>
- (x.elements zip y.elements).map { case ((xName, xElt), (yName, yElt)) =>
- require(xName == yName) // assume fields returned in same, deterministic order
- getMatchedFields(xElt, yElt)
- }.fold(Seq(x -> y)) { _ ++ _ }
- }
-
- requireIsChiselType(this, "bundle literal constructor model")
- val clone = cloneType
- val cloneFields = getRecursiveFields(clone, "(bundle root)").toMap
-
- // Create the Bundle literal binding from litargs of arguments
- val bundleLitMap = elems.map { fn => fn(clone) }.flatMap { case (field, value) =>
- val fieldName = cloneFields.getOrElse(field,
- throw new BundleLiteralException(s"field $field (with value $value) is not a field," +
- s" ensure the field is specified as a function returning a field on an object of class ${this.getClass}," +
- s" eg '_.a' to select hypothetical bundle field 'a'")
- )
- val valueBinding = value.topBindingOpt match {
- case Some(litBinding: LitBinding) => litBinding
- case _ => throw new BundleLiteralException(s"field $fieldName specified with non-literal value $value")
- }
-
- field match { // Get the litArg(s) for this field
- case field: Bits =>
- if (field.getClass != value.getClass) { // TODO typeEquivalent is too strict because it checks width
- throw new BundleLiteralException(s"Field $fieldName $field specified with non-type-equivalent value $value")
- }
- val litArg = valueBinding match {
- case ElementLitBinding(litArg) => litArg
- case BundleLitBinding(litMap) => litMap.getOrElse(value,
- throw new BundleLiteralException(s"Field $fieldName specified with unspecified value"))
- }
- Seq(field -> litArg)
- case field: Record =>
- if (!(field typeEquivalent value)) {
- throw new BundleLiteralException(s"field $fieldName $field specified with non-type-equivalent value $value")
- }
- // Copy the source BundleLitBinding with fields (keys) remapped to the clone
- val remap = getMatchedFields(value, field).toMap
- value.topBinding.asInstanceOf[BundleLitBinding].litMap.map { case (valueField, valueValue) =>
- remap(valueField) -> valueValue
- }
- case _ => throw new BundleLiteralException(s"unsupported field $fieldName of type $field")
- }
- } // don't convert to a Map yet to preserve duplicate keys
- val duplicates = bundleLitMap.map(_._1).groupBy(identity).collect { case (x, elts) if elts.size > 1 => x }
- if (!duplicates.isEmpty) {
- val duplicateNames = duplicates.map(cloneFields(_)).mkString(", ")
- throw new BundleLiteralException(s"duplicate fields $duplicateNames in Bundle literal constructor")
- }
- clone.bind(BundleLitBinding(bundleLitMap.toMap))
- clone
- }
-
- /** The collection of [[Data]]
- *
- * This underlying datastructure is a ListMap because the elements must
- * remain ordered for serialization/deserialization. Elements added later
- * are higher order when serialized (this is similar to [[Vec]]). For example:
- * {{{
- * // Assume we have some type MyRecord that creates a Record from the ListMap
- * val record = MyRecord(ListMap("fizz" -> UInt(16.W), "buzz" -> UInt(16.W)))
- * // "buzz" is higher order because it was added later than "fizz"
- * record("fizz") := "hdead".U
- * record("buzz") := "hbeef".U
- * val uint = record.asUInt
- * assert(uint === "hbeefdead".U) // This will pass
- * }}}
- */
- override def toString: String = {
- val bindingString = topBindingOpt match {
- case Some(BundleLitBinding(_)) =>
- val contents = elements.toList.reverse.map { case (name, data) =>
- s"$name=$data"
- }.mkString(", ")
- s"($contents)"
- case _ => bindingToString
- }
- s"$className$bindingString"
- }
-
- val elements: ListMap[String, Data]
-
- /** Name for Pretty Printing */
- def className: String = this.getClass.getSimpleName
-
- private[core] override def typeEquivalent(that: Data): Boolean = that match {
- case that: Record =>
- this.getClass == that.getClass &&
- this.elements.size == that.elements.size &&
- this.elements.forall{case (name, model) =>
- that.elements.contains(name) &&
- (that.elements(name) typeEquivalent model)}
- case _ => false
- }
-
- // NOTE: This sets up dependent references, it can be done before closing the Module
- private[chisel3] override def _onModuleClose: Unit = { // scalastyle:ignore method.name
- // Since Bundle names this via reflection, it is impossible for two elements to have the same
- // identifier; however, Namespace sanitizes identifiers to make them legal for Firrtl/Verilog
- // which can cause collisions
- val _namespace = Namespace.empty
- for ((name, elt) <- elements) { elt.setRef(this, _namespace.name(name, leadingDigitOk=true)) }
- }
-
- private[chisel3] final def allElements: Seq[Element] = elements.toIndexedSeq.flatMap(_._2.allElements)
-
- override def getElements: Seq[Data] = elements.toIndexedSeq.map(_._2)
-
- // Helper because Bundle elements are reversed before printing
- private[chisel3] def toPrintableHelper(elts: Seq[(String, Data)]): Printable = {
- // scalastyle:off if.brace
- val xs =
- if (elts.isEmpty) List.empty[Printable] // special case because of dropRight below
- else elts flatMap { case (name, data) =>
- List(PString(s"$name -> "), data.toPrintable, PString(", "))
- } dropRight 1 // Remove trailing ", "
- // scalastyle:on if.brace
- PString(s"$className(") + Printables(xs) + PString(")")
- }
- /** Default "pretty-print" implementation
- * Analogous to printing a Map
- * Results in "`\$className(elt0.name -> elt0.value, ...)`"
- */
- def toPrintable: Printable = toPrintableHelper(elements.toList)
-}
-
-/**
- * Mix-in for Bundles that have arbitrary Seqs of Chisel types that aren't
- * involved in hardware construction.
- *
- * Used to avoid raising an error/exception when a Seq is a public member of the
- * bundle.
- * This is useful if we those public Seq fields in the Bundle are unrelated to
- * hardware construction.
- */
-trait IgnoreSeqInBundle {
- this: Bundle =>
-
- override def ignoreSeq: Boolean = true
-}
-
-class AutoClonetypeException(message: String) extends ChiselException(message)
-class BundleLiteralException(message: String) extends ChiselException(message)
-
-/** Base class for data types defined as a bundle of other data types.
- *
- * Usage: extend this class (either as an anonymous or named class) and define
- * members variables of [[Data]] subtypes to be elements in the Bundle.
- *
- * Example of an anonymous IO bundle
- * {{{
- * class MyModule extends Module {
- * val io = IO(new Bundle {
- * val in = Input(UInt(64.W))
- * val out = Output(SInt(128.W))
- * })
- * }
- * }}}
- *
- * Or as a named class
- * {{{
- * class Packet extends Bundle {
- * val header = UInt(16.W)
- * val addr = UInt(16.W)
- * val data = UInt(32.W)
- * }
- * class MyModule extends Module {
- * val io = IO(new Bundle {
- * val inPacket = Input(new Packet)
- * val outPacket = Output(new Packet)
- * })
- * val reg = Reg(new Packet)
- * reg <> inPacket
- * outPacket <> reg
- * }
- * }}}
- */
-abstract class Bundle(implicit compileOptions: CompileOptions) extends Record {
- override def className: String = this.getClass.getSimpleName match {
- case name if name.startsWith("$anon$") => "AnonymousBundle" // fallback for anonymous Bundle case
- case "" => "AnonymousBundle" // ditto, but on other platforms
- case name => name
- }
- /** The collection of [[Data]]
- *
- * Elements defined earlier in the Bundle are higher order upon
- * serialization. For example:
- * @example
- * {{{
- * class MyBundle extends Bundle {
- * val foo = UInt(16.W)
- * val bar = UInt(16.W)
- * }
- * // Note that foo is higher order because its defined earlier in the Bundle
- * val bundle = Wire(new MyBundle)
- * bundle.foo := 0x1234.U
- * bundle.bar := 0x5678.U
- * val uint = bundle.asUInt
- * assert(uint === "h12345678".U) // This will pass
- * }}}
- */
- final lazy val elements: ListMap[String, Data] = {
- val nameMap = LinkedHashMap[String, Data]()
- for (m <- getPublicFields(classOf[Bundle])) {
- getBundleField(m) match {
- case Some(d: Data) =>
- if (nameMap contains m.getName) {
- require(nameMap(m.getName) eq d)
- } else {
- nameMap(m.getName) = d
- }
- case None =>
- if (!ignoreSeq) {
- m.invoke(this) match {
- case s: scala.collection.Seq[Any] if s.nonEmpty => s.head match {
- // Ignore empty Seq()
- case d: Data => throwException("Public Seq members cannot be used to define Bundle elements " +
- s"(found public Seq member '${m.getName}'). " +
- "Either use a Vec if all elements are of the same type, or MixedVec if the elements " +
- "are of different types. If this Seq member is not intended to construct RTL, mix in the trait " +
- "IgnoreSeqInBundle.")
- case _ => // don't care about non-Data Seq
- }
- case _ => // not a Seq
- }
- }
- }
- }
- ListMap(nameMap.toSeq sortWith { case ((an, a), (bn, b)) => (a._id > b._id) || ((a eq b) && (an > bn)) }: _*)
- // scalastyle:ignore method.length
- }
-
- /**
- * Overridden by [[IgnoreSeqInBundle]] to allow arbitrary Seqs of Chisel elements.
- */
- def ignoreSeq: Boolean = false
-
- /** Returns a field's contained user-defined Bundle element if it appears to
- * be one, otherwise returns None.
- */
- private def getBundleField(m: java.lang.reflect.Method): Option[Data] = m.invoke(this) match {
- case d: Data => Some(d)
- case Some(d: Data) => Some(d)
- case _ => None
- }
-
- // Memoize the outer instance for autoclonetype, especially where this is context-dependent
- // (like the outer module or enclosing Bundles).
- private var _outerInst: Option[Object] = None
-
- // For autoclonetype, record possible candidates for outer instance.
- // _outerInst should always take precedence, since it should be propagated from the original
- // object which has the most accurate context.
- private val _containingModule: Option[BaseModule] = Builder.currentModule
- private val _containingBundles: Seq[Bundle] = Builder.updateBundleStack(this)
-
- override def cloneType : this.type = { // scalastyle:ignore cyclomatic.complexity method.length
- // This attempts to infer constructor and arguments to clone this Bundle subtype without
- // requiring the user explicitly overriding cloneType.
- import scala.language.existentials
- import scala.reflect.runtime.universe._
-
- val clazz = this.getClass
-
- def autoClonetypeError(desc: String): Nothing = {
- throw new AutoClonetypeException(s"Unable to automatically infer cloneType on $clazz: $desc")
- }
-
- def validateClone(clone: Bundle, equivDiagnostic: String): Unit = {
- if (!clone.typeEquivalent(this)) {
- autoClonetypeError(s"Automatically cloned $clone not type-equivalent to base $this. " + equivDiagnostic)
- }
-
- for ((name, field) <- elements) {
- if (clone.elements(name) eq field) {
- autoClonetypeError(s"Automatically cloned $clone has field $name aliased with base $this." +
- " In the future, this can be solved by wrapping the field in Field(...)," +
- " see https://github.com/freechipsproject/chisel3/pull/909." +
- " For now, ensure Chisel types used in the Bundle definition are passed through constructor arguments," +
- " or wrapped in Input(...), Output(...), or Flipped(...) if appropriate.")
- }
- }
- }
-
- val mirror = runtimeMirror(clazz.getClassLoader)
- val classSymbolOption = try {
- Some(mirror.reflect(this).symbol)
- } catch {
- case e: scala.reflect.internal.Symbols#CyclicReference => None // Workaround for a scala bug
- }
-
- val enclosingClassOption = (clazz.getEnclosingClass, classSymbolOption) match {
- case (null, _) => None
- case (_, Some(classSymbol)) if classSymbol.isStatic => None // allows support for members of companion objects
- case (outerClass, _) => Some(outerClass)
- }
-
- // For compatibility with pre-3.1, where null is tried as an argument to the constructor.
- // This stores potential error messages which may be used later.
- var outerClassError: Option[String] = None
-
- // Check if this is an inner class, and if so, try to get the outer instance
- val outerClassInstance = enclosingClassOption.map { outerClass =>
- def canAssignOuterClass(x: Object) = outerClass.isAssignableFrom(x.getClass)
-
- val outerInstance = _outerInst match {
- case Some(outerInstance) => outerInstance // use _outerInst if defined
- case None => // determine outer instance if not already recorded
- try {
- // Prefer this if it works, but doesn't work in all cases, namely anonymous inner Bundles
- val outer = clazz.getDeclaredField("$outer").get(this)
- _outerInst = Some(outer)
- outer
- } catch {
- case (_: NoSuchFieldException | _: IllegalAccessException) =>
- // Fallback using guesses based on common patterns
- val allOuterCandidates = Seq(
- _containingModule.toSeq,
- _containingBundles
- ).flatten.distinct
- allOuterCandidates.filter(canAssignOuterClass(_)) match {
- case outer :: Nil =>
- _outerInst = Some(outer) // record the guess for future use
- outer
- case Nil => // TODO: replace with fatal autoClonetypeError once compatibility period is dropped
- outerClassError = Some(s"Unable to determine instance of outer class $outerClass," +
- s" no candidates assignable to outer class types; examined $allOuterCandidates")
- null
- case candidates => // TODO: replace with fatal autoClonetypeError once compatibility period is dropped
- outerClassError = Some(s"Unable to determine instance of outer class $outerClass," +
- s" multiple possible candidates $candidates assignable to outer class type")
- null
- }
- }
- }
- (outerClass, outerInstance)
- }
-
- // If possible (constructor with no arguments), try Java reflection first
- // This handles two cases that Scala reflection doesn't:
- // 1. getting the ClassSymbol of a class with an anonymous outer class fails with a
- // CyclicReference exception
- // 2. invoking the constructor of an anonymous inner class seems broken (it expects the outer
- // class as an argument, but fails because the number of arguments passed in is incorrect)
- if (clazz.getConstructors.size == 1) {
- var ctor = clazz.getConstructors.head
- val argTypes = ctor.getParameterTypes.toList
- val clone = (argTypes, outerClassInstance) match {
- case (Nil, None) => // no arguments, no outer class, invoke constructor directly
- Some(ctor.newInstance().asInstanceOf[this.type])
- case (argType :: Nil, Some((_, outerInstance))) =>
- if (outerInstance == null) {
- Builder.deprecated(s"chisel3.1 autoclonetype failed, falling back to 3.0 behavior using null as the outer instance." + // scalastyle:ignore line.size.limit
- s" Autoclonetype failure reason: ${outerClassError.get}",
- Some(s"$clazz"))
- Some(ctor.newInstance(outerInstance).asInstanceOf[this.type])
- } else if (argType isAssignableFrom outerInstance.getClass) {
- Some(ctor.newInstance(outerInstance).asInstanceOf[this.type])
- } else {
- None
- }
- case _ => None
-
- }
- clone match {
- case Some(clone) =>
- clone._outerInst = this._outerInst
- validateClone(clone, "Constructor argument values were not inferred, ensure constructor is deterministic.")
- return clone.asInstanceOf[this.type]
- case None =>
- }
- }
-
- // Get constructor parameters and accessible fields
- val classSymbol = classSymbolOption.getOrElse(autoClonetypeError(s"scala reflection failed." +
- " This is known to occur with inner classes on anonymous outer classes." +
- " In those cases, autoclonetype only works with no-argument constructors, or you can define a custom cloneType.")) // scalastyle:ignore line.size.limit
-
- val decls = classSymbol.typeSignature.decls
- val ctors = decls.collect { case meth: MethodSymbol if meth.isConstructor => meth }
- if (ctors.size != 1) {
- autoClonetypeError(s"found multiple constructors ($ctors)." +
- " Either remove all but the default constructor, or define a custom cloneType method.")
- }
- val ctor = ctors.head
- val ctorParamss = ctor.paramLists
- val ctorParams = ctorParamss match {
- case Nil => List()
- case ctorParams :: Nil => ctorParams
- case ctorParams :: ctorImplicits :: Nil => ctorParams ++ ctorImplicits
- case _ => autoClonetypeError(s"internal error, unexpected ctorParamss = $ctorParamss")
- }
- val ctorParamsNames = ctorParams.map(_.name.toString)
-
- // Special case for anonymous inner classes: their constructor consists of just the outer class reference
- // Scala reflection on anonymous inner class constructors seems broken
- if (ctorParams.size == 1 && outerClassInstance.isDefined &&
- ctorParams.head.typeSignature == mirror.classSymbol(outerClassInstance.get._1).toType) {
- // Fall back onto Java reflection
- val ctors = clazz.getConstructors
- require(ctors.size == 1) // should be consistent with Scala constructors
- try {
- val clone = ctors.head.newInstance(outerClassInstance.get._2).asInstanceOf[this.type]
- clone._outerInst = this._outerInst
-
- validateClone(clone, "Outer class instance was inferred, ensure constructor is deterministic.")
- return clone
- } catch {
- case e @ (_: java.lang.reflect.InvocationTargetException | _: IllegalArgumentException) =>
- autoClonetypeError(s"unexpected failure at constructor invocation, got $e.")
- }
- }
-
- // Get all the class symbols up to (but not including) Bundle and get all the accessors.
- // (each ClassSymbol's decls only includes those declared in the class itself)
- val bundleClassSymbol = mirror.classSymbol(classOf[Bundle])
- val superClassSymbols = classSymbol.baseClasses.takeWhile(_ != bundleClassSymbol)
- val superClassDecls = superClassSymbols.map(_.typeSignature.decls).flatten
- val accessors = superClassDecls.collect { case meth: MethodSymbol if meth.isParamAccessor => meth }
-
- // Get constructor argument values
- // Check that all ctor params are immutable and accessible. Immutability is required to avoid
- // potential subtle bugs (like values changing after cloning).
- // This also generates better error messages (all missing elements shown at once) instead of
- // failing at the use site one at a time.
- val accessorsName = accessors.filter(_.isStable).map(_.name.toString)
- val paramsDiff = ctorParamsNames.toSet -- accessorsName.toSet
- if (!paramsDiff.isEmpty) {
- // scalastyle:off line.size.limit
- autoClonetypeError(s"constructor has parameters (${paramsDiff.toList.sorted.mkString(", ")}) that are not both immutable and accessible." +
- " Either make all parameters immutable and accessible (vals) so cloneType can be inferred, or define a custom cloneType method.")
- // scalastyle:on line.size.limit
- }
-
- // Get all the argument values
- val accessorsMap = accessors.map(accessor => accessor.name.toString -> accessor).toMap
- val instanceReflect = mirror.reflect(this)
- val ctorParamsNameVals = ctorParamsNames.map {
- paramName => paramName -> instanceReflect.reflectMethod(accessorsMap(paramName)).apply()
- }
-
- // Opportunistic sanity check: ensure any arguments of type Data is not bound
- // (which could lead to data conflicts, since it's likely the user didn't know to re-bind them).
- // This is not guaranteed to catch all cases (for example, Data in Tuples or Iterables).
- val boundDataParamNames = ctorParamsNameVals.collect {
- case (paramName, paramVal: Data) if paramVal.topBindingOpt.isDefined => paramName
- }
- if (boundDataParamNames.nonEmpty) {
- // scalastyle:off line.size.limit
- autoClonetypeError(s"constructor parameters (${boundDataParamNames.sorted.mkString(", ")}) have values that are hardware types, which is likely to cause subtle errors." +
- " Use chisel types instead: use the value before it is turned to a hardware type (with Wire(...), Reg(...), etc) or use chiselTypeOf(...) to extract the chisel type.")
- // scalastyle:on line.size.limit
- }
-
- // Clone unbound parameters in case they are being used as bundle fields.
- val ctorParamsVals = ctorParamsNameVals.map {
- case (_, paramVal: Data) => paramVal.cloneTypeFull
- case (_, paramVal) => paramVal
- }
-
- // Invoke ctor
- val classMirror = outerClassInstance match {
- case Some((_, null)) => autoClonetypeError(outerClassError.get) // deals with the null hack for 3.0 compatibility
- case Some((_, outerInstance)) => mirror.reflect(outerInstance).reflectClass(classSymbol)
- case _ => mirror.reflectClass(classSymbol)
- }
- val clone = classMirror.reflectConstructor(ctor).apply(ctorParamsVals:_*).asInstanceOf[this.type]
- clone._outerInst = this._outerInst
-
- validateClone(clone,
- "Constructor argument values were inferred:" +
- " ensure that variable names are consistent and have the same value throughout the constructor chain," +
- " and that the constructor is deterministic."
- )
- clone
- }
-
- /** Default "pretty-print" implementation
- * Analogous to printing a Map
- * Results in "`Bundle(elt0.name -> elt0.value, ...)`"
- * @note The order is reversed from the order of elements in order to print
- * the fields in the order they were defined
- */
- override def toPrintable: Printable = toPrintableHelper(elements.toList.reverse)
- // scalastyle:off method.length
-}
-// scalastyle:off file.size.limit
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Annotation.scala b/chiselFrontend/src/main/scala/chisel3/core/Annotation.scala
deleted file mode 100644
index b7e82f63..00000000
--- a/chiselFrontend/src/main/scala/chisel3/core/Annotation.scala
+++ /dev/null
@@ -1,138 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3.core
-
-import scala.language.existentials
-
-import chisel3.internal.{Builder, InstanceId}
-import firrtl.Transform
-import firrtl.annotations.{Annotation, CircuitName, ComponentName, ModuleName}
-import firrtl.transforms.{DontTouchAnnotation, NoDedupAnnotation}
-
-/** Interface for Annotations in Chisel
- *
- * Defines a conversion to a corresponding FIRRTL Annotation
- */
-trait ChiselAnnotation {
- /** Conversion to FIRRTL Annotation */
- def toFirrtl: Annotation
-}
-object ChiselAnnotation {
- @deprecated("Write a custom ChiselAnnotation subclass instead", "3.1")
- def apply(component: InstanceId, transformClass: Class[_ <: Transform], value: String): ChiselLegacyAnnotation =
- ChiselLegacyAnnotation(component, transformClass, value)
- @deprecated("Write a custom ChiselAnnotation subclass instead", "3.1")
- def unapply(anno: ChiselAnnotation): Option[(InstanceId, Class[_ <: Transform], String)] =
- anno match {
- case ChiselLegacyAnnotation(c, t, v) => Some(c, t, v)
- case _ => None
- }
-}
-
-/** Mixin for [[ChiselAnnotation]] that instantiates an associated FIRRTL Transform when this Annotation is present
- * during a run of
- * [[Driver$.execute(args:Array[String],dut:()=>chisel3\.experimental\.RawModule)* Driver.execute]].
- * Automatic Transform instantiation is *not* supported when the Circuit and Annotations are serialized before invoking
- * FIRRTL.
- */
-// TODO There should be a FIRRTL API for this instead
-trait RunFirrtlTransform extends ChiselAnnotation {
- def transformClass: Class[_ <: Transform]
-}
-
-// This exists for implementation reasons, we don't want people using this type directly
-final case class ChiselLegacyAnnotation private[chisel3] (
- component: InstanceId,
- transformClass: Class[_ <: Transform],
- value: String) extends ChiselAnnotation with RunFirrtlTransform {
- def toFirrtl: Annotation = Annotation(component.toNamed, transformClass, value)
-}
-private[chisel3] object ChiselLegacyAnnotation
-
-object annotate { // scalastyle:ignore object.name
- def apply(anno: ChiselAnnotation): Unit = {
- Builder.annotations += anno
- }
-}
-
-/** Marks that a signal should not be removed by Chisel and Firrtl optimization passes
- *
- * @example {{{
- * class MyModule extends Module {
- * val io = IO(new Bundle {
- * val a = Input(UInt(32.W))
- * val b = Output(UInt(32.W))
- * })
- * io.b := io.a
- * val dead = io.a +% 1.U // normally dead would be pruned by DCE
- * dontTouch(dead) // Marking it as such will preserve it
- * }
- * }}}
- *
- * @note Calling this on [[Data]] creates an annotation that Chisel emits to a separate annotations
- * file. This file must be passed to FIRRTL independently of the `.fir` file. The execute methods
- * in [[chisel3.Driver]] will pass the annotations to FIRRTL automatically.
- */
-object dontTouch { // scalastyle:ignore object.name
- /** Marks a signal to be preserved in Chisel and Firrtl
- *
- * @note Requires the argument to be bound to hardware
- * @param data The signal to be marked
- * @return Unmodified signal `data`
- */
- def apply[T <: Data](data: T)(implicit compileOptions: CompileOptions): T = {
- if (compileOptions.checkSynthesizable) {
- requireIsHardware(data, "Data marked dontTouch")
- }
- annotate(new ChiselAnnotation { def toFirrtl = DontTouchAnnotation(data.toNamed) })
- data
- }
-}
-
-/** Marks that a module to be ignored in Dedup Transform in Firrtl pass
- *
- * @example {{{
- * def fullAdder(a: UInt, b: UInt, myName: String): UInt = {
- * val m = Module(new Module {
- * val io = IO(new Bundle {
- * val a = Input(UInt(32.W))
- * val b = Input(UInt(32.W))
- * val out = Output(UInt(32.W))
- * })
- * override def desiredName = "adder_" + myNname
- * io.out := io.a + io.b
- * })
- * doNotDedup(m)
- * m.io.a := a
- * m.io.b := b
- * m.io.out
- * }
- *
- *class AdderTester extends Module
- * with ConstantPropagationTest {
- * val io = IO(new Bundle {
- * val a = Input(UInt(32.W))
- * val b = Input(UInt(32.W))
- * val out = Output(Vec(2, UInt(32.W)))
- * })
- *
- * io.out(0) := fullAdder(io.a, io.b, "mod1")
- * io.out(1) := fullAdder(io.a, io.b, "mod2")
- * }
- * }}}
- *
- * @note Calling this on [[Data]] creates an annotation that Chisel emits to a separate annotations
- * file. This file must be passed to FIRRTL independently of the `.fir` file. The execute methods
- * in [[chisel3.Driver]] will pass the annotations to FIRRTL automatically.
- */
-
-object doNotDedup { // scalastyle:ignore object.name
- /** Marks a module to be ignored in Dedup Transform in Firrtl
- *
- * @param data The module to be marked
- * @return Unmodified signal `module`
- */
- def apply[T <: LegacyModule](module: T)(implicit compileOptions: CompileOptions): Unit = {
- annotate(new ChiselAnnotation { def toFirrtl = NoDedupAnnotation(module.toNamed) })
- }
-}
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Assert.scala b/chiselFrontend/src/main/scala/chisel3/core/Assert.scala
deleted file mode 100644
index 054222c3..00000000
--- a/chiselFrontend/src/main/scala/chisel3/core/Assert.scala
+++ /dev/null
@@ -1,92 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3.core
-
-import scala.reflect.macros.blackbox.Context
-import scala.language.experimental.macros
-
-import chisel3.internal._
-import chisel3.internal.Builder.pushCommand
-import chisel3.internal.firrtl._
-import chisel3.internal.sourceinfo.SourceInfo
-
-object assert { // scalastyle:ignore object.name
- /** Checks for a condition to be valid in the circuit at all times. If the
- * condition evaluates to false, the circuit simulation stops with an error.
- *
- * Does not fire when in reset (defined as the encapsulating Module's
- * reset). If your definition of reset is not the encapsulating Module's
- * reset, you will need to gate this externally.
- *
- * May be called outside of a Module (like defined in a function), so
- * functions using assert make the standard Module assumptions (single clock
- * and single reset).
- *
- * @param cond condition, assertion fires (simulation fails) when false
- * @param message optional format string to print when the assertion fires
- * @param data optional bits to print in the message formatting
- *
- * @note See [[printf.apply(fmt:String* printf]] for format string documentation
- * @note currently cannot be used in core Chisel / libraries because macro
- * defs need to be compiled first and the SBT project is not set up to do
- * that
- */
- // Macros currently can't take default arguments, so we need two functions to emulate defaults.
- def apply(cond: Bool, message: String, data: Bits*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Unit = macro apply_impl_msg_data // scalastyle:ignore line.size.limit
- def apply(cond: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Unit = macro apply_impl
-
- def apply_impl_msg_data(c: Context)(cond: c.Tree, message: c.Tree, data: c.Tree*)(sourceInfo: c.Tree, compileOptions: c.Tree): c.Tree = { // scalastyle:ignore line.size.limit
- import c.universe._
- val p = c.enclosingPosition
- val condStr = s"${p.source.file.name}:${p.line} ${p.lineContent.trim}"
- val apply_impl_do = symbolOf[this.type].asClass.module.info.member(TermName("apply_impl_do"))
- q"$apply_impl_do($cond, $condStr, _root_.scala.Some($message), ..$data)($sourceInfo, $compileOptions)"
- }
-
- def apply_impl(c: Context)(cond: c.Tree)(sourceInfo: c.Tree, compileOptions: c.Tree): c.Tree = {
- import c.universe._
- val p = c.enclosingPosition
- val condStr = s"${p.source.file.name}:${p.line} ${p.lineContent.trim}"
- val apply_impl_do = symbolOf[this.type].asClass.module.info.member(TermName("apply_impl_do"))
- q"$apply_impl_do($cond, $condStr, _root_.scala.None)($sourceInfo, $compileOptions)"
- }
-
- def apply_impl_do(cond: Bool, line: String, message: Option[String], data: Bits*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) { // scalastyle:ignore line.size.limit
- val escLine = line.replaceAll("%", "%%")
- when (!(cond || Module.reset.asBool)) {
- val fmt = message match {
- case Some(msg) =>
- s"Assertion failed: $msg\n at $escLine\n"
- case None => s"Assertion failed\n at $escLine\n"
- }
- printf.printfWithoutReset(fmt, data:_*)
- pushCommand(Stop(sourceInfo, Builder.forcedClock.ref, 1))
- }
- }
-
- /** An elaboration-time assertion, otherwise the same as the above run-time
- * assertion. */
- def apply(cond: Boolean, message: => String) {
- Predef.assert(cond, message)
- }
-
- /** A workaround for default-value overloading problems in Scala, just
- * 'assert(cond, "")' */
- def apply(cond: Boolean) {
- Predef.assert(cond, "")
- }
-}
-
-object stop { // scalastyle:ignore object.name
- /** Terminate execution with a failure code. */
- def apply(code: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Unit = {
- when (!Module.reset.asBool) {
- pushCommand(Stop(sourceInfo, Builder.forcedClock.ref, code))
- }
- }
-
- /** Terminate execution, indicating success. */
- def apply()(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Unit = {
- stop(0)
- }
-}
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Attach.scala b/chiselFrontend/src/main/scala/chisel3/core/Attach.scala
deleted file mode 100644
index 5fb89b18..00000000
--- a/chiselFrontend/src/main/scala/chisel3/core/Attach.scala
+++ /dev/null
@@ -1,45 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3.core
-
-import chisel3.internal._
-import chisel3.internal.Builder.pushCommand
-import chisel3.internal.firrtl._
-import chisel3.internal.sourceinfo.{SourceInfo}
-
-object attach { // scalastyle:ignore object.name
- // Exceptions that can be generated by attach
- case class AttachException(message: String) extends ChiselException(message)
- def ConditionalAttachException: AttachException = // scalastyle:ignore method.name
- AttachException(": Conditional attach is not allowed!")
-
- // Actual implementation
- private[core] def impl(elts: Seq[Analog], contextModule: RawModule)(implicit sourceInfo: SourceInfo): Unit = {
- if (Builder.whenDepth != 0) throw ConditionalAttachException
-
- // TODO Check that references are valid and can be attached
-
- pushCommand(Attach(sourceInfo, elts.map(_.lref)))
- }
-
- /** Create an electrical connection between [[Analog]] components
- *
- * @param elts The components to attach
- *
- * @example
- * {{{
- * val a1 = Wire(Analog(32.W))
- * val a2 = Wire(Analog(32.W))
- * attach(a1, a2)
- * }}}
- */
- def apply(elts: Analog*)(implicit sourceInfo: SourceInfo): Unit = {
- try {
- impl(elts, Builder.forcedUserModule)
- } catch {
- case AttachException(message) =>
- throwException(elts.mkString("Attaching (", ", ", s") failed @$message"))
- }
- }
-}
-
diff --git a/chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala b/chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala
deleted file mode 100644
index b1f9bcb5..00000000
--- a/chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala
+++ /dev/null
@@ -1,332 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3.core
-
-import chisel3.internal.ChiselException
-import chisel3.internal.Builder.pushCommand
-import chisel3.internal.firrtl.{Connect, DefInvalid}
-import scala.language.experimental.macros
-import chisel3.internal.sourceinfo._
-
-/**
-* BiConnect.connect executes a bidirectional connection element-wise.
-*
-* Note that the arguments are left and right (not source and sink) so the
-* intent is for the operation to be commutative.
-*
-* The connect operation will recurse down the left Data (with the right Data).
-* An exception will be thrown if a movement through the left cannot be matched
-* in the right (or if the right side has extra fields).
-*
-* See elemConnect for details on how the root connections are issued.
-*
-*/
-
-object BiConnect {
- // scalastyle:off method.name public.methods.have.type
- // These are all the possible exceptions that can be thrown.
- case class BiConnectException(message: String) extends ChiselException(message)
- // These are from element-level connection
- def BothDriversException =
- BiConnectException(": Both Left and Right are drivers")
- def NeitherDriverException =
- BiConnectException(": Neither Left nor Right is a driver")
- def UnknownDriverException =
- BiConnectException(": Locally unclear whether Left or Right (both internal)")
- def UnknownRelationException =
- BiConnectException(": Left or Right unavailable to current module.")
- // These are when recursing down aggregate types
- def MismatchedVecException =
- BiConnectException(": Left and Right are different length Vecs.")
- def MissingLeftFieldException(field: String) =
- BiConnectException(s".$field: Left Record missing field ($field).")
- def MissingRightFieldException(field: String) =
- BiConnectException(s": Right Record missing field ($field).")
- def MismatchedException(left: String, right: String) =
- BiConnectException(s": Left ($left) and Right ($right) have different types.")
- def AttachAlreadyBulkConnectedException(sourceInfo: SourceInfo) =
- BiConnectException(sourceInfo.makeMessage(": Analog previously bulk connected at " + _))
- def DontCareCantBeSink =
- BiConnectException(": DontCare cannot be a connection sink (LHS)")
- // scalastyle:on method.name public.methods.have.type
-
- /** This function is what recursively tries to connect a left and right together
- *
- * There is some cleverness in the use of internal try-catch to catch exceptions
- * during the recursive decent and then rethrow them with extra information added.
- * This gives the user a 'path' to where in the connections things went wrong.
- */
- def connect(sourceInfo: SourceInfo, connectCompileOptions: CompileOptions, left: Data, right: Data, context_mod: RawModule): Unit = { // scalastyle:ignore line.size.limit cyclomatic.complexity method.length
- (left, right) match {
- // Handle element case (root case)
- case (left_a: Analog, right_a: Analog) =>
- try {
- analogAttach(sourceInfo, left_a, right_a, context_mod)
- } catch {
- // If attach fails, convert to BiConnectException
- case attach.AttachException(message) => throw BiConnectException(message)
- }
- case (left_e: Element, right_e: Element) => {
- elemConnect(sourceInfo, connectCompileOptions, left_e, right_e, context_mod)
- // TODO(twigg): Verify the element-level classes are connectable
- }
- // Handle Vec case
- case (left_v: Vec[Data@unchecked], right_v: Vec[Data@unchecked]) => {
- if (left_v.length != right_v.length) {
- throw MismatchedVecException
- }
- for (idx <- 0 until left_v.length) {
- try {
- implicit val compileOptions = connectCompileOptions
- connect(sourceInfo, connectCompileOptions, left_v(idx), right_v(idx), context_mod)
- } catch {
- case BiConnectException(message) => throw BiConnectException(s"($idx)$message")
- }
- }
- }
- // Handle Vec connected to DontCare
- case (left_v: Vec[Data@unchecked], DontCare) => {
- for (idx <- 0 until left_v.length) {
- try {
- implicit val compileOptions = connectCompileOptions
- connect(sourceInfo, connectCompileOptions, left_v(idx), right, context_mod)
- } catch {
- case BiConnectException(message) => throw BiConnectException(s"($idx)$message")
- }
- }
- }
- // Handle DontCare connected to Vec
- case (DontCare, right_v: Vec[Data@unchecked]) => {
- for (idx <- 0 until right_v.length) {
- try {
- implicit val compileOptions = connectCompileOptions
- connect(sourceInfo, connectCompileOptions, left, right_v(idx), context_mod)
- } catch {
- case BiConnectException(message) => throw BiConnectException(s"($idx)$message")
- }
- }
- }
- // Handle Records defined in Chisel._ code (change to NotStrict)
- case (left_r: Record, right_r: Record) => (left_r.compileOptions, right_r.compileOptions) match {
- case (ExplicitCompileOptions.NotStrict, _) =>
- left_r.bulkConnect(right_r)(sourceInfo, ExplicitCompileOptions.NotStrict)
- case (_, ExplicitCompileOptions.NotStrict) =>
- left_r.bulkConnect(right_r)(sourceInfo, ExplicitCompileOptions.NotStrict)
- case _ => recordConnect(sourceInfo, connectCompileOptions, left_r, right_r, context_mod)
- }
-
- // Handle Records connected to DontCare (change to NotStrict)
- case (left_r: Record, DontCare) =>
- left_r.compileOptions match {
- case ExplicitCompileOptions.NotStrict =>
- left.bulkConnect(right)(sourceInfo, ExplicitCompileOptions.NotStrict)
- case _ =>
- // For each field in left, descend with right
- for ((field, left_sub) <- left_r.elements) {
- try {
- connect(sourceInfo, connectCompileOptions, left_sub, right, context_mod)
- } catch {
- case BiConnectException(message) => throw BiConnectException(s".$field$message")
- }
- }
- }
- case (DontCare, right_r: Record) =>
- right_r.compileOptions match {
- case ExplicitCompileOptions.NotStrict =>
- left.bulkConnect(right)(sourceInfo, ExplicitCompileOptions.NotStrict)
- case _ =>
- // For each field in left, descend with right
- for ((field, right_sub) <- right_r.elements) {
- try {
- connect(sourceInfo, connectCompileOptions, left, right_sub, context_mod)
- } catch {
- case BiConnectException(message) => throw BiConnectException(s".$field$message")
- }
- }
- }
-
- // Left and right are different subtypes of Data so fail
- case (left, right) => throw MismatchedException(left.toString, right.toString)
- }
- }
-
- // Do connection of two Records
- def recordConnect(sourceInfo: SourceInfo,
- connectCompileOptions: CompileOptions,
- left_r: Record,
- right_r: Record,
- context_mod: RawModule): Unit = {
- // Verify right has no extra fields that left doesn't have
- for((field, right_sub) <- right_r.elements) {
- if(!left_r.elements.isDefinedAt(field)) {
- if (connectCompileOptions.connectFieldsMustMatch) {
- throw MissingLeftFieldException(field)
- }
- }
- }
- // For each field in left, descend with right
- for((field, left_sub) <- left_r.elements) {
- try {
- right_r.elements.get(field) match {
- case Some(right_sub) => connect(sourceInfo, connectCompileOptions, left_sub, right_sub, context_mod)
- case None => {
- if (connectCompileOptions.connectFieldsMustMatch) {
- throw MissingRightFieldException(field)
- }
- }
- }
- } catch {
- case BiConnectException(message) => throw BiConnectException(s".$field$message")
- }
- }
- }
-
-
- // These functions (finally) issue the connection operation
- // Issue with right as sink, left as source
- private def issueConnectL2R(left: Element, right: Element)(implicit sourceInfo: SourceInfo): Unit = {
- // Source and sink are ambiguous in the case of a Bi/Bulk Connect (<>).
- // If either is a DontCareBinding, just issue a DefInvalid for the other,
- // otherwise, issue a Connect.
- (left.topBinding, right.topBinding) match {
- case (lb: DontCareBinding, _) => pushCommand(DefInvalid(sourceInfo, right.lref))
- case (_, rb: DontCareBinding) => pushCommand(DefInvalid(sourceInfo, left.lref))
- case (_, _) => pushCommand(Connect(sourceInfo, right.lref, left.ref))
- }
- }
- // Issue with left as sink, right as source
- private def issueConnectR2L(left: Element, right: Element)(implicit sourceInfo: SourceInfo): Unit = {
- // Source and sink are ambiguous in the case of a Bi/Bulk Connect (<>).
- // If either is a DontCareBinding, just issue a DefInvalid for the other,
- // otherwise, issue a Connect.
- (left.topBinding, right.topBinding) match {
- case (lb: DontCareBinding, _) => pushCommand(DefInvalid(sourceInfo, right.lref))
- case (_, rb: DontCareBinding) => pushCommand(DefInvalid(sourceInfo, left.lref))
- case (_, _) => pushCommand(Connect(sourceInfo, left.lref, right.ref))
- }
- }
-
- // This function checks if element-level connection operation allowed.
- // Then it either issues it or throws the appropriate exception.
- def elemConnect(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions, left: Element, right: Element, context_mod: RawModule): Unit = { // scalastyle:ignore line.size.limit cyclomatic.complexity method.length
- import BindingDirection.{Internal, Input, Output} // Using extensively so import these
- // If left or right have no location, assume in context module
- // This can occur if one of them is a literal, unbound will error previously
- val left_mod: BaseModule = left.topBinding.location.getOrElse(context_mod)
- val right_mod: BaseModule = right.topBinding.location.getOrElse(context_mod)
-
- val left_direction = BindingDirection.from(left.topBinding, left.direction)
- val right_direction = BindingDirection.from(right.topBinding, right.direction)
-
- // CASE: Context is same module as left node and right node is in a child module
- if( (left_mod == context_mod) &&
- (right_mod._parent.map(_ == context_mod).getOrElse(false)) ) {
- // Thus, right node better be a port node and thus have a direction hint
- ((left_direction, right_direction): @unchecked) match {
- // CURRENT MOD CHILD MOD
- case (Input, Input) => issueConnectL2R(left, right)
- case (Internal, Input) => issueConnectL2R(left, right)
-
- case (Output, Output) => issueConnectR2L(left, right)
- case (Internal, Output) => issueConnectR2L(left, right)
-
- case (Input, Output) => throw BothDriversException
- case (Output, Input) => throw NeitherDriverException
- case (_, Internal) => throw UnknownRelationException
- }
- }
-
- // CASE: Context is same module as right node and left node is in child module
- else if( (right_mod == context_mod) &&
- (left_mod._parent.map(_ == context_mod).getOrElse(false)) ) {
- // Thus, left node better be a port node and thus have a direction hint
- ((left_direction, right_direction): @unchecked) match {
- // CHILD MOD CURRENT MOD
- case (Input, Input) => issueConnectR2L(left, right)
- case (Input, Internal) => issueConnectR2L(left, right)
-
- case (Output, Output) => issueConnectL2R(left, right)
- case (Output, Internal) => issueConnectL2R(left, right)
-
- case (Input, Output) => throw NeitherDriverException
- case (Output, Input) => throw BothDriversException
- case (Internal, _) => throw UnknownRelationException
- }
- }
-
- // CASE: Context is same module that both left node and right node are in
- else if( (context_mod == left_mod) && (context_mod == right_mod) ) {
- ((left_direction, right_direction): @unchecked) match {
- // CURRENT MOD CURRENT MOD
- case (Input, Output) => issueConnectL2R(left, right)
- case (Input, Internal) => issueConnectL2R(left, right)
- case (Internal, Output) => issueConnectL2R(left, right)
-
- case (Output, Input) => issueConnectR2L(left, right)
- case (Output, Internal) => issueConnectR2L(left, right)
- case (Internal, Input) => issueConnectR2L(left, right)
-
- case (Input, Input) => throw BothDriversException
- case (Output, Output) => throw BothDriversException
- case (Internal, Internal) => {
- if (connectCompileOptions.dontAssumeDirectionality) {
- throw UnknownDriverException
- } else {
- issueConnectR2L(left, right)
- }
- }
- }
- }
-
- // CASE: Context is the parent module of both the module containing left node
- // and the module containing right node
- // Note: This includes case when left and right in same module but in parent
- else if( (left_mod._parent.map(_ == context_mod).getOrElse(false)) &&
- (right_mod._parent.map(_ == context_mod).getOrElse(false))
- ) {
- // Thus both nodes must be ports and have a direction hint
- ((left_direction, right_direction): @unchecked) match {
- // CHILD MOD CHILD MOD
- case (Input, Output) => issueConnectR2L(left, right)
- case (Output, Input) => issueConnectL2R(left, right)
-
- case (Input, Input) => throw NeitherDriverException
- case (Output, Output) => throw BothDriversException
- case (_, Internal) =>
- if (connectCompileOptions.dontAssumeDirectionality) {
- throw UnknownRelationException
- } else {
- issueConnectR2L(left, right)
- }
- case (Internal, _) =>
- if (connectCompileOptions.dontAssumeDirectionality) {
- throw UnknownRelationException
- } else {
- issueConnectR2L(left, right)
- }
- }
- }
-
- // Not quite sure where left and right are compared to current module
- // so just error out
- else throw UnknownRelationException
- }
-
- // This function checks if analog element-level attaching is allowed
- // Then it either issues it or throws the appropriate exception.
- def analogAttach(implicit sourceInfo: SourceInfo, left: Analog, right: Analog, contextModule: RawModule): Unit = {
- // Error if left or right is BICONNECTED in the current module already
- for (elt <- left :: right :: Nil) {
- elt.biConnectLocs.get(contextModule) match {
- case Some(sl) => throw AttachAlreadyBulkConnectedException(sl)
- case None => // Do nothing
- }
- }
-
- // Do the attachment
- attach.impl(Seq(left, right), contextModule)
- // Mark bulk connected
- left.biConnectLocs(contextModule) = sourceInfo
- right.biConnectLocs(contextModule) = sourceInfo
- }
-}
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Binding.scala b/chiselFrontend/src/main/scala/chisel3/core/Binding.scala
deleted file mode 100644
index e30b91ec..00000000
--- a/chiselFrontend/src/main/scala/chisel3/core/Binding.scala
+++ /dev/null
@@ -1,122 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3.core
-
-import chisel3.internal.ChiselException
-import chisel3.internal.Builder.{forcedModule}
-import chisel3.internal.firrtl.LitArg
-
-object Binding {
- class BindingException(message: String) extends ChiselException(message)
- /** A function expected a Chisel type but got a hardware object
- */
- case class ExpectedChiselTypeException(message: String) extends BindingException(message)
- /**A function expected a hardware object but got a Chisel type
- */
- case class ExpectedHardwareException(message: String) extends BindingException(message)
- /** An aggregate had a mix of specified and unspecified directionality children
- */
- case class MixedDirectionAggregateException(message: String) extends BindingException(message)
- /** Attempted to re-bind an already bound (directionality or hardware) object
- */
- case class RebindingException(message: String) extends BindingException(message)
-}
-
-/** Requires that a node is hardware ("bound")
- */
-object requireIsHardware {
- def apply(node: Data, msg: String = ""): Unit = {
- node._parent match { // Compatibility layer hack
- case Some(x: BaseModule) => x._compatAutoWrapPorts
- case _ =>
- }
- if (!node.isSynthesizable) {
- val prefix = if (msg.nonEmpty) s"$msg " else ""
- throw Binding.ExpectedHardwareException(s"$prefix'$node' must be hardware, " +
- "not a bare Chisel type. Perhaps you forgot to wrap it in Wire(_) or IO(_)?")
- }
- }
-}
-
-/** Requires that a node is a chisel type (not hardware, "unbound")
- */
-object requireIsChiselType {
- def apply(node: Data, msg: String = ""): Unit = if (node.isSynthesizable) {
- val prefix = if (msg.nonEmpty) s"$msg " else ""
- throw Binding.ExpectedChiselTypeException(s"$prefix'$node' must be a Chisel type, not hardware")
- }
-}
-
-// Element only direction used for the Binding system only.
-sealed abstract class BindingDirection
-object BindingDirection {
- /** Internal type or wire
- */
- case object Internal extends BindingDirection
- /** Module port with output direction
- */
- case object Output extends BindingDirection
- /** Module port with input direction
- */
- case object Input extends BindingDirection
-
- /** Determine the BindingDirection of an Element given its top binding and resolved direction.
- */
- def from(binding: TopBinding, direction: ActualDirection): BindingDirection = {
- binding match {
- case PortBinding(_) => direction match {
- case ActualDirection.Output => Output
- case ActualDirection.Input => Input
- case dir => throw new RuntimeException(s"Unexpected port element direction '$dir'")
- }
- case _ => Internal
- }
- }
-}
-
-// Location refers to 'where' in the Module hierarchy this lives
-sealed trait Binding {
- def location: Option[BaseModule]
-}
-// Top-level binding representing hardware, not a pointer to another binding (like ChildBinding)
-sealed trait TopBinding extends Binding
-
-// Constrained-ness refers to whether 'bound by Module boundaries'
-// An unconstrained binding, like a literal, can be read by everyone
-sealed trait UnconstrainedBinding extends TopBinding {
- def location: Option[BaseModule] = None
-}
-// A constrained binding can only be read/written by specific modules
-// Location will track where this Module is, and the bound object can be referenced in FIRRTL
-sealed trait ConstrainedBinding extends TopBinding {
- def enclosure: BaseModule
- def location: Option[BaseModule] = Some(enclosure)
-}
-
-// A binding representing a data that cannot be (re)assigned to.
-sealed trait ReadOnlyBinding extends TopBinding
-
-// TODO(twigg): Ops between unenclosed nodes can also be unenclosed
-// However, Chisel currently binds all op results to a module
-case class OpBinding(enclosure: RawModule) extends ConstrainedBinding with ReadOnlyBinding
-case class MemoryPortBinding(enclosure: RawModule) extends ConstrainedBinding
-case class PortBinding(enclosure: BaseModule) extends ConstrainedBinding
-case class RegBinding(enclosure: RawModule) extends ConstrainedBinding
-case class WireBinding(enclosure: RawModule) extends ConstrainedBinding
-
-case class ChildBinding(parent: Data) extends Binding {
- def location: Option[BaseModule] = parent.topBinding.location
-}
-/** Special binding for Vec.sample_element */
-case class SampleElementBinding[T <: Data](parent: Vec[T]) extends Binding {
- def location = parent.topBinding.location
-}
-// A DontCare element has a specific Binding, somewhat like a literal.
-// It is a source (RHS). It may only be connected/applied to sinks.
-case class DontCareBinding() extends UnconstrainedBinding
-
-sealed trait LitBinding extends UnconstrainedBinding with ReadOnlyBinding
-// Literal binding attached to a element that is not part of a Bundle.
-case class ElementLitBinding(litArg: LitArg) extends LitBinding
-// Literal binding attached to the root of a Bundle, containing literal values of its children.
-case class BundleLitBinding(litMap: Map[Data, LitArg]) extends LitBinding
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala
deleted file mode 100644
index b18b27e5..00000000
--- a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala
+++ /dev/null
@@ -1,1808 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3.core
-
-import scala.language.experimental.macros
-import collection.mutable
-
-import chisel3.internal._
-import chisel3.internal.Builder.{pushCommand, pushOp}
-import chisel3.internal.firrtl._
-import chisel3.internal.sourceinfo.{SourceInfo, DeprecatedSourceInfo, SourceInfoTransform, SourceInfoWhiteboxTransform,
- UIntTransform}
-import chisel3.internal.firrtl.PrimOp._
-
-// scalastyle:off method.name line.size.limit file.size.limit
-
-/** Element is a leaf data type: it cannot contain other [[Data]] objects. Example uses are for representing primitive
- * data types, like integers and bits.
- *
- * @define coll element
- */
-abstract class Element extends Data {
- private[chisel3] final def allElements: Seq[Element] = Seq(this)
- def widthKnown: Boolean = width.known
- def name: String = getRef.name
-
- private[chisel3] override def bind(target: Binding, parentDirection: SpecifiedDirection) {
- binding = target
- val resolvedDirection = SpecifiedDirection.fromParent(parentDirection, specifiedDirection)
- direction = ActualDirection.fromSpecified(resolvedDirection)
- }
-
- private[core] override def topBindingOpt: Option[TopBinding] = super.topBindingOpt match {
- // Translate Bundle lit bindings to Element lit bindings
- case Some(BundleLitBinding(litMap)) => litMap.get(this) match {
- case Some(litArg) => Some(ElementLitBinding(litArg))
- case _ => Some(DontCareBinding())
- }
- case topBindingOpt => topBindingOpt
- }
-
- private[core] def litArgOption: Option[LitArg] = topBindingOpt match {
- case Some(ElementLitBinding(litArg)) => Some(litArg)
- case _ => None
- }
-
- override def litOption: Option[BigInt] = litArgOption.map(_.num)
- private[core] def litIsForcedWidth: Option[Boolean] = litArgOption.map(_.forcedWidth)
-
- // provide bits-specific literal handling functionality here
- override private[chisel3] def ref: Arg = topBindingOpt match {
- case Some(ElementLitBinding(litArg)) => litArg
- case Some(BundleLitBinding(litMap)) => litMap.get(this) match {
- case Some(litArg) => litArg
- case _ => throwException(s"internal error: DontCare should be caught before getting ref")
- }
- case _ => super.ref
- }
-
- private[core] def legacyConnect(that: Data)(implicit sourceInfo: SourceInfo): Unit = {
- // If the source is a DontCare, generate a DefInvalid for the sink,
- // otherwise, issue a Connect.
- if (that == DontCare) {
- pushCommand(DefInvalid(sourceInfo, Node(this)))
- } else {
- pushCommand(Connect(sourceInfo, Node(this), that.ref))
- }
- }
-}
-
-/** Exists to unify common interfaces of [[Bits]] and [[Reset]].
- *
- * @note This is a workaround because macros cannot override abstract methods.
- */
-private[chisel3] sealed trait ToBoolable extends Element {
-
- /** Casts this $coll to a [[Bool]]
- *
- * @note The width must be known and equal to 1
- */
- final def asBool(): Bool = macro SourceInfoWhiteboxTransform.noArg
-
- /** @group SourceInfoTransformMacro */
- def do_asBool(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool
-
- /** Casts this $coll to a [[Bool]]
- *
- * @note The width must be known and equal to 1
- */
- final def toBool(): Bool = macro SourceInfoWhiteboxTransform.noArg
-
- /** @group SourceInfoTransformMacro */
- def do_toBool(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool
-}
-
-/** A data type for values represented by a single bitvector. This provides basic bitwise operations.
- *
- * @groupdesc Bitwise Bitwise hardware operators
- * @define coll [[Bits]]
- * @define sumWidthInt @note The width of the returned $coll is `width of this` + `that`.
- * @define sumWidth @note The width of the returned $coll is `width of this` + `width of that`.
- * @define unchangedWidth @note The width of the returned $coll is unchanged, i.e., the `width of this`.
- */
-sealed abstract class Bits(private[chisel3] val width: Width) extends Element with ToBoolable { //scalastyle:off number.of.methods
- // TODO: perhaps make this concrete?
- // Arguments for: self-checking code (can't do arithmetic on bits)
- // Arguments against: generates down to a FIRRTL UInt anyways
-
- // Only used for in a few cases, hopefully to be removed
- private[core] def cloneTypeWidth(width: Width): this.type
-
- def cloneType: this.type = cloneTypeWidth(width)
-
- /** Tail operator
- *
- * @param n the number of bits to remove
- * @return This $coll with the `n` most significant bits removed.
- * @group Bitwise
- */
- final def tail(n: Int): UInt = macro SourceInfoTransform.nArg
-
- /** Head operator
- *
- * @param n the number of bits to take
- * @return The `n` most significant bits of this $coll
- * @group Bitwise
- */
- final def head(n: Int): UInt = macro SourceInfoTransform.nArg
-
- /** @group SourceInfoTransformMacro */
- def do_tail(n: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = {
- val w = width match {
- case KnownWidth(x) =>
- require(x >= n, s"Can't tail($n) for width $x < $n")
- Width(x - n)
- case UnknownWidth() => Width()
- }
- binop(sourceInfo, UInt(width = w), TailOp, n)
- }
-
- /** @group SourceInfoTransformMacro */
- def do_head(n: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = {
- width match {
- case KnownWidth(x) => require(x >= n, s"Can't head($n) for width $x < $n")
- case UnknownWidth() =>
- }
- binop(sourceInfo, UInt(Width(n)), HeadOp, n)
- }
-
- /** Returns the specified bit on this $coll as a [[Bool]], statically addressed.
- *
- * @param x an index
- * @return the specified bit
- */
- final def apply(x: BigInt): Bool = macro SourceInfoTransform.xArg
-
- /** @group SourceInfoTransformMacro */
- final def do_apply(x: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = {
- if (x < 0) {
- Builder.error(s"Negative bit indices are illegal (got $x)")
- }
- // This preserves old behavior while a more more consistent API is under debate
- // See https://github.com/freechipsproject/chisel3/issues/867
- litOption.map { value =>
- (((value >> castToInt(x, "Index")) & 1) == 1).asBool
- }.getOrElse {
- requireIsHardware(this, "bits to be indexed")
- pushOp(DefPrim(sourceInfo, Bool(), BitsExtractOp, this.ref, ILit(x), ILit(x)))
- }
- }
-
- /** Returns the specified bit on this $coll as a [[Bool]], statically addressed.
- *
- * @param x an index
- * @return the specified bit
- * @note convenience method allowing direct use of [[scala.Int]] without implicits
- */
- final def apply(x: Int): Bool = macro SourceInfoTransform.xArg
-
- /** @group SourceInfoTransformMacro */
- final def do_apply(x: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = apply(BigInt(x))
-
- /** Returns the specified bit on this wire as a [[Bool]], dynamically addressed.
- *
- * @param x a hardware component whose value will be used for dynamic addressing
- * @return the specified bit
- */
- final def apply(x: UInt): Bool = macro SourceInfoTransform.xArg
-
- /** @group SourceInfoTransformMacro */
- final def do_apply(x: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = {
- val theBits = this >> x
- theBits(0)
- }
-
- /** Returns a subset of bits on this $coll from `hi` to `lo` (inclusive), statically addressed.
- *
- * @example
- * {{{
- * myBits = 0x5 = 0b101
- * myBits(1,0) => 0b01 // extracts the two least significant bits
- * }}}
- * @param x the high bit
- * @param y the low bit
- * @return a hardware component contain the requested bits
- */
- final def apply(x: Int, y: Int): UInt = macro SourceInfoTransform.xyArg
-
- /** @group SourceInfoTransformMacro */
- final def do_apply(x: Int, y: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = {
- if (x < y || y < 0) {
- Builder.error(s"Invalid bit range ($x,$y)")
- }
- val w = x - y + 1
- // This preserves old behavior while a more more consistent API is under debate
- // See https://github.com/freechipsproject/chisel3/issues/867
- litOption.map { value =>
- ((value >> y) & ((BigInt(1) << w) - 1)).asUInt(w.W)
- }.getOrElse {
- requireIsHardware(this, "bits to be sliced")
- pushOp(DefPrim(sourceInfo, UInt(Width(w)), BitsExtractOp, this.ref, ILit(x), ILit(y)))
- }
- }
-
- // REVIEW TODO: again, is this necessary? Or just have this and use implicits?
- /** Returns a subset of bits on this $coll from `hi` to `lo` (inclusive), statically addressed.
- *
- * @example
- * {{{
- * myBits = 0x5 = 0b101
- * myBits(1,0) => 0b01 // extracts the two least significant bits
- * }}}
- * @param x the high bit
- * @param y the low bit
- * @return a hardware component contain the requested bits
- */
- final def apply(x: BigInt, y: BigInt): UInt = macro SourceInfoTransform.xyArg
-
- /** @group SourceInfoTransformMacro */
- final def do_apply(x: BigInt, y: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
- apply(castToInt(x, "High index"), castToInt(y, "Low index"))
-
- private[core] def unop[T <: Data](sourceInfo: SourceInfo, dest: T, op: PrimOp): T = {
- requireIsHardware(this, "bits operated on")
- pushOp(DefPrim(sourceInfo, dest, op, this.ref))
- }
- private[core] def binop[T <: Data](sourceInfo: SourceInfo, dest: T, op: PrimOp, other: BigInt): T = {
- requireIsHardware(this, "bits operated on")
- pushOp(DefPrim(sourceInfo, dest, op, this.ref, ILit(other)))
- }
- private[core] def binop[T <: Data](sourceInfo: SourceInfo, dest: T, op: PrimOp, other: Bits): T = {
- requireIsHardware(this, "bits operated on")
- requireIsHardware(other, "bits operated on")
- pushOp(DefPrim(sourceInfo, dest, op, this.ref, other.ref))
- }
- private[core] def compop(sourceInfo: SourceInfo, op: PrimOp, other: Bits): Bool = {
- requireIsHardware(this, "bits operated on")
- requireIsHardware(other, "bits operated on")
- pushOp(DefPrim(sourceInfo, Bool(), op, this.ref, other.ref))
- }
- private[core] def redop(sourceInfo: SourceInfo, op: PrimOp): Bool = {
- requireIsHardware(this, "bits operated on")
- pushOp(DefPrim(sourceInfo, Bool(), op, this.ref))
- }
-
- /** Pad operator
- *
- * @param that the width to pad to
- * @return this @coll zero padded up to width `that`. If `that` is less than the width of the original component,
- * this method returns the original component.
- * @note For [[SInt]]s only, this will do sign extension.
- * @group Bitwise
- */
- final def pad(that: Int): this.type = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_pad(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): this.type = this.width match {
- case KnownWidth(w) if w >= that => this
- case _ => binop(sourceInfo, cloneTypeWidth(this.width max Width(that)), PadOp, that)
- }
-
- /** Bitwise inversion operator
- *
- * @return this $coll with each bit inverted
- * @group Bitwise
- */
- final def unary_~ (): Bits = macro SourceInfoWhiteboxTransform.noArg
-
- /** @group SourceInfoTransformMacro */
- def do_unary_~ (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits
-
- /** Static left shift operator
- *
- * @param that an amount to shift by
- * @return this $coll with `that` many zeros concatenated to its least significant end
- * $sumWidthInt
- * @group Bitwise
- */
- // REVIEW TODO: redundant
- // REVIEW TODO: should these return this.type or Bits?
- final def << (that: BigInt): Bits = macro SourceInfoWhiteboxTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_<< (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits
-
- /** Static left shift operator
- *
- * @param that an amount to shift by
- * @return this $coll with `that` many zeros concatenated to its least significant end
- * $sumWidthInt
- * @group Bitwise
- */
- final def << (that: Int): Bits = macro SourceInfoWhiteboxTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_<< (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits
-
- /** Dynamic left shift operator
- *
- * @param that a hardware component
- * @return this $coll dynamically shifted left by `that` many places, shifting in zeros from the right
- * @note The width of the returned $coll is `width of this + pow(2, width of that) - 1`.
- * @group Bitwise
- */
- final def << (that: UInt): Bits = macro SourceInfoWhiteboxTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_<< (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits
-
- /** Static right shift operator
- *
- * @param that an amount to shift by
- * @return this $coll with `that` many least significant bits truncated
- * $unchangedWidth
- * @group Bitwise
- */
- // REVIEW TODO: redundant
- final def >> (that: BigInt): Bits = macro SourceInfoWhiteboxTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_>> (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits
-
- /** Static right shift operator
- *
- * @param that an amount to shift by
- * @return this $coll with `that` many least significant bits truncated
- * $unchangedWidth
- * @group Bitwise
- */
- final def >> (that: Int): Bits = macro SourceInfoWhiteboxTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_>> (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits
-
- /** Dynamic right shift operator
- *
- * @param that a hardware component
- * @return this $coll dynamically shifted right by the value of `that` component, inserting zeros into the most
- * significant bits.
- * $unchangedWidth
- * @group Bitwise
- */
- final def >> (that: UInt): Bits = macro SourceInfoWhiteboxTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_>> (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits
-
- /** Returns the contents of this wire as a [[scala.collection.Seq]] of [[Bool]]. */
- final def toBools(): Seq[Bool] = macro SourceInfoTransform.noArg
-
- /** @group SourceInfoTransformMacro */
- @chiselRuntimeDeprecated
- @deprecated("Use asBools instead", "3.2")
- def do_toBools(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Seq[Bool] = do_asBools
-
- /** Returns the contents of this wire as a [[scala.collection.Seq]] of [[Bool]]. */
- final def asBools(): Seq[Bool] = macro SourceInfoTransform.noArg
-
- /** @group SourceInfoTransformMacro */
- def do_asBools(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Seq[Bool] =
- Seq.tabulate(this.getWidth)(i => this(i))
-
- /** Reinterpret this $coll as an [[SInt]]
- *
- * @note The arithmetic value is not preserved if the most-significant bit is set. For example, a [[UInt]] of
- * width 3 and value 7 (0b111) would become an [[SInt]] of width 3 and value -1.
- */
- final def asSInt(): SInt = macro SourceInfoTransform.noArg
-
- /** @group SourceInfoTransformMacro */
- def do_asSInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt
-
- /** Reinterpret this $coll as a [[FixedPoint]].
- *
- * @note The value is not guaranteed to be preserved. For example, a [[UInt]] of width 3 and value 7 (0b111) would
- * become a [[FixedPoint]] with value -1. The interpretation of the number is also affected by the specified binary
- * point. '''Caution is advised!'''
- */
- final def asFixedPoint(that: BinaryPoint): FixedPoint = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_asFixedPoint(that: BinaryPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = {
- throwException(s"Cannot call .asFixedPoint on $this")
- }
-
- /** Reinterpret cast to Bits. */
- @chiselRuntimeDeprecated
- @deprecated("Use asUInt, which does the same thing but returns a more concrete type", "chisel3")
- final def asBits(implicit compileOptions: CompileOptions): Bits = {
- implicit val sourceInfo = DeprecatedSourceInfo
- do_asUInt
- }
-
- @chiselRuntimeDeprecated
- @deprecated("Use asSInt, which makes the reinterpret cast more explicit", "chisel3")
- final def toSInt(implicit compileOptions: CompileOptions): SInt = {
- implicit val sourceInfo = DeprecatedSourceInfo
- do_asSInt
- }
-
- @chiselRuntimeDeprecated
- @deprecated("Use asUInt, which makes the reinterpret cast more explicit", "chisel3")
- final def toUInt(implicit compileOptions: CompileOptions): UInt = {
- implicit val sourceInfo = DeprecatedSourceInfo
- do_asUInt
- }
-
- final def do_asBool(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = {
- width match {
- case KnownWidth(1) => this(0)
- case _ => throwException(s"can't covert ${this.getClass.getSimpleName}$width to Bool")
- }
- }
-
- @chiselRuntimeDeprecated
- @deprecated("Use asBool instead", "3.2")
- final def do_toBool(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = do_asBool
-
- /** Concatenation operator
- *
- * @param that a hardware component
- * @return this $coll concatenated to the most significant end of `that`
- * $sumWidth
- * @group Bitwise
- */
- final def ## (that: Bits): UInt = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_## (that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = {
- val w = this.width + that.width
- pushOp(DefPrim(sourceInfo, UInt(w), ConcatOp, this.ref, that.ref))
- }
-
- /** Default print as [[Decimal]] */
- final def toPrintable: Printable = Decimal(this)
-
- protected final def validateShiftAmount(x: Int): Int = {
- if (x < 0)
- Builder.error(s"Negative shift amounts are illegal (got $x)")
- x
- }
-}
-
-// REVIEW TODO: Further discussion needed on what Num actually is.
-/** Abstract trait defining operations available on numeric-like hardware data types.
- *
- * @tparam T the underlying type of the number
- * @groupdesc Arithmetic Arithmetic hardware operators
- * @groupdesc Comparison Comparison hardware operators
- * @groupdesc Logical Logical hardware operators
- * @define coll numeric-like type
- * @define numType hardware type
- * @define canHaveHighCost can result in significant cycle time and area costs
- * @define canGenerateA This method generates a
- * @define singleCycleMul @note $canGenerateA fully combinational multiplier which $canHaveHighCost.
- * @define singleCycleDiv @note $canGenerateA fully combinational divider which $canHaveHighCost.
- * @define maxWidth @note The width of the returned $numType is `max(width of this, width of that)`.
- * @define maxWidthPlusOne @note The width of the returned $numType is `max(width of this, width of that) + 1`.
- * @define sumWidth @note The width of the returned $numType is `width of this` + `width of that`.
- * @define unchangedWidth @note The width of the returned $numType is unchanged, i.e., the `width of this`.
- */
-abstract trait Num[T <: Data] {
- self: Num[T] =>
- // def << (b: T): T
- // def >> (b: T): T
- //def unary_-(): T
-
- // REVIEW TODO: double check ops conventions against FIRRTL
-
- /** Addition operator
- *
- * @param that a $numType
- * @return the sum of this $coll and `that`
- * $maxWidthPlusOne
- * @group Arithmetic
- */
- final def + (that: T): T = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_+ (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T
-
- /** Multiplication operator
- *
- * @param that a $numType
- * @return the product of this $coll and `that`
- * $sumWidth
- * $singleCycleMul
- * @group Arithmetic
- */
- final def * (that: T): T = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_* (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T
-
- /** Division operator
- *
- * @param that a $numType
- * @return the quotient of this $coll divided by `that`
- * $singleCycleDiv
- * @todo full rules
- * @group Arithmetic
- */
- final def / (that: T): T = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_/ (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T
-
- /** Modulo operator
- *
- * @param that a $numType
- * @return the remainder of this $coll divided by `that`
- * $singleCycleDiv
- * @group Arithmetic
- */
- final def % (that: T): T = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_% (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T
-
- /** Subtraction operator
- *
- * @param that a $numType
- * @return the difference of this $coll less `that`
- * $maxWidthPlusOne
- * @group Arithmetic
- */
- final def - (that: T): T = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_- (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T
-
- /** Less than operator
- *
- * @param that a $numType
- * @return a hardware [[Bool]] asserted if this $coll is less than `that`
- * @group Comparison
- */
- final def < (that: T): Bool = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_< (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool
-
- /** Less than or equal to operator
- *
- * @param that a $numType
- * @return a hardware [[Bool]] asserted if this $coll is less than or equal to `that`
- * @group Comparison
- */
- final def <= (that: T): Bool = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_<= (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool
-
- /** Greater than operator
- *
- * @param that a hardware component
- * @return a hardware [[Bool]] asserted if this $coll is greater than `that`
- * @group Comparison
- */
- final def > (that: T): Bool = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_> (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool
-
- /** Greater than or equal to operator
- *
- * @param that a hardware component
- * @return a hardware [[Bool]] asserted if this $coll is greather than or equal to `that`
- * @group Comparison
- */
- final def >= (that: T): Bool = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_>= (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool
-
- /** Absolute value operator
- *
- * @return a $numType with a value equal to the absolute value of this $coll
- * $unchangedWidth
- * @group Arithmetic
- */
- final def abs(): T = macro SourceInfoTransform.noArg
-
- /** @group SourceInfoTransformMacro */
- def do_abs(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T
-
- /** Minimum operator
- *
- * @param that a hardware $coll
- * @return a $numType with a value equal to the mimimum value of this $coll and `that`
- * $maxWidth
- * @group Arithmetic
- */
- final def min(that: T): T = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_min(that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T =
- Mux(this < that, this.asInstanceOf[T], that)
-
- /** Maximum operator
- *
- * @param that a $numType
- * @return a $numType with a value equal to the mimimum value of this $coll and `that`
- * $maxWidth
- * @group Arithmetic
- */
- final def max(that: T): T = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_max(that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T =
- Mux(this < that, that, this.asInstanceOf[T])
-}
-
-/** A data type for unsigned integers, represented as a binary bitvector. Defines arithmetic operations between other
- * integer types.
- *
- * @define coll [[UInt]]
- * @define numType $coll
- * @define expandingWidth @note The width of the returned $coll is `width of this` + `1`.
- * @define constantWidth @note The width of the returned $coll is unchanged, i.e., `width of this`.
- */
-sealed class UInt private[core] (width: Width) extends Bits(width) with Num[UInt] {
- override def toString: String = {
- val bindingString = litOption match {
- case Some(value) => s"($value)"
- case _ => bindingToString
- }
- s"UInt$width$bindingString"
- }
-
- private[core] override def typeEquivalent(that: Data): Boolean =
- that.isInstanceOf[UInt] && this.width == that.width
-
- private[core] override def cloneTypeWidth(w: Width): this.type =
- new UInt(w).asInstanceOf[this.type]
-
- // TODO: refactor to share documentation with Num or add independent scaladoc
- /** Unary negation (expanding width)
- *
- * @return a $coll equal to zero minus this $coll
- * $constantWidth
- * @group Arithmetic
- */
- final def unary_- (): UInt = macro SourceInfoTransform.noArg
-
- /** Unary negation (constant width)
- *
- * @return a $coll equal to zero minus this $coll shifted right by one.
- * $constantWidth
- * @group Arithmetic
- */
- final def unary_-% (): UInt = macro SourceInfoTransform.noArg
-
- /** @group SourceInfoTransformMacro */
- def do_unary_- (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) : UInt = 0.U - this
- /** @group SourceInfoTransformMacro */
- def do_unary_-% (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = 0.U -% this
-
- override def do_+ (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = this +% that
- override def do_- (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = this -% that
- override def do_/ (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
- binop(sourceInfo, UInt(this.width), DivideOp, that)
- override def do_% (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
- binop(sourceInfo, UInt(this.width), RemOp, that)
- override def do_* (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
- binop(sourceInfo, UInt(this.width + that.width), TimesOp, that)
-
- /** Multiplication operator
- *
- * @param that a hardware [[SInt]]
- * @return the product of this $coll and `that`
- * $sumWidth
- * $singleCycleMul
- * @group Arithmetic
- */
- final def * (that: SInt): SInt = macro SourceInfoTransform.thatArg
- /** @group SourceInfoTransformMacro */
- def do_* (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = that * this
-
- /** Addition operator (expanding width)
- *
- * @param that a hardware $coll
- * @return the sum of this $coll and `that`
- * $maxWidthPlusOne
- * @group Arithmetic
- */
- final def +& (that: UInt): UInt = macro SourceInfoTransform.thatArg
-
- /** Addition operator (constant width)
- *
- * @param that a hardware $coll
- * @return the sum of this $coll and `that`
- * $maxWidth
- * @group Arithmetic
- */
- final def +% (that: UInt): UInt = macro SourceInfoTransform.thatArg
-
- /** Subtraction operator (increasing width)
- *
- * @param that a hardware $coll
- * @return the difference of this $coll less `that`
- * $maxWidthPlusOne
- * @group Arithmetic
- */
- final def -& (that: UInt): UInt = macro SourceInfoTransform.thatArg
-
- /** Subtraction operator (constant width)
- *
- * @param that a hardware $coll
- * @return the difference of this $coll less `that`
- * $maxWidth
- * @group Arithmetic
- */
- final def -% (that: UInt): UInt = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_+& (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
- binop(sourceInfo, UInt((this.width max that.width) + 1), AddOp, that)
- /** @group SourceInfoTransformMacro */
- def do_+% (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
- (this +& that).tail(1)
- /** @group SourceInfoTransformMacro */
- def do_-& (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
- (this subtractAsSInt that).asUInt
- /** @group SourceInfoTransformMacro */
- def do_-% (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
- (this subtractAsSInt that).tail(1)
-
- /** Bitwise and operator
- *
- * @param that a hardware $coll
- * @return the bitwise and of this $coll and `that`
- * $maxWidth
- * @group Bitwise
- */
- final def & (that: UInt): UInt = macro SourceInfoTransform.thatArg
-
- /** Bitwise or operator
- *
- * @param that a hardware $coll
- * @return the bitwise or of this $coll and `that`
- * $maxWidth
- * @group Bitwise
- */
- final def | (that: UInt): UInt = macro SourceInfoTransform.thatArg
-
- /** Bitwise exclusive or (xor) operator
- *
- * @param that a hardware $coll
- * @return the bitwise xor of this $coll and `that`
- * $maxWidth
- * @group Bitwise
- */
- final def ^ (that: UInt): UInt = macro SourceInfoTransform.thatArg
-
- // override def abs: UInt = macro SourceInfoTransform.noArg
- def do_abs(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = this
-
- /** @group SourceInfoTransformMacro */
- def do_& (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
- binop(sourceInfo, UInt(this.width max that.width), BitAndOp, that)
- /** @group SourceInfoTransformMacro */
- def do_| (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
- binop(sourceInfo, UInt(this.width max that.width), BitOrOp, that)
- /** @group SourceInfoTransformMacro */
- def do_^ (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
- binop(sourceInfo, UInt(this.width max that.width), BitXorOp, that)
-
- /** @group SourceInfoTransformMacro */
- def do_unary_~ (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
- unop(sourceInfo, UInt(width = width), BitNotOp)
-
- // REVIEW TODO: Can these be defined on Bits?
- /** Or reduction operator
- *
- * @return a hardware [[Bool]] resulting from every bit of this $coll or'd together
- * @group Bitwise
- */
- final def orR(): Bool = macro SourceInfoTransform.noArg
-
- /** And reduction operator
- *
- * @return a hardware [[Bool]] resulting from every bit of this $coll and'd together
- * @group Bitwise
- */
- final def andR(): Bool = macro SourceInfoTransform.noArg
-
- /** Exclusive or (xor) reduction operator
- *
- * @return a hardware [[Bool]] resulting from every bit of this $coll xor'd together
- * @group Bitwise
- */
- final def xorR(): Bool = macro SourceInfoTransform.noArg
-
- /** @group SourceInfoTransformMacro */
- def do_orR(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = this =/= 0.U
- /** @group SourceInfoTransformMacro */
- def do_andR(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = width match {
- // Generate a simpler expression if the width is known
- case KnownWidth(w) => this === ((BigInt(1) << w) - 1).U
- case UnknownWidth() => ~this === 0.U
- }
- /** @group SourceInfoTransformMacro */
- def do_xorR(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = redop(sourceInfo, XorReduceOp)
-
- override def do_< (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, LessOp, that)
- override def do_> (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, GreaterOp, that)
- override def do_<= (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, LessEqOp, that)
- override def do_>= (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, GreaterEqOp, that)
-
- @chiselRuntimeDeprecated
- @deprecated("Use '=/=', which avoids potential precedence problems", "chisel3")
- final def != (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = this =/= that
-
- /** Dynamic not equals operator
- *
- * @param that a hardware $coll
- * @return a hardware [[Bool]] asserted if this $coll is not equal to `that`
- * @group Comparison
- */
- final def =/= (that: UInt): Bool = macro SourceInfoTransform.thatArg
-
- /** Dynamic equals operator
- *
- * @param that a hardware $coll
- * @return a hardware [[Bool]] asserted if this $coll is equal to `that`
- * @group Comparison
- */
- final def === (that: UInt): Bool = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_=/= (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, NotEqualOp, that)
- /** @group SourceInfoTransformMacro */
- def do_=== (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, EqualOp, that)
-
- /** Unary not
- *
- * @return a hardware [[Bool]] asserted if this $coll equals zero
- * @group Bitwise
- */
- final def unary_! () : Bool = macro SourceInfoTransform.noArg
-
- /** @group SourceInfoTransformMacro */
- def do_unary_! (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) : Bool = this === 0.U(1.W)
-
- override def do_<< (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
- binop(sourceInfo, UInt(this.width + that), ShiftLeftOp, validateShiftAmount(that))
- override def do_<< (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
- this << castToInt(that, "Shift amount")
- override def do_<< (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
- binop(sourceInfo, UInt(this.width.dynamicShiftLeft(that.width)), DynamicShiftLeftOp, that)
- override def do_>> (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
- binop(sourceInfo, UInt(this.width.shiftRight(that)), ShiftRightOp, validateShiftAmount(that))
- override def do_>> (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
- this >> castToInt(that, "Shift amount")
- override def do_>> (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
- binop(sourceInfo, UInt(this.width), DynamicShiftRightOp, that)
-
- /** Conditionally set or clear a bit
- *
- * @param off a dynamic offset
- * @param dat set if true, clear if false
- * @return a hrdware $coll with bit `off` set or cleared based on the value of `dat`
- * $unchangedWidth
- */
- final def bitSet(off: UInt, dat: Bool): UInt = macro UIntTransform.bitset
-
- /** @group SourceInfoTransformMacro */
- def do_bitSet(off: UInt, dat: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = {
- val bit = 1.U(1.W) << off
- Mux(dat, this | bit, ~(~this | bit))
- }
-
- // TODO: this eventually will be renamed as toSInt, once the existing toSInt
- // completes its deprecation phase.
- /** Zero extend as [[SInt]]
- *
- * @return an [[SInt]] equal to this $coll with an additional zero in its most significant bit
- * @note The width of the returned [[SInt]] is `width of this` + `1`.
- */
- final def zext(): SInt = macro SourceInfoTransform.noArg
- /** @group SourceInfoTransformMacro */
- def do_zext(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
- pushOp(DefPrim(sourceInfo, SInt(width + 1), ConvertOp, ref))
-
- override def do_asSInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
- pushOp(DefPrim(sourceInfo, SInt(width), AsSIntOp, ref))
- override def do_asUInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = this
- override def do_asFixedPoint(binaryPoint: BinaryPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = {
- binaryPoint match {
- case KnownBinaryPoint(value) =>
- val iLit = ILit(value)
- pushOp(DefPrim(sourceInfo, FixedPoint(width, binaryPoint), AsFixedPointOp, ref, iLit))
- case _ =>
- throwException(s"cannot call $this.asFixedPoint(binaryPoint=$binaryPoint), you must specify a known binaryPoint")
- }
- }
-
- private[core] override def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions): Unit = {
- this := that.asUInt
- }
-
- private def subtractAsSInt(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
- binop(sourceInfo, SInt((this.width max that.width) + 1), SubOp, that)
-}
-
-// This is currently a factory because both Bits and UInt inherit it.
-trait UIntFactory {
- /** Create a UInt type with inferred width. */
- def apply(): UInt = apply(Width())
- /** Create a UInt port with specified width. */
- def apply(width: Width): UInt = new UInt(width)
-
- /** Create a UInt literal with specified width. */
- protected[chisel3] def Lit(value: BigInt, width: Width): UInt = {
- val lit = ULit(value, width)
- val result = new UInt(lit.width)
- // Bind result to being an Literal
- lit.bindLitArg(result)
- }
-
- /** Create a UInt with the specified range */
- def apply(range: Range): UInt = {
- apply(range.getWidth)
- }
- /** Create a UInt with the specified range */
- def apply(range: (NumericBound[Int], NumericBound[Int])): UInt = {
- apply(KnownUIntRange(range._1, range._2))
- }
-}
-
-object UInt extends UIntFactory
-object Bits extends UIntFactory
-
-/** A data type for signed integers, represented as a binary bitvector. Defines arithmetic operations between other
- * integer types.
- *
- * @define coll [[SInt]]
- * @define numType $coll
- * @define expandingWidth @note The width of the returned $coll is `width of this` + `1`.
- * @define constantWidth @note The width of the returned $coll is unchanged, i.e., `width of this`.
- */
-sealed class SInt private[core] (width: Width) extends Bits(width) with Num[SInt] {
- override def toString: String = {
- val bindingString = litOption match {
- case Some(value) => s"($value)"
- case _ => bindingToString
- }
- s"SInt$width$bindingString"
- }
-
- private[core] override def typeEquivalent(that: Data): Boolean =
- this.getClass == that.getClass && this.width == that.width // TODO: should this be true for unspecified widths?
-
- private[core] override def cloneTypeWidth(w: Width): this.type =
- new SInt(w).asInstanceOf[this.type]
-
- /** Unary negation (expanding width)
- *
- * @return a hardware $coll equal to zero minus this $coll
- * $constantWidth
- * @group Arithmetic
- */
- final def unary_- (): SInt = macro SourceInfoTransform.noArg
-
- /** Unary negation (constant width)
- *
- * @return a hardware $coll equal to zero minus `this` shifted right by one
- * $constantWidth
- * @group Arithmetic
- */
- final def unary_-% (): SInt = macro SourceInfoTransform.noArg
-
- /** @group SourceInfoTransformMacro */
- def unary_- (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = 0.S - this
- /** @group SourceInfoTransformMacro */
- def unary_-% (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = 0.S -% this
-
- /** add (default - no growth) operator */
- override def do_+ (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
- this +% that
- /** subtract (default - no growth) operator */
- override def do_- (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
- this -% that
- override def do_* (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
- binop(sourceInfo, SInt(this.width + that.width), TimesOp, that)
- override def do_/ (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
- binop(sourceInfo, SInt(this.width), DivideOp, that)
- override def do_% (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
- binop(sourceInfo, SInt(this.width), RemOp, that)
-
- /** Multiplication operator
- *
- * @param that a hardware $coll
- * @return the product of this $coll and `that`
- * $sumWidth
- * $singleCycleMul
- * @group Arithmetic
- */
- final def * (that: UInt): SInt = macro SourceInfoTransform.thatArg
- /** @group SourceInfoTransformMacro */
- def do_* (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = {
- val thatToSInt = that.zext()
- val result = binop(sourceInfo, SInt(this.width + thatToSInt.width), TimesOp, thatToSInt)
- result.tail(1).asSInt
- }
-
- /** Addition operator (expanding width)
- *
- * @param that a hardware $coll
- * @return the sum of this $coll and `that`
- * $maxWidthPlusOne
- * @group Arithmetic
- */
- final def +& (that: SInt): SInt = macro SourceInfoTransform.thatArg
-
- /** Addition operator (constant width)
- *
- * @param that a hardware $coll
- * @return the sum of this $coll and `that` shifted right by one
- * $maxWidth
- * @group Arithmetic
- */
- final def +% (that: SInt): SInt = macro SourceInfoTransform.thatArg
-
- /** Subtraction operator (increasing width)
- *
- * @param that a hardware $coll
- * @return the difference of this $coll less `that`
- * $maxWidthPlusOne
- * @group Arithmetic
- */
- final def -& (that: SInt): SInt = macro SourceInfoTransform.thatArg
-
- /** Subtraction operator (constant width)
- *
- * @param that a hardware $coll
- * @return the difference of this $coll less `that` shifted right by one
- * $maxWidth
- * @group Arithmetic
- */
- final def -% (that: SInt): SInt = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_+& (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
- binop(sourceInfo, SInt((this.width max that.width) + 1), AddOp, that)
- /** @group SourceInfoTransformMacro */
- def do_+% (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
- (this +& that).tail(1).asSInt
- /** @group SourceInfoTransformMacro */
- def do_-& (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
- binop(sourceInfo, SInt((this.width max that.width) + 1), SubOp, that)
- /** @group SourceInfoTransformMacro */
- def do_-% (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
- (this -& that).tail(1).asSInt
-
- /** Bitwise and operator
- *
- * @param that a hardware $coll
- * @return the bitwise and of this $coll and `that`
- * $maxWidth
- * @group Bitwise
- */
- final def & (that: SInt): SInt = macro SourceInfoTransform.thatArg
-
- /** Bitwise or operator
- *
- * @param that a hardware $coll
- * @return the bitwise or of this $coll and `that`
- * $maxWidth
- * @group Bitwise
- */
- final def | (that: SInt): SInt = macro SourceInfoTransform.thatArg
-
- /** Bitwise exclusive or (xor) operator
- *
- * @param that a hardware $coll
- * @return the bitwise xor of this $coll and `that`
- * $maxWidth
- * @group Bitwise
- */
- final def ^ (that: SInt): SInt = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_& (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
- binop(sourceInfo, UInt(this.width max that.width), BitAndOp, that).asSInt
- /** @group SourceInfoTransformMacro */
- def do_| (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
- binop(sourceInfo, UInt(this.width max that.width), BitOrOp, that).asSInt
- /** @group SourceInfoTransformMacro */
- def do_^ (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
- binop(sourceInfo, UInt(this.width max that.width), BitXorOp, that).asSInt
-
- /** @group SourceInfoTransformMacro */
- def do_unary_~ (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
- unop(sourceInfo, UInt(width = width), BitNotOp).asSInt
-
- override def do_< (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, LessOp, that)
- override def do_> (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, GreaterOp, that)
- override def do_<= (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, LessEqOp, that)
- override def do_>= (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, GreaterEqOp, that)
-
- @chiselRuntimeDeprecated
- @deprecated("Use '=/=', which avoids potential precedence problems", "chisel3")
- final def != (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = this =/= that
-
- /** Dynamic not equals operator
- *
- * @param that a hardware $coll
- * @return a hardware [[Bool]] asserted if this $coll is not equal to `that`
- * @group Comparison
- */
- final def =/= (that: SInt): Bool = macro SourceInfoTransform.thatArg
-
- /** Dynamic equals operator
- *
- * @param that a hardware $coll
- * @return a hardware [[Bool]] asserted if this $coll is equal to `that`
- * @group Comparison
- */
- final def === (that: SInt): Bool = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_=/= (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, NotEqualOp, that)
- /** @group SourceInfoTransformMacro */
- def do_=== (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, EqualOp, that)
-
-// final def abs(): UInt = macro SourceInfoTransform.noArg
-
- def do_abs(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = {
- Mux(this < 0.S, (-this), this)
- }
-
- override def do_<< (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
- binop(sourceInfo, SInt(this.width + that), ShiftLeftOp, validateShiftAmount(that))
- override def do_<< (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
- this << castToInt(that, "Shift amount")
- override def do_<< (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
- binop(sourceInfo, SInt(this.width.dynamicShiftLeft(that.width)), DynamicShiftLeftOp, that)
- override def do_>> (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
- binop(sourceInfo, SInt(this.width.shiftRight(that)), ShiftRightOp, validateShiftAmount(that))
- override def do_>> (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
- this >> castToInt(that, "Shift amount")
- override def do_>> (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
- binop(sourceInfo, SInt(this.width), DynamicShiftRightOp, that)
-
- override def do_asUInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = pushOp(DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref))
- override def do_asSInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = this
- override def do_asFixedPoint(binaryPoint: BinaryPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = {
- binaryPoint match {
- case KnownBinaryPoint(value) =>
- val iLit = ILit(value)
- pushOp(DefPrim(sourceInfo, FixedPoint(width, binaryPoint), AsFixedPointOp, ref, iLit))
- case _ =>
- throwException(s"cannot call $this.asFixedPoint(binaryPoint=$binaryPoint), you must specify a known binaryPoint")
- }
- }
-
- private[core] override def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) {
- this := that.asSInt
- }
-}
-
-trait SIntFactory {
- /** Create an SInt type with inferred width. */
- def apply(): SInt = apply(Width())
- /** Create a SInt type or port with fixed width. */
- def apply(width: Width): SInt = new SInt(width)
-
- /** Create a SInt with the specified range */
- def apply(range: Range): SInt = {
- apply(range.getWidth)
- }
- /** Create a SInt with the specified range */
- def apply(range: (NumericBound[Int], NumericBound[Int])): SInt = {
- apply(KnownSIntRange(range._1, range._2))
- }
-
- /** Create an SInt literal with specified width. */
- protected[chisel3] def Lit(value: BigInt, width: Width): SInt = {
- val lit = SLit(value, width)
- val result = new SInt(lit.width)
- lit.bindLitArg(result)
- }
-}
-
-object SInt extends SIntFactory
-
-sealed trait Reset extends Element with ToBoolable
-
-// REVIEW TODO: Why does this extend UInt and not Bits? Does defining airth
-// operations on a Bool make sense?
-/** A data type for booleans, defined as a single bit indicating true or false.
- *
- * @define coll [[Bool]]
- * @define numType $coll
- */
-sealed class Bool() extends UInt(1.W) with Reset {
- override def toString: String = {
- val bindingString = litToBooleanOption match {
- case Some(value) => s"($value)"
- case _ => bindingToString
- }
- s"Bool$bindingString"
- }
-
- private[core] override def cloneTypeWidth(w: Width): this.type = {
- require(!w.known || w.get == 1)
- new Bool().asInstanceOf[this.type]
- }
-
- /** Convert to a [[scala.Option]] of [[scala.Boolean]] */
- def litToBooleanOption: Option[Boolean] = litOption.map {
- case intVal if intVal == 1 => true
- case intVal if intVal == 0 => false
- case intVal => throwException(s"Boolean with unexpected literal value $intVal")
- }
-
- /** Convert to a [[scala.Boolean]] */
- def litToBoolean: Boolean = litToBooleanOption.get
-
- // REVIEW TODO: Why does this need to exist and have different conventions
- // than Bits?
-
- /** Bitwise and operator
- *
- * @param that a hardware $coll
- * @return the bitwise and of this $coll and `that`
- * @group Bitwise
- */
- final def & (that: Bool): Bool = macro SourceInfoTransform.thatArg
-
- /** Bitwise or operator
- *
- * @param that a hardware $coll
- * @return the bitwise or of this $coll and `that`
- * @group Bitwise
- */
- final def | (that: Bool): Bool = macro SourceInfoTransform.thatArg
-
- /** Bitwise exclusive or (xor) operator
- *
- * @param that a hardware $coll
- * @return the bitwise xor of this $coll and `that`
- * @group Bitwise
- */
- final def ^ (that: Bool): Bool = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_& (that: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool =
- binop(sourceInfo, Bool(), BitAndOp, that)
- /** @group SourceInfoTransformMacro */
- def do_| (that: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool =
- binop(sourceInfo, Bool(), BitOrOp, that)
- /** @group SourceInfoTransformMacro */
- def do_^ (that: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool =
- binop(sourceInfo, Bool(), BitXorOp, that)
-
- /** @group SourceInfoTransformMacro */
- override def do_unary_~ (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool =
- unop(sourceInfo, Bool(), BitNotOp)
-
- /** Logical or operator
- *
- * @param that a hardware $coll
- * @return the lgocial or of this $coll and `that`
- * @note this is equivalent to [[Bool!.|(that:chisel3\.core\.Bool)* Bool.|)]]
- * @group Logical
- */
- def || (that: Bool): Bool = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_|| (that: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = this | that
-
- /** Logical and operator
- *
- * @param that a hardware $coll
- * @return the lgocial and of this $coll and `that`
- * @note this is equivalent to [[Bool!.&(that:chisel3\.core\.Bool)* Bool.&]]
- * @group Logical
- */
- def && (that: Bool): Bool = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_&& (that: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = this & that
-
- /** Reinterprets this $coll as a clock */
- def asClock(): Clock = macro SourceInfoTransform.noArg
-
- /** @group SourceInfoTransformMacro */
- def do_asClock(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Clock = pushOp(DefPrim(sourceInfo, Clock(), AsClockOp, ref))
-}
-
-trait BoolFactory {
- /** Creates an empty Bool.
- */
- def apply(): Bool = new Bool()
-
- /** Creates Bool literal.
- */
- protected[chisel3] def Lit(x: Boolean): Bool = {
- val result = new Bool()
- val lit = ULit(if (x) 1 else 0, Width(1))
- // Ensure we have something capable of generating a name.
- lit.bindLitArg(result)
- }
-}
-
-object Bool extends BoolFactory
-
-//scalastyle:off number.of.methods
-/** A sealed class representing a fixed point number that has a bit width and a binary point The width and binary point
- * may be inferred.
- *
- * IMPORTANT: The API provided here is experimental and may change in the future.
- *
- * @param width bit width of the fixed point number
- * @param binaryPoint the position of the binary point with respect to the right most bit of the width currently this
- * should be positive but it is hoped to soon support negative points and thus use this field as a
- * simple exponent
- * @define coll [[FixedPoint]]
- * @define numType $coll
- * @define expandingWidth @note The width of the returned $coll is `width of this` + `1`.
- * @define constantWidth @note The width of the returned $coll is unchanged, i.e., `width of this`.
- */
-sealed class FixedPoint private (width: Width, val binaryPoint: BinaryPoint)
- extends Bits(width) with Num[FixedPoint] {
- override def toString: String = {
- val bindingString = litToDoubleOption match {
- case Some(value) => s"($value)"
- case _ => bindingToString
- }
- s"FixedPoint$width$binaryPoint$bindingString"
- }
-
- private[core] override def typeEquivalent(that: Data): Boolean = that match {
- case that: FixedPoint => this.width == that.width && this.binaryPoint == that.binaryPoint // TODO: should this be true for unspecified widths?
- case _ => false
- }
-
- private[core] override def cloneTypeWidth(w: Width): this.type =
- new FixedPoint(w, binaryPoint).asInstanceOf[this.type]
-
- override def connect (that: Data)(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): Unit = that match {
- case _: FixedPoint|DontCare => super.connect(that)
- case _ => this badConnect that
- }
-
- /** Convert to a [[scala.Option]] of [[scala.Boolean]] */
- def litToDoubleOption: Option[Double] = litOption.map { intVal =>
- val multiplier = math.pow(2, binaryPoint.get)
- intVal.toDouble / multiplier
- }
-
- /** Convert to a [[scala.Option]] */
- def litToDouble: Double = litToDoubleOption.get
-
-
- /** Unary negation (expanding width)
- *
- * @return a hardware $coll equal to zero minus this $coll
- * $expandingWidth
- * @group Arithmetic
- */
- final def unary_- (): FixedPoint = macro SourceInfoTransform.noArg
-
- /** Unary negation (constant width)
- *
- * @return a hardware $coll equal to zero minus `this` shifted right by one
- * $constantWidth
- * @group Arithmetic
- */
- final def unary_-% (): FixedPoint = macro SourceInfoTransform.noArg
-
- /** @group SourceInfoTransformMacro */
- def unary_- (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = FixedPoint.fromBigInt(0) - this
- /** @group SourceInfoTransformMacro */
- def unary_-% (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = FixedPoint.fromBigInt(0) -% this
-
- /** add (default - no growth) operator */
- override def do_+ (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- this +% that
- /** subtract (default - no growth) operator */
- override def do_- (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- this -% that
- override def do_* (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- binop(sourceInfo, FixedPoint(this.width + that.width, this.binaryPoint + that.binaryPoint), TimesOp, that)
- override def do_/ (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- throwException(s"division is illegal on FixedPoint types")
- override def do_% (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- throwException(s"mod is illegal on FixedPoint types")
-
-
- /** Multiplication operator
- *
- * @param that a hardware [[UInt]]
- * @return the product of this $coll and `that`
- * $sumWidth
- * $singleCycleMul
- * @group Arithmetic
- */
- final def * (that: UInt): FixedPoint = macro SourceInfoTransform.thatArg
- /** @group SourceInfoTransformMacro */
- def do_* (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- binop(sourceInfo, FixedPoint(this.width + that.width, binaryPoint), TimesOp, that)
-
- /** Multiplication operator
- *
- * @param that a hardware [[SInt]]
- * @return the product of this $coll and `that`
- * $sumWidth
- * $singleCycleMul
- * @group Arithmetic
- */
- final def * (that: SInt): FixedPoint = macro SourceInfoTransform.thatArg
- /** @group SourceInfoTransformMacro */
- def do_* (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- binop(sourceInfo, FixedPoint(this.width + that.width, binaryPoint), TimesOp, that)
-
- /** Addition operator (expanding width)
- *
- * @param that a hardware $coll
- * @return the sum of this $coll and `that`
- * $maxWidthPlusOne
- * @group Arithmetic
- */
- final def +& (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg
-
- /** Addition operator (constant width)
- *
- * @param that a hardware $coll
- * @return the sum of this $coll and `that` shifted right by one
- * $maxWidth
- * @group Arithmetic
- */
- final def +% (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg
-
- /** Subtraction operator (increasing width)
- *
- * @param that a hardware $coll
- * @return the difference of this $coll less `that`
- * $maxWidthPlusOne
- * @group Arithmetic
- */
- final def -& (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg
-
- /** Subtraction operator (constant width)
- *
- * @param that a hardware $coll
- * @return the difference of this $coll less `that` shifted right by one
- * $maxWidth
- * @group Arithmetic
- */
- final def -% (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_+& (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = {
- (this.width, that.width, this.binaryPoint, that.binaryPoint) match {
- case (KnownWidth(thisWidth), KnownWidth(thatWidth), KnownBinaryPoint(thisBP), KnownBinaryPoint(thatBP)) =>
- val thisIntWidth = thisWidth - thisBP
- val thatIntWidth = thatWidth - thatBP
- val newBinaryPoint = thisBP max thatBP
- val newWidth = (thisIntWidth max thatIntWidth) + newBinaryPoint + 1
- binop(sourceInfo, FixedPoint(newWidth.W, newBinaryPoint.BP), AddOp, that)
- case _ =>
- val newBinaryPoint = this.binaryPoint max that.binaryPoint
- binop(sourceInfo, FixedPoint(UnknownWidth(), newBinaryPoint), AddOp, that)
- }
- }
-
- /** @group SourceInfoTransformMacro */
- def do_+% (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- (this +& that).tail(1).asFixedPoint(this.binaryPoint max that.binaryPoint)
- /** @group SourceInfoTransformMacro */
- def do_-& (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = {
- (this.width, that.width, this.binaryPoint, that.binaryPoint) match {
- case (KnownWidth(thisWidth), KnownWidth(thatWidth), KnownBinaryPoint(thisBP), KnownBinaryPoint(thatBP)) =>
- val thisIntWidth = thisWidth - thisBP
- val thatIntWidth = thatWidth - thatBP
- val newBinaryPoint = thisBP max thatBP
- val newWidth = (thisIntWidth max thatIntWidth) + newBinaryPoint + 1
- binop(sourceInfo, FixedPoint(newWidth.W, newBinaryPoint.BP), SubOp, that)
- case _ =>
- val newBinaryPoint = this.binaryPoint max that.binaryPoint
- binop(sourceInfo, FixedPoint(UnknownWidth(), newBinaryPoint), SubOp, that)
- }
- }
-
- /** @group SourceInfoTransformMacro */
- def do_-% (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- (this -& that).tail(1).asFixedPoint(this.binaryPoint max that.binaryPoint)
-
- /** Bitwise and operator
- *
- * @param that a hardware $coll
- * @return the bitwise and of this $coll and `that`
- * $maxWidth
- * @group Bitwise
- */
- final def & (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg
-
- /** Bitwise or operator
- *
- * @param that a hardware $coll
- * @return the bitwise or of this $coll and `that`
- * $maxWidth
- * @group Bitwise
- */
- final def | (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg
-
- /** Bitwise exclusive or (xor) operator
- *
- * @param that a hardware $coll
- * @return the bitwise xor of this $coll and `that`
- * $maxWidth
- * @group Bitwise
- */
- final def ^ (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_& (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- throwException(s"And is illegal between $this and $that")
- /** @group SourceInfoTransformMacro */
- def do_| (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- throwException(s"Or is illegal between $this and $that")
- /** @group SourceInfoTransformMacro */
- def do_^ (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- throwException(s"Xor is illegal between $this and $that")
-
- final def setBinaryPoint(that: Int): FixedPoint = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_setBinaryPoint(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = this.binaryPoint match {
- case KnownBinaryPoint(value) =>
- binop(sourceInfo, FixedPoint(this.width + (that - value), KnownBinaryPoint(that)), SetBinaryPoint, that)
- case _ =>
- binop(sourceInfo, FixedPoint(UnknownWidth(), KnownBinaryPoint(that)), SetBinaryPoint, that)
- }
-
- /** @group SourceInfoTransformMacro */
- def do_unary_~ (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- throwException(s"Not is illegal on $this")
-
- // TODO(chick): Consider comparison with UInt and SInt
- override def do_< (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, LessOp, that)
- override def do_> (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, GreaterOp, that)
- override def do_<= (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, LessEqOp, that)
- override def do_>= (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, GreaterEqOp, that)
-
- final def != (that: FixedPoint): Bool = macro SourceInfoTransform.thatArg
-
- /** Dynamic not equals operator
- *
- * @param that a hardware $coll
- * @return a hardware [[Bool]] asserted if this $coll is not equal to `that`
- * @group Comparison
- */
- final def =/= (that: FixedPoint): Bool = macro SourceInfoTransform.thatArg
-
- /** Dynamic equals operator
- *
- * @param that a hardware $coll
- * @return a hardware [[Bool]] asserted if this $coll is equal to `that`
- * @group Comparison
- */
- final def === (that: FixedPoint): Bool = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_!= (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, NotEqualOp, that)
- /** @group SourceInfoTransformMacro */
- def do_=/= (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, NotEqualOp, that)
- /** @group SourceInfoTransformMacro */
- def do_=== (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, EqualOp, that)
-
- def do_abs(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = {
- // TODO: remove this once we have CompileOptions threaded through the macro system.
- import chisel3.core.ExplicitCompileOptions.NotStrict
- Mux(this < 0.F(0.BP), 0.F(0.BP) - this, this)
- }
-
- override def do_<< (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- binop(sourceInfo, FixedPoint(this.width + that, this.binaryPoint), ShiftLeftOp, validateShiftAmount(that))
- override def do_<< (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- (this << castToInt(that, "Shift amount")).asFixedPoint(this.binaryPoint)
- override def do_<< (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- binop(sourceInfo, FixedPoint(this.width.dynamicShiftLeft(that.width), this.binaryPoint), DynamicShiftLeftOp, that)
- override def do_>> (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- binop(sourceInfo, FixedPoint(this.width.shiftRight(that), this.binaryPoint), ShiftRightOp, validateShiftAmount(that))
- override def do_>> (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- (this >> castToInt(that, "Shift amount")).asFixedPoint(this.binaryPoint)
- override def do_>> (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
- binop(sourceInfo, FixedPoint(this.width, this.binaryPoint), DynamicShiftRightOp, that)
-
- override def do_asUInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = pushOp(DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref))
- override def do_asSInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = pushOp(DefPrim(sourceInfo, SInt(this.width), AsSIntOp, ref))
-
- override def do_asFixedPoint(binaryPoint: BinaryPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = {
- binaryPoint match {
- case KnownBinaryPoint(value) =>
- val iLit = ILit(value)
- pushOp(DefPrim(sourceInfo, FixedPoint(width, binaryPoint), AsFixedPointOp, ref, iLit))
- case _ =>
- throwException(s"cannot call $this.asFixedPoint(binaryPoint=$binaryPoint), you must specify a known binaryPoint")
- }
- }
-
- private[core] override def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) {
- // TODO: redefine as just asFixedPoint on that, where FixedPoint.asFixedPoint just works.
- this := (that match {
- case fp: FixedPoint => fp.asSInt.asFixedPoint(this.binaryPoint)
- case _ => that.asFixedPoint(this.binaryPoint)
- })
- }
- //TODO(chick): Consider "convert" as an arithmetic conversion to UInt/SInt
-}
-
-/** Use PrivateObject to force users to specify width and binaryPoint by name
- */
-sealed trait PrivateType
-private case object PrivateObject extends PrivateType
-
-/**
- * Factory and convenience methods for the FixedPoint class
- * IMPORTANT: The API provided here is experimental and may change in the future.
- */
-object FixedPoint {
- /** Create an FixedPoint type with inferred width. */
- def apply(): FixedPoint = apply(Width(), BinaryPoint())
-
- /** Create an FixedPoint type or port with fixed width. */
- @chiselRuntimeDeprecated
- @deprecated("Use FixedPoint(width: Width, binaryPoint: BinaryPoint) example FixedPoint(16.W, 8.BP)", "chisel3")
- def apply(width: Int, binaryPoint: Int): FixedPoint = apply(Width(width), BinaryPoint(binaryPoint))
-
- /** Create an FixedPoint type or port with fixed width. */
- def apply(width: Width, binaryPoint: BinaryPoint): FixedPoint = new FixedPoint(width, binaryPoint)
-
- /** Create an FixedPoint literal with inferred width from BigInt.
- * Use PrivateObject to force users to specify width and binaryPoint by name
- */
- def fromBigInt(value: BigInt, width: Width, binaryPoint: BinaryPoint): FixedPoint = {
- apply(value, width, binaryPoint)
- }
- /** Create an FixedPoint literal with inferred width from BigInt.
- * Use PrivateObject to force users to specify width and binaryPoint by name
- */
- def fromBigInt(value: BigInt, binaryPoint: BinaryPoint = 0.BP): FixedPoint = {
- apply(value, Width(), binaryPoint)
- }
- /** Create an FixedPoint literal with inferred width from BigInt.
- * Use PrivateObject to force users to specify width and binaryPoint by name
- */
- def fromBigInt(value: BigInt, width: Int, binaryPoint: Int): FixedPoint =
- if(width == -1) {
- apply(value, Width(), BinaryPoint(binaryPoint))
- }
- else {
- apply(value, Width(width), BinaryPoint(binaryPoint))
- }
- /** Create an FixedPoint literal with inferred width from Double.
- * Use PrivateObject to force users to specify width and binaryPoint by name
- */
- @chiselRuntimeDeprecated
- @deprecated("use fromDouble(value: Double, width: Width, binaryPoint: BinaryPoint)", "chisel3")
- def fromDouble(value: Double, dummy: PrivateType = PrivateObject,
- width: Int = -1, binaryPoint: Int = 0): FixedPoint = {
- fromBigInt(
- toBigInt(value, binaryPoint), width = width, binaryPoint = binaryPoint
- )
- }
- /** Create an FixedPoint literal with inferred width from Double.
- * Use PrivateObject to force users to specify width and binaryPoint by name
- */
- def fromDouble(value: Double, width: Width, binaryPoint: BinaryPoint): FixedPoint = {
- fromBigInt(
- toBigInt(value, binaryPoint.get), width = width, binaryPoint = binaryPoint
- )
- }
-
- /** Create an FixedPoint port with specified width and binary position. */
- def apply(value: BigInt, width: Width, binaryPoint: BinaryPoint): FixedPoint = {
- val lit = FPLit(value, width, binaryPoint)
- val newLiteral = new FixedPoint(lit.width, lit.binaryPoint)
- // Ensure we have something capable of generating a name.
- lit.bindLitArg(newLiteral)
- }
-
- /**
- * How to create a bigint from a double with a specific binaryPoint
- * @param x a double value
- * @param binaryPoint a binaryPoint that you would like to use
- * @return
- */
- def toBigInt(x: Double, binaryPoint : Int): BigInt = {
- val multiplier = math.pow(2,binaryPoint )
- val result = BigInt(math.round(x * multiplier))
- result
- }
-
- /**
- * converts a bigInt with the given binaryPoint into the double representation
- * @param i a bigint
- * @param binaryPoint the implied binaryPoint of @i
- * @return
- */
- def toDouble(i: BigInt, binaryPoint : Int): Double = {
- val multiplier = math.pow(2,binaryPoint)
- val result = i.toDouble / multiplier
- result
- }
-
-}
-
-/** Data type for representing bidirectional bitvectors of a given width
- *
- * Analog support is limited to allowing wiring up of Verilog BlackBoxes with bidirectional (inout)
- * pins. There is currently no support for reading or writing of Analog types within Chisel code.
- *
- * Given that Analog is bidirectional, it is illegal to assign a direction to any Analog type. It
- * is legal to "flip" the direction (since Analog can be a member of aggregate types) which has no
- * effect.
- *
- * Analog types are generally connected using the bidirectional [[attach]] mechanism, but also
- * support limited bulkconnect `<>`. Analog types are only allowed to be bulk connected *once* in a
- * given module. This is to prevent any surprising consequences of last connect semantics.
- *
- * @note This API is experimental and subject to change
- */
-final class Analog private (private[chisel3] val width: Width) extends Element {
- require(width.known, "Since Analog is only for use in BlackBoxes, width must be known")
-
- override def toString: String = {
- s"Analog$width$bindingToString"
- }
-
- private[core] override def typeEquivalent(that: Data): Boolean =
- that.isInstanceOf[Analog] && this.width == that.width
-
- override def litOption: Option[BigInt] = None
-
- def cloneType: this.type = new Analog(width).asInstanceOf[this.type]
-
- // Used to enforce single bulk connect of Analog types, multi-attach is still okay
- // Note that this really means 1 bulk connect per Module because a port can
- // be connected in the parent module as well
- private[core] val biConnectLocs = mutable.Map.empty[RawModule, SourceInfo]
-
- // Define setter/getter pairing
- // Analog can only be bound to Ports and Wires (and Unbound)
- private[chisel3] override def bind(target: Binding, parentDirection: SpecifiedDirection) {
- SpecifiedDirection.fromParent(parentDirection, specifiedDirection) match {
- case SpecifiedDirection.Unspecified | SpecifiedDirection.Flip =>
- case x => throwException(s"Analog may not have explicit direction, got '$x'")
- }
- val targetTopBinding = target match {
- case target: TopBinding => target
- case ChildBinding(parent) => parent.topBinding
- // See https://github.com/freechipsproject/chisel3/pull/946
- case SampleElementBinding(parent) => parent.topBinding
- }
-
- // Analog counts as different directions based on binding context
- targetTopBinding match {
- case WireBinding(_) => direction = ActualDirection.Unspecified // internal wire
- case PortBinding(_) => direction = ActualDirection.Bidirectional(ActualDirection.Default)
- case x => throwException(s"Analog can only be Ports and Wires, not '$x'")
- }
- binding = target
- }
-
- override def do_asUInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
- throwException("Analog does not support asUInt")
-
- private[core] override def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions): Unit = {
- throwException("Analog does not support connectFromBits")
- }
-
- final def toPrintable: Printable = PString("Analog")
-}
-/** Object that provides factory methods for [[Analog]] objects
- *
- * @note This API is experimental and subject to change
- */
-object Analog {
- def apply(width: Width): Analog = new Analog(width)
-}
diff --git a/chiselFrontend/src/main/scala/chisel3/core/BlackBox.scala b/chiselFrontend/src/main/scala/chisel3/core/BlackBox.scala
deleted file mode 100644
index e8dc2bfe..00000000
--- a/chiselFrontend/src/main/scala/chisel3/core/BlackBox.scala
+++ /dev/null
@@ -1,172 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3.core
-
-import chisel3.internal.Builder.pushCommand
-import chisel3.internal.firrtl._
-import chisel3.internal.throwException
-import chisel3.internal.sourceinfo.{SourceInfo, UnlocatableSourceInfo}
-
-/** Parameters for BlackBoxes */
-sealed abstract class Param
-case class IntParam(value: BigInt) extends Param
-case class DoubleParam(value: Double) extends Param
-case class StringParam(value: String) extends Param
-/** Unquoted String */
-case class RawParam(value: String) extends Param
-
-abstract class BaseBlackBox extends BaseModule
-
-/** Defines a black box, which is a module that can be referenced from within
- * Chisel, but is not defined in the emitted Verilog. Useful for connecting
- * to RTL modules defined outside Chisel.
- *
- * A variant of BlackBox, this has a more consistent naming scheme in allowing
- * multiple top-level IO and does not drop the top prefix.
- *
- * @example
- * Some design require a differential input clock to clock the all design.
- * With the xilinx FPGA for example, a Verilog template named IBUFDS must be
- * integrated to use differential input:
- * {{{
- * IBUFDS #(.DIFF_TERM("TRUE"),
- * .IOSTANDARD("DEFAULT")) ibufds (
- * .IB(ibufds_IB),
- * .I(ibufds_I),
- * .O(ibufds_O)
- * );
- * }}}
- *
- * To instantiate it, a BlackBox can be used like following:
- * {{{
- * import chisel3._
- * import chisel3.experimental._
- *
- * // Example with Xilinx differential buffer IBUFDS
- * class IBUFDS extends ExtModule(Map("DIFF_TERM" -> "TRUE", // Verilog parameters
- * "IOSTANDARD" -> "DEFAULT"
- * )) {
- * val O = IO(Output(Clock()))
- * val I = IO(Input(Clock()))
- * val IB = IO(Input(Clock()))
- * }
- * }}}
- * @note The parameters API is experimental and may change
- */
-abstract class ExtModule(val params: Map[String, Param] = Map.empty[String, Param]) extends BaseBlackBox {
- private[core] override def generateComponent(): Component = {
- require(!_closed, "Can't generate module more than once")
- _closed = true
-
- val names = nameIds(classOf[ExtModule])
-
- // Name ports based on reflection
- for (port <- getModulePorts) {
- require(names.contains(port), s"Unable to name port $port in $this")
- port.setRef(ModuleIO(this, _namespace.name(names(port))))
- }
-
- // All suggestions are in, force names to every node.
- // While BlackBoxes are not supposed to have an implementation, we still need to call
- // _onModuleClose on all nodes (for example, Aggregates use it for recursive naming).
- for (id <- getIds) {
- id._onModuleClose
- }
-
- val firrtlPorts = getModulePorts map {port => Port(port, port.specifiedDirection)}
- val component = DefBlackBox(this, name, firrtlPorts, SpecifiedDirection.Unspecified, params)
- _component = Some(component)
- component
- }
-
- private[core] def initializeInParent(parentCompileOptions: CompileOptions): Unit = {
- implicit val sourceInfo = UnlocatableSourceInfo
-
- for (x <- getModulePorts) {
- pushCommand(DefInvalid(sourceInfo, x.ref))
- }
- }
-}
-
-/** Defines a black box, which is a module that can be referenced from within
- * Chisel, but is not defined in the emitted Verilog. Useful for connecting
- * to RTL modules defined outside Chisel.
- *
- * @example
- * Some design require a differential input clock to clock the all design.
- * With the xilinx FPGA for example, a Verilog template named IBUFDS must be
- * integrated to use differential input:
- * {{{
- * IBUFDS #(.DIFF_TERM("TRUE"),
- * .IOSTANDARD("DEFAULT")) ibufds (
- * .IB(ibufds_IB),
- * .I(ibufds_I),
- * .O(ibufds_O)
- * );
- * }}}
- *
- * To instantiate it, a BlackBox can be used like following:
- * {{{
- * import chisel3._
- * import chisel3.experimental._
- *
- * // Example with Xilinx differential buffer IBUFDS
- * class IBUFDS extends BlackBox(Map("DIFF_TERM" -> "TRUE", // Verilog parameters
- * "IOSTANDARD" -> "DEFAULT"
- * )) {
- * val io = IO(new Bundle {
- * val O = Output(Clock()) // IO names will be the same
- * val I = Input(Clock()) // (without 'io_' in prefix)
- * val IB = Input(Clock()) //
- * })
- * }
- * }}}
- * @note The parameters API is experimental and may change
- */
-abstract class BlackBox(val params: Map[String, Param] = Map.empty[String, Param])(implicit compileOptions: CompileOptions) extends BaseBlackBox { // scalastyle:ignore line.size.limit
- def io: Record
-
- // Allow access to bindings from the compatibility package
- protected def _compatIoPortBound() = portsContains(io) // scalastyle:ignore method.name
-
- private[core] override def generateComponent(): Component = {
- _compatAutoWrapPorts() // pre-IO(...) compatibility hack
-
- // Restrict IO to just io, clock, and reset
- require(io != null, "BlackBox must have io")
- require(portsContains(io), "BlackBox must have io wrapped in IO(...)")
- require(portsSize == 1, "BlackBox must only have io as IO")
-
- require(!_closed, "Can't generate module more than once")
- _closed = true
-
- val namedPorts = io.elements.toSeq.reverse // ListMaps are stored in reverse order
-
- // setRef is not called on the actual io.
- // There is a risk of user improperly attempting to connect directly with io
- // Long term solution will be to define BlackBox IO differently as part of
- // it not descending from the (current) Module
- for ((name, port) <- namedPorts) {
- port.setRef(ModuleIO(this, _namespace.name(name)))
- }
-
- // We need to call forceName and onModuleClose on all of the sub-elements
- // of the io bundle, but NOT on the io bundle itself.
- // Doing so would cause the wrong names to be assigned, since their parent
- // is now the module itself instead of the io bundle.
- for (id <- getIds; if id ne io) {
- id._onModuleClose
- }
-
- val firrtlPorts = namedPorts map {namedPort => Port(namedPort._2, namedPort._2.specifiedDirection)}
- val component = DefBlackBox(this, name, firrtlPorts, io.specifiedDirection, params)
- _component = Some(component)
- component
- }
-
- private[core] def initializeInParent(parentCompileOptions: CompileOptions): Unit = {
- for ((_, port) <- io.elements) {
- pushCommand(DefInvalid(UnlocatableSourceInfo, port.ref))
- }
- }
-}
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Clock.scala b/chiselFrontend/src/main/scala/chisel3/core/Clock.scala
deleted file mode 100644
index 364ac5aa..00000000
--- a/chiselFrontend/src/main/scala/chisel3/core/Clock.scala
+++ /dev/null
@@ -1,38 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3.core
-
-import chisel3.internal.Builder.{pushOp}
-import chisel3.internal.firrtl._
-import chisel3.internal.sourceinfo._
-import chisel3.internal.firrtl.PrimOp.AsUIntOp
-
-object Clock {
- def apply(): Clock = new Clock
-}
-
-// TODO: Document this.
-sealed class Clock(private[chisel3] val width: Width = Width(1)) extends Element {
- override def toString: String = s"Clock$bindingToString"
-
- def cloneType: this.type = Clock().asInstanceOf[this.type]
-
- private[core] def typeEquivalent(that: Data): Boolean =
- this.getClass == that.getClass
-
- override def connect(that: Data)(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): Unit = that match { // scalastyle:ignore line.size.limit
- case _: Clock => super.connect(that)(sourceInfo, connectCompileOptions)
- case _ => super.badConnect(that)(sourceInfo)
- }
-
- override def litOption: Option[BigInt] = None
-
- /** Not really supported */
- def toPrintable: Printable = PString("CLOCK")
-
- override def do_asUInt(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): UInt = pushOp(DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref)) // scalastyle:ignore line.size.limit
- private[core] override def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions): Unit = {
- this := that
- }
-}
diff --git a/chiselFrontend/src/main/scala/chisel3/core/CompileOptions.scala b/chiselFrontend/src/main/scala/chisel3/core/CompileOptions.scala
deleted file mode 100644
index a2f94e51..00000000
--- a/chiselFrontend/src/main/scala/chisel3/core/CompileOptions.scala
+++ /dev/null
@@ -1,76 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3.core
-
-import scala.language.experimental.macros
-import scala.reflect.macros.blackbox.Context
-
-trait CompileOptions {
- // Should Record connections require a strict match of fields.
- // If true and the same fields aren't present in both source and sink, a MissingFieldException,
- // MissingLeftFieldException, or MissingRightFieldException will be thrown.
- val connectFieldsMustMatch: Boolean
- // When creating an object that takes a type argument, the argument must be unbound (a pure type).
- val declaredTypeMustBeUnbound: Boolean
- // If a connection operator fails, don't try the connection with the operands (source and sink) reversed.
- val dontTryConnectionsSwapped: Boolean
- // If connection directionality is not explicit, do not use heuristics to attempt to determine it.
- val dontAssumeDirectionality: Boolean
- // Check that referenced Data have actually been declared.
- val checkSynthesizable: Boolean
- // Require explicit assignment of DontCare to generate "x is invalid"
- val explicitInvalidate: Boolean
-}
-
-object CompileOptions {
- // Provides a low priority Strict default. Can be overridden by importing the NotStrict option.
- // Implemented as a macro to prevent this from being used inside chisel core.
- implicit def materialize: CompileOptions = macro materialize_impl
-
- def materialize_impl(c: Context): c.Tree = {
- import c.universe._
- q"_root_.chisel3.core.ExplicitCompileOptions.Strict"
- }
-}
-
-object ExplicitCompileOptions {
- case class CompileOptionsClass (
- // Should Record connections require a strict match of fields.
- // If true and the same fields aren't present in both source and sink, a MissingFieldException,
- // MissingLeftFieldException, or MissingRightFieldException will be thrown.
- val connectFieldsMustMatch: Boolean,
- // When creating an object that takes a type argument, the argument must be unbound (a pure type).
- val declaredTypeMustBeUnbound: Boolean,
- // If a connection operator fails, don't try the connection with the operands (source and sink) reversed.
- val dontTryConnectionsSwapped: Boolean,
- // If connection directionality is not explicit, do not use heuristics to attempt to determine it.
- val dontAssumeDirectionality: Boolean,
- // Check that referenced Data have actually been declared.
- val checkSynthesizable: Boolean,
- // Require an explicit DontCare assignment to generate a firrtl DefInvalid
- val explicitInvalidate: Boolean
- ) extends CompileOptions
-
- // Collection of "not strict" connection compile options.
- // These provide compatibility with existing code.
- // import chisel3.core.ExplicitCompileOptions.NotStrict
- implicit val NotStrict = new CompileOptionsClass (
- connectFieldsMustMatch = false,
- declaredTypeMustBeUnbound = false,
- dontTryConnectionsSwapped = false,
- dontAssumeDirectionality = false,
- checkSynthesizable = false,
- explicitInvalidate = false
- )
-
- // Collection of "strict" connection compile options, preferred for new code.
- // import chisel3.core.ExplicitCompileOptions.Strict
- implicit val Strict = new CompileOptionsClass (
- connectFieldsMustMatch = true,
- declaredTypeMustBeUnbound = true,
- dontTryConnectionsSwapped = true,
- dontAssumeDirectionality = true,
- checkSynthesizable = true,
- explicitInvalidate = true
- )
-}
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala
deleted file mode 100644
index 3ce79786..00000000
--- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala
+++ /dev/null
@@ -1,742 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3.core
-
-import scala.language.experimental.macros
-
-import chisel3.internal._
-import chisel3.internal.Builder.{pushCommand, pushOp}
-import chisel3.internal.firrtl._
-import chisel3.internal.sourceinfo.{SourceInfo, SourceInfoTransform, UnlocatableSourceInfo, DeprecatedSourceInfo}
-import chisel3.SourceInfoDoc
-import chisel3.core.BiConnect.DontCareCantBeSink
-
-/** User-specified directions.
- */
-sealed abstract class SpecifiedDirection
-object SpecifiedDirection {
- /** Default user direction, also meaning 'not-flipped'
- */
- case object Unspecified extends SpecifiedDirection
- /** Node and its children are forced as output
- */
- case object Output extends SpecifiedDirection
- /** Node and its children are forced as inputs
- */
- case object Input extends SpecifiedDirection
- /** Mainly for containers, children are flipped.
- */
- case object Flip extends SpecifiedDirection
-
- def flip(dir: SpecifiedDirection): SpecifiedDirection = dir match {
- case Unspecified => Flip
- case Flip => Unspecified
- case Output => Input
- case Input => Output
- }
-
- /** Returns the effective SpecifiedDirection of this node given the parent's effective SpecifiedDirection
- * and the user-specified SpecifiedDirection of this node.
- */
- def fromParent(parentDirection: SpecifiedDirection, thisDirection: SpecifiedDirection): SpecifiedDirection =
- (parentDirection, thisDirection) match {
- case (SpecifiedDirection.Output, _) => SpecifiedDirection.Output
- case (SpecifiedDirection.Input, _) => SpecifiedDirection.Input
- case (SpecifiedDirection.Unspecified, thisDirection) => thisDirection
- case (SpecifiedDirection.Flip, thisDirection) => SpecifiedDirection.flip(thisDirection)
- }
-}
-
-/** Resolved directions for both leaf and container nodes, only visible after
- * a node is bound (since higher-level specifications like Input and Output
- * can override directions).
- */
-sealed abstract class ActualDirection
-
-object ActualDirection {
- /** The object does not exist / is empty and hence has no direction
- */
- case object Empty extends ActualDirection
-
- /** Undirectioned, struct-like
- */
- case object Unspecified extends ActualDirection
- /** Output element, or container with all outputs (even if forced)
- */
- case object Output extends ActualDirection
- /** Input element, or container with all inputs (even if forced)
- */
- case object Input extends ActualDirection
-
- sealed abstract class BidirectionalDirection
- case object Default extends BidirectionalDirection
- case object Flipped extends BidirectionalDirection
-
- case class Bidirectional(dir: BidirectionalDirection) extends ActualDirection
-
- def fromSpecified(direction: SpecifiedDirection): ActualDirection = direction match {
- case SpecifiedDirection.Unspecified | SpecifiedDirection.Flip => ActualDirection.Unspecified
- case SpecifiedDirection.Output => ActualDirection.Output
- case SpecifiedDirection.Input => ActualDirection.Input
- }
-
- /** Determine the actual binding of a container given directions of its children.
- * Returns None in the case of mixed specified / unspecified directionality.
- */
- def fromChildren(childDirections: Set[ActualDirection], containerDirection: SpecifiedDirection):
- Option[ActualDirection] = {
- if (childDirections == Set()) { // Sadly, Scala can't do set matching
- ActualDirection.fromSpecified(containerDirection) match {
- case ActualDirection.Unspecified => Some(ActualDirection.Empty) // empty direction if relative / no direction
- case dir => Some(dir) // use assigned direction if specified
- }
- } else if (childDirections == Set(ActualDirection.Unspecified)) {
- Some(ActualDirection.Unspecified)
- } else if (childDirections == Set(ActualDirection.Input)) {
- Some(ActualDirection.Input)
- } else if (childDirections == Set(ActualDirection.Output)) {
- Some(ActualDirection.Output)
- } else if (childDirections subsetOf
- Set(ActualDirection.Output, ActualDirection.Input,
- ActualDirection.Bidirectional(ActualDirection.Default),
- ActualDirection.Bidirectional(ActualDirection.Flipped))) {
- containerDirection match {
- case SpecifiedDirection.Unspecified => Some(ActualDirection.Bidirectional(ActualDirection.Default))
- case SpecifiedDirection.Flip => Some(ActualDirection.Bidirectional(ActualDirection.Flipped))
- case _ => throw new RuntimeException("Unexpected forced Input / Output")
- }
- } else {
- None
- }
- }
-}
-
-object debug { // scalastyle:ignore object.name
- @chiselRuntimeDeprecated
- @deprecated("debug doesn't do anything in Chisel3 as no pruning happens in the frontend", "chisel3")
- def apply (arg: Data): Data = arg
-}
-
-/** Experimental hardware construction reflection API
- */
-object DataMirror {
- def widthOf(target: Data): Width = target.width
- def specifiedDirectionOf(target: Data): SpecifiedDirection = target.specifiedDirection
- def directionOf(target: Data): ActualDirection = {
- requireIsHardware(target, "node requested directionality on")
- target.direction
- }
-
- // Returns the top-level module ports
- // TODO: maybe move to something like Driver or DriverUtils, since this is mainly for interacting
- // with compiled artifacts (vs. elaboration-time reflection)?
- def modulePorts(target: BaseModule): Seq[(String, Data)] = target.getChiselPorts
-
- // Returns all module ports with underscore-qualified names
- def fullModulePorts(target: BaseModule): Seq[(String, Data)] = {
- def getPortNames(name: String, data: Data): Seq[(String, Data)] = Seq(name -> data) ++ (data match {
- case _: Element => Seq()
- case r: Record => r.elements.toSeq flatMap { case (eltName, elt) => getPortNames(s"${name}_${eltName}", elt) }
- case v: Vec[_] => v.zipWithIndex flatMap { case (elt, index) => getPortNames(s"${name}_${index}", elt) }
- })
- modulePorts(target).flatMap { case (name, data) =>
- getPortNames(name, data).toList
- }
- }
-
- // Internal reflection-style APIs, subject to change and removal whenever.
- object internal { // scalastyle:ignore object.name
- def isSynthesizable(target: Data): Boolean = target.isSynthesizable
- // For those odd cases where you need to care about object reference and uniqueness
- def chiselTypeClone[T<:Data](target: Data): T = {
- target.cloneTypeFull.asInstanceOf[T]
- }
- }
-}
-
-/** Creates a clone of the super-type of the input elements. Super-type is defined as:
- * - for Bits type of the same class: the cloned type of the largest width
- * - Bools are treated as UInts
- * - For other types of the same class are are the same: clone of any of the elements
- * - Otherwise: fail
- */
-//scalastyle:off cyclomatic.complexity
-private[core] object cloneSupertype {
- def apply[T <: Data](elts: Seq[T], createdType: String)(implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions): T = {
- require(!elts.isEmpty, s"can't create $createdType with no inputs")
-
- val filteredElts = elts.filter(_ != DontCare)
- require(!filteredElts.isEmpty, s"can't create $createdType with only DontCare inputs")
-
- if (filteredElts.head.isInstanceOf[Bits]) {
- val model: T = filteredElts reduce { (elt1: T, elt2: T) => ((elt1, elt2) match {
- case (elt1: Bool, elt2: Bool) => elt1
- case (elt1: Bool, elt2: UInt) => elt2 // TODO: what happens with zero width UInts?
- case (elt1: UInt, elt2: Bool) => elt1 // TODO: what happens with zero width UInts?
- case (elt1: UInt, elt2: UInt) =>
- // TODO: perhaps redefine Widths to allow >= op?
- if (elt1.width == (elt1.width max elt2.width)) elt1 else elt2
- case (elt1: SInt, elt2: SInt) => if (elt1.width == (elt1.width max elt2.width)) elt1 else elt2
- case (elt1: FixedPoint, elt2: FixedPoint) => {
- (elt1.binaryPoint, elt2.binaryPoint, elt1.width, elt2.width) match {
- case (KnownBinaryPoint(bp1), KnownBinaryPoint(bp2), KnownWidth(w1), KnownWidth(w2)) =>
- val maxBinaryPoint = bp1 max bp2
- val maxIntegerWidth = (w1 - bp1) max (w2 - bp2)
- FixedPoint((maxIntegerWidth + maxBinaryPoint).W, (maxBinaryPoint).BP)
- case (KnownBinaryPoint(bp1), KnownBinaryPoint(bp2), _, _) =>
- FixedPoint(Width(), (bp1 max bp2).BP)
- case _ => FixedPoint()
- }
- }
- case (elt1, elt2) =>
- throw new AssertionError(
- s"can't create $createdType with heterogeneous types ${elt1.getClass} and ${elt2.getClass}")
- }).asInstanceOf[T] }
- model.cloneTypeFull
- }
- else {
- for (elt <- filteredElts.tail) {
- require(elt.getClass == filteredElts.head.getClass,
- s"can't create $createdType with heterogeneous types ${filteredElts.head.getClass} and ${elt.getClass}")
- require(elt typeEquivalent filteredElts.head,
- s"can't create $createdType with non-equivalent types ${filteredElts.head} and ${elt}")
- }
- filteredElts.head.cloneTypeFull
- }
- }
-}
-
-/** Returns the chisel type of a hardware object, allowing other hardware to be constructed from it.
- */
-object chiselTypeOf {
- def apply[T <: Data](target: T): T = {
- requireIsHardware(target)
- target.cloneTypeFull.asInstanceOf[T]
- }
-}
-
-/**
-* Input, Output, and Flipped are used to define the directions of Module IOs.
-*
-* Note that they currently clone their source argument, including its bindings.
-*
-* Thus, an error will be thrown if these are used on bound Data
-*/
-object Input {
- def apply[T<:Data](source: T)(implicit compileOptions: CompileOptions): T = {
- if (compileOptions.checkSynthesizable) {
- requireIsChiselType(source)
- }
- val out = source.cloneType.asInstanceOf[T]
- out.specifiedDirection = SpecifiedDirection.Input
- out
- }
-}
-object Output {
- def apply[T<:Data](source: T)(implicit compileOptions: CompileOptions): T = {
- if (compileOptions.checkSynthesizable) {
- requireIsChiselType(source)
- }
- val out = source.cloneType.asInstanceOf[T]
- out.specifiedDirection = SpecifiedDirection.Output
- out
- }
-}
-object Flipped {
- def apply[T<:Data](source: T)(implicit compileOptions: CompileOptions): T = {
- if (compileOptions.checkSynthesizable) {
- requireIsChiselType(source)
- }
- val out = source.cloneType.asInstanceOf[T]
- out.specifiedDirection = SpecifiedDirection.flip(source.specifiedDirection)
- out
- }
-}
-
-/** This forms the root of the type system for wire data types. The data value
- * must be representable as some number (need not be known at Chisel compile
- * time) of bits, and must have methods to pack / unpack structured data to /
- * from bits.
- *
- * @groupdesc Connect Utilities for connecting hardware components
- * @define coll data
- */
-abstract class Data extends HasId with NamedComponent with SourceInfoDoc { // scalastyle:ignore number.of.methods
- // This is a bad API that punches through object boundaries.
- @deprecated("pending removal once all instances replaced", "chisel3")
- private[chisel3] def flatten: IndexedSeq[Element] = {
- this match {
- case elt: Aggregate => elt.getElements.toIndexedSeq flatMap {_.flatten}
- case elt: Element => IndexedSeq(elt)
- case elt => throwException(s"Cannot flatten type ${elt.getClass}")
- }
- }
-
- // User-specified direction, local at this node only.
- // Note that the actual direction of this node can differ from child and parent specifiedDirection.
- private var _specifiedDirection: SpecifiedDirection = SpecifiedDirection.Unspecified
- private[chisel3] def specifiedDirection: SpecifiedDirection = _specifiedDirection
- private[core] def specifiedDirection_=(direction: SpecifiedDirection) = {
- if (_specifiedDirection != SpecifiedDirection.Unspecified) {
- this match {
- // Anything flies in compatibility mode
- case t: Record if !t.compileOptions.dontAssumeDirectionality =>
- case _ => throw Binding.RebindingException(s"Attempted reassignment of user-specified direction to $this")
- }
- }
- _specifiedDirection = direction
- }
-
- /** This overwrites a relative SpecifiedDirection with an explicit one, and is used to implement
- * the compatibility layer where, at the elements, Flip is Input and unspecified is Output.
- * DO NOT USE OUTSIDE THIS PURPOSE. THIS OPERATION IS DANGEROUS!
- */
- private[core] def _assignCompatibilityExplicitDirection: Unit = { // scalastyle:off method.name
- (this, _specifiedDirection) match {
- case (_: Analog, _) => // nothing to do
- case (_, SpecifiedDirection.Unspecified) => _specifiedDirection = SpecifiedDirection.Output
- case (_, SpecifiedDirection.Flip) => _specifiedDirection = SpecifiedDirection.Input
- case (_, SpecifiedDirection.Input | SpecifiedDirection.Output) => // nothing to do
- }
- }
-
- // Binding stores information about this node's position in the hardware graph.
- // This information is supplemental (more than is necessary to generate FIRRTL) and is used to
- // perform checks in Chisel, where more informative error messages are possible.
- private var _binding: Option[Binding] = None
- // Only valid after node is bound (synthesizable), crashes otherwise
- protected[core] def binding: Option[Binding] = _binding
- protected def binding_=(target: Binding) {
- if (_binding.isDefined) {
- throw Binding.RebindingException(s"Attempted reassignment of binding to $this")
- }
- _binding = Some(target)
- }
-
- // Similar to topBindingOpt except it explicitly excludes SampleElements which are bound but not
- // hardware
- private[core] final def isSynthesizable: Boolean = _binding.map {
- case ChildBinding(parent) => parent.isSynthesizable
- case _: TopBinding => true
- case _: SampleElementBinding[_] => false
- }.getOrElse(false)
-
- private[core] def topBindingOpt: Option[TopBinding] = _binding.flatMap {
- case ChildBinding(parent) => parent.topBindingOpt
- case bindingVal: TopBinding => Some(bindingVal)
- case SampleElementBinding(parent) => parent.topBindingOpt
- }
-
- private[core] def topBinding: TopBinding = topBindingOpt.get
-
- /** Binds this node to the hardware graph.
- * parentDirection is the direction of the parent node, or Unspecified (default) if the target
- * node is the top-level.
- * binding and direction are valid after this call completes.
- */
- private[chisel3] def bind(target: Binding, parentDirection: SpecifiedDirection = SpecifiedDirection.Unspecified)
-
- // Both _direction and _resolvedUserDirection are saved versions of computed variables (for
- // efficiency, avoid expensive recomputation of frequent operations).
- // Both are only valid after binding is set.
-
- // Direction of this node, accounting for parents (force Input / Output) and children.
- private var _direction: Option[ActualDirection] = None
-
- private[chisel3] def direction: ActualDirection = _direction.get
- private[core] def direction_=(actualDirection: ActualDirection) {
- if (_direction.isDefined) {
- throw Binding.RebindingException(s"Attempted reassignment of resolved direction to $this")
- }
- _direction = Some(actualDirection)
- }
-
- // User-friendly representation of the binding as a helper function for toString.
- // Provides a unhelpful fallback for literals, which should have custom rendering per
- // Data-subtype.
- // TODO Is this okay for sample_element? It *shouldn't* be visible to users
- protected def bindingToString: String = topBindingOpt match {
- case None => ""
- case Some(OpBinding(enclosure)) => s"(OpResult in ${enclosure.desiredName})"
- case Some(MemoryPortBinding(enclosure)) => s"(MemPort in ${enclosure.desiredName})"
- case Some(PortBinding(enclosure)) if !enclosure.isClosed => s"(IO in unelaborated ${enclosure.desiredName})"
- case Some(PortBinding(enclosure)) if enclosure.isClosed =>
- DataMirror.fullModulePorts(enclosure).find(_._2 eq this) match {
- case Some((name, _)) => s"(IO $name in ${enclosure.desiredName})"
- case None => s"(IO (unknown) in ${enclosure.desiredName})"
- }
- case Some(RegBinding(enclosure)) => s"(Reg in ${enclosure.desiredName})"
- case Some(WireBinding(enclosure)) => s"(Wire in ${enclosure.desiredName})"
- case Some(DontCareBinding()) => s"(DontCare)"
- case Some(ElementLitBinding(litArg)) => s"(unhandled literal)"
- case Some(BundleLitBinding(litMap)) => s"(unhandled bundle literal)"
- }
-
- // Return ALL elements at root of this type.
- // Contasts with flatten, which returns just Bits
- // TODO: refactor away this, this is outside the scope of Data
- private[chisel3] def allElements: Seq[Element]
-
- private[core] def badConnect(that: Data)(implicit sourceInfo: SourceInfo): Unit =
- throwException(s"cannot connect ${this} and ${that}")
- private[chisel3] def connect(that: Data)(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): Unit = { // scalastyle:ignore line.size.limit
- if (connectCompileOptions.checkSynthesizable) {
- requireIsHardware(this, "data to be connected")
- requireIsHardware(that, "data to be connected")
- this.topBinding match {
- case _: ReadOnlyBinding => throwException(s"Cannot reassign to read-only $this")
- case _ => // fine
- }
- try {
- MonoConnect.connect(sourceInfo, connectCompileOptions, this, that, Builder.forcedUserModule)
- } catch {
- case MonoConnect.MonoConnectException(message) =>
- throwException(
- s"Connection between sink ($this) and source ($that) failed @$message"
- )
- }
- } else {
- this legacyConnect that
- }
- }
- private[chisel3] def bulkConnect(that: Data)(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): Unit = { // scalastyle:ignore line.size.limit
- if (connectCompileOptions.checkSynthesizable) {
- requireIsHardware(this, s"data to be bulk-connected")
- requireIsHardware(that, s"data to be bulk-connected")
- (this.topBinding, that.topBinding) match {
- case (_: ReadOnlyBinding, _: ReadOnlyBinding) => throwException(s"Both $this and $that are read-only")
- // DontCare cannot be a sink (LHS)
- case (_: DontCareBinding, _) => throw DontCareCantBeSink
- case _ => // fine
- }
- try {
- BiConnect.connect(sourceInfo, connectCompileOptions, this, that, Builder.forcedUserModule)
- } catch {
- case BiConnect.BiConnectException(message) =>
- throwException(
- s"Connection between left ($this) and source ($that) failed @$message"
- )
- }
- } else {
- this legacyConnect that
- }
- }
-
- /** Whether this Data has the same model ("data type") as that Data.
- * Data subtypes should overload this with checks against their own type.
- */
- private[core] def typeEquivalent(that: Data): Boolean
-
- // Internal API: returns a ref that can be assigned to, if consistent with the binding
- private[chisel3] def lref: Node = {
- requireIsHardware(this)
- topBindingOpt match {
- case Some(binding: ReadOnlyBinding) => throwException(s"internal error: attempted to generate LHS ref to ReadOnlyBinding $binding") // scalastyle:ignore line.size.limit
- case Some(binding: TopBinding) => Node(this)
- case opt => throwException(s"internal error: unknown binding $opt in generating LHS ref")
- }
- }
-
-
- // Internal API: returns a ref, if bound. Literals should override this as needed.
- private[chisel3] def ref: Arg = {
- requireIsHardware(this)
- topBindingOpt match {
- case Some(binding: LitBinding) => throwException(s"internal error: can't handle literal binding $binding")
- case Some(binding: TopBinding) => Node(this)
- case opt => throwException(s"internal error: unknown binding $opt in generating LHS ref")
- }
- }
-
- private[chisel3] def width: Width
- private[core] def legacyConnect(that: Data)(implicit sourceInfo: SourceInfo): Unit
-
- /** Internal API; Chisel users should look at chisel3.chiselTypeOf(...).
- *
- * cloneType must be defined for any Chisel object extending Data.
- * It is responsible for constructing a basic copy of the object being cloned.
- *
- * @return a copy of the object.
- */
- def cloneType: this.type
-
- /** Internal API; Chisel users should look at chisel3.chiselTypeOf(...).
- *
- * Returns a copy of this data type, with hardware bindings (if any) removed.
- * Directionality data is still preserved.
- */
- private[chisel3] def cloneTypeFull: this.type = {
- val clone = this.cloneType.asInstanceOf[this.type] // get a fresh object, without bindings
- // Only the top-level direction needs to be fixed up, cloneType should do the rest
- clone.specifiedDirection = specifiedDirection
- clone
- }
-
- /** Connect this $coll to that $coll mono-directionally and element-wise.
- *
- * This uses the [[MonoConnect]] algorithm.
- *
- * @param that the $coll to connect to
- * @group Connect
- */
- final def := (that: Data)(implicit sourceInfo: SourceInfo, connectionCompileOptions: CompileOptions): Unit = this.connect(that)(sourceInfo, connectionCompileOptions) // scalastyle:ignore line.size.limit
-
- /** Connect this $coll to that $coll bi-directionally and element-wise.
- *
- * This uses the [[BiConnect]] algorithm.
- *
- * @param that the $coll to connect to
- * @group Connect
- */
- final def <> (that: Data)(implicit sourceInfo: SourceInfo, connectionCompileOptions: CompileOptions): Unit = this.bulkConnect(that)(sourceInfo, connectionCompileOptions) // scalastyle:ignore line.size.limit
-
- @chiselRuntimeDeprecated
- @deprecated("litArg is deprecated, use litOption or litTo*Option", "chisel3.2")
- def litArg(): Option[LitArg] = topBindingOpt match {
- case Some(ElementLitBinding(litArg)) => Some(litArg)
- case Some(BundleLitBinding(litMap)) => None // this API does not support Bundle literals
- case _ => None
- }
-
- def isLit(): Boolean = litArg.isDefined
-
- /**
- * If this is a literal that is representable as bits, returns the value as a BigInt.
- * If not a literal, or not representable as bits (for example, is or contains Analog), returns None.
- */
- def litOption(): Option[BigInt]
-
- /**
- * Returns the literal value if this is a literal that is representable as bits, otherwise crashes.
- */
- def litValue(): BigInt = litOption.get
-
- /** Returns the width, in bits, if currently known. */
- final def getWidth: Int =
- if (isWidthKnown) width.get else throwException(s"Width of $this is unknown!")
- /** Returns whether the width is currently known. */
- final def isWidthKnown: Boolean = width.known
- /** Returns Some(width) if the width is known, else None. */
- final def widthOption: Option[Int] = if (isWidthKnown) Some(getWidth) else None
-
- /** Packs the value of this object as plain Bits.
- *
- * This performs the inverse operation of fromBits(Bits).
- */
- @chiselRuntimeDeprecated
- @deprecated("Best alternative, .asUInt()", "chisel3")
- def toBits(implicit compileOptions: CompileOptions): UInt = do_asUInt(DeprecatedSourceInfo, compileOptions)
-
- /** Does a reinterpret cast of the bits in this node into the format that provides.
- * Returns a new Wire of that type. Does not modify existing nodes.
- *
- * x.asTypeOf(that) performs the inverse operation of x := that.toBits.
- *
- * @note bit widths are NOT checked, may pad or drop bits from input
- * @note that should have known widths
- */
- def asTypeOf[T <: Data](that: T): T = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_asTypeOf[T <: Data](that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
- val thatCloned = Wire(that.cloneTypeFull)
- thatCloned.connectFromBits(this.asUInt())
- thatCloned
- }
-
- /** Assigns this node from Bits type. Internal implementation for asTypeOf.
- */
- private[core] def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions): Unit
-
- /** Reinterpret cast to UInt.
- *
- * @note value not guaranteed to be preserved: for example, a SInt of width
- * 3 and value -1 (0b111) would become an UInt with value 7
- * @note Aggregates are recursively packed with the first element appearing
- * in the least-significant bits of the result.
- */
- final def asUInt(): UInt = macro SourceInfoTransform.noArg
-
- /** @group SourceInfoTransformMacro */
- def do_asUInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt
-
- /** Default pretty printing */
- def toPrintable: Printable
-}
-
-trait WireFactory {
- /** Construct a [[Wire]] from a type template
- * @param t The template from which to construct this wire
- */
- def apply[T <: Data](t: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
- if (compileOptions.declaredTypeMustBeUnbound) {
- requireIsChiselType(t, "wire type")
- }
- val x = t.cloneTypeFull
-
- // Bind each element of x to being a Wire
- x.bind(WireBinding(Builder.forcedUserModule))
-
- pushCommand(DefWire(sourceInfo, x))
- if (!compileOptions.explicitInvalidate) {
- pushCommand(DefInvalid(sourceInfo, x.ref))
- }
-
- x
- }
-}
-
-/** Utility for constructing hardware wires
- *
- * The width of a `Wire` (inferred or not) is copied from the type template
- * {{{
- * val w0 = Wire(UInt()) // width is inferred
- * val w1 = Wire(UInt(8.W)) // width is set to 8
- *
- * val w2 = Wire(Vec(4, UInt())) // width is inferred
- * val w3 = Wire(Vec(4, UInt(8.W))) // width of each element is set to 8
- *
- * class MyBundle {
- * val unknown = UInt()
- * val known = UInt(8.W)
- * }
- * val w4 = Wire(new MyBundle)
- * // Width of w4.unknown is inferred
- * // Width of w4.known is set to 8
- * }}}
- *
- */
-object Wire extends WireFactory
-
-
-/** Utility for constructing hardware wires with a default connection
- *
- * The two forms of `WireDefault` differ in how the type and width of the resulting [[Wire]] are
- * specified.
- *
- * ==Single Argument==
- * The single argument form uses the argument to specify both the type and default connection. For
- * non-literal [[Bits]], the width of the [[Wire]] will be inferred. For literal [[Bits]] and all
- * non-Bits arguments, the type will be copied from the argument. See the following examples for
- * more details:
- *
- * 1. Literal [[Bits]] initializer: width will be set to match
- * {{{
- * val w1 = WireDefault(1.U) // width will be inferred to be 1
- * val w2 = WireDefault(1.U(8.W)) // width is set to 8
- * }}}
- *
- * 2. Non-Literal [[Element]] initializer - width will be inferred
- * {{{
- * val x = Wire(UInt())
- * val y = Wire(UInt(8.W))
- * val w1 = WireDefault(x) // width will be inferred
- * val w2 = WireDefault(y) // width will be inferred
- * }}}
- *
- * 3. [[Aggregate]] initializer - width will be set to match the aggregate
- *
- * {{{
- * class MyBundle {
- * val unknown = UInt()
- * val known = UInt(8.W)
- * }
- * val w1 = Wire(new MyBundle)
- * val w2 = WireDefault(w1)
- * // Width of w2.unknown is inferred
- * // Width of w2.known is set to 8
- * }}}
- *
- * ==Double Argument==
- * The double argument form allows the type of the [[Wire]] and the default connection to be
- * specified independently.
- *
- * The width inference semantics for `WireDefault` with two arguments match those of [[Wire]]. The
- * first argument to `WireDefault` is the type template which defines the width of the `Wire` in
- * exactly the same way as the only argument to [[Wire]].
- *
- * More explicitly, you can reason about `WireDefault` with multiple arguments as if it were defined
- * as:
- * {{{
- * def WireDefault[T <: Data](t: T, init: T): T = {
- * val x = Wire(t)
- * x := init
- * x
- * }
- * }}}
- *
- * @note The `Default` in `WireDefault` refers to a `default` connection. This is in contrast to
- * [[RegInit]] where the `Init` refers to a value on reset.
- */
-object WireDefault {
-
- private def applyImpl[T <: Data](t: T, init: Data)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { // scalastyle:ignore line.size.limit
- implicit val noSourceInfo = UnlocatableSourceInfo
- val x = Wire(t)
- requireIsHardware(init, "wire initializer")
- x := init
- x
- }
-
- /** Construct a [[Wire]] with a type template and a [[chisel3.DontCare]] default
- * @param t The type template used to construct this [[Wire]]
- * @param init The default connection to this [[Wire]], can only be [[DontCare]]
- * @note This is really just a specialized form of `apply[T <: Data](t: T, init: T): T` with [[DontCare]] as `init`
- */
- def apply[T <: Data](t: T, init: DontCare.type)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { // scalastyle:ignore line.size.limit
- applyImpl(t, init)
- }
-
- /** Construct a [[Wire]] with a type template and a default connection
- * @param t The type template used to construct this [[Wire]]
- * @param init The hardware value that will serve as the default value
- */
- def apply[T <: Data](t: T, init: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
- applyImpl(t, init)
- }
-
- /** Construct a [[Wire]] with a default connection
- * @param init The hardware value that will serve as a type template and default value
- */
- def apply[T <: Data](init: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
- val model = (init match {
- // If init is a literal without forced width OR any non-literal, let width be inferred
- case init: Bits if !init.litIsForcedWidth.getOrElse(false) => init.cloneTypeWidth(Width())
- case _ => init.cloneTypeFull
- }).asInstanceOf[T]
- apply(model, init)
- }
-}
-
-/** RHS (source) for Invalidate API.
- * Causes connection logic to emit a DefInvalid when connected to an output port (or wire).
- */
-private[chisel3] object DontCare extends Element {
- // This object should be initialized before we execute any user code that refers to it,
- // otherwise this "Chisel" object will end up on the UserModule's id list.
- // We make it private to chisel3 so it has to be accessed through the package object.
-
- private[chisel3] override val width: Width = UnknownWidth()
-
- bind(DontCareBinding(), SpecifiedDirection.Output)
- override def cloneType: this.type = DontCare
-
- override def toString: String = "DontCare()"
-
- override def litOption: Option[BigInt] = None
-
- def toPrintable: Printable = PString("DONTCARE")
-
- private[core] def connectFromBits(that: chisel3.core.Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Unit = { // scalastyle:ignore line.size.limit
- Builder.error("connectFromBits: DontCare cannot be a connection sink (LHS)")
- }
-
- def do_asUInt(implicit sourceInfo: chisel3.internal.sourceinfo.SourceInfo, compileOptions: CompileOptions): chisel3.core.UInt = { // scalastyle:ignore line.size.limit
- Builder.error("DontCare does not have a UInt representation")
- 0.U
- }
- // DontCare's only match themselves.
- private[core] def typeEquivalent(that: chisel3.core.Data): Boolean = that == DontCare
-}
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Mem.scala b/chiselFrontend/src/main/scala/chisel3/core/Mem.scala
deleted file mode 100644
index d44178ad..00000000
--- a/chiselFrontend/src/main/scala/chisel3/core/Mem.scala
+++ /dev/null
@@ -1,216 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3.core
-
-import scala.language.experimental.macros
-
-import chisel3.internal._
-import chisel3.internal.Builder.pushCommand
-import chisel3.internal.firrtl._
-import chisel3.internal.sourceinfo.{SourceInfo, SourceInfoTransform, UnlocatableSourceInfo, MemTransform}
-import chisel3.SourceInfoDoc
-
-object Mem {
- // scalastyle:off line.size.limit
- @chiselRuntimeDeprecated
- @deprecated("Mem argument order should be size, t; this will be removed by the official release", "chisel3")
- def apply[T <: Data](t: T, size: BigInt)(implicit compileOptions: CompileOptions): Mem[T] = do_apply(size, t)(UnlocatableSourceInfo, compileOptions)
-
- // scalastyle:off line.size.limit
- @chiselRuntimeDeprecated
- @deprecated("Mem argument order should be size, t; this will be removed by the official release", "chisel3")
- def apply[T <: Data](t: T, size: Int)(implicit compileOptions: CompileOptions): Mem[T] = do_apply(size, t)(UnlocatableSourceInfo, compileOptions)
-
- /** Creates a combinational/asynchronous-read, sequential/synchronous-write [[Mem]].
- *
- * @param size number of elements in the memory
- * @param t data type of memory element
- */
- def apply[T <: Data](size: BigInt, t: T): Mem[T] = macro MemTransform.apply[T]
-
- /** Creates a combinational/asynchronous-read, sequential/synchronous-write [[Mem]].
- *
- * @param size number of elements in the memory
- * @param t data type of memory element
- */
- def apply[T <: Data](size: Int, t: T): Mem[T] = macro MemTransform.apply[T]
-
- /** @group SourceInfoTransformMacro */
- def do_apply[T <: Data](size: BigInt, t: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Mem[T] = {
- if (compileOptions.declaredTypeMustBeUnbound) {
- requireIsChiselType(t, "memory type")
- }
- val mt = t.cloneTypeFull
- val mem = new Mem(mt, size)
- pushCommand(DefMemory(sourceInfo, mem, mt, size))
- mem
- }
-
- /** @group SourceInfoTransformMacro */
- def do_apply[T <: Data](size: Int, t: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Mem[T] =
- do_apply(BigInt(size), t)(sourceInfo, compileOptions)
-}
-
-sealed abstract class MemBase[T <: Data](t: T, val length: BigInt) extends HasId with NamedComponent with SourceInfoDoc {
- // REVIEW TODO: make accessors (static/dynamic, read/write) combinations consistent.
-
- /** Creates a read accessor into the memory with static addressing. See the
- * class documentation of the memory for more detailed information.
- */
- def apply(x: BigInt): T = macro SourceInfoTransform.xArg
-
- /** Creates a read accessor into the memory with static addressing. See the
- * class documentation of the memory for more detailed information.
- */
- def apply(x: Int): T = macro SourceInfoTransform.xArg
-
- /** @group SourceInfoTransformMacro */
- def do_apply(idx: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
- require(idx >= 0 && idx < length)
- apply(idx.asUInt)
- }
-
- /** @group SourceInfoTransformMacro */
- def do_apply(idx: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T =
- do_apply(BigInt(idx))(sourceInfo, compileOptions)
-
- /** Creates a read/write accessor into the memory with dynamic addressing.
- * See the class documentation of the memory for more detailed information.
- */
- def apply(x: UInt): T = macro SourceInfoTransform.xArg
-
- /** @group SourceInfoTransformMacro */
- def do_apply(idx: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T =
- makePort(sourceInfo, idx, MemPortDirection.INFER)
-
- /** Creates a read accessor into the memory with dynamic addressing. See the
- * class documentation of the memory for more detailed information.
- */
- def read(x: UInt): T = macro SourceInfoTransform.xArg
-
- /** @group SourceInfoTransformMacro */
- def do_read(idx: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T =
- makePort(sourceInfo, idx, MemPortDirection.READ)
-
- /** Creates a write accessor into the memory.
- *
- * @param idx memory element index to write into
- * @param data new data to write
- */
- def write(idx: UInt, data: T)(implicit compileOptions: CompileOptions): Unit = {
- implicit val sourceInfo = UnlocatableSourceInfo
- makePort(UnlocatableSourceInfo, idx, MemPortDirection.WRITE) := data
- }
-
- /** Creates a masked write accessor into the memory.
- *
- * @param idx memory element index to write into
- * @param data new data to write
- * @param mask write mask as a Seq of Bool: a write to the Vec element in
- * memory is only performed if the corresponding mask index is true.
- *
- * @note this is only allowed if the memory's element data type is a Vec
- */
- def write(idx: UInt, data: T, mask: Seq[Bool]) (implicit evidence: T <:< Vec[_], compileOptions: CompileOptions): Unit = {
- implicit val sourceInfo = UnlocatableSourceInfo
- val accessor = makePort(sourceInfo, idx, MemPortDirection.WRITE).asInstanceOf[Vec[Data]]
- val dataVec = data.asInstanceOf[Vec[Data]]
- if (accessor.length != dataVec.length) {
- Builder.error(s"Mem write data must contain ${accessor.length} elements (found ${dataVec.length})")
- }
- if (accessor.length != mask.length) {
- Builder.error(s"Mem write mask must contain ${accessor.length} elements (found ${mask.length})")
- }
- for (((cond, port), datum) <- mask zip accessor zip dataVec)
- when (cond) { port := datum }
- }
-
- private def makePort(sourceInfo: SourceInfo, idx: UInt, dir: MemPortDirection)(implicit compileOptions: CompileOptions): T = {
- requireIsHardware(idx, "memory port index")
- val i = Vec.truncateIndex(idx, length)(sourceInfo, compileOptions)
-
- val port = pushCommand(
- DefMemPort(sourceInfo,
- t.cloneTypeFull, Node(this), dir, i.ref, Builder.forcedClock.ref)
- ).id
- // Bind each element of port to being a MemoryPort
- port.bind(MemoryPortBinding(Builder.forcedUserModule))
- port
- }
-}
-
-/** A combinational/asynchronous-read, sequential/synchronous-write memory.
- *
- * Writes take effect on the rising clock edge after the request. Reads are
- * combinational (requests will return data on the same cycle).
- * Read-after-write hazards are not an issue.
- *
- * @note when multiple conflicting writes are performed on a Mem element, the
- * result is undefined (unlike Vec, where the last assignment wins)
- */
-sealed class Mem[T <: Data] private (t: T, length: BigInt) extends MemBase(t, length)
-
-object SyncReadMem {
- @chiselRuntimeDeprecated
- @deprecated("SeqMem/SyncReadMem argument order should be size, t; this will be removed by the official release", "chisel3")
- def apply[T <: Data](t: T, size: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SyncReadMem[T] = do_apply(size, t)
-
- @chiselRuntimeDeprecated
- @deprecated("SeqMem/SyncReadMem argument order should be size, t; this will be removed by the official release", "chisel3")
- def apply[T <: Data](t: T, size: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SyncReadMem[T] = do_apply(size, t)
-
- /** Creates a sequential/synchronous-read, sequential/synchronous-write [[SyncReadMem]].
- *
- * @param size number of elements in the memory
- * @param t data type of memory element
- */
- def apply[T <: Data](size: BigInt, t: T): SyncReadMem[T] = macro MemTransform.apply[T]
-
- /** Creates a sequential/synchronous-read, sequential/synchronous-write [[SyncReadMem]].
- *
- * @param size number of elements in the memory
- * @param t data type of memory element
- */
- def apply[T <: Data](size: Int, t: T): SyncReadMem[T] = macro MemTransform.apply[T]
-
- /** @group SourceInfoTransformMacro */
- def do_apply[T <: Data](size: BigInt, t: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SyncReadMem[T] = {
- if (compileOptions.declaredTypeMustBeUnbound) {
- requireIsChiselType(t, "memory type")
- }
- val mt = t.cloneTypeFull
- val mem = new SyncReadMem(mt, size)
- pushCommand(DefSeqMemory(sourceInfo, mem, mt, size))
- mem
- }
-
- /** @group SourceInfoTransformMacro */
- def do_apply[T <: Data](size: Int, t: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SyncReadMem[T] =
- do_apply(BigInt(size), t)(sourceInfo, compileOptions)
-}
-
-/** A sequential/synchronous-read, sequential/synchronous-write memory.
- *
- * Writes take effect on the rising clock edge after the request. Reads return
- * data on the rising edge after the request. Read-after-write behavior (when
- * a read and write to the same address are requested on the same cycle) is
- * undefined.
- *
- * @note when multiple conflicting writes are performed on a Mem element, the
- * result is undefined (unlike Vec, where the last assignment wins)
- */
-sealed class SyncReadMem[T <: Data] private (t: T, n: BigInt) extends MemBase[T](t, n) {
- def read(x: UInt, en: Bool): T = macro SourceInfoTransform.xEnArg
-
- /** @group SourceInfoTransformMacro */
- def do_read(addr: UInt, enable: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
- val a = Wire(UInt())
- a := DontCare
- var port: Option[T] = None
- when (enable) {
- a := addr
- port = Some(read(a))
- }
- port.get
- }
-}
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Module.scala b/chiselFrontend/src/main/scala/chisel3/core/Module.scala
deleted file mode 100644
index 5cd48a6a..00000000
--- a/chiselFrontend/src/main/scala/chisel3/core/Module.scala
+++ /dev/null
@@ -1,355 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3.core
-
-import scala.collection.immutable.ListMap
-import scala.collection.mutable.{ArrayBuffer, HashMap}
-import scala.collection.JavaConversions._
-import scala.language.experimental.macros
-
-import java.util.IdentityHashMap
-
-import chisel3.internal._
-import chisel3.internal.Builder._
-import chisel3.internal.firrtl._
-import chisel3.internal.sourceinfo.{InstTransform, SourceInfo}
-import chisel3.SourceInfoDoc
-
-import _root_.firrtl.annotations.{CircuitName, ModuleName}
-
-object Module extends SourceInfoDoc {
- /** A wrapper method that all Module instantiations must be wrapped in
- * (necessary to help Chisel track internal state).
- *
- * @param bc the Module being created
- *
- * @return the input module `m` with Chisel metadata properly set
- */
- def apply[T <: BaseModule](bc: => T): T = macro InstTransform.apply[T]
-
- /** @group SourceInfoTransformMacro */
- def do_apply[T <: BaseModule](bc: => T)
- (implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions): T = {
- if (Builder.readyForModuleConstr) {
- throwException("Error: Called Module() twice without instantiating a Module." +
- sourceInfo.makeMessage(" See " + _))
- }
- Builder.readyForModuleConstr = true
-
- val parent = Builder.currentModule
- val whenDepth: Int = Builder.whenDepth
-
- // Save then clear clock and reset to prevent leaking scope, must be set again in the Module
- val (saveClock, saveReset) = (Builder.currentClock, Builder.currentReset)
- Builder.currentClock = None
- Builder.currentReset = None
-
- // Execute the module, this has the following side effects:
- // - set currentModule
- // - unset readyForModuleConstr
- // - reset whenDepth to 0
- // - set currentClockAndReset
- val module: T = bc // bc is actually evaluated here
-
- if (Builder.whenDepth != 0) {
- throwException("Internal Error! when() scope depth is != 0, this should have been caught!")
- }
- if (Builder.readyForModuleConstr) {
- throwException("Error: attempted to instantiate a Module, but nothing happened. " +
- "This is probably due to rewrapping a Module instance with Module()." +
- sourceInfo.makeMessage(" See " + _))
- }
- Builder.currentModule = parent // Back to parent!
- Builder.whenDepth = whenDepth
- Builder.currentClock = saveClock // Back to clock and reset scope
- Builder.currentReset = saveReset
-
- val component = module.generateComponent()
- Builder.components += component
-
- // Handle connections at enclosing scope
- if(!Builder.currentModule.isEmpty) {
- pushCommand(DefInstance(sourceInfo, module, component.ports))
- module.initializeInParent(compileOptions)
- }
- module
- }
-
- /** Returns the implicit Clock */
- def clock: Clock = Builder.forcedClock
- /** Returns the implicit Reset */
- def reset: Reset = Builder.forcedReset
- /** Returns the current Module */
- def currentModule: Option[BaseModule] = Builder.currentModule
-}
-
-object IO {
- /** Constructs a port for the current Module
- *
- * This must wrap the datatype used to set the io field of any Module.
- * i.e. All concrete modules must have defined io in this form:
- * [lazy] val io[: io type] = IO(...[: io type])
- *
- * Items in [] are optional.
- *
- * The granted iodef must be a chisel type and not be bound to hardware.
- *
- * Also registers a Data as a port, also performing bindings. Cannot be called once ports are
- * requested (so that all calls to ports will return the same information).
- * Internal API.
- */
- def apply[T<:Data](iodef: T): T = {
- val module = Module.currentModule.get // Impossible to fail
- require(!module.isClosed, "Can't add more ports after module close")
- requireIsChiselType(iodef, "io type")
-
- // Clone the IO so we preserve immutability of data types
- val iodefClone = try {
- iodef.cloneTypeFull
- } catch {
- // For now this is going to be just a deprecation so we don't suddenly break everyone's code
- case e: AutoClonetypeException =>
- Builder.deprecated(e.getMessage, Some(s"${iodef.getClass}"))
- iodef
- }
- module.bindIoInPlace(iodefClone)
- iodefClone
- }
-}
-
-object BaseModule {
- private[chisel3] class ClonePorts (elts: Data*)(implicit compileOptions: CompileOptions) extends Record {
- val elements = ListMap(elts.map(d => d.instanceName -> d.cloneTypeFull): _*)
- def apply(field: String) = elements(field)
- override def cloneType = (new ClonePorts(elts: _*)).asInstanceOf[this.type]
- }
-
- private[chisel3] def cloneIORecord(proto: BaseModule)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): ClonePorts = {
- require(proto.isClosed, "Can't clone a module before module close")
- val clonePorts = new ClonePorts(proto.getModulePorts: _*)
- clonePorts.bind(WireBinding(Builder.forcedUserModule))
- val cloneInstance = new DefInstance(sourceInfo, proto, proto._component.get.ports) {
- override def name = clonePorts.getRef.name
- }
- pushCommand(cloneInstance)
- if (!compileOptions.explicitInvalidate) {
- pushCommand(DefInvalid(sourceInfo, clonePorts.ref))
- }
- if (proto.isInstanceOf[MultiIOModule]) {
- clonePorts("clock") := Module.clock
- clonePorts("reset") := Module.reset
- }
- clonePorts
- }
-}
-
-/** Abstract base class for Modules, an instantiable organizational unit for RTL.
- */
-// TODO: seal this?
-abstract class BaseModule extends HasId {
- //
- // Builder Internals - this tracks which Module RTL construction belongs to.
- //
- if (!Builder.readyForModuleConstr) {
- throwException("Error: attempted to instantiate a Module without wrapping it in Module().")
- }
- readyForModuleConstr = false
-
- Builder.currentModule = Some(this)
- Builder.whenDepth = 0
-
- //
- // Module Construction Internals
- //
- protected var _closed = false
-
- /** Internal check if a Module is closed */
- private[core] def isClosed = _closed
-
- // Fresh Namespace because in Firrtl, Modules namespaces are disjoint with the global namespace
- private[core] val _namespace = Namespace.empty
- private val _ids = ArrayBuffer[HasId]()
- private[chisel3] def addId(d: HasId) {
- require(!_closed, "Can't write to module after module close")
- _ids += d
- }
- protected def getIds = {
- require(_closed, "Can't get ids before module close")
- _ids.toSeq
- }
-
- private val _ports = new ArrayBuffer[Data]()
- // getPorts unfortunately already used for tester compatibility
- protected def getModulePorts = {
- require(_closed, "Can't get ports before module close")
- _ports.toSeq
- }
-
- // These methods allow checking some properties of ports before the module is closed,
- // mainly for compatibility purposes.
- protected def portsContains(elem: Data): Boolean = _ports contains elem
- protected def portsSize: Int = _ports.size
-
- /** Generates the FIRRTL Component (Module or Blackbox) of this Module.
- * Also closes the module so no more construction can happen inside.
- */
- private[core] def generateComponent(): Component
-
- /** Sets up this module in the parent context
- */
- private[core] def initializeInParent(parentCompileOptions: CompileOptions): Unit
-
- //
- // Chisel Internals
- //
- /** Desired name of this module. Override this to give this module a custom, perhaps parametric,
- * name.
- */
- def desiredName: String = this.getClass.getName.split('.').last
-
- /** Legalized name of this module. */
- final lazy val name = try {
- Builder.globalNamespace.name(desiredName)
- } catch {
- case e: NullPointerException => throwException(
- s"Error: desiredName of ${this.getClass.getName} is null. Did you evaluate 'name' before all values needed by desiredName were available?", e) // scalastyle:ignore line.size.limit
- case t: Throwable => throw t
- }
-
- /** Returns a FIRRTL ModuleName that references this object
- * @note Should not be called until circuit elaboration is complete
- */
- final def toNamed: ModuleName = ModuleName(this.name, CircuitName(this.circuitName))
-
- /**
- * Internal API. Returns a list of this module's generated top-level ports as a map of a String
- * (FIRRTL name) to the IO object. Only valid after the module is closed.
- *
- * Note: for BlackBoxes (but not ExtModules), this returns the contents of the top-level io
- * object, consistent with what is emitted in FIRRTL.
- *
- * TODO: Use SeqMap/VectorMap when those data structures become available.
- */
- private[core] def getChiselPorts: Seq[(String, Data)] = {
- require(_closed, "Can't get ports before module close")
- _component.get.ports.map { port =>
- (port.id.getRef.asInstanceOf[ModuleIO].name, port.id)
- }
- }
-
- /** Called at the Module.apply(...) level after this Module has finished elaborating.
- * Returns a map of nodes -> names, for named nodes.
- *
- * Helper method.
- */
- protected def nameIds(rootClass: Class[_]): HashMap[HasId, String] = {
- val names = new HashMap[HasId, String]()
-
- def name(node: HasId, name: String) {
- // First name takes priority, like suggestName
- // TODO: DRYify with suggestName
- if (!names.contains(node)) {
- names.put(node, name)
- }
- }
-
- /** Scala generates names like chisel3$util$Queue$$ram for private vals
- * This extracts the part after $$ for names like this and leaves names
- * without $$ unchanged
- */
- def cleanName(name: String): String = name.split("""\$\$""").lastOption.getOrElse(name)
-
- for (m <- getPublicFields(rootClass)) {
- Builder.nameRecursively(cleanName(m.getName), m.invoke(this), name)
- }
-
- names
- }
-
- /** Compatibility function. Allows Chisel2 code which had ports without the IO wrapper to
- * compile under Bindings checks. Does nothing in non-compatibility mode.
- *
- * Should NOT be used elsewhere. This API will NOT last.
- *
- * TODO: remove this, perhaps by removing Bindings checks in compatibility mode.
- */
- def _compatAutoWrapPorts() {} // scalastyle:ignore method.name
-
- //
- // BaseModule User API functions
- //
- @deprecated("Use chisel3.experimental.annotate instead", "3.1")
- protected def annotate(annotation: ChiselAnnotation): Unit = {
- Builder.annotations += annotation
- }
-
- /** Chisel2 code didn't require the IO(...) wrapper and would assign a Chisel type directly to
- * io, then do operations on it. This binds a Chisel type in-place (mutably) as an IO.
- */
- protected def _bindIoInPlace(iodef: Data): Unit = { // scalastyle:ignore method.name
- // Compatibility code: Chisel2 did not require explicit direction on nodes
- // (unspecified treated as output, and flip on nothing was input).
- // This sets assigns the explicit directions required by newer semantics on
- // Bundles defined in compatibility mode.
- // This recursively walks the tree, and assigns directions if no explicit
- // direction given by upper-levels (override Input / Output) AND element is
- // directly inside a compatibility Bundle determined by compile options.
- def assignCompatDir(data: Data, insideCompat: Boolean): Unit = {
- data match {
- case data: Element if insideCompat => data._assignCompatibilityExplicitDirection
- case data: Element => // Not inside a compatibility Bundle, nothing to be done
- case data: Aggregate => data.specifiedDirection match {
- // Recurse into children to ensure explicit direction set somewhere
- case SpecifiedDirection.Unspecified | SpecifiedDirection.Flip => data match {
- case record: Record =>
- val compatRecord = !record.compileOptions.dontAssumeDirectionality
- record.getElements.foreach(assignCompatDir(_, compatRecord))
- case vec: Vec[_] =>
- vec.getElements.foreach(assignCompatDir(_, insideCompat))
- }
- case SpecifiedDirection.Input | SpecifiedDirection.Output => // forced assign, nothing to do
- }
- }
- }
- assignCompatDir(iodef, false)
-
- iodef.bind(PortBinding(this))
- _ports += iodef
- }
- /** Private accessor for _bindIoInPlace */
- private[core] def bindIoInPlace(iodef: Data): Unit = _bindIoInPlace(iodef)
-
- /**
- * This must wrap the datatype used to set the io field of any Module.
- * i.e. All concrete modules must have defined io in this form:
- * [lazy] val io[: io type] = IO(...[: io type])
- *
- * Items in [] are optional.
- *
- * The granted iodef must be a chisel type and not be bound to hardware.
- *
- * Also registers a Data as a port, also performing bindings. Cannot be called once ports are
- * requested (so that all calls to ports will return the same information).
- * Internal API.
- *
- * TODO(twigg): Specifically walk the Data definition to call out which nodes
- * are problematic.
- */
- protected def IO[T<:Data](iodef: T): T = chisel3.core.IO.apply(iodef) // scalastyle:ignore method.name
-
- //
- // Internal Functions
- //
-
- /** Keep component for signal names */
- private[chisel3] var _component: Option[Component] = None
-
- /** Signal name (for simulation). */
- override def instanceName: String =
- if (_parent == None) name else _component match {
- case None => getRef.name
- case Some(c) => getRef fullName c
- }
-
-}
diff --git a/chiselFrontend/src/main/scala/chisel3/core/MonoConnect.scala b/chiselFrontend/src/main/scala/chisel3/core/MonoConnect.scala
deleted file mode 100644
index 6a4ae9bf..00000000
--- a/chiselFrontend/src/main/scala/chisel3/core/MonoConnect.scala
+++ /dev/null
@@ -1,246 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3.core
-
-import chisel3.internal.ChiselException
-import chisel3.internal.Builder.pushCommand
-import chisel3.internal.firrtl.{Connect, DefInvalid}
-import scala.language.experimental.macros
-import chisel3.internal.sourceinfo.SourceInfo
-
-/**
-* MonoConnect.connect executes a mono-directional connection element-wise.
-*
-* Note that this isn't commutative. There is an explicit source and sink
-* already determined before this function is called.
-*
-* The connect operation will recurse down the left Data (with the right Data).
-* An exception will be thrown if a movement through the left cannot be matched
-* in the right. The right side is allowed to have extra Record fields.
-* Vecs must still be exactly the same size.
-*
-* See elemConnect for details on how the root connections are issued.
-*
-* Note that a valid sink must be writable so, one of these must hold:
-* - Is an internal writable node (Reg or Wire)
-* - Is an output of the current module
-* - Is an input of a submodule of the current module
-*
-* Note that a valid source must be readable so, one of these must hold:
-* - Is an internal readable node (Reg, Wire, Op)
-* - Is a literal
-* - Is a port of the current module or submodule of the current module
-*/
-
-object MonoConnect {
- // scalastyle:off method.name public.methods.have.type
- // These are all the possible exceptions that can be thrown.
- case class MonoConnectException(message: String) extends ChiselException(message)
- // These are from element-level connection
- def UnreadableSourceException =
- MonoConnectException(": Source is unreadable from current module.")
- def UnwritableSinkException =
- MonoConnectException(": Sink is unwriteable by current module.")
- def UnknownRelationException =
- MonoConnectException(": Sink or source unavailable to current module.")
- // These are when recursing down aggregate types
- def MismatchedVecException =
- MonoConnectException(": Sink and Source are different length Vecs.")
- def MissingFieldException(field: String) =
- MonoConnectException(s": Source Record missing field ($field).")
- def MismatchedException(sink: String, source: String) =
- MonoConnectException(s": Sink ($sink) and Source ($source) have different types.")
- def DontCareCantBeSink =
- MonoConnectException(": DontCare cannot be a connection sink (LHS)")
- // scalastyle:on method.name public.methods.have.type
-
- /** This function is what recursively tries to connect a sink and source together
- *
- * There is some cleverness in the use of internal try-catch to catch exceptions
- * during the recursive decent and then rethrow them with extra information added.
- * This gives the user a 'path' to where in the connections things went wrong.
- */
- def connect( //scalastyle:off cyclomatic.complexity method.length
- sourceInfo: SourceInfo,
- connectCompileOptions: CompileOptions,
- sink: Data,
- source: Data,
- context_mod: RawModule): Unit =
- (sink, source) match {
-
- // Handle legal element cases, note (Bool, Bool) is caught by the first two, as Bool is a UInt
- case (sink_e: Bool, source_e: UInt) =>
- elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod)
- case (sink_e: UInt, source_e: Bool) =>
- elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod)
- case (sink_e: UInt, source_e: UInt) =>
- elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod)
- case (sink_e: SInt, source_e: SInt) =>
- elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod)
- case (sink_e: FixedPoint, source_e: FixedPoint) =>
- elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod)
- case (sink_e: Clock, source_e: Clock) =>
- elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod)
- case (sink_e: EnumType, source_e: UnsafeEnum) =>
- elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod)
- case (sink_e: EnumType, source_e: EnumType) if sink_e.typeEquivalent(source_e) =>
- elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod)
- case (sink_e: UnsafeEnum, source_e: UInt) =>
- elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod)
-
- // Handle Vec case
- case (sink_v: Vec[Data @unchecked], source_v: Vec[Data @unchecked]) =>
- if(sink_v.length != source_v.length) { throw MismatchedVecException }
- for(idx <- 0 until sink_v.length) {
- try {
- implicit val compileOptions = connectCompileOptions
- connect(sourceInfo, connectCompileOptions, sink_v(idx), source_v(idx), context_mod)
- } catch {
- case MonoConnectException(message) => throw MonoConnectException(s"($idx)$message")
- }
- }
- // Handle Vec connected to DontCare. Apply the DontCare to individual elements.
- case (sink_v: Vec[Data @unchecked], DontCare) =>
- for(idx <- 0 until sink_v.length) {
- try {
- implicit val compileOptions = connectCompileOptions
- connect(sourceInfo, connectCompileOptions, sink_v(idx), source, context_mod)
- } catch {
- case MonoConnectException(message) => throw MonoConnectException(s"($idx)$message")
- }
- }
-
- // Handle Record case
- case (sink_r: Record, source_r: Record) =>
- // For each field, descend with right
- for((field, sink_sub) <- sink_r.elements) {
- try {
- source_r.elements.get(field) match {
- case Some(source_sub) => connect(sourceInfo, connectCompileOptions, sink_sub, source_sub, context_mod)
- case None => {
- if (connectCompileOptions.connectFieldsMustMatch) {
- throw MissingFieldException(field)
- }
- }
- }
- } catch {
- case MonoConnectException(message) => throw MonoConnectException(s".$field$message")
- }
- }
- // Handle Record connected to DontCare. Apply the DontCare to individual elements.
- case (sink_r: Record, DontCare) =>
- // For each field, descend with right
- for((field, sink_sub) <- sink_r.elements) {
- try {
- connect(sourceInfo, connectCompileOptions, sink_sub, source, context_mod)
- } catch {
- case MonoConnectException(message) => throw MonoConnectException(s".$field$message")
- }
- }
-
- // Source is DontCare - it may be connected to anything. It generates a defInvalid for the sink.
- case (sink, DontCare) => pushCommand(DefInvalid(sourceInfo, sink.lref))
- // DontCare as a sink is illegal.
- case (DontCare, _) => throw DontCareCantBeSink
- // Sink and source are different subtypes of data so fail
- case (sink, source) => throw MismatchedException(sink.toString, source.toString)
- }
-
- // This function (finally) issues the connection operation
- private def issueConnect(sink: Element, source: Element)(implicit sourceInfo: SourceInfo): Unit = {
- // If the source is a DontCare, generate a DefInvalid for the sink,
- // otherwise, issue a Connect.
- source.topBinding match {
- case b: DontCareBinding => pushCommand(DefInvalid(sourceInfo, sink.lref))
- case _ => pushCommand(Connect(sourceInfo, sink.lref, source.ref))
- }
- }
-
- // This function checks if element-level connection operation allowed.
- // Then it either issues it or throws the appropriate exception.
- def elemConnect(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions, sink: Element, source: Element, context_mod: RawModule): Unit = { // scalastyle:ignore line.size.limit
- import BindingDirection.{Internal, Input, Output} // Using extensively so import these
- // If source has no location, assume in context module
- // This can occur if is a literal, unbound will error previously
- val sink_mod: BaseModule = sink.topBinding.location.getOrElse(throw UnwritableSinkException)
- val source_mod: BaseModule = source.topBinding.location.getOrElse(context_mod)
-
- val sink_direction = BindingDirection.from(sink.topBinding, sink.direction)
- val source_direction = BindingDirection.from(source.topBinding, source.direction)
-
- // CASE: Context is same module that both left node and right node are in
- if( (context_mod == sink_mod) && (context_mod == source_mod) ) {
- ((sink_direction, source_direction): @unchecked) match {
- // SINK SOURCE
- // CURRENT MOD CURRENT MOD
- case (Output, _) => issueConnect(sink, source)
- case (Internal, _) => issueConnect(sink, source)
- case (Input, _) => throw UnwritableSinkException
- }
- }
-
- // CASE: Context is same module as sink node and right node is in a child module
- else if( (sink_mod == context_mod) &&
- (source_mod._parent.map(_ == context_mod).getOrElse(false)) ) {
- // Thus, right node better be a port node and thus have a direction
- ((sink_direction, source_direction): @unchecked) match {
- // SINK SOURCE
- // CURRENT MOD CHILD MOD
- case (Internal, Output) => issueConnect(sink, source)
- case (Internal, Input) => issueConnect(sink, source)
- case (Output, Output) => issueConnect(sink, source)
- case (Output, Input) => issueConnect(sink, source)
- case (_, Internal) => {
- if (!(connectCompileOptions.dontAssumeDirectionality)) {
- issueConnect(sink, source)
- } else {
- throw UnreadableSourceException
- }
- }
- case (Input, Output) if (!(connectCompileOptions.dontTryConnectionsSwapped)) => issueConnect(source, sink) // scalastyle:ignore line.size.limit
- case (Input, _) => throw UnwritableSinkException
- }
- }
-
- // CASE: Context is same module as source node and sink node is in child module
- else if( (source_mod == context_mod) &&
- (sink_mod._parent.map(_ == context_mod).getOrElse(false)) ) {
- // Thus, left node better be a port node and thus have a direction
- ((sink_direction, source_direction): @unchecked) match {
- // SINK SOURCE
- // CHILD MOD CURRENT MOD
- case (Input, _) => issueConnect(sink, source)
- case (Output, _) => throw UnwritableSinkException
- case (Internal, _) => throw UnwritableSinkException
- }
- }
-
- // CASE: Context is the parent module of both the module containing sink node
- // and the module containing source node
- // Note: This includes case when sink and source in same module but in parent
- else if( (sink_mod._parent.map(_ == context_mod).getOrElse(false)) &&
- (source_mod._parent.map(_ == context_mod).getOrElse(false))
- ) {
- // Thus both nodes must be ports and have a direction
- ((sink_direction, source_direction): @unchecked) match {
- // SINK SOURCE
- // CHILD MOD CHILD MOD
- case (Input, Input) => issueConnect(sink, source)
- case (Input, Output) => issueConnect(sink, source)
- case (Output, _) => throw UnwritableSinkException
- case (_, Internal) => {
- if (!(connectCompileOptions.dontAssumeDirectionality)) {
- issueConnect(sink, source)
- } else {
- throw UnreadableSourceException
- }
- }
- case (Internal, _) => throw UnwritableSinkException
- }
- }
-
- // Not quite sure where left and right are compared to current module
- // so just error out
- else throw UnknownRelationException
- }
-}
diff --git a/chiselFrontend/src/main/scala/chisel3/core/MultiClock.scala b/chiselFrontend/src/main/scala/chisel3/core/MultiClock.scala
deleted file mode 100644
index aaa03d78..00000000
--- a/chiselFrontend/src/main/scala/chisel3/core/MultiClock.scala
+++ /dev/null
@@ -1,70 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3.core
-
-import chisel3.internal._
-
-import scala.language.experimental.macros
-
-object withClockAndReset { // scalastyle:ignore object.name
- /** Creates a new Clock and Reset scope
- *
- * @param clock the new implicit Clock
- * @param reset the new implicit Reset
- * @param block the block of code to run with new implicit Clock and Reset
- * @return the result of the block
- */
- def apply[T](clock: Clock, reset: Reset)(block: => T): T = {
- // Save parentScope
- val parentClock = Builder.currentClock
- val parentReset = Builder.currentReset
-
- Builder.currentClock = Some(clock)
- Builder.currentReset = Some(reset)
-
- val res = block // execute block
-
- // Return to old scope
- Builder.currentClock = parentClock
- Builder.currentReset = parentReset
- res
- }
-}
-
-object withClock { // scalastyle:ignore object.name
- /** Creates a new Clock scope
- *
- * @param clock the new implicit Clock
- * @param block the block of code to run with new implicit Clock
- * @return the result of the block
- */
- def apply[T](clock: Clock)(block: => T): T = {
- // Save parentScope
- val parentClock = Builder.currentClock
- Builder.currentClock = Some(clock)
- val res = block // execute block
- // Return to old scope
- Builder.currentClock = parentClock
- res
- }
-}
-
-object withReset { // scalastyle:ignore object.name
- /** Creates a new Reset scope
- *
- * @param reset the new implicit Reset
- * @param block the block of code to run with new implicit Reset
- * @return the result of the block
- */
- def apply[T](reset: Reset)(block: => T): T = {
- // Save parentScope
- val parentReset = Builder.currentReset
- Builder.currentReset = Some(reset)
- val res = block // execute block
- // Return to old scope
- Builder.currentReset = parentReset
- res
- }
-
-}
-
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Mux.scala b/chiselFrontend/src/main/scala/chisel3/core/Mux.scala
deleted file mode 100644
index 7dd1b98b..00000000
--- a/chiselFrontend/src/main/scala/chisel3/core/Mux.scala
+++ /dev/null
@@ -1,51 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3.core
-
-import scala.language.experimental.macros
-
-import chisel3.internal._
-import chisel3.internal.Builder.{pushOp}
-import chisel3.internal.sourceinfo.{SourceInfo, MuxTransform}
-import chisel3.internal.firrtl._
-import chisel3.internal.firrtl.PrimOp._
-import chisel3.SourceInfoDoc
-
-object Mux extends SourceInfoDoc {
- /** Creates a mux, whose output is one of the inputs depending on the
- * value of the condition.
- *
- * @param cond condition determining the input to choose
- * @param con the value chosen when `cond` is true
- * @param alt the value chosen when `cond` is false
- * @example
- * {{{
- * val muxOut = Mux(data_in === 3.U, 3.U(4.W), 0.U(4.W))
- * }}}
- */
- def apply[T <: Data](cond: Bool, con: T, alt: T): T = macro MuxTransform.apply[T]
-
- /** @group SourceInfoTransformMacro */
- def do_apply[T <: Data](cond: Bool, con: T, alt: T)(implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions): T = {
- requireIsHardware(cond, "mux condition")
- requireIsHardware(con, "mux true value")
- requireIsHardware(alt, "mux false value")
- val d = cloneSupertype(Seq(con, alt), "Mux")
- val conRef = con match { // this matches chisel semantics (DontCare as object) to firrtl semantics (invalidate)
- case DontCare =>
- val dcWire = Wire(d)
- dcWire := DontCare
- dcWire.ref
- case _ => con.ref
- }
- val altRef = alt match {
- case DontCare =>
- val dcWire = Wire(d)
- dcWire := DontCare
- dcWire.ref
- case _ => alt.ref
- }
- pushOp(DefPrim(sourceInfo, d, MultiplexOp, cond.ref, conRef, altRef))
- }
-}
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Printable.scala b/chiselFrontend/src/main/scala/chisel3/core/Printable.scala
deleted file mode 100644
index c724f682..00000000
--- a/chiselFrontend/src/main/scala/chisel3/core/Printable.scala
+++ /dev/null
@@ -1,179 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3.core
-
-import chisel3.internal.firrtl.Component
-import chisel3.internal.HasId
-
-import scala.collection.mutable
-
-import java.util.{
- MissingFormatArgumentException,
- UnknownFormatConversionException
-}
-
-/** Superclass of things that can be printed in the resulting circuit
- *
- * Usually created using the custom string interpolator `p"..."`. Printable string interpolation is
- * similar to [[https://docs.scala-lang.org/overviews/core/string-interpolation.html String
- * interpolation in Scala]] For example:
- * {{{
- * printf(p"The value of wire = \$wire\n")
- * }}}
- * This is equivalent to writing:
- * {{{
- * printf(p"The value of wire = %d\n", wire)
- * }}}
- * All Chisel data types have a method `.toPrintable` that gives a default pretty print that can be
- * accessed via `p"..."`. This works even for aggregate types, for example:
- * {{{
- * val myVec = VecInit(5.U, 10.U, 13.U)
- * printf(p"myVec = \$myVec\n")
- * // myVec = Vec(5, 10, 13)
- *
- * val myBundle = Wire(new Bundle {
- * val foo = UInt()
- * val bar = UInt()
- * })
- * myBundle.foo := 3.U
- * myBundle.bar := 11.U
- * printf(p"myBundle = \$myBundle\n")
- * // myBundle = Bundle(a -> 3, b -> 11)
- * }}}
- * Users can override the default behavior of `.toPrintable` in custom [[Bundle]] and [[Record]]
- * types.
- */
-// TODO Add support for names of Modules
-// Currently impossible because unpack is called before the name is selected
-// Could be implemented by adding a new format specifier to Firrtl (eg. %m)
-// TODO Should we provide more functions like map and mkPrintable?
-sealed abstract class Printable {
- /** Unpack into format String and a List of String arguments (identifiers)
- * @note This must be called after elaboration when Chisel nodes actually
- * have names
- */
- def unpack(ctx: Component): (String, Iterable[String])
- /** Allow for appending Printables like Strings */
- final def +(that: Printable): Printables = Printables(List(this, that))
- /** Allow for appending Strings to Printables */
- final def +(that: String): Printables = Printables(List(this, PString(that)))
-}
-object Printable {
- /** Pack standard printf fmt, args* style into Printable
- */
- def pack(fmt: String, data: Data*): Printable = { // scalastyle:ignore method.length
- val args = data.toIterator
-
- // Error handling
- def carrotAt(index: Int) = (" " * index) + "^"
- def errorMsg(index: Int) =
- s"""| fmt = "$fmt"
- | ${carrotAt(index)}
- | data = ${data mkString ", "}""".stripMargin
- def getArg(i: Int): Data = {
- if (!args.hasNext) {
- val msg = "has no matching argument!\n" + errorMsg(i)
- // Exception wraps msg in s"Format Specifier '$msg'"
- throw new MissingFormatArgumentException(msg)
- }
- args.next()
- }
-
- val pables = mutable.ListBuffer.empty[Printable]
- var str = ""
- var percent = false
- for ((c, i) <- fmt.zipWithIndex) {
- if (percent) {
- val arg = c match {
- case FirrtlFormat(x) => FirrtlFormat(x.toString, getArg(i))
- case 'n' => Name(getArg(i))
- case 'N' => FullName(getArg(i))
- case '%' => Percent
- case x =>
- val msg = s"Illegal format specifier '$x'!\n" + errorMsg(i)
- throw new UnknownFormatConversionException(msg)
- }
- pables += PString(str dropRight 1) // remove format %
- pables += arg
- str = ""
- percent = false
- } else {
- str += c
- percent = c == '%'
- }
- }
- if (percent) {
- val msg = s"Trailing %\n" + errorMsg(fmt.size - 1)
- throw new UnknownFormatConversionException(msg)
- }
- require(!args.hasNext,
- s"Too many arguments! More format specifier(s) expected!\n" +
- errorMsg(fmt.size))
-
- pables += PString(str)
- Printables(pables)
- }
-}
-
-case class Printables(pables: Iterable[Printable]) extends Printable {
- require(pables.hasDefiniteSize, "Infinite-sized iterables are not supported!")
- final def unpack(ctx: Component): (String, Iterable[String]) = {
- val (fmts, args) = pables.map(_ unpack ctx).unzip
- (fmts.mkString, args.flatten)
- }
-}
-/** Wrapper for printing Scala Strings */
-case class PString(str: String) extends Printable {
- final def unpack(ctx: Component): (String, Iterable[String]) =
- (str replaceAll ("%", "%%"), List.empty)
-}
-/** Superclass for Firrtl format specifiers for Bits */
-sealed abstract class FirrtlFormat(private[chisel3] val specifier: Char) extends Printable {
- def bits: Bits
- def unpack(ctx: Component): (String, Iterable[String]) = {
- (s"%$specifier", List(bits.ref.fullName(ctx)))
- }
-}
-object FirrtlFormat {
- final val legalSpecifiers = List('d', 'x', 'b', 'c')
-
- def unapply(x: Char): Option[Char] =
- Option(x) filter (x => legalSpecifiers contains x)
-
- /** Helper for constructing Firrtl Formats
- * Accepts data to simplify pack
- */
- def apply(specifier: String, data: Data): FirrtlFormat = {
- val bits = data match {
- case b: Bits => b
- case d => throw new Exception(s"Trying to construct FirrtlFormat with non-bits $d!")
- }
- specifier match {
- case "d" => Decimal(bits)
- case "x" => Hexadecimal(bits)
- case "b" => Binary(bits)
- case "c" => Character(bits)
- case c => throw new Exception(s"Illegal format specifier '$c'!")
- }
- }
-}
-/** Format bits as Decimal */
-case class Decimal(bits: Bits) extends FirrtlFormat('d')
-/** Format bits as Hexidecimal */
-case class Hexadecimal(bits: Bits) extends FirrtlFormat('x')
-/** Format bits as Binary */
-case class Binary(bits: Bits) extends FirrtlFormat('b')
-/** Format bits as Character */
-case class Character(bits: Bits) extends FirrtlFormat('c')
-/** Put innermost name (eg. field of bundle) */
-case class Name(data: Data) extends Printable {
- final def unpack(ctx: Component): (String, Iterable[String]) = (data.ref.name, List.empty)
-}
-/** Put full name within parent namespace (eg. bundleName.field) */
-case class FullName(data: Data) extends Printable {
- final def unpack(ctx: Component): (String, Iterable[String]) = (data.ref.fullName(ctx), List.empty)
-}
-/** Represents escaped percents */
-case object Percent extends Printable {
- final def unpack(ctx: Component): (String, Iterable[String]) = ("%%", List.empty)
-}
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Printf.scala b/chiselFrontend/src/main/scala/chisel3/core/Printf.scala
deleted file mode 100644
index 5c2f89e9..00000000
--- a/chiselFrontend/src/main/scala/chisel3/core/Printf.scala
+++ /dev/null
@@ -1,100 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3.core
-
-import scala.language.experimental.macros
-
-import chisel3.internal._
-import chisel3.internal.Builder.pushCommand
-import chisel3.internal.firrtl._
-import chisel3.internal.sourceinfo.SourceInfo
-
-/** Prints a message in simulation
- *
- * See apply methods for use
- */
-object printf { // scalastyle:ignore object.name
- /** Helper for packing escape characters */
- private[chisel3] def format(formatIn: String): String = {
- require(formatIn forall (c => c.toInt > 0 && c.toInt < 128),
- "format strings must comprise non-null ASCII values")
- def escaped(x: Char) = {
- require(x.toInt >= 0)
- if (x == '"' || x == '\\') {
- s"\\${x}"
- } else if (x == '\n') {
- "\\n"
- } else {
- require(x.toInt >= 32) // TODO \xNN once FIRRTL issue #59 is resolved
- x
- }
- }
- formatIn map escaped mkString ""
- }
-
- /** Prints a message in simulation
- *
- * Prints a message every cycle. If defined within the scope of a [[when]] block, the message
- * will only be printed on cycles that the when condition is true.
- *
- * Does not fire when in reset (defined as the encapsulating Module's reset). If your definition
- * of reset is not the encapsulating Module's reset, you will need to gate this externally.
- *
- * May be called outside of a Module (like defined in a function), uses the current default clock
- * and reset. These can be overriden with [[withClockAndReset]].
- *
- * ==Format Strings==
- *
- * This method expects a ''format string'' and an ''argument list'' in a similar style to printf
- * in C. The format string expects a [[scala.Predef.String String]] that may contain ''format
- * specifiers'' For example:
- * {{{
- * printf("myWire has the value %d\n", myWire)
- * }}}
- * This prints the string "myWire has the value " followed by the current value of `myWire` (in
- * decimal, followed by a newline.
- *
- * There must be exactly as many arguments as there are format specifiers
- *
- * ===Format Specifiers===
- *
- * Format specifiers are prefixed by `%`. If you wish to print a literal `%`, use `%%`.
- * - `%d` - Decimal
- * - `%x` - Hexadecimal
- * - `%b` - Binary
- * - `%c` - 8-bit Character
- * - `%n` - Name of a signal
- * - `%N` - Full name of a leaf signal (in an aggregate)
- *
- * @param fmt printf format string
- * @param data format string varargs containing data to print
- */
- def apply(fmt: String, data: Bits*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Unit =
- apply(Printable.pack(fmt, data:_*))
- /** Prints a message in simulation
- *
- * Prints a message every cycle. If defined within the scope of a [[when]] block, the message
- * will only be printed on cycles that the when condition is true.
- *
- * Does not fire when in reset (defined as the encapsulating Module's reset). If your definition
- * of reset is not the encapsulating Module's reset, you will need to gate this externally.
- *
- * May be called outside of a Module (like defined in a function), uses the current default clock
- * and reset. These can be overriden with [[withClockAndReset]].
- *
- * @see [[Printable]] documentation
- * @param pable [[Printable]] to print
- */
- def apply(pable: Printable)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Unit = {
- when (!Module.reset.asBool) {
- printfWithoutReset(pable)
- }
- }
-
- private[chisel3] def printfWithoutReset(pable: Printable)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Unit = { // scalastyle:ignore line.size.limit
- val clock = Builder.forcedClock
- pushCommand(Printf(sourceInfo, clock.ref, pable))
- }
- private[chisel3] def printfWithoutReset(fmt: String, data: Bits*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Unit = // scalastyle:ignore line.size.limit
- printfWithoutReset(Printable.pack(fmt, data:_*))
-}
diff --git a/chiselFrontend/src/main/scala/chisel3/core/RawModule.scala b/chiselFrontend/src/main/scala/chisel3/core/RawModule.scala
deleted file mode 100644
index b224d9a3..00000000
--- a/chiselFrontend/src/main/scala/chisel3/core/RawModule.scala
+++ /dev/null
@@ -1,255 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3.core
-
-import scala.collection.mutable.{ArrayBuffer, HashMap}
-import scala.collection.JavaConversions._
-import scala.language.experimental.macros
-
-import chisel3.internal._
-import chisel3.internal.Builder._
-import chisel3.internal.firrtl._
-import chisel3.internal.firrtl.{Command => _, _}
-import chisel3.internal.sourceinfo.UnlocatableSourceInfo
-
-/** Abstract base class for Modules that contain Chisel RTL.
- * This abstract base class is a user-defined module which does not include implicit clock and reset and supports
- * multiple IO() declarations.
- */
-abstract class RawModule(implicit moduleCompileOptions: CompileOptions)
- extends BaseModule {
- //
- // RTL construction internals
- //
- private val _commands = ArrayBuffer[Command]()
- private[chisel3] def addCommand(c: Command) {
- require(!_closed, "Can't write to module after module close")
- _commands += c
- }
- protected def getCommands = {
- require(_closed, "Can't get commands before module close")
- _commands.toSeq
- }
-
- //
- // Other Internal Functions
- //
- // For debuggers/testers, TODO: refactor out into proper public API
- private var _firrtlPorts: Option[Seq[firrtl.Port]] = None
- lazy val getPorts = _firrtlPorts.get
-
- val compileOptions = moduleCompileOptions
-
- private[chisel3] def namePorts(names: HashMap[HasId, String]): Unit = {
- for (port <- getModulePorts) {
- port.suggestedName.orElse(names.get(port)) match {
- case Some(name) =>
- if (_namespace.contains(name)) {
- Builder.error(s"""Unable to name port $port to "$name" in $this,""" +
- " name is already taken by another port!")
- }
- port.setRef(ModuleIO(this, _namespace.name(name)))
- case None => Builder.error(s"Unable to name port $port in $this, " +
- "try making it a public field of the Module")
- }
- }
- }
-
-
- private[core] override def generateComponent(): Component = { // scalastyle:ignore cyclomatic.complexity
- require(!_closed, "Can't generate module more than once")
- _closed = true
-
- val names = nameIds(classOf[RawModule])
-
- // Ports get first naming priority, since they are part of a Module's IO spec
- namePorts(names)
-
- // Then everything else gets named
- for ((node, name) <- names) {
- node.suggestName(name)
- }
-
- // All suggestions are in, force names to every node.
- for (id <- getIds) {
- id match {
- case id: BaseModule => id.forceName(default=id.desiredName, _namespace)
- case id: MemBase[_] => id.forceName(default="_T", _namespace)
- case id: Data =>
- if (id.isSynthesizable) {
- id.topBinding match {
- case OpBinding(_) | MemoryPortBinding(_) | PortBinding(_) | RegBinding(_) | WireBinding(_) =>
- id.forceName(default="_T", _namespace)
- case _ => // don't name literals
- }
- } // else, don't name unbound types
- }
- id._onModuleClose
- }
-
- val firrtlPorts = getModulePorts map { port: Data =>
- // Special case Vec to make FIRRTL emit the direction of its
- // element.
- // Just taking the Vec's specifiedDirection is a bug in cases like
- // Vec(Flipped()), since the Vec's specifiedDirection is
- // Unspecified.
- val direction = port match {
- case v: Vec[_] => v.specifiedDirection match {
- case SpecifiedDirection.Input => SpecifiedDirection.Input
- case SpecifiedDirection.Output => SpecifiedDirection.Output
- case SpecifiedDirection.Flip => SpecifiedDirection.flip(v.sample_element.specifiedDirection)
- case SpecifiedDirection.Unspecified => v.sample_element.specifiedDirection
- }
- case _ => port.specifiedDirection
- }
-
- Port(port, direction)
- }
- _firrtlPorts = Some(firrtlPorts)
-
- // Generate IO invalidation commands to initialize outputs as unused,
- // unless the client wants explicit control over their generation.
- val invalidateCommands = {
- if (!compileOptions.explicitInvalidate) {
- getModulePorts map { port => DefInvalid(UnlocatableSourceInfo, port.ref) }
- } else {
- Seq()
- }
- }
- val component = DefModule(this, name, firrtlPorts, invalidateCommands ++ getCommands)
- _component = Some(component)
- component
- }
-
- private[core] def initializeInParent(parentCompileOptions: CompileOptions): Unit = {
- implicit val sourceInfo = UnlocatableSourceInfo
-
- if (!parentCompileOptions.explicitInvalidate) {
- for (port <- getModulePorts) {
- pushCommand(DefInvalid(sourceInfo, port.ref))
- }
- }
- }
-}
-
-/** Abstract base class for Modules, which behave much like Verilog modules.
- * These may contain both logic and state which are written in the Module
- * body (constructor).
- * This abstract base class includes an implicit clock and reset.
- *
- * @note Module instantiations must be wrapped in a Module() call.
- */
-abstract class MultiIOModule(implicit moduleCompileOptions: CompileOptions)
- extends RawModule {
- // Implicit clock and reset pins
- val clock: Clock = IO(Input(Clock()))
- val reset: Reset = IO(Input(Bool()))
-
- // Setup ClockAndReset
- Builder.currentClock = Some(clock)
- Builder.currentReset = Some(reset)
-
- private[core] override def initializeInParent(parentCompileOptions: CompileOptions): Unit = {
- implicit val sourceInfo = UnlocatableSourceInfo
-
- super.initializeInParent(parentCompileOptions)
- clock := Builder.forcedClock
- reset := Builder.forcedReset
- }
-}
-
-/** Legacy Module class that restricts IOs to just io, clock, and reset, and provides a constructor
- * for threading through explicit clock and reset.
- *
- * While this class isn't planned to be removed anytime soon (there are benefits to restricting
- * IO), the clock and reset constructors will be phased out. Recommendation is to wrap the module
- * in a withClock/withReset/withClockAndReset block, or directly hook up clock or reset IO pins.
- */
-abstract class LegacyModule(implicit moduleCompileOptions: CompileOptions)
- extends MultiIOModule {
- // These are to be phased out
- protected var override_clock: Option[Clock] = None
- protected var override_reset: Option[Bool] = None
-
- // _clock and _reset can be clock and reset in these 2ary constructors
- // once chisel2 compatibility issues are resolved
- @chiselRuntimeDeprecated
- @deprecated("Module constructor with override_clock and override_reset deprecated, use withClockAndReset", "chisel3")
- def this(override_clock: Option[Clock]=None, override_reset: Option[Bool]=None)
- (implicit moduleCompileOptions: CompileOptions) = {
- this()
- this.override_clock = override_clock
- this.override_reset = override_reset
- }
-
- @chiselRuntimeDeprecated
- @deprecated("Module constructor with override _clock deprecated, use withClock", "chisel3")
- def this(_clock: Clock)(implicit moduleCompileOptions: CompileOptions) = this(Option(_clock), None)(moduleCompileOptions) // scalastyle:ignore line.size.limit
-
- @chiselRuntimeDeprecated
- @deprecated("Module constructor with override _reset deprecated, use withReset", "chisel3")
- def this(_reset: Bool)(implicit moduleCompileOptions: CompileOptions) = this(None, Option(_reset))(moduleCompileOptions) // scalastyle:ignore line.size.limit
-
- @chiselRuntimeDeprecated
- @deprecated("Module constructor with override _clock, _reset deprecated, use withClockAndReset", "chisel3")
- def this(_clock: Clock, _reset: Bool)(implicit moduleCompileOptions: CompileOptions) = this(Option(_clock), Option(_reset))(moduleCompileOptions) // scalastyle:ignore line.size.limit
-
- // IO for this Module. At the Scala level (pre-FIRRTL transformations),
- // connections in and out of a Module may only go through `io` elements.
- def io: Record
-
- // Allow access to bindings from the compatibility package
- protected def _compatIoPortBound() = portsContains(io)// scalastyle:ignore method.name
-
- protected override def nameIds(rootClass: Class[_]): HashMap[HasId, String] = {
- val names = super.nameIds(rootClass)
-
- // Allow IO naming without reflection
- names.put(io, "io")
- names.put(clock, "clock")
- names.put(reset, "reset")
-
- names
- }
-
- private[chisel3] override def namePorts(names: HashMap[HasId, String]): Unit = {
- for (port <- getModulePorts) {
- // This should already have been caught
- if (!names.contains(port)) throwException(s"Unable to name port $port in $this")
- val name = names(port)
- port.setRef(ModuleIO(this, _namespace.name(name)))
- }
- }
-
- private[core] override def generateComponent(): Component = {
- _compatAutoWrapPorts() // pre-IO(...) compatibility hack
-
- // Restrict IO to just io, clock, and reset
- require(io != null, "Module must have io")
- require(portsContains(io), "Module must have io wrapped in IO(...)")
- require((portsContains(clock)) && (portsContains(reset)), "Internal error, module did not have clock or reset as IO") // scalastyle:ignore line.size.limit
- require(portsSize == 3, "Module must only have io, clock, and reset as IO")
-
- super.generateComponent()
- }
-
- private[core] override def initializeInParent(parentCompileOptions: CompileOptions): Unit = {
- // Don't generate source info referencing parents inside a module, since this interferes with
- // module de-duplication in FIRRTL emission.
- implicit val sourceInfo = UnlocatableSourceInfo
-
- if (!parentCompileOptions.explicitInvalidate) {
- pushCommand(DefInvalid(sourceInfo, io.ref))
- }
-
- override_clock match {
- case Some(override_clock) => clock := override_clock
- case _ => clock := Builder.forcedClock
- }
-
- override_reset match {
- case Some(override_reset) => reset := override_reset
- case _ => reset := Builder.forcedReset
- }
- }
-}
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Reg.scala b/chiselFrontend/src/main/scala/chisel3/core/Reg.scala
deleted file mode 100644
index 747fad73..00000000
--- a/chiselFrontend/src/main/scala/chisel3/core/Reg.scala
+++ /dev/null
@@ -1,175 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3.core
-
-import scala.language.experimental.macros
-
-import chisel3.internal._
-import chisel3.internal.Builder.pushCommand
-import chisel3.internal.firrtl._
-import chisel3.internal.sourceinfo.{SourceInfo}
-
-/** Utility for constructing hardware registers
- *
- * The width of a `Reg` (inferred or not) is copied from the type template
- * {{{
- * val r0 = Reg(UInt()) // width is inferred
- * val r1 = Reg(UInt(8.W)) // width is set to 8
- *
- * val r2 = Reg(Vec(4, UInt())) // width is inferred
- * val r3 = Reg(Vec(4, UInt(8.W))) // width of each element is set to 8
- *
- * class MyBundle {
- * val unknown = UInt()
- * val known = UInt(8.W)
- * }
- * val r4 = Reg(new MyBundle)
- * // Width of r4.unknown is inferred
- * // Width of r4.known is set to 8
- * }}}
- *
- */
-object Reg {
- /** Construct a [[Reg]] from a type template with no initialization value (reset is ignored).
- * Value will not change unless the [[Reg]] is given a connection.
- * @param t The template from which to construct this wire
- */
- def apply[T <: Data](t: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
- if (compileOptions.declaredTypeMustBeUnbound) {
- requireIsChiselType(t, "reg type")
- }
- val reg = t.cloneTypeFull
- val clock = Node(Builder.forcedClock)
-
- reg.bind(RegBinding(Builder.forcedUserModule))
- pushCommand(DefReg(sourceInfo, reg, clock))
- reg
- }
-}
-
-object RegNext {
- /** Returns a register with the specified next and no reset initialization.
- *
- * Essentially a 1-cycle delayed version of the input signal.
- */
- def apply[T <: Data](next: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
- val model = (next match {
- case next: Bits => next.cloneTypeWidth(Width())
- case next => next.cloneTypeFull
- }).asInstanceOf[T]
- val reg = Reg(model)
-
- requireIsHardware(next, "reg next")
- reg := next
-
- reg
- }
-
- /** Returns a register with the specified next and reset initialization.
- *
- * Essentially a 1-cycle delayed version of the input signal.
- */
- def apply[T <: Data](next: T, init: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
- val model = (next match {
- case next: Bits => next.cloneTypeWidth(Width())
- case next => next.cloneTypeFull
- }).asInstanceOf[T]
- val reg = RegInit(model, init) // TODO: this makes NO sense
-
- requireIsHardware(next, "reg next")
- reg := next
-
- reg
- }
-}
-
-/** Utility for constructing hardware registers with an initialization value.
- *
- * The register is set to the initialization value when the current implicit `reset` is high
- *
- * The two forms of `RegInit` differ in how the type and width of the resulting [[Reg]] are
- * specified.
- *
- * ==Single Argument==
- * The single argument form uses the argument to specify both the type and reset value. For
- * non-literal [[Bits]], the width of the [[Reg]] will be inferred. For literal [[Bits]] and all
- * non-Bits arguments, the type will be copied from the argument. See the following examples for
- * more details:
- *
- * 1. Literal [[Bits]] initializer: width will be set to match
- * {{{
- * val r1 = RegInit(1.U) // width will be inferred to be 1
- * val r2 = RegInit(1.U(8.W)) // width is set to 8
- * }}}
- *
- * 2. Non-Literal [[Element]] initializer - width will be inferred
- * {{{
- * val x = Wire(UInt())
- * val y = Wire(UInt(8.W))
- * val r1 = RegInit(x) // width will be inferred
- * val r2 = RegInit(y) // width will be inferred
- * }}}
- *
- * 3. [[Aggregate]] initializer - width will be set to match the aggregate
- *
- * {{{
- * class MyBundle {
- * val unknown = UInt()
- * val known = UInt(8.W)
- * }
- * val w1 = Reg(new MyBundle)
- * val w2 = RegInit(w1)
- * // Width of w2.unknown is inferred
- * // Width of w2.known is set to 8
- * }}}
- *
- * ==Double Argument==
- * The double argument form allows the type of the [[Reg]] and the default connection to be
- * specified independently.
- *
- * The width inference semantics for `RegInit` with two arguments match those of [[Reg]]. The
- * first argument to `RegInit` is the type template which defines the width of the `Reg` in
- * exactly the same way as the only argument to [[Wire]].
- *
- * More explicitly, you can reason about `RegInit` with multiple arguments as if it were defined
- * as:
- * {{{
- * def RegInit[T <: Data](t: T, init: T): T = {
- * val x = Reg(t)
- * x := init
- * x
- * }
- * }}}
- */
-object RegInit {
- /** Construct a [[Reg]] from a type template initialized to the specified value on reset
- * @param t The type template used to construct this [[Reg]]
- * @param init The value the [[Reg]] is initialized to on reset
- */
- def apply[T <: Data](t: T, init: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
- if (compileOptions.declaredTypeMustBeUnbound) {
- requireIsChiselType(t, "reg type")
- }
- val reg = t.cloneTypeFull
- val clock = Builder.forcedClock.ref
- val reset = Builder.forcedReset.ref
-
- reg.bind(RegBinding(Builder.forcedUserModule))
- requireIsHardware(init, "reg initializer")
- pushCommand(DefRegInit(sourceInfo, reg, clock, reset, init.ref))
- reg
- }
-
- /** Construct a [[Reg]] initialized on reset to the specified value.
- * @param init Initial value that serves as a type template and reset value
- */
- def apply[T <: Data](init: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
- val model = (init match {
- // If init is a literal without forced width OR any non-literal, let width be inferred
- case init: Bits if !init.litIsForcedWidth.getOrElse(false) => init.cloneTypeWidth(Width())
- case init => init.cloneTypeFull
- }).asInstanceOf[T]
- RegInit(model, init)
- }
-
-}
diff --git a/chiselFrontend/src/main/scala/chisel3/core/SeqUtils.scala b/chiselFrontend/src/main/scala/chisel3/core/SeqUtils.scala
deleted file mode 100644
index f15fb178..00000000
--- a/chiselFrontend/src/main/scala/chisel3/core/SeqUtils.scala
+++ /dev/null
@@ -1,127 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3.core
-
-import chisel3.internal.throwException
-
-import scala.language.experimental.macros
-import chisel3.internal.sourceinfo._
-
-//scalastyle:off method.name
-
-private[chisel3] object SeqUtils {
- /** Concatenates the data elements of the input sequence, in sequence order, together.
- * The first element of the sequence forms the least significant bits, while the last element
- * in the sequence forms the most significant bits.
- *
- * Equivalent to r(n-1) ## ... ## r(1) ## r(0).
- */
- def asUInt[T <: Bits](in: Seq[T]): UInt = macro SourceInfoTransform.inArg
-
- /** @group SourceInfoTransformMacros */
- def do_asUInt[T <: Bits](in: Seq[T])(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = {
- if (in.tail.isEmpty) {
- in.head.asUInt
- } else {
- val left = asUInt(in.slice(0, in.length/2))
- val right = asUInt(in.slice(in.length/2, in.length))
- right ## left
- }
- }
-
- /** Outputs the number of elements that === true.B.
- */
- def count(in: Seq[Bool]): UInt = macro SourceInfoTransform.inArg
-
- /** @group SourceInfoTransformMacros */
- def do_count(in: Seq[Bool])(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = in.size match {
- case 0 => 0.U
- case 1 => in.head
- case n =>
- val sum = count(in take n/2) +& count(in drop n/2)
- sum(BigInt(n).bitLength - 1, 0)
- }
-
- /** Returns the data value corresponding to the first true predicate.
- */
- def priorityMux[T <: Data](in: Seq[(Bool, T)]): T = macro SourceInfoTransform.inArg
-
- /** @group SourceInfoTransformMacros */
- def do_priorityMux[T <: Data](in: Seq[(Bool, T)])
- (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
- if (in.size == 1) {
- in.head._2
- } else {
- Mux(in.head._1, in.head._2, priorityMux(in.tail))
- }
- }
-
- /** Returns the data value corresponding to the lone true predicate.
- * This is elaborated to firrtl using a structure that should be optimized into and and/or tree.
- *
- * @note assumes exactly one true predicate, results undefined otherwise
- * FixedPoint values or aggregates containing FixedPoint values cause this optimized structure to be lost
- */
- def oneHotMux[T <: Data](in: Iterable[(Bool, T)]): T = macro SourceInfoTransform.inArg
-
- //scalastyle:off method.length cyclomatic.complexity
- /** @group SourceInfoTransformMacros */
- def do_oneHotMux[T <: Data](in: Iterable[(Bool, T)])
- (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
- if (in.tail.isEmpty) {
- in.head._2
- }
- else {
- val output = cloneSupertype(in.toSeq map { _._2}, "oneHotMux")
-
- def buildAndOrMultiplexor[TT <: Data](inputs: Iterable[(Bool, TT)]): T = {
- val masked = for ((s, i) <- inputs) yield Mux(s, i.asUInt(), 0.U)
- masked.reduceLeft(_ | _).asTypeOf(output)
- }
-
- output match {
- case _: SInt =>
- // SInt's have to be managed carefully so sign extension works
-
- val sInts: Iterable[(Bool, SInt)] = in.collect { case (s: Bool, f: SInt) =>
- (s, f.asTypeOf(output).asInstanceOf[SInt])
- }
-
- val masked = for ((s, i) <- sInts) yield Mux(s, i, 0.S)
- masked.reduceLeft(_ | _).asTypeOf(output)
-
- case _: FixedPoint =>
- val (sels, possibleOuts) = in.toSeq.unzip
-
- val (intWidths, binaryPoints) = in.toSeq.map { case (_, o) =>
- val fo = o.asInstanceOf[FixedPoint]
- require(fo.binaryPoint.known, "Mux1H requires width/binary points to be defined")
- (fo.getWidth - fo.binaryPoint.get, fo.binaryPoint.get)
- }.unzip
-
- if (intWidths.distinct.length == 1 && binaryPoints.distinct.length == 1) {
- buildAndOrMultiplexor(in)
- }
- else {
- val maxIntWidth = intWidths.max
- val maxBP = binaryPoints.max
- val inWidthMatched = Seq.fill(intWidths.length)(Wire(FixedPoint((maxIntWidth + maxBP).W, maxBP.BP)))
- inWidthMatched.zipWithIndex foreach { case (e, idx) => e := possibleOuts(idx).asInstanceOf[FixedPoint] }
- buildAndOrMultiplexor(sels.zip(inWidthMatched))
- }
-
- case _: Aggregate =>
- val allDefineWidth = in.forall { case (_, element) => element.widthOption.isDefined }
- if(allDefineWidth) {
- buildAndOrMultiplexor(in)
- }
- else {
- throwException(s"Cannot Mux1H with aggregates with inferred widths")
- }
-
- case _ =>
- buildAndOrMultiplexor(in)
- }
- }
- }
-}
diff --git a/chiselFrontend/src/main/scala/chisel3/core/StrongEnum.scala b/chiselFrontend/src/main/scala/chisel3/core/StrongEnum.scala
deleted file mode 100644
index 63f7a8a0..00000000
--- a/chiselFrontend/src/main/scala/chisel3/core/StrongEnum.scala
+++ /dev/null
@@ -1,344 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3.core
-
-import scala.language.experimental.macros
-import scala.reflect.macros.blackbox.Context
-import scala.collection.mutable
-import chisel3.internal.Builder.pushOp
-import chisel3.internal.firrtl.PrimOp._
-import chisel3.internal.firrtl._
-import chisel3.internal.sourceinfo._
-import chisel3.internal.{Builder, InstanceId, throwException}
-import firrtl.annotations._
-
-
-object EnumAnnotations {
- /** An annotation for strong enum instances that are ''not'' inside of Vecs
- *
- * @param target the enum instance being annotated
- * @param typeName the name of the enum's type (e.g. ''"mypackage.MyEnum"'')
- */
- case class EnumComponentAnnotation(target: Named, enumTypeName: String) extends SingleTargetAnnotation[Named] {
- def duplicate(n: Named): EnumComponentAnnotation = this.copy(target = n)
- }
-
- case class EnumComponentChiselAnnotation(target: InstanceId, enumTypeName: String) extends ChiselAnnotation {
- def toFirrtl: EnumComponentAnnotation = EnumComponentAnnotation(target.toNamed, enumTypeName)
- }
-
- /** An annotation for Vecs of strong enums.
- *
- * The ''fields'' parameter deserves special attention, since it may be difficult to understand. Suppose you create a the following Vec:
-
- * {{{
- * VecInit(new Bundle {
- * val e = MyEnum()
- * val b = new Bundle {
- * val inner_e = MyEnum()
- * }
- * val v = Vec(3, MyEnum())
- * }
- * }}}
- *
- * Then, the ''fields'' parameter will be: ''Seq(Seq("e"), Seq("b", "inner_e"), Seq("v"))''. Note that for any Vec that doesn't contain Bundles, this field will simply be an empty Seq.
- *
- * @param target the Vec being annotated
- * @param typeName the name of the enum's type (e.g. ''"mypackage.MyEnum"'')
- * @param fields a list of all chains of elements leading from the Vec instance to its inner enum fields.
- *
- */
- case class EnumVecAnnotation(target: Named, typeName: String, fields: Seq[Seq[String]]) extends SingleTargetAnnotation[Named] {
- def duplicate(n: Named) = this.copy(target = n)
- }
-
- case class EnumVecChiselAnnotation(target: InstanceId, typeName: String, fields: Seq[Seq[String]]) extends ChiselAnnotation {
- override def toFirrtl = EnumVecAnnotation(target.toNamed, typeName, fields)
- }
-
- /** An annotation for enum types (rather than enum ''instances'').
- *
- * @param typeName the name of the enum's type (e.g. ''"mypackage.MyEnum"'')
- * @param definition a map describing which integer values correspond to which enum names
- */
- case class EnumDefAnnotation(typeName: String, definition: Map[String, BigInt]) extends NoTargetAnnotation
-
- case class EnumDefChiselAnnotation(typeName: String, definition: Map[String, BigInt]) extends ChiselAnnotation {
- override def toFirrtl: Annotation = EnumDefAnnotation(typeName, definition)
- }
-}
-import EnumAnnotations._
-
-
-abstract class EnumType(private val factory: EnumFactory, selfAnnotating: Boolean = true) extends Element {
- override def toString: String = {
- val bindingString = litOption match {
- case Some(value) => factory.nameOfValue(value) match {
- case Some(name) => s"($value=$name)"
- case None => s"($value=(invalid))"
- }
- case _ => bindingToString
- }
- // Use getSimpleName instead of enumTypeName because for debugging purposes the fully qualified name isn't
- // necessary (compared to for the Enum annotation), and it's more consistent with Bundle printing.
- s"${factory.getClass.getSimpleName.init}$bindingString"
- }
-
- override def cloneType: this.type = factory().asInstanceOf[this.type]
-
- private[core] def compop(sourceInfo: SourceInfo, op: PrimOp, other: EnumType): Bool = {
- requireIsHardware(this, "bits operated on")
- requireIsHardware(other, "bits operated on")
-
- if(!this.typeEquivalent(other)) {
- throwException(s"Enum types are not equivalent: ${this.enumTypeName}, ${other.enumTypeName}")
- }
-
- pushOp(DefPrim(sourceInfo, Bool(), op, this.ref, other.ref))
- }
-
- private[core] override def typeEquivalent(that: Data): Boolean = {
- this.getClass == that.getClass &&
- this.factory == that.asInstanceOf[EnumType].factory
- }
-
- private[core] override def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions): Unit = {
- this := factory.apply(that.asUInt)
- }
-
- final def === (that: EnumType): Bool = macro SourceInfoTransform.thatArg
- final def =/= (that: EnumType): Bool = macro SourceInfoTransform.thatArg
- final def < (that: EnumType): Bool = macro SourceInfoTransform.thatArg
- final def <= (that: EnumType): Bool = macro SourceInfoTransform.thatArg
- final def > (that: EnumType): Bool = macro SourceInfoTransform.thatArg
- final def >= (that: EnumType): Bool = macro SourceInfoTransform.thatArg
-
- // scalastyle:off line.size.limit method.name
- def do_=== (that: EnumType)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, EqualOp, that)
- def do_=/= (that: EnumType)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, NotEqualOp, that)
- def do_< (that: EnumType)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, LessOp, that)
- def do_> (that: EnumType)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, GreaterOp, that)
- def do_<= (that: EnumType)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, LessEqOp, that)
- def do_>= (that: EnumType)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, GreaterEqOp, that)
- // scalastyle:on line.size.limit method.name
-
- override def do_asUInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
- pushOp(DefPrim(sourceInfo, UInt(width), AsUIntOp, ref))
-
- protected[chisel3] override def width: Width = factory.width
-
- def isValid(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = {
- if (litOption.isDefined) {
- true.B
- } else {
- factory.all.map(this === _).reduce(_ || _)
- }
- }
-
- def next(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): this.type = {
- if (litOption.isDefined) {
- val index = factory.all.indexOf(this)
-
- if (index < factory.all.length-1) {
- factory.all(index + 1).asInstanceOf[this.type]
- } else {
- factory.all.head.asInstanceOf[this.type]
- }
- } else {
- val enums_with_nexts = factory.all zip (factory.all.tail :+ factory.all.head)
- val next_enum = SeqUtils.priorityMux(enums_with_nexts.map { case (e,n) => (this === e, n) } )
- next_enum.asInstanceOf[this.type]
- }
- }
-
- private[core] def bindToLiteral(num: BigInt, w: Width): Unit = {
- val lit = ULit(num, w)
- lit.bindLitArg(this)
- }
-
- override private[chisel3] def bind(target: Binding, parentDirection: SpecifiedDirection = SpecifiedDirection.Unspecified): Unit = {
- super.bind(target, parentDirection)
-
- // Make sure we only annotate hardware and not literals
- if (selfAnnotating && isSynthesizable && topBindingOpt.get.isInstanceOf[ConstrainedBinding]) {
- annotateEnum()
- }
- }
-
- // This function conducts a depth-wise search to find all enum-type fields within a vector or bundle (or vector of bundles)
- private def enumFields(d: Aggregate): Seq[Seq[String]] = d match {
- case v: Vec[_] => v.sample_element match {
- case b: Bundle => enumFields (b)
- case _ => Seq ()
- }
- case b: Bundle =>
- b.elements.collect {
- case (name, e: EnumType) if this.typeEquivalent(e) => Seq(Seq(name))
- case (name, v: Vec[_]) if this.typeEquivalent(v.sample_element) => Seq(Seq(name))
- case (name, b2: Bundle) => enumFields(b2).map(name +: _)
- }.flatten.toSeq
- }
-
- private def outerMostVec(d: Data = this): Option[Vec[_]] = {
- val currentVecOpt = d match {
- case v: Vec[_] => Some(v)
- case _ => None
- }
-
- d.binding match {
- case Some(ChildBinding(parent)) => outerMostVec(parent) match {
- case outer @ Some(_) => outer
- case None => currentVecOpt
- }
- case _ => currentVecOpt
- }
- }
-
- private def annotateEnum(): Unit = {
- val anno = outerMostVec() match {
- case Some(v) => EnumVecChiselAnnotation(v, enumTypeName, enumFields(v))
- case None => EnumComponentChiselAnnotation(this, enumTypeName)
- }
-
- if (!Builder.annotations.contains(anno)) {
- annotate(anno)
- }
-
- if (!Builder.annotations.contains(factory.globalAnnotation)) {
- annotate(factory.globalAnnotation)
- }
- }
-
- protected def enumTypeName: String = factory.enumTypeName
-
- def toPrintable: Printable = FullName(this) // TODO: Find a better pretty printer
-}
-
-
-abstract class EnumFactory {
- class Type extends EnumType(this)
- object Type {
- def apply(): Type = EnumFactory.this.apply()
- }
-
- private var id: BigInt = 0
- private[core] var width: Width = 0.W
-
- private case class EnumRecord(inst: Type, name: String)
- private val enum_records = mutable.ArrayBuffer.empty[EnumRecord]
-
- private def enumNames = enum_records.map(_.name).toSeq
- private def enumValues = enum_records.map(_.inst.litValue()).toSeq
- private def enumInstances = enum_records.map(_.inst).toSeq
-
- private[core] val enumTypeName = getClass.getName.init
-
- private[core] def globalAnnotation: EnumDefChiselAnnotation =
- EnumDefChiselAnnotation(enumTypeName, (enumNames, enumValues).zipped.toMap)
-
- def getWidth: Int = width.get
-
- def all: Seq[Type] = enumInstances
-
- private[chisel3] def nameOfValue(id: BigInt): Option[String] = {
- enum_records.find(_.inst.litValue() == id).map(_.name)
- }
-
- protected def Value: Type = macro EnumMacros.ValImpl // scalastyle:off method.name
- protected def Value(id: UInt): Type = macro EnumMacros.ValCustomImpl // scalastyle:off method.name
-
- protected def do_Value(names: Seq[String]): Type = {
- val result = new Type
-
- // We have to use UnknownWidth here, because we don't actually know what the final width will be
- result.bindToLiteral(id, UnknownWidth())
-
- val result_name = names.find(!enumNames.contains(_)).get
- enum_records.append(EnumRecord(result, result_name))
-
- width = (1 max id.bitLength).W
- id += 1
-
- result
- }
-
- protected def do_Value(names: Seq[String], id: UInt): Type = {
- // TODO: These throw ExceptionInInitializerError which can be confusing to the user. Get rid of the error, and just
- // throw an exception
- if (id.litOption.isEmpty) {
- throwException(s"$enumTypeName defined with a non-literal type")
- }
- if (id.litValue() < this.id) {
- throwException(s"Enums must be strictly increasing: $enumTypeName")
- }
-
- this.id = id.litValue()
- do_Value(names)
- }
-
- def apply(): Type = new Type
-
- def apply(n: UInt)(implicit sourceInfo: SourceInfo, connectionCompileOptions: CompileOptions): Type = {
- // scalastyle:off line.size.limit
- if (n.litOption.isDefined) {
- enumInstances.find(_.litValue == n.litValue) match {
- case Some(result) => result
- case None => throwException(s"${n.litValue} is not a valid value for $enumTypeName")
- }
- } else if (!n.isWidthKnown) {
- throwException(s"Non-literal UInts being cast to $enumTypeName must have a defined width")
- } else if (n.getWidth > this.getWidth) {
- throwException(s"The UInt being cast to $enumTypeName is wider than $enumTypeName's width ($getWidth)")
- } else {
- Builder.warning(s"Casting non-literal UInt to $enumTypeName. You can check that its value is legal by calling isValid")
-
- val glue = Wire(new UnsafeEnum(width))
- glue := n
- val result = Wire(new Type)
- result := glue
- result
- }
- }
- // scalastyle:on line.size.limit
-}
-
-
-private[core] object EnumMacros {
- def ValImpl(c: Context) : c.Tree = { // scalastyle:off method.name
- import c.universe._
- val names = getNames(c)
- q"""this.do_Value(Seq(..$names))"""
- }
-
- def ValCustomImpl(c: Context)(id: c.Expr[UInt]): c.universe.Tree = { // scalastyle:off method.name
- import c.universe._
- val names = getNames(c)
- q"""this.do_Value(Seq(..$names), $id)"""
- }
-
- // Much thanks to Travis Brown for this solution:
- // stackoverflow.com/questions/18450203/retrieve-the-name-of-the-value-a-scala-macro-invocation-will-be-assigned-to
- def getNames(c: Context): Seq[String] = {
- import c.universe._
-
- val names = c.enclosingClass.collect {
- case ValDef(_, name, _, rhs)
- if rhs.pos == c.macroApplication.pos => name.decodedName.toString
- }
-
- if (names.isEmpty) {
- c.abort(c.enclosingPosition, "Value cannot be called without assigning to an enum")
- }
-
- names
- }
-}
-
-
-// This is an enum type that can be connected directly to UInts. It is used as a "glue" to cast non-literal UInts
-// to enums.
-private[chisel3] class UnsafeEnum(override val width: Width) extends EnumType(UnsafeEnum, selfAnnotating = false) {
- override def cloneType: this.type = new UnsafeEnum(width).asInstanceOf[this.type]
-}
-private object UnsafeEnum extends EnumFactory
diff --git a/chiselFrontend/src/main/scala/chisel3/core/When.scala b/chiselFrontend/src/main/scala/chisel3/core/When.scala
deleted file mode 100644
index 78fc0fc5..00000000
--- a/chiselFrontend/src/main/scala/chisel3/core/When.scala
+++ /dev/null
@@ -1,85 +0,0 @@
-// See LICENSE for license details.
-
-package chisel3.core
-
-import scala.language.experimental.macros
-
-import chisel3.internal._
-import chisel3.internal.Builder.pushCommand
-import chisel3.internal.firrtl._
-import chisel3.internal.sourceinfo.{SourceInfo}
-
-object when { // scalastyle:ignore object.name
- /** Create a `when` condition block, where whether a block of logic is
- * executed or not depends on the conditional.
- *
- * @param cond condition to execute upon
- * @param block logic that runs only if `cond` is true
- *
- * @example
- * {{{
- * when ( myData === 3.U ) {
- * // Some logic to run when myData equals 3.
- * } .elsewhen ( myData === 1.U ) {
- * // Some logic to run when myData equals 1.
- * } .otherwise {
- * // Some logic to run when myData is neither 3 nor 1.
- * }
- * }}}
- */
-
- def apply(cond: => Bool)(block: => Unit)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): WhenContext = { // scalastyle:ignore line.size.limit
- new WhenContext(sourceInfo, Some(() => cond), block)
- }
-}
-
-/** A WhenContext may represent a when, and elsewhen, or an
- * otherwise. Since FIRRTL does not have an "elsif" statement,
- * alternatives must be mapped to nested if-else statements inside
- * the alternatives of the preceeding condition. In order to emit
- * proper FIRRTL, it is necessary to keep track of the depth of
- * nesting of the FIRRTL whens. Due to the "thin frontend" nature of
- * Chisel3, it is not possible to know if a when or elsewhen has a
- * succeeding elsewhen or otherwise; therefore, this information is
- * added by preprocessing the command queue.
- */
-final class WhenContext(sourceInfo: SourceInfo, cond: Option[() => Bool], block: => Unit, firrtlDepth: Int = 0) {
-
- /** This block of logic gets executed if above conditions have been
- * false and this condition is true. The lazy argument pattern
- * makes it possible to delay evaluation of cond, emitting the
- * declaration and assignment of the Bool node of the predicate in
- * the correct place.
- */
- def elsewhen (elseCond: => Bool)(block: => Unit)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): WhenContext = { // scalastyle:ignore line.size.limit
- new WhenContext(sourceInfo, Some(() => elseCond), block, firrtlDepth + 1)
- }
-
- /** This block of logic gets executed only if the above conditions
- * were all false. No additional logic blocks may be appended past
- * the `otherwise`. The lazy argument pattern makes it possible to
- * delay evaluation of cond, emitting the declaration and
- * assignment of the Bool node of the predicate in the correct
- * place.
- */
- def otherwise(block: => Unit)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Unit =
- new WhenContext(sourceInfo, None, block, firrtlDepth + 1)
-
- /*
- *
- */
- if (firrtlDepth > 0) { pushCommand(AltBegin(sourceInfo)) }
- cond.foreach( c => pushCommand(WhenBegin(sourceInfo, c().ref)) )
- Builder.whenDepth += 1
- try {
- block
- } catch {
- case ret: scala.runtime.NonLocalReturnControl[_] =>
- throwException("Cannot exit from a when() block with a \"return\"!" +
- " Perhaps you meant to use Mux or a Wire as a return value?"
- )
- }
- Builder.whenDepth -= 1
- cond.foreach( c => pushCommand(WhenEnd(sourceInfo,firrtlDepth)) )
- if (cond.isEmpty) { pushCommand(OtherwiseEnd(sourceInfo,firrtlDepth)) }
-}
diff --git a/chiselFrontend/src/main/scala/chisel3/core/package.scala b/chiselFrontend/src/main/scala/chisel3/core/package.scala
index 46db337b..ac69ca33 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/package.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/package.scala
@@ -1,133 +1,293 @@
// See LICENSE for license details.
-package chisel3 {
- import internal.Builder
-
- package object core {
- import internal.firrtl.{Width, BinaryPoint}
-
- /**
- * These implicit classes allow one to convert scala.Int|scala.BigInt to
- * Chisel.UInt|Chisel.SInt by calling .asUInt|.asSInt on them, respectively.
- * The versions .asUInt(width)|.asSInt(width) are also available to explicitly
- * mark a width for the new literal.
- *
- * Also provides .asBool to scala.Boolean and .asUInt to String
- *
- * Note that, for stylistic reasons, one should avoid extracting immediately
- * after this call using apply, ie. 0.asUInt(1)(0) due to potential for
- * confusion (the 1 is a bit length and the 0 is a bit extraction position).
- * Prefer storing the result and then extracting from it.
- *
- * Implementation note: the empty parameter list (like `U()`) is necessary to prevent
- * interpreting calls that have a non-Width parameter as a chained apply, otherwise things like
- * `0.asUInt(16)` (instead of `16.W`) compile without error and produce undesired results.
- */
- implicit class fromBigIntToLiteral(bigint: BigInt) {
- /** Int to Bool conversion, allowing compact syntax like 1.B and 0.B
- */
- def B: Bool = bigint match { // scalastyle:ignore method.name
- case bigint if bigint == 0 => Bool.Lit(false)
- case bigint if bigint == 1 => Bool.Lit(true)
- case bigint => Builder.error(s"Cannot convert $bigint to Bool, must be 0 or 1"); Bool.Lit(false)
- }
- /** Int to UInt conversion, recommended style for constants.
- */
- def U: UInt = UInt.Lit(bigint, Width()) // scalastyle:ignore method.name
- /** Int to SInt conversion, recommended style for constants.
- */
- def S: SInt = SInt.Lit(bigint, Width()) // scalastyle:ignore method.name
- /** Int to UInt conversion with specified width, recommended style for constants.
- */
- def U(width: Width): UInt = UInt.Lit(bigint, width) // scalastyle:ignore method.name
- /** Int to SInt conversion with specified width, recommended style for constants.
- */
- def S(width: Width): SInt = SInt.Lit(bigint, width) // scalastyle:ignore method.name
-
- /** Int to UInt conversion, recommended style for variables.
- */
- def asUInt(): UInt = UInt.Lit(bigint, Width())
- /** Int to SInt conversion, recommended style for variables.
- */
- def asSInt(): SInt = SInt.Lit(bigint, Width())
- /** Int to UInt conversion with specified width, recommended style for variables.
- */
- def asUInt(width: Width): UInt = UInt.Lit(bigint, width)
- /** Int to SInt conversion with specified width, recommended style for variables.
- */
- def asSInt(width: Width): SInt = SInt.Lit(bigint, width)
- }
-
- implicit class fromIntToLiteral(int: Int) extends fromBigIntToLiteral(int)
- implicit class fromLongToLiteral(long: Long) extends fromBigIntToLiteral(long)
-
- implicit class fromStringToLiteral(str: String) {
- /** String to UInt parse, recommended style for constants.
- */
- def U: UInt = str.asUInt() // scalastyle:ignore method.name
- /** String to UInt parse with specified width, recommended style for constants.
- */
- def U(width: Width): UInt = str.asUInt(width) // scalastyle:ignore method.name
-
- /** String to UInt parse, recommended style for variables.
- */
- def asUInt(): UInt = {
- val bigInt = parse(str)
- UInt.Lit(bigInt, Width(bigInt.bitLength max 1))
- }
- /** String to UInt parse with specified width, recommended style for variables.
- */
- def asUInt(width: Width): UInt = UInt.Lit(parse(str), width)
-
- protected def parse(n: String) = {
- val (base, num) = n.splitAt(1)
- val radix = base match {
- case "x" | "h" => 16
- case "d" => 10
- case "o" => 8
- case "b" => 2
- case _ => Builder.error(s"Invalid base $base"); 2
- }
- BigInt(num.filterNot(_ == '_'), radix)
- }
- }
-
- implicit class fromBooleanToLiteral(boolean: Boolean) {
- /** Boolean to Bool conversion, recommended style for constants.
- */
- def B: Bool = Bool.Lit(boolean) // scalastyle:ignore method.name
-
- /** Boolean to Bool conversion, recommended style for variables.
- */
- def asBool(): Bool = Bool.Lit(boolean)
- }
-
- //scalastyle:off method.name
- implicit class fromDoubleToLiteral(double: Double) {
- @deprecated("Use notation <double>.F(<binary_point>.BP) instead", "chisel3")
- def F(binaryPoint: Int): FixedPoint = FixedPoint.fromDouble(double, binaryPoint = binaryPoint)
- def F(binaryPoint: BinaryPoint): FixedPoint = {
- FixedPoint.fromDouble(double, Width(), binaryPoint)
- }
- def F(width: Width, binaryPoint: BinaryPoint): FixedPoint = {
- FixedPoint.fromDouble(double, width, binaryPoint)
- }
- }
-
- implicit class fromIntToWidth(int: Int) {
- def W: Width = Width(int) // scalastyle:ignore method.name
- }
-
- implicit class fromIntToBinaryPoint(int: Int) {
- def BP: BinaryPoint = BinaryPoint(int) // scalastyle:ignore method.name
- }
-
- // These provide temporary compatibility for those who foolishly imported from chisel3.core
- @deprecated("Avoid importing from chisel3.core, these are not public APIs and may change at any time. " +
- " Use chisel3.experimental.RawModule instead.", "since the beginning of time")
- type UserModule = chisel3.core.RawModule
- @deprecated("Avoid importing from chisel3.core, these are not public APIs and may change at any time. " +
- "Use chisel3.experimental.MultiIOModule instead.", "since the beginning of time")
- type ImplicitModule = chisel3.core.MultiIOModule
- }
+package chisel3
+
+package object core {
+
+ /**
+ * These definitions exist to deal with those clients that relied on chisel3.core
+ * They will be deprecated in the future.
+ */
+ @deprecated("Use the version in chisel3._", "3.3")
+ val CompileOptions = chisel3.CompileOptions
+
+ @deprecated("Use the version in chisel3._", "3.3")
+ val Input = chisel3.Input
+ @deprecated("Use the version in chisel3._", "3.3")
+ val Output = chisel3.Output
+ @deprecated("Use the version in chisel3._", "3.3")
+ val Flipped = chisel3.Flipped
+ @deprecated("Use the version in chisel3._", "3.3")
+ val chiselTypeOf = chisel3.chiselTypeOf
+
+ @deprecated("Use the version in chisel3._", "3.3")
+ type Data = chisel3.Data
+
+ @deprecated("Use the version in chisel3._", "3.3")
+ val WireDefault = chisel3.WireDefault
+
+ @deprecated("Use the version in chisel3._", "3.3")
+ val Clock = chisel3.Clock
+ @deprecated("Use the version in chisel3._", "3.3")
+ type Clock = chisel3.Clock
+
+ @deprecated("Use the version in chisel3._", "3.3")
+ type Reset = chisel3.Reset
+
+ @deprecated("Use the version in chisel3._", "3.3")
+ type Aggregate = chisel3.Aggregate
+
+ @deprecated("Use the version in chisel3._", "3.3")
+ val Vec = chisel3.Vec
+ @deprecated("Use the version in chisel3._", "3.3")
+ val VecInit = chisel3.VecInit
+ @deprecated("Use the version in chisel3._", "3.3")
+ type Vec[T <: Data] = chisel3.Vec[T]
+ @deprecated("Use the version in chisel3._", "3.3")
+ type VecLike[T <: Data] = chisel3.VecLike[T]
+ @deprecated("Use the version in chisel3._", "3.3")
+ type Bundle = chisel3.Bundle
+ @deprecated("Use the version in chisel3._", "3.3")
+ type IgnoreSeqInBundle = chisel3.IgnoreSeqInBundle
+ @deprecated("Use the version in chisel3._", "3.3")
+ type Record = chisel3.Record
+
+ @deprecated("Use the version in chisel3._", "3.3")
+ val assert = chisel3.assert
+
+ @deprecated("Use the version in chisel3._", "3.3")
+ type Element = chisel3.Element
+ @deprecated("Use the version in chisel3._", "3.3")
+ type Bits = chisel3.Bits
+
+ // These provide temporary compatibility for those who foolishly imported from chisel3.core
+ @deprecated("Avoid importing from chisel3.core, these are not public APIs and may change at any time. " +
+ " Use chisel3.experimental.RawModule instead.", "since the beginning of time")
+ type RawModule = chisel3.experimental.RawModule
+ @deprecated("Avoid importing from chisel3.core, these are not public APIs and may change at any time. " +
+ "Use chisel3.experimental.MultiIOModule instead.", "since the beginning of time")
+ type MultiIOModule = chisel3.experimental.MultiIOModule
+ @deprecated("Avoid importing from chisel3.core, these are not public APIs and may change at any time. " +
+ " Use chisel3.experimental.RawModule instead.", "since the beginning of time")
+ type UserModule = chisel3.experimental.RawModule
+ @deprecated("Avoid importing from chisel3.core, these are not public APIs and may change at any time. " +
+ "Use chisel3.experimental.MultiIOModule instead.", "since the beginning of time")
+ type ImplicitModule = chisel3.experimental.MultiIOModule
+
+ @deprecated("Use the version in chisel3._", "3.3")
+ val Bits = chisel3.Bits
+ @deprecated("Use the version in chisel3._", "3.3")
+ type Num[T <: chisel3.Data] = chisel3.Num[T]
+ @deprecated("Use the version in chisel3._", "3.3")
+ type UInt = chisel3.UInt
+ @deprecated("Use the version in chisel3._", "3.3")
+ val UInt = chisel3.UInt
+ @deprecated("Use the version in chisel3._", "3.3")
+ type SInt = chisel3.SInt
+ @deprecated("Use the version in chisel3._", "3.3")
+ val SInt = chisel3.SInt
+ @deprecated("Use the version in chisel3._", "3.3")
+ type Bool = chisel3.Bool
+ @deprecated("Use the version in chisel3._", "3.3")
+ val Bool = chisel3.Bool
+ @deprecated("Use the version in chisel3._", "3.3")
+ val Mux = chisel3.Mux
+
+ @deprecated("Use the version in chisel3._", "3.3")
+ type BlackBox = chisel3.BlackBox
+
+ @deprecated("Use the version in chisel3._", "3.3")
+ val Mem = chisel3.Mem
+ @deprecated("Use the version in chisel3._", "3.3")
+ type MemBase[T <: chisel3.Data] = chisel3.MemBase[T]
+ @deprecated("Use the version in chisel3._", "3.3")
+ type Mem[T <: chisel3.Data] = chisel3.Mem[T]
+ @deprecated("Use the version in chisel3._", "3.3")
+ val SyncReadMem = chisel3.SyncReadMem
+ @deprecated("Use the version in chisel3._", "3.3")
+ type SyncReadMem[T <: chisel3.Data] = chisel3.SyncReadMem[T]
+
+ @deprecated("Use the version in chisel3._", "3.3")
+ val Module = chisel3.Module
+ @deprecated("Use the version in chisel3._", "3.3")
+ type Module = chisel3.Module
+
+ @deprecated("Use the version in chisel3._", "3.3")
+ val printf = chisel3.printf
+
+ @deprecated("Use the version in chisel3._", "3.3")
+ val RegNext = chisel3.RegNext
+ @deprecated("Use the version in chisel3._", "3.3")
+ val RegInit = chisel3.RegInit
+ @deprecated("Use the version in chisel3._", "3.3")
+ val Reg = chisel3.Reg
+
+ @deprecated("Use the version in chisel3._", "3.3")
+ val when = chisel3.when
+ @deprecated("Use the version in chisel3._", "3.3")
+ type WhenContext = chisel3.WhenContext
+
+ @deprecated("Use the version in chisel3._", "3.3")
+ type Printable = chisel3.Printable
+ @deprecated("Use the version in chisel3._", "3.3")
+ val Printable = chisel3.Printable
+ @deprecated("Use the version in chisel3._", "3.3")
+ type Printables = chisel3.Printables
+ @deprecated("Use the version in chisel3._", "3.3")
+ val Printables = chisel3.Printables
+ @deprecated("Use the version in chisel3._", "3.3")
+ type PString = chisel3.PString
+ @deprecated("Use the version in chisel3._", "3.3")
+ val PString = chisel3.PString
+ @deprecated("Use the version in chisel3._", "3.3")
+ type FirrtlFormat = chisel3.FirrtlFormat
+ @deprecated("Use the version in chisel3._", "3.3")
+ val FirrtlFormat = chisel3.FirrtlFormat
+ @deprecated("Use the version in chisel3._", "3.3")
+ type Decimal = chisel3.Decimal
+ @deprecated("Use the version in chisel3._", "3.3")
+ val Decimal = chisel3.Decimal
+ @deprecated("Use the version in chisel3._", "3.3")
+ type Hexadecimal = chisel3.Hexadecimal
+ val Hexadecimal = chisel3.Hexadecimal
+ @deprecated("Use the version in chisel3._", "3.3")
+ type Binary = chisel3.Binary
+ @deprecated("Use the version in chisel3._", "3.3")
+ val Binary = chisel3.Binary
+ @deprecated("Use the version in chisel3._", "3.3")
+ type Character = chisel3.Character
+ @deprecated("Use the version in chisel3._", "3.3")
+ val Character = chisel3.Character
+ @deprecated("Use the version in chisel3._", "3.3")
+ type Name = chisel3.Name
+ @deprecated("Use the version in chisel3._", "3.3")
+ val Name = chisel3.Name
+ @deprecated("Use the version in chisel3._", "3.3")
+ type FullName = chisel3.FullName
+ @deprecated("Use the version in chisel3._", "3.3")
+ val FullName = chisel3.FullName
+ @deprecated("Use the version in chisel3._", "3.3")
+ val Percent = chisel3.Percent
+
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ type Param = chisel3.experimental.Param
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ type IntParam = chisel3.experimental.IntParam
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ val IntParam = chisel3.experimental.IntParam
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ type DoubleParam = chisel3.experimental.DoubleParam
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ val DoubleParam = chisel3.experimental.DoubleParam
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ type StringParam = chisel3.experimental.StringParam
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ val StringParam = chisel3.experimental.StringParam
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ type RawParam = chisel3.experimental.RawParam
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ val RawParam = chisel3.experimental.RawParam
+
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ type Analog = chisel3.experimental.Analog
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ val Analog = chisel3.experimental.Analog
+
+ @deprecated("Use the version in chisel3._", "3.3")
+ implicit class fromIntToWidth(int: Int) extends chisel3.fromIntToWidth(int)
+
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ val attach = chisel3.experimental.attach
+
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ type EnumType = chisel3.experimental.EnumType
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ type EnumFactory = chisel3.experimental.EnumFactory
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ val EnumAnnotations = chisel3.experimental.EnumAnnotations
+
+ @deprecated("Use the version in chisel3._", "3.3")
+ val withClockAndReset = chisel3.withClockAndReset
+ @deprecated("Use the version in chisel3._", "3.3")
+ val withClock = chisel3.withClock
+ @deprecated("Use the version in chisel3._", "3.3")
+ val withReset = chisel3.withReset
+
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ val dontTouch = chisel3.experimental.dontTouch
+
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ type BaseModule = chisel3.experimental.BaseModule
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ type ExtModule = chisel3.experimental.ExtModule
+
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ val IO = chisel3.experimental.IO
+
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ type FixedPoint = chisel3.experimental.FixedPoint
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ val FixedPoint = chisel3.experimental.FixedPoint
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ implicit class fromDoubleToLiteral(double: Double) extends experimental.FixedPoint.Implicits.fromDoubleToLiteral(double)
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ implicit class fromIntToBinaryPoint(int: Int) extends experimental.FixedPoint.Implicits.fromIntToBinaryPoint(int)
+
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ type ChiselAnnotation = chisel3.experimental.ChiselAnnotation
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ val ChiselAnnotation = chisel3.experimental.ChiselAnnotation
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ type RunFirrtlTransform = chisel3.experimental.RunFirrtlTransform
+
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ val annotate = chisel3.experimental.annotate
+
+ @deprecated("Use the version in chisel3.experimental._", "3.3")
+ val DataMirror = chisel3.experimental.DataMirror
+ @deprecated("Use the version in chisel3._", "3.3")
+ type ActualDirection = chisel3.ActualDirection
+ @deprecated("Use the version in chisel3._", "3.3")
+ val ActualDirection = chisel3.ActualDirection
+
+ @deprecated("Use the version in chisel3.internal._", "3.3")
+ val requireIsHardware = chisel3.internal.requireIsHardware
+ @deprecated("Use the version in chisel3.internal._", "3.3")
+ val requireIsChiselType = chisel3.internal.requireIsChiselType
+ @deprecated("Use the version in chisel3.internal._", "3.3")
+ val BiConnect = chisel3.internal.BiConnect
+ @deprecated("Use the version in chisel3.internal._", "3.3")
+ val MonoConnect = chisel3.internal.MonoConnect
+ @deprecated("Use the version in chisel3.internal._", "3.3")
+ val BindingDirection = chisel3.internal.BindingDirection
+ @deprecated("Use the version in chisel3.internal._", "3.3")
+ type Binding = chisel3.internal.Binding
+ @deprecated("Use the version in chisel3.internal._", "3.3")
+ type TopBinding = chisel3.internal.TopBinding
+ @deprecated("Use the version in chisel3.internal._", "3.3")
+ type UnconstrainedBinding = chisel3.internal.UnconstrainedBinding
+ @deprecated("Use the version in chisel3.internal._", "3.3")
+ type ConstrainedBinding = chisel3.internal.ConstrainedBinding
+ @deprecated("Use the version in chisel3.internal._", "3.3")
+ type ReadOnlyBinding = chisel3.internal.ReadOnlyBinding
+ @deprecated("Use the version in chisel3.internal._", "3.3")
+ type OpBinding = chisel3.internal.OpBinding
+ @deprecated("Use the version in chisel3.internal._", "3.3")
+ type MemoryPortBinding = chisel3.internal.MemoryPortBinding
+ @deprecated("Use the version in chisel3.internal._", "3.3")
+ type PortBinding = chisel3.internal.PortBinding
+ @deprecated("Use the version in chisel3.internal._", "3.3")
+ type RegBinding = chisel3.internal.RegBinding
+ @deprecated("Use the version in chisel3.internal._", "3.3")
+ type WireBinding = chisel3.internal.WireBinding
+ @deprecated("Use the version in chisel3.internal._", "3.3")
+ type ChildBinding = chisel3.internal.ChildBinding
+ @deprecated("Use the version in chisel3.internal._", "3.3")
+ type DontCareBinding = chisel3.internal.DontCareBinding
+ @deprecated("Use the version in chisel3.internal._", "3.3")
+ type LitBinding = chisel3.internal.LitBinding
+ @deprecated("Use the version in chisel3.internal._", "3.3")
+ type ElementLitBinding = chisel3.internal.ElementLitBinding
+ @deprecated("Use the version in chisel3.internal._", "3.3")
+ type BundleLitBinding = chisel3.internal.BundleLitBinding
}