diff options
| author | Jim Lawson | 2016-09-01 17:09:23 -0700 |
|---|---|---|
| committer | GitHub | 2016-09-01 17:09:23 -0700 |
| commit | f85945511aeeb7eea9a3d715257a09c080d9b3f2 (patch) | |
| tree | 2f5b74bb83c3e2caba64cb42dc90c6e88b7408c9 | |
| parent | e2c76e1b752cb332d6c3b23dd224db14951c7e72 (diff) | |
| parent | 3442fac58a99551ca9e25dbc2c363c866c40e3cf (diff) | |
Merge pull request #273 from ucb-bar/check-vec
Check that Vecs have homogeneous types
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala | 17 | ||||
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/Bits.scala | 11 |
2 files changed, 23 insertions, 5 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index 82c6097f..e6ecff91 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -48,8 +48,21 @@ object Vec { // 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)) + def gen = elts.head match { + case e: Element => + // Vec[Element] must have homogeneous types, but may differ in width + for (elt <- elts.tail) + require(e.getClass == elt.getClass, + s"can't create Vec of heterogeneous types ${e.getClass} and ${elt.getClass}") + val maxWidth = elts.map(_.width).reduce(_ max _) + elts.head.cloneTypeWidth(maxWidth) + case a: Aggregate => + // Vec[Aggregate] must be homogeneous in type and width + for (elt <- elts.tail) + require(Mux.typesCompatible(a, elt), s"can't create Vec of heterogeneous types ${a.getClass} and ${elt.getClass}") + elts.head.cloneType + } + val vec = Wire(new Vec(gen, elts.length)) for ((v, e) <- vec zip elts) v := e vec diff --git a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala index 015b9dfb..44beab66 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala @@ -737,10 +737,15 @@ object Mux { pushOp(DefPrim(sourceInfo, d, MultiplexOp, cond.ref, con.ref, alt.ref)) } + private[core] def typesCompatible[T <: Data](x: T, y: T): Boolean = { + val sameTypes = x.getClass == y.getClass + val sameElements = x.flatten zip y.flatten forall { case (a, b) => a.getClass == b.getClass && a.width == b.width } + val sameNumElements = x.flatten.size == y.flatten.size + sameTypes && sameElements && sameNumElements + } + private def doAggregateMux[T <: Data](cond: Bool, con: T, alt: T)(implicit sourceInfo: SourceInfo): T = { - require(con.getClass == alt.getClass, s"can't Mux between ${con.getClass} and ${alt.getClass}") - for ((c, a) <- con.flatten zip alt.flatten) - require(c.width == a.width, "can't Mux between aggregates of different width") + require(typesCompatible(con, alt), s"can't Mux between heterogeneous types ${con.getClass} and ${alt.getClass}") doMux(cond, con, alt) } } |
