summaryrefslogtreecommitdiff
path: root/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
diff options
context:
space:
mode:
authorJim Lawson2016-09-30 12:13:58 -0700
committerGitHub2016-09-30 12:13:58 -0700
commitdb25e8180a53fb8f4912fd37b7a613e15a01564f (patch)
tree8bb5597746002ac98641f394cee4c94e1d154aff /chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
parent785620b1403d827986bf60c2a001d8d6f71eed72 (diff)
parent6edbdf279257d656b5eac38d9de8645a068611bf (diff)
Merge pull request #265 from ucb-bar/gsdt
Gsdt - Fixup to Chisel connections and direction - PR 200 revisited.
Diffstat (limited to 'chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala')
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala96
1 files changed, 61 insertions, 35 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
index d07c5dcd..5cec54c2 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
@@ -14,7 +14,7 @@ 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) {
+sealed abstract class Aggregate extends Data {
private[core] def cloneTypeWidth(width: Width): this.type = cloneType
private[core] def width: Width = flatten.map(_.width).reduce(_ + _)
}
@@ -24,10 +24,10 @@ object Vec {
*
* @note elements are NOT assigned by default and have no value
*/
- def apply[T <: Data](n: Int, gen: T): Vec[T] = new Vec(gen.cloneType, n)
+ def apply[T <: Data](n: Int, gen: T): Vec[T] = new Vec(gen, n)
@deprecated("Vec argument order should be size, t; this will be removed by the official release", "chisel3")
- def apply[T <: Data](gen: T, n: Int): Vec[T] = new Vec(gen.cloneType, n)
+ def apply[T <: Data](gen: T, n: Int): Vec[T] = new Vec(gen, n)
/** Creates a new [[Vec]] composed of elements of the input Seq of [[Data]]
* nodes.
@@ -61,8 +61,16 @@ object Vec {
val maxWidth = elts.map(_.width).reduce(_ max _)
val vec = Wire(new Vec(t.cloneTypeWidth(maxWidth), elts.length))
- for ((v, e) <- vec zip elts)
- v := e
+ def doConnect(sink: T, source: T) = {
+ if (elts.head.flatten.exists(_.dir != Direction.Unspecified)) {
+ sink bulkConnect source
+ } else {
+ sink connect source
+ }
+ }
+ for ((v, e) <- vec zip elts) {
+ doConnect(v, e)
+ }
vec
}
@@ -100,6 +108,7 @@ object Vec {
* @param gen function that generates the [[Data]] that becomes the output
* element
*/
+ @deprecated("Vec.fill(n)(gen) is deprecated. Please use Vec(Seq.fill(n)(gen))", "chisel3")
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] =
@@ -115,49 +124,69 @@ object Vec {
* @note Vecs, unlike classes in Scala's collection library, are propagated
* 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] {
+sealed class Vec[T <: Data] private (gen: T, val length: Int)
+ 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: Seq[T] = Vector.fill(length)(gen.chiselCloneType)
- private val self = IndexedSeq.fill(length)(gen)
+ /**
+ * 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.chiselCloneType
- override def <> (that: Data)(implicit sourceInfo: SourceInfo): Unit = this := that
+ // 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, 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): 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, moduleCompileOptions: CompileOptions): Unit = this bulkConnect that.asInstanceOf[Data]
/** 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 = {
+ 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): Unit = this connect that
+ def := (that: Vec[T])(implicit sourceInfo: SourceInfo, moduleCompileOptions: CompileOptions): Unit = this connect that
/** 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.chiselCloneType
+ 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.
@@ -168,13 +197,15 @@ 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)(DeprecatedSourceInfo)
+ def write(idx: UInt, data: T): Unit = {
+ apply(idx).:=(data)(DeprecatedSourceInfo, chisel3.core.ExplicitCompileOptions.NotStrict)
+ }
- override def cloneType: this.type =
+ 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)
@@ -278,7 +309,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
@@ -294,13 +325,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:_*)
@@ -355,7 +379,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.isFirrtlFlipped(elt)) "flip " else ""
s"${flipStr}${elt.getRef.name} : ${elt.toType}"
}
s"{${namedElts.reverse.map(e => eltPort(e._2)).mkString(", ")}}"
@@ -365,6 +389,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
@@ -410,6 +436,6 @@ class Bundle extends Aggregate(NO_DIR) {
}
private[core] object Bundle {
- val keywords = List("flip", "asInput", "asOutput", "cloneType", "toBits",
+ val keywords = List("flip", "asInput", "asOutput", "cloneType", "chiselCloneType", "toBits",
"widthOption", "signalName", "signalPathName", "signalParent", "signalComponent")
}