From 7a31e39481c4a74119eda66165b27fdd90909b29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kevin=20L=C3=A4ufer?= Date: Mon, 26 Jul 2021 16:28:54 -0700 Subject: [PATCH] ir: make HashCode.toHashString public This will allow chiseltest to save the hash code to disk for the purpose of caching simulation binaries. --- src/main/scala/firrtl/ir/StructuralHash.scala | 12 ++++++++---- src/test/scala/firrtl/ir/StructuralHashSpec.scala | 10 ++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main/scala/firrtl/ir/StructuralHash.scala b/src/main/scala/firrtl/ir/StructuralHash.scala index 20c63e4e1c..26e7d210e8 100644 --- a/src/main/scala/firrtl/ir/StructuralHash.scala +++ b/src/main/scala/firrtl/ir/StructuralHash.scala @@ -115,16 +115,20 @@ object StructuralHash { } trait HashCode { - protected val str: String - override def hashCode(): Int = str.hashCode + + /** String representation of the hash code. + * Two instances of [[HashCode]] are equal if and only if their toHashString values are equal. + */ + def toHashString: String + override def hashCode(): Int = toHashString.hashCode override def equals(obj: Any): Boolean = obj match { - case hashCode: HashCode => this.str.equals(hashCode.str) + case hashCode: HashCode => this.toHashString.equals(hashCode.toHashString) case _ => false } } private class MDHashCode(code: Array[Byte]) extends HashCode { - protected override val str: String = code.map(b => f"${b.toInt & 0xff}%02x").mkString("") + override val toHashString: String = code.map(b => f"${b.toInt & 0xff}%02x").mkString("") } /** Generic hashing interface which allows us to use different backends to trade of speed and collision resistance */ diff --git a/src/test/scala/firrtl/ir/StructuralHashSpec.scala b/src/test/scala/firrtl/ir/StructuralHashSpec.scala index ffd0312632..4372cc705f 100644 --- a/src/test/scala/firrtl/ir/StructuralHashSpec.scala +++ b/src/test/scala/firrtl/ir/StructuralHashSpec.scala @@ -38,6 +38,16 @@ class StructuralHashSpec extends AnyFlatSpec { assert(hash(b1) != hash(UIntLiteral(1, IntWidth(2)))) } + it should "generate the same hash String if the objects are structurally the same" in { + assert(hash(b0).toHashString == hash(UIntLiteral(0, IntWidth(1))).toHashString) + assert(hash(b0).toHashString != hash(UIntLiteral(1, IntWidth(1))).toHashString) + assert(hash(b0).toHashString != hash(UIntLiteral(1, IntWidth(2))).toHashString) + + assert(hash(b1).toHashString == hash(UIntLiteral(1, IntWidth(1))).toHashString) + assert(hash(b1).toHashString != hash(UIntLiteral(0, IntWidth(1))).toHashString) + assert(hash(b1).toHashString != hash(UIntLiteral(1, IntWidth(2))).toHashString) + } + it should "ignore expression types" in { assert(hash(add) == hash(DoPrim(Add, Seq(b0, b1), Seq(), UnknownType))) assert(hash(add) == hash(DoPrim(Add, Seq(b0, b1), Seq(), UIntType(UnknownWidth))))