summaryrefslogtreecommitdiff
path: root/chiselFrontend
diff options
context:
space:
mode:
Diffstat (limited to 'chiselFrontend')
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala17
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Bits.scala11
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)
}
}