summaryrefslogtreecommitdiff
path: root/chiselFrontend/src/main/scala/Chisel/Aggregate.scala
diff options
context:
space:
mode:
Diffstat (limited to 'chiselFrontend/src/main/scala/Chisel/Aggregate.scala')
-rw-r--r--chiselFrontend/src/main/scala/Chisel/Aggregate.scala73
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:_*)