diff options
Diffstat (limited to 'chiselFrontend/src/main/scala/Chisel/Aggregate.scala')
| -rw-r--r-- | chiselFrontend/src/main/scala/Chisel/Aggregate.scala | 73 |
1 files changed, 52 insertions, 21 deletions
diff --git a/chiselFrontend/src/main/scala/Chisel/Aggregate.scala b/chiselFrontend/src/main/scala/Chisel/Aggregate.scala index 4d35e2f0..197135d7 100644 --- a/chiselFrontend/src/main/scala/Chisel/Aggregate.scala +++ b/chiselFrontend/src/main/scala/Chisel/Aggregate.scala @@ -4,10 +4,12 @@ package Chisel import scala.collection.immutable.ListMap import scala.collection.mutable.{ArrayBuffer, HashSet, LinkedHashMap} +import scala.language.experimental.macros import internal._ import internal.Builder.pushCommand import internal.firrtl._ +import internal.sourceinfo.{SourceInfo, DeprecatedSourceInfo, VecTransform, SourceInfoTransform} /** An abstract class for data types that solely consist of (are an aggregate * of) other Data objects. @@ -36,14 +38,15 @@ object Vec { * element * @note output elements are connected from the input elements */ - def apply[T <: Data](elts: Seq[T]): Vec[T] = { + def apply[T <: Data](elts: Seq[T]): Vec[T] = macro VecTransform.apply_elts + + def do_apply[T <: Data](elts: Seq[T])(implicit sourceInfo: SourceInfo): 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. - require(!elts.isEmpty) val width = elts.map(_.width).reduce(_ max _) val vec = Wire(new Vec(elts.head.cloneTypeWidth(width), elts.length)) @@ -60,7 +63,9 @@ object Vec { * element * @note output elements are connected from the input elements */ - def apply[T <: Data](elt0: T, elts: T*): Vec[T] = + def apply[T <: Data](elt0: T, elts: T*): Vec[T] = macro VecTransform.apply_elt0 + + def do_apply[T <: Data](elt0: T, elts: T*)(implicit sourceInfo: SourceInfo): Vec[T] = apply(elt0 +: elts.toSeq) /** Creates a new [[Vec]] of length `n` composed of the results of the given @@ -71,7 +76,9 @@ object Vec { * @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] = + def tabulate[T <: Data](n: Int)(gen: (Int) => T): Vec[T] = macro VecTransform.tabulate + + def do_tabulate[T <: Data](n: Int)(gen: (Int) => T)(implicit sourceInfo: SourceInfo): Vec[T] = apply((0 until n).map(i => gen(i))) /** Creates a new [[Vec]] of length `n` composed of the result of the given @@ -82,7 +89,10 @@ object Vec { * @param gen function that generates the [[Data]] that becomes the output * element */ - def fill[T <: Data](n: Int)(gen: => T): Vec[T] = apply(Seq.fill(n)(gen)) + def fill[T <: Data](n: Int)(gen: => T): Vec[T] = macro VecTransform.fill + + def do_fill[T <: Data](n: Int)(gen: => T)(implicit sourceInfo: SourceInfo): Vec[T] = + apply(Seq.fill(n)(gen)) } /** A vector (array) of [[Data]] elements. Provides hardware versions of various @@ -102,18 +112,18 @@ sealed class Vec[T <: Data] private (gen: => T, val length: Int) private val self = IndexedSeq.fill(length)(gen) - override def <> (that: Data): Unit = this := that + override def <> (that: Data)(implicit sourceInfo: SourceInfo): Unit = this := that /** 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]): Unit = this := that + def <> (that: Seq[T])(implicit sourceInfo: SourceInfo): Unit = this := that // TODO: eliminate once assign(Seq) isn't ambiguous with assign(Data) since Vec extends Seq and Data - def <> (that: Vec[T]): Unit = this := that.asInstanceOf[Data] + def <> (that: Vec[T])(implicit sourceInfo: SourceInfo): Unit = this := that.asInstanceOf[Data] - override def := (that: Data): Unit = that match { + override def := (that: Data)(implicit sourceInfo: SourceInfo): Unit = that match { case _: Vec[_] => this connect that case _ => this badConnect that } @@ -122,14 +132,14 @@ sealed class Vec[T <: Data] private (gen: => T, val length: Int) * * @note the length of this Vec must match the length of the input Seq */ - def := (that: Seq[T]): Unit = { + def := (that: Seq[T])(implicit sourceInfo: SourceInfo): 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]): Unit = this connect that + def := (that: Vec[T])(implicit sourceInfo: SourceInfo): Unit = this connect that /** Creates a dynamically indexed read or write accessor into the array. */ @@ -147,7 +157,7 @@ sealed class Vec[T <: Data] private (gen: => T, val length: Int) def read(idx: UInt): T = apply(idx) @deprecated("Use Vec.apply instead", "chisel3") - def write(idx: UInt, data: T): Unit = apply(idx) := data + def write(idx: UInt, data: T): Unit = apply(idx).:=(data)(DeprecatedSourceInfo) override def cloneType: this.type = Vec(length, gen).asInstanceOf[this.type] @@ -175,20 +185,32 @@ trait VecLike[T <: Data] extends collection.IndexedSeq[T] { /** Outputs true if p outputs true for every element. */ - def forall(p: T => Bool): Bool = (this map p).fold(Bool(true))(_ && _) + def forall(p: T => Bool): Bool = macro SourceInfoTransform.pArg + + def do_forall(p: T => Bool)(implicit sourceInfo: SourceInfo): Bool = + (this map p).fold(Bool(true))(_ && _) /** Outputs true if p outputs true for at least one element. */ - def exists(p: T => Bool): Bool = (this map p).fold(Bool(false))(_ || _) + def exists(p: T => Bool): Bool = macro SourceInfoTransform.pArg + + def do_exists(p: T => Bool)(implicit sourceInfo: SourceInfo): Bool = + (this map p).fold(Bool(false))(_ || _) /** Outputs true if the vector contains at least one element equal to x (using * the === operator). */ - def contains(x: T)(implicit evidence: T <:< UInt): Bool = this.exists(_ === x) + def contains(x: T)(implicit ev: T <:< UInt): Bool = macro VecTransform.contains + + def do_contains(x: T)(implicit sourceInfo: SourceInfo, ev: T <:< UInt): Bool = + this.exists(_ === x) /** Outputs the number of elements for which p is true. */ - def count(p: T => Bool): UInt = SeqUtils.count(this map p) + def count(p: T => Bool): UInt = macro SourceInfoTransform.pArg + + def do_count(p: T => Bool)(implicit sourceInfo: SourceInfo): 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. @@ -197,11 +219,17 @@ trait VecLike[T <: Data] extends collection.IndexedSeq[T] { /** Outputs the index of the first element for which p outputs true. */ - def indexWhere(p: T => Bool): UInt = SeqUtils.priorityMux(indexWhereHelper(p)) + def indexWhere(p: T => Bool): UInt = macro SourceInfoTransform.pArg + + def do_indexWhere(p: T => Bool)(implicit sourceInfo: SourceInfo): UInt = + SeqUtils.priorityMux(indexWhereHelper(p)) /** Outputs the index of the last element for which p outputs true. */ - def lastIndexWhere(p: T => Bool): UInt = SeqUtils.priorityMux(indexWhereHelper(p).reverse) + def lastIndexWhere(p: T => Bool): UInt = macro SourceInfoTransform.pArg + + def do_lastIndexWhere(p: T => Bool)(implicit sourceInfo: SourceInfo): 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. @@ -213,7 +241,10 @@ trait VecLike[T <: Data] extends collection.IndexedSeq[T] { * 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 = SeqUtils.oneHotMux(indexWhereHelper(p)) + def onlyIndexWhere(p: T => Bool): UInt = macro SourceInfoTransform.pArg + + def do_onlyIndexWhere(p: T => Bool)(implicit sourceInfo: SourceInfo): UInt = + SeqUtils.oneHotMux(indexWhereHelper(p)) } /** Base class for data types defined as a bundle of other data types. @@ -237,13 +268,13 @@ class Bundle extends Aggregate(NO_DIR) { * mySubModule.io <> io * }}} */ - override def <> (that: Data): Unit = that match { + override def <> (that: Data)(implicit sourceInfo: SourceInfo): Unit = that match { case _: Bundle => this bulkConnect that case _ => this badConnect that } // TODO: replace with better defined FIRRTL strong-connect operator - override def := (that: Data): Unit = this <> that + override def := (that: Data)(implicit sourceInfo: SourceInfo): Unit = this <> that lazy val elements: ListMap[String, Data] = ListMap(namedElts:_*) |
