diff options
| author | Jack Koenig | 2018-07-02 17:18:32 -0700 |
|---|---|---|
| committer | GitHub | 2018-07-02 17:18:32 -0700 |
| commit | 2b405652a266114377816b8175ef9fad7d36ed14 (patch) | |
| tree | 9d126903e1fee1d05e534b75cfdfed60fcef1651 /src | |
| parent | 4ee238fc482aab582130cc4c3bb067cc3e872ce4 (diff) | |
Make ZeroWidth properly rename removed empty aggregates (#839)
Fixes #756
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/scala/firrtl/passes/ZeroWidth.scala | 20 | ||||
| -rw-r--r-- | src/test/scala/firrtlTests/AnnotationTests.scala | 35 |
2 files changed, 52 insertions, 3 deletions
diff --git a/src/main/scala/firrtl/passes/ZeroWidth.scala b/src/main/scala/firrtl/passes/ZeroWidth.scala index a8e6141c..12da7d9b 100644 --- a/src/main/scala/firrtl/passes/ZeroWidth.scala +++ b/src/main/scala/firrtl/passes/ZeroWidth.scala @@ -55,13 +55,27 @@ object ZeroWidth extends Transform { state.copy(circuit = result) } + // This is slightly different and specialized version of create_exps, TODO unify? + private def findRemovable(expr: => Expression, tpe: Type): Seq[Expression] = tpe match { + case GroundType(width) => width match { + case IntWidth(ZERO) => List(expr) + case _ => List.empty + } + case BundleType(fields) => + if (fields.isEmpty) List(expr) + else fields.flatMap(f => findRemovable(WSubField(expr, f.name, f.tpe, MALE), f.tpe)) + case VectorType(vtpe, size) => + if (size == 0) List(expr) + else findRemovable(WSubIndex(expr, 0, vtpe, MALE), vtpe).flatMap { e => + (0 until size).map(i => e.asInstanceOf[WSubIndex].copy(value = i)) + } + } + private val ZERO = BigInt(0) private def getRemoved(x: IsDeclaration): Seq[String] = { var removedNames: Seq[String] = Seq.empty def onType(name: String)(t: Type): Type = { - removedNames = Utils.create_exps(name, t) map {e => (e, e.tpe)} collect { - case (e, GroundType(IntWidth(ZERO))) => e.serialize - } + removedNames = findRemovable(WRef(name), t).map(_.serialize) t } x match { diff --git a/src/test/scala/firrtlTests/AnnotationTests.scala b/src/test/scala/firrtlTests/AnnotationTests.scala index 9fb8dfd9..99e1ea2c 100644 --- a/src/test/scala/firrtlTests/AnnotationTests.scala +++ b/src/test/scala/firrtlTests/AnnotationTests.scala @@ -420,6 +420,40 @@ abstract class AnnotationTests extends AnnotationSpec with Matchers { val y = AnnotationUtils.toNamed(x.serialize) require(x == y) } + + "Annotations on empty aggregates" should "be deleted" in { + val compiler = new VerilogCompiler + val input = + """circuit Top : + | module Top : + | input x : { foo : UInt<8>, bar : {}, fizz : UInt<8>[0], buzz : UInt<0> } + | output y : { foo : UInt<8>, bar : {}, fizz : UInt<8>[0], buzz : UInt<0> } + | output a : {} + | output b : UInt<8>[0] + | y <= x + |""".stripMargin + val annos = Seq( + anno("x"), anno("y.bar"), anno("y.fizz"), anno("y.buzz"), anno("a"), anno("b") + ) + val result = compiler.compile(CircuitState(parse(input), ChirrtlForm, annos), Nil) + val resultAnno = result.annotations.toSeq + resultAnno should contain (anno("x_foo")) + resultAnno should not contain (anno("a")) + resultAnno should not contain (anno("b")) + // Check both with and without dots because both are wrong + resultAnno should not contain (anno("y.bar")) + resultAnno should not contain (anno("y.fizz")) + resultAnno should not contain (anno("y.buzz")) + resultAnno should not contain (anno("x.bar")) + resultAnno should not contain (anno("x.fizz")) + resultAnno should not contain (anno("x.buzz")) + resultAnno should not contain (anno("y_bar")) + resultAnno should not contain (anno("y_fizz")) + resultAnno should not contain (anno("y_buzz")) + resultAnno should not contain (anno("x_bar")) + resultAnno should not contain (anno("x_fizz")) + resultAnno should not contain (anno("x_buzz")) + } } class LegacyAnnotationTests extends AnnotationTests { @@ -464,6 +498,7 @@ class LegacyAnnotationTests extends AnnotationTests { } thrown.getMessage should include ("Illegal circuit name") } + } class JsonAnnotationTests extends AnnotationTests with BackendCompilationUtilities { |
