summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWesley W. Terpstra2016-06-01 16:09:20 -0700
committerAndrew Waterman2016-06-01 16:09:20 -0700
commitfd53af8642237998e23456a3fd1648ac84607db0 (patch)
tree6c73c89a2e1b9621f126f1e501baf9bb804b5070
parent0b6f6b67f9b511468936ca30218343283071a69d (diff)
Fix a fairly serious bug whereby Vec's could incorrectly compare as equal (#204)
* chiselTests: include an example of two empty Vectors killing FIRRTL * Aggregate: fix a bug whereby Vec[T] was using equals/hashCode of Seq In Chisel, two vectors are NOT equal just if their contents are equal. For example, two empty vectors should not be considered equal. This patch makes Vec use the HasId._id for equality like other Chisel types. Without this fix, Bundle.namedElts.seen: HashSet[Data]() will eliminate one of the named vectors and emit bad IR.
-rw-r--r--chiselFrontend/src/main/scala/Chisel/Aggregate.scala6
-rw-r--r--src/test/scala/chiselTests/Vec.scala30
2 files changed, 35 insertions, 1 deletions
diff --git a/chiselFrontend/src/main/scala/Chisel/Aggregate.scala b/chiselFrontend/src/main/scala/Chisel/Aggregate.scala
index 197135d7..1eef5d69 100644
--- a/chiselFrontend/src/main/scala/Chisel/Aggregate.scala
+++ b/chiselFrontend/src/main/scala/Chisel/Aggregate.scala
@@ -174,9 +174,13 @@ sealed class Vec[T <: Data] private (gen: => T, val length: Int)
/** A trait for [[Vec]]s containing common hardware generators for collection
* operations.
*/
-trait VecLike[T <: Data] extends collection.IndexedSeq[T] {
+trait VecLike[T <: Data] extends collection.IndexedSeq[T] with HasId {
def apply(idx: UInt): T
+ // IndexedSeq has its own hashCode/equals that we must not use
+ override def hashCode: Int = super[HasId].hashCode
+ override def equals(that: Any): Boolean = super[HasId].equals(that)
+
@deprecated("Use Vec.apply instead", "chisel3")
def read(idx: UInt): T
diff --git a/src/test/scala/chiselTests/Vec.scala b/src/test/scala/chiselTests/Vec.scala
index 5239c6ba..943d9e4b 100644
--- a/src/test/scala/chiselTests/Vec.scala
+++ b/src/test/scala/chiselTests/Vec.scala
@@ -41,6 +41,32 @@ class ShiftRegisterTester(n: Int) extends BasicTester {
}
}
+class FunBundle extends Bundle {
+ val stuff = UInt(width = 10)
+}
+
+class ZeroModule extends Module {
+ val io = new Bundle {
+ val mem = UInt(width = 10)
+ val interrupts = Vec(2, Bool()).asInput
+ val mmio_axi = Vec(0, new FunBundle)
+ val mmio_ahb = Vec(0, new FunBundle).flip
+ }
+
+ io.mmio_axi <> io.mmio_ahb
+
+ io.mem := UInt(0)
+ when (io.interrupts(0)) { io.mem := UInt(1) }
+ when (io.interrupts(1)) { io.mem := UInt(2) }
+}
+
+class ZeroTester extends BasicTester {
+ val foo = Module(new ZeroModule)
+ foo.io.interrupts := Vec.tabulate(2) { _ => Bool(true) }
+ assert (foo.io.mem === UInt(2))
+ stop()
+}
+
class VecSpec extends ChiselPropSpec {
property("Vecs should be assignable") {
forAll(safeUIntN(8)) { case(w: Int, v: List[Int]) =>
@@ -55,4 +81,8 @@ class VecSpec extends ChiselPropSpec {
property("Regs of vecs should be usable as shift registers") {
forAll(smallPosInts) { (n: Int) => assertTesterPasses{ new ShiftRegisterTester(n) } }
}
+
+ property("Dual empty Vectors") {
+ assertTesterPasses{ new ZeroTester }
+ }
}