diff options
| author | Adam Izraelevitz | 2017-05-10 11:23:18 -0700 |
|---|---|---|
| committer | GitHub | 2017-05-10 11:23:18 -0700 |
| commit | 8b8eb4eac5b353d4d632065c78faf6a706d6aae8 (patch) | |
| tree | 39e2d9344166b61b376df9d3cd15a4787bcd01f4 /src/test/scala/firrtlTests/AnnotationTests.scala | |
| parent | af222c1737fa72fce964190876346bdb7ff220cd (diff) | |
Update rename2 (#478)
* Added pass name to debug logger
* Addresses #459. Rewords transform annotations API.
Now, any annotation not propagated by a transform is considered deleted.
A new DeletedAnnotation is added in place of it.
* Added more stylized debugging style
* WIP: make pass transform
* WIP: All tests pass, need to pull master
* Cleaned up PR
* Added rename updates to all core transforms
* Added more rename tests, and bugfixes
* Renaming tracks non-leaf subfields
E.g. given:
wire x: {a: UInt<1>, b: UInt<1>[2]}
Annotating x.b will eventually annotate x_b_0 and x_b_1
* Bugfix instance rename lowering broken
* Address review comments
* Remove check for seqTransform, UnknownForm too restrictive check
Diffstat (limited to 'src/test/scala/firrtlTests/AnnotationTests.scala')
| -rw-r--r-- | src/test/scala/firrtlTests/AnnotationTests.scala | 293 |
1 files changed, 275 insertions, 18 deletions
diff --git a/src/test/scala/firrtlTests/AnnotationTests.scala b/src/test/scala/firrtlTests/AnnotationTests.scala index 81d982e4..81c394c1 100644 --- a/src/test/scala/firrtlTests/AnnotationTests.scala +++ b/src/test/scala/firrtlTests/AnnotationTests.scala @@ -11,6 +11,7 @@ import firrtl.passes.InlineAnnotation import firrtl.passes.memlib.PinAnnotation import net.jcazevedo.moultingyaml._ import org.scalatest.Matchers +import logger._ /** * An example methodology for testing Firrtl annotations. @@ -25,8 +26,8 @@ trait AnnotationSpec extends LowTransformSpec { compile(CircuitState(parse(input), ChirrtlForm, Some(annotations)), Seq.empty) } } - def execute(annotations: AnnotationMap, input: String, check: Annotation): Unit = { - val cr = compile(CircuitState(parse(input), ChirrtlForm, Some(annotations)), Seq.empty) + def execute(aMap: Option[AnnotationMap], input: String, check: Annotation): Unit = { + val cr = compile(CircuitState(parse(input), ChirrtlForm, aMap), Seq.empty) cr.annotations.get.annotations should contain (check) } } @@ -40,20 +41,19 @@ trait AnnotationSpec extends LowTransformSpec { * Unstable, Fickle, and Insistent can be tested. */ class AnnotationTests extends AnnotationSpec with Matchers { - def getAMap (a: Annotation): AnnotationMap = AnnotationMap(Seq(a)) - val input: String = - """circuit Top : - | module Top : - | input a : UInt<1>[2] - | input b : UInt<1> - | node c = b""".stripMargin - val mName = ModuleName("Top", CircuitName("Top")) - val aName = ComponentName("a", mName) - val bName = ComponentName("b", mName) - val cName = ComponentName("c", mName) + def getAMap(a: Annotation): Option[AnnotationMap] = Some(AnnotationMap(Seq(a))) + def getAMap(as: Seq[Annotation]): Option[AnnotationMap] = Some(AnnotationMap(as)) + def anno(s: String, value: String ="this is a value"): Annotation = + Annotation(ComponentName(s, ModuleName("Top", CircuitName("Top"))), classOf[Transform], value) "Loose and Sticky annotation on a node" should "pass through" in { - val ta = Annotation(cName, classOf[Transform], "") + val input: String = + """circuit Top : + | module Top : + | input a : UInt<1>[2] + | input b : UInt<1> + | node c = b""".stripMargin + val ta = anno("c", "") execute(getAMap(ta), input, ta) } @@ -134,11 +134,10 @@ class AnnotationTests extends AnnotationSpec with Matchers { val outputForm = LowForm def execute(state: CircuitState) = state.copy(annotations = None) } - val anno = InlineAnnotation(CircuitName("Top")) - val annoOpt = Some(AnnotationMap(Seq(anno))) - val result = compiler.compile(CircuitState(parse(input), ChirrtlForm, annoOpt), Seq(new DeletingTransform)) + val inlineAnn = InlineAnnotation(CircuitName("Top")) + val result = compiler.compile(CircuitState(parse(input), ChirrtlForm, getAMap(inlineAnn)), Seq(new DeletingTransform)) result.annotations.get.annotations.head should matchPattern { - case DeletedAnnotation(x, anno) => + case DeletedAnnotation(x, inlineAnn) => } val exception = (intercept[FIRRTLException] { result.getEmittedCircuit @@ -146,4 +145,262 @@ class AnnotationTests extends AnnotationSpec with Matchers { val deleted = result.deletedAnnotations exception.str should be (s"No EmittedCircuit found! Did you delete any annotations?\n$deleted") } + + "Renaming" should "propagate in Lowering of memories" in { + val compiler = new VerilogCompiler + // Uncomment to help debugging failing tests + // Logger.setClassLogLevels(Map(compiler.getClass.getName -> LogLevel.Debug)) + val input = + """circuit Top : + | module Top : + | input clk: Clock + | input in: UInt<3> + | mem m: + | data-type => {a: UInt<4>, b: UInt<4>[2]} + | depth => 8 + | write-latency => 1 + | read-latency => 0 + | reader => r + | m.r.clk <= clk + | m.r.en <= UInt(1) + | m.r.addr <= in + |""".stripMargin + val annos = Seq(anno("m.r.data.b", "sub"), anno("m.r.data", "all"), anno("m", "mem")) + val result = compiler.compile(CircuitState(parse(input), ChirrtlForm, getAMap(annos)), Nil) + val resultAnno = result.annotations.get.annotations + resultAnno should contain (anno("m_a", "mem")) + resultAnno should contain (anno("m_b_0", "mem")) + resultAnno should contain (anno("m_b_1", "mem")) + resultAnno should contain (anno("m_a.r.data", "all")) + resultAnno should contain (anno("m_b_0.r.data", "all")) + resultAnno should contain (anno("m_b_1.r.data", "all")) + resultAnno should contain (anno("m_b_0.r.data", "sub")) + resultAnno should contain (anno("m_b_1.r.data", "sub")) + resultAnno should not contain (anno("m")) + resultAnno should not contain (anno("r")) + } + + "Renaming" should "propagate in RemoveChirrtl and Lowering of memories" in { + val compiler = new VerilogCompiler + Logger.setClassLogLevels(Map(compiler.getClass.getName -> LogLevel.Debug)) + val input = + """circuit Top : + | module Top : + | input clk: Clock + | input in: UInt<3> + | cmem m: {a: UInt<4>, b: UInt<4>[2]}[8] + | read mport r = m[in], clk + |""".stripMargin + val annos = Seq(anno("r.b", "sub"), anno("r", "all"), anno("m", "mem")) + val result = compiler.compile(CircuitState(parse(input), ChirrtlForm, getAMap(annos)), Nil) + val resultAnno = result.annotations.get.annotations + resultAnno should contain (anno("m_a", "mem")) + resultAnno should contain (anno("m_b_0", "mem")) + resultAnno should contain (anno("m_b_1", "mem")) + resultAnno should contain (anno("m_a.r.data", "all")) + resultAnno should contain (anno("m_b_0.r.data", "all")) + resultAnno should contain (anno("m_b_1.r.data", "all")) + resultAnno should contain (anno("m_b_0.r.data", "sub")) + resultAnno should contain (anno("m_b_1.r.data", "sub")) + resultAnno should not contain (anno("m")) + resultAnno should not contain (anno("r")) + } + + "Renaming" should "propagate in ZeroWidth" in { + val compiler = new VerilogCompiler + val input = + """circuit Top : + | module Top : + | input zero: UInt<0> + | wire x: {a: UInt<3>, b: UInt<0>} + | wire y: UInt<0>[3] + | y[0] <= zero + | y[1] <= zero + | y[2] <= zero + | x.a <= zero + | x.b <= zero + |""".stripMargin + val annos = Seq(anno("zero"), anno("x.a"), anno("x.b"), anno("y[0]"), anno("y[1]"), anno("y[2]")) + val result = compiler.compile(CircuitState(parse(input), ChirrtlForm, getAMap(annos)), Nil) + val resultAnno = result.annotations.get.annotations + resultAnno should contain (anno("x_a")) + resultAnno should not contain (anno("zero")) + resultAnno should not contain (anno("x.a")) + resultAnno should not contain (anno("x.b")) + resultAnno should not contain (anno("x_b")) + resultAnno should not contain (anno("y[0]")) + resultAnno should not contain (anno("y[1]")) + resultAnno should not contain (anno("y[2]")) + resultAnno should not contain (anno("y_0")) + resultAnno should not contain (anno("y_1")) + resultAnno should not contain (anno("y_2")) + } + + "Renaming subcomponents" should "propagate in Lowering" in { + val compiler = new VerilogCompiler + val input = + """circuit Top : + | module Top : + | input clk: Clock + | input pred: UInt<1> + | input in: {a: UInt<3>, b: UInt<3>[2]} + | output out: {a: UInt<3>, b: UInt<3>[2]} + | wire w: {a: UInt<3>, b: UInt<3>[2]} + | w is invalid + | node n = mux(pred, in, w) + | out <= n + | reg r: {a: UInt<3>, b: UInt<3>[2]}, clk + | cmem mem: {a: UInt<3>, b: UInt<3>[2]}[8] + | write mport write = mem[pred], clk + | write <= in + |""".stripMargin + val annos = Seq( + anno("in.a"), anno("in.b[0]"), anno("in.b[1]"), + anno("out.a"), anno("out.b[0]"), anno("out.b[1]"), + anno("w.a"), anno("w.b[0]"), anno("w.b[1]"), + anno("n.a"), anno("n.b[0]"), anno("n.b[1]"), + anno("r.a"), anno("r.b[0]"), anno("r.b[1]"), + anno("write.a"), anno("write.b[0]"), anno("write.b[1]") + ) + val result = compiler.compile(CircuitState(parse(input), ChirrtlForm, getAMap(annos)), Nil) + val resultAnno = result.annotations.get.annotations + resultAnno should not contain (anno("in.a")) + resultAnno should not contain (anno("in.b[0]")) + resultAnno should not contain (anno("in.b[1]")) + resultAnno should not contain (anno("out.a")) + resultAnno should not contain (anno("out.b[0]")) + resultAnno should not contain (anno("out.b[1]")) + resultAnno should not contain (anno("w.a")) + resultAnno should not contain (anno("w.b[0]")) + resultAnno should not contain (anno("w.b[1]")) + resultAnno should not contain (anno("n.a")) + resultAnno should not contain (anno("n.b[0]")) + resultAnno should not contain (anno("n.b[1]")) + resultAnno should not contain (anno("r.a")) + resultAnno should not contain (anno("r.b[0]")) + resultAnno should not contain (anno("r.b[1]")) + resultAnno should contain (anno("in_a")) + resultAnno should contain (anno("in_b_0")) + resultAnno should contain (anno("in_b_1")) + resultAnno should contain (anno("out_a")) + resultAnno should contain (anno("out_b_0")) + resultAnno should contain (anno("out_b_1")) + resultAnno should contain (anno("w_a")) + resultAnno should contain (anno("w_b_0")) + resultAnno should contain (anno("w_b_1")) + resultAnno should contain (anno("n_a")) + resultAnno should contain (anno("n_b_0")) + resultAnno should contain (anno("n_b_1")) + resultAnno should contain (anno("r_a")) + resultAnno should contain (anno("r_b_0")) + resultAnno should contain (anno("r_b_1")) + resultAnno should contain (anno("mem_a.write.data")) + resultAnno should contain (anno("mem_b_0.write.data")) + resultAnno should contain (anno("mem_b_1.write.data")) + } + + "Renaming components" should "expand in Lowering" in { + val compiler = new VerilogCompiler + val input = + """circuit Top : + | module Top : + | input clk: Clock + | input pred: UInt<1> + | input in: {a: UInt<3>, b: UInt<3>[2]} + | output out: {a: UInt<3>, b: UInt<3>[2]} + | wire w: {a: UInt<3>, b: UInt<3>[2]} + | w is invalid + | node n = mux(pred, in, w) + | out <= n + | reg r: {a: UInt<3>, b: UInt<3>[2]}, clk + |""".stripMargin + val annos = Seq(anno("in"), anno("out"), anno("w"), anno("n"), anno("r")) + val result = compiler.compile(CircuitState(parse(input), ChirrtlForm, getAMap(annos)), Nil) + val resultAnno = result.annotations.get.annotations + resultAnno should contain (anno("in_a")) + resultAnno should contain (anno("in_b_0")) + resultAnno should contain (anno("in_b_1")) + resultAnno should contain (anno("out_a")) + resultAnno should contain (anno("out_b_0")) + resultAnno should contain (anno("out_b_1")) + resultAnno should contain (anno("w_a")) + resultAnno should contain (anno("w_b_0")) + resultAnno should contain (anno("w_b_1")) + resultAnno should contain (anno("n_a")) + resultAnno should contain (anno("n_b_0")) + resultAnno should contain (anno("n_b_1")) + resultAnno should contain (anno("r_a")) + resultAnno should contain (anno("r_b_0")) + resultAnno should contain (anno("r_b_1")) + } + + "Renaming subcomponents that aren't leaves" should "expand in Lowering" in { + val compiler = new VerilogCompiler + val input = + """circuit Top : + | module Top : + | input clk: Clock + | input pred: UInt<1> + | input in: {a: UInt<3>, b: UInt<3>[2]} + | output out: {a: UInt<3>, b: UInt<3>[2]} + | wire w: {a: UInt<3>, b: UInt<3>[2]} + | w is invalid + | node n = mux(pred, in, w) + | out <= n + | reg r: {a: UInt<3>, b: UInt<3>[2]}, clk + |""".stripMargin + val annos = Seq(anno("in.b"), anno("out.b"), anno("w.b"), anno("n.b"), anno("r.b")) + val result = compiler.compile(CircuitState(parse(input), ChirrtlForm, getAMap(annos)), Nil) + val resultAnno = result.annotations.get.annotations + resultAnno should contain (anno("in_b_0")) + resultAnno should contain (anno("in_b_1")) + resultAnno should contain (anno("out_b_0")) + resultAnno should contain (anno("out_b_1")) + resultAnno should contain (anno("w_b_0")) + resultAnno should contain (anno("w_b_1")) + resultAnno should contain (anno("n_b_0")) + resultAnno should contain (anno("n_b_1")) + resultAnno should contain (anno("r_b_0")) + resultAnno should contain (anno("r_b_1")) + } + + + "Renaming" should "track dce" in { + val compiler = new VerilogCompiler + val input = + """circuit Top : + | module Top : + | input clk: Clock + | input pred: UInt<1> + | input in: {a: UInt<3>, b: UInt<3>[2]} + | output out: {a: UInt<3>, b: UInt<3>[2]} + | node n = in + | out <= n + |""".stripMargin + val annos = Seq( + anno("in.a"), anno("in.b[0]"), anno("in.b[1]"), + anno("out.a"), anno("out.b[0]"), anno("out.b[1]"), + anno("n.a"), anno("n.b[0]"), anno("n.b[1]") + ) + val result = compiler.compile(CircuitState(parse(input), ChirrtlForm, getAMap(annos)), Nil) + val resultAnno = result.annotations.get.annotations + resultAnno should not contain (anno("in.a")) + resultAnno should not contain (anno("in.b[0]")) + resultAnno should not contain (anno("in.b[1]")) + resultAnno should not contain (anno("out.a")) + resultAnno should not contain (anno("out.b[0]")) + resultAnno should not contain (anno("out.b[1]")) + resultAnno should not contain (anno("n.a")) + resultAnno should not contain (anno("n.b[0]")) + resultAnno should not contain (anno("n.b[1]")) + resultAnno should not contain (anno("n_a")) + resultAnno should not contain (anno("n_b_0")) + resultAnno should not contain (anno("n_b_1")) + resultAnno should contain (anno("in_a")) + resultAnno should contain (anno("in_b_0")) + resultAnno should contain (anno("in_b_1")) + resultAnno should contain (anno("out_a")) + resultAnno should contain (anno("out_b_0")) + resultAnno should contain (anno("out_b_1")) + } } |
