summaryrefslogtreecommitdiff
path: root/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
diff options
context:
space:
mode:
Diffstat (limited to 'chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala')
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala70
1 files changed, 42 insertions, 28 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
index a453d5e0..1b49e163 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
@@ -14,9 +14,9 @@ import chisel3.internal.sourceinfo.{SourceInfo, DeprecatedSourceInfo, VecTransfo
/** An abstract class for data types that solely consist of (are an aggregate
* of) other Data objects.
*/
-sealed abstract class Aggregate(dirArg: Direction) extends Data(dirArg) {
- private[core] def cloneTypeWidth(width: Width): this.type = cloneType
- def width: Width = flatten.map(_.width).reduce(_ + _)
+sealed abstract class Aggregate extends Data {
+ private[chisel3] def cloneTypeWidth(width: Width): this.type = cloneType
+ private[chisel3] def width: Width = flatten.map(_.width).reduce(_ + _)
}
object Vec {
@@ -105,28 +105,40 @@ object Vec {
* intact to FIRRTL as a vector type, which may make debugging easier
*/
sealed class Vec[T <: Data] private (gen: => T, val length: Int)
- extends Aggregate(gen.dir) with VecLike[T] {
+ extends Aggregate with VecLike[T] {
// 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 = IndexedSeq.fill(length)(gen)
- override def <> (that: Data)(implicit sourceInfo: SourceInfo): Unit = this := that
+ /**
+ * sample_element 'tracks' all changes to the elements of self.
+ * 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[core] 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 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): Unit = this := that
+ 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])(implicit sourceInfo: SourceInfo): Unit = this := that.asInstanceOf[Data]
-
- override def := (that: Data)(implicit sourceInfo: SourceInfo): Unit = that match {
- case _: Vec[_] => this connect that
- case _ => this badConnect that
- }
+ def <> (that: Vec[T])(implicit sourceInfo: SourceInfo): Unit = this bulkConnect that.asInstanceOf[Data]
/** Strong bulk connect, assigning elements in this Vec from elements in a Seq.
*
@@ -144,9 +156,17 @@ sealed class Vec[T <: Data] private (gen: => T, val length: Int)
/** Creates a dynamically indexed read or write accessor into the array.
*/
def apply(idx: UInt): T = {
- val x = gen
- x.setRef(this, idx)
- x
+ Binding.checkSynthesizable(idx ,s"'idx' ($idx)")
+ val port = sample_element.cloneType
+ port.setRef(this, idx) //TODO(twigg): This is a bit too magical
+
+ // Bind each element of port to being whatever the base type is
+ // Using the head element as the sample_element
+ for((port_elem, model_elem) <- port.allElements zip sample_element.allElements) {
+ port_elem.binding = model_elem.binding
+ }
+
+ port
}
/** Creates a statically indexed read or write accessor into the array.
@@ -162,8 +182,7 @@ sealed class Vec[T <: Data] private (gen: => T, val length: Int)
override def cloneType: this.type =
Vec(length, gen).asInstanceOf[this.type]
- private val t = gen
- private[chisel3] def toType: String = s"${t.toType}[$length]"
+ private[chisel3] def toType: String = s"${sample_element.toType}[$length]"
private[chisel3] lazy val flatten: IndexedSeq[Bits] =
(0 until length).flatMap(i => this.apply(i).flatten)
@@ -256,7 +275,7 @@ trait VecLike[T <: Data] extends collection.IndexedSeq[T] with HasId {
* Usage: extend this class (either as an anonymous or named class) and define
* members variables of [[Data]] subtypes to be elements in the Bundle.
*/
-class Bundle extends Aggregate(NO_DIR) {
+class Bundle extends Aggregate {
private val _namespace = Builder.globalNamespace.child
// TODO: replace with better defined FIRRTL weak-connect operator
@@ -272,13 +291,6 @@ class Bundle extends Aggregate(NO_DIR) {
* mySubModule.io <> io
* }}}
*/
- 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)(implicit sourceInfo: SourceInfo): Unit = this <> that
lazy val elements: ListMap[String, Data] = ListMap(namedElts:_*)
@@ -333,7 +345,7 @@ class Bundle extends Aggregate(NO_DIR) {
}
private[chisel3] def toType = {
def eltPort(elt: Data): String = {
- val flipStr = if (elt.isFlip) "flip " else ""
+ val flipStr: String = if(Data.isFlipped(elt)) "flip " else ""
s"${flipStr}${elt.getRef.name} : ${elt.toType}"
}
s"{${namedElts.reverse.map(e => eltPort(e._2)).mkString(", ")}}"
@@ -343,6 +355,8 @@ class Bundle extends Aggregate(NO_DIR) {
namedElts += name -> elt
private[chisel3] override def _onModuleClose: Unit = // scalastyle:ignore method.name
for ((name, elt) <- namedElts) { elt.setRef(this, _namespace.name(name)) }
+
+ private[chisel3] final def allElements: Seq[Element] = namedElts.flatMap(_._2.allElements)
override def cloneType : this.type = {
// If the user did not provide a cloneType method, try invoking one of
@@ -373,5 +387,5 @@ class Bundle extends Aggregate(NO_DIR) {
}
private[core] object Bundle {
- val keywords = List("flip", "asInput", "asOutput", "cloneType", "toBits", "newType")
+ val keywords = List("flip", "asInput", "asOutput", "cloneType", "toBits")
}