aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/scala/firrtlTests/UniquifySpec.scala294
1 files changed, 294 insertions, 0 deletions
diff --git a/src/test/scala/firrtlTests/UniquifySpec.scala b/src/test/scala/firrtlTests/UniquifySpec.scala
new file mode 100644
index 00000000..7e01c3eb
--- /dev/null
+++ b/src/test/scala/firrtlTests/UniquifySpec.scala
@@ -0,0 +1,294 @@
+/*
+Copyright (c) 2014 - 2016 The Regents of the University of
+California (Regents). All Rights Reserved. Redistribution and use in
+source and binary forms, with or without modification, are permitted
+provided that the following conditions are met:
+ * Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the following
+ two paragraphs of disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ two paragraphs of disclaimer in the documentation and/or other materials
+ provided with the distribution.
+ * Neither the name of the Regents nor the names of its contributors
+ may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
+ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
+REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF
+ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION
+TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+MODIFICATIONS.
+*/
+
+package firrtlTests
+
+import java.io._
+import org.scalatest._
+import org.scalatest.prop._
+import firrtl.{Parser, Circuit}
+import firrtl.passes._
+
+class UniquifySpec extends FirrtlFlatSpec {
+
+ private val passes = Seq(
+ ToWorkingIR,
+ CheckHighForm,
+ ResolveKinds,
+ InferTypes,
+ Uniquify
+ )
+
+ private def executeTest(input: String, expected: Seq[String]) = {
+ val c = passes.foldLeft(Parser.parse("", input.split("\n").toIterator)) {
+ (c: Circuit, p: Pass) => p.run(c)
+ }
+ val lines = c.serialize.split("\n") map normalized
+
+ expected foreach { e =>
+ lines should contain(e)
+ }
+ }
+
+ behavior of "Uniquify"
+
+ it should "rename colliding ports" in {
+ val input =
+ """circuit Test :
+ | module Test :
+ | input a : { flip b : UInt<1>, c : { d : UInt<2>, flip e : UInt<3>}[2], c_1_e : UInt<4>}[2]
+ | output a_0_c_ : UInt<5>
+ | output a__0 : UInt<6>
+ """.stripMargin
+ val expected = Seq(
+ "input a__ : { flip b : UInt<1>, c_ : { d : UInt<2>, flip e : UInt<3>}[2], c_1_e : UInt<4>}[2]",
+ "output a_0_c_ : UInt<5>",
+ "output a__0 : UInt<6>") map normalized
+
+ executeTest(input, expected)
+ }
+
+ it should "rename colliding registers" in {
+ val input =
+ """circuit Test :
+ | module Test :
+ | input clk : Clock
+ | reg a : { b : UInt<1>, c : { d : UInt<2>, e : UInt<3>}[2], c_1_e : UInt<4>}[2], clk
+ | reg a_0_c_ : UInt<5>, clk
+ | reg a__0 : UInt<6>, clk
+ """.stripMargin
+ val expected = Seq(
+ "reg a__ : { b : UInt<1>, c_ : { d : UInt<2>, e : UInt<3>}[2], c_1_e : UInt<4>}[2], clk with :",
+ "reg a_0_c_ : UInt<5>, clk with :",
+ "reg a__0 : UInt<6>, clk with :") map normalized
+
+ executeTest(input, expected)
+ }
+
+ it should "rename colliding nodes" in {
+ val input =
+ """circuit Test :
+ | module Test :
+ | input clk : Clock
+ | reg x : { b : UInt<1>, c : { d : UInt<2>, e : UInt<3>}[2], c_1_e : UInt<4>}[2], clk
+ | node a = x
+ | node a_0_c_ = a[0].b
+ | node a__0 = a[1].c[0].d
+ """.stripMargin
+ val expected = Seq("node a__ = x") map normalized
+
+ executeTest(input, expected)
+ }
+
+
+ it should "rename DefRegister expressions: clk, reset, and init" in {
+ val input =
+ """circuit Test :
+ | module Test :
+ | input clk : Clock[2]
+ | input clk_0 : Clock
+ | input reset : { a : UInt<1>, b : UInt<1>}
+ | input reset_a : UInt<1>
+ | input init : { a : UInt<4>, b : { c : UInt<4>, d : UInt<4>}[2], b_1_c : UInt<4>}[4]
+ | input init_0_a : UInt<4>
+ | reg foo : UInt<4>, clk[1], with :
+ | reset => (reset.a, init[3].b[1].d)
+ """.stripMargin
+ val expected = Seq(
+ "reg foo : UInt<4>, clk_[1] with :",
+ "reset => (reset_.a, init_[3].b_[1].d)"
+ ) map normalized
+
+ executeTest(input, expected)
+ }
+
+ it should "rename ports before statements" in {
+ val input =
+ """circuit Test :
+ | module Test :
+ | input data : { a : UInt<4>, b : UInt<4>}[2]
+ | node data_0_a = data[0].a
+ """.stripMargin
+ val expected = Seq(
+ "input data : { a : UInt<4>, b : UInt<4>}[2]",
+ "node data_0_a_ = data[0].a"
+ ) map normalized
+
+ executeTest(input, expected)
+ }
+
+ it should "rename node expressions" in {
+ val input =
+ """circuit Test :
+ | module Test :
+ | input data : { a : UInt<4>, b : UInt<4>[2]}
+ | input data_a : UInt<4>
+ | input data__b_1 : UInt<4>
+ | node foo = data.a
+ | node bar = data.b[1]
+ """.stripMargin
+ val expected = Seq(
+ "node foo = data__.a",
+ "node bar = data__.b[1]") map normalized
+
+ executeTest(input, expected)
+ }
+
+ it should "rename both side of connects" in {
+ val input =
+ """circuit Test :
+ | module Test :
+ | input a : { b : UInt<1>, flip c : { d : UInt<2>, e : UInt<3>}[2], c_1_e : UInt<4>}[2]
+ | output a_0_b : UInt<1>
+ | input a__0_c_ : { d : UInt<2>, e : UInt<3>}[2]
+ | a_0_b <= a[0].b
+ | a[0].c <- a__0_c_
+ """.stripMargin
+ val expected = Seq(
+ "a_0_b <= a__[0].b",
+ "a__[0].c_ <- a__0_c_") map normalized
+
+ executeTest(input, expected)
+ }
+
+ it should "rename SubAccesses" in {
+ val input =
+ """circuit Test :
+ | module Test :
+ | input a : { b : UInt<1>, c : { d : UInt<2>, e : UInt<3>}[2], c_1_e : UInt<4>}[2]
+ | output a_0_b : UInt<2>
+ | input i : UInt<1>[2]
+ | output i_0 : UInt<1>
+ | a_0_b <= a.c[i[1]].d
+ """.stripMargin
+ val expected = Seq(
+ "a_0_b <= a_.c_[i_[1]].d") map normalized
+
+ executeTest(input, expected)
+ }
+
+ it should "rename deeply nested expressions" in {
+ val input =
+ """circuit Test :
+ | module Test :
+ | input a : { b : UInt<1>, flip c : { d : UInt<2>, e : UInt<3>}[2], c_1_e : UInt<4>}[2]
+ | output a_0_b : UInt<1>
+ | input a__0_c_ : { d : UInt<2>, e : UInt<3>}[2]
+ | a_0_b <= mux(a[UInt(0)].c_1_e, or(a[or(a[0].b, a[1].b)].b, xorr(a[0].c_1_e)), orr(cat(a__0_c_[0].e, a[1].c_1_e)))
+ """.stripMargin
+ val expected = Seq(
+ "a_0_b <= mux(a__[UInt<1>(\"h0\")].c_1_e, or(a__[or(a__[0].b, a__[1].b)].b, xorr(a__[0].c_1_e)), orr(cat(a__0_c_[0].e, a__[1].c_1_e)))"
+ ) map normalized
+
+ executeTest(input, expected)
+ }
+
+ it should "rename memories" in {
+ val input =
+ """circuit Test :
+ | module Test :
+ | input clk : Clock
+ | mem mem :
+ | data-type => { a : UInt<8>, b : UInt<8>[2]}[2]
+ | depth => 32
+ | read-latency => 0
+ | write-latency => 1
+ | reader => read
+ | writer => write
+ | node mem_0_b = mem.read.data[0].b
+ |
+ | mem.read.addr is invalid
+ | mem.read.en <= UInt(1)
+ | mem.read.clk <= clk
+ | mem.write.data is invalid
+ | mem.write.mask is invalid
+ | mem.write.addr is invalid
+ | mem.write.en <= UInt(0)
+ | mem.write.clk <= clk
+ """.stripMargin
+ val expected = Seq(
+ "mem mem_ :",
+ "node mem_0_b = mem_.read.data[0].b",
+ "mem_.read.addr is invalid") map normalized
+
+ executeTest(input, expected)
+ }
+
+ it should "rename aggregate typed memories" in {
+ val input =
+ """circuit Test :
+ | module Test :
+ | input clk : Clock
+ | mem mem :
+ | data-type => { a : UInt<8>, b : UInt<8>[2], b_0 : UInt<8> }
+ | depth => 32
+ | read-latency => 0
+ | write-latency => 1
+ | reader => read
+ | writer => write
+ | node x = mem.read.data.b[0]
+ |
+ | mem.read.addr is invalid
+ | mem.read.en <= UInt(1)
+ | mem.read.clk <= clk
+ | mem.write.data is invalid
+ | mem.write.mask is invalid
+ | mem.write.addr is invalid
+ | mem.write.en <= UInt(0)
+ | mem.write.clk <= clk
+ """.stripMargin
+ val expected = Seq(
+ "data-type => { a : UInt<8>, b_ : UInt<8>[2], b_0 : UInt<8>}",
+ "node x = mem.read.data.b_[0]") map normalized
+
+ executeTest(input, expected)
+ }
+
+ it should "rename instances and their ports" in {
+ val input =
+ """circuit Test :
+ | module Other :
+ | input a : { b : UInt<4>, c : UInt<4> }
+ | output a_b : UInt<4>
+ | a_b <= a.b
+ |
+ | module Test :
+ | node x = UInt(6)
+ | inst mod of Other
+ | mod.a.b <= x
+ | mod.a.c <= x
+ | node mod_a_b = mod.a_b
+ """.stripMargin
+ val expected = Seq(
+ "inst mod_ of Other",
+ "mod_.a_.b <= x",
+ "mod_.a_.c <= x",
+ "node mod_a_b = mod_.a_b") map normalized
+
+ executeTest(input, expected)
+ }
+}