diff options
| author | Jim Lawson | 2016-09-30 12:13:58 -0700 |
|---|---|---|
| committer | GitHub | 2016-09-30 12:13:58 -0700 |
| commit | db25e8180a53fb8f4912fd37b7a613e15a01564f (patch) | |
| tree | 8bb5597746002ac98641f394cee4c94e1d154aff /chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala | |
| parent | 785620b1403d827986bf60c2a001d8d6f71eed72 (diff) | |
| parent | 6edbdf279257d656b5eac38d9de8645a068611bf (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.scala | 96 |
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") } |
